* added 0.99 linux version
[mascara-docs.git] / i386 / linux / linux-2.3.21 / arch / ppc / xmon / start.c
blob1b0fffd7128cc831a7fec6787e659cef6966f35a
1 /*
2 * Copyright (C) 1996 Paul Mackerras.
3 */
4 #include <linux/config.h>
5 #include <linux/string.h>
6 #include <asm/machdep.h>
7 #include <asm/io.h>
8 #include <asm/page.h>
9 #include <asm/pgtable.h>
10 #include <linux/adb.h>
11 #include <linux/pmu.h>
12 #include <asm/prom.h>
13 #include <asm/bootx.h>
15 static volatile unsigned char *sccc, *sccd;
16 unsigned long TXRDY, RXRDY;
17 extern void xmon_printf(const char *fmt, ...);
18 extern void map_bootx_text(void);
19 extern void drawchar(char);
20 extern void drawstring(const char *str);
22 static int console = 0;
23 static int use_screen = 0;
25 void buf_access(void)
27 if ( _machine == _MACH_chrp )
28 sccd[3] &= ~0x80; /* reset DLAB */
31 void
32 xmon_map_scc(void)
34 volatile unsigned char *base;
36 if ( _machine == _MACH_Pmac )
38 struct device_node *np;
39 extern boot_infos_t *boot_infos;
40 unsigned long addr;
42 #ifdef CONFIG_BOOTX_TEXT
43 if (boot_infos != 0 && find_via_pmu()) {
44 printk(KERN_INFO "xmon uses screen and keyboard\n");
45 use_screen = 1;
46 map_bootx_text();
47 return;
49 #endif
50 #ifdef CHRP_ESCC
51 addr = 0xc1013020;
52 #else
53 addr = 0xf3013020;
54 #endif
55 TXRDY = 4;
56 RXRDY = 1;
58 np = find_devices("mac-io");
59 if (np && np->n_addrs) {
60 addr = np->addrs[0].address + 0x13000;
61 /* use the B channel on the iMac, A channel on others */
62 if (addr >= 0xf0000000)
63 addr += 0x20; /* use A channel */
65 base = (volatile unsigned char *) ioremap(addr & PAGE_MASK, PAGE_SIZE);
66 sccc = base + (addr & ~PAGE_MASK);
67 #ifdef CHRP_ESCC
68 sccd = sccc + (0xc1013030 - 0xc1013020);
69 #else
70 sccd = sccc + (0xf3013030 - 0xf3013020);
71 #endif
73 else
75 /* should already be mapped by the kernel boot */
76 sccc = (volatile unsigned char *) (isa_io_base + 0x3fd);
77 sccd = (volatile unsigned char *) (isa_io_base + 0x3f8);
78 TXRDY = 0x20;
79 RXRDY = 1;
83 static int scc_initialized = 0;
85 void xmon_init_scc(void);
86 extern void pmu_poll(void);
88 int
89 xmon_write(void *handle, void *ptr, int nb)
91 char *p = ptr;
92 int i, ct;
94 #ifdef CONFIG_BOOTX_TEXT
95 if (use_screen) {
96 /* write it on the screen */
97 for (i = 0; i < nb; ++i)
98 drawchar(*p++);
99 return nb;
101 #endif
102 if (!scc_initialized)
103 xmon_init_scc();
104 for (i = 0; i < nb; ++i) {
105 while ((*sccc & TXRDY) == 0)
106 if (sys_ctrler == SYS_CTRLER_PMU)
107 pmu_poll();
108 buf_access();
109 if ( console && (*p != '\r'))
110 printk("%c", *p);
111 ct = 0;
112 if ( *p == '\n')
113 ct = 1;
114 *sccd = *p++;
115 if ( ct )
116 xmon_write(handle, "\r", 1);
118 return i;
121 int xmon_wants_key;
122 int xmon_pmu_keycode;
124 #ifdef CONFIG_BOOTX_TEXT
125 static int xmon_pmu_shiftstate;
127 static unsigned char xmon_keytab[128] =
128 "asdfhgzxcv\000bqwer" /* 0x00 - 0x0f */
129 "yt123465=97-80o]" /* 0x10 - 0x1f */
130 "u[ip\rlj'k;\\,/nm." /* 0x20 - 0x2f */
131 "\t `\177\0\033\0\0\0\0\0\0\0\0\0\0" /* 0x30 - 0x3f */
132 "\0.\0*\0+\0\0\0\0\0/\r\0-\0" /* 0x40 - 0x4f */
133 "\0\0000123456789\0\0\0"; /* 0x50 - 0x5f */
135 static unsigned char xmon_shift_keytab[128] =
136 "ASDFHGZXCV\000BQWER" /* 0x00 - 0x0f */
137 "YT!@#$^%+(&=*)}O" /* 0x10 - 0x1f */
138 "U{IP\rLJ\"K:|<?NM>" /* 0x20 - 0x2f */
139 "\t ~\177\0\033\0\0\0\0\0\0\0\0\0\0" /* 0x30 - 0x3f */
140 "\0.\0*\0+\0\0\0\0\0/\r\0-\0" /* 0x40 - 0x4f */
141 "\0\0000123456789\0\0\0"; /* 0x50 - 0x5f */
143 static int
144 xmon_get_pmu_key(void)
146 int k, t, on;
148 xmon_wants_key = 1;
149 for (;;) {
150 xmon_pmu_keycode = -1;
151 t = 0;
152 on = 0;
153 do {
154 if (--t < 0) {
155 on = 1 - on;
156 drawchar(on? 0xdb: 0x20);
157 drawchar('\b');
158 t = 200000;
160 pmu_poll();
161 } while (xmon_pmu_keycode == -1);
162 k = xmon_pmu_keycode;
163 if (on)
164 drawstring(" \b");
166 /* test for shift keys */
167 if ((k & 0x7f) == 0x38 || (k & 0x7f) == 0x7b) {
168 xmon_pmu_shiftstate = (k & 0x80) == 0;
169 continue;
171 if (k >= 0x80)
172 continue; /* ignore up transitions */
173 k = (xmon_pmu_shiftstate? xmon_shift_keytab: xmon_keytab)[k];
174 if (k != 0)
175 break;
177 xmon_wants_key = 0;
178 return k;
180 #endif /* CONFIG_BOOTX_TEXT */
183 xmon_read(void *handle, void *ptr, int nb)
185 char *p = ptr;
186 int i;
188 #ifdef CONFIG_BOOTX_TEXT
189 if (use_screen) {
190 for (i = 0; i < nb; ++i)
191 *p++ = xmon_get_pmu_key();
192 return i;
194 #endif
195 if (!scc_initialized)
196 xmon_init_scc();
197 for (i = 0; i < nb; ++i) {
198 while ((*sccc & RXRDY) == 0)
199 if (sys_ctrler == SYS_CTRLER_PMU)
200 pmu_poll();
201 buf_access();
202 #if 0
203 if ( 0/*console*/ )
204 *p++ = ppc_md.kbd_getkeycode();
205 else
206 #endif
207 *p++ = *sccd;
209 return i;
212 static unsigned char scc_inittab[] = {
213 13, 0, /* set baud rate divisor */
214 12, 1,
215 14, 1, /* baud rate gen enable, src=rtxc */
216 11, 0x50, /* clocks = br gen */
217 5, 0x6a, /* tx 8 bits, assert RTS */
218 4, 0x44, /* x16 clock, 1 stop */
219 3, 0xc1, /* rx enable, 8 bits */
222 void
223 xmon_init_scc()
225 if ( _machine == _MACH_chrp )
227 sccd[3] = 0x83; eieio(); /* LCR = 8N1 + DLAB */
228 sccd[0] = 3; eieio(); /* DLL = 38400 baud */
229 sccd[1] = 0; eieio();
230 sccd[2] = 0; eieio(); /* FCR = 0 */
231 sccd[3] = 3; eieio(); /* LCR = 8N1 */
232 sccd[1] = 0; eieio(); /* IER = 0 */
234 else
236 int i, x;
238 for (i = 20000; i != 0; --i) {
239 x = *sccc; eieio();
241 *sccc = 9; eieio(); /* reset A or B side */
242 *sccc = ((unsigned long)sccc & 0x20)? 0x80: 0x40; eieio();
243 for (i = 0; i < sizeof(scc_inittab); ++i) {
244 *sccc = scc_inittab[i];
245 eieio();
248 scc_initialized = 1;
251 #if 0
252 extern int (*prom_entry)(void *);
255 xmon_exit(void)
257 struct prom_args {
258 char *service;
259 } args;
261 for (;;) {
262 args.service = "exit";
263 (*prom_entry)(&args);
266 #endif
268 void *xmon_stdin;
269 void *xmon_stdout;
270 void *xmon_stderr;
272 void
273 xmon_init(void)
278 xmon_putc(int c, void *f)
280 char ch = c;
282 if (c == '\n')
283 xmon_putc('\r', f);
284 return xmon_write(f, &ch, 1) == 1? c: -1;
288 xmon_putchar(int c)
290 return xmon_putc(c, xmon_stdout);
294 xmon_fputs(char *str, void *f)
296 int n = strlen(str);
298 return xmon_write(f, str, n) == n? 0: -1;
302 xmon_readchar(void)
304 char ch;
306 for (;;) {
307 switch (xmon_read(xmon_stdin, &ch, 1)) {
308 case 1:
309 return ch;
310 case -1:
311 xmon_printf("read(stdin) returned -1\r\n", 0, 0);
312 return -1;
317 static char line[256];
318 static char *lineptr;
319 static int lineleft;
322 xmon_getchar(void)
324 int c;
326 if (lineleft == 0) {
327 lineptr = line;
328 for (;;) {
329 c = xmon_readchar();
330 if (c == -1 || c == 4)
331 break;
332 if (c == '\r' || c == '\n') {
333 *lineptr++ = '\n';
334 xmon_putchar('\n');
335 break;
337 switch (c) {
338 case 0177:
339 case '\b':
340 if (lineptr > line) {
341 xmon_putchar('\b');
342 xmon_putchar(' ');
343 xmon_putchar('\b');
344 --lineptr;
346 break;
347 case 'U' & 0x1F:
348 while (lineptr > line) {
349 xmon_putchar('\b');
350 xmon_putchar(' ');
351 xmon_putchar('\b');
352 --lineptr;
354 break;
355 default:
356 if (lineptr >= &line[sizeof(line) - 1])
357 xmon_putchar('\a');
358 else {
359 xmon_putchar(c);
360 *lineptr++ = c;
364 lineleft = lineptr - line;
365 lineptr = line;
367 if (lineleft == 0)
368 return -1;
369 --lineleft;
370 return *lineptr++;
373 char *
374 xmon_fgets(char *str, int nb, void *f)
376 char *p;
377 int c;
379 for (p = str; p < str + nb - 1; ) {
380 c = xmon_getchar();
381 if (c == -1) {
382 if (p == str)
383 return 0;
384 break;
386 *p++ = c;
387 if (c == '\n')
388 break;
390 *p = 0;
391 return str;