Page 1 of 1
Interrupt Descriptor Table: Masking and shifting addresses
Posted: Thu Dec 24, 2015 5:54 am
by glauxosdever
Hi all,
I want to make an Interrupt Descriptor Table, which needs to have the address of the interrupt handler for each entry. The problem is that there are two fields for the address: the one contains the lower 16 bits, the other contains the upper 16 bits. Like this (NASM):
Code: Select all
dw handler_addr & 0xFFFF
dw 0x08
db 0x00
db 0x8F
dw handler_addr >> 16
But these are not scalar values. I tried the solution provided
on the wiki but doesn't work for elf32. I remember it worked fine for flat binary. Any ideas?
P.S. I'd prefer not having runtime initialisation code.
Regards,
glauxosdever
Re: Interrupt Descriptor Table: Masking and shifting address
Posted: Thu Dec 24, 2015 6:33 am
by alexfru
Change the order to concatenate the two address halves and pre-initialize like that. At run-time in a loop change the order to what the CPU wants. Unions might help.
Another option might be to recognize something here:
Code: Select all
...
dw handler_addr & 0xFFFF
dw 0x08
db 0x00
db 0x8F
dw handler_addr >> 16
dw handler_addr & 0xFFFF
dw 0x08
db 0x00
db 0x8F
dw handler_addr >> 16
...
But you'd still need to swap the address halves.
Re: Interrupt Descriptor Table: Masking and shifting address
Posted: Thu Dec 24, 2015 6:53 am
by Combuster
The ELF object file contains relocations of a fixed format that correspond to the instruction set. The x86 architecture has no instruction that is in any tradition used to load the top 16 bits of an address into, therefore you can't express that in an object file. Several RISC processors do have an explicit load high with a 16-bit immediate where the fixed instruction width requires two instructions to load a 32-bit integer. When assembling directly to a flat binary you don't have the restrictions of an intermediate object file, and the assembler is often capable (or to some extent, if you look at the fix) of filling out the addresses on the spot.
If you want to use object files, you'll have to initialize the tables at runtime. The resulting code could well be cleaner for lack of pages worth of loop unrolling.
Re: Interrupt Descriptor Table: Masking and shifting address
Posted: Thu Dec 24, 2015 9:22 am
by Brendan
Hi,
glauxosdever wrote:P.S. I'd prefer not having runtime initialisation code.
Realistically:
- The first 32 entries are exceptions handlers that could be statically allocated, but they're also a perfect place to have different code for different systems. For example, maybe you want one page fault handler for "plain 32-bit paging" and a different page fault handler for "PAE"; and one "invalid opcode" exception handler for CPUs that support AVX and a different one for when the kernel emulates AVX instructions, etc.
- The 15 interrupts used by the PIC chips depend on whether or not the OS decides to use PIC or IO APIC (if the OS uses IO APIC then you only need 2 "spurious IRQ from PIC chip" interrupt handlers because the PIC chips won't send normal IRQs)
- The variable number of interrupts used by IO APIC is variable (and depend on whether the OS decides to use PIC or IO APIC)
- Any interrupts used by the local APIC (spurious, timer, thermal status, performance monitoring) depend on whether or not the local APIC exists (and whether or not things like performance monitoring for the specific CPU is supported by the kernel)
- The interrupt vectors the OS uses for IPIs (e.g. multi-CPU TLB shootdown, etc) mostly depend on whether the computer has 2 or more CPUs (but even for single-CPU some might be used for some sort of deferred procedure call thing, which would depend on the existence of the local APIC). This is another place where you might choose one of multiple interrupt handlers (e.g. one "multi-CPU TLB shootdown IPI" handler for SMP and another/different one for NUMA)
- The vast majority of "otherwise unused" interrupts may or may not be used for PCI devices using MSI
Basically; you might only be able to setup less than 10% of IDT entries at compile time anyway.
Cheers,
Brendan
Re: Interrupt Descriptor Table: Masking and shifting address
Posted: Thu Dec 24, 2015 11:09 am
by glauxosdever
Hi all,
Thank you kindly for your answers. Based on them I decided to initialise the Interrupt Descriptor Table at runtime.
Regards,
glauxosdever