File: /usr/src/linux/arch/ppc/boot/pmac/start.c

1     /*
2      * BK Id: SCCS/s.start.c 1.10 07/25/01 18:13:07 trini
3      */
4     /*
5      * Copyright (C) Paul Mackerras 1997.
6      *
7      * This program is free software; you can redistribute it and/or
8      * modify it under the terms of the GNU General Public License
9      * as published by the Free Software Foundation; either version
10      * 2 of the License, or (at your option) any later version.
11      */
12     #include <stdarg.h>
13     
14     extern int strlen(const char *s);
15     extern void boot(int a1, int a2, void *prom);
16     
17     int (*prom)();
18     
19     void *chosen_handle;
20     void *stdin;
21     void *stdout;
22     void *stderr;
23     
24     void exit(void);
25     void *finddevice(const char *name);
26     int getprop(void *phandle, const char *name, void *buf, int buflen);
27     void printk(char *fmt, ...);
28     
29     void
30     start(int a1, int a2, void *promptr)
31     {
32         prom = (int (*)()) promptr;
33         chosen_handle = finddevice("/chosen");
34         if (chosen_handle == (void *) -1)
35     	exit();
36         if (getprop(chosen_handle, "stdout", &stdout, sizeof(stdout)) != 4)
37     	exit();
38         stderr = stdout;
39         if (getprop(chosen_handle, "stdin", &stdin, sizeof(stdin)) != 4)
40     	exit();
41     
42         boot(a1, a2, promptr);
43         for (;;)
44     	exit();
45     }
46     
47     int
48     write(void *handle, void *ptr, int nb)
49     {
50         struct prom_args {
51     	char *service;
52     	int nargs;
53     	int nret;
54     	void *ihandle;
55     	void *addr;
56     	int len;
57     	int actual;
58         } args;
59     
60         args.service = "write";
61         args.nargs = 3;
62         args.nret = 1;
63         args.ihandle = handle;
64         args.addr = ptr;
65         args.len = nb;
66         args.actual = -1;
67         (*prom)(&args);
68         return args.actual;
69     }
70     
71     int writestring(void *f, char *ptr, int nb)
72     {
73     	int w = 0, i;
74     	char *ret = "\r";
75     
76     	for (i = 0; i < nb; ++i) {
77     		if (ptr[i] == '\n') {
78     			if (i > w) {
79     				write(f, ptr + w, i - w);
80     				w = i;
81     			}
82     			write(f, ret, 1);
83     		}
84     	}
85     	if (w < nb)
86     		write(f, ptr + w, nb - w);
87     	return nb;
88     }
89     
90     int
91     read(void *handle, void *ptr, int nb)
92     {
93         struct prom_args {
94     	char *service;
95     	int nargs;
96     	int nret;
97     	void *ihandle;
98     	void *addr;
99     	int len;
100     	int actual;
101         } args;
102     
103         args.service = "read";
104         args.nargs = 3;
105         args.nret = 1;
106         args.ihandle = handle;
107         args.addr = ptr;
108         args.len = nb;
109         args.actual = -1;
110         (*prom)(&args);
111         return args.actual;
112     }
113     
114     void
115     exit(void)
116     {
117         struct prom_args {
118     	char *service;
119         } args;
120     
121         for (;;) {
122     	args.service = "exit";
123     	(*prom)(&args);
124         }
125     }
126     
127     void
128     pause(void)
129     {
130         struct prom_args {
131     	char *service;
132         } args;
133     
134         args.service = "enter";
135         (*prom)(&args);
136     }
137     
138     void *
139     finddevice(const char *name)
140     {
141         struct prom_args {
142     	char *service;
143     	int nargs;
144     	int nret;
145     	const char *devspec;
146     	void *phandle;
147         } args;
148     
149         args.service = "finddevice";
150         args.nargs = 1;
151         args.nret = 1;
152         args.devspec = name;
153         args.phandle = (void *) -1;
154         (*prom)(&args);
155         return args.phandle;
156     }
157     
158     void *
159     claim(unsigned int virt, unsigned int size, unsigned int align)
160     {
161         struct prom_args {
162     	char *service;
163     	int nargs;
164     	int nret;
165     	unsigned int virt;
166     	unsigned int size;
167     	unsigned int align;
168     	void *ret;
169         } args;
170     
171         args.service = "claim";
172         args.nargs = 3;
173         args.nret = 1;
174         args.virt = virt;
175         args.size = size;
176         args.align = align;
177         (*prom)(&args);
178         return args.ret;
179     }
180     
181     void
182     release(void *virt, unsigned int size)
183     {
184         struct prom_args {
185     	char *service;
186     	int nargs;
187     	int nret;
188     	void *virt;
189     	unsigned int size;
190         } args;
191     
192         args.service = "release";
193         args.nargs = 2;
194         args.nret = 0;
195         args.virt = virt;
196         args.size = size;
197         (*prom)(&args);
198     }
199     
200     int
201     getprop(void *phandle, const char *name, void *buf, int buflen)
202     {
203         struct prom_args {
204     	char *service;
205     	int nargs;
206     	int nret;
207     	void *phandle;
208     	const char *name;
209     	void *buf;
210     	int buflen;
211     	int size;
212         } args;
213     
214         args.service = "getprop";
215         args.nargs = 4;
216         args.nret = 1;
217         args.phandle = phandle;
218         args.name = name;
219         args.buf = buf;
220         args.buflen = buflen;
221         args.size = -1;
222         (*prom)(&args);
223         return args.size;
224     }
225     
226     int
227     putc(int c, void *f)
228     {
229         char ch = c;
230     
231         return writestring(f, &ch, 1) == 1? c: -1;
232     }
233     
234     int
235     putchar(int c)
236     {
237         return putc(c, stdout);
238     }
239     
240     int
241     fputs(char *str, void *f)
242     {
243         int n = strlen(str);
244     
245         return writestring(f, str, n) == n? 0: -1;
246     }
247     
248     int
249     readchar(void)
250     {
251         char ch;
252     
253         for (;;) {
254     	switch (read(stdin, &ch, 1)) {
255     	case 1:
256     	    return ch;
257     	case -1:
258     	    printk("read(stdin) returned -1\n");
259     	    return -1;
260     	}
261         }
262     }
263     
264     static char line[256];
265     static char *lineptr;
266     static int lineleft;
267     
268     int
269     getchar(void)
270     {
271         int c;
272     
273         if (lineleft == 0) {
274     	lineptr = line;
275     	for (;;) {
276     	    c = readchar();
277     	    if (c == -1 || c == 4)
278     		break;
279     	    if (c == '\r' || c == '\n') {
280     		*lineptr++ = '\n';
281     		putchar('\n');
282     		break;
283     	    }
284     	    switch (c) {
285     	    case 0177:
286     	    case '\b':
287     		if (lineptr > line) {
288     		    putchar('\b');
289     		    putchar(' ');
290     		    putchar('\b');
291     		    --lineptr;
292     		}
293     		break;
294     	    case 'U' & 0x1F:
295     		while (lineptr > line) {
296     		    putchar('\b');
297     		    putchar(' ');
298     		    putchar('\b');
299     		    --lineptr;
300     		}
301     		break;
302     	    default:
303     		if (lineptr >= &line[sizeof(line) - 1])
304     		    putchar('\a');
305     		else {
306     		    putchar(c);
307     		    *lineptr++ = c;
308     		}
309     	    }
310     	}
311     	lineleft = lineptr - line;
312     	lineptr = line;
313         }
314         if (lineleft == 0)
315     	return -1;
316         --lineleft;
317         return *lineptr++;
318     }
319     
320     extern int vsprintf(char *buf, const char *fmt, va_list args);
321     static char sprint_buf[1024];
322     
323     void
324     printk(char *fmt, ...)
325     {
326     	va_list args;
327     	int n;
328     
329     	va_start(args, fmt);
330     	n = vsprintf(sprint_buf, fmt, args);
331     	va_end(args);
332     	writestring(stdout, sprint_buf, n);
333     }
334     
335     int
336     printf(char *fmt, ...)
337     {
338     	va_list args;
339     	int n;
340     
341     	va_start(args, fmt);
342     	n = vsprintf(sprint_buf, fmt, args);
343     	va_end(args);
344     	writestring(stdout, sprint_buf, n);
345     	return n;
346     }
347