Review of the stage-8 hang (code reading plus Linux evidence):
- The breadcrumb does not prove the hang is in our own map(): the window between step 8 and 9 also covers WindowServer opening the newly registered framebuffer and IOFramebuffer's console takeover. WindowServer was crash-looping every 10 s when the framebuffer appeared (~84 s after boot).
- A WC mapping of the firmware framebuffer is not unsafe in itself: Linux simpledrm scanned out of 0x70800000-0x7179ffff (BOOTFB) for ~15 minutes on this machine before i915 loaded. Candidate on XNU: the video console maps the same pages uncached (VM_WIMG_IO) and keeps writing under -v, so a write-combined alias is an undefined memory-type alias.
- IOFBDependentID/Index 4 set while no NVRM framebuffer exists (with -nvoff) leaves an IOFBController with no index 0; IOGraphics dereferences fFbs[0] in asyncWork. To be fixed in the next NMIntelFB build (set them only when NVRM is up, and before IOFramebuffer::start).
- Also to change: release the BAR0 mapping right after the register reads; class name without "Intel" (CoreDisplay vendor sniff).
NMIntelFB is parked while #14's simpler fix is tested: if Apple's IONDRV drives the panel, NMIntelFB is only needed for the NVIDIA copy path (#16).