aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorcl349@freefall.cl.cam.ac.uk <cl349@freefall.cl.cam.ac.uk>2004-11-12 17:21:13 +0000
committercl349@freefall.cl.cam.ac.uk <cl349@freefall.cl.cam.ac.uk>2004-11-12 17:21:13 +0000
commitc35cd837f62e8ff4f951327aa6cf2de6f2c78255 (patch)
treecd8e959bd4a6ddf220436bfbbf88bb48b7300a1e
parent5da67c5f110443d63da475d0a87a0249a3322d1a (diff)
parent1b8bcd6f21cc91011cedfa9535625c5321aedd31 (diff)
downloadxen-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--.rootkeys1
-rw-r--r--xen/arch/x86/traps.c30
-rw-r--r--xen/common/keyhandler.c25
-rw-r--r--xen/common/vsprintf.c4
-rw-r--r--xen/drivers/char/console.c17
-rw-r--r--xen/drivers/char/serial.c39
-rw-r--r--xen/include/xen/console.h4
-rw-r--r--xen/include/xen/debugger_hooks.h37
-rw-r--r--xen/include/xen/keyhandler.h7
-rw-r--r--xen/include/xen/serial.h4
10 files changed, 131 insertions, 37 deletions
diff --git a/.rootkeys b/.rootkeys
index c6a8030301..45ec7aa3a7 100644
--- a/.rootkeys
+++ b/.rootkeys
@@ -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);