Page 1 of 1
Is IO wait necessary, when remapping IRQs on x86-64?
Posted: Fri Feb 07, 2025 12:05 pm
by sandras
From
https://wiki.osdev.org/8259_PIC, regarding IRQ remapping:
Note the presence of io_wait() calls, on older machines its necessary to give the PIC some time to react to commands as they might not be processed quickly
I'm wondering, do I need to perform IO wait when remapping IRQs on x86-64?
Just saying "older machines" is vague. Perhaps we could clarify what it means in this context?
Re: Is IO wait necessary, when remapping IRQs on x86-64?
Posted: Fri Feb 07, 2025 1:47 pm
by Octocontrabass
It probably isn't necessary on any 64-bit PCs, but it's tough to know for sure without testing all of them.
Re: Is IO wait necessary, when remapping IRQs on x86-64?
Posted: Fri Feb 07, 2025 4:06 pm
by sandras
OK, I understand. I have a follow-up question, though.
In the wiki, there's this code example:
Code: Select all
/* reinitialize the PIC controllers, giving them specified vector offsets
rather than 8h and 70h, as configured by default */
#define ICW1_ICW4 0x01 /* Indicates that ICW4 will be present */
#define ICW1_SINGLE 0x02 /* Single (cascade) mode */
#define ICW1_INTERVAL4 0x04 /* Call address interval 4 (8) */
#define ICW1_LEVEL 0x08 /* Level triggered (edge) mode */
#define ICW1_INIT 0x10 /* Initialization - required! */
#define ICW4_8086 0x01 /* 8086/88 (MCS-80/85) mode */
#define ICW4_AUTO 0x02 /* Auto (normal) EOI */
#define ICW4_BUF_SLAVE 0x08 /* Buffered mode/slave */
#define ICW4_BUF_MASTER 0x0C /* Buffered mode/master */
#define ICW4_SFNM 0x10 /* Special fully nested (not) */
/*
arguments:
offset1 - vector offset for master PIC
vectors on the master become offset1..offset1+7
offset2 - same for slave PIC: offset2..offset2+7
*/
void PIC_remap(int offset1, int offset2)
{
uint8_t a1, a2;
a1 = inb(PIC1_DATA); // save masks
a2 = inb(PIC2_DATA);
outb(PIC1_COMMAND, ICW1_INIT | ICW1_ICW4); // starts the initialization sequence (in cascade mode)
io_wait();
outb(PIC2_COMMAND, ICW1_INIT | ICW1_ICW4);
io_wait();
outb(PIC1_DATA, offset1); // ICW2: Master PIC vector offset
io_wait();
outb(PIC2_DATA, offset2); // ICW2: Slave PIC vector offset
io_wait();
outb(PIC1_DATA, 4); // ICW3: tell Master PIC that there is a slave PIC at IRQ2 (0000 0100)
io_wait();
outb(PIC2_DATA, 2); // ICW3: tell Slave PIC its cascade identity (0000 0010)
io_wait();
outb(PIC1_DATA, ICW4_8086); // ICW4: have the PICs use 8086 mode (and not 8080 mode)
io_wait();
outb(PIC2_DATA, ICW4_8086);
io_wait();
outb(PIC1_DATA, a1); // restore saved masks.
outb(PIC2_DATA, a2);
}
Say I'm remapping IRQs right before loading IDT and enabling interrupts. Wouldn't it be more correct to also wait after "restoring saved masks"?
Re: Is IO wait necessary, when remapping IRQs on x86-64?
Posted: Fri Feb 07, 2025 5:49 pm
by Octocontrabass
Probably, yes, but in practice it doesn't seem to be necessary.
Also, you wouldn't want to restore the masks set by the firmware. I'm not sure why the wiki example does that.
Re: Is IO wait necessary, when remapping IRQs on x86-64?
Posted: Sat Feb 08, 2025 7:27 am
by sandras
I think I'll do what seems correct to me and wait after setting the masks too.
To me it seems that the wiki example tries to be general in nature - a function to remap IRQs at any time and restore the masks to their previous state, while everyone probably just remaps IRQs once at boot time, and sets the masks to known values once or twice during the run of the kernel. I'll try to simplify the masking in the wiki.