Login
Username:

Password:

Remember me



Lost Password?

Register now!

Sections

Who's Online
119 user(s) are online (92 user(s) are browsing Forums)

Members: 1
Guests: 118

jarokuczi, more...

Headlines

 
  Register To Post  

« 1 2 3 (4) 5 6 7 »
Re: Qemu Pegasos II interrupts issue
Quite a regular
Quite a regular


See User information
@Hans
Quote:
The 8259 has a master and slave, and the slave is mapped through to one of the interrupt lines on the master (IRR = 2, so IRQ 1). The PCI interrupts appear to be routed to the slave (IRR = 2 as well, which is IRQ 9).

Your conclusion is probably right but just to correct the above. There are actually two 8259 PICs in a PC AT (XT had only one) and each can handle 8 interrupt inputs. The master PIC's output is connected to the CPU, the 2nd (slave) PIC's output is connected to INT2 (bit 2, value 4) of the master PIC also called the cascade interrupt that signals there's an interrupt on the slave PIC. Masking out INT2 on master will disable all interrupts >=8. IRQ9 is bit 1, value 2 on the slave so it's not the same bit on both PICs. IRQ1 on master is used by the keyboard.

There are some docs here: https://wiki.osdev.org/PIC and more links at the end of that document which have tables of which bit corresponds to what.

Quote:
So, when a PCI interrupt occurs, then bit 2 should be set on both the master and the slave.

Bit 2 on master, bit 1 on slave (counted starting from 0).

Go to top
Re: Qemu Pegasos II interrupts issue
Just popping in
Just popping in


See User information
@HansQuote:
Hans wrote:@all

Looking into this a bit more, it looks like the problem might be triggered when an interrupt from the VirtioGPU device comes in while the OS is still busy calling interrupt handlers for another device.


Another idea: maybe the OS assumes (and possibly did something to make sure) that interrupts don't nest (get called during another interrupt.), or maybe at least don't nest if it's the same interrupt (number). And this for whatever reason is ignored by Qemu.

Can anyone test on real hw if OS prevents nesting interrupts (maybe just if interrupt number is the same).

Go to top
Re: Qemu Pegasos II interrupts issue
Quite a regular
Quite a regular


See User information
@Georg
That's a vague idea. I wouldn't know what to check in QEMU without knowing what the OS might do to prevent nesting. Also how could that be tested on real hardware? So this would need to be elaborated further to be able to check that.

Go to top
Re: Qemu Pegasos II interrupts issue
Home away from home
Home away from home


See User information
@balaton

Quote:
I've asked this before but did you try if the problem also reproduces with -bios pegasos2.rom or using -machine sam460ex that does not use ISA PIC? ...

Yes, you've asked this multiple times. However, I'm currently only set up to use BBoot on Pegasos2, so there's a high switching cost. You already posted some info about what the pegasos2.rom is doing with the PIC, here.

Quote:
Your conclusion is probably right but just to correct the above. There are actually two 8259 PICs in a PC AT (XT had only one) and each can handle 8 interrupt inputs. The master PIC's output is connected to the CPU, the 2nd (slave) PIC's output is connected to INT2 (bit 2, value 4) of the master PIC also called the cascade interrupt that signals there's an interrupt on the slave PIC. Masking out INT2 on master will disable all interrupts >=8. IRQ9 is bit 1, value 2 on the slave so it's not the same bit on both PICs. IRQ1 on master is used by the keyboard.

I just realized that I was reading the master and slave round the wrong way. The master PIC is the one with "master 1" (in the logs), and I've been treating "master 0" as the master PIC.

@Georg
Quote:
Another idea: maybe the OS assumes (and possibly did something to make sure) that interrupts don't nest (get called during another interrupt.), or maybe at least don't nest if it's the same interrupt (number). And this for whatever reason is ignored by Qemu.

Can anyone test on real hw if OS prevents nesting interrupts (maybe just if interrupt number is the same).

AmigaOS disables interrupts while processing interrupts. So, an interrupt cannot interrupt an existing interrupt handler (what a mouthful...). If an interrupt comes in during that time, then it should be triggered as soon as the existing interrupt handling is done, and interrupts are enabled again.


Hans

http://hdrlab.org.nz/ - Amiga OS 4 projects, programming articles and more.
https://keasigmadelta.com/ - more of my work
Go to top
Re: Qemu Pegasos II interrupts issue
Home away from home
Home away from home


See User information
@balaton

Quote:
That sounds wrong if you want it to retrigger interrupts that were not yet serviced. I think edge mode will only trigger the interrupt once when the device signals it but does not keep the state, but I could be wrong about that.

I agree. I've captured another log, and it's very clear that it fails when the Virtio GPU interrupt is triggered when IRQ 9's bit is still high from another device. The interrupt gets missed, because the PIC is in edge mode, and there's no edge to trigger it.

I'll have a look at how the firmware and OS set up the PIC.

Hans

http://hdrlab.org.nz/ - Amiga OS 4 projects, programming articles and more.
https://keasigmadelta.com/ - more of my work
Go to top
Re: Qemu Pegasos II interrupts issue
Home away from home
Home away from home


See User information
@all
I can now confirm that the OS puts both PICs in edge triggered mode (as does the firmware).

Here are the initialization register writes from AmigaOS:
pic_ioport_write master 1 addr 0x0 val 0x11
pic_ioport_write master 1 addr 0x1 val 0x0
pic_ioport_write master 1 addr 0x1 val 0x4
pic_ioport_write master 1 addr 0x1 val 0x1

pic_ioport_write master 0 addr 0x0 val 0x11
pic_ioport_write master 0 addr 0x1 val 0x8
pic_ioport_write master 0 addr 0x1 val 0x2
pic_ioport_write master 0 addr 0x1 val 0x1


The problem is that the first write to each PIC's command register is 0x11. Bit 3 is zero, which puts the PIC in edge triggered mode.

Hans

http://hdrlab.org.nz/ - Amiga OS 4 projects, programming articles and more.
https://keasigmadelta.com/ - more of my work
Go to top
Re: Qemu Pegasos II interrupts issue
Just can't stay away
Just can't stay away


See User information
@Hans
Quote:
I can now confirm that the OS puts both PICs in edge triggered mode (as does the firmware).
Strange. On the AmigaOne it's configured only by the U-Boot firmware and can be changed in the AGP/PCI menu, and if you change the mode from the default level to edge there you get the same interrupt problems on an AmigaOne.
At least on real hardware, no idea about QEmu.

Go to top
Re: Qemu Pegasos II interrupts issue
Home away from home
Home away from home


See User information
@joerg

Yes, that surprises me too. I don't see how a shared interrupt line can work 100% properly unless it's level triggered. When it's edge triggered then there's always that narrow window where an interrupt can go missing.

This is going to need a kernel update to fix...

Hans

http://hdrlab.org.nz/ - Amiga OS 4 projects, programming articles and more.
https://keasigmadelta.com/ - more of my work
Go to top
Re: Qemu Pegasos II interrupts issue
Quite a regular
Quite a regular


See User information
@Hans
Quote:
The problem is that the first write to each PIC's command register is 0x11. Bit 3 is zero, which puts the PIC in edge triggered mode.

That's the old gobal LTIM bit that wasn't even supported by QEMU until we found MorphOS uses that. All other modern systems use a newer way that can set edge/level per interrupt line. But I don't know where is that and how to program it, I only know about that because of this commit message:
https://patchew.org/QEMU/2023030209062 ... 37-1-dwmw2@infradead.org/
So check those ELCR bits too and maybe that should be used to fix this instead of the LTIM bit, although now both should work in QEMU.

Go to top
Re: Qemu Pegasos II interrupts issue
Home away from home
Home away from home


See User information
@balaton

Quote:
So check those ELCR bits too and maybe that should be used to fix this instead of the LTIM bit, although now both should work in QEMU.

The ELCR offsets are 0x4d0, and 0x4d1. The OS is *NOT* writing to them.

I've already experimented with it, and enabling level triggered interrupts for PCI interrupts solves the problem where interrupts suddenly stop coming in.

Hans

http://hdrlab.org.nz/ - Amiga OS 4 projects, programming articles and more.
https://keasigmadelta.com/ - more of my work
Go to top
Re: Qemu Pegasos II interrupts issue
Quite a regular
Quite a regular


See User information
@Hans
Quote:
The ELCR offsets are 0x4d0, and 0x4d1. The OS is *NOT* writing to them.

Does the firmware write them? If so this may be added to BBoot. (I've traced the firmware in the post you've linked to but I don't understand what those logs mean so I can't tell if there's something done by the firmware that AmigaOS might rely on.)

Go to top
Re: Qemu Pegasos II interrupts issue
Just can't stay away
Just can't stay away


See User information
@Hans
Quote:
Yes, that surprises me too. I don't see how a shared interrupt line can work 100% properly unless it's level triggered. When it's edge triggered then there's always that narrow window where an interrupt can go missing.
On the Pegasos2 it's even worse than on the AmigaOne: Pegasos2 uses a single interrupt line for all PCI devices, while AmigaOne uses 4 different ones for the 4 AGP/PCI slots.
But even with the different IRQs for each of the AGP/PCI slots you still have IRQs shared with onboard hardware on the AmigaOne.

@balaton
Quote:
Does the firmware write them? If so this may be added to BBoot. (I've traced the firmware in the post you've linked to but I don't understand what those logs mean so I can't tell if there's something done by the firmware that AmigaOS might rely on.)
If the slightly different VIAs are similar enough you could check in the AmigaOne U-Boot sources what it does when changing the level/edge settings in the AGP/PCI menu, or since that's just a GUI the pci_irq[abcd]_select ENV variables (all AmigaOne U-Boot variables should be documented here), and add whatever it does to your BBoot.

Go to top
Re: Qemu Pegasos II interrupts issue
Quite a regular
Quite a regular


See User information
@joerg
The VIA south bridges are quite similar and the ISA PIC is an even older device that works the same way in all implementations as it has to be compatible with the original. But the source of the amigaone U-Boot is not available and nobody knows where is it. I've asked at several places for it but nobody could dig up a source. The only source available is a partial one for G3SE that was once in upstream U-Boot, but that does not include the menu parts. What's there seems to program the PIC to edge mode and have env vars for edge/level for the PCI interrupts (which is probably what the menu sets) and this is only used for setting config reg 0x54 of the ISA bridge. So if this is the same as the actual amigaone U-Boot then I wonder if this 0x54 reg overrides the ISA PIC setting or does it keep track of interrupts separately and retrigger the PIC? This register is not emulated in QEMU because I don't know if it's needed and not sure how it works. It there was some evidence about how it works on real machine I could implement that in QEMU but so far I'm not sure. This register defaults to level trigger so if unset then maybe the PCI interrupts are handled as level triggered before they are routed to the PIC so even with the PIC set to edge mode it would be retriggered by the ISA bridge? But even then that's only true for the PCI IRQ inputs and not the other internal devices that share the same interrupt so it seems to be better and the only correct way to set the PIC to level trigger.

Also if AmigaOS resets the PICs then it probably does not matter what the firmware has set it to and the OS would need to program it correctly.

Go to top
Re: Qemu Pegasos II interrupts issue
Just popping in
Just popping in


See User information
@balaton

I've found only some snippets of code from the AmigaOneG3SE u-boot source code, maybe the following code may help:

void via_init_irq_routing(uint8 irq_map[])
{
    
char *s;
    
uint8 level_edge_bits 0xf;

    
/* Set irq routings */
    
pci_write_cfg_byte(07<<30x55irq_map[0]<<4);
    
pci_write_cfg_byte(07<<30x56irq_map[1] | irq_map[2]<<4);
    
pci_write_cfg_byte(07<<30x57irq_map[3]<<4);

    
/*
     * Gather level/edge bits
     * Default is to assume level triggered
     */

    
getenv("pci_irqa_select");
    if (
&& strcmp(s"level") == 0)
    
level_edge_bits &= ~0x01;

    
getenv("pci_irqb_select");
    if (
&& strcmp(s"level") == 0)
    
level_edge_bits &= ~0x02;

    
getenv("pci_irqc_select");
    if (
&& strcmp(s"level") == 0)
    
level_edge_bits &= ~0x04;

    
getenv("pci_irqd_select");
    if (
&& strcmp(s"level") == 0)
    
level_edge_bits &= ~0x08;

    
PRINTF("IRQ map\n");
    
PRINTF("%d: %s\n"irq_map[0], level_edge_bits&0x1 "edge" "level");
    
PRINTF("%d: %s\n"irq_map[1], level_edge_bits&0x2 "edge" "level");
    
PRINTF("%d: %s\n"irq_map[2], level_edge_bits&0x4 "edge" "level");
    
PRINTF("%d: %s\n"irq_map[3], level_edge_bits&0x8 "edge" "level");
    
pci_write_cfg_byte(07<<30x54level_edge_bits);

    
PRINTF("%02x %02x %02x %02x\n"pci_read_cfg_byte(07<<30x54),
       
pci_read_cfg_byte(07<<30x55), pci_read_cfg_byte(07<<30x56),
       
pci_read_cfg_byte(07<<30x57));
}

and

/*  Setup the ISA-to-PCI host bridge */
void via_isa_init(pci_dev_t devstruct pci_config_table *table)
{
    
char regval;
    if (
PCI_FUNC(dev) == 0)
    {
    
PRINTF("... PCI-to-ISA bridge, dev=0x%X\n"dev);

    
/*  Enable I/O Recovery time */
    
pci_write_config_byte(dev0x400x08);

    
/*  Enable ISA refresh */
    
pci_write_config_byte(dev0x410x41); /*  was 01 */

    /*  Enable ISA line buffer */
    
pci_write_config_byte(dev0x450x80);

    
/*  Gate INTR, and flush line buffer */
    
pci_write_config_byte(dev0x460x60);

    
/*  Enable EISA ports 4D0/4D1. Do we need this ? */
    
pci_write_config_byte(dev0x470xe6); /*  was 20 */

    /*  512 K PCI Decode */
    
pci_write_config_byte(dev0x480x01);

    
/*  Wait for PGNT before grant to ISA Master/DMA */
    /*  ports 0-FF to SDBus */
    /*  IRQ 14 and 15 for ide 0/1 */
    
pci_write_config_byte(dev0x4a0x04); /*  Was c4 */

    /*  Plug'n'Play */
    /*  Parallel DRQ 3, Floppy DRQ 2 (default) */
    
pci_write_config_byte(dev0x500x0e);

    
/*  IRQ Routing for Floppy and Parallel port */
    /*  IRQ 6 for floppy, IRQ 7 for parallel port */
    
pci_write_config_byte(dev0x510x76);

    
/*  IRQ Routing for serial ports (take IRQ 3 and 4) */
    
pci_write_config_byte(dev0x520x34);

    
/*  All IRQ's level triggered. */
    
pci_write_config_byte(dev0x540x00);

    
/*  PCI IRQ's all at IRQ 9 */
    
pci_write_config_byte(dev0x550x90);
    
pci_write_config_byte(dev0x560x99);
    
pci_write_config_byte(dev0x570x90);

    
/*  Enable Keyboard */
    
pci_read_config_byte(dev0x5A, &regval);
    
regval |= 0x01;
    
pci_write_config_byte(dev0x5Aregval);

    
pci_write_config_byte(dev0x800);
    
pci_write_config_byte(dev0x850x01);

/*     pci_write_config_byte(dev, 0x77, 0x00); */
    
}
}

and more

void articiaS_pci_irq_init(void)
{
    
char *s;

    
getenv("pci_irqa");
    if (
s)
    
pci_intmap[0] = simple_strtoul (sNULL10);
    else
    
pci_intmap[0] = pci_irq_alloc();

    
getenv("pci_irqb");
    if (
s)
    
pci_intmap[1] = simple_strtoul (sNULL10);
    else
    
pci_intmap[1] = pci_irq_alloc();

    
getenv("pci_irqc");
    if (
s)
    
pci_intmap[2] = simple_strtoul (sNULL10);
    else
    
pci_intmap[2] = pci_irq_alloc();

    
getenv("pci_irqd");
    if (
s)
    
pci_intmap[3] = simple_strtoul (sNULL10);
    else
    
pci_intmap[3] = pci_irq_alloc();
}

Max Tretene, ACube Systems Srl, Soft3
Go to top
Re: Qemu Pegasos II interrupts issue
Quite a regular
Quite a regular


See User information
@m3x
And where have you found that? Posting only snippets does not help much because it's hard to see how these fit together. If this is from the U-Boot git before it was removed from it I've found that too. But this only programs the VIA south bridge and not the i8259 PIC. There's also i8259_init() which is called from interrupt_init() but I don't see where the latter is called from if at all. The i8259_init() seems to only do basic setup setting the LTIM bit to edge triggered and this is later redone by AmigaOS so probably does not matter as it will be overwritten anyway.

I still don't see how can this work on real machine unless the VIA ISA bridge 0x54 register in level mode means that PCI interrupts will be retriggered to PIC even when the PIC is in edge mode but then there's still a possibility of interrupts from internal chip functions also mapped to IRQ9 to get lost when the PIC is not in level mode so register 0x54 may only fix the PCI interrupts but I'm not even sure about that. I could try to implement that in QEMU but since it likely won't fix all problems and not needed when AmigaOS sets the PIC in level mode I'll leave it for now.

Go to top
Re: Qemu Pegasos II interrupts issue
Just can't stay away
Just can't stay away


See User information
@balaton
Quote:
... and this is later redone by AmigaOS so probably does not matter as it will be overwritten anyway.
It didn't make any sense to duplicate U-Boot code in the AmigaOS kernel, for the AmigaOne both were implemented by the same developers, and Hans wrote that the OS does not change ELCR in 0x4D0 and 0x4D1.

Quote:
I still don't see how can this work on real machine ...
On the Pegasos2 it could be that it doesn't work, as I told you already there were too few, or even none, OS4 beta testers with that hardware to be able make it stable.
Next to no end users with it either, for checking and fixing bugs reported after public release.

As long as your BBoot doesn't do everything the firmware does I can only urge any QEmu user not using it, as it's incomplete hardware initialization may be the reason for other problems as well, for example the RTL8139 driver not working.

Go to top
Re: Qemu Pegasos II interrupts issue
Amigans Defender
Amigans Defender


See User information

i'm really tired...
Go to top
Re: Qemu Pegasos II interrupts issue
Quite a regular
Quite a regular


See User information
@afxgroup
That's a quite unrelated repo of a fork of some random old U-Boot with unknown changes. Why not look at the upstream U-Boot repo and go back to before the G3SE was removed? I did that before and even tried to build a firmware from that for the amigaone but I've concluded that code upstream is not the same as the U-Boot binary on Hyperion site was built from and does not work so we can't use that as authorative source as the actual amigaone U-Boot may do some other things that were never upstreamed.

Go to top
Re: Qemu Pegasos II interrupts issue
Quite a regular
Quite a regular


See User information
@joerg
The first thing AmigaOS kernel does on amigaone is this:
articia_reg_writeUnimplemented register write 0x80 1 <- b0
pic_ioport_write master 1 addr 0x1 val 0xff
pic_ioport_write master 0 addr 0x1 val 0xff
pic_ioport_write master 1 addr 0x0 val 0x11
pic_ioport_write master 1 addr 0x1 val 0x0
pic_ioport_write master 1 addr 0x1 val 0x4
pic_ioport_write master 1 addr 0x1 val 0x1
pic_ioport_write master 0 addr 0x0 val 0x11
pic_ioport_write master 0 addr 0x1 val 0x8
pic_ioport_write master 0 addr 0x1 val 0x2
pic_ioport_write master 0 addr 0x1 val 0x1
pic_ioport_write master 1 addr 0x0 val 0xb
pic_ioport_write master 0 addr 0x0 val 0xb
pic_ioport_write master 1 addr 0x1 val 0xff
pic_ioport_write master 0 addr 0x1 val 0xff
pic_ioport_write master 1 addr 0x1 val 0xfb
pic_ioport_write master 0 addr 0x1 val 0xff
pic_ioport_write master 1 addr 0x1 val 0xfa
pic_ioport_write master 0 addr 0x1 val 0xff
pic_ioport_read master 1 addr 0x1 val 0xfa
pic_ioport_write master 1 addr 0x1 val 0xfb
pic_ioport_write master 1 addr 0x0 val 0xb
pic_ioport_read master 1 addr 0x0 val 0x1
pic_ioport_write master 1 addr 0x0 val 0x60
pic_ioport_write master 1 addr 0x0 val 0xb
pic_ioport_read master 1 addr 0x0 val 0x0
pic_ioport_write master 1 addr 0x1 val 0xfa
pic_ioport_write master 0 addr 0x1 val 0xff
pic_ioport_read master 1 addr 0x0 val 0x0
pic_ioport_read master 1 addr 0x1 val 0xfa
pic_ioport_write master 1 addr 0x1 val 0xfb
pic_ioport_write master 1 addr 0x0 val 0xb
pic_ioport_read master 1 addr 0x0 val 0x1
pic_ioport_write master 1 addr 0x0 val 0x60
pic_ioport_write master 1 addr 0x0 val 0xb

AFAIK 0xff masks out all interrupts then 0x11 resets the PIC at which point it does not matter what the firmware has set as it needs to be reprogrammed which the AmigaOS kernel does. So I'm not convinced it actually works on real machine. It also works fine on QEMU as long as there's no heavy interrupt load, the problem only happens if multiple devices do a lot of interrupts. And on pegasos2 it happens faster because everything is on the same interrupt. I've heard real machines also lock up sometimes so maybe the bug also exists there just happens less freqently as there is no virtio-gpu generating a lot of interrupts. Now thanks to QEMU this could be debugged and fixing it would also make it work better on real machine.

The AmigaOne G3SE U-Boot sources we have upstream (which is not the same as the XE and may also be incomplete for G3SE) does not set PIC to level mode, it only sets the VIA PCI edge/level register to level mode which only affects the PCI interrupt inputs which should already be emulated in QEMU (with the fix that you've called failed attempt) as it implementes the default level mode. But that's not enough even on real hardware if the interrupt is shared with other than PCI devices as on pegasos2. This could be checked by testing the same on the amigaone machine or sam460ex but only Hans can test that and he only tried pegasos2 so far I think.

Interrupts can be shared in either level or edge mode but the OS has to do the right thing. If interrupts are edge triggered the OS has to keep the state itself and note interrupts to be serviced even while it services another one (as edge mode interrupts don't retrigger) or set the hardware to do this tracking by setting level mode then interrupt is kept raised as long as there are still pending devices.

Go to top
Re: Qemu Pegasos II interrupts issue
Quite a regular
Quite a regular


See User information
@Hans
Quote:
The ELCR offsets are 0x4d0, and 0x4d1. The OS is *NOT* writing to them.

That's ISA IO port which may be memory mapped on PPC but the VIA docs don't mention it so I'm not sure it's supported. Maybe the only way for VIA is the LTIM bit then which MorphOS sets so it should be OK for AmigaOS to use that as well.

Quote:
I've already experimented with it, and enabling level triggered interrupts for PCI interrupts solves the problem where interrupts suddenly stop coming in.

OK so looks like this problem is solved then.

Go to top

  Register To Post
« 1 2 3 (4) 5 6 7 »

 




Currently Active Users Viewing This Thread: 1 ( 0 members and 1 Anonymous Users )




Powered by XOOPS 2.0 © 2001-2023 The XOOPS Project