universalisos/RISCV_PIKEOS_PARITY_PLAN.md

14 KiB

UniversalisOS RISC-V S-mode Paravirtualized Hypervisor — PikeOS 5.0 Parity Plan

Date: 2026-07-09
Scope: Port UniversalisOS S-mode paravirtualized hypervisor to RISC-V (RV64) on the PolarFire SoC Icicle Kit and align functionality with PikeOS 5.0, using Jailhouse, seL4, and Bao as reference implementations.
Primary reference: PikeOS 5.0 ukernel sources (ARMv7hf) under src/sources/ukernel-arm_v7hf/.
PikeOS source location: /home/fabiorafaelcoutada/portugalfuturista/universalisos/src (PikeOS 5.0 distribution).
Important: The Icicle Kit U54 cores do not implement the RISC-V H-extension. The hypervisor therefore runs in S-mode and guests run in U-mode, with privileged operations mediated by ecall hypercalls. This is a paravirtualized design, not a hardware-virtualized (type-1) design.


1. Reference Codebase Assessment

1.1 PikeOS 5.0 (universalisos/src)

  • Status in source drop: ARMv7/ARMv8, PowerPC e500/e500mc/e5500, x86-64 ukernels are present.
  • RISC-V status: Only toolchain/RPM target macros exist (config/rpm/targets/riscv_rv64-linux); no ukernel source tree for RISC-V in this drop.
  • Hypervisor model: ARM-centric (p4hwvirt headers, hwvirt-linux guest drivers, HVC protocol).
  • What we reuse for RISC-V (S-mode paravirtualized):
    • Partition/resource model (respart.c, sys_respart.c).
    • Scheduling concepts (time partitioning + preemptive priority in sched.c, tps.c).
    • Memory API shape (p4map.h, p4mm.h).
    • Health monitoring / safety patterns (hm.c).
    • KDEV device framework shape.
    • Note: PikeOS H-extension / VS-mode concepts do not apply. We map PikeOS "task" to our "partition" and PikeOS "thread" to our "task" (schedulable entity).

1.2 Bao Hypervisor (reference for H-extension platforms)

  • Strengths: Complete RISC-V H-extension type-1 static partitioning hypervisor; clean separation of portable core and arch code.
  • Mechanisms we adopt where applicable:
    • Sv39 page-table allocator and TLB management.
    • SBI ecall proxy for guest OS compatibility.
    • PLIC interrupt handling.
    • 1:1 vCPU-to-pCPU assignment with static scheduling.
    • Not applicable: hstatus, hedeleg, hideleg, hgatp, hvip, VS-mode CSRs, two-stage translation, vPLIC / APLIC / AIA, RISC-V IOMMU — the Icicle Kit lacks the H-extension.

1.3 Jailhouse

  • Strengths: Static partitioning, cell abstraction, comm regions, PCI pass-through, IVSHMEM.
  • RISC-V status: No RISC-V support.
  • Mechanisms we adopt:
    • Cell-based static partitioning config.
    • Per-cell comm region / hypercall ABI.
    • Device assignment and IOMMU integration patterns.
    • Memory region flags and loadable region semantics.

1.4 seL4

  • Strengths: Verified microkernel, RISC-V S-mode support, capability-based security.
  • Hypervisor status: No RISC-V H-extension; guest virtualization would be userland VMM.
  • Mechanisms we adopt:
    • Capability-based access control (already present in cap/).
    • ASID management and TLB invalidation patterns.
    • Trap entry/exit assembly discipline.

2. PikeOS 5.0 → RISC-V S-mode Paravirtualized Feature Parity Map

PikeOS 5.0 Feature UniversalisOS ARM Status RISC-V Target Reference Files Priority
S-mode bare-metal boot Working M-mode trampoline → S-mode (firmware=none) boot.S, trap.S P0
Exception/trap handling Framework S-mode trap vector + U-mode ecall hypercall trap.S, exceptions.cpp P0
UART console (NS16550a) PL011 NS16550a (Icicle MMUART0) uart.cpp P0
MMU / page tables Section map Sv39 identity + per-partition page tables page_table.cpp P0
Address-space isolation PoC Per-partition SATP (no VMID/ASID needed) vm.cpp, memory.cpp P0
Interrupt controller GICv2 Physical PLIC + paravirtualized IRQ routing plic.cpp P0
Timer tick Generic Timer CLINT mtimecmp (1 MHz) timer.cpp P0
Context switch ⚠️ Partial Task trap-frame save/restore + sret to U-mode context_switch_asm.S P0
Guest virtual time ⚠️ Framework virtual_time + virtual_timer_deadline per partition vm.cpp, hypercall.cpp P1
Guest OS boot ⚠️ Framework Load raw image, set a0/a1, sret to U-mode guest_loader.cpp, vm.cpp P1
Device pass-through ⚠️ Framework MMIO mapped into guest SATP (no emulation) vm.cpp P1
Scheduling (RMS/DMS/ARINC 653) ⚠️ Framework PikeOS-style time-partition + priority scheduler task_sched.cpp P1
Inter-partition communication ⚠️ Stub Shared memory + doorbell IRQ (future) P2
Safety monitoring / HM ⚠️ Stub Health monitor events/actions hm.cpp P2
PikeOS API (p4_* / uos_*) ⚠️ Stub Map to RISC-V ecall hypercalls hypercall.cpp P2
Tooling / XSD codegen ⚠️ Stub Extend manifest generator for RISC-V PikeOS xsdgen/ P3

3. RISC-V Architecture Strategy

3.1 Privilege Mode

  • Hypervisor runs in RISC-V S-mode (Supervisor mode).
  • Previous boot stage is either OpenSBI in M-mode (firmware path) or direct QEMU entry in M-mode (firmware=none).
  • In the M-mode case, a tiny trampoline sets PMP, delegates exceptions/interrupts to S-mode, and srets to _start_smode.
  • Guests run in U-mode (User mode) with their own satp page tables.
  • No H-extension: All privileged operations are mediated by ecall hypercalls.

3.2 Required RISC-V Extensions

  • rv64imac base (U54 cores do not implement F/D).
  • H-extension NOT available on Icicle Kit U54 cores.
  • Zicsr, Zifencei.
  • Optional: Sstc (per-hart timer), Svpbmt (PMA in PTEs) — not present on U54.

3.3 Memory Layout (Icicle Kit)

  • Hypervisor loaded at 0x8020_0000.
  • RAM: 0x8000_00000xBFFF_FFFF (1 GiB low DDR).
  • PLIC: 0x0C00_0000.
  • CLINT: 0x0200_0000.
  • MMUART0 (NS16550a): 0x2000_0000.

3.4 Address-Space Isolation

  • Hypervisor uses satp with Sv39 identity map (_boot_l1_pt).
  • Each guest partition uses its own satp with a private Sv39 root page table.
  • No two-stage translation (no hgatp). Guest physical = host physical for mapped regions.

4. Implementation Roadmap

Phase A — RISC-V S-mode Paravirtualized Foundation COMPLETE

  • Reference analysis (PikeOS, Bao, Jailhouse, seL4).
  • M-mode trampoline → S-mode boot (arch/riscv/boot.S).
  • NS16550a UART driver (arch/riscv/uart.cpp).
  • Sv39 page-table allocator (arch/riscv/page_table.cpp).
  • S-mode trap vector (arch/riscv/trap.S) and C handler (arch/riscv/exceptions.cpp).
  • CLINT timer (arch/riscv/timer.cpp) + PLIC skeleton (arch/riscv/plic.cpp).
  • Task context structure (arch/riscv/vm.h) and assembly save/restore (arch/riscv/context_switch_asm.S).
  • Makefile ARCH=riscv target.
  • Per-hart kernel stack in trap frame (kernel_sp field).
  • Scheduler ready-queue fix (in_ready_queue flag).
  • Guest virtual time / timer hypercall.
  • Paravirtualized IRQ routing (riscv_plic_route_irq).
  • Console hypercall with guest-VA translation.
  • Memory map/unmap hypercalls.
  • Partition reset / yield / IPI hypercalls.
  • Multi-partition scheduling (time-partition windows).

Phase B — PikeOS Parity Core 🔄 IN PROGRESS

  • PikeOS-style scheduler with time partitions / windows (arch/riscv/task_sched.cpp/h).
  • PikeOS-style memory map API (arch/riscv/memory.cpp/h).
  • Health monitoring hooks (arch/riscv/hm.cpp/h).
  • Guest image loading / boot (arch/riscv/guest_loader.cpp/h).
  • Paravirtualized PLIC IRQ routing to guests.
  • Guest device tree generation (not needed for paravirtualized guests).
  • Port partition lifecycle (partition.c) — mapped to vm.cpp.
  • PikeOS API syscall mapping on RISC-V ecall — partial in hypercall.cpp.

5. Files Added / Modified in This Session

New files

  • kernel/src/arch/riscv/csr.h
  • kernel/src/arch/riscv/page_table.h
  • kernel/src/arch/riscv/page_table.cpp
  • kernel/src/arch/riscv/trap.S
  • kernel/src/arch/riscv/cpu.h
  • kernel/src/arch/riscv/cpu.cpp
  • kernel/src/arch/riscv/vm.h
  • kernel/src/arch/riscv/vm.cpp
  • kernel/src/arch/riscv/context_switch_asm.S
  • kernel/src/arch/riscv/context_switch.cpp
  • kernel/src/arch/riscv/timer.h
  • kernel/src/arch/riscv/timer.cpp
  • kernel/src/arch/riscv/plic.h
  • kernel/src/arch/riscv/plic.cpp
  • kernel/src/arch/riscv/sbi.h
  • kernel/src/arch/riscv/sbi.cpp
  • kernel/src/arch/riscv/task_sched.h
  • kernel/src/arch/riscv/task_sched.cpp
  • kernel/src/arch/riscv/memory.h
  • kernel/src/arch/riscv/memory.cpp
  • kernel/src/arch/riscv/hm.h
  • kernel/src/arch/riscv/hm.cpp
  • kernel/src/arch/riscv/guest_loader.h
  • kernel/src/arch/riscv/guest_loader.cpp
  • kernel/src/arch/riscv/hypercall.h
  • kernel/src/arch/riscv/hypercall.cpp
  • kernel/src/arch/riscv/exceptions.h
  • kernel/src/arch/riscv/exceptions.cpp
  • kernel/src/arch/riscv/smp.h
  • kernel/src/arch/riscv/smp.cpp
  • kernel/src/arch/riscv/boot.S
  • kernel/src/arch/riscv/linker_polarfire.ld
  • kernel/src/arch/riscv/uart.h
  • kernel/src/arch/riscv/uart.cpp
  • kernel/src/arch/riscv/board_icicle.h
  • kernel/src/arch/riscv/kernel.cpp

Renamed files (old → new)

  • kernel_riscv.cppkernel.cpp
  • sched_pikeos.cpptask_sched.cpp
  • sched_pikeos.htask_sched.h
  • mem_pikeos.cppmemory.cpp
  • mem_pikeos.hmemory.h
  • guest_boot.cppguest_loader.cpp
  • guest_boot.hguest_loader.h
  • hcall.cpphypercall.cpp
  • hcall.hhypercall.h

6. Notes & Risks

  1. S-mode paravirtualized design: The Icicle Kit U54 cores lack the H-extension. The hypervisor runs in S-mode, guests in U-mode, and all privileged operations are mediated by ecall. This is a different architecture from the HS-mode / VS-mode design originally planned.
  2. No RISC-V toolchain in current environment: riscv64-unknown-elf-g++ / qemu-system-riscv64 are not installed in this environment. Code is written for cross-compilation on a host with the toolchain; syntax correctness has not been verified locally.
  3. PikeOS RISC-V source absent: We cannot copy PikeOS RISC-V code; we implement equivalent behavior using PikeOS ARM ukernel patterns and align data structures with PikeOS semantics.
  4. QEMU firmware=none path: The M-mode trampoline in boot.S handles direct QEMU entry. When using OpenSBI, the firmware path skips the trampoline and enters directly in S-mode.
  5. Secondary harts: Currently parked in wfi loops. Per-hart scheduler state and SMP scheduling are future work.

7. File-Level PikeOS → RISC-V S-mode Mapping

PikeOS 5.0 Source (ARM ukernel) RISC-V UniversalisOS Equivalent Notes
sources/ukernel-arm_v7hf/src/main.c arch/riscv/kernel.cpp Bare-metal entry, subsystem init.
sources/ukernel-arm_v7hf/arch/arm/src/aexcpt.S arch/riscv/trap.S Trap entry/exit (S-mode).
sources/ukernel-arm_v7hf/arch/arm/src/cexcpt.c arch/riscv/exceptions.cpp C trap dispatch (U-mode ecall → hypercall).
sources/ukernel-arm_v7hf/arch/arm/src/mmu.c arch/riscv/page_table.cpp Sv39 page tables (no G-stage).
sources/ukernel-arm_v7hf/src/sched.c / tps.c arch/riscv/task_sched.cpp Time partitioning + priority scheduler.
sources/ukernel-arm_v7hf/src/int.c arch/riscv/plic.cpp Physical PLIC + paravirtualized IRQ routing.
sources/ukernel-arm_v7hf/src/task.c / thread.c arch/riscv/vm.cpp Partition / task lifecycle.
sources/ukernel-arm_v7hf/src/respart.c respart.cpp (future) Physical partition allocator (architecture-neutral).
sources/ukernel-arm_v7hf/src/uos_kdev_*.c TBD Kernel device framework.
sources/ukernel-arm_v7hf/src/hm.c arch/riscv/hm.cpp Health monitoring / safety.

8. Build & Run Commands

# ARM build (default, verified working)
cd /home/fabiorafaelcoutada/portugalfuturista/universalisos/kernel
make ARCH=arm clean && make ARCH=arm

# RISC-V build (requires riscv64-unknown-elf-g++ and qemu-system-riscv64)
make ARCH=riscv clean && make ARCH=riscv
make ARCH=riscv run

9. Known Limitations of This Session

  1. No RISC-V toolchain in this environment: The code is written against the RISC-V ISA and has not been compiled or executed here. Syntax/semantics errors may exist.
  2. Guest execution is not yet exercised: riscv_task_run() sets up satp and enters U-mode via sret, but a real guest image and MMIO emulation path are still TODO.
  3. Device pass-through is skeletal: Only the PLIC and UART drivers are present; IOMMU, virtio, and PCI are not implemented.
  4. PikeOS API parity is partial: Only the capability and resource-partition foundations are shared with the ARM build; the full uos_*/p4_* API surface is still being mapped.
  5. SMP is not active for RISC-V: Secondary harts park; per-hart scheduler state and SMP scheduling are future work.
  6. No H-extension: The Icicle Kit U54 cores do not implement the RISC-V H-extension. The design is S-mode paravirtualized, not type-1 hardware-virtualized.

10. Next Immediate Steps

  1. Install/obtain riscv64-unknown-elf-g++ and qemu-system-riscv64 and fix any compile errors.
  2. Provide a minimal guest image (e.g., a tiny bare-metal RV64 binary) and test riscv_task_run().
  3. Implement paravirtualized virtio-console or block device so guests can perform I/O.
  4. Port the PikeOS p4_* API surface to RISC-V ecall hypercalls.
  5. Map PikeOS respart.c, task.c, and hm.c semantics onto the RISC-V S-mode paravirtualized model.