To add full VMM support, the Hypervisor also needs to implement localized page tables and page table access levels. Access levels could be implemented fairly easily by having two sets of page tables for privileged and non-privileged cpu modes.
There's a few games that require CPU Paravirtualization to work unaltered, including:
- Adventures, classic complication
- Axis (although this has been patched via the Boot script, to prevent it using FIQ for extra registers)
- Blitz!
- SWIV
- OS_EnterOS needs Hypervising (coded)
- Use of MSR CPSR_cf/CPSR_all, Rx within codelets need to instead use SWI ADFFS_MSRRx - where x is the register that contains the new PSR (coded)
- Use of MRS Rx, CPSR within codelets need to instead use SWI ADFFS_MRSRx - where x is the register that needs to contain the current PSR (coded)
- ARMv4 PSR conversion code within codelets need removing as ADFFS_MSRRx /ADFFS_MRSRx can implement the ARMv3 PSR (coded)
- ADFFS_MSRR0 .. R3 need implementing (coded)
- ADFFS_MRSR0 .. R3 need implementing (coded)
- Needs space allocating within the VM to store R8-R14 for all four CPU modes (ie 4 x 8 x 4 = 128 bytes) (coded)
- Needs to store the current PSR in the banked USER R15 (coded)
- Vector_Claim_Handlers need to switch to USER, using the paravirtualized cpu mode registers
- IRQ_Vector_stack/OIRQ_Vector_stack need to move from a DA to the VM and use the VM's paravirtualized R13's
- GOARM3JIT needs to use the local USER stack before jumping into user code
- OS_FSControl needs to use the local USER stack before jumping into user code
- BASIC needs to be localized
- LDRT needs coding
- STRT needs coding
- LDM Rx,{<reglist>}^ needs to load user registers if PC not present in <reglist>
- STM Rx,{<reglist>}^ needs to store user registers if PC not present in <reglist>
- tmp_Module_stack/Otmp_Module_stack need to move from a DA to the VM and use the VM's paravirtualized R13's (optional)
- IOC_IRQ_stack needs to move from a DA to the VM and use the VM's paravirtualized R13's (optional)
Need coding as follows:
- If currently in FIQ, store R8-R14 to FIQ register bank, for all other modes store R8-R12 to USER register bank and R13-R14 to current CPU mode register bank
- If switching to FIQ restore R8-R14 from FIQ register bank, for all other modes, restore R8-R12 from USER register bank and R13-R14 from new CPU mode bank
- Set NZCV and IRQ/FIQ bits accordingly in SPSR
- Exit back via LDMFD R13!, {PC}^ to return in USER with CF bits set accordingly
Need coding as follows:
- Rx=(SPSR & (%1111 << 28)) | ((SPSR & %11000000) << 20) | <new CPU mode>
For full VMM support, it would be preferable to replace instructions that require codelets with Hypercalls and then emulate the instruction. This would be substantially slower, but removes the complication of codelet management.
NOTE: Although I coded a lot of this back in 2016, I removed the code so I could progress other development. At some point I'll revisit this.