aboutsummaryrefslogtreecommitdiffstats
path: root/src/kbd.c
diff options
context:
space:
mode:
authorKevin O'Connor <kevin@koconnor.net>2009-01-01 21:00:59 -0500
committerKevin O'Connor <kevin@koconnor.net>2009-01-01 21:00:59 -0500
commita83ff550b4cbf0b1bc35f493c8715a69a9e28b7e (patch)
tree3b434ad53bc40b2960bcd0d7abe05e2596f23372 /src/kbd.c
parent7f343097712ebdd1f11953c867e208da899b4ba3 (diff)
downloadseabios-a83ff550b4cbf0b1bc35f493c8715a69a9e28b7e.tar.gz
Reduce stack usage of hw irq handlers.
Avoid using call16_int() -- it consumes too much stack space. Instead, use a new function (call16_simpint). This assumes that the handler wont corrupt regs - which should be a safe assumption, because if they did corrupt regs they wouldn't work on any bios. Avoid enabling irqs in the hw irq handlers - there are no loops in the handlers that could cause any notable latency.
Diffstat (limited to 'src/kbd.c')
-rw-r--r--src/kbd.c21
1 files changed, 9 insertions, 12 deletions
diff --git a/src/kbd.c b/src/kbd.c
index 9c590056..3af70337 100644
--- a/src/kbd.c
+++ b/src/kbd.c
@@ -418,7 +418,10 @@ static struct scaninfo {
{ 0x8600, 0x8800, 0x8a00, 0x8c00, none }, /* F12 */
};
-static void
+// Handle a scancode read from the ps2 port. Note that "noinline" is
+// used to make sure the call to call16_simpint in handle_09 doesn't
+// have the overhead of this function's stack.
+static void noinline
process_key(u8 scancode)
{
u8 shift_flags = GET_BDA(kbd_flag0);
@@ -620,23 +623,17 @@ handle_09()
}
u8 key = inb(PORT_PS2_DATA);
- irq_enable();
if (CONFIG_KBD_CALL_INT15_4F) {
// allow for keyboard intercept
- struct bregs tr;
- memset(&tr, 0, sizeof(tr));
- tr.al = key;
- tr.ah = 0x4f;
- tr.flags = F_CF;
- call16_int(0x15, &tr);
- if (!(tr.flags & F_CF))
+ u32 eax = (0x4f << 8) | key;
+ u32 flags;
+ call16_simpint(0x15, &eax, &flags);
+ if (!(flags & F_CF))
goto done;
- key = tr.al;
+ key = eax;
}
process_key(key);
- irq_disable();
-
done:
eoi_pic1();
}