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

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