Author: phueper Date: 2009-03-14 16:55:43 +0100 (Sat, 14 Mar 2009) New Revision: 1150
Modified: coreboot-v3/util/x86emu/yabel/biosemu.c coreboot-v3/util/x86emu/yabel/biosemu.h coreboot-v3/util/x86emu/yabel/interrupt.c Log: 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
Modified: coreboot-v3/util/x86emu/yabel/biosemu.c =================================================================== --- coreboot-v3/util/x86emu/yabel/biosemu.c 2009-03-14 15:43:28 UTC (rev 1149) +++ coreboot-v3/util/x86emu/yabel/biosemu.c 2009-03-14 15:55:43 UTC (rev 1150) @@ -52,6 +52,9 @@ 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:
Modified: coreboot-v3/util/x86emu/yabel/biosemu.h =================================================================== --- coreboot-v3/util/x86emu/yabel/biosemu.h 2009-03-14 15:43:28 UTC (rev 1149) +++ coreboot-v3/util/x86emu/yabel/biosemu.h 2009-03-14 15:55:43 UTC (rev 1150) @@ -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
Modified: coreboot-v3/util/x86emu/yabel/interrupt.c =================================================================== --- coreboot-v3/util/x86emu/yabel/interrupt.c 2009-03-14 15:43:28 UTC (rev 1149) +++ coreboot-v3/util/x86emu/yabel/interrupt.c 2009-03-14 15:55:43 UTC (rev 1150) @@ -518,54 +518,61 @@ // 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) {