1433d6423SLionel Sambuc /* This file contains a collection of miscellaneous procedures: 2433d6423SLionel Sambuc * panic: abort MINIX due to a fatal error 3433d6423SLionel Sambuc * kputc: buffered putc used by kernel printf 4433d6423SLionel Sambuc */ 5433d6423SLionel Sambuc 6433d6423SLionel Sambuc #include "kernel/kernel.h" 7433d6423SLionel Sambuc #include "arch_proto.h" 8433d6423SLionel Sambuc 9433d6423SLionel Sambuc #include <minix/syslib.h> 10433d6423SLionel Sambuc #include <unistd.h> 11433d6423SLionel Sambuc #include <stdarg.h> 12433d6423SLionel Sambuc #include <signal.h> 13433d6423SLionel Sambuc #include <string.h> 14433d6423SLionel Sambuc 15433d6423SLionel Sambuc #include <minix/sys_config.h> 16433d6423SLionel Sambuc 17433d6423SLionel Sambuc #define ARE_PANICING 0xDEADC0FF 18433d6423SLionel Sambuc 19433d6423SLionel Sambuc /*===========================================================================* 20433d6423SLionel Sambuc * panic * 21433d6423SLionel Sambuc *===========================================================================*/ panic(const char * fmt,...)22433d6423SLionel Sambucvoid panic(const char *fmt, ...) 23433d6423SLionel Sambuc { 24433d6423SLionel Sambuc va_list arg; 25433d6423SLionel Sambuc /* The system has run aground of a fatal kernel error. Terminate execution. */ 26433d6423SLionel Sambuc if (kinfo.minix_panicing == ARE_PANICING) { 27433d6423SLionel Sambuc reset(); 28433d6423SLionel Sambuc } 29433d6423SLionel Sambuc kinfo.minix_panicing = ARE_PANICING; 30433d6423SLionel Sambuc if (fmt != NULL) { 31433d6423SLionel Sambuc printf("kernel panic: "); 32433d6423SLionel Sambuc va_start(arg, fmt); 33433d6423SLionel Sambuc vprintf(fmt, arg); 34*81ae2bc4SBen Mezger va_end(arg); 35433d6423SLionel Sambuc printf("\n"); 36433d6423SLionel Sambuc } 37433d6423SLionel Sambuc 38433d6423SLionel Sambuc printf("kernel on CPU %d: ", cpuid); 39433d6423SLionel Sambuc util_stacktrace(); 40433d6423SLionel Sambuc 41433d6423SLionel Sambuc #if 0 42433d6423SLionel Sambuc if(get_cpulocal_var(proc_ptr)) { 43433d6423SLionel Sambuc printf("current process : "); 44433d6423SLionel Sambuc proc_stacktrace(get_cpulocal_var(proc_ptr)); 45433d6423SLionel Sambuc } 46433d6423SLionel Sambuc #endif 47433d6423SLionel Sambuc 48433d6423SLionel Sambuc /* Abort MINIX. */ 49cfd712b4SDavid van Moolenbroek minix_shutdown(0); 50433d6423SLionel Sambuc } 51433d6423SLionel Sambuc 52433d6423SLionel Sambuc /*===========================================================================* 53433d6423SLionel Sambuc * kputc * 54433d6423SLionel Sambuc *===========================================================================*/ kputc(int c)556077d1adSDr. Florian Grätzvoid kputc( 566077d1adSDr. Florian Grätz int c /* character to append */ 576077d1adSDr. Florian Grätz ) 58433d6423SLionel Sambuc { 59433d6423SLionel Sambuc /* Accumulate a single character for a kernel message. Send a notification 60433d6423SLionel Sambuc * to the output drivers if an END_OF_KMESS is encountered. 61433d6423SLionel Sambuc */ 62433d6423SLionel Sambuc if (c != END_OF_KMESS) { 63433d6423SLionel Sambuc int maxblpos = sizeof(kmess.kmess_buf) - 2; 64433d6423SLionel Sambuc #ifdef DEBUG_SERIAL 65433d6423SLionel Sambuc if (kinfo.do_serial_debug) { 66433d6423SLionel Sambuc if(c == '\n') 67433d6423SLionel Sambuc ser_putc('\r'); 68433d6423SLionel Sambuc ser_putc(c); 69433d6423SLionel Sambuc } 70433d6423SLionel Sambuc #endif 71433d6423SLionel Sambuc kmess.km_buf[kmess.km_next] = c; /* put normal char in buffer */ 72433d6423SLionel Sambuc kmess.kmess_buf[kmess.blpos] = c; 73433d6423SLionel Sambuc if (kmess.km_size < sizeof(kmess.km_buf)) 74433d6423SLionel Sambuc kmess.km_size += 1; 75433d6423SLionel Sambuc kmess.km_next = (kmess.km_next + 1) % _KMESS_BUF_SIZE; 76433d6423SLionel Sambuc if(kmess.blpos == maxblpos) { 77433d6423SLionel Sambuc memmove(kmess.kmess_buf, 78433d6423SLionel Sambuc kmess.kmess_buf+1, sizeof(kmess.kmess_buf)-1); 79433d6423SLionel Sambuc } else kmess.blpos++; 80433d6423SLionel Sambuc } else if (!(kinfo.minix_panicing || kinfo.do_serial_debug)) { 81433d6423SLionel Sambuc send_diag_sig(); 82433d6423SLionel Sambuc } 83433d6423SLionel Sambuc } 84433d6423SLionel Sambuc 85433d6423SLionel Sambuc /*===========================================================================* 86433d6423SLionel Sambuc * _exit * 87433d6423SLionel Sambuc *===========================================================================*/ _exit(int e)886077d1adSDr. Florian Grätzvoid _exit( 896077d1adSDr. Florian Grätz int e /* error code */ 906077d1adSDr. Florian Grätz ) 91433d6423SLionel Sambuc { 92433d6423SLionel Sambuc panic("_exit called from within the kernel, should not happen. (err %i)", e); 93433d6423SLionel Sambuc } 94