xref: /minix3/minix/kernel/utility.c (revision 0b98e8aad89f2bd4ba80b523d73cf29e9dd82ce1)
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 	printf("\n");
35   }
36 
37   printf("kernel on CPU %d: ", cpuid);
38   util_stacktrace();
39 
40 #if 0
41   if(get_cpulocal_var(proc_ptr)) {
42 	  printf("current process : ");
43 	  proc_stacktrace(get_cpulocal_var(proc_ptr));
44   }
45 #endif
46 
47   /* Abort MINIX. */
48   minix_shutdown(NULL);
49 }
50 
51 /*===========================================================================*
52  *				kputc				     	     *
53  *===========================================================================*/
54 void kputc(c)
55 int c;					/* character to append */
56 {
57 /* Accumulate a single character for a kernel message. Send a notification
58  * to the output drivers if an END_OF_KMESS is encountered.
59  */
60   if (c != END_OF_KMESS) {
61       int maxblpos = sizeof(kmess.kmess_buf) - 2;
62 #ifdef DEBUG_SERIAL
63       if (kinfo.do_serial_debug) {
64 	if(c == '\n')
65       		ser_putc('\r');
66       	ser_putc(c);
67       }
68 #endif
69       kmess.km_buf[kmess.km_next] = c;	/* put normal char in buffer */
70       kmess.kmess_buf[kmess.blpos] = c;
71       if (kmess.km_size < sizeof(kmess.km_buf))
72           kmess.km_size += 1;
73       kmess.km_next = (kmess.km_next + 1) % _KMESS_BUF_SIZE;
74       if(kmess.blpos == maxblpos) {
75       	memmove(kmess.kmess_buf,
76 		kmess.kmess_buf+1, sizeof(kmess.kmess_buf)-1);
77       } else kmess.blpos++;
78   } else if (!(kinfo.minix_panicing || kinfo.do_serial_debug)) {
79 	send_diag_sig();
80   }
81 }
82 
83 /*===========================================================================*
84  *				_exit				     	     *
85  *===========================================================================*/
86 void _exit(e)
87 int e;					/* error code */
88 {
89   panic("_exit called from within the kernel, should not happen. (err %i)", e);
90 }
91