#include "oxpcie.h"
#include "kernel/proc.h"
#include "kernel/debug.h"
+#include "mb_utils.h"
#include <machine/multiboot.h>
#include "glo.h"
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.
*/
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;
}
*/
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();
* 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;
}
}
#endif
-#define COLOR_BASE 0xB8000L
-
/* Saved by mpx386.s into these variables. */
u32_t params_size, params_offset, mon_ds;
--- /dev/null
+#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
#include "string.h"
#include "arch_proto.h"
#include "libexec.h"
+#include "mb_utils.h"
+#include "serial.h"
#include <machine/multiboot.h>
#if USE_SYSDEBUG
#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];
/* 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)
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 */
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) {
* 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')
}
#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;