1 #include "u.h"
2 #include "../port/lib.h"
3 #include "mem.h"
4 #include "dat.h"
5 #include "fns.h"
6 #include "io.h"
7 #include "ureg.h"
8 #include "version.h"
9
10 /* where b.com or qboot leaves configuration info */
11 #define BOOTARGS ((char*)CONFADDR)
12 #define BOOTARGSLEN 1024
13 #define MAXCONF 32
14
15 extern ulong kerndate;
16 extern int cflag;
17 int remotedebug;
18
19 extern int main_pool_pcnt;
20 extern int heap_pool_pcnt;
21 extern int image_pool_pcnt;
22
23 char bootargs[BOOTARGSLEN+1];
24 char bootdisk[KNAMELEN];
25 char *confname[MAXCONF];
26 char *confval[MAXCONF];
27 int nconf;
28
29 extern void addconf(char *, char *);
30
31 /*
32 * arguments passed to initcode and /boot
33 */
34 char argbuf[128];
35
36 static void
options(void)37 options(void)
38 {
39 long i, n;
40 char *cp, *line[MAXCONF], *p, *q;
41
42 /*
43 * parse configuration args from bootstrap
44 */
45 memmove(bootargs, BOOTARGS, BOOTARGSLEN); /* where b.com leaves its config */
46 cp = bootargs;
47 cp[BOOTARGSLEN-1] = 0;
48
49 /*
50 * Strip out '\r', change '\t' -> ' '.
51 */
52 p = cp;
53 for(q = cp; *q; q++){
54 if(*q == '\r')
55 continue;
56 if(*q == '\t')
57 *q = ' ';
58 *p++ = *q;
59 }
60 *p = 0;
61
62 n = getfields(cp, line, MAXCONF, 1, "\n");
63 for(i = 0; i < n; i++){
64 if(*line[i] == '#')
65 continue;
66 cp = strchr(line[i], '=');
67 if(cp == 0)
68 continue;
69 *cp++ = 0;
70 confname[nconf] = line[i];
71 confval[nconf] = cp;
72 nconf++;
73 }
74 }
75
76 void
doc(char * m)77 doc(char *m)
78 {
79 USED(m);
80 print("%s...\n", m); uartwait();
81 }
82
83 static void
poolsizeinit(void)84 poolsizeinit(void)
85 {
86 ulong nb;
87
88 nb = conf.npage*BY2PG;
89 poolsize(mainmem, (nb*main_pool_pcnt)/100, 0);
90 poolsize(heapmem, (nb*heap_pool_pcnt)/100, 0);
91 poolsize(imagmem, (nb*image_pool_pcnt)/100, 1);
92 }
93
94 static void
serialconsole(void)95 serialconsole(void)
96 {
97 char *p;
98 int port, baud;
99
100 p = getconf("console");
101 if(p == nil)
102 p = "0";
103 if(p != nil && !remotedebug){
104 port = strtol(p, nil, 0);
105 baud = 9600;
106 p = getconf("baud");
107 if(p != nil){
108 baud = strtol(p, nil, 0);
109 if(baud < 9600)
110 baud = 9600;
111 }
112 uartspecial(port, baud, &kbdq, &printq, kbdcr2nl);
113 }
114 }
115
116 void
main(void)117 main(void)
118 {
119 machinit();
120 options();
121 archinit();
122 quotefmtinstall();
123 confinit();
124 cpminit();
125 xinit();
126 poolsizeinit();
127 trapinit();
128 mmuinit();
129 printinit();
130 uartinstall();
131 serialconsole();
132 doc("screeninit");
133 screeninit();
134 doc("kbdinit");
135 kbdinit();
136 doc("clockinit");
137 clockinit();
138 doc("procinit");
139 procinit();
140 cpuidprint();
141 doc("links");
142 links();
143 doc("chandevreset");
144 chandevreset();
145
146 eve = strdup("inferno");
147
148 print("\nInferno %s\n", VERSION);
149 print("Vita Nuova\n");
150 print("conf %s (%lud) jit %d\n\n",conffile, kerndate, cflag);
151
152 doc("userinit");
153 userinit();
154 doc("schedinit");
155 schedinit();
156 }
157
158 void
machinit(void)159 machinit(void)
160 {
161 int n;
162
163 n = m->machno;
164 memset(m, 0, sizeof(Mach));
165 m->machno = n;
166 m->mmask = 1<<m->machno;
167 m->iomem = KADDR(getimmr() & ~0xFFFF);
168 m->cputype = getpvr()>>16;
169 m->delayloop = 20000; /* initial estimate only; set by clockinit */
170 m->speed = 50; /* initial estimate only; set by archinit */
171 }
172
173 void
init0(void)174 init0(void)
175 {
176 Osenv *o;
177 int i;
178 char buf[2*KNAMELEN];
179
180 up->nerrlab = 0;
181
182 spllo();
183
184 if(waserror())
185 panic("init0");
186 /*
187 * These are o.k. because rootinit is null.
188 * Then early kproc's will have a root and dot.
189 */
190 o = up->env;
191 o->pgrp->slash = namec("#/", Atodir, 0, 0);
192 cnameclose(o->pgrp->slash->name);
193 o->pgrp->slash->name = newcname("/");
194 o->pgrp->dot = cclone(o->pgrp->slash);
195
196 chandevinit();
197
198 if(!waserror()){
199 ksetenv("cputype", "power", 0);
200 snprint(buf, sizeof(buf), "power %s", conffile);
201 ksetenv("terminal", buf, 0);
202 poperror();
203 }
204 for(i = 0; i < nconf; i++)
205 if(confname[i][0] != '*'){
206 if(!waserror()){
207 ksetenv(confname[i], confval[i], 0);
208 poperror();
209 }
210 }
211
212 poperror();
213 disinit("/osinit.dis");
214 }
215
216 void
userinit(void)217 userinit(void)
218 {
219 Proc *p;
220 Osenv *o;
221
222 p = newproc();
223 o = p->env;
224
225 o->fgrp = newfgrp(nil);
226
227 o->pgrp = newpgrp();
228 o->egrp = newegrp();
229 kstrdup(&o->user, eve);
230
231 strcpy(p->text, "interp");
232
233 /*
234 * Kernel Stack
235 */
236 p->sched.pc = (ulong)init0;
237 p->sched.sp = (ulong)p->kstack+KSTACK;
238
239 ready(p);
240 }
241
242 Conf conf;
243
244 void
addconf(char * name,char * val)245 addconf(char *name, char *val)
246 {
247 if(nconf >= MAXCONF)
248 return;
249 confname[nconf] = name;
250 confval[nconf] = val;
251 nconf++;
252 }
253
254 char*
getconf(char * name)255 getconf(char *name)
256 {
257 int i;
258
259 for(i = 0; i < nconf; i++)
260 if(cistrcmp(confname[i], name) == 0)
261 return confval[i];
262 return 0;
263 }
264
265 void
confinit(void)266 confinit(void)
267 {
268 char *p;
269 int pcnt;
270
271 if(p = getconf("*kernelpercent"))
272 pcnt = 100 - strtol(p, 0, 0);
273 else
274 pcnt = 0;
275
276 conf.nscc = 4;
277 conf.smcuarts = 1<<0; /* SMC1 (usual console) */
278 conf.sccuarts = 0; /* SCC2 not available by default (it's Ether) */
279
280 archconfinit();
281
282 conf.npage = conf.npage0 + conf.npage1;
283 if(pcnt < 10)
284 pcnt = 70;
285 conf.ialloc = (((conf.npage*(100-pcnt))/100)/2)*BY2PG;
286
287 conf.nproc = 100 + ((conf.npage*BY2PG)/MB)*5;
288 conf.nmach = MAXMACH;
289 }
290
291 void
exit(int ispanic)292 exit(int ispanic)
293 {
294 up = 0;
295 spllo();
296 print("cpu %d exiting\n", m->machno);
297
298 /* Shutdown running devices */
299 chandevshutdown();
300
301 delay(1000);
302 splhi();
303 if(ispanic)
304 for(;;);
305 archreboot();
306 }
307
308 void
reboot(void)309 reboot(void)
310 {
311 exit(0);
312 }
313
314 void
halt(void)315 halt(void)
316 {
317 print("cpu halted\n");
318 microdelay(1000);
319 for(;;)
320 ;
321 }
322
323 int
isaconfig(char * class,int ctlrno,ISAConf * isa)324 isaconfig(char *class, int ctlrno, ISAConf *isa)
325 {
326 char cc[KNAMELEN], *p;
327 int i;
328
329 snprint(cc, sizeof cc, "%s%d", class, ctlrno);
330 p = getconf(cc);
331 if(p == nil)
332 return 0;
333
334 isa->nopt = tokenize(p, isa->opt, NISAOPT);
335 for(i = 0; i < isa->nopt; i++){
336 p = isa->opt[i];
337 if(cistrncmp(p, "type=", 5) == 0)
338 isa->type = p + 5;
339 else if(cistrncmp(p, "port=", 5) == 0)
340 isa->port = strtoul(p+5, &p, 0);
341 else if(cistrncmp(p, "irq=", 4) == 0)
342 isa->irq = strtoul(p+4, &p, 0);
343 else if(cistrncmp(p, "mem=", 4) == 0)
344 isa->mem = strtoul(p+4, &p, 0);
345 else if(cistrncmp(p, "size=", 5) == 0)
346 isa->size = strtoul(p+5, &p, 0);
347 else if(cistrncmp(p, "freq=", 5) == 0)
348 isa->freq = strtoul(p+5, &p, 0);
349 else if(cistrncmp(p, "dma=", 4) == 0)
350 isa->dma = strtoul(p+4, &p, 0);
351 }
352 return 1;
353 }
354
355 /*
356 * Save the mach dependent part of the process state.
357 */
358 void
procsave(Proc *)359 procsave(Proc*)
360 {
361 }
362
363 void
uartputs(char * s,int n)364 uartputs(char *s, int n)
365 {
366 // screenputs(buf, n);
367 putstrn(s, n);
368 uartwait();
369 }
370
371 /* stubs */
372 void
setfsr(ulong)373 setfsr(ulong)
374 {
375 }
376
377 ulong
getfsr()378 getfsr()
379 {
380 return 0;
381 }
382
383 void
setfcr(ulong)384 setfcr(ulong)
385 {
386 }
387
388 ulong
getfcr()389 getfcr()
390 {
391 return 0;
392 }
393