]> git.ipfire.org Git - thirdparty/ipxe.git/commitdiff
[comboot] Use built-in interrupt reflector
authorMichael Brown <mcb30@ipxe.org>
Mon, 28 Apr 2014 20:11:04 +0000 (21:11 +0100)
committerMichael Brown <mcb30@ipxe.org>
Tue, 29 Apr 2014 17:24:10 +0000 (18:24 +0100)
We now have the ability to handle interrupts while in protected mode,
and so no longer need to set up a dedicated interrupt descriptor table
while running COM32 executables.

Signed-off-by: Michael Brown <mcb30@ipxe.org>
src/arch/i386/image/com32.c
src/arch/i386/include/comboot.h
src/arch/i386/interface/syslinux/com32_call.c
src/arch/i386/interface/syslinux/com32_wrapper.S

index 5cc9a4476296caed1f75957c3d2b8ec5a7a0bc70..c12ffb684039c7375de28d22fa271ed866f93e33 100644 (file)
@@ -41,13 +41,6 @@ FILE_LICENCE ( GPL2_OR_LATER );
 #include <ipxe/init.h>
 #include <ipxe/io.h>
 
-struct idt_register com32_external_idtr = {
-       .limit = COM32_NUM_IDT_ENTRIES * sizeof ( struct idt_descriptor ) - 1,
-       .base = COM32_IDT
-};
-
-struct idt_register com32_internal_idtr;
-
 /**
  * Execute COMBOOT image
  *
@@ -95,8 +88,6 @@ static int com32_exec_loop ( struct image *image ) {
                unregister_image ( image );
 
                __asm__ __volatile__ (
-                       "sidt com32_internal_idtr\n\t"
-                       "lidt com32_external_idtr\n\t"         /* Set up IDT */
                        "movl %%esp, (com32_internal_esp)\n\t" /* Save internal virtual address space ESP */
                        "movl (com32_external_esp), %%esp\n\t" /* Switch to COM32 ESP (top of available memory) */
                        "call _virt_to_phys\n\t"               /* Switch to flat physical address space */
@@ -110,8 +101,7 @@ static int com32_exec_loop ( struct image *image ) {
                        "pushl $6\n\t"                         /* Number of additional arguments */
                        "call *%6\n\t"                         /* Execute image */
                        "cli\n\t"                              /* Disable interrupts */
-                       "call _phys_to_virt\n\t"               /* Switch back to internal virtual address space */
-                       "lidt com32_internal_idtr\n\t"         /* Switch back to internal IDT (for debugging) */
+                       "call _phys_to_virt\n\t"               /* Switch back to internal virtual address space */
                        "movl (com32_internal_esp), %%esp\n\t" /* Switch back to internal stack */
                :
                :
@@ -201,55 +191,25 @@ static int com32_identify ( struct image *image ) {
 
 
 /**
- * Load COM32 image into memory and set up the IDT
+ * Load COM32 image into memory
  * @v image            COM32 image
  * @ret rc             Return status code
  */
 static int com32_load_image ( struct image *image ) {
-       physaddr_t com32_irq_wrapper_phys;
-       struct idt_descriptor *idt;
-       struct ijb_entry *ijb;
        size_t filesz, memsz;
        userptr_t buffer;
-       int rc, i;
-
-       /* The interrupt descriptor table, interrupt jump buffer, and
-        * image data are all contiguous in memory. Prepare them all at once.
-        */
-       filesz = image->len +
-               COM32_NUM_IDT_ENTRIES * sizeof ( struct idt_descriptor ) +
-               COM32_NUM_IDT_ENTRIES * sizeof ( struct ijb_entry );
+       int rc;
+
+       filesz = image->len;
        memsz = filesz;
-       buffer = phys_to_user ( COM32_IDT );
+       buffer = phys_to_user ( COM32_START_PHYS );
        if ( ( rc = prep_segment ( buffer, filesz, memsz ) ) != 0 ) {
                DBGC ( image, "COM32 %p: could not prepare segment: %s\n",
                       image, strerror ( rc ) );
                return rc;
        }
 
-       /* Write the IDT and IJB */
-       idt = phys_to_virt ( COM32_IDT );
-       ijb = phys_to_virt ( COM32_IJB );
-       com32_irq_wrapper_phys = virt_to_phys ( com32_irq_wrapper );
-
-       for ( i = 0; i < COM32_NUM_IDT_ENTRIES; i++ ) {
-               uint32_t ijb_address = virt_to_phys ( &ijb[i] );
-
-               idt[i].offset_low = ijb_address & 0xFFFF;
-               idt[i].selector = PHYSICAL_CS;
-               idt[i].flags = IDT_INTERRUPT_GATE_FLAGS;
-               idt[i].offset_high = ijb_address >> 16;
-
-               ijb[i].pusha_instruction = IJB_PUSHA;
-               ijb[i].mov_instruction = IJB_MOV_AL_IMM8;
-               ijb[i].mov_value = i;
-               ijb[i].jump_instruction = IJB_JMP_REL32;
-               ijb[i].jump_destination = com32_irq_wrapper_phys -
-                       virt_to_phys ( &ijb[i + 1] );
-       }
-
        /* Copy image to segment */
-       buffer = phys_to_user ( COM32_START_PHYS );
        memcpy_user ( buffer, 0, image->data, 0, filesz );
 
        return 0;
index b3434139840c50c374294da92190b828cbb94109..2d2f04fe173bd16f33a0d4563ef7bf5ca1d77891 100644 (file)
@@ -13,50 +13,6 @@ FILE_LICENCE ( GPL2_OR_LATER );
 #include <setjmp.h>
 #include <ipxe/in.h>
 
-/** Descriptor in a 32-bit IDT */
-struct idt_descriptor {
-       uint16_t offset_low;
-       uint16_t selector;
-       uint16_t flags;
-       uint16_t offset_high;
-} __attribute__ (( packed ));
-
-/** Operand for the LIDT instruction */
-struct idt_register {
-       uint16_t limit;
-       uint32_t base;
-} __attribute__ (( packed ));
-
-/** Entry in the interrupt jump buffer */
-struct ijb_entry {
-       uint8_t pusha_instruction;
-       uint8_t mov_instruction;
-       uint8_t mov_value;
-       uint8_t jump_instruction;
-       uint32_t jump_destination;
-} __attribute__ (( packed ));
-
-/** The x86 opcode for "pushal" */
-#define IJB_PUSHA 0x60
-
-/** The x86 opcode for "movb $imm8,%al" */
-#define IJB_MOV_AL_IMM8 0xB0
-
-/** The x86 opcode for "jmp rel32" */
-#define IJB_JMP_REL32 0xE9
-
-/** Flags that specify a 32-bit interrupt gate with DPL=0 */
-#define IDT_INTERRUPT_GATE_FLAGS 0x8E00
-
-/** Address of COM32 interrupt descriptor table */
-#define COM32_IDT 0x100000
-
-/** Number of entries in a fully populated IDT */
-#define COM32_NUM_IDT_ENTRIES 256
-
-/** Address of COM32 interrupt jump buffer */
-#define COM32_IJB 0x100800
-
 /** Segment used for COMBOOT PSP and image */
 #define COMBOOT_PSP_SEG 0x07C0
 
@@ -153,7 +109,6 @@ extern void unhook_comboot_interrupts ( );
 extern void com32_intcall_wrapper ( );
 extern void com32_farcall_wrapper ( );
 extern void com32_cfarcall_wrapper ( );
-extern void com32_irq_wrapper ( );
 
 /* Resolve a hostname to an (IPv4) address */
 extern int comboot_resolv ( const char *name, struct in_addr *address );
index 8fffd0692bda100b6519cbf9c8f7be4a9b2c93cd..75dcc238f1e14ddeb9982325c81a6a9e0a83148a 100644 (file)
@@ -189,20 +189,3 @@ int __asmcall com32_cfarcall ( uint32_t proc, physaddr_t stack, size_t stacksz )
 
        return eax;
 }
-
-/**
- * IRQ handler
- */
-void __asmcall com32_irq ( uint32_t vector ) {
-       uint32_t *ivt_entry = phys_to_virt( vector * 4 );
-
-       __asm__ __volatile__ (
-               REAL_CODE ( "pushfw\n\t"
-                           "pushw %%cs\n\t"
-                           "pushw $com32_irq_return\n\t"
-                           "pushl %0\n\t"
-                           "lret\n"
-                           "com32_irq_return:\n\t" )
-               : /* no outputs */
-               : "r" ( *ivt_entry ) );
-}
index 69cea02e8ab40db99630f96957a2eac629fca0f5..c9d1452b421b1c17bd027fa4a97d2d8ff879afa4 100644 (file)
@@ -23,26 +23,6 @@ FILE_LICENCE ( GPL2_OR_LATER )
        .arch i386
        .code32
 
-       /*
-        * This code is entered after running the following sequence out of
-        * the interrupt jump buffer:
-        *
-        * pushal
-        * movb $vector, %al
-        * jmp com32_irq_wrapper
-        */
-
-       .globl com32_irq_wrapper
-com32_irq_wrapper:
-
-       movzbl %al,%eax
-       pushl %eax
-       movl $com32_irq, %eax
-       call com32_wrapper
-       popl %eax
-       popal
-       iret
-
        .globl com32_farcall_wrapper
 com32_farcall_wrapper:
 
@@ -69,9 +49,6 @@ com32_wrapper:
        /* Switch to internal virtual address space */
        call _phys_to_virt
 
-       /* Switch to internal IDT (if we have one for debugging) */
-       lidt com32_internal_idtr
-
        mov %eax, (com32_helper_function)
 
        /* Save external COM32 stack pointer */
@@ -99,9 +76,6 @@ com32_wrapper:
        movl %esp, (com32_internal_esp)
        movl (com32_external_esp), %esp
 
-       /* Switch to com32 IDT */
-       lidt com32_external_idtr
-
        /* Switch to external flat physical address space */
        call _virt_to_phys