changelog shortlog tags branches changeset files file revisions raw help

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

changeset 7155: 85c4b38d9a82
parent: 01468da33a6e
child: 66132ebbe687
author: cinap_lenrek@felloff.net
date: Thu, 11 Apr 2019 13:51:38 +0200
permissions: -rw-r--r--
description: kernel: get rid of PTR2UINT() and UINT2PTR() macros
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
 /*
cinap_lenrek@2323 19
  * Where configuration info is left for the loaded programme.
cinap_lenrek@2323 20
  */
cinap_lenrek@2323 21
 #define BOOTARGS	((char*)CONFADDR)
cinap_lenrek@6851 22
 #define	BOOTARGSLEN	(REBOOTADDR-PADDR(CONFADDR))
cinap_lenrek@2323 23
 #define	MAXCONF		64
cinap_lenrek@2323 24
 #define MAXCONFLINE	160
cinap_lenrek@2323 25
 
cinap_lenrek@2323 26
 uintptr kseg0 = KZERO;
cinap_lenrek@2323 27
 Mach*	machaddr[MAXMACH];
cinap_lenrek@2323 28
 Conf	conf;
cinap_lenrek@2323 29
 ulong	memsize = 128*1024*1024;
cinap_lenrek@2323 30
 
cinap_lenrek@2323 31
 /*
cinap_lenrek@2323 32
  * Option arguments from the command line.
cinap_lenrek@2323 33
  * oargv[0] is the boot file.
cinap_lenrek@2323 34
  */
cinap_lenrek@2323 35
 static int oargc;
cinap_lenrek@2323 36
 static char* oargv[20];
cinap_lenrek@2323 37
 static char oargb[128];
cinap_lenrek@2323 38
 static int oargblen;
cinap_lenrek@2323 39
 
cinap_lenrek@2323 40
 static uintptr sp;		/* XXX - must go - user stack of init proc */
cinap_lenrek@2323 41
 
cinap_lenrek@2323 42
 /* store plan9.ini contents here at least until we stash them in #ec */
cinap_lenrek@2323 43
 static char confname[MAXCONF][KNAMELEN];
cinap_lenrek@2323 44
 static char confval[MAXCONF][MAXCONFLINE];
cinap_lenrek@2323 45
 static int nconf;
cinap_lenrek@2323 46
 
cinap_lenrek@2323 47
 typedef struct Atag Atag;
cinap_lenrek@2323 48
 struct Atag {
cinap_lenrek@2323 49
 	u32int	size;	/* size of atag in words, including this header */
cinap_lenrek@2323 50
 	u32int	tag;	/* atag type */
cinap_lenrek@2323 51
 	union {
cinap_lenrek@2323 52
 		u32int	data[1];	/* actually [size-2] */
cinap_lenrek@2323 53
 		/* AtagMem */
cinap_lenrek@2323 54
 		struct {
cinap_lenrek@2323 55
 			u32int	size;
cinap_lenrek@2323 56
 			u32int	base;
cinap_lenrek@2323 57
 		} mem;
cinap_lenrek@2323 58
 		/* AtagCmdLine */
cinap_lenrek@2323 59
 		char	cmdline[1];	/* actually [4*(size-2)] */
cinap_lenrek@2323 60
 	};
cinap_lenrek@2323 61
 };
cinap_lenrek@2323 62
 
cinap_lenrek@2323 63
 enum {
cinap_lenrek@2323 64
 	AtagNone	= 0x00000000,
cinap_lenrek@2323 65
 	AtagCore	= 0x54410001,
cinap_lenrek@2323 66
 	AtagMem		= 0x54410002,
cinap_lenrek@2323 67
 	AtagCmdline	= 0x54410009,
cinap_lenrek@2323 68
 };
cinap_lenrek@2323 69
 
cinap_lenrek@2323 70
 static int
cinap_lenrek@2323 71
 findconf(char *name)
cinap_lenrek@2323 72
 {
cinap_lenrek@2323 73
 	int i;
cinap_lenrek@2323 74
 
cinap_lenrek@2323 75
 	for(i = 0; i < nconf; i++)
cinap_lenrek@2323 76
 		if(cistrcmp(confname[i], name) == 0)
cinap_lenrek@2323 77
 			return i;
cinap_lenrek@2323 78
 	return -1;
cinap_lenrek@2323 79
 }
cinap_lenrek@2323 80
 
cinap_lenrek@2323 81
 char*
cinap_lenrek@2323 82
 getconf(char *name)
cinap_lenrek@2323 83
 {
cinap_lenrek@2323 84
 	int i;
cinap_lenrek@2323 85
 
cinap_lenrek@2323 86
 	i = findconf(name);
cinap_lenrek@2323 87
 	if(i >= 0)
cinap_lenrek@2323 88
 		return confval[i];
cinap_lenrek@2323 89
 	return nil;
cinap_lenrek@2323 90
 }
cinap_lenrek@2323 91
 
cinap_lenrek@2323 92
 void
cinap_lenrek@2323 93
 addconf(char *name, char *val)
cinap_lenrek@2323 94
 {
cinap_lenrek@2323 95
 	int i;
cinap_lenrek@2323 96
 
cinap_lenrek@2323 97
 	i = findconf(name);
cinap_lenrek@2323 98
 	if(i < 0){
cinap_lenrek@2323 99
 		if(val == nil || nconf >= MAXCONF)
cinap_lenrek@2323 100
 			return;
cinap_lenrek@2323 101
 		i = nconf++;
cinap_lenrek@2323 102
 		strecpy(confname[i], confname[i]+sizeof(confname[i]), name);
cinap_lenrek@2323 103
 	}
cinap_lenrek@2323 104
 	strecpy(confval[i], confval[i]+sizeof(confval[i]), val);
cinap_lenrek@2323 105
 }
cinap_lenrek@2323 106
 
cinap_lenrek@2323 107
 static void
cinap_lenrek@2323 108
 writeconf(void)
cinap_lenrek@2323 109
 {
cinap_lenrek@2323 110
 	char *p, *q;
cinap_lenrek@2323 111
 	int n;
cinap_lenrek@2323 112
 
cinap_lenrek@2323 113
 	p = getconfenv();
cinap_lenrek@2323 114
 
cinap_lenrek@2323 115
 	if(waserror()) {
cinap_lenrek@2323 116
 		free(p);
cinap_lenrek@2323 117
 		nexterror();
cinap_lenrek@2323 118
 	}
cinap_lenrek@2323 119
 
cinap_lenrek@2323 120
 	/* convert to name=value\n format */
cinap_lenrek@2323 121
 	for(q=p; *q; q++) {
cinap_lenrek@2323 122
 		q += strlen(q);
cinap_lenrek@2323 123
 		*q = '=';
cinap_lenrek@2323 124
 		q += strlen(q);
cinap_lenrek@2323 125
 		*q = '\n';
cinap_lenrek@2323 126
 	}
cinap_lenrek@2323 127
 	n = q - p + 1;
cinap_lenrek@2323 128
 	if(n >= BOOTARGSLEN)
cinap_lenrek@2323 129
 		error("kernel configuration too large");
cinap_lenrek@2323 130
 	memmove(BOOTARGS, p, n);
cinap_lenrek@2323 131
 	memset(BOOTARGS + n, '\n', BOOTARGSLEN - n);
cinap_lenrek@2323 132
 	poperror();
cinap_lenrek@2323 133
 	free(p);
cinap_lenrek@2323 134
 }
cinap_lenrek@2323 135
 
cinap_lenrek@2323 136
 static void
cinap_lenrek@2323 137
 plan9iniinit(char *s, int cmdline)
cinap_lenrek@2323 138
 {
cinap_lenrek@2323 139
 	char *toks[MAXCONF];
cinap_lenrek@2323 140
 	int i, c, n;
cinap_lenrek@2323 141
 	char *v;
cinap_lenrek@2323 142
 
cinap_lenrek@2323 143
 	if((c = *s) < ' ' || c >= 0x80)
cinap_lenrek@2323 144
 		return;
cinap_lenrek@2323 145
 	if(cmdline)
cinap_lenrek@2323 146
 		n = tokenize(s, toks, MAXCONF);
cinap_lenrek@2323 147
 	else
cinap_lenrek@2323 148
 		n = getfields(s, toks, MAXCONF, 1, "\n");
cinap_lenrek@2323 149
 	for(i = 0; i < n; i++){
cinap_lenrek@2323 150
 		if(toks[i][0] == '#')
cinap_lenrek@2323 151
 			continue;
cinap_lenrek@2323 152
 		v = strchr(toks[i], '=');
cinap_lenrek@2323 153
 		if(v == nil)
cinap_lenrek@2323 154
 			continue;
cinap_lenrek@2323 155
 		*v++ = '\0';
cinap_lenrek@2323 156
 		addconf(toks[i], v);
cinap_lenrek@2323 157
 	}
cinap_lenrek@2323 158
 }
cinap_lenrek@2323 159
 
cinap_lenrek@2323 160
 static void
cinap_lenrek@2323 161
 ataginit(Atag *a)
cinap_lenrek@2323 162
 {
cinap_lenrek@2323 163
 	int n;
cinap_lenrek@2323 164
 
cinap_lenrek@2323 165
 	if(a->tag != AtagCore){
cinap_lenrek@2323 166
 		plan9iniinit((char*)a, 0);
cinap_lenrek@2323 167
 		return;
cinap_lenrek@2323 168
 	}
cinap_lenrek@2323 169
 	while(a->tag != AtagNone){
cinap_lenrek@2323 170
 		switch(a->tag){
cinap_lenrek@2323 171
 		case AtagMem:
cinap_lenrek@2323 172
 			/* use only first bank */
cinap_lenrek@2323 173
 			if(conf.mem[0].limit == 0 && a->mem.size != 0){
cinap_lenrek@2323 174
 				memsize = a->mem.size;
cinap_lenrek@2323 175
 				conf.mem[0].base = a->mem.base;
cinap_lenrek@2323 176
 				conf.mem[0].limit = a->mem.base + memsize;
cinap_lenrek@2323 177
 			}
cinap_lenrek@2323 178
 			break;
cinap_lenrek@2323 179
 		case AtagCmdline:
cinap_lenrek@2323 180
 			n = (a->size * sizeof(u32int)) - offsetof(Atag, cmdline[0]);
cinap_lenrek@2323 181
 			if(a->cmdline + n < BOOTARGS + BOOTARGSLEN)
cinap_lenrek@2323 182
 				a->cmdline[n] = 0;
cinap_lenrek@2323 183
 			else
cinap_lenrek@2323 184
 				BOOTARGS[BOOTARGSLEN-1] = 0;
cinap_lenrek@2323 185
 			plan9iniinit(a->cmdline, 1);
cinap_lenrek@2323 186
 			break;
cinap_lenrek@2323 187
 		}
cinap_lenrek@2323 188
 		a = (Atag*)((u32int*)a + a->size);
cinap_lenrek@2323 189
 	}
cinap_lenrek@2323 190
 }
cinap_lenrek@2323 191
 
cinap_lenrek@2323 192
 void
cinap_lenrek@2323 193
 machinit(void)
cinap_lenrek@2323 194
 {
cinap_lenrek@6832 195
 	Mach *m0;
cinap_lenrek@6832 196
 
cinap_lenrek@6832 197
 	m->ticks = 1;
cinap_lenrek@6832 198
 	m->perf.period = 1;
cinap_lenrek@6832 199
 	m0 = MACHP(0);
cinap_lenrek@6832 200
 	if (m->machno != 0) {
cinap_lenrek@6832 201
 		/* synchronise with cpu 0 */
cinap_lenrek@6832 202
 		m->ticks = m0->ticks;
cinap_lenrek@6832 203
 	}
cinap_lenrek@6832 204
 }
cinap_lenrek@6832 205
 
cinap_lenrek@6832 206
 void
cinap_lenrek@6832 207
 mach0init(void)
cinap_lenrek@6832 208
 {
cinap_lenrek@6832 209
 	m->mmul1 = (PTE*)L1;
cinap_lenrek@2323 210
 	m->machno = 0;
cinap_lenrek@2323 211
 	machaddr[m->machno] = m;
cinap_lenrek@2323 212
 
cinap_lenrek@2323 213
 	m->ticks = 1;
cinap_lenrek@2323 214
 	m->perf.period = 1;
cinap_lenrek@2323 215
 
cinap_lenrek@5034 216
 	active.machs[0] = 1;
cinap_lenrek@2323 217
 	active.exiting = 0;
cinap_lenrek@2323 218
 
cinap_lenrek@2323 219
 	up = nil;
cinap_lenrek@2323 220
 }
cinap_lenrek@2323 221
 
cinap_lenrek@2323 222
 static void
cinap_lenrek@6832 223
 launchinit(void)
cinap_lenrek@6832 224
 {
cinap_lenrek@6832 225
 	int mach;
cinap_lenrek@6832 226
 	Mach *mm;
cinap_lenrek@6832 227
 	PTE *l1;
cinap_lenrek@6832 228
 
cinap_lenrek@6832 229
 	for(mach = 1; mach < conf.nmach; mach++){
cinap_lenrek@6832 230
 		machaddr[mach] = mm = mallocalign(MACHSIZE, MACHSIZE, 0, 0);
cinap_lenrek@6832 231
 		l1 = mallocalign(L1SIZE, L1SIZE, 0, 0);
cinap_lenrek@6832 232
 		if(mm == nil || l1 == nil)
cinap_lenrek@6832 233
 			panic("launchinit");
cinap_lenrek@6832 234
 		memset(mm, 0, MACHSIZE);
cinap_lenrek@6832 235
 		mm->machno = mach;
cinap_lenrek@6832 236
 
cinap_lenrek@6832 237
 		memmove(l1, m->mmul1, L1SIZE);  /* clone cpu0's l1 table */
cinap_lenrek@6832 238
 		cachedwbse(l1, L1SIZE);
cinap_lenrek@6832 239
 		mm->mmul1 = l1;
cinap_lenrek@6832 240
 		cachedwbse(mm, MACHSIZE);
cinap_lenrek@6832 241
 
cinap_lenrek@6832 242
 	}
cinap_lenrek@6832 243
 	cachedwbse(machaddr, sizeof machaddr);
cinap_lenrek@6832 244
 	if((mach = startcpus(conf.nmach)) < conf.nmach)
cinap_lenrek@6855 245
 		print("only %d cpu%s started\n", mach, mach == 1? "" : "s");
cinap_lenrek@6832 246
 }
cinap_lenrek@6832 247
 
cinap_lenrek@6832 248
 static void
cinap_lenrek@2323 249
 optionsinit(char* s)
cinap_lenrek@2323 250
 {
cinap_lenrek@2323 251
 	strecpy(oargb, oargb+sizeof(oargb), s);
cinap_lenrek@2323 252
 
cinap_lenrek@2323 253
 	oargblen = strlen(oargb);
cinap_lenrek@2323 254
 	oargc = tokenize(oargb, oargv, nelem(oargv)-1);
cinap_lenrek@2323 255
 	oargv[oargc] = nil;
cinap_lenrek@2323 256
 }
cinap_lenrek@2323 257
 
cinap_lenrek@2323 258
 void
cinap_lenrek@2323 259
 main(void)
cinap_lenrek@2323 260
 {
cinap_lenrek@2323 261
 	extern char edata[], end[];
cinap_lenrek@6832 262
 	uint fw, board;
cinap_lenrek@2323 263
 
cinap_lenrek@2323 264
 	m = (Mach*)MACHADDR;
cinap_lenrek@2323 265
 	memset(edata, 0, end - edata);	/* clear bss */
cinap_lenrek@6832 266
 	mach0init();
cinap_lenrek@2323 267
 
cinap_lenrek@2323 268
 	optionsinit("/boot/boot boot");
cinap_lenrek@2323 269
 	quotefmtinstall();
cinap_lenrek@2323 270
 	
cinap_lenrek@2323 271
 	ataginit((Atag*)BOOTARGS);
cinap_lenrek@2323 272
 	confinit();		/* figures out amount of memory */
cinap_lenrek@2323 273
 	xinit();
cinap_lenrek@2323 274
 	uartconsinit();
cinap_lenrek@2323 275
 	screeninit();
cinap_lenrek@2323 276
 
cinap_lenrek@2323 277
 	print("\nPlan 9 from Bell Labs\n");
cinap_lenrek@6832 278
 	board = getboardrev();
cinap_lenrek@6832 279
 	fw = getfirmware();
cinap_lenrek@6832 280
 	print("board rev: %#ux firmware rev: %d\n", board, fw);
cinap_lenrek@6832 281
 	if(fw < Minfirmrev){
cinap_lenrek@6832 282
 		print("Sorry, firmware (start*.elf) must be at least rev %d"
cinap_lenrek@6832 283
 		      " or newer than %s\n", Minfirmrev, Minfirmdate);
cinap_lenrek@2323 284
 		for(;;)
cinap_lenrek@2323 285
 			;
cinap_lenrek@2323 286
 	}
cinap_lenrek@6832 287
 	/* set clock rate to arm_freq from config.txt (default pi1:700Mhz pi2:900MHz) */
cinap_lenrek@6832 288
 	setclkrate(ClkArm, 0);
cinap_lenrek@2323 289
 	trapinit();
cinap_lenrek@2323 290
 	clockinit();
cinap_lenrek@2323 291
 	printinit();
cinap_lenrek@2323 292
 	timersinit();
cinap_lenrek@2323 293
 	cpuidprint();
cinap_lenrek@2323 294
 	archreset();
cinap_lenrek@6832 295
 	vgpinit();
cinap_lenrek@2323 296
 
cinap_lenrek@2323 297
 	procinit0();
cinap_lenrek@2323 298
 	initseg();
cinap_lenrek@2323 299
 	links();
cinap_lenrek@2323 300
 	chandevreset();			/* most devices are discovered here */
cinap_lenrek@2323 301
 	pageinit();
cinap_lenrek@2323 302
 	userinit();
cinap_lenrek@6832 303
 	launchinit();
cinap_lenrek@6851 304
 	mmuinit1(0);
cinap_lenrek@2323 305
 	schedinit();
cinap_lenrek@2323 306
 	assert(0);			/* shouldn't have returned */
cinap_lenrek@2323 307
 }
cinap_lenrek@2323 308
 
cinap_lenrek@2323 309
 /*
cinap_lenrek@2323 310
  *  starting place for first process
cinap_lenrek@2323 311
  */
cinap_lenrek@2323 312
 void
cinap_lenrek@2323 313
 init0(void)
cinap_lenrek@2323 314
 {
cinap_lenrek@2323 315
 	int i;
cinap_lenrek@2323 316
 	char buf[2*KNAMELEN];
cinap_lenrek@2323 317
 
cinap_lenrek@2323 318
 	up->nerrlab = 0;
cinap_lenrek@2323 319
 	coherence();
cinap_lenrek@2323 320
 	spllo();
cinap_lenrek@2323 321
 
cinap_lenrek@2323 322
 	/*
cinap_lenrek@2323 323
 	 * These are o.k. because rootinit is null.
cinap_lenrek@2323 324
 	 * Then early kproc's will have a root and dot.
cinap_lenrek@2323 325
 	 */
cinap_lenrek@2323 326
 	up->slash = namec("#/", Atodir, 0, 0);
cinap_lenrek@2323 327
 	pathclose(up->slash->path);
cinap_lenrek@2323 328
 	up->slash->path = newpath("/");
cinap_lenrek@2323 329
 	up->dot = cclone(up->slash);
cinap_lenrek@2323 330
 
cinap_lenrek@2323 331
 	chandevinit();
cinap_lenrek@2323 332
 
cinap_lenrek@2323 333
 	if(!waserror()){
cinap_lenrek@2323 334
 		snprint(buf, sizeof(buf), "%s %s", "ARM", conffile);
cinap_lenrek@2323 335
 		ksetenv("terminal", buf, 0);
cinap_lenrek@2323 336
 		ksetenv("cputype", "arm", 0);
cinap_lenrek@2323 337
 		if(cpuserver)
cinap_lenrek@2323 338
 			ksetenv("service", "cpu", 0);
cinap_lenrek@2323 339
 		else
cinap_lenrek@2323 340
 			ksetenv("service", "terminal", 0);
cinap_lenrek@2323 341
 		snprint(buf, sizeof(buf), "-a %s", getethermac());
cinap_lenrek@2323 342
 		ksetenv("etherargs", buf, 0);
cinap_lenrek@2323 343
 
cinap_lenrek@2323 344
 		/* convert plan9.ini variables to #e and #ec */
cinap_lenrek@2323 345
 		for(i = 0; i < nconf; i++) {
cinap_lenrek@2323 346
 			ksetenv(confname[i], confval[i], 0);
cinap_lenrek@2323 347
 			ksetenv(confname[i], confval[i], 1);
cinap_lenrek@2323 348
 		}
cinap_lenrek@2323 349
 		poperror();
cinap_lenrek@2323 350
 	}
cinap_lenrek@2323 351
 	kproc("alarm", alarmkproc, 0);
cinap_lenrek@2323 352
 	touser(sp);
cinap_lenrek@2323 353
 	assert(0);			/* shouldn't have returned */
cinap_lenrek@2323 354
 }
cinap_lenrek@2323 355
 
cinap_lenrek@2323 356
 static void
cinap_lenrek@2323 357
 bootargs(uintptr base)
cinap_lenrek@2323 358
 {
cinap_lenrek@2323 359
 	int i;
cinap_lenrek@2323 360
 	ulong ssize;
cinap_lenrek@2323 361
 	char **av, *p;
cinap_lenrek@2323 362
 
cinap_lenrek@2323 363
 	/*
cinap_lenrek@2323 364
 	 * Push the boot args onto the stack.
cinap_lenrek@2323 365
 	 * The initial value of the user stack must be such
cinap_lenrek@2323 366
 	 * that the total used is larger than the maximum size
cinap_lenrek@2323 367
 	 * of the argument list checked in syscall.
cinap_lenrek@2323 368
 	 */
cinap_lenrek@2323 369
 	i = oargblen+1;
cinap_lenrek@7155 370
 	p = (void*)STACKALIGN(base + BY2PG - sizeof(Tos) - i);
cinap_lenrek@2323 371
 	memmove(p, oargb, i);
cinap_lenrek@2323 372
 
cinap_lenrek@2323 373
 	/*
cinap_lenrek@2323 374
 	 * Now push the argv pointers.
cinap_lenrek@2323 375
 	 * The code jumped to by touser in lproc.s expects arguments
cinap_lenrek@2323 376
 	 *	main(char* argv0, ...)
cinap_lenrek@2323 377
 	 * and calls
cinap_lenrek@2323 378
 	 * 	startboot("/boot/boot", &argv0)
cinap_lenrek@2323 379
 	 * not the usual (int argc, char* argv[])
cinap_lenrek@2323 380
 	 */
cinap_lenrek@2323 381
 	av = (char**)(p - (oargc+1)*sizeof(char*));
cinap_lenrek@7155 382
 	ssize = base + BY2PG - (uintptr)av;
cinap_lenrek@2323 383
 	for(i = 0; i < oargc; i++)
cinap_lenrek@2323 384
 		*av++ = (oargv[i] - oargb) + (p - base) + (USTKTOP - BY2PG);
cinap_lenrek@2323 385
 	*av = nil;
cinap_lenrek@2323 386
 	sp = USTKTOP - ssize;
cinap_lenrek@2323 387
 }
cinap_lenrek@2323 388
 
cinap_lenrek@2323 389
 /*
cinap_lenrek@2323 390
  *  create the first process
cinap_lenrek@2323 391
  */
cinap_lenrek@2323 392
 void
cinap_lenrek@2323 393
 userinit(void)
cinap_lenrek@2323 394
 {
cinap_lenrek@2323 395
 	Proc *p;
cinap_lenrek@2323 396
 	Segment *s;
cinap_lenrek@2323 397
 	KMap *k;
cinap_lenrek@2323 398
 	Page *pg;
cinap_lenrek@2323 399
 
cinap_lenrek@2323 400
 	/* no processes yet */
cinap_lenrek@2323 401
 	up = nil;
cinap_lenrek@2323 402
 
cinap_lenrek@2323 403
 	p = newproc();
cinap_lenrek@2323 404
 	p->pgrp = newpgrp();
cinap_lenrek@2323 405
 	p->egrp = smalloc(sizeof(Egrp));
cinap_lenrek@2323 406
 	p->egrp->ref = 1;
cinap_lenrek@2323 407
 	p->fgrp = dupfgrp(nil);
cinap_lenrek@2323 408
 	p->rgrp = newrgrp();
cinap_lenrek@2323 409
 	p->procmode = 0640;
cinap_lenrek@2323 410
 
cinap_lenrek@2323 411
 	kstrdup(&eve, "");
cinap_lenrek@2323 412
 	kstrdup(&p->text, "*init*");
cinap_lenrek@2323 413
 	kstrdup(&p->user, eve);
cinap_lenrek@2323 414
 
cinap_lenrek@2323 415
 	/*
cinap_lenrek@2323 416
 	 * Kernel Stack
cinap_lenrek@2323 417
 	 */
cinap_lenrek@7155 418
 	p->sched.pc = (uintptr)init0;
cinap_lenrek@7155 419
 	p->sched.sp = (uintptr)p->kstack+KSTACK-sizeof(up->s.args)-sizeof(uintptr);
cinap_lenrek@2323 420
 	p->sched.sp = STACKALIGN(p->sched.sp);
cinap_lenrek@2323 421
 
cinap_lenrek@2323 422
 	/*
cinap_lenrek@2323 423
 	 * User Stack
cinap_lenrek@2323 424
 	 *
cinap_lenrek@2323 425
 	 * Technically, newpage can't be called here because it
cinap_lenrek@2323 426
 	 * should only be called when in a user context as it may
cinap_lenrek@2323 427
 	 * try to sleep if there are no pages available, but that
cinap_lenrek@2323 428
 	 * shouldn't be the case here.
cinap_lenrek@2323 429
 	 */
cinap_lenrek@2323 430
 	s = newseg(SG_STACK, USTKTOP-USTKSIZE, USTKSIZE/BY2PG);
cinap_lenrek@2323 431
 	s->flushme++;
cinap_lenrek@2323 432
 	p->seg[SSEG] = s;
cinap_lenrek@2323 433
 	pg = newpage(1, 0, USTKTOP-BY2PG);
cinap_lenrek@2323 434
 	segpage(s, pg);
cinap_lenrek@2323 435
 	k = kmap(pg);
cinap_lenrek@2323 436
 	bootargs(VA(k));
cinap_lenrek@2323 437
 	kunmap(k);
cinap_lenrek@2323 438
 
cinap_lenrek@2323 439
 	/*
cinap_lenrek@2323 440
 	 * Text
cinap_lenrek@2323 441
 	 */
cinap_lenrek@2323 442
 	s = newseg(SG_TEXT, UTZERO, 1);
cinap_lenrek@2323 443
 	p->seg[TSEG] = s;
cinap_lenrek@2323 444
 	pg = newpage(1, 0, UTZERO);
cinap_lenrek@4250 445
 	pg->txtflush = ~0;
cinap_lenrek@2323 446
 	segpage(s, pg);
cinap_lenrek@2323 447
 	k = kmap(s->map[0]->pages[0]);
cinap_lenrek@7155 448
 	memmove((void*)VA(k), initcode, sizeof initcode);
cinap_lenrek@2323 449
 	kunmap(k);
cinap_lenrek@2323 450
 
cinap_lenrek@2323 451
 	ready(p);
cinap_lenrek@2323 452
 }
cinap_lenrek@2323 453
 
cinap_lenrek@2323 454
 void
cinap_lenrek@2323 455
 confinit(void)
cinap_lenrek@2323 456
 {
stanley@3401 457
 	int i, userpcnt;
cinap_lenrek@2323 458
 	ulong kpages;
cinap_lenrek@2323 459
 	uintptr pa;
cinap_lenrek@2323 460
 	char *p;
cinap_lenrek@2323 461
 
cinap_lenrek@3448 462
 	if(p = getconf("service")){
cinap_lenrek@3448 463
 		if(strcmp(p, "cpu") == 0)
cinap_lenrek@3448 464
 			cpuserver = 1;
cinap_lenrek@3448 465
 		else if(strcmp(p,"terminal") == 0)
cinap_lenrek@3448 466
 			cpuserver = 0;
cinap_lenrek@3448 467
 	}
cinap_lenrek@3448 468
 
stanley@3401 469
 	if(p = getconf("*kernelpercent"))
stanley@3401 470
 		userpcnt = 100 - strtol(p, 0, 0);
stanley@3401 471
 	else
stanley@3401 472
 		userpcnt = 0;
stanley@3401 473
 
cinap_lenrek@2323 474
 	if((p = getconf("*maxmem")) != nil){
cinap_lenrek@2323 475
 		memsize = strtoul(p, 0, 0) - PHYSDRAM;
cinap_lenrek@2323 476
 		if (memsize < 16*MB)		/* sanity */
cinap_lenrek@2323 477
 			memsize = 16*MB;
cinap_lenrek@2323 478
 	}
cinap_lenrek@2323 479
 
cinap_lenrek@2323 480
 	getramsize(&conf.mem[0]);
cinap_lenrek@2323 481
 	if(conf.mem[0].limit == 0){
cinap_lenrek@2323 482
 		conf.mem[0].base = PHYSDRAM;
cinap_lenrek@2323 483
 		conf.mem[0].limit = PHYSDRAM + memsize;
cinap_lenrek@2323 484
 	}else if(p != nil)
cinap_lenrek@2323 485
 		conf.mem[0].limit = conf.mem[0].base + memsize;
cinap_lenrek@2323 486
 
cinap_lenrek@2323 487
 	conf.npage = 0;
cinap_lenrek@7155 488
 	pa = PADDR(PGROUND((uintptr)end));
cinap_lenrek@2323 489
 
cinap_lenrek@2323 490
 	/*
cinap_lenrek@2323 491
 	 *  we assume that the kernel is at the beginning of one of the
cinap_lenrek@2323 492
 	 *  contiguous chunks of memory and fits therein.
cinap_lenrek@2323 493
 	 */
cinap_lenrek@2323 494
 	for(i=0; i<nelem(conf.mem); i++){
cinap_lenrek@2323 495
 		/* take kernel out of allocatable space */
cinap_lenrek@2323 496
 		if(pa > conf.mem[i].base && pa < conf.mem[i].limit)
cinap_lenrek@2323 497
 			conf.mem[i].base = pa;
cinap_lenrek@2323 498
 
cinap_lenrek@2323 499
 		conf.mem[i].npage = (conf.mem[i].limit - conf.mem[i].base)/BY2PG;
cinap_lenrek@2323 500
 		conf.npage += conf.mem[i].npage;
cinap_lenrek@2323 501
 	}
cinap_lenrek@2323 502
 
stanley@3401 503
 	if(userpcnt < 10)
stanley@3401 504
 		userpcnt = 60 + cpuserver*10;
stanley@3401 505
 	kpages = conf.npage - (conf.npage*userpcnt)/100;
stanley@3401 506
 
stanley@3401 507
 	/*
stanley@3401 508
 	 * can't go past the end of virtual memory
stanley@3401 509
 	 * (ulong)-KZERO is 2^32 - KZERO
stanley@3401 510
 	 */
stanley@3401 511
 	if(kpages > ((ulong)-KZERO)/BY2PG)
stanley@3401 512
 		kpages = ((ulong)-KZERO)/BY2PG;
stanley@3401 513
 
stanley@3401 514
 	conf.upages = conf.npage - kpages;
stanley@3401 515
 	conf.ialloc = (kpages/2)*BY2PG;
cinap_lenrek@2323 516
 
cinap_lenrek@6832 517
 	conf.nmach = getncpus();
cinap_lenrek@2323 518
 
cinap_lenrek@2323 519
 	/* set up other configuration parameters */
cinap_lenrek@2323 520
 	conf.nproc = 100 + ((conf.npage*BY2PG)/MB)*5;
cinap_lenrek@2323 521
 	if(cpuserver)
cinap_lenrek@2323 522
 		conf.nproc *= 3;
cinap_lenrek@2323 523
 	if(conf.nproc > 2000)
cinap_lenrek@2323 524
 		conf.nproc = 2000;
cinap_lenrek@2323 525
 	conf.nswap = conf.npage*3;
cinap_lenrek@2323 526
 	conf.nswppo = 4096;
cinap_lenrek@2323 527
 	conf.nimage = 200;
cinap_lenrek@2323 528
 
cinap_lenrek@6832 529
 	conf.copymode = conf.nmach > 1;
cinap_lenrek@2323 530
 
cinap_lenrek@2323 531
 	/*
cinap_lenrek@2323 532
 	 * Guess how much is taken by the large permanent
cinap_lenrek@4074 533
 	 * datastructures. Mntcache and Mntrpc are not accounted for.
cinap_lenrek@2323 534
 	 */
cinap_lenrek@2323 535
 	kpages = conf.npage - conf.upages;
cinap_lenrek@2323 536
 	kpages *= BY2PG;
cinap_lenrek@2323 537
 	kpages -= conf.upages*sizeof(Page)
cinap_lenrek@2323 538
 		+ conf.nproc*sizeof(Proc)
cinap_lenrek@2323 539
 		+ conf.nimage*sizeof(Image)
cinap_lenrek@2323 540
 		+ conf.nswap
stanley@3401 541
 		+ conf.nswppo*sizeof(Page*);
cinap_lenrek@2323 542
 	mainmem->maxsize = kpages;
cinap_lenrek@2323 543
 	if(!cpuserver)
cinap_lenrek@2323 544
 		/*
cinap_lenrek@2323 545
 		 * give terminals lots of image memory, too; the dynamic
cinap_lenrek@2323 546
 		 * allocation will balance the load properly, hopefully.
cinap_lenrek@2323 547
 		 * be careful with 32-bit overflow.
cinap_lenrek@2323 548
 		 */
cinap_lenrek@2323 549
 		imagmem->maxsize = kpages;
cinap_lenrek@2323 550
 
cinap_lenrek@2323 551
 }
cinap_lenrek@2323 552
 
cinap_lenrek@6851 553
 static void
cinap_lenrek@6855 554
 rebootjump(void *entry, void *code, ulong size)
cinap_lenrek@6851 555
 {
cinap_lenrek@6855 556
 	void (*f)(void*, void*, ulong);
cinap_lenrek@6851 557
 
cinap_lenrek@6851 558
 	intrsoff();
cinap_lenrek@6851 559
 	intrcpushutdown();
cinap_lenrek@6851 560
 
cinap_lenrek@6851 561
 	/* redo identity map */
cinap_lenrek@6851 562
 	mmuinit1(1);
cinap_lenrek@6851 563
 
cinap_lenrek@6855 564
 	/* setup reboot trampoline function */
cinap_lenrek@6855 565
 	f = (void*)REBOOTADDR;
cinap_lenrek@6855 566
 	memmove(f, rebootcode, sizeof(rebootcode));
cinap_lenrek@6851 567
 	cacheuwbinv();
cinap_lenrek@6851 568
 
cinap_lenrek@6851 569
 	(*f)(entry, code, size);
cinap_lenrek@6851 570
 
cinap_lenrek@6851 571
 	for(;;);
cinap_lenrek@6851 572
 }
cinap_lenrek@6851 573
 
cinap_lenrek@2323 574
 /*
cinap_lenrek@2323 575
  *  exit kernel either on a panic or user request
cinap_lenrek@2323 576
  */
cinap_lenrek@2323 577
 void
cinap_lenrek@4993 578
 exit(int)
cinap_lenrek@2323 579
 {
cinap_lenrek@4993 580
 	cpushutdown();
cinap_lenrek@2323 581
 	splfhi();
cinap_lenrek@6855 582
 	if(m->machno == 0)
cinap_lenrek@6855 583
 		archreboot();
cinap_lenrek@6855 584
 	rebootjump(0, 0, 0);
cinap_lenrek@2323 585
 }
cinap_lenrek@2323 586
 
cinap_lenrek@2323 587
 /*
cinap_lenrek@2323 588
  * stub for ../omap/devether.c
cinap_lenrek@2323 589
  */
cinap_lenrek@2323 590
 int
cinap_lenrek@6832 591
 isaconfig(char *, int, ISAConf *)
cinap_lenrek@2323 592
 {
cinap_lenrek@6832 593
 	return 0;
cinap_lenrek@2323 594
 }
cinap_lenrek@2323 595
 
cinap_lenrek@2323 596
 /*
cinap_lenrek@2323 597
  * the new kernel is already loaded at address `code'
cinap_lenrek@2323 598
  * of size `size' and entry point `entry'.
cinap_lenrek@2323 599
  */
cinap_lenrek@2323 600
 void
cinap_lenrek@2323 601
 reboot(void *entry, void *code, ulong size)
cinap_lenrek@2323 602
 {
cinap_lenrek@2323 603
 	writeconf();
cinap_lenrek@6855 604
 	while(m->machno != 0){
cinap_lenrek@6832 605
 		procwired(up, 0);
cinap_lenrek@6832 606
 		sched();
cinap_lenrek@6832 607
 	}
cinap_lenrek@6832 608
 
cinap_lenrek@4993 609
 	cpushutdown();
cinap_lenrek@6855 610
 	delay(2000);
cinap_lenrek@6832 611
 
cinap_lenrek@6832 612
 	splfhi();
cinap_lenrek@2323 613
 
cinap_lenrek@2323 614
 	/* turn off buffered serial console */
cinap_lenrek@2323 615
 	serialoq = nil;
cinap_lenrek@2323 616
 
cinap_lenrek@2323 617
 	/* shutdown devices */
cinap_lenrek@2323 618
 	chandevshutdown();
cinap_lenrek@2323 619
 
cinap_lenrek@2323 620
 	/* stop the clock (and watchdog if any) */
cinap_lenrek@2323 621
 	clockshutdown();
cinap_lenrek@6851 622
 	wdogoff();
cinap_lenrek@2323 623
 
cinap_lenrek@2323 624
 	/* off we go - never to return */
cinap_lenrek@6855 625
 	rebootjump(entry, code, size);
cinap_lenrek@2323 626
 }
cinap_lenrek@2323 627
 
aiju@6012 628
 void
aiju@6012 629
 setupwatchpts(Proc *, Watchpt *, int n)
aiju@6012 630
 {
aiju@6012 631
 	if(n > 0)
aiju@6012 632
 		error("no watchpoints");
aiju@6012 633
 }