aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/asm-offsets.c1
-rw-r--r--src/clock.c20
-rw-r--r--src/disk.c4
-rw-r--r--src/floppy.c4
-rw-r--r--src/kbd.c14
-rw-r--r--src/misc.c14
-rw-r--r--src/mouse.c57
-rw-r--r--src/output.c9
-rw-r--r--src/ps2port.c8
-rw-r--r--src/romlayout.S60
-rw-r--r--src/stacks.c4
-rw-r--r--src/util.h25
-rwxr-xr-xtools/checkstack.py2
13 files changed, 127 insertions, 95 deletions
diff --git a/src/asm-offsets.c b/src/asm-offsets.c
index b98f3b5..576bf34 100644
--- a/src/asm-offsets.c
+++ b/src/asm-offsets.c
@@ -20,4 +20,5 @@ void foo(void)
OFFSET(BREGS_edi, bregs, edi);
OFFSET(BREGS_flags, bregs, flags);
OFFSET(BREGS_code, bregs, code);
+ DEFINE(BREGS_size, sizeof(struct bregs));
}
diff --git a/src/clock.c b/src/clock.c
index 97d5301..55dde2e 100644
--- a/src/clock.c
+++ b/src/clock.c
@@ -516,9 +516,9 @@ handle_1a(struct bregs *regs)
// INT 08h System Timer ISR Entry Point
void VISIBLE16
-handle_08(void)
+handle_08(struct bregs *regs)
{
- debug_isr(DEBUG_ISR_08);
+ debug_enter(regs, DEBUG_ISR_08);
floppy_tick();
@@ -536,8 +536,10 @@ handle_08(void)
usb_check_event();
// chain to user timer tick INT #0x1c
- u32 eax=0, flags;
- call16_simpint(0x1c, &eax, &flags);
+ struct bregs br;
+ memset(&br, 0, sizeof(br));
+ br.flags = F_IF;
+ call16_int(0x1c, &br);
eoi_pic1();
}
@@ -657,9 +659,9 @@ handle_1583(struct bregs *regs)
// int70h: IRQ8 - CMOS RTC
void VISIBLE16
-handle_70(void)
+handle_70(struct bregs *regs)
{
- debug_isr(DEBUG_ISR_70);
+ debug_enter(regs, DEBUG_ISR_70);
// Check which modes are enabled and have occurred.
u8 registerB = inb_cmos(CMOS_STATUS_B);
@@ -669,8 +671,10 @@ handle_70(void)
goto done;
if (registerC & RTC_B_AIE) {
// Handle Alarm Interrupt.
- u32 eax=0, flags;
- call16_simpint(0x4a, &eax, &flags);
+ struct bregs br;
+ memset(&br, 0, sizeof(br));
+ br.flags = F_IF;
+ call16_int(0x4a, &br);
}
if (!(registerC & RTC_B_PIE))
goto done;
diff --git a/src/disk.c b/src/disk.c
index 080d6cd..ed54e97 100644
--- a/src/disk.c
+++ b/src/disk.c
@@ -883,9 +883,9 @@ handle_13(struct bregs *regs)
// record completion in BIOS task complete flag
void VISIBLE16
-handle_76(void)
+handle_76(struct bregs *regs)
{
- debug_isr(DEBUG_ISR_76);
+ debug_enter(regs, DEBUG_ISR_76);
SET_BDA(disk_interrupt_flag, 0xff);
eoi_pic2();
}
diff --git a/src/floppy.c b/src/floppy.c
index 72bc79b..5400bb0 100644
--- a/src/floppy.c
+++ b/src/floppy.c
@@ -582,9 +582,9 @@ process_floppy_op(struct disk_op_s *op)
// INT 0Eh Diskette Hardware ISR Entry Point
void VISIBLE16
-handle_0e(void)
+handle_0e(struct bregs *regs)
{
- debug_isr(DEBUG_ISR_0e);
+ debug_enter(regs, DEBUG_ISR_0e);
if (! CONFIG_FLOPPY)
goto done;
diff --git a/src/kbd.c b/src/kbd.c
index fdb61d4..586d57e 100644
--- a/src/kbd.c
+++ b/src/kbd.c
@@ -379,7 +379,7 @@ static struct scaninfo {
};
// Handle a scancode read from the ps2 port. Note that "noinline" is
-// used to make sure the call to call16_simpint in process_key doesn't
+// used to make sure the call to call16_int in process_key doesn't
// have the overhead of this function's stack.
static void noinline
__process_key(u8 scancode)
@@ -562,12 +562,14 @@ process_key(u8 key)
if (CONFIG_KBD_CALL_INT15_4F) {
// allow for keyboard intercept
- u32 eax = (0x4f << 8) | key;
- u32 flags;
- call16_simpint(0x15, &eax, &flags);
- if (!(flags & F_CF))
+ struct bregs br;
+ memset(&br, 0, sizeof(br));
+ br.eax = (0x4f << 8) | key;
+ br.flags = F_IF|F_CF;
+ call16_int(0x15, &br);
+ if (!(br.flags & F_CF))
return;
- key = eax;
+ key = br.eax;
}
__process_key(key);
}
diff --git a/src/misc.c b/src/misc.c
index 9db49e3..d0d6665 100644
--- a/src/misc.c
+++ b/src/misc.c
@@ -55,9 +55,9 @@ handle_10(struct bregs *regs)
// NMI handler
void VISIBLE16
-handle_02(void)
+handle_02(struct bregs *regs)
{
- debug_isr(DEBUG_ISR_02);
+ debug_enter(regs, DEBUG_ISR_02);
}
void
@@ -71,17 +71,19 @@ mathcp_setup(void)
// INT 75 - IRQ13 - MATH COPROCESSOR EXCEPTION
void VISIBLE16
-handle_75(void)
+handle_75(struct bregs *regs)
{
- debug_isr(DEBUG_ISR_75);
+ debug_enter(regs, DEBUG_ISR_75);
// clear irq13
outb(0, PORT_MATH_CLEAR);
// clear interrupt
eoi_pic2();
// legacy nmi call
- u32 eax=0, flags;
- call16_simpint(0x02, &eax, &flags);
+ struct bregs br;
+ memset(&br, 0, sizeof(br));
+ br.flags = F_IF;
+ call16_int(0x02, &br);
}
diff --git a/src/mouse.c b/src/mouse.c
index 237c8ff..93e4ed2 100644
--- a/src/mouse.c
+++ b/src/mouse.c
@@ -6,8 +6,7 @@
// This file may be distributed under the terms of the GNU LGPLv3 license.
#include "biosvar.h" // GET_EBDA
-#include "util.h" // debug_isr
-#include "pic.h" // eoi_pic2
+#include "util.h" // dprintf
#include "bregs.h" // struct bregs
#include "ps2port.h" // ps2_mouse_command
#include "usb-hid.h" // usb_mouse_command
@@ -273,34 +272,12 @@ handle_15c2(struct bregs *regs)
}
}
-void noinline
-process_mouse(u8 data)
+static void
+invoke_mouse_handler(u16 ebda_seg)
{
- if (!CONFIG_MOUSE)
- return;
-
- u16 ebda_seg = get_ebda_seg();
- u8 mouse_flags_1 = GET_EBDA(ebda_seg, mouse_flag1);
- u8 mouse_flags_2 = GET_EBDA(ebda_seg, mouse_flag2);
-
- if (! (mouse_flags_2 & 0x80))
- // far call handler not installed
- return;
-
- u8 package_count = mouse_flags_2 & 0x07;
- u8 index = mouse_flags_1 & 0x07;
- SET_EBDA(ebda_seg, mouse_data[index], data);
-
- if ((index+1) < package_count) {
- mouse_flags_1++;
- SET_EBDA(ebda_seg, mouse_flag1, mouse_flags_1);
- return;
- }
-
u16 status = GET_EBDA(ebda_seg, mouse_data[0]);
u16 X = GET_EBDA(ebda_seg, mouse_data[1]);
u16 Y = GET_EBDA(ebda_seg, mouse_data[2]);
- SET_EBDA(ebda_seg, mouse_flag1, 0);
struct segoff_s func = GET_EBDA(ebda_seg, far_call_pointer);
dprintf(16, "mouse farcall s=%04x x=%04x y=%04x func=%04x:%04x\n"
@@ -325,3 +302,31 @@ process_mouse(u8 data)
:
: "edi", "esi", "cc", "memory");
}
+
+void noinline
+process_mouse(u8 data)
+{
+ if (!CONFIG_MOUSE)
+ return;
+
+ u16 ebda_seg = get_ebda_seg();
+ u8 mouse_flags_1 = GET_EBDA(ebda_seg, mouse_flag1);
+ u8 mouse_flags_2 = GET_EBDA(ebda_seg, mouse_flag2);
+
+ if (! (mouse_flags_2 & 0x80))
+ // far call handler not installed
+ return;
+
+ u8 package_count = mouse_flags_2 & 0x07;
+ u8 index = mouse_flags_1 & 0x07;
+ SET_EBDA(ebda_seg, mouse_data[index], data);
+
+ if ((index+1) < package_count) {
+ mouse_flags_1++;
+ SET_EBDA(ebda_seg, mouse_flag1, mouse_flags_1);
+ return;
+ }
+
+ SET_EBDA(ebda_seg, mouse_flag1, 0);
+ stack_hop_back(ebda_seg, 0, invoke_mouse_handler);
+}
diff --git a/src/output.c b/src/output.c
index 37c4942..1fe5d91 100644
--- a/src/output.c
+++ b/src/output.c
@@ -487,15 +487,6 @@ dump_regs(struct bregs *regs)
, regs->code.seg, regs->code.offset, regs->flags);
}
-// Report entry to an Interrupt Service Routine (ISR).
-void
-__debug_isr(const char *fname)
-{
- puts_cs(&debuginfo, fname);
- putc(&debuginfo, '\n');
- debug_serial_flush();
-}
-
// Function called on handler startup.
void
__debug_enter(struct bregs *regs, const char *fname)
diff --git a/src/ps2port.c b/src/ps2port.c
index 15bce8e..c835e14 100644
--- a/src/ps2port.c
+++ b/src/ps2port.c
@@ -357,12 +357,12 @@ ps2_mouse_command(int command, u8 *param)
// INT74h : PS/2 mouse hardware interrupt
void VISIBLE16
-handle_74(void)
+handle_74(struct bregs *regs)
{
if (! CONFIG_PS2PORT)
return;
- debug_isr(DEBUG_ISR_74);
+ debug_enter(regs, DEBUG_ISR_74);
u8 v = inb(PORT_PS2_STATUS);
if ((v & (I8042_STR_OBF|I8042_STR_AUXDATA))
@@ -384,12 +384,12 @@ done:
// INT09h : Keyboard Hardware Service Entry Point
void VISIBLE16
-handle_09(void)
+handle_09(struct bregs *regs)
{
if (! CONFIG_PS2PORT)
return;
- debug_isr(DEBUG_ISR_09);
+ debug_enter(regs, DEBUG_ISR_09);
// read key from keyboard controller
u8 v = inb(PORT_PS2_STATUS);
diff --git a/src/romlayout.S b/src/romlayout.S
index 147cd3b..aadc9cf 100644
--- a/src/romlayout.S
+++ b/src/romlayout.S
@@ -219,12 +219,15 @@ __call16big:
lretw
.endm
+ IRQ_TRAMPOLINE 02
IRQ_TRAMPOLINE 10
IRQ_TRAMPOLINE 13
IRQ_TRAMPOLINE 15
IRQ_TRAMPOLINE 16
IRQ_TRAMPOLINE 18
IRQ_TRAMPOLINE 19
+ IRQ_TRAMPOLINE 1c
+ IRQ_TRAMPOLINE 4a
/****************************************************************
@@ -386,10 +389,55 @@ entry_elf:
* Interrupt entry points
****************************************************************/
- // Main entry point for interrupts without args
- DECLFUNC irqentry
-irqentry:
- ENTRY_ST
+ // Main entry point for interrupts handled on extra stack
+ DECLFUNC irqentry_extrastack
+irqentry_extrastack:
+ cli
+ cld
+ pushw %ds
+ pushl %eax
+ movl $_datalow_seg, %eax
+ movl %eax, %ds
+ movl StackPos, %eax
+ subl $BREGS_size+12, %eax
+ popl BREGS_eax(%eax)
+ popw BREGS_ds(%eax)
+ movl %edi, BREGS_edi(%eax)
+ movl %esi, BREGS_esi(%eax)
+ movl %ebp, BREGS_ebp(%eax)
+ movl %ebx, BREGS_ebx(%eax)
+ movl %edx, BREGS_edx(%eax)
+ movl %ecx, BREGS_ecx(%eax)
+ movw %es, BREGS_es(%eax)
+ popl %ecx
+ popl BREGS_code(%eax)
+ popw BREGS_flags(%eax)
+
+ movw %ss, BREGS_size+8(%eax)
+ movzwl %sp, %edx
+ movl %edx, BREGS_size+4(%eax)
+ movl %esp, BREGS_size+0(%eax)
+ movw %ds, %dx
+ movw %dx, %ss
+ movl %eax, %esp
+ calll *%ecx
+
+ movl %esp, %eax
+ movw BREGS_size+8(%eax), %ss
+ movl BREGS_size+0(%eax), %esp
+ movl BREGS_edi(%eax), %edi
+ movl BREGS_esi(%eax), %esi
+ movl BREGS_ebp(%eax), %ebp
+ movl BREGS_ebx(%eax), %ebx
+ movl BREGS_edx(%eax), %edx
+ movl BREGS_ecx(%eax), %ecx
+ movw BREGS_es(%eax), %es
+ pushw BREGS_flags(%eax)
+ pushl BREGS_code(%eax)
+ pushw BREGS_ds(%eax)
+ pushl BREGS_eax(%eax)
+ popl %eax
+ popw %ds
iretw
// Main entry point for interrupts with args
@@ -398,12 +446,12 @@ irqentryarg:
ENTRY_ARG_ST
iretw
- // Define an entry point for an interrupt (no args passed).
+ // Define an entry point for hardware interrupts.
.macro IRQ_ENTRY num
.global entry_\num
entry_\num :
pushl $ handle_\num
- jmp irqentry
+ jmp irqentry_extrastack
.endm
.macro DECL_IRQ_ENTRY num
diff --git a/src/stacks.c b/src/stacks.c
index cfdd68d..2804e47 100644
--- a/src/stacks.c
+++ b/src/stacks.c
@@ -25,7 +25,7 @@ on_extra_stack(void)
}
// Switch to the extra stack and call a function.
-inline u32
+u32
stack_hop(u32 eax, u32 edx, void *func)
{
if (on_extra_stack())
@@ -58,7 +58,7 @@ stack_hop(u32 eax, u32 edx, void *func)
}
// Switch back to original caller's stack and call a function.
-static u32
+u32
stack_hop_back(u32 eax, u32 edx, void *func)
{
if (!on_extra_stack())
diff --git a/src/util.h b/src/util.h
index a4fabd5..0d41785 100644
--- a/src/util.h
+++ b/src/util.h
@@ -159,23 +159,6 @@ static inline u8 readb(const void *addr) {
return *(volatile const u8 *)addr;
}
-#define call16_simpint(nr, peax, pflags) do { \
- ASSERT16(); \
- asm volatile( \
- "pushl %%ebp\n" \
- "sti\n" \
- "stc\n" \
- "int %2\n" \
- "pushfl\n" \
- "popl %1\n" \
- "cli\n" \
- "cld\n" \
- "popl %%ebp" \
- : "+a"(*peax), "=c"(*pflags) \
- : "i"(nr) \
- : "ebx", "edx", "esi", "edi", "cc", "memory"); \
- } while (0)
-
// GDT bits
#define GDT_CODE (0x9bULL << 40) // Code segment - P,R,A bits also set
#define GDT_DATA (0x93ULL << 40) // Data segment - W,A bits also set
@@ -222,7 +205,8 @@ int get_keystroke(int msec);
// stacks.c
extern u8 ExtraStack[], *StackPos;
-inline u32 stack_hop(u32 eax, u32 edx, void *func);
+u32 stack_hop(u32 eax, u32 edx, void *func);
+u32 stack_hop_back(u32 eax, u32 edx, void *func);
u32 call32(void *func, u32 eax, u32 errret);
struct bregs;
inline void farcall16(struct bregs *callregs);
@@ -260,7 +244,6 @@ char * znprintf(size_t size, const char *fmt, ...)
void __dprintf(const char *fmt, ...)
__attribute__ ((format (printf, 1, 2)));
void __debug_enter(struct bregs *regs, const char *fname);
-void __debug_isr(const char *fname);
void __debug_stub(struct bregs *regs, int lineno, const char *fname);
void __warn_invalid(struct bregs *regs, int lineno, const char *fname);
void __warn_unimplemented(struct bregs *regs, int lineno, const char *fname);
@@ -282,10 +265,6 @@ void hexdump(const void *d, int len);
if ((lvl) && (lvl) <= CONFIG_DEBUG_LEVEL) \
__debug_enter((regs), __func__); \
} while (0)
-#define debug_isr(lvl) do { \
- if ((lvl) && (lvl) <= CONFIG_DEBUG_LEVEL) \
- __debug_isr(__func__); \
- } while (0)
#define debug_stub(regs) \
__debug_stub((regs), __LINE__, __func__)
#define warn_invalid(regs) \
diff --git a/tools/checkstack.py b/tools/checkstack.py
index 717de2d..23b7c8e 100755
--- a/tools/checkstack.py
+++ b/tools/checkstack.py
@@ -13,7 +13,7 @@ import sys
import re
# Functions that change stacks
-STACKHOP = ['__send_disk_op']
+STACKHOP = ['stack_hop', 'stack_hop_back']
# List of functions we can assume are never called.
#IGNORE = ['panic', '__dprintf']
IGNORE = ['panic']