summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMichael Brown2006-05-13 13:44:11 +0200
committerMichael Brown2006-05-13 13:44:11 +0200
commit63499e9cfd5331e90a88a6d92d370bfe6f1874f3 (patch)
treea66e0542554e7b7cfb3bbaee1d2fe6d53a9156da
parentDefine BIOS data segment in bios.h (diff)
downloadipxe-63499e9cfd5331e90a88a6d92d370bfe6f1874f3.tar.gz
ipxe-63499e9cfd5331e90a88a6d92d370bfe6f1874f3.tar.xz
ipxe-63499e9cfd5331e90a88a6d92d370bfe6f1874f3.zip
Allow re-entrancy and provide a global counter of the number of
interrupts hooked.
-rw-r--r--src/arch/i386/interface/pcbios/biosint.c20
1 files changed, 20 insertions, 0 deletions
diff --git a/src/arch/i386/interface/pcbios/biosint.c b/src/arch/i386/interface/pcbios/biosint.c
index 345961ac..6028998a 100644
--- a/src/arch/i386/interface/pcbios/biosint.c
+++ b/src/arch/i386/interface/pcbios/biosint.c
@@ -8,6 +8,17 @@
*/
/**
+ * Hooked interrupt count
+ *
+ * At exit, after unhooking all possible interrupts, this counter
+ * should be examined. If it is non-zero, it means that we failed to
+ * unhook at least one interrupt vector, and so must not free up the
+ * memory we are using. (Note that this also implies that we should
+ * re-hook INT 15 in order to hide ourselves from the memory map).
+ */
+int hooked_bios_interrupts = 0;
+
+/**
* Hook INT vector
*
* @v interrupt INT number
@@ -26,9 +37,15 @@ void hook_bios_interrupt ( unsigned int interrupt, unsigned int handler,
.offset = handler,
};
+ if ( ( chain_vector->segment != 0 ) ||
+ ( chain_vector->offset != 0 ) ) {
+ /* Already hooked; do nothing */
+ return;
+ }
copy_from_real ( chain_vector, 0, ( interrupt * 4 ),
sizeof ( *chain_vector ) );
copy_to_real ( 0, ( interrupt * 4 ), &vector, sizeof ( vector ) );
+ hooked_bios_interrupts++;
}
/**
@@ -53,5 +70,8 @@ int unhook_bios_interrupt ( unsigned int interrupt, unsigned int handler,
return -EBUSY;
copy_to_real ( 0, ( interrupt * 4 ), chain_vector,
sizeof ( *chain_vector ) );
+ chain_vector->segment = 0;
+ chain_vector->offset = 0;
+ hooked_bios_interrupts--;
return 0;
}