xref: /minix/minix/kernel/utility.c (revision 35b65c5a)
1 /* This file contains a collection of miscellaneous procedures:
2  *   panic:    abort MINIX due to a fatal error
3  *   kputc:          buffered putc used by kernel printf
4  */
5 
6 #include "kernel/kernel.h"
7 #include "arch_proto.h"
8 
9 #include <minix/syslib.h>
10 #include <unistd.h>
11 #include <stdarg.h>
12 #include <signal.h>
13 #include <string.h>
14 
15 #include <minix/sys_config.h>
16 
17 #define ARE_PANICING 0xDEADC0FF
18 
19 /*===========================================================================*
20  *			panic                                          *
21  *===========================================================================*/
22 void panic(const char *fmt, ...)
23 {
24   va_list arg;
25   /* The system has run aground of a fatal kernel error. Terminate execution. */
26   if (kinfo.minix_panicing == ARE_PANICING) {
27   	reset();
28   }
29   kinfo.minix_panicing = ARE_PANICING;
30   if (fmt != NULL) {
31 	printf("kernel panic: ");
32   	va_start(arg, fmt);
33 	vprintf(fmt, arg);
34 	va_end(arg);
35 	printf("\n");
36   }
37 
38   printf("kernel on CPU %d: ", cpuid);
39   util_stacktrace();
40 
41 #if 0
42   if(get_cpulocal_var(proc_ptr)) {
43 	  printf("current process : ");
44 	  proc_stacktrace(get_cpulocal_var(proc_ptr));
45   }
46 #endif
47 
48   /* Abort MINIX. */
49   minix_shutdown(0);
50 }
51 
52 /*===========================================================================*
53  *				kputc				     	     *
54  *===========================================================================*/
55 void kputc(
56   int c					/* character to append */
57 )
58 {
59 /* Accumulate a single character for a kernel message. Send a notification
60  * to the output drivers if an END_OF_KMESS is encountered.
61  */
62   if (c != END_OF_KMESS) {
63       int maxblpos = sizeof(kmess.kmess_buf) - 2;
64 #ifdef DEBUG_SERIAL
65       if (kinfo.do_serial_debug) {
66 	if(c == '\n')
67       		ser_putc('\r');
68       	ser_putc(c);
69       }
70 #endif
71       kmess.km_buf[kmess.km_next] = c;	/* put normal char in buffer */
72       kmess.kmess_buf[kmess.blpos] = c;
73       if (kmess.km_size < sizeof(kmess.km_buf))
74           kmess.km_size += 1;
75       kmess.km_next = (kmess.km_next + 1) % _KMESS_BUF_SIZE;
76       if(kmess.blpos == maxblpos) {
77       	memmove(kmess.kmess_buf,
78 		kmess.kmess_buf+1, sizeof(kmess.kmess_buf)-1);
79       } else kmess.blpos++;
80   } else if (!(kinfo.minix_panicing || kinfo.do_serial_debug)) {
81 	send_diag_sig();
82   }
83 }
84 
85 /*===========================================================================*
86  *				_exit				     	     *
87  *===========================================================================*/
88 void _exit(
89   int e					/* error code */
90 )
91 {
92   panic("_exit called from within the kernel, should not happen. (err %i)", e);
93 }
94