3 #include "../port/lib.h"
11 #include "rebootcode.i"
14 * Where configuration info is left for the loaded programme.
15 * This will turn into a structure as more is done by the boot loader
16 * (e.g. why parse the .ini file twice?).
17 * There are 3584 bytes available at CONFADDR.
19 #define BOOTARGS ((char*)CONFADDR)
20 #define BOOTARGSLEN (16*KiB) /* limit in devenv.c */
22 #define MAXCONFLINE 160
25 Minmem = 256*MB, /* conservative default */
28 #define isascii(c) ((uchar)(c) > 0 && (uchar)(c) < 0177)
30 uintptr kseg0 = KZERO;
31 Mach* machaddr[MAXMACH];
37 /* store plan9.ini contents here at least until we stash them in #ec */
38 static char confname[MAXCONF][KNAMELEN];
39 static char confval[MAXCONF][MAXCONFLINE];
47 for(i = 0; i < nconf; i++)
48 if(cistrcmp(confname[i], name) == 0)
65 addconf(char *name, char *val)
71 if(val == nil || nconf >= MAXCONF)
74 strecpy(confname[i], confname[i]+sizeof(confname[i]), name);
77 strecpy(confval[i], confval[i]+sizeof(confval[i]), val);
93 /* convert to name=value\n format */
102 error("kernel configuration too large");
103 memmove(BOOTARGS, p, n);
104 memset(BOOTARGS + n, '\n', BOOTARGSLEN - n);
110 * assumes that we have loaded our /cfg/pxe/mac file at 0x1000 with
111 * tftp in u-boot. no longer uses malloc, so can be called early.
118 k = (char *)CONFADDR;
122 for(; k && *k != '\0'; k = next) {
123 if (!isascii(*k)) /* sanity check */
125 next = strchr(k, '\n');
129 if (*k == '\0' || *k == '\n' || *k == '#')
133 continue; /* mal-formed line */
144 extern char bdata[], edata[], end[], etext[];
145 static ulong vfy = 0xcafebabe;
147 /* l.s has already printed "Plan 9 from Be" */
148 // m = mach; /* now done in l.s */
150 /* realign data seg; apparently -H0 -R4096 does not pad the text seg */
151 if (vfy != 0xcafebabe) {
152 // wave('<'); wave('-');
153 memmove(bdata, etext, edata - bdata);
156 * once data segment is in place, always zero bss since we may
157 * have been loaded by another Plan 9 kernel.
159 memset(edata, 0, end - edata); /* zero BSS */
163 if (vfy != 0xcafebabe)
164 panic("data segment misaligned");
173 /* want plan9.ini to be able to affect memory sizing in confinit */
174 plan9iniinit(); /* before we step on plan9.ini in low memory */
176 trapinit(); /* so confinit can probe memory to size it */
177 confinit(); /* figures out amount of memory */
178 /* xinit prints (if it can), so finish up the banner here. */
180 iprint("l Labs\n\n");
184 mainmem->flags |= POOL_ANTAGONISM /* | POOL_PARANOIA */ ;
187 * Printinit will cause the first malloc call.
188 * (printinit->qopen->malloc) unless any of the
189 * above (like clockinit) do an irqenable, which
191 * If the system dies here it's probably due
192 * to malloc(->xalloc) not being initialised
193 * correctly, or the data segment is misaligned
194 * (it's amazing how far you can get with
195 * things like that completely broken).
197 * (Should be) boilerplate from here on.
200 archreset(); /* configure clock signals */
201 clockinit(); /* start clocks */
205 delay(250); /* let uart catch up */
219 chandevreset(); /* most devices are discovered here */
221 // i8250console(); /* too early; see init0 */
233 // memset(m, 0, sizeof(Mach)); /* done by l.s, now contains stack */
235 machaddr[m->machno] = m;
249 * exit kernel either on a panic or user request
260 isaconfig(char *class, int ctlrno, ISAConf *isa)
265 snprint(cc, sizeof cc, "%s%d", class, ctlrno);
275 isa->nopt = tokenize(p, isa->opt, NISAOPT);
276 for(i = 0; i < isa->nopt; i++){
278 if(cistrncmp(p, "type=", 5) == 0)
280 else if(cistrncmp(p, "port=", 5) == 0)
281 isa->port = strtoul(p+5, &p, 0);
282 else if(cistrncmp(p, "irq=", 4) == 0)
283 isa->irq = strtoul(p+4, &p, 0);
284 else if(cistrncmp(p, "dma=", 4) == 0)
285 isa->dma = strtoul(p+4, &p, 0);
286 else if(cistrncmp(p, "mem=", 4) == 0)
287 isa->mem = strtoul(p+4, &p, 0);
288 else if(cistrncmp(p, "size=", 5) == 0)
289 isa->size = strtoul(p+5, &p, 0);
290 else if(cistrncmp(p, "freq=", 5) == 0)
291 isa->freq = strtoul(p+5, &p, 0);
297 * the new kernel is already loaded at address `code'
298 * of size `size' and entry point `entry'.
301 reboot(void *entry, void *code, ulong size)
303 void (*f)(ulong, ulong, ulong);
308 /* turn off buffered serial console */
313 /* shutdown devices */
316 /* call off the dog */
322 /* setup reboot trampoline function */
323 f = (void*)REBOOTADDR;
324 memmove(f, rebootcode, sizeof(rebootcode));
328 /* off we go - never to return */
329 (*f)(PADDR(entry), PADDR(code), size);
333 * starting place for first process
338 char buf[2*KNAMELEN], **sp;
341 dmatest(); /* needs `up' set, so can't do it earlier */
343 i8250console(); /* might be redundant, but harmless */
345 panic("init0: nil serialoq");
349 snprint(buf, sizeof(buf), "%s %s", "ARM", conffile);
350 ksetenv("terminal", buf, 0);
351 ksetenv("cputype", "arm", 0);
353 ksetenv("service", "cpu", 0);
355 ksetenv("service", "terminal", 0);
357 /* convert plan9.ini variables to #e and #ec */
358 for(i = 0; i < nconf; i++) {
359 ksetenv(confname[i], confval[i], 0);
360 ksetenv(confname[i], confval[i], 1);
364 kproc("alarm", alarmkproc, 0);
366 sp = (char**)(USTKTOP - sizeof(Tos) - 8 - sizeof(sp[0])*4);
367 sp[3] = sp[2] = sp[1] = nil;
368 strcpy(sp[0] = (char*)&sp[4], "boot");
372 Conf conf; /* XXX - must go - gag */
374 Confmem omapmem[nelem(conf.mem)] = {
376 * Memory available to Plan 9:
378 { .base = PHYSDRAM, .limit = PHYSDRAM + Minmem, },
380 ulong memsize = Minmem;
387 addr = PHYSDRAM + sz - BY2WD;
389 if (probeaddr(addr) >= 0) {
405 * Copy the physical memory configuration to Conf.mem.
407 if(nelem(omapmem) > nelem(conf.mem)){
408 iprint("memory configuration botch\n");
411 if((p = getconf("*maxmem")) != nil) {
412 memsize = strtoul(p, 0, 0) - PHYSDRAM;
413 if (memsize < 16*MB) /* sanity */
418 * see if all that memory exists; if not, find out how much does.
419 * trapinit must have been called first.
421 if (gotmem(memsize) < 0 && gotmem(256*MB) < 0 && gotmem(128*MB) < 0) {
422 iprint("can't find any memory, assuming %dMB\n", Minmem / MB);
426 omapmem[0].limit = PHYSDRAM + memsize;
427 memmove(conf.mem, omapmem, sizeof(omapmem));
430 pa = PADDR(PGROUND((uintptr)end));
433 * we assume that the kernel is at the beginning of one of the
434 * contiguous chunks of memory and fits therein.
436 for(i=0; i<nelem(conf.mem); i++){
437 /* take kernel out of allocatable space */
438 if(pa > conf.mem[i].base && pa < conf.mem[i].limit)
439 conf.mem[i].base = pa;
441 conf.mem[i].npage = (conf.mem[i].limit - conf.mem[i].base)/BY2PG;
442 conf.npage += conf.mem[i].npage;
445 conf.upages = (conf.npage*80)/100;
446 conf.ialloc = ((conf.npage-conf.upages)/2)*BY2PG;
448 /* only one processor */
451 /* set up other configuration parameters */
452 conf.nproc = 100 + ((conf.npage*BY2PG)/MB)*5;
455 if(conf.nproc > 2000)
457 conf.nswap = conf.npage*3;
461 conf.copymode = 0; /* copy on write */
464 * Guess how much is taken by the large permanent
465 * datastructures. Mntcache and Mntrpc are not accounted for.
467 kpages = conf.npage - conf.upages;
469 kpages -= conf.upages*sizeof(Page)
470 + conf.nproc*sizeof(Proc)
471 + conf.nimage*sizeof(Image)
473 + conf.nswppo*sizeof(Page*);
474 mainmem->maxsize = kpages;
477 * give terminals lots of image memory, too; the dynamic
478 * allocation will balance the load properly, hopefully.
479 * be careful with 32-bit overflow.
481 imagmem->maxsize = kpages;
487 cmpswap(long *addr, long old, long new)
489 return cas32(addr, old, new);
493 setupwatchpts(Proc *, Watchpt *, int n)
496 error("no watchpoints");