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).
EINVALfor mode>3 or error-code>7.EPERMreserved 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 word0x3f. - Both IPA writes use the volatile-u32 field-store pattern (alignment-safe at
EL2, see
AARCH64_UOS_ABI.mdpitfall).GET_ERROR_STATUSwrites 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_AVAILABLEuntil then (already the default viaapex_map_rc(ENOSYS)if you add a stub call). Progress (this session): vCPU identity is now table-backed, not hardcoded.aarch64_vcpu_tgainedvcpu_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 + ag_part0_onlinecounter 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 (newaarch64_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.c—apex_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— tagsg_vcpu{part0,vcpu0} and bumps the online counter at bring-up.