xref: /minix/minix/kernel/utility.c (revision fb4fbf7a)
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(
55   int c					/* character to append */
56 )
57 {
58 /* Accumulate a single character for a kernel message. Send a notification
59  * to the output drivers if an END_OF_KMESS is encountered.
60  */
61   if (c != END_OF_KMESS) {
62       int maxblpos = sizeof(kmess.kmess_buf) - 2;
63 #ifdef DEBUG_SERIAL
64       if (kinfo.do_serial_debug) {
65 	if(c == '\n')
66       		ser_putc('\r');
67       	ser_putc(c);
68       }
69 #endif
70       kmess.km_buf[kmess.km_next] = c;	/* put normal char in buffer */
71       kmess.kmess_buf[kmess.blpos] = c;
72       if (kmess.km_size < sizeof(kmess.km_buf))
73           kmess.km_size += 1;
74       kmess.km_next = (kmess.km_next + 1) % _KMESS_BUF_SIZE;
75       if(kmess.blpos == maxblpos) {
76       	memmove(kmess.kmess_buf,
77 		kmess.kmess_buf+1, sizeof(kmess.kmess_buf)-1);
78       } else kmess.blpos++;
79   } else if (!(kinfo.minix_panicing || kinfo.do_serial_debug)) {
80 	send_diag_sig();
81   }
82 }
83 
84 /*===========================================================================*
85  *				_exit				     	     *
86  *===========================================================================*/
87 void _exit(
88   int e					/* error code */
89 )
90 {
91   panic("_exit called from within the kernel, should not happen. (err %i)", e);
92 }
93