xref: /minix3/minix/kernel/utility.c (revision 81ae2bc455a73c05792f181d5497cdbd33f3c135)
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 Sambuc void 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ätz void 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ätz void _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