summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPattrick Hueper <phueper@hueper.net>2009-03-14 15:55:43 +0000
committerPattrick Hueper <phueper@hueper.net>2009-03-14 15:55:43 +0000
commit0b77932cbafd539bb26ca0d4da117e7a36399a56 (patch)
treec2ff683ac471e496e1680859764c5700f65c735d
parent131affc05a81d19193391263fd7890447ee44d09 (diff)
downloadcoreboot-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.c3
-rw-r--r--util/x86emu/yabel/biosemu.h8
-rw-r--r--util/x86emu/yabel/interrupt.c91
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) {