Main Page | Alphabetical List | Data Structures | Directories | File List | Data Fields | Globals

chrpboot/start.c

Go to the documentation of this file.
00001 /*
00002  * Copyright (C) Paul Mackerras 1997.
00003  *
00004  * This program is free software; you can redistribute it and/or
00005  * modify it under the terms of the GNU General Public License
00006  * as published by the Free Software Foundation; either version
00007  * 2 of the License, or (at your option) any later version.
00008  */
00009 #include <stdarg.h>
00010 
00011 int (*prom)();
00012 
00013 void *chosen_handle;
00014 void *stdin;
00015 void *stdout;
00016 void *stderr;
00017 
00018 void exit(void);
00019 void *finddevice(const char *name);
00020 int getprop(void *phandle, const char *name, void *buf, int buflen);
00021 
00022 void printk(char *fmt, ...);
00023 
00024 void
00025 start(int a1, int a2, void *promptr)
00026 {
00027     prom = (int (*)()) promptr;
00028     chosen_handle = finddevice("/chosen");
00029     if (chosen_handle == (void *) -1)
00030         exit();
00031     if (getprop(chosen_handle, "stdout", &stdout, sizeof(stdout)) != 4)
00032         exit();
00033     stderr = stdout;
00034     if (getprop(chosen_handle, "stdin", &stdin, sizeof(stdin)) != 4)
00035         exit();
00036 
00037     chrpboot(a1, a2, promptr);
00038     for (;;)
00039         exit();
00040 }
00041 
00042 int
00043 write(void *handle, void *ptr, int nb)
00044 {
00045     struct prom_args {
00046         char *service;
00047         int nargs;
00048         int nret;
00049         void *ihandle;
00050         void *addr;
00051         int len;
00052         int actual;
00053     } args;
00054 
00055     args.service = "write";
00056     args.nargs = 3;
00057     args.nret = 1;
00058     args.ihandle = handle;
00059     args.addr = ptr;
00060     args.len = nb;
00061     args.actual = -1;
00062     (*prom)(&args);
00063     return args.actual;
00064 }
00065 
00066 int
00067 read(void *handle, void *ptr, int nb)
00068 {
00069     struct prom_args {
00070         char *service;
00071         int nargs;
00072         int nret;
00073         void *ihandle;
00074         void *addr;
00075         int len;
00076         int actual;
00077     } args;
00078 
00079     args.service = "read";
00080     args.nargs = 3;
00081     args.nret = 1;
00082     args.ihandle = handle;
00083     args.addr = ptr;
00084     args.len = nb;
00085     args.actual = -1;
00086     (*prom)(&args);
00087     return args.actual;
00088 }
00089 
00090 void
00091 exit()
00092 {
00093     struct prom_args {
00094         char *service;
00095     } args;
00096 
00097     for (;;) {
00098         args.service = "exit";
00099         (*prom)(&args);
00100     }
00101 }
00102 
00103 void
00104 pause()
00105 {
00106     struct prom_args {
00107         char *service;
00108     } args;
00109 
00110     args.service = "enter";
00111     (*prom)(&args);
00112 }
00113 
00114 void *
00115 finddevice(const char *name)
00116 {
00117     struct prom_args {
00118         char *service;
00119         int nargs;
00120         int nret;
00121         const char *devspec;
00122         void *phandle;
00123     } args;
00124 
00125     args.service = "finddevice";
00126     args.nargs = 1;
00127     args.nret = 1;
00128     args.devspec = name;
00129     args.phandle = (void *) -1;
00130     (*prom)(&args);
00131     return args.phandle;
00132 }
00133 
00134 void *
00135 claim(unsigned int virt, unsigned int size, unsigned int align)
00136 {
00137     struct prom_args {
00138         char *service;
00139         int nargs;
00140         int nret;
00141         unsigned int virt;
00142         unsigned int size;
00143         unsigned int align;
00144         void *ret;
00145     } args;
00146 
00147     args.service = "claim";
00148     args.nargs = 3;
00149     args.nret = 1;
00150     args.virt = virt;
00151     args.size = size;
00152     args.align = align;
00153     (*prom)(&args);
00154     return args.ret;
00155 }
00156 
00157 int
00158 getprop(void *phandle, const char *name, void *buf, int buflen)
00159 {
00160     struct prom_args {
00161         char *service;
00162         int nargs;
00163         int nret;
00164         void *phandle;
00165         const char *name;
00166         void *buf;
00167         int buflen;
00168         int size;
00169     } args;
00170 
00171     args.service = "getprop";
00172     args.nargs = 4;
00173     args.nret = 1;
00174     args.phandle = phandle;
00175     args.name = name;
00176     args.buf = buf;
00177     args.buflen = buflen;
00178     args.size = -1;
00179     (*prom)(&args);
00180     return args.size;
00181 }
00182 
00183 int
00184 putc(int c, void *f)
00185 {
00186     char ch = c;
00187 
00188     if (c == '\n')
00189         putc('\r', f);
00190     return write(f, &ch, 1) == 1? c: -1;
00191 }
00192 
00193 int
00194 putchar(int c)
00195 {
00196     return putc(c, stdout);
00197 }
00198 
00199 int
00200 fputs(char *str, void *f)
00201 {
00202     int n = strlen(str);
00203 
00204     return write(f, str, n) == n? 0: -1;
00205 }
00206 
00207 int
00208 readchar()
00209 {
00210     char ch;
00211 
00212     for (;;) {
00213         switch (read(stdin, &ch, 1)) {
00214         case 1:
00215             return ch;
00216         case -1:
00217             printk("read(stdin) returned -1\r\n");
00218             return -1;
00219         }
00220     }
00221 }
00222 
00223 static char line[256];
00224 static char *lineptr;
00225 static int lineleft;
00226 
00227 int
00228 getchar()
00229 {
00230     int c;
00231 
00232     if (lineleft == 0) {
00233         lineptr = line;
00234         for (;;) {
00235             c = readchar();
00236             if (c == -1 || c == 4)
00237                 break;
00238             if (c == '\r' || c == '\n') {
00239                 *lineptr++ = '\n';
00240                 putchar('\n');
00241                 break;
00242             }
00243             switch (c) {
00244             case 0177:
00245             case '\b':
00246                 if (lineptr > line) {
00247                     putchar('\b');
00248                     putchar(' ');
00249                     putchar('\b');
00250                     --lineptr;
00251                 }
00252                 break;
00253             case 'U' & 0x1F:
00254                 while (lineptr > line) {
00255                     putchar('\b');
00256                     putchar(' ');
00257                     putchar('\b');
00258                     --lineptr;
00259                 }
00260                 break;
00261             default:
00262                 if (lineptr >= &line[sizeof(line) - 1])
00263                     putchar('\a');
00264                 else {
00265                     putchar(c);
00266                     *lineptr++ = c;
00267                 }
00268             }
00269         }
00270         lineleft = lineptr - line;
00271         lineptr = line;
00272     }
00273     if (lineleft == 0)
00274         return -1;
00275     --lineleft;
00276     return *lineptr++;
00277 }
00278 
00279 extern int vsprintf(char *buf, const char *fmt, va_list args);
00280 static char sprint_buf[1024];
00281 
00282 void
00283 printk(char *fmt, ...)
00284 {
00285         va_list args;
00286         int n;
00287 
00288         va_start(args, fmt);
00289         n = vsprintf(sprint_buf, fmt, args);
00290         va_end(args);
00291         write(stdout, sprint_buf, n);
00292 }
00293 
00294 int
00295 printf(char *fmt, ...)
00296 {
00297         va_list args;
00298         int n;
00299 
00300         va_start(args, fmt);
00301         n = vsprintf(sprint_buf, fmt, args);
00302         va_end(args);
00303         write(stdout, sprint_buf, n);
00304         return n;
00305 }