]> Zhao Yanbai Git Server - minix.git/commitdiff
make panic() work for multiboot/elf case
authorEvgeniy Ivanov <lolkaantimat@gmail.com>
Sun, 12 Feb 2012 15:11:47 +0000 (19:11 +0400)
committerBen Gras <ben@minix3.org>
Tue, 14 Feb 2012 13:48:10 +0000 (14:48 +0100)
. we cannot use the boot monitor to print the system diag buffer
. for serial, we do nothing, just reset, everything is already printed
. for not-serial, we print the current diag buffer using direct video
  memory access from the kernel

kernel/arch/i386/arch_system.c
kernel/arch/i386/mb_utils.h [new file with mode: 0644]
kernel/arch/i386/pre_init.c
kernel/glo.h
kernel/utility.c

index b4f33ab2121c3f66b4d9cf56e693dc2692216f6a..022beac082ca847e6cb7939fbfd9679a2b135b07 100644 (file)
@@ -25,6 +25,7 @@
 #include "oxpcie.h"
 #include "kernel/proc.h"
 #include "kernel/debug.h"
+#include "mb_utils.h"
 #include <machine/multiboot.h>
 
 #include "glo.h"
@@ -85,15 +86,14 @@ PUBLIC int cpu_has_tsc;
 
 PUBLIC __dead void arch_shutdown(int how)
 {
-       static char mybuffer[sizeof(params_buffer)];
        u16_t magic;
        vm_stop();
 
        /* Mask all interrupts, including the clock. */
        outb( INT_CTLMASK, ~0);
 
-#if USE_BOOTPARAM
        if(minix_panicing) {
+               unsigned char unused_ch;
                /* We're panicing? Then retrieve and decode currently
                 * loaded segment selectors.
                 */
@@ -102,8 +102,22 @@ PUBLIC __dead void arch_shutdown(int how)
                if(read_ds() != read_ss()) {
                        printseg("ss: ", 0, NULL, read_ss());
                }
+
+               /* Printing is done synchronously over serial. */
+               if (do_serial_debug)
+                       reset();
+
+               /* Print accumulated diagnostics buffer and reset. */
+               mb_cls();
+               mb_print("Minix panic. System diagnostics buffer:\n\n");
+               mb_print(kmess_buf);
+               mb_print("\nSystem has panicked, press any key to reboot");
+               while (!mb_read_char(&unused_ch))
+                       ;
+               reset();
        }
 
+#if USE_BOOTPARAM
        if (how == RBT_DEFAULT) {
                how = mon_return ? RBT_HALT : RBT_RESET;
        }
@@ -119,37 +133,7 @@ PUBLIC __dead void arch_shutdown(int how)
                 */
                if (how != RBT_MONITOR)
                        arch_set_params("", 1);
-               if(minix_panicing) {
-                       int source, dest;
-                       const char *lead = "echo \\n*** kernel messages:\\n";
-                       const int leadlen = strlen(lead);
-                       strcpy(mybuffer, lead);
-
-#define DECSOURCE source = (source - 1 + _KMESS_BUF_SIZE) % _KMESS_BUF_SIZE
-
-                       dest = sizeof(mybuffer)-1;
-                       mybuffer[dest--] = '\0';
-
-                       source = kmess.km_next;
-                       DECSOURCE; 
-
-                       while(dest >= leadlen) {
-                               const char c = kmess.km_buf[source];
-                               if(c == '\n') {
-                                       mybuffer[dest--] = 'n';
-                                       mybuffer[dest] = '\\';
-                               } else if(isprint(c) &&
-                                       c != '\'' && c != '"' &&
-                                       c != '\\' && c != ';') {
-                                       mybuffer[dest] = c;
-                               } else  mybuffer[dest] = ' ';
-
-                               DECSOURCE;
-                               dest--;
-                       }
 
-                       arch_set_params(mybuffer, strlen(mybuffer)+1);
-               }
                if (mon_return)
                        arch_monitor();
 
@@ -157,14 +141,7 @@ PUBLIC __dead void arch_shutdown(int how)
                 * depending on the parameters
                 */
                if (how == RBT_MONITOR) {
-                       mybuffer[0] = '\0';
-                       arch_get_params(mybuffer, sizeof(mybuffer));
-                       if (strstr(mybuffer, "boot") ||
-                               strstr(mybuffer, "menu") ||     
-                               strstr(mybuffer, "reset"))
-                               how = RBT_RESET;
-                       else
-                               how = RBT_HALT;
+                       how = RBT_RESET;
                }
        }
 
@@ -643,8 +620,6 @@ PUBLIC void arch_ack_profile_clock(void)
 
 #endif
 
-#define COLOR_BASE     0xB8000L
-
 /* Saved by mpx386.s into these variables. */
 u32_t params_size, params_offset, mon_ds;
 
diff --git a/kernel/arch/i386/mb_utils.h b/kernel/arch/i386/mb_utils.h
new file mode 100644 (file)
index 0000000..a17753d
--- /dev/null
@@ -0,0 +1,12 @@
+#ifndef MB_UTILS_H
+#define MB_UTILS_H
+
+#include "kernel/kernel.h"
+
+_PROTOTYPE(void mb_cls, (void));
+_PROTOTYPE(void mb_print, (char*));
+_PROTOTYPE(void mb_print_char, (char));
+_PROTOTYPE(int mb_read_char, (unsigned char*));
+
+
+#endif
index fe020b9f6f209a62b271b1024f096a44f7bf8441..eef6d4cf354b920fc78da913fdb940a552cef32d 100644 (file)
@@ -16,6 +16,8 @@
 #include "string.h"
 #include "arch_proto.h"
 #include "libexec.h"
+#include "mb_utils.h"
+#include "serial.h"
 #include <machine/multiboot.h>
 
 #if USE_SYSDEBUG
@@ -38,8 +40,6 @@
 #define mb_save_phymem(buf, phy, len) \
                phys_copy((u32_t)(buf), (phy), (len))
 
-FORWARD _PROTOTYPE(void mb_print, (char *str));
-
 PRIVATE void mb_itoa(u32_t val, char * out) 
 {
        char ret[ITOA_BUFFER_SIZE];
@@ -117,50 +117,104 @@ PRIVATE char mb_get_char(int line, int col)
 
 /* Give non-zero values to avoid them in BSS */
 PRIVATE int print_line = 1, print_col = 1;
+
+#include <sys/video.h>
        
-PRIVATE void mb_cls(void) 
+PUBLIC void mb_cls(void)
 {
-#if MULTIBOOT_VERBOSE
        int i, j;
        /* Clear screen */
        for (i = 0; i < MULTIBOOT_CONSOLE_LINES; i++ )
                for (j = 0; j < MULTIBOOT_CONSOLE_COLS; j++ )
                        mb_put_char(0, i, j);
        print_line = print_col = 0;
-#endif
+
+       /* Tell video hardware origin is 0. */
+       outb(C_6845+INDEX, VID_ORG);
+       outb(C_6845+DATA, 0);
+       outb(C_6845+INDEX, VID_ORG+1);
+       outb(C_6845+DATA, 0);
 }
 
 PRIVATE void mb_scroll_up(int lines) 
 {
        int i, j;
-       for (i = 0; i < MULTIBOOT_CONSOLE_LINES - lines; i++ ) {
-               for (j = 0; j < MULTIBOOT_CONSOLE_COLS; j++ )
-                       mb_put_char(mb_get_char(i + lines, j), i, j);
+       for (i = 0; i < MULTIBOOT_CONSOLE_LINES; i++ ) {
+               for (j = 0; j < MULTIBOOT_CONSOLE_COLS; j++ ) {
+                       char c = 0;
+                       if(i < MULTIBOOT_CONSOLE_LINES-lines)
+                               c = mb_get_char(i + lines, j);
+                       mb_put_char(c, i, j);
+               }
        }
        print_line-= lines;
 }
 
-PRIVATE void mb_print(char *str) 
+PUBLIC void mb_print_char(char c)
+{
+       while (print_line >= MULTIBOOT_CONSOLE_LINES)
+               mb_scroll_up(1);
+
+       if (c == '\n') {
+               while (print_col < MULTIBOOT_CONSOLE_COLS)
+                       mb_put_char(' ', print_line, print_col++);
+               print_line++;
+               print_col = 0;
+               return;
+       }
+
+       mb_put_char(c, print_line, print_col++);
+
+       if (print_col >= MULTIBOOT_CONSOLE_COLS) {
+               print_line++;
+               print_col = 0;
+       }
+
+       while (print_line >= MULTIBOOT_CONSOLE_LINES)
+               mb_scroll_up(1);
+}
+
+PUBLIC void mb_print(char *str)
 {
-#if MULTIBOOT_VERBOSE
        while (*str) {
-               if (*str == '\n') {
-                       str++;
-                       while (print_col < MULTIBOOT_CONSOLE_COLS)
-                               mb_put_char(' ', print_line, print_col++);
-                       print_line++;
-                       print_col = 0;
-                       continue;
-               }
-               mb_put_char(*str++, print_line, print_col++);
-               if (print_col >= MULTIBOOT_CONSOLE_COLS) {
-                       print_line++;
-                       print_col = 0;
-               }
-               while (print_line >= MULTIBOOT_CONSOLE_LINES)
-                       mb_scroll_up(1);
+               mb_print_char(*str);
+               str++;
+       }
+}
+
+/* Standard and AT keyboard.  (PS/2 MCA implies AT throughout.) */
+#define KEYBD          0x60    /* I/O port for keyboard data */
+#define KB_STATUS      0x64    /* I/O port for status on AT */
+#define KB_OUT_FULL    0x01    /* status bit set when keypress char pending */
+#define KB_AUX_BYTE    0x20    /* Auxiliary Device Output Buffer Full */
+
+PUBLIC int mb_read_char(unsigned char *ch)
+{
+       unsigned long b, sb;
+#ifdef DEBUG_SERIAL
+       u8_t c, lsr;
+
+       if (do_serial_debug) {
+               lsr= inb(COM1_LSR);
+               if (!(lsr & LSR_DR))
+                       return 0;
+               c = inb(COM1_RBR);
+               return 1;
        }
-#endif /* MULTIBOOT_VERBOSE */
+#endif /* DEBUG_SERIAL */
+
+       sb = inb(KB_STATUS);
+
+       if (!(sb & KB_OUT_FULL)) {
+               return 0;
+       }
+
+       b = inb(KEYBD);
+
+       if (!(sb & KB_AUX_BYTE))
+               return 1;
+
+       return 0;
 }
 
 PRIVATE void mb_print_hex(u32_t value) 
index 51adb7583536813c18d8dc5deaf687e54a0d6073..a0deadf212ee6a1292b6c572f6a40b21bc8cdbc7 100644 (file)
@@ -22,6 +22,7 @@
 EXTERN struct kinfo kinfo;             /* kernel information for users */
 EXTERN struct machine machine;         /* machine information for users */
 EXTERN struct kmessages kmess;         /* diagnostic messages in kernel */
+EXTERN char kmess_buf[80*25];          /* printable copy of message buffer */
 EXTERN struct k_randomness krandom;    /* gather kernel random information */
 EXTERN struct loadinfo kloadinfo;      /* status of load average */
 
index fdae2506f816df917fbed4b595106ddc9944d7f1..2dcb98fd7760f1b11d4b5eb4332de2f7567d1972 100644 (file)
@@ -23,7 +23,7 @@ PUBLIC void panic(const char *fmt, ...)
   va_list arg;
   /* The system has run aground of a fatal kernel error. Terminate execution. */
   if (minix_panicing == ARE_PANICING) {
-       arch_monitor();
+       reset();
   }
   minix_panicing = ARE_PANICING;
   if (fmt != NULL) {
@@ -53,6 +53,8 @@ int c;                                        /* character to append */
  * to the output driver if an END_OF_KMESS is encountered. 
  */
   if (c != END_OF_KMESS) {
+      static int blpos = 0;
+      int maxblpos = sizeof(kmess_buf) - 2;
 #ifdef DEBUG_SERIAL
       if (do_serial_debug) {
        if(c == '\n')
@@ -61,9 +63,13 @@ int c;                                       /* character to append */
       }
 #endif
       kmess.km_buf[kmess.km_next] = c; /* put normal char in buffer */
+      kmess_buf[blpos] = c;
       if (kmess.km_size < sizeof(kmess.km_buf))
           kmess.km_size += 1;          
       kmess.km_next = (kmess.km_next + 1) % _KMESS_BUF_SIZE;
+      if(blpos == maxblpos) {
+       memmove(kmess_buf, kmess_buf+1, sizeof(kmess_buf)-1);
+      } else blpos++;
   } else {
       int p;
       endpoint_t outprocs[] = OUTPUT_PROCS_ARRAY;