[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Xen-changelog] Manual merge.



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


 


Rackspace

Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.