Page 1 of 1

How does the PIC map interrupt vectors to IDT ?

Posted: Wed Oct 26, 2022 5:50 pm
by drnono
I'm trying to set up interrupts, but I don't understand how the PIC maps vectors to the IDT.
I assumed it was just like if the vector is 0x20 then that would map to the 32nd entry in the 64bit wide IDT.
This doesn't seem to be the case on VirtualBox anyway. When I map the PIC master vector to 8 the corresponding entry
in IDT is 11, with vector 16 the IDT entry is 19 and with the recommended 32, the IDT entry is not within 256 entries!?

The interrupt service routine is working for vectors 8, 16 though, but at a weird IDT offset.


Code: Select all

void init_interrupts(uint64_t *interrupt_descriptor_table)
{

	uint8_t *ptr = (uint8_t *) &asm_ISR_keyboard + image_base;
	uint32_t *ISR_keyboard = (uint32_t *) ptr;
	

	// remap VECTORs
	PIC_remap(0x20, 0x28);

	// lazy: set all interrupts to the same routine, check which IDT entry is the correct one for the VECTOR 
	
        for (uint16_t i=0;i<256;i++) 
        {
	               interrupt_descriptor_table[i] = 0 | ((uint64_t) GD_PRESENT_BIT << 47) 
                                                         | ((uint64_t) GD_DPL_KERNEL << 45) 
                                                         | ((uint64_t) 0 << 44) 
                                                         | ((uint64_t) GD32_INTERRUPT_GATE << 40) 
                                                         | ((uint64_t) 0x8 << 16)
                                                         | (((uint64_t) ((uint32_t) ISR_keyboard & 0xffff0000)) << 32) 
                                                         | ((uint64_t) ((uint32_t) ISR_keyboard & 0x0000ffff));
        }

	

	
	// disable all interrupts except keyboard
	for (uint8_t j =0 ; j<16; j++)
	{
		IRQ_set_mask(j);
		wait();
	}
	IRQ_clear_mask(IRQ_KEYBOARD);
	asm("sti");


	return;
}

Re: How does the PIC map interrupt vectors to IDT ?

Posted: Wed Oct 26, 2022 8:14 pm
by Octocontrabass
drnono wrote:I assumed it was just like if the vector is 0x20 then that would map to the 32nd entry in the 64bit wide IDT.
If you set the vector to 0x20, it uses eight vectors from 0x20 to 0x27.
drnono wrote:This doesn't seem to be the case on VirtualBox anyway. When I map the PIC master vector to 8 the corresponding entry
in IDT is 11, with vector 16 the IDT entry is 19 and with the recommended 32, the IDT entry is not within 256 entries!?
How are you getting these numbers?

Re: How does the PIC map interrupt vectors to IDT ?

Posted: Wed Oct 26, 2022 8:56 pm
by drnono
I disabled all the interrupts except for the keyboard. When I press a key the interrupt service routine runs
but only when I load IDT like this:

PIC master remap 0 => interrupt_descriptor_table[3] works - the ISR will run.
PIC master remap 8 => interrupt_descriptor_table[11] works - the ISR will run.
PIC master remap 16 => interrupt_descriptor_table[19] works - the ISR will run.

PIC master remap 0x20 => it actually does call the ISR but does not return, crashes at iret and I don't know which IDT entry it's at just that it's one of 256

Re: How does the PIC map interrupt vectors to IDT ?

Posted: Thu Oct 27, 2022 2:29 am
by Octocontrabass
Something must be very wrong with your code to get results like that. The PIC cannot map IRQ1 to vector 3, 11, or 19.

Re: How does the PIC map interrupt vectors to IDT ?

Posted: Thu Oct 27, 2022 4:23 am
by Gigasoft
At least fix your loading issue first, something is clearly not right if you have to write "+ image_base" everywhere.

Re: How does the PIC map interrupt vectors to IDT ?

Posted: Thu Oct 27, 2022 5:02 pm
by MichaelPetch
I have to agree that there seems to be something fundamentally wrong with your code and/or the environment it is running in. I suspect the problems you are encountering are related to some more fundamental bug/issue, possibly even how you loaded it into memory, or even built the code. Do you have a copy of your project on something like Github that can be looked at?