ChangeSet 1.1454, 2005/05/18 18:01:38+01:00, kaf24@xxxxxxxxxxxxxxxxxxxx
Manual merge.
console.c | 172 ++++++++++++++++++++++++++++++++++++++++++++++++++++++--------
1 files changed, 151 insertions(+), 21 deletions(-)
diff -Nru a/xen/drivers/char/console.c b/xen/drivers/char/console.c
--- a/xen/drivers/char/console.c 2005-05-18 14:02:52 -04:00
+++ b/xen/drivers/char/console.c 2005-05-18 14:02:52 -04:00
@@ -17,11 +17,13 @@
#include <xen/console.h>
#include <xen/serial.h>
#include <xen/keyhandler.h>
+#include <xen/mm.h>
#include <asm/uaccess.h>
-#include <asm/mm.h>
+#include <asm/debugger.h>
+#include <asm/io.h>
/* opt_console: comma-separated list of console outputs. */
-static unsigned char opt_console[30] = "com1,vga";
+static char opt_console[30] = OPT_CONSOLE_STR;
string_param("console", opt_console);
/* opt_conswitch: a character pair controlling console switching. */
@@ -49,7 +51,6 @@
spinlock_t console_lock = SPIN_LOCK_UNLOCKED;
-
/*
* *******************************************************
* *************** OUTPUT TO VGA CONSOLE *****************
@@ -252,12 +253,14 @@
static char *input_str[2] = { "DOM0", "Xen" };
xen_rx = !xen_rx;
if ( SWITCH_CODE != 0 )
+ {
printk("*** Serial input -> %s "
"(type 'CTRL-%c' three times to switch input to %s).\n",
input_str[xen_rx], opt_conswitch[0], input_str[!xen_rx]);
+ }
}
-static void __serial_rx(unsigned char c, struct xen_regs *regs)
+static void __serial_rx(unsigned char c, struct cpu_user_regs *regs)
{
if ( xen_rx )
return handle_keypress(c, regs);
@@ -266,10 +269,10 @@
if ( (serial_rx_prod-serial_rx_cons) != SERIAL_RX_SIZE )
serial_rx_ring[SERIAL_RX_MASK(serial_rx_prod++)] = c;
/* Always notify the guest: prevents receive path from getting stuck. */
- send_guest_virq(dom0, VIRQ_CONSOLE);
+ send_guest_virq(dom0->exec_domain[0], VIRQ_CONSOLE);
}
-static void serial_rx(unsigned char c, struct xen_regs *regs)
+static void serial_rx(unsigned char c, struct cpu_user_regs *regs)
{
static int switch_code_count = 0;
@@ -298,7 +301,7 @@
#ifndef VERBOSE
/* Only domain-0 may access the emergency console. */
- if ( current->id != 0 )
+ if ( current->domain->domain_id != 0 )
return -EPERM;
#endif
@@ -349,7 +352,9 @@
static inline void __putstr(const char *str)
{
int c;
+
serial_puts(sercon_handle, str);
+
while ( (c = *str++) != '\0' )
{
putchar_console(c);
@@ -402,7 +407,7 @@
void init_console(void)
{
- unsigned char *p;
+ char *p;
/* Where should console output go? */
for ( p = opt_console; p != NULL; p = strchr(p, ',') )
@@ -477,6 +482,124 @@
/*
* **************************************************************
+ * *************** Serial console ring buffer *******************
+ * **************************************************************
+ */
+
+#ifndef NDEBUG
+
+/* Send output direct to console, or buffer it? */
+int debugtrace_send_to_console;
+
+static char *debugtrace_buf; /* Debug-trace buffer */
+static unsigned int debugtrace_prd; /* Producer index */
+static unsigned int debugtrace_kilobytes = 128, debugtrace_bytes;
+static unsigned int debugtrace_used;
+static spinlock_t debugtrace_lock = SPIN_LOCK_UNLOCKED;
+integer_param("debugtrace", debugtrace_kilobytes);
+
+void debugtrace_dump(void)
+{
+ unsigned long flags;
+
+ if ( (debugtrace_bytes == 0) || !debugtrace_used )
+ return;
+
+ watchdog_disable();
+
+ spin_lock_irqsave(&debugtrace_lock, flags);
+
+ printk("debugtrace_dump() starting\n");
+
+ /* Print oldest portion of the ring. */
+ ASSERT(debugtrace_buf[debugtrace_bytes - 1] == 0);
+ serial_puts(sercon_handle, &debugtrace_buf[debugtrace_prd]);
+
+ /* Print youngest portion of the ring. */
+ debugtrace_buf[debugtrace_prd] = '\0';
+ serial_puts(sercon_handle, &debugtrace_buf[0]);
+
+ memset(debugtrace_buf, '\0', debugtrace_bytes);
+
+ printk("debugtrace_dump() finished\n");
+
+ spin_unlock_irqrestore(&debugtrace_lock, flags);
+
+ watchdog_enable();
+}
+
+void debugtrace_printk(const char *fmt, ...)
+{
+ static char buf[1024];
+
+ va_list args;
+ char *p;
+ unsigned long flags;
+
+ if ( debugtrace_bytes == 0 )
+ return;
+
+ debugtrace_used = 1;
+
+ spin_lock_irqsave(&debugtrace_lock, flags);
+
+ ASSERT(debugtrace_buf[debugtrace_bytes - 1] == 0);
+
+ va_start(args, fmt);
+ (void)vsnprintf(buf, sizeof(buf), fmt, args);
+ va_end(args);
+
+ if ( debugtrace_send_to_console )
+ {
+ serial_puts(sercon_handle, buf);
+ }
+ else
+ {
+ for ( p = buf; *p != '\0'; p++ )
+ {
+ debugtrace_buf[debugtrace_prd++] = *p;
+ /* Always leave a nul byte at the end of the buffer. */
+ if ( debugtrace_prd == (debugtrace_bytes - 1) )
+ debugtrace_prd = 0;
+ }
+ }
+
+ spin_unlock_irqrestore(&debugtrace_lock, flags);
+}
+
+static int __init debugtrace_init(void)
+{
+ int order;
+ unsigned int kbytes, bytes;
+
+ /* Round size down to next power of two. */
+ while ( (kbytes = (debugtrace_kilobytes & (debugtrace_kilobytes-1))) != 0 )
+ debugtrace_kilobytes = kbytes;
+
+ bytes = debugtrace_kilobytes << 10;
+ if ( bytes == 0 )
+ return 0;
+
+ order = get_order(bytes);
+ debugtrace_buf = (char *)alloc_xenheap_pages(order);
+ ASSERT(debugtrace_buf != NULL);
+
+ memset(debugtrace_buf, '\0', bytes);
+
+ debugtrace_bytes = bytes;
+
+ memset(debugtrace_buf, '\0', debugtrace_bytes);
+
+ return 0;
+}
+__initcall(debugtrace_init);
+
+#endif /* !NDEBUG */
+
+
+
+/*
+ * **************************************************************
* *************** Debugging/tracing/error-report ***************
* **************************************************************
*/
@@ -484,35 +607,42 @@
void panic(const char *fmt, ...)
{
va_list args;
- char buf[128];
+ char buf[128], cpustr[10];
unsigned long flags;
extern void machine_restart(char *);
+ debugtrace_dump();
+
va_start(args, fmt);
(void)vsnprintf(buf, sizeof(buf), fmt, args);
va_end(args);
-
+
+ debugger_trap_immediate();
+
/* Spit out multiline message in one go. */
spin_lock_irqsave(&console_lock, flags);
__putstr("\n****************************************\n");
+ __putstr("Panic on CPU");
+ sprintf(cpustr, "%d", smp_processor_id());
+ __putstr(cpustr);
+ __putstr(":\n");
__putstr(buf);
- __putstr("Aieee! CPU");
- sprintf(buf, "%d", smp_processor_id());
- __putstr(buf);
- __putstr(" is toast...\n");
__putstr("****************************************\n\n");
__putstr("Reboot in five seconds...\n");
spin_unlock_irqrestore(&console_lock, flags);
- watchdog_on = 0;
+ watchdog_disable();
mdelay(5000);
machine_restart(0);
}
+/*
_______________________________________________
Xen-changelog mailing list
Xen-changelog@xxxxxxxxxxxxxxxxxxx
http://lists.xensource.com/xen-changelog
|