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