qemu-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

RE: Emulating Solaris 10 on SPARC64 sun4u


From: BALATON Zoltan
Subject: RE: Emulating Solaris 10 on SPARC64 sun4u
Date: Fri, 28 Feb 2020 23:05:00 +0100 (CET)
User-agent: Alpine 2.22 (BSF 395 2020-01-19)

On Wed, 19 Feb 2020, BALATON Zoltan wrote:
On Wed, 19 Feb 2020, BALATON Zoltan wrote:
faster or doing something differently? Does someone know what interrupts are generated on real hardware in DMA mode so we can compare that to what we see with QEMU?

The document Programming Interface for Bus Master IDE Controller, Revision 1.0 (5/16/94) has some info on this. AFAIU it says that after DMA operation is completed an IRQ should be raised. On page 5, section 3.1. Data Synchronization it says:

"Another way to view this requirement is that the first read to the controller Status register in response to the IDE device interrupt must return with the Interrupt bit set and with the guarantee that all buffered data has been written to memory."

Not sure if this is relevant but how is it handled in QEMU? Is the right interrupt bit set after DMA transfer is done? If so is it the one that's checked by the OS driver?

I think I now understand the problem with via-ide at least and the following is true for that case. I'm not sure about the CMD646 but it may be similar as these seem to be similar designs or maybe even related somehow. The problem in my case stems from that the device has two modes documented: legacy where it uses standard ISA ioports and INT14 and 15 for the two channels and native mode in which it uses PCI BARs for io address and an IRQ configurable via PCI_INTERRUPT_LINE (config reg 9). It seems the IRQ in native mode is still not a PCI INT line but an ISA IRQ, however it can be selected by config reg and it's a single interrupt instead of two for separate channels (Linux prints these during boot so that's a good way to check which mode it thinks it's using). That's so far is complex enough to not be easy to emulate in QEMU as we can set up legacy ISA ports with ide_init_ioport() but there's no way then to switch it off so via-ide either implemented legacy or native mode but can't correctly switch between those. This may not be a problem most of the time for Linux at least which tries to check which mode the controller is in and use that so it would work with whatever is there as long as the regs match what's emulated so we can just emulate one mode and still work.

But all of the above is further complicated by that on some (most?) boards there's also a "non 100% native mode" in which the io addresses are taken from the PCI BARs but still using hardcoded INT14 and 15, ignoring the setting in PCI_INTERRUPT_LINE. So guest drivers may assume this without checking regs and not care about what's set in PCI_INTERRUPT_LINE just expect interrupts on INT14 and 15. If the emulation raises PCI INT or some other isa interrupt it won't work, even if config regs correctly describe the difference following the docs but guest drivers don't care about the chip spec only the implementation on the board they meant to run on. Unfortunately different guests use different heuristics and workarounds (even Linux does so on different archs) so it's not easy to make an emulation that works with all. The pegasos2 firmware for example sets via-ide in native mode and assigns interrupt 9 but on real hardware this reg seems to be hardcoded to 14 and Linux uses this to detect if it needs to use the half-native mode but sets the mode reg to legacy to note this despite then using PCI BARs (so we can't hardcode mode reg to always native without breaking this but have to force int reg and emulate half native mode to work with other guests). Linux would also work with 100% native mode with IRQ9 but Amiga like OSes don't seem to care and just use hardcoded half-native mode regardless of config regs and expect interrupt on IRQ14 and 15. I could make a patch to work with all these on pegasos2 but the via-ide is also used on a mips board where the corresponding Linux version also applies its own (different) workarounds corresponding to the quirks of that board and ends up either trying to use legacy mode (which is not emulated as io is only on PCI BARs) or trying to use 100% native mode which does not work with half-native interrupts. I think I'll need to add a special property to the device to set it to half-native for pegasos2 and leave it 100% native for mips, otherwise there may not be a combination which works with all these firmwares and guests on both machines. (We still can avoid having to implement native mode as well but I can imagine if some PC guests were involved we may need that too but on these ppc and mips boards and also in your case I think native and half-native modes should be enough as that's all guests use.)

The CMD646 case might be similar and that's also used on a hppa board so you may need to check with that too if you make changes. To check this theory you might try forcing ide interrupts to be IRQ14 and 15 via something like:

qemu_set_irq(isa_get_irq(NULL, (channel ? 15 : 14)), level);

instead of using PCI interrupt or configured ISA interrupt in native mode and see if Solaris likes it better. If so then go on a quest to find a combination that works with at least Linux on both the sparc and hppa boards and Solaris (if that's not enough you can also try NeXTSTEP :-) ). So I think after all the common ide and bmdma code is probably OK and we have problems in individual controller emulations which is made difficult because of different hardware quirks and assumptions of guest sofware.

Regards,
BALATON Zoltan




reply via email to

[Prev in Thread] Current Thread [Next in Thread]