diff options
author | Michael Brown | 2014-04-28 21:17:15 +0200 |
---|---|---|
committer | Michael Brown | 2014-04-29 19:24:04 +0200 |
commit | 23b671daf490acaec6fdad55f2bfa44021200a63 (patch) | |
tree | d457aaccd7b8764494b932fbf59b412a85878298 /src/arch/i386/include/librm.h | |
parent | [build] Allow for a debug level of zero (diff) | |
download | ipxe-23b671daf490acaec6fdad55f2bfa44021200a63.tar.gz ipxe-23b671daf490acaec6fdad55f2bfa44021200a63.tar.xz ipxe-23b671daf490acaec6fdad55f2bfa44021200a63.zip |
[librm] Allow interrupts in protected mode
When running in a virtual machine, switching to real mode may be
expensive. Allow interrupts to be enabled while in protected mode and
reflected down to the real-mode interrupt handlers.
Signed-off-by: Michael Brown <mcb30@ipxe.org>
Diffstat (limited to 'src/arch/i386/include/librm.h')
-rw-r--r-- | src/arch/i386/include/librm.h | 65 |
1 files changed, 65 insertions, 0 deletions
diff --git a/src/arch/i386/include/librm.h b/src/arch/i386/include/librm.h index fc5598eb..4a4e61aa 100644 --- a/src/arch/i386/include/librm.h +++ b/src/arch/i386/include/librm.h @@ -209,6 +209,71 @@ extern void remove_user_from_rm_stack ( userptr_t data, size_t size ); asm_code_str \ "call _phys_to_virt\n\t" +/** Number of interrupts */ +#define NUM_INT 256 + +/** An interrupt descriptor table register */ +struct idtr { + /** Limit */ + uint16_t limit; + /** Base */ + uint32_t base; +} __attribute__ (( packed )); + +/** An interrupt descriptor table entry */ +struct interrupt_descriptor { + /** Low 16 bits of address */ + uint16_t low; + /** Code segment */ + uint16_t segment; + /** Unused */ + uint8_t unused; + /** Type and attributes */ + uint8_t attr; + /** High 16 bits of address */ + uint16_t high; +} __attribute__ (( packed )); + +/** Interrupt descriptor is present */ +#define IDTE_PRESENT 0x80 + +/** Interrupt descriptor 32-bit interrupt gate type */ +#define IDTE_TYPE_IRQ32 0x0e + +/** An interrupt vector + * + * Each interrupt vector comprises an eight-byte fragment of code: + * + * 60 pushal + * b0 xx movb $INT, %al + * e9 xx xx xx xx jmp interrupt_wrapper + */ +struct interrupt_vector { + /** "pushal" instruction */ + uint8_t pushal; + /** "movb" instruction */ + uint8_t movb; + /** Interrupt number */ + uint8_t intr; + /** "jmp" instruction */ + uint8_t jmp; + /** Interrupt wrapper address offset */ + uint32_t offset; + /** Next instruction after jump */ + uint8_t next[0]; +} __attribute__ (( packed )); + +/** "pushal" instruction */ +#define PUSHAL_INSN 0x60 + +/** "movb" instruction */ +#define MOVB_INSN 0xb0 + +/** "jmp" instruction */ +#define JMP_INSN 0xe9 + +extern void set_interrupt_vector ( unsigned int intr, void *vector ); + #endif /* ASSEMBLY */ #endif /* LIBRM_H */ |