universalisos/kernel/docs/AARCH64_APEX.md

5.8 KiB

AArch64 EL2 APEX (ARINC-653) shim — handoff

Status: first slice guest-verifiable end-to-end. linux_stub.c:apex_probe() prints [apex] OK. Builds clean on aarch64 + armv7; no p4 token in any touched file.

Why

APEX is the ARINC-653 application executive a partitioned safety-critical guest (LynxOS-178-, VxWorks-653-, INTEGRITY-178-, PikeOS-style) links against. Rather than re-implement APEX inside UniversalisOS, we bind the standard APEX procedure names to the existing uos_ paravirtual ABI (hvc #0x5500). A partitioned guest links libuos_apex.h and sees the familiar APEX surface; underneath every call is one hypercall. This is the layer the wider apex replication track builds on, and it reuses the ABI extended in AARCH64_UOS_ABI.md.

What this slice covers (bounded + verifiable)

ARINC-653 procedure HV call notes
GET_PARTITION_STATUS UOS_HV_PART_GET_STATUS 0x0e period/duration/mode/start-cond/procs
SET_PARTITION_MODE UOS_HV_PART_SET_MODE 0x0f NORMAL<->IDLE free; COLD/WARM re-init
RAISE_APPLICATION_ERROR UOS_HV_ERROR_RAISE 0x10 latches code+timestamp, logs on PL011
GET_ERROR_STATUS UOS_HV_ERROR_GET_STATUS0x11 read-then-clears the latch
GET_MY_ID UOS_HV_GET_VCPU_ID 0x0b process==vcpu today (0)
GET_TIME UOS_HV_GETTIME 0x02 cntvct ticks

Standard APEX return codes (APEX_NO_ERROR/NO_ACTION/NOT_AVAILABLE/ INVALID_PARAM/INVALID_CONFIG/INVALID_MODE/TIMED_OUT) are mapped from the UOS_HV_E* errno returns by apex_map_rc().

HV-side state (el2_guest.cpp, file-static)

  • g_part_mode (default NORMAL), g_part_start_cond (default COLD_START).
  • g_err_code (0xFFFFFFFF = none latched), g_err_timestamp, g_err_proc.
  • Mode rules implemented: any in-range mode accepted; COLD/WARM update the start condition; setting any mode clears the error latch (fresh mode = fresh health). EINVAL for mode>3 or error-code>7. EPERM reserved for the future multi-partition case (only the HM/owner may restart a partition).
  • INFO capabilities now advertise UOS_HV_CAP_APEX (1<<5) -> caps word 0x3f.
  • Both IPA writes use the volatile-u32 field-store pattern (alignment-safe at EL2, see AARCH64_UOS_ABI.md pitfall). GET_ERROR_STATUS writes the u64 timestamp as two u32 halves.

Verification (ad-hoc, NOT suite green)

Guest self-check (apex_probe): status=NORMAL/id=0/procs=1; GET_MY_ID=0; SET_MODE(IDLE)->status IDLE, back to NORMAL; SET_MODE(99)=INVALID_PARAM; RAISE(APPLICATION_ERROR)->GET_STATUS code=1 ts!=0; GET_STATUS again=0xffffffff (cleared). [uosabi] OK and [apex] OK both present; full-log scan shows no EL2 TRAP|Stage-2 data abort|virtual SError|FAIL|MISMATCH. aarch64-classic and armv7 build clean. The MP0 A/B scheduler UART interleave ([A-start]/[B-start], mid-token lone A/B, e.g. caAps) is expected and benign — assert on the decisive markers, not strict line regexes.

Resume / extend (open items, in order)

  • APEX-1: CREATE_PROCESS / START / STOP / SUSPEND / RESUME / GET_PROCESS_STATUS — needs per-process state + a partition scheduler on the EL2 track. Today there is exactly one vCPU/process; land multi-vCPU first, then map processes to vCPUs. Return APEX_NOT_AVAILABLE until then (already the default via apex_map_rc(ENOSYS) if you add a stub call). Progress (this session): vCPU identity is now table-backed, not hardcoded. aarch64_vcpu_t gained vcpu_id/part_id/online; aarch64_vcpu_set_id() tags a vCPU, aarch64_current_vcpu() recovers it from TPIDR_EL2 on a guest PE, aarch64_current_vcpu_id()/_part_id() give safe (0/0) fallbacks. GET_VCPU_ID / GET_PART_ID / INFO.{vcpu_id,partition_id,nr_vcpus} / PART_GET_STATUS.{identifier,num_assigned_procs} / ERROR_RAISE.failed_proc all source from the live vCPU + a g_part0_online counter bumped at bring-up (aarch64_partition0_add_vcpu()). Today still 1 vCPU (ids 0/0/1) — adding the second guest vCPU is now a state change (new aarch64_vcpu_t + set_id(0,1) + PSCI CPU_ON to MP2 + its own stage-2/stack/DTB), not an ABI rewrite.
  • APEX-2: SAMPLING_PORT / QUEUING_PORT — inter-partition IPC; needs a partition table + channel config from the XSD lane (mycelium codegen). The uos: config-schema lane is the right place for port/channel declarations.
  • APEX-3: BUFFER / BLACKBOARD / SEMAPHORE / EVENT — intra-partition primitives; pure guest-side once processes exist (no new HV calls), or a small HV assist for blocking wakeups.
  • APEX-4: TIMED_WAIT / PERIODIC_WAIT / PARTITION_SCHEDULE — needs the EL2 physical timer (CNTHP, INTID 26) preemption that the U3 item tracks; once ticks preempt, the partition time window becomes real.
  • APEX-5: source GET_MY_ID / IDENTIFIER / num_assigned_procs from the per-PE current vcpu/partition once multi-vCPU lands (same as U-abi-1).

Files

  • src/arch/aarch64/inc/uos_hv_abi.h — calls 0x0e..0x11, modes, error codes, uos_hv_part_status_t, uos_hv_error_status_t, UOS_HV_CAP_APEX, inlines.
  • src/arch/aarch64/inc/libuos_apex.h — APEX types/procedures/return-codes -> uos_ HV calls.
  • src/arch/aarch64/el2_guest.cpp — partition/error file-statics + 4 dispatcher cases; INFO caps OR'd with APEX.
  • src/arch/aarch64/guest_payload/linux_stub.capex_probe() ([apex] OK).
  • src/arch/aarch64/vcpu.{h,cpp} — vCPU identity: vcpu_id/part_id/online, aarch64_vcpu_set_id(), aarch64_current_vcpu{,_id,_part_id}().
  • src/arch/aarch64/kernel_aarch64.cpp — tags g_vcpu {part0,vcpu0} and bumps the online counter at bring-up.