diff options
author | Pattrick Hueper <phueper@hueper.net> | 2009-03-14 15:55:43 +0000 |
---|---|---|
committer | Pattrick Hueper <phueper@hueper.net> | 2009-03-14 15:55:43 +0000 |
commit | 0b77932cbafd539bb26ca0d4da117e7a36399a56 (patch) | |
tree | c2ff683ac471e496e1680859764c5700f65c735d | |
parent | 131affc05a81d19193391263fd7890447ee44d09 (diff) | |
download | coreboot-0b77932cbafd539bb26ca0d4da117e7a36399a56.tar.gz coreboot-0b77932cbafd539bb26ca0d4da117e7a36399a56.tar.bz2 coreboot-0b77932cbafd539bb26ca0d4da117e7a36399a56.zip |
add intFuncArray to be able to override INT handlers from YABEL caller
Signed-off-by: Pattrick Hueper <phueper@hueper.net>
Acked-by: Stefan Reinauer <stepan@coresystems.de>
git-svn-id: svn://coreboot.org/repository/coreboot-v3@1150 f3766cd6-281f-0410-b1cd-43a5c92072e9
-rw-r--r-- | util/x86emu/yabel/biosemu.c | 3 | ||||
-rw-r--r-- | util/x86emu/yabel/biosemu.h | 8 | ||||
-rw-r--r-- | util/x86emu/yabel/interrupt.c | 91 |
3 files changed, 60 insertions, 42 deletions
diff --git a/util/x86emu/yabel/biosemu.c b/util/x86emu/yabel/biosemu.c index 059ac0458806..e0010d8377f8 100644 --- a/util/x86emu/yabel/biosemu.c +++ b/util/x86emu/yabel/biosemu.c @@ -52,6 +52,9 @@ static X86EMU_pioFuncs my_pio_funcs = { my_outb, my_outw, my_outl }; +/* interrupt function override array (see biosemu.h) */ +yabel_handleIntFunc yabel_intFuncArray[256]; + void dump(u8 * addr, u32 len); /* main entry into YABEL biosemu, arguments are: diff --git a/util/x86emu/yabel/biosemu.h b/util/x86emu/yabel/biosemu.h index 7ffd5bcffa2e..20aff6f5c086 100644 --- a/util/x86emu/yabel/biosemu.h +++ b/util/x86emu/yabel/biosemu.h @@ -37,4 +37,12 @@ // Address, there will only be a call to this INT and a RETF #define PNP_INT_NUM 0xFD +/* array of funtion pointers to override generic interrupt handlers + * a YABEL caller can add functions to this array before calling YABEL + * if a interrupt occurs, YABEL checks wether a function is set in + * this array and only runs the generic interrupt handler code, if + * the function pointer is NULL */ +typedef int (* yabel_handleIntFunc)(void); +extern yabel_handleIntFunc yabel_intFuncArray[256]; + #endif diff --git a/util/x86emu/yabel/interrupt.c b/util/x86emu/yabel/interrupt.c index 62f8c25b4966..254334c2675d 100644 --- a/util/x86emu/yabel/interrupt.c +++ b/util/x86emu/yabel/interrupt.c @@ -518,54 +518,61 @@ handleInterrupt(int intNum) // so we only enable it, if int10 print is disabled DEBUG_PRINTF_INTR("%s(%x)\n", __func__, intNum); #endif - switch (intNum) { - case 0x10: //BIOS video interrupt - case 0x42: // INT 10h relocated by EGA/VGA BIOS - case 0x6d: // INT 10h relocated by VGA BIOS - // get interrupt vector from IDT (4 bytes per Interrupt starting at address 0 - if ((my_rdl(intNum * 4) == 0xF000F065) || //F000:F065 is default BIOS interrupt handler address - (my_rdl(intNum * 4) == 0xF4F4F4F4)) //invalid - { + + /* check wether this interrupt has a function pointer set in yabel_intFuncArray and run that */ + if (yabel_intFuncArray[intNum]) { + DEBUG_PRINTF_INTR("%s(%x) intHandler overridden, calling it...\n", __func__, intNum); + int_handled = (*yabel_intFuncArray[intNum])(); + } else { + switch (intNum) { + case 0x10: //BIOS video interrupt + case 0x42: // INT 10h relocated by EGA/VGA BIOS + case 0x6d: // INT 10h relocated by VGA BIOS + // get interrupt vector from IDT (4 bytes per Interrupt starting at address 0 + if ((my_rdl(intNum * 4) == 0xF000F065) || //F000:F065 is default BIOS interrupt handler address + (my_rdl(intNum * 4) == 0xF4F4F4F4)) //invalid + { #if 0 - // ignore interrupt... - DEBUG_PRINTF_INTR - ("%s(%x): invalid interrupt Vector (%08x) found, interrupt ignored...\n", - __func__, intNum, my_rdl(intNum * 4)); + // ignore interrupt... + DEBUG_PRINTF_INTR + ("%s(%x): invalid interrupt Vector (%08x) found, interrupt ignored...\n", + __func__, intNum, my_rdl(intNum * 4)); + DEBUG_PRINTF_INTR("AX=%04x BX=%04x CX=%04x DX=%04x\n", + M.x86.R_AX, M.x86.R_BX, M.x86.R_CX, + M.x86.R_DX); + //HALT_SYS(); +#endif + handleInt10(); + int_handled = 1; + } + break; + case 0x16: + // Keyboard BIOS Interrupt + handleInt16(); + int_handled = 1; + break; + case 0x1a: + // PCI BIOS Interrupt + handleInt1a(); + int_handled = 1; + break; + case PMM_INT_NUM: + /* the selfdefined PMM INT number, this is called by the code in PMM struct, it + * is handled by pmm_handleInt() + */ + pmm_handleInt(); + int_handled = 1; + break; + default: + printf("Interrupt %#x (Vector: %x) not implemented\n", intNum, + my_rdl(intNum * 4)); DEBUG_PRINTF_INTR("AX=%04x BX=%04x CX=%04x DX=%04x\n", M.x86.R_AX, M.x86.R_BX, M.x86.R_CX, M.x86.R_DX); - //HALT_SYS(); -#endif - handleInt10(); int_handled = 1; + HALT_SYS(); + break; } - break; - case 0x16: - // Keyboard BIOS Interrupt - handleInt16(); - int_handled = 1; - break; - case 0x1a: - // PCI BIOS Interrupt - handleInt1a(); - int_handled = 1; - break; - case PMM_INT_NUM: - /* the selfdefined PMM INT number, this is called by the code in PMM struct, it - * is handled by pmm_handleInt() - */ - pmm_handleInt(); - int_handled = 1; - break; - default: - printf("Interrupt %#x (Vector: %x) not implemented\n", intNum, - my_rdl(intNum * 4)); - DEBUG_PRINTF_INTR("AX=%04x BX=%04x CX=%04x DX=%04x\n", - M.x86.R_AX, M.x86.R_BX, M.x86.R_CX, - M.x86.R_DX); - int_handled = 1; - HALT_SYS(); - break; } // if we did not handle the interrupt, jump to the interrupt vector... if (!int_handled) { |