3 #include "../port/lib.h"
8 #include "../port/pci.h"
11 #include "rebootcode.i"
17 extern void (*i8237alloc)(void);
18 extern void bootscreeninit(void);
27 if(p = getconf("service")){
28 if(strcmp(p, "cpu") == 0)
30 else if(strcmp(p,"terminal") == 0)
34 if(p = getconf("*kernelpercent"))
35 userpcnt = 100 - strtol(p, 0, 0);
40 for(i=0; i<nelem(conf.mem); i++)
41 conf.npage += conf.mem[i].npage;
43 conf.nproc = 100 + ((conf.npage*BY2PG)/MB)*5;
49 conf.nswap = conf.nproc*80;
55 kpages = conf.npage - (conf.npage*userpcnt)/100;
56 conf.nimage = conf.nproc;
59 if(conf.npage*BY2PG < 16*MB)
64 kpages = conf.npage - (conf.npage*userpcnt)/100;
67 * Make sure terminals with low memory get at least
68 * 4MB on the first Image chunk allocation.
70 if(conf.npage*BY2PG < 16*MB)
71 imagmem->minarena = 4*MB;
75 * can't go past the end of virtual memory.
77 if(kpages > ((uintptr)-KZERO)/BY2PG)
78 kpages = ((uintptr)-KZERO)/BY2PG;
80 conf.upages = conf.npage - kpages;
81 conf.ialloc = (kpages/2)*BY2PG;
84 * Guess how much is taken by the large permanent
85 * datastructures. Mntcache and Mntrpc are not accounted for.
88 kpages -= conf.nproc*sizeof(Proc)
89 + conf.nimage*sizeof(Image)
91 + conf.nswppo*sizeof(Page*);
92 mainmem->maxsize = kpages;
95 * the dynamic allocation will balance the load properly,
96 * hopefully. be careful with 32-bit overflow.
98 imagmem->maxsize = kpages - (kpages/10);
99 if(p = getconf("*imagemaxmb")){
100 imagmem->maxsize = strtol(p, nil, 0)*MB;
101 if(imagmem->maxsize > mainmem->maxsize)
102 imagmem->maxsize = mainmem->maxsize;
116 memset(m, 0, sizeof(Mach));
123 * For polled uart output at boot, need
124 * a default delay constant. 100000 should
125 * be enough for a while. Cpuidentify will
126 * calculate the real value later.
128 m->loopconst = 100000;
136 MACHP(0) = (Mach*)CPU0MACH;
139 m->pml4 = (u64int*)CPU0PML4;
140 m->gdt = (Segdesc*)CPU0GDT;
151 char buf[2*KNAMELEN], **sp;
156 snprint(buf, sizeof(buf), "%s %s", arch->id, conffile);
157 ksetenv("terminal", buf, 0);
158 ksetenv("cputype", "amd64", 0);
160 ksetenv("service", "cpu", 0);
162 ksetenv("service", "terminal", 0);
166 kproc("alarm", alarmkproc, 0);
168 sp = (char**)(USTKTOP - sizeof(Tos) - 8 - sizeof(sp[0])*4);
170 strcpy(sp[1] = (char*)&sp[4], "boot");
195 if(i8237alloc != nil)
207 if(arch->clockenable)
223 rebootjump(uintptr entry, uintptr code, ulong size)
225 void (*f)(uintptr, uintptr, ulong);
232 * This allows the reboot code to turn off the page mapping
234 *mmuwalk(m->pml4, 0, 3, 0) = *mmuwalk(m->pml4, KZERO, 3, 0);
235 *mmuwalk(m->pml4, 0, 2, 0) = *mmuwalk(m->pml4, KZERO, 2, 0);
237 if((pte = mmuwalk(m->pml4, REBOOTADDR, 1, 0)) != nil)
239 if((pte = mmuwalk(m->pml4, REBOOTADDR, 0, 0)) != nil)
244 /* setup reboot trampoline function */
245 f = (void*)REBOOTADDR;
246 memmove(f, rebootcode, sizeof(rebootcode));
248 /* off we go - never to return */
250 (*f)(entry, code, size);
266 reboot(void *entry, void *code, ulong size)
272 * the boot processor is cpu0. execute this function on it
273 * so that the new kernel has the same cpu0. this only matters
274 * because the hardware has a notion of which processor was the
275 * boot processor and we look at it at start up.
277 if (m->machno != 0) {
285 /* turn off buffered serial console */
288 /* shutdown devices */
291 /* disable pci devices */
294 rebootjump((uintptr)entry & (ulong)~0xF0000000UL, PADDR(code), size);
302 /* clear debug registers */
303 memset(p->dr, 0, sizeof(p->dr));
337 if(p->state == Moribund)
343 * While this processor is in the scheduler, the process could run
344 * on another processor and exit, returning the page tables to
345 * the free list where they could be reallocated and overwritten.
346 * When this processor eventually has to get an entry from the
347 * trashed page tables it will crash.
349 * If there's only one processor, this can't happen.
350 * You might think it would be a win not to do this in that case,
351 * especially on VMware, but it turns out not to matter.