qemu-block
[Top][All Lists]
Advanced

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

Re: [PATCH 2/2] via-ide: Also emulate non 100% native mode


From: BALATON Zoltan
Subject: Re: [PATCH 2/2] via-ide: Also emulate non 100% native mode
Date: Mon, 2 Mar 2020 22:40:14 +0100 (CET)
User-agent: Alpine 2.22 (BSF 395 2020-01-19)

On Mon, 2 Mar 2020, Mark Cave-Ayland wrote:
On 01/03/2020 21:30, BALATON Zoltan wrote:
On Sun, 1 Mar 2020, Mark Cave-Ayland wrote:
On 01/03/2020 18:53, BALATON Zoltan wrote:
On Sun, 1 Mar 2020, BALATON Zoltan wrote:
is not legacy mode but "not 100% native mode". The prog-if is set to 0x8a which
corresponds to native mode but this is what the Linux fixup function does, 
firmware
sets it to 0x8f which means native mode.

I mean, 0x8a legacy mode and 0x8f native mode, I see firmware poking 0x8f and 
Amiga
like OSes reading that yet expecting legacy interrupts. Linux fixes up prog-if 
so its
driver detects legacy interrupts but still uses ioports from PCI BARs.

I see. Note that it is also possible to have a prog-if value of 0x80 which is 
where
the hardware is locked into legacy mode via a pull-down resistor. Perhaps this 
is the
case for Pegasos, since it would explain why attempts to switch the mode via 
prog-if
are ignored?

I've seen such option in CMD646 docs but couldn't find similar in VT8231. 
Genesi has
published the schematics of Pegasos II (linked from my
https://osdn.net/projects/qmiga/wiki/SubprojectPegasos2 page) so we could check 
if
you can tell which pin is that. But we get 0x8a in Linux lspci output on real
hardware for prog-if which is explained by firmare setting it to 0x8f then Linux
fixup function clearing bits 0 and 2 so does not seem it started as 0x80 
because then
firmware should not be able to set it to 0x8f either.

I had a quick look at the schematics linked from the page above, and they 
confirm
that the VIA IDE interface is connected directly to IRQs 14 and 15 and not to 
the PCI
interrupt pins.

Where did you see that? What I got from trying to look this up in the schematics was that VT8231 has two pins named IRQ14 and IRQ15 (but described as Primary and Secondary Channel Interrupt Request in doc) where the interrupt lines of the two IDE ports/channels are connected but how they are routed within the chip after that was not clear. The chip doc says that in native mode the interrupt should be configurable and use a single interrupt for both channels and in legacy mode they use the usual 14 and 15 but this is not what guest drivers expect so I think not how really works on PegasosII. It is true however that connection to PCI interrupts aren't mentioned so it always uses ISA IRQ numbers, it just depends on legacy vs. native mode which line is raised. But that was never really a question for VT8231 and maybe only CMD646 could have such interconnection with PCI interrupts. (Proabable reason is that via-ide is part of a southbridge chip where it has connections to ISA bus while CMD646 is a PCI IDE controller but I could be wrong as my knowledge is limited about these.)

So on that basis the best explanation as to what is happening is the
comment in the link you provided here:
https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git/tree/arch/powerpc/platforms/chrp/pci.c?h=v4.14.172#n353

/* Pegasos2 firmware version 20040810 configures the built-in IDE controller
* in legacy mode, but sets the PCI registers to PCI native mode.
* The chip can only operate in legacy mode, so force the PCI class into legacy
* mode as well. The same fixup must be done to the class-code property in
* the IDE node /pci@80000000/ide@C,1
*/

I'm not sure that it makes much sense that the firmware configures the chip one way then puts info about a different way in the device tree. There could be bugs but this is not likely. Especially because I see in traces that the firmware does try to configure the device in native mode. These are the first few accesses of the firmware to via-ide:

pci_cfg_write via-ide 12:1 @0x9 <- 0xf
pci_cfg_write via-ide 12:1 @0x40 <- 0xb
pci_cfg_write via-ide 12:1 @0x41 <- 0xf2
pci_cfg_write via-ide 12:1 @0x43 <- 0x35
pci_cfg_write via-ide 12:1 @0x44 <- 0x18
pci_cfg_write via-ide 12:1 @0x45 <- 0x1c
pci_cfg_write via-ide 12:1 @0x46 <- 0xc0
pci_cfg_write via-ide 12:1 @0x50 <- 0x17171717
pci_cfg_write via-ide 12:1 @0x54 <- 0x14
pci_cfg_read via-ide 12:1 @0x0 -> 0x5711106
pci_cfg_read via-ide 12:1 @0x0 -> 0x5711106
pci_cfg_read via-ide 12:1 @0x8 -> 0x1018f06
pci_cfg_read via-ide 12:1 @0xc -> 0x0
pci_cfg_read via-ide 12:1 @0x2c -> 0x11001af4
pci_cfg_read via-ide 12:1 @0x3c -> 0x10e
pci_cfg_read via-ide 12:1 @0x4 -> 0x2800080
pci_cfg_read via-ide 12:1 @0x3c -> 0x10e
pci_cfg_write via-ide 12:1 @0x3c <- 0x109

The very first write is to turn on native mode, so I think it's not about what the firmware does but something about how hardware is wired on Pegasos II or the VT8231 chip itself that only allows legacy interrupts instead of 100% native mode for IDE.

Given that the DT is wrong, then we should assume that all OSs would have to
compensate for this in the same way as Linux, and therefore this should be 
handled
automatically.

AFAICT this then only leaves the question: why does the firmware set
PCI_INTERRUPT_LINE to 9, which is presumably why you are seeing problems running
MorphOS under QEMU.

Linux does try to handle both true native mode and half-native mode. It only uses half-native mode if finds IRQ14 on Pegasos, otherwise skips Pegasos specific fixup and uses true native mode setup. I don't know what MorphOS does but I think it justs knows that Pegasos2 has this quirk and does not look at the device tree at all.

Could it be that setting prog-if to 0x8a legacy mode also resets 
PCI_INTERRUPT_LINE
to 14? You should be able to confirm this easily on real hardware using the 
Forth
config-* words on the IDE node and reading the prog-if byte before and after.

I don't have direct access to real hardware and would also need to come up with some Forth to verify that but given the above trace that the firmware does before we can enter any Forth we would likely find @0x9 = 0x8f and @0x3c = 0x0e because after booting Linux we see 0x8a and 0x0e and Linux only touches the two mode bits.

So I don't know the ultimate reason why it works that way but I'm quite sure that this emulation is close enough and guests are happy with it too.

Regards,
BALATON Zoltan



reply via email to

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