oxidecomputer / oxidecomputer/propolis
Support PAM registers in i440fx
Nobody has claimed this yet.
- Dominant language
- Rust
- Stars
- 270
- Forks
- 42
- Avg merge
- 4d 5h
- Merged PRs (30d)
- 6
Description
I spent the afternoon debugging why a SeaBIOS ROM was wholly unable to boot under propolis. With its debugging configuration set to maximum, the ROM would not make any forward progress before falling into a loop of unhandled IO port accesses to a seemingly nonsensical address:
Sep 11 21:47:19.977 ERRO Unhandled pio In(IoPort { port: 0, bytes: 2 }), rip: 0
Sep 11 21:47:19.980 ERRO Unhandled pio In(IoPort { port: 83, bytes: 2 }), rip: 51913
Sep 11 21:47:20.055 ERRO Unhandled pio In(IoPort { port: 600, bytes: 2 }), rip: 31545
Sep 11 21:47:20.055 ERRO Unhandled pio Out(IoPort { port: 600, bytes: 1 }, ff), rip: 31533
Sep 11 21:47:20.056 ERRO Unhandled pio In(IoPort { port: 600, bytes: 2 }), rip: 31517
Sep 11 21:47:20.056 ERRO Unhandled pio Out(IoPort { port: 600, bytes: 1 }, ff), rip: 31521
Sep 11 21:47:20.056 ERRO Unhandled pio Out(IoPort { port: 600, bytes: 1 }, ff), rip: 31527
Sep 11 21:47:20.056 ERRO Unhandled pio In(IoPort { port: 600, bytes: 2 }), rip: 31517
After reading through the seabios source, I traced IO port accesses in the kernel vmm, since in theory the ROM should be accessing the CMOS (RTC) to determine if the boot was a resume or "full POST". No such access occurred, which suggested that we weren't even progressing to the early POST logic. After further reading, and single-stepping a guest during boot on an Intel machine, I came to scrutinize the literal first instruction of the ROM:
reset_vector:
ljmpw $SEG_BIOS, $entry_post
... and ...
#define SEG_BIOS 0xf000
This long-jmp would result in a %cs base address of 0xf0000 to use when offsetting the entry_post address. This is a bit odd, considering the ROM is mapped at 0xfffe0000 (offset for size) in order to locate the first instruction at the ISA-defined 0xfffffff0 address.
Recalling that i440fx (and some subsequent Intel chipsets like Q35) have some special remapping behavior using their "PAM" registers. Said registers can cause ranges such as 0xf0000 to alias to the ROM. I suspect we'll need to at least partially emulate such behavior in order to run SeaBIOS without significant modification.
What I believe this requires from bhyve and propolis:
- Supporting more than the low (currently 8) number of memory mappings in the guest address space
- Better handling of
VM_EXITCODE_PAGINGconditions, where a present mapping in the guest address space fails protection checks. Falling back to instruction-emulation logic for this, and eschewing thePAGINGexitcode entirely would probably be proper - Wiring up propolis to juggle the aliased mappings when the guest twiddles the PAM registers in the chipset
Contributor guide
No contributing guide indexed for this repository
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start by tracing the bhyve kernel VMM handling of guest memory mappings and VM_EXITCODE_PAGING, then inspect how propolis wires chipset register accesses into the guest address space. The issue identifies PAM registers, aliased mappings, and protection-failure fallback as the required areas. Done means SeaBIOS can boot on i440fx with PAM-controlled ROM aliases and the required mapping limits are supported.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- rust
- Domain
- operating-systems
- Issue type
- Feature
- Difficulty
- 5/5
- Estimated time
- Over a week
- Activity status
- Stale
- Clarity
- Mostly clear
- Newbie friendliness
- 25/100