On Thu, 8 Aug 2019, Jd Lyons wrote:
I’m 99% sure this is the trouble, I don’’t really understand IRQ’s and interrupts, there is some info in the Rage_128_register_referance_guide.
OK we might be onto something but still don't understand what exactly is missing and just adding the property may be enough to get the NDRV load but then probably will hang eventually if it relies on the device generating interrupts which we don't emulate. I don't know either how IRQ is used in Rage128P and haven't checked the docs but in general a device can have an interrupt line that it can use to send interrupt request to the CPU when it needs attention (such as finished with an async task, some buffer is full or empty, etc.). These are likely settable in the device's registers to tell it when to generate interrupt so we should implement that functionality. But it's likely we don't even emulate the function that should generate an interrupt yet as the emulation is very simple currently so first that function needs to be implemented so we can implement an interrupt.
I tested my theory via OS X 10.4.11and it mapped the VRAM rather than giving me the ATY:Not Usable, it also changed the screen resolution twice, once to 640x480 then to 1280x960.
dev /pci/@f “ /pci/@f” select-dev “ ATY,Rage128Pd” encode-string “ name” property 1 encode-int “ interrupts” property boot
OS X would not be able to change the screen resolution if the ‘NDRV’ didn’t load!!!
So I’m 99% sure this is the trouble and we need to figure out how to create a mapped interrupt for the card, rather than this dummy Interrupt I create because I’m a dummy;-)
MacOS does not like the above. With sufficiently large debug level it gives me:
Copying peer property 'interrupts' stored at 0x1FB28484 ---------------- Node 'usb' has 1 interrupt(s). ---------------- Processing unit_interrupt_specifier: Raw unit_int_specifier : 00006800 00000000 00000000 00000001 Interrupt-map-mask values: 00FFF800 00000000 00000000 00000007
Comparing interrupt-map entries to this unit_interrupt_specifier:
Masked unit_int_specifier: 00006800 00000000 00000000 00000001 Interrupt-map child spec : 00006800 00000000 00000000 00000001 New unit_int_specifier : 0000001C 00000001
unit_interrupt_specifer[0] = 28 (ua_size = 0, is_size = 2) setting edge[0] to 0 OpenPIC setup: vectorIndex 13, intSource 28, level 2, sense 1, polarity 0
This is for comparison for the USB controller where it works, then with above dummy interrupts property for ati-vga (after running FCode ROM and adding interrupts property as above):
Copying device node peer 'ATY,Rage128Ps' of node at 0x1FAD8270. device_type 'display': Matched parcel 'cofb', device_type 'display'. Copying first property 'name' stored at 0x1FB28824, devNode 0x1FAD8288 Copying peer property 'vendor-id' stored at 0x1FB2885C Copying peer property 'device-id' stored at 0x1FB28888 Copying peer property 'revision-id' stored at 0x1FB288B4 Copying peer property 'class-code' stored at 0x1FB288E0 Copying peer property 'min-grant' stored at 0x1FB2890C Copying peer property 'max-latency' stored at 0x1FB28938 Copying peer property 'devsel-speed' stored at 0x1FB28964 Copying peer property 'subsystem-vendor-id' stored at 0x1FB28990 Copying peer property 'subsystem-id' stored at 0x1FB289BC Copying peer property 'cache-line-size' stored at 0x1FB289E8 Copying peer property 'device_type' stored at 0x1FB28A14 Copying peer property 'model' stored at 0x1FB28A44 Copying peer property 'compatible' stored at 0x1FB28A7C Copying peer property 'assigned-addresses' stored at 0x1FB28AA8 Creating property - 'AAPL,address' (size = 12) Creating property 'AAPL,address' (size = 0xC); stored at 0x1FB28B0C. Belongs to devNode 0x1FAD8288 Copying peer property 'reg' stored at 0x1FB28B40 Copying peer property 'width' stored at 0x1FB28BB8 Copying peer property 'height' stored at 0x1FB28BE4 Copying peer property 'depth' stored at 0x1FB28C10 Copying peer property 'linebytes' stored at 0x1FB28C3C Copying peer property 'interrupts' stored at 0x1FB28C68 ---------------- Node 'ATY,Rage128Ps' has 1 interrupt(s). ---------------- Processing unit_interrupt_specifier: Raw unit_int_specifier : 00007000 00000000 00000000 00000001 Interrupt-map-mask values: 00FFF800 00000000 00000000 00000007
Comparing interrupt-map entries to this unit_interrupt_specifier:
Masked unit_int_specifier: 00007000 00000000 00000000 00000001 Interrupt-map child spec : 00006800 00000000 00000000 00000001 ******************* MacOS: Fatal Error! (0xF3B37FDB) ******************* ***** MacOS: the following error causes your machine not to be able to boot: ***** ***** MacOS: unit-interrupt-specifier for 'ATY,Rage128Ps' not found in map. ***** unit_interrupt_specifer[3] = 1 (ua_size = 3, is_size = 1) setting edge[0] to 0 OpenPIC setup: vectorIndex 14, intSource 1, level 2, sense 1, polarity 0 Copying peer property 'address' stored at 0x1FB28D44 Copying peer property 'ATY,Status' stored at 0x1FB28D70 Copying peer property 'ATY,Flags' stored at 0x1FB28D9C Copying peer property 'EDID' stored at 0x1FB28DC8 Copying peer property 'character-set' stored at 0x1FB28E70 Copying peer property 'AGP_Address_Range' stored at 0x1FB28EA4 Copying peer property 'AGP_Address_Block' stored at 0x1FB28ED4 Copying peer property 'AGP_Alignment' stored at 0x1FB28F00 Copying peer property 'AGP_AllowOverlap' stored at 0x1FB28F2C Copying peer property 'ATY,Rom#' stored at 0x1FB28F58 Copying peer property 'ATY,Card#' stored at 0x1FB28F90 Copying peer property 'ATY,Fcode' stored at 0x1FB28FC8 Copying peer property 'driver,AAPL,MacOS,PowerPC' stored at 0x1FB28FF8 node 'ATY,Rage128Ps': Did NOT replace property 'driver,AAPL,MacOS,PowerPC'. Copying peer property 'stdin' stored at 0x1FB3DB58 Copying peer property 'stdout' stored at 0x1FB3DB84 Copying peer property 'supports-bootinfo' stored at 0x1FB3DBB0 node 'ATY,Rage128Ps': Property NOT added (already loaded) 'driver,AAPL,MacOS,PowerPC'.
then booting stops later due to the above error. So we need to make sure these properties match with whatever they should match.
This interrupts property should be added by OpenBIOS if the card specifies it uses an IRQ, this is done in drivers/pci.c::ob_pci_configure_irq() if I understood that right. That looks at the config of the PCI device (see https://wiki.osdev.org/PCI). We can patch ati-vga in QEMU to say it uses an IRQ:
diff --git a/hw/display/ati.c b/hw/display/ati.c index 84961d193f..d89153a826 100644 --- a/hw/display/ati.c +++ b/hw/display/ati.c @@ -902,6 +910,9 @@ static void ati_vga_realize(PCIDevice *dev, Error **errp) pci_register_bar(dev, 0, PCI_BASE_ADDRESS_MEM_PREFETCH, &vga->vram); pci_register_bar(dev, 1, PCI_BASE_ADDRESS_SPACE_IO, &s->io); pci_register_bar(dev, 2, PCI_BASE_ADDRESS_SPACE_MEMORY, &s->mm); + + /* interrupt not yet emulated but MacOS driver needs it to load */ + dev->config[PCI_INTERRUPT_PIN] = 1; }
Then OpenBIOS adds the interrupts property and I don't get the above fatal error:
---------------- Node 'ATY,Rage128Ps' has 1 interrupt(s). ---------------- Processing unit_interrupt_specifier: Raw unit_int_specifier : 00007000 00000000 00000000 00000001 Interrupt-map-mask values: 00FFF800 00000000 00000000 00000007
Comparing interrupt-map entries to this unit_interrupt_specifier:
Masked unit_int_specifier: 00007000 00000000 00000000 00000001 Interrupt-map child spec : 00006800 00000000 00000000 00000001 Interrupt-map child spec : 00007000 00000000 00000000 00000001 New unit_int_specifier : 0000001D 00000001
unit_interrupt_specifer[0] = 29 (ua_size = 0, is_size = 2) setting edge[0] to 0 OpenPIC setup: vectorIndex 14, intSource 29, level 2, sense 1, polarity 0
Then it tries to switch mode but programs wrong values for resolution before reading EDID info and after reading EDID it does not program new values but hangs around where it exited before:
ati_mm_write 1 0x68 GPIO_MONID <- 0x0 ati_mm_write 1 0x6b GPIO_MONID <- 0x7 ati_mm_write 1 0x6a GPIO_MONID <- 0x0 ati_mm_write 1 0x52 CRTC_GEN_CNTL <- 0x9 ati_mm_write 1 0x271 CUR_CLR1 <- 0x0 ati_mm_write 1 0x272 CUR_CLR1 <- 0x0 ati_mm_write 1 0x52 CRTC_GEN_CNTL <- 0x9 ati_mm_write 1 0x52 CRTC_GEN_CNTL <- 0x9 ati_mm_write 1 0x271 CUR_CLR1 <- 0x0 ati_mm_write 1 0x272 CUR_CLR1 <- 0x0 ati_mm_write 1 0x52 CRTC_GEN_CNTL <- 0x9 ati_mm_write 1 0x52 CRTC_GEN_CNTL <- 0x9 ati_mm_write 1 0x271 CUR_CLR1 <- 0x0 ati_mm_write 1 0x272 CUR_CLR1 <- 0x0 ati_mm_write 1 0x52 CRTC_GEN_CNTL <- 0x9 ati_mm_write 1 0x52 CRTC_GEN_CNTL <- 0x9 ati_mm_write 1 0x271 CUR_CLR1 <- 0x0 ati_mm_write 1 0x272 CUR_CLR1 <- 0x0 ati_mm_write 1 0x52 CRTC_GEN_CNTL <- 0x9 Extend free pool: phys 0x1ffb5000 virt 0x00000000 count: 11 ati_mm_write 1 0x52 CRTC_GEN_CNTL <- 0x9 ati_mm_write 1 0x271 CUR_CLR1 <- 0x0 ati_mm_write 1 0x272 CUR_CLR1 <- 0x0 ati_mm_write 1 0x52 CRTC_GEN_CNTL <- 0x9 ati_mm_read 4 0x100 CONFIG_APER_0_BASE -> 0x81000000
Then does not boot further from here so you can keep continue guessing why it hangs (maybe waiting for an interrupt?) now or check what the NDRV wants to do to understand better what we need. (I haven't tried OS X.)
Regards, BALATON Zoltan