diff options
author | cl349@freefall.cl.cam.ac.uk <cl349@freefall.cl.cam.ac.uk> | 2004-11-12 17:21:13 +0000 |
---|---|---|
committer | cl349@freefall.cl.cam.ac.uk <cl349@freefall.cl.cam.ac.uk> | 2004-11-12 17:21:13 +0000 |
commit | c35cd837f62e8ff4f951327aa6cf2de6f2c78255 (patch) | |
tree | cd8e959bd4a6ddf220436bfbbf88bb48b7300a1e | |
parent | 5da67c5f110443d63da475d0a87a0249a3322d1a (diff) | |
parent | 1b8bcd6f21cc91011cedfa9535625c5321aedd31 (diff) | |
download | xen-c35cd837f62e8ff4f951327aa6cf2de6f2c78255.tar.gz xen-c35cd837f62e8ff4f951327aa6cf2de6f2c78255.tar.bz2 xen-c35cd837f62e8ff4f951327aa6cf2de6f2c78255.zip |
bitkeeper revision 1.1159.170.13 (4194f109iXlnhuZNs5l5WjDDk5pnXA)
Merge freefall.cl.cam.ac.uk:/auto/groups/xeno/BK/xeno.bk
into freefall.cl.cam.ac.uk:/auto/groups/xeno/users/cl349/BK/xen.bk-ddb
-rw-r--r-- | .rootkeys | 1 | ||||
-rw-r--r-- | xen/arch/x86/traps.c | 30 | ||||
-rw-r--r-- | xen/common/keyhandler.c | 25 | ||||
-rw-r--r-- | xen/common/vsprintf.c | 4 | ||||
-rw-r--r-- | xen/drivers/char/console.c | 17 | ||||
-rw-r--r-- | xen/drivers/char/serial.c | 39 | ||||
-rw-r--r-- | xen/include/xen/console.h | 4 | ||||
-rw-r--r-- | xen/include/xen/debugger_hooks.h | 37 | ||||
-rw-r--r-- | xen/include/xen/keyhandler.h | 7 | ||||
-rw-r--r-- | xen/include/xen/serial.h | 4 |
10 files changed, 131 insertions, 37 deletions
@@ -768,6 +768,7 @@ 3ddb79c259jh8hE7vre_8NuE7nwNSA xen/include/xen/config.h 3eb165e0eawr3R-p2ZQtSdLWtLRN_A xen/include/xen/console.h 3ddb79c1V44RD26YqCUm-kqIupM37A xen/include/xen/ctype.h +4194efbdvxUXjCLobbopgLOojisO4Q xen/include/xen/debugger_hooks.h 3ddb79c05DdHQ0UxX_jKsXdR4QlMCA xen/include/xen/delay.h 3ddb79c2O729EttZTYu1c8LcsUO_GQ xen/include/xen/elf.h 3ddb79c0HIghfBF8zFUdmXhOU8i6hA xen/include/xen/errno.h diff --git a/xen/arch/x86/traps.c b/xen/arch/x86/traps.c index b15939d6cf..2026432ec0 100644 --- a/xen/arch/x86/traps.c +++ b/xen/arch/x86/traps.c @@ -51,6 +51,7 @@ #include <asm/uaccess.h> #include <asm/i387.h> #include <asm/pdb.h> +#include <xen/debugger_hooks.h> extern char opt_nmi[]; @@ -243,6 +244,9 @@ static inline void do_trap(int trapnr, char *str, return; } + if (debugger_trap(trapnr, regs)) + return; + show_registers(regs); panic("CPU%d FATAL TRAP: vector = %d (%s)\n" "[error_code=%08x]\n", @@ -280,10 +284,8 @@ asmlinkage void do_int3(struct xen_regs *regs, long error_code) struct guest_trap_bounce *gtb = guest_trap_bounce+smp_processor_id(); trap_info_t *ti; -#ifdef XEN_DEBUGGER - if ( pdb_initialized && pdb_handle_exception(3, regs) == 0 ) + if (debugger_trap(3, regs)) return; -#endif if ( (regs->cs & 3) != 3 ) { @@ -329,6 +331,8 @@ asmlinkage void do_double_fault(void) printk("System needs manual reset.\n"); printk("************************************\n"); + debugger_trap(8, NULL); + /* Lock up the console to prevent spurious output from other CPUs. */ console_force_lock(); @@ -406,6 +410,9 @@ asmlinkage void do_page_fault(struct xen_regs *regs, long error_code) return; } + if (debugger_trap(14, regs)) + return; + if ( addr >= PAGE_OFFSET ) { unsigned long page; @@ -423,17 +430,6 @@ asmlinkage void do_page_fault(struct xen_regs *regs, long error_code) #endif } -#ifdef XEN_DEBUGGER - if ( pdb_page_fault_possible ) - { - pdb_page_fault = 1; - /* make eax & edx valid to complete the instruction */ - regs->eax = (long)&pdb_page_fault_scratch; - regs->edx = (long)&pdb_page_fault_scratch; - return; - } -#endif - show_registers(regs); panic("CPU%d FATAL PAGE FAULT\n" "[error_code=%08x]\n" @@ -520,6 +516,9 @@ asmlinkage void do_general_protection(struct xen_regs *regs, long error_code) return; } + if (debugger_trap(13, regs)) + return; + die("general protection fault", regs, error_code); } @@ -565,6 +564,9 @@ asmlinkage void io_check_error(struct xen_regs *regs) static void unknown_nmi_error(unsigned char reason, struct xen_regs * regs) { + if (debugger_trap(2, regs)) + return; + printk("Uhhuh. NMI received for unknown reason %02x.\n", reason); printk("Dazed and confused, but trying to continue\n"); printk("Do you have a strange power saving mode enabled?\n"); diff --git a/xen/common/keyhandler.c b/xen/common/keyhandler.c index d52aabd771..045f861880 100644 --- a/xen/common/keyhandler.c +++ b/xen/common/keyhandler.c @@ -11,10 +11,13 @@ #define STR_MAX 64 static struct { - key_handler *handler; + key_handler *handler; + int flags; char desc[STR_MAX]; } key_table[KEY_MAX]; +#define KEYHANDLER_NO_DEFER 0x1 + static unsigned char keypress_key; void keypress_softirq(void) @@ -25,19 +28,33 @@ void keypress_softirq(void) (*h)(key); } -void handle_keypress(unsigned char key) +void handle_keypress(unsigned char key, struct xen_regs *regs) { + key_handler *h; + keypress_key = key; - raise_softirq(KEYPRESS_SOFTIRQ); + if ( (key_table[key].flags & KEYHANDLER_NO_DEFER) && + ((h = key_table[key].handler) != NULL) ) + ((void (*)(unsigned char, struct xen_regs *))*h)(key, regs); + else + raise_softirq(KEYPRESS_SOFTIRQ); } void add_key_handler(unsigned char key, key_handler *handler, char *desc) { - key_table[key].handler = handler; + key_table[key].handler = handler; + key_table[key].flags = 0; strncpy(key_table[key].desc, desc, STR_MAX); key_table[key].desc[STR_MAX-1] = '\0'; } +void add_key_handler_no_defer(unsigned char key, key_handler *handler, + char *desc) +{ + add_key_handler(key, handler, desc); + key_table[key].flags |= KEYHANDLER_NO_DEFER; +} + static void show_handlers(unsigned char key) { int i; diff --git a/xen/common/vsprintf.c b/xen/common/vsprintf.c index cfda9601d1..906e7734db 100644 --- a/xen/common/vsprintf.c +++ b/xen/common/vsprintf.c @@ -315,6 +315,10 @@ int vsnprintf(char *buf, size_t size, const char *fmt, va_list args) ++fmt; } } + if (*fmt == 'q') { + qualifier = 'L'; + ++fmt; + } /* default base */ base = 10; diff --git a/xen/drivers/char/console.c b/xen/drivers/char/console.c index 51e97fc82f..cb57740996 100644 --- a/xen/drivers/char/console.c +++ b/xen/drivers/char/console.c @@ -247,7 +247,7 @@ static void __serial_rx(unsigned char c, struct xen_regs *regs) { if ( xen_rx ) { - handle_keypress(c); + handle_keypress(c, regs); } else if ( (serial_rx_prod-serial_rx_cons) != SERIAL_RX_SIZE ) { @@ -436,6 +436,21 @@ void console_force_lock(void) spin_lock(&console_lock); } +void console_putc(char c) +{ + serial_putc(sercon_handle, c); +} + +int console_getc(void) +{ + return serial_getc(sercon_handle); +} + +int irq_console_getc(void) +{ + return irq_serial_getc(sercon_handle); +} + /* * ************************************************************** diff --git a/xen/drivers/char/serial.c b/xen/drivers/char/serial.c index 8ca8972175..bdd1995f52 100644 --- a/xen/drivers/char/serial.c +++ b/xen/drivers/char/serial.c @@ -416,13 +416,10 @@ static int byte_matches(int handle, unsigned char *pc) return 0; } -unsigned char serial_getc(int handle) +unsigned char irq_serial_getc(int handle) { uart_t *uart = &com[handle & SERHND_IDX]; unsigned char c; - unsigned long flags; - - spin_lock_irqsave(&uart->lock, flags); while ( uart->rxbufp != uart->rxbufc ) { @@ -431,16 +428,6 @@ unsigned char serial_getc(int handle) goto out; } - disable_irq(uart->irq); - - /* disable_irq() may have raced execution of uart_rx(). */ - while ( uart->rxbufp != uart->rxbufc ) - { - c = uart->rxbuf[MASK_RXBUF_IDX(uart->rxbufc++)]; - if ( byte_matches(handle, &c) ) - goto enable_and_out; - } - /* We now wait for the UART to receive a suitable character. */ do { while ( (inb(uart->io_base + LSR) & LSR_DR) == 0 ) @@ -449,7 +436,29 @@ unsigned char serial_getc(int handle) } while ( !byte_matches(handle, &c) ); - enable_and_out: + out: + return c; +} + +unsigned char serial_getc(int handle) +{ + uart_t *uart = &com[handle & SERHND_IDX]; + unsigned char c; + unsigned long flags; + + spin_lock_irqsave(&uart->lock, flags); + + while ( uart->rxbufp != uart->rxbufc ) + { + c = uart->rxbuf[MASK_RXBUF_IDX(uart->rxbufc++)]; + if ( byte_matches(handle, &c) ) + goto out; + } + + disable_irq(uart->irq); + + c = irq_serial_getc(handle); + enable_irq(uart->irq); out: spin_unlock_irqrestore(&uart->lock, flags); diff --git a/xen/include/xen/console.h b/xen/include/xen/console.h index 628eb044d4..abcb2fa1d8 100644 --- a/xen/include/xen/console.h +++ b/xen/include/xen/console.h @@ -22,4 +22,8 @@ void console_endboot(int disable_vga); void console_force_unlock(void); void console_force_lock(void); +void console_putc(char c); +int console_getc(void); +int irq_console_getc(void); + #endif diff --git a/xen/include/xen/debugger_hooks.h b/xen/include/xen/debugger_hooks.h new file mode 100644 index 0000000000..4663b2b3bd --- /dev/null +++ b/xen/include/xen/debugger_hooks.h @@ -0,0 +1,37 @@ + +#ifndef __DEBUGGER_HOOKS_H__ +#define __DEBUGGER_HOOKS_H__ + +static inline int debugger_trap(int type, struct xen_regs *regs) +{ + int ret = 0; + +#ifdef XEN_DEBUGGER + switch (type) { + case 3: + if ( pdb_initialized && pdb_handle_exception(type, regs) == 0 ) + return 1; + break; + case 14: + if ( pdb_page_fault_possible ) + { + pdb_page_fault = 1; + /* make eax & edx valid to complete the instruction */ + regs->eax = (long)&pdb_page_fault_scratch; + regs->edx = (long)&pdb_page_fault_scratch; + return 1; + } + break; + } +#endif + +#if 0 + extern int kdb_trap(int, int, struct xen_regs *); + if ((ret = kdb_trap(type, 0, regs))) + return ret; +#endif + + return ret; +} + +#endif /* __DEBUGGER_HOOKS_H__ */ diff --git a/xen/include/xen/keyhandler.h b/xen/include/xen/keyhandler.h index d12621ef33..09e2f234ad 100644 --- a/xen/include/xen/keyhandler.h +++ b/xen/include/xen/keyhandler.h @@ -4,12 +4,13 @@ ** debug flag, dump registers, reboot, etc) to be hooked in in a slightly ** nicer fashion than just editing the serial/keyboard drivers. */ -#include <xen/sched.h> +struct xen_regs; typedef void key_handler(unsigned char key); extern void add_key_handler(unsigned char key, key_handler *handler, char *desc); +extern void add_key_handler_no_defer(unsigned char key, + key_handler *handler, char *desc); -extern void handle_keypress(unsigned char key); - +extern void handle_keypress(unsigned char key, struct xen_regs *regs); diff --git a/xen/include/xen/serial.h b/xen/include/xen/serial.h index c0ffebbbd9..5c40db3e7d 100644 --- a/xen/include/xen/serial.h +++ b/xen/include/xen/serial.h @@ -42,6 +42,10 @@ void serial_puts(int handle, const unsigned char *s); * called with interrupts disabled. */ unsigned char serial_getc(int handle); +/* + * Same as serial_getc but can also be called from interrupt handlers. + */ +unsigned char irq_serial_getc(int handle); void serial_force_unlock(int handle); |