1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26#include <stdarg.h>
27#include <machine/machine_routines.h>
28#include <pexpert/protos.h>
29#include <pexpert/pexpert.h>
30#include <pexpert/ppc/powermac.h>
31#include <pexpert/device_tree.h>
32#include <kern/debug.h>
33#include <kern/simple_lock.h>
34
35
36extern void init_display_putc(unsigned char*, int, int);
37extern void display_putc(char c);
38extern int scc_putc(int unit, int line, int c);
39extern void cnputc(char c);
40
41
42void serial_putc(char c);
43
44
45void (*PE_kputc)(char c) = 0;
46
47unsigned int disableSerialOuput = TRUE;
48
49vm_offset_t scc = 0;
50
51struct slock kprintf_lock;
52
53void PE_init_kprintf(boolean_t vm_initialized)
54{
55 unsigned int boot_arg;
56 int32_t cnt, size, serial_baud = -1;
57 DTEntry options;
58 char *str, baud[7];
59
60 if (PE_state.initialized == FALSE)
61 panic("Platform Expert not initialized");
62
63 if (PE_parse_boot_arg("debug", &boot_arg))
64 if(boot_arg & DB_KPRT) disableSerialOuput = FALSE;
65
66 if (DTLookupEntry(0, "/options", &options) == kSuccess) {
67 if (DTGetProperty(options, "input-device", &str, &size) == kSuccess) {
68 if ((size > 5) && !strncmp("scca:", str, 5)) {
69 size -= 5;
70 str += 5;
71 if (size <= 6) {
72 strncpy(baud, str, size);
73 baud[size] = '\0';
74 gPESerialBaud = strtol(baud, 0, 0);
75 }
76 }
77 }
78 if (DTGetProperty(options, "output-device", &str, &size) == kSuccess) {
79 if ((size > 5) && !strncmp("scca:", str, 5)) {
80 size -= 5;
81 str += 5;
82 if (size <= 6) {
83 strncpy(baud, str, size);
84 baud[size] = '\0';
85 gPESerialBaud = strtol(baud, 0, 0);
86 }
87 }
88 }
89 }
90
91
92 if (PE_parse_boot_arg("serialbaud", &serial_baud))
93 if (serial_baud != -1) gPESerialBaud = serial_baud;
94
95 if( (scc = PE_find_scc())) {
96 scc = io_map_spec(scc, 0x1000);
97 initialize_serial((void *)scc, gPESerialBaud);
98 PE_kputc = serial_putc;
99
100 simple_lock_init(&kprintf_lock, 0);
101 } else
102 PE_kputc = cnputc;
103
104#if 0
105
106
107
108
109 switch (PE_state.debug_video.v_display) {
110 case kDebugTypeSerial:
111 PE_kputc = serial_putc;
112 break;
113
114 case kDebugTypeDisplay:
115 init_display_putc( (unsigned char*)PE_state.debug_video.v_baseAddr,
116 PE_state.debug_video.v_rowBytes,
117 PE_state.debug_video.v_height);
118 PE_kputc = display_putc;
119 break;
120
121 default:
122 PE_state.debug_video.v_baseAddr = 0;
123 }
124#endif
125}
126
127void serial_putc(char c)
128{
129 (void) scc_putc(0, 1, c);
130 if (c == '\n') (void) scc_putc(0, 1, '\r');
131
132#if 0
133 (void) scc_putc(0, (int)PE_state.debug_video.v_baseAddr, c);
134 if (c == '\n') (void) scc_putc(0, (int)PE_state.debug_video.v_baseAddr, '\r');
135#endif
136}
137
138void kprintf(const char *fmt, ...)
139{
140 va_list listp;
141 boolean_t state;
142
143 state = ml_set_interrupts_enabled(FALSE);
144 simple_lock(&kprintf_lock);
145
146 if (!disableSerialOuput) {
147 va_start(listp, fmt);
148 _doprnt(fmt, &listp, PE_kputc, 16);
149 va_end(listp);
150 }
151
152 simple_unlock(&kprintf_lock);
153 ml_set_interrupts_enabled(state);
154}
155
156