make panic() work for multiboot/elf case
. 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
This commit is contained in:
parent
a73c217bf6
commit
2487445f5f
5 changed files with 118 additions and 70 deletions
|
@ -25,6 +25,7 @@
|
||||||
#include "oxpcie.h"
|
#include "oxpcie.h"
|
||||||
#include "kernel/proc.h"
|
#include "kernel/proc.h"
|
||||||
#include "kernel/debug.h"
|
#include "kernel/debug.h"
|
||||||
|
#include "mb_utils.h"
|
||||||
#include <machine/multiboot.h>
|
#include <machine/multiboot.h>
|
||||||
|
|
||||||
#include "glo.h"
|
#include "glo.h"
|
||||||
|
@ -85,15 +86,14 @@ PUBLIC int cpu_has_tsc;
|
||||||
|
|
||||||
PUBLIC __dead void arch_shutdown(int how)
|
PUBLIC __dead void arch_shutdown(int how)
|
||||||
{
|
{
|
||||||
static char mybuffer[sizeof(params_buffer)];
|
|
||||||
u16_t magic;
|
u16_t magic;
|
||||||
vm_stop();
|
vm_stop();
|
||||||
|
|
||||||
/* Mask all interrupts, including the clock. */
|
/* Mask all interrupts, including the clock. */
|
||||||
outb( INT_CTLMASK, ~0);
|
outb( INT_CTLMASK, ~0);
|
||||||
|
|
||||||
#if USE_BOOTPARAM
|
|
||||||
if(minix_panicing) {
|
if(minix_panicing) {
|
||||||
|
unsigned char unused_ch;
|
||||||
/* We're panicing? Then retrieve and decode currently
|
/* We're panicing? Then retrieve and decode currently
|
||||||
* loaded segment selectors.
|
* loaded segment selectors.
|
||||||
*/
|
*/
|
||||||
|
@ -102,8 +102,22 @@ PUBLIC __dead void arch_shutdown(int how)
|
||||||
if(read_ds() != read_ss()) {
|
if(read_ds() != read_ss()) {
|
||||||
printseg("ss: ", 0, NULL, 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) {
|
if (how == RBT_DEFAULT) {
|
||||||
how = mon_return ? RBT_HALT : RBT_RESET;
|
how = mon_return ? RBT_HALT : RBT_RESET;
|
||||||
}
|
}
|
||||||
|
@ -119,37 +133,7 @@ PUBLIC __dead void arch_shutdown(int how)
|
||||||
*/
|
*/
|
||||||
if (how != RBT_MONITOR)
|
if (how != RBT_MONITOR)
|
||||||
arch_set_params("", 1);
|
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)
|
if (mon_return)
|
||||||
arch_monitor();
|
arch_monitor();
|
||||||
|
|
||||||
|
@ -157,14 +141,7 @@ PUBLIC __dead void arch_shutdown(int how)
|
||||||
* depending on the parameters
|
* depending on the parameters
|
||||||
*/
|
*/
|
||||||
if (how == RBT_MONITOR) {
|
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;
|
how = RBT_RESET;
|
||||||
else
|
|
||||||
how = RBT_HALT;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -643,8 +620,6 @@ PUBLIC void arch_ack_profile_clock(void)
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#define COLOR_BASE 0xB8000L
|
|
||||||
|
|
||||||
/* Saved by mpx386.s into these variables. */
|
/* Saved by mpx386.s into these variables. */
|
||||||
u32_t params_size, params_offset, mon_ds;
|
u32_t params_size, params_offset, mon_ds;
|
||||||
|
|
||||||
|
|
12
kernel/arch/i386/mb_utils.h
Normal file
12
kernel/arch/i386/mb_utils.h
Normal file
|
@ -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
|
|
@ -16,6 +16,8 @@
|
||||||
#include "string.h"
|
#include "string.h"
|
||||||
#include "arch_proto.h"
|
#include "arch_proto.h"
|
||||||
#include "libexec.h"
|
#include "libexec.h"
|
||||||
|
#include "mb_utils.h"
|
||||||
|
#include "serial.h"
|
||||||
#include <machine/multiboot.h>
|
#include <machine/multiboot.h>
|
||||||
|
|
||||||
#if USE_SYSDEBUG
|
#if USE_SYSDEBUG
|
||||||
|
@ -38,8 +40,6 @@
|
||||||
#define mb_save_phymem(buf, phy, len) \
|
#define mb_save_phymem(buf, phy, len) \
|
||||||
phys_copy((u32_t)(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)
|
PRIVATE void mb_itoa(u32_t val, char * out)
|
||||||
{
|
{
|
||||||
char ret[ITOA_BUFFER_SIZE];
|
char ret[ITOA_BUFFER_SIZE];
|
||||||
|
@ -118,49 +118,103 @@ PRIVATE char mb_get_char(int line, int col)
|
||||||
/* Give non-zero values to avoid them in BSS */
|
/* Give non-zero values to avoid them in BSS */
|
||||||
PRIVATE int print_line = 1, print_col = 1;
|
PRIVATE int print_line = 1, print_col = 1;
|
||||||
|
|
||||||
PRIVATE void mb_cls(void)
|
#include <sys/video.h>
|
||||||
|
|
||||||
|
PUBLIC void mb_cls(void)
|
||||||
{
|
{
|
||||||
#if MULTIBOOT_VERBOSE
|
|
||||||
int i, j;
|
int i, j;
|
||||||
/* Clear screen */
|
/* Clear screen */
|
||||||
for (i = 0; i < MULTIBOOT_CONSOLE_LINES; i++ )
|
for (i = 0; i < MULTIBOOT_CONSOLE_LINES; i++ )
|
||||||
for (j = 0; j < MULTIBOOT_CONSOLE_COLS; j++ )
|
for (j = 0; j < MULTIBOOT_CONSOLE_COLS; j++ )
|
||||||
mb_put_char(0, i, j);
|
mb_put_char(0, i, j);
|
||||||
print_line = print_col = 0;
|
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)
|
PRIVATE void mb_scroll_up(int lines)
|
||||||
{
|
{
|
||||||
int i, j;
|
int i, j;
|
||||||
for (i = 0; i < MULTIBOOT_CONSOLE_LINES - lines; i++ ) {
|
for (i = 0; i < MULTIBOOT_CONSOLE_LINES; i++ ) {
|
||||||
for (j = 0; j < MULTIBOOT_CONSOLE_COLS; j++ )
|
for (j = 0; j < MULTIBOOT_CONSOLE_COLS; j++ ) {
|
||||||
mb_put_char(mb_get_char(i + lines, j), i, 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;
|
print_line-= lines;
|
||||||
}
|
}
|
||||||
|
|
||||||
PRIVATE void mb_print(char *str)
|
PUBLIC void mb_print_char(char c)
|
||||||
{
|
{
|
||||||
#if MULTIBOOT_VERBOSE
|
while (print_line >= MULTIBOOT_CONSOLE_LINES)
|
||||||
while (*str) {
|
mb_scroll_up(1);
|
||||||
if (*str == '\n') {
|
|
||||||
str++;
|
if (c == '\n') {
|
||||||
while (print_col < MULTIBOOT_CONSOLE_COLS)
|
while (print_col < MULTIBOOT_CONSOLE_COLS)
|
||||||
mb_put_char(' ', print_line, print_col++);
|
mb_put_char(' ', print_line, print_col++);
|
||||||
print_line++;
|
print_line++;
|
||||||
print_col = 0;
|
print_col = 0;
|
||||||
continue;
|
return;
|
||||||
}
|
}
|
||||||
mb_put_char(*str++, print_line, print_col++);
|
|
||||||
|
mb_put_char(c, print_line, print_col++);
|
||||||
|
|
||||||
if (print_col >= MULTIBOOT_CONSOLE_COLS) {
|
if (print_col >= MULTIBOOT_CONSOLE_COLS) {
|
||||||
print_line++;
|
print_line++;
|
||||||
print_col = 0;
|
print_col = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
while (print_line >= MULTIBOOT_CONSOLE_LINES)
|
while (print_line >= MULTIBOOT_CONSOLE_LINES)
|
||||||
mb_scroll_up(1);
|
mb_scroll_up(1);
|
||||||
}
|
}
|
||||||
#endif /* MULTIBOOT_VERBOSE */
|
|
||||||
|
PUBLIC void mb_print(char *str)
|
||||||
|
{
|
||||||
|
while (*str) {
|
||||||
|
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 /* 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)
|
PRIVATE void mb_print_hex(u32_t value)
|
||||||
|
|
|
@ -22,6 +22,7 @@
|
||||||
EXTERN struct kinfo kinfo; /* kernel information for users */
|
EXTERN struct kinfo kinfo; /* kernel information for users */
|
||||||
EXTERN struct machine machine; /* machine information for users */
|
EXTERN struct machine machine; /* machine information for users */
|
||||||
EXTERN struct kmessages kmess; /* diagnostic messages in kernel */
|
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 k_randomness krandom; /* gather kernel random information */
|
||||||
EXTERN struct loadinfo kloadinfo; /* status of load average */
|
EXTERN struct loadinfo kloadinfo; /* status of load average */
|
||||||
|
|
||||||
|
|
|
@ -23,7 +23,7 @@ PUBLIC void panic(const char *fmt, ...)
|
||||||
va_list arg;
|
va_list arg;
|
||||||
/* The system has run aground of a fatal kernel error. Terminate execution. */
|
/* The system has run aground of a fatal kernel error. Terminate execution. */
|
||||||
if (minix_panicing == ARE_PANICING) {
|
if (minix_panicing == ARE_PANICING) {
|
||||||
arch_monitor();
|
reset();
|
||||||
}
|
}
|
||||||
minix_panicing = ARE_PANICING;
|
minix_panicing = ARE_PANICING;
|
||||||
if (fmt != NULL) {
|
if (fmt != NULL) {
|
||||||
|
@ -53,6 +53,8 @@ int c; /* character to append */
|
||||||
* to the output driver if an END_OF_KMESS is encountered.
|
* to the output driver if an END_OF_KMESS is encountered.
|
||||||
*/
|
*/
|
||||||
if (c != END_OF_KMESS) {
|
if (c != END_OF_KMESS) {
|
||||||
|
static int blpos = 0;
|
||||||
|
int maxblpos = sizeof(kmess_buf) - 2;
|
||||||
#ifdef DEBUG_SERIAL
|
#ifdef DEBUG_SERIAL
|
||||||
if (do_serial_debug) {
|
if (do_serial_debug) {
|
||||||
if(c == '\n')
|
if(c == '\n')
|
||||||
|
@ -61,9 +63,13 @@ int c; /* character to append */
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
kmess.km_buf[kmess.km_next] = c; /* put normal char in buffer */
|
kmess.km_buf[kmess.km_next] = c; /* put normal char in buffer */
|
||||||
|
kmess_buf[blpos] = c;
|
||||||
if (kmess.km_size < sizeof(kmess.km_buf))
|
if (kmess.km_size < sizeof(kmess.km_buf))
|
||||||
kmess.km_size += 1;
|
kmess.km_size += 1;
|
||||||
kmess.km_next = (kmess.km_next + 1) % _KMESS_BUF_SIZE;
|
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 {
|
} else {
|
||||||
int p;
|
int p;
|
||||||
endpoint_t outprocs[] = OUTPUT_PROCS_ARRAY;
|
endpoint_t outprocs[] = OUTPUT_PROCS_ARRAY;
|
||||||
|
|
Loading…
Reference in a new issue