changelog shortlog tags branches changeset files file revisions raw help

Mercurial > hg > plan9front / annotate sys/src/9/bcm/main.c

changeset 7159: 66132ebbe687
parent: 85c4b38d9a82
child: fc141b91ed8a
author: cinap_lenrek@felloff.net
date: Thu, 11 Apr 2019 19:10:47 +0200
permissions: -rw-r--r--
description: bcm: move CONFADDR parsing into bootargs.c, simplify initcode start() args handling
cinap_lenrek@2323 1
 #include "u.h"
cinap_lenrek@2323 2
 #include "tos.h"
cinap_lenrek@2323 3
 #include "../port/lib.h"
cinap_lenrek@2323 4
 #include "mem.h"
cinap_lenrek@2323 5
 #include "dat.h"
cinap_lenrek@2323 6
 #include "fns.h"
cinap_lenrek@6832 7
 #include "io.h"
cinap_lenrek@2323 8
 
cinap_lenrek@2323 9
 #include "init.h"
cinap_lenrek@2323 10
 #include <pool.h>
cinap_lenrek@2323 11
 
cinap_lenrek@2323 12
 #include "reboot.h"
cinap_lenrek@2323 13
 
cinap_lenrek@2323 14
 /* Firmware compatibility */
cinap_lenrek@2323 15
 #define	Minfirmrev	326770
cinap_lenrek@2323 16
 #define	Minfirmdate	"22 Jul 2012"
cinap_lenrek@2323 17
 
cinap_lenrek@2323 18
 uintptr kseg0 = KZERO;
cinap_lenrek@2323 19
 Mach*	machaddr[MAXMACH];
cinap_lenrek@2323 20
 Conf	conf;
cinap_lenrek@2323 21
 ulong	memsize = 128*1024*1024;
cinap_lenrek@2323 22
 
cinap_lenrek@2323 23
 void
cinap_lenrek@2323 24
 machinit(void)
cinap_lenrek@2323 25
 {
cinap_lenrek@6832 26
 	Mach *m0;
cinap_lenrek@6832 27
 
cinap_lenrek@6832 28
 	m->ticks = 1;
cinap_lenrek@6832 29
 	m->perf.period = 1;
cinap_lenrek@6832 30
 	m0 = MACHP(0);
cinap_lenrek@6832 31
 	if (m->machno != 0) {
cinap_lenrek@6832 32
 		/* synchronise with cpu 0 */
cinap_lenrek@6832 33
 		m->ticks = m0->ticks;
cinap_lenrek@6832 34
 	}
cinap_lenrek@6832 35
 }
cinap_lenrek@6832 36
 
cinap_lenrek@6832 37
 void
cinap_lenrek@6832 38
 mach0init(void)
cinap_lenrek@6832 39
 {
cinap_lenrek@6832 40
 	m->mmul1 = (PTE*)L1;
cinap_lenrek@2323 41
 	m->machno = 0;
cinap_lenrek@2323 42
 	machaddr[m->machno] = m;
cinap_lenrek@2323 43
 
cinap_lenrek@2323 44
 	m->ticks = 1;
cinap_lenrek@2323 45
 	m->perf.period = 1;
cinap_lenrek@2323 46
 
cinap_lenrek@5034 47
 	active.machs[0] = 1;
cinap_lenrek@2323 48
 	active.exiting = 0;
cinap_lenrek@2323 49
 
cinap_lenrek@2323 50
 	up = nil;
cinap_lenrek@2323 51
 }
cinap_lenrek@2323 52
 
cinap_lenrek@2323 53
 static void
cinap_lenrek@6832 54
 launchinit(void)
cinap_lenrek@6832 55
 {
cinap_lenrek@6832 56
 	int mach;
cinap_lenrek@6832 57
 	Mach *mm;
cinap_lenrek@6832 58
 	PTE *l1;
cinap_lenrek@6832 59
 
cinap_lenrek@6832 60
 	for(mach = 1; mach < conf.nmach; mach++){
cinap_lenrek@6832 61
 		machaddr[mach] = mm = mallocalign(MACHSIZE, MACHSIZE, 0, 0);
cinap_lenrek@6832 62
 		l1 = mallocalign(L1SIZE, L1SIZE, 0, 0);
cinap_lenrek@6832 63
 		if(mm == nil || l1 == nil)
cinap_lenrek@6832 64
 			panic("launchinit");
cinap_lenrek@6832 65
 		memset(mm, 0, MACHSIZE);
cinap_lenrek@6832 66
 		mm->machno = mach;
cinap_lenrek@6832 67
 
cinap_lenrek@6832 68
 		memmove(l1, m->mmul1, L1SIZE);  /* clone cpu0's l1 table */
cinap_lenrek@6832 69
 		cachedwbse(l1, L1SIZE);
cinap_lenrek@6832 70
 		mm->mmul1 = l1;
cinap_lenrek@6832 71
 		cachedwbse(mm, MACHSIZE);
cinap_lenrek@6832 72
 
cinap_lenrek@6832 73
 	}
cinap_lenrek@6832 74
 	cachedwbse(machaddr, sizeof machaddr);
cinap_lenrek@6832 75
 	if((mach = startcpus(conf.nmach)) < conf.nmach)
cinap_lenrek@6855 76
 		print("only %d cpu%s started\n", mach, mach == 1? "" : "s");
cinap_lenrek@6832 77
 }
cinap_lenrek@6832 78
 
cinap_lenrek@2323 79
 void
cinap_lenrek@2323 80
 main(void)
cinap_lenrek@2323 81
 {
cinap_lenrek@2323 82
 	extern char edata[], end[];
cinap_lenrek@6832 83
 	uint fw, board;
cinap_lenrek@2323 84
 
cinap_lenrek@2323 85
 	m = (Mach*)MACHADDR;
cinap_lenrek@2323 86
 	memset(edata, 0, end - edata);	/* clear bss */
cinap_lenrek@6832 87
 	mach0init();
cinap_lenrek@2323 88
 	quotefmtinstall();
cinap_lenrek@7159 89
 	bootargsinit();
cinap_lenrek@2323 90
 	confinit();		/* figures out amount of memory */
cinap_lenrek@2323 91
 	xinit();
cinap_lenrek@2323 92
 	uartconsinit();
cinap_lenrek@2323 93
 	screeninit();
cinap_lenrek@2323 94
 
cinap_lenrek@2323 95
 	print("\nPlan 9 from Bell Labs\n");
cinap_lenrek@6832 96
 	board = getboardrev();
cinap_lenrek@6832 97
 	fw = getfirmware();
cinap_lenrek@6832 98
 	print("board rev: %#ux firmware rev: %d\n", board, fw);
cinap_lenrek@6832 99
 	if(fw < Minfirmrev){
cinap_lenrek@6832 100
 		print("Sorry, firmware (start*.elf) must be at least rev %d"
cinap_lenrek@6832 101
 		      " or newer than %s\n", Minfirmrev, Minfirmdate);
cinap_lenrek@2323 102
 		for(;;)
cinap_lenrek@2323 103
 			;
cinap_lenrek@2323 104
 	}
cinap_lenrek@6832 105
 	/* set clock rate to arm_freq from config.txt (default pi1:700Mhz pi2:900MHz) */
cinap_lenrek@6832 106
 	setclkrate(ClkArm, 0);
cinap_lenrek@2323 107
 	trapinit();
cinap_lenrek@2323 108
 	clockinit();
cinap_lenrek@2323 109
 	printinit();
cinap_lenrek@2323 110
 	timersinit();
cinap_lenrek@2323 111
 	cpuidprint();
cinap_lenrek@2323 112
 	archreset();
cinap_lenrek@6832 113
 	vgpinit();
cinap_lenrek@2323 114
 
cinap_lenrek@2323 115
 	procinit0();
cinap_lenrek@2323 116
 	initseg();
cinap_lenrek@2323 117
 	links();
cinap_lenrek@2323 118
 	chandevreset();			/* most devices are discovered here */
cinap_lenrek@2323 119
 	pageinit();
cinap_lenrek@2323 120
 	userinit();
cinap_lenrek@6832 121
 	launchinit();
cinap_lenrek@6851 122
 	mmuinit1(0);
cinap_lenrek@2323 123
 	schedinit();
cinap_lenrek@2323 124
 	assert(0);			/* shouldn't have returned */
cinap_lenrek@2323 125
 }
cinap_lenrek@2323 126
 
cinap_lenrek@2323 127
 /*
cinap_lenrek@2323 128
  *  starting place for first process
cinap_lenrek@2323 129
  */
cinap_lenrek@2323 130
 void
cinap_lenrek@2323 131
 init0(void)
cinap_lenrek@2323 132
 {
cinap_lenrek@7159 133
 	char buf[2*KNAMELEN], **sp;
cinap_lenrek@2323 134
 
cinap_lenrek@2323 135
 	up->nerrlab = 0;
cinap_lenrek@2323 136
 	coherence();
cinap_lenrek@2323 137
 	spllo();
cinap_lenrek@2323 138
 
cinap_lenrek@2323 139
 	/*
cinap_lenrek@2323 140
 	 * These are o.k. because rootinit is null.
cinap_lenrek@2323 141
 	 * Then early kproc's will have a root and dot.
cinap_lenrek@2323 142
 	 */
cinap_lenrek@2323 143
 	up->slash = namec("#/", Atodir, 0, 0);
cinap_lenrek@2323 144
 	pathclose(up->slash->path);
cinap_lenrek@2323 145
 	up->slash->path = newpath("/");
cinap_lenrek@2323 146
 	up->dot = cclone(up->slash);
cinap_lenrek@2323 147
 
cinap_lenrek@2323 148
 	chandevinit();
cinap_lenrek@2323 149
 
cinap_lenrek@2323 150
 	if(!waserror()){
cinap_lenrek@2323 151
 		snprint(buf, sizeof(buf), "%s %s", "ARM", conffile);
cinap_lenrek@2323 152
 		ksetenv("terminal", buf, 0);
cinap_lenrek@2323 153
 		ksetenv("cputype", "arm", 0);
cinap_lenrek@2323 154
 		if(cpuserver)
cinap_lenrek@2323 155
 			ksetenv("service", "cpu", 0);
cinap_lenrek@2323 156
 		else
cinap_lenrek@2323 157
 			ksetenv("service", "terminal", 0);
cinap_lenrek@2323 158
 		snprint(buf, sizeof(buf), "-a %s", getethermac());
cinap_lenrek@2323 159
 		ksetenv("etherargs", buf, 0);
cinap_lenrek@2323 160
 
cinap_lenrek@2323 161
 		/* convert plan9.ini variables to #e and #ec */
cinap_lenrek@7159 162
 		setconfenv();
cinap_lenrek@2323 163
 		poperror();
cinap_lenrek@2323 164
 	}
cinap_lenrek@2323 165
 	kproc("alarm", alarmkproc, 0);
cinap_lenrek@2323 166
 
cinap_lenrek@7159 167
 	sp = (char**)(USTKTOP - sizeof(Tos) - 8 - sizeof(sp[0])*4);
cinap_lenrek@7159 168
 	sp[3] = sp[2] = sp[1] = nil;
cinap_lenrek@7159 169
 	strcpy(sp[0] = (char*)&sp[4], "boot");
cinap_lenrek@2323 170
 
cinap_lenrek@7159 171
 	touser((uintptr)sp);
cinap_lenrek@7159 172
 	assert(0);			/* shouldn't have returned */
cinap_lenrek@2323 173
 }
cinap_lenrek@2323 174
 
cinap_lenrek@2323 175
 /*
cinap_lenrek@2323 176
  *  create the first process
cinap_lenrek@2323 177
  */
cinap_lenrek@2323 178
 void
cinap_lenrek@2323 179
 userinit(void)
cinap_lenrek@2323 180
 {
cinap_lenrek@2323 181
 	Proc *p;
cinap_lenrek@2323 182
 	Segment *s;
cinap_lenrek@2323 183
 	KMap *k;
cinap_lenrek@2323 184
 	Page *pg;
cinap_lenrek@2323 185
 
cinap_lenrek@2323 186
 	/* no processes yet */
cinap_lenrek@2323 187
 	up = nil;
cinap_lenrek@2323 188
 
cinap_lenrek@2323 189
 	p = newproc();
cinap_lenrek@2323 190
 	p->pgrp = newpgrp();
cinap_lenrek@2323 191
 	p->egrp = smalloc(sizeof(Egrp));
cinap_lenrek@2323 192
 	p->egrp->ref = 1;
cinap_lenrek@2323 193
 	p->fgrp = dupfgrp(nil);
cinap_lenrek@2323 194
 	p->rgrp = newrgrp();
cinap_lenrek@2323 195
 	p->procmode = 0640;
cinap_lenrek@2323 196
 
cinap_lenrek@2323 197
 	kstrdup(&eve, "");
cinap_lenrek@2323 198
 	kstrdup(&p->text, "*init*");
cinap_lenrek@2323 199
 	kstrdup(&p->user, eve);
cinap_lenrek@2323 200
 
cinap_lenrek@2323 201
 	/*
cinap_lenrek@2323 202
 	 * Kernel Stack
cinap_lenrek@2323 203
 	 */
cinap_lenrek@7155 204
 	p->sched.pc = (uintptr)init0;
cinap_lenrek@7155 205
 	p->sched.sp = (uintptr)p->kstack+KSTACK-sizeof(up->s.args)-sizeof(uintptr);
cinap_lenrek@2323 206
 	p->sched.sp = STACKALIGN(p->sched.sp);
cinap_lenrek@2323 207
 
cinap_lenrek@2323 208
 	/*
cinap_lenrek@2323 209
 	 * User Stack
cinap_lenrek@2323 210
 	 *
cinap_lenrek@2323 211
 	 * Technically, newpage can't be called here because it
cinap_lenrek@2323 212
 	 * should only be called when in a user context as it may
cinap_lenrek@2323 213
 	 * try to sleep if there are no pages available, but that
cinap_lenrek@2323 214
 	 * shouldn't be the case here.
cinap_lenrek@2323 215
 	 */
cinap_lenrek@2323 216
 	s = newseg(SG_STACK, USTKTOP-USTKSIZE, USTKSIZE/BY2PG);
cinap_lenrek@2323 217
 	s->flushme++;
cinap_lenrek@2323 218
 	p->seg[SSEG] = s;
cinap_lenrek@2323 219
 	pg = newpage(1, 0, USTKTOP-BY2PG);
cinap_lenrek@2323 220
 	segpage(s, pg);
cinap_lenrek@2323 221
 	k = kmap(pg);
cinap_lenrek@7159 222
 	memset((void*)VA(k), 0, BY2PG);
cinap_lenrek@2323 223
 	kunmap(k);
cinap_lenrek@2323 224
 
cinap_lenrek@2323 225
 	/*
cinap_lenrek@2323 226
 	 * Text
cinap_lenrek@2323 227
 	 */
cinap_lenrek@2323 228
 	s = newseg(SG_TEXT, UTZERO, 1);
cinap_lenrek@2323 229
 	p->seg[TSEG] = s;
cinap_lenrek@2323 230
 	pg = newpage(1, 0, UTZERO);
cinap_lenrek@4250 231
 	pg->txtflush = ~0;
cinap_lenrek@2323 232
 	segpage(s, pg);
cinap_lenrek@2323 233
 	k = kmap(s->map[0]->pages[0]);
cinap_lenrek@7155 234
 	memmove((void*)VA(k), initcode, sizeof initcode);
cinap_lenrek@2323 235
 	kunmap(k);
cinap_lenrek@2323 236
 
cinap_lenrek@2323 237
 	ready(p);
cinap_lenrek@2323 238
 }
cinap_lenrek@2323 239
 
cinap_lenrek@2323 240
 void
cinap_lenrek@2323 241
 confinit(void)
cinap_lenrek@2323 242
 {
stanley@3401 243
 	int i, userpcnt;
cinap_lenrek@2323 244
 	ulong kpages;
cinap_lenrek@2323 245
 	uintptr pa;
cinap_lenrek@2323 246
 	char *p;
cinap_lenrek@2323 247
 
cinap_lenrek@3448 248
 	if(p = getconf("service")){
cinap_lenrek@3448 249
 		if(strcmp(p, "cpu") == 0)
cinap_lenrek@3448 250
 			cpuserver = 1;
cinap_lenrek@3448 251
 		else if(strcmp(p,"terminal") == 0)
cinap_lenrek@3448 252
 			cpuserver = 0;
cinap_lenrek@3448 253
 	}
cinap_lenrek@3448 254
 
stanley@3401 255
 	if(p = getconf("*kernelpercent"))
stanley@3401 256
 		userpcnt = 100 - strtol(p, 0, 0);
stanley@3401 257
 	else
stanley@3401 258
 		userpcnt = 0;
stanley@3401 259
 
cinap_lenrek@2323 260
 	if((p = getconf("*maxmem")) != nil){
cinap_lenrek@2323 261
 		memsize = strtoul(p, 0, 0) - PHYSDRAM;
cinap_lenrek@2323 262
 		if (memsize < 16*MB)		/* sanity */
cinap_lenrek@2323 263
 			memsize = 16*MB;
cinap_lenrek@2323 264
 	}
cinap_lenrek@2323 265
 
cinap_lenrek@2323 266
 	getramsize(&conf.mem[0]);
cinap_lenrek@2323 267
 	if(conf.mem[0].limit == 0){
cinap_lenrek@2323 268
 		conf.mem[0].base = PHYSDRAM;
cinap_lenrek@2323 269
 		conf.mem[0].limit = PHYSDRAM + memsize;
cinap_lenrek@2323 270
 	}else if(p != nil)
cinap_lenrek@2323 271
 		conf.mem[0].limit = conf.mem[0].base + memsize;
cinap_lenrek@2323 272
 
cinap_lenrek@2323 273
 	conf.npage = 0;
cinap_lenrek@7155 274
 	pa = PADDR(PGROUND((uintptr)end));
cinap_lenrek@2323 275
 
cinap_lenrek@2323 276
 	/*
cinap_lenrek@2323 277
 	 *  we assume that the kernel is at the beginning of one of the
cinap_lenrek@2323 278
 	 *  contiguous chunks of memory and fits therein.
cinap_lenrek@2323 279
 	 */
cinap_lenrek@2323 280
 	for(i=0; i<nelem(conf.mem); i++){
cinap_lenrek@2323 281
 		/* take kernel out of allocatable space */
cinap_lenrek@2323 282
 		if(pa > conf.mem[i].base && pa < conf.mem[i].limit)
cinap_lenrek@2323 283
 			conf.mem[i].base = pa;
cinap_lenrek@2323 284
 
cinap_lenrek@2323 285
 		conf.mem[i].npage = (conf.mem[i].limit - conf.mem[i].base)/BY2PG;
cinap_lenrek@2323 286
 		conf.npage += conf.mem[i].npage;
cinap_lenrek@2323 287
 	}
cinap_lenrek@2323 288
 
stanley@3401 289
 	if(userpcnt < 10)
stanley@3401 290
 		userpcnt = 60 + cpuserver*10;
stanley@3401 291
 	kpages = conf.npage - (conf.npage*userpcnt)/100;
stanley@3401 292
 
stanley@3401 293
 	/*
stanley@3401 294
 	 * can't go past the end of virtual memory
stanley@3401 295
 	 * (ulong)-KZERO is 2^32 - KZERO
stanley@3401 296
 	 */
stanley@3401 297
 	if(kpages > ((ulong)-KZERO)/BY2PG)
stanley@3401 298
 		kpages = ((ulong)-KZERO)/BY2PG;
stanley@3401 299
 
stanley@3401 300
 	conf.upages = conf.npage - kpages;
stanley@3401 301
 	conf.ialloc = (kpages/2)*BY2PG;
cinap_lenrek@2323 302
 
cinap_lenrek@6832 303
 	conf.nmach = getncpus();
cinap_lenrek@2323 304
 
cinap_lenrek@2323 305
 	/* set up other configuration parameters */
cinap_lenrek@2323 306
 	conf.nproc = 100 + ((conf.npage*BY2PG)/MB)*5;
cinap_lenrek@2323 307
 	if(cpuserver)
cinap_lenrek@2323 308
 		conf.nproc *= 3;
cinap_lenrek@2323 309
 	if(conf.nproc > 2000)
cinap_lenrek@2323 310
 		conf.nproc = 2000;
cinap_lenrek@2323 311
 	conf.nswap = conf.npage*3;
cinap_lenrek@2323 312
 	conf.nswppo = 4096;
cinap_lenrek@2323 313
 	conf.nimage = 200;
cinap_lenrek@2323 314
 
cinap_lenrek@6832 315
 	conf.copymode = conf.nmach > 1;
cinap_lenrek@2323 316
 
cinap_lenrek@2323 317
 	/*
cinap_lenrek@2323 318
 	 * Guess how much is taken by the large permanent
cinap_lenrek@4074 319
 	 * datastructures. Mntcache and Mntrpc are not accounted for.
cinap_lenrek@2323 320
 	 */
cinap_lenrek@2323 321
 	kpages = conf.npage - conf.upages;
cinap_lenrek@2323 322
 	kpages *= BY2PG;
cinap_lenrek@2323 323
 	kpages -= conf.upages*sizeof(Page)
cinap_lenrek@2323 324
 		+ conf.nproc*sizeof(Proc)
cinap_lenrek@2323 325
 		+ conf.nimage*sizeof(Image)
cinap_lenrek@2323 326
 		+ conf.nswap
stanley@3401 327
 		+ conf.nswppo*sizeof(Page*);
cinap_lenrek@2323 328
 	mainmem->maxsize = kpages;
cinap_lenrek@2323 329
 	if(!cpuserver)
cinap_lenrek@2323 330
 		/*
cinap_lenrek@2323 331
 		 * give terminals lots of image memory, too; the dynamic
cinap_lenrek@2323 332
 		 * allocation will balance the load properly, hopefully.
cinap_lenrek@2323 333
 		 * be careful with 32-bit overflow.
cinap_lenrek@2323 334
 		 */
cinap_lenrek@2323 335
 		imagmem->maxsize = kpages;
cinap_lenrek@2323 336
 
cinap_lenrek@2323 337
 }
cinap_lenrek@2323 338
 
cinap_lenrek@6851 339
 static void
cinap_lenrek@6855 340
 rebootjump(void *entry, void *code, ulong size)
cinap_lenrek@6851 341
 {
cinap_lenrek@6855 342
 	void (*f)(void*, void*, ulong);
cinap_lenrek@6851 343
 
cinap_lenrek@6851 344
 	intrsoff();
cinap_lenrek@6851 345
 	intrcpushutdown();
cinap_lenrek@6851 346
 
cinap_lenrek@6851 347
 	/* redo identity map */
cinap_lenrek@6851 348
 	mmuinit1(1);
cinap_lenrek@6851 349
 
cinap_lenrek@6855 350
 	/* setup reboot trampoline function */
cinap_lenrek@6855 351
 	f = (void*)REBOOTADDR;
cinap_lenrek@6855 352
 	memmove(f, rebootcode, sizeof(rebootcode));
cinap_lenrek@6851 353
 	cacheuwbinv();
cinap_lenrek@6851 354
 
cinap_lenrek@6851 355
 	(*f)(entry, code, size);
cinap_lenrek@6851 356
 
cinap_lenrek@6851 357
 	for(;;);
cinap_lenrek@6851 358
 }
cinap_lenrek@6851 359
 
cinap_lenrek@2323 360
 /*
cinap_lenrek@2323 361
  *  exit kernel either on a panic or user request
cinap_lenrek@2323 362
  */
cinap_lenrek@2323 363
 void
cinap_lenrek@4993 364
 exit(int)
cinap_lenrek@2323 365
 {
cinap_lenrek@4993 366
 	cpushutdown();
cinap_lenrek@2323 367
 	splfhi();
cinap_lenrek@6855 368
 	if(m->machno == 0)
cinap_lenrek@6855 369
 		archreboot();
cinap_lenrek@6855 370
 	rebootjump(0, 0, 0);
cinap_lenrek@2323 371
 }
cinap_lenrek@2323 372
 
cinap_lenrek@2323 373
 /*
cinap_lenrek@2323 374
  * stub for ../omap/devether.c
cinap_lenrek@2323 375
  */
cinap_lenrek@2323 376
 int
cinap_lenrek@6832 377
 isaconfig(char *, int, ISAConf *)
cinap_lenrek@2323 378
 {
cinap_lenrek@6832 379
 	return 0;
cinap_lenrek@2323 380
 }
cinap_lenrek@2323 381
 
cinap_lenrek@2323 382
 /*
cinap_lenrek@2323 383
  * the new kernel is already loaded at address `code'
cinap_lenrek@2323 384
  * of size `size' and entry point `entry'.
cinap_lenrek@2323 385
  */
cinap_lenrek@2323 386
 void
cinap_lenrek@2323 387
 reboot(void *entry, void *code, ulong size)
cinap_lenrek@2323 388
 {
cinap_lenrek@2323 389
 	writeconf();
cinap_lenrek@6855 390
 	while(m->machno != 0){
cinap_lenrek@6832 391
 		procwired(up, 0);
cinap_lenrek@6832 392
 		sched();
cinap_lenrek@6832 393
 	}
cinap_lenrek@6832 394
 
cinap_lenrek@4993 395
 	cpushutdown();
cinap_lenrek@6855 396
 	delay(2000);
cinap_lenrek@6832 397
 
cinap_lenrek@6832 398
 	splfhi();
cinap_lenrek@2323 399
 
cinap_lenrek@2323 400
 	/* turn off buffered serial console */
cinap_lenrek@2323 401
 	serialoq = nil;
cinap_lenrek@2323 402
 
cinap_lenrek@2323 403
 	/* shutdown devices */
cinap_lenrek@2323 404
 	chandevshutdown();
cinap_lenrek@2323 405
 
cinap_lenrek@2323 406
 	/* stop the clock (and watchdog if any) */
cinap_lenrek@2323 407
 	clockshutdown();
cinap_lenrek@6851 408
 	wdogoff();
cinap_lenrek@2323 409
 
cinap_lenrek@2323 410
 	/* off we go - never to return */
cinap_lenrek@6855 411
 	rebootjump(entry, code, size);
cinap_lenrek@2323 412
 }
cinap_lenrek@2323 413
 
aiju@6012 414
 void
aiju@6012 415
 setupwatchpts(Proc *, Watchpt *, int n)
aiju@6012 416
 {
aiju@6012 417
 	if(n > 0)
aiju@6012 418
 		error("no watchpoints");
aiju@6012 419
 }