How does the PIC map interrupt vectors to IDT ?

Question about which tools to use, bugs, the best way to implement a function, etc should go here. Don't forget to see if your question is answered in the wiki first! When in doubt post here.
Post Reply
drnono
Posts: 23
Joined: Sun Aug 09, 2015 11:54 am

How does the PIC map interrupt vectors to IDT ?

Post 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;
}
Octocontrabass
Member
Member
Posts: 5563
Joined: Mon Mar 25, 2013 7:01 pm

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

Post 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?
drnono
Posts: 23
Joined: Sun Aug 09, 2015 11:54 am

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

Post 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
Octocontrabass
Member
Member
Posts: 5563
Joined: Mon Mar 25, 2013 7:01 pm

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

Post 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.
Gigasoft
Member
Member
Posts: 856
Joined: Sat Nov 21, 2009 5:11 pm

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

Post by Gigasoft »

At least fix your loading issue first, something is clearly not right if you have to write "+ image_base" everywhere.
MichaelPetch
Member
Member
Posts: 797
Joined: Fri Aug 26, 2016 1:41 pm
Libera.chat IRC: mpetch

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

Post 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?
Post Reply