changelog shortlog tags branches changeset file revisions annotate raw help

Mercurial > hg > plan9front / sys/src/9/bcm64/main.c

revision 7199: ba62683c0e2d
child 7206: 53f5476f9ffd
     1.1new file mode 100644
     1.2--- /dev/null
     1.3+++ b/sys/src/9/bcm64/main.c
     1.4@@ -0,0 +1,337 @@
     1.5+#include "u.h"
     1.6+#include "tos.h"
     1.7+#include "../port/lib.h"
     1.8+#include "mem.h"
     1.9+#include "dat.h"
    1.10+#include "fns.h"
    1.11+#include "../port/error.h"
    1.12+#include "io.h"
    1.13+#include "init.h"
    1.14+#include "sysreg.h"
    1.15+
    1.16+#include <pool.h>
    1.17+#include <libsec.h>
    1.18+
    1.19+Conf conf;
    1.20+ulong memsize = GiB;
    1.21+
    1.22+/*
    1.23+ *  starting place for first process
    1.24+ */
    1.25+void
    1.26+init0(void)
    1.27+{
    1.28+	char buf[2*KNAMELEN], **sp;
    1.29+
    1.30+	up->nerrlab = 0;
    1.31+	spllo();
    1.32+
    1.33+	/*
    1.34+	 * These are o.k. because rootinit is null.
    1.35+	 * Then early kproc's will have a root and dot.
    1.36+	 */
    1.37+	up->slash = namec("#/", Atodir, 0, 0);
    1.38+	pathclose(up->slash->path);
    1.39+	up->slash->path = newpath("/");
    1.40+	up->dot = cclone(up->slash);
    1.41+	chandevinit();
    1.42+
    1.43+	if(!waserror()){
    1.44+		snprint(buf, sizeof(buf), "%s %s", "ARM64", conffile);
    1.45+		ksetenv("terminal", buf, 0);
    1.46+		ksetenv("cputype", "arm64", 0);
    1.47+		if(cpuserver)
    1.48+			ksetenv("service", "cpu", 0);
    1.49+		else
    1.50+			ksetenv("service", "terminal", 0);
    1.51+		snprint(buf, sizeof(buf), "-a %s", getethermac());
    1.52+		ksetenv("etherargs", buf, 0);
    1.53+
    1.54+		/* convert plan9.ini variables to #e and #ec */
    1.55+		setconfenv();
    1.56+		poperror();
    1.57+	}
    1.58+	kproc("alarm", alarmkproc, 0);
    1.59+
    1.60+	sp = (char**)(USTKTOP-sizeof(Tos) - 8 - sizeof(sp[0])*4);
    1.61+	sp[3] = sp[2] = sp[1] = nil;
    1.62+	strcpy(sp[1] = (char*)&sp[4], "boot");
    1.63+	sp[0] = (void*)&sp[1];
    1.64+
    1.65+	touser((uintptr)sp);
    1.66+
    1.67+	assert(0);			/* shouldn't have returned */
    1.68+}
    1.69+
    1.70+/*
    1.71+ *  create the first process
    1.72+ */
    1.73+void
    1.74+userinit(void)
    1.75+{
    1.76+	Proc *p;
    1.77+	Segment *s;
    1.78+	KMap *k;
    1.79+	Page *pg;
    1.80+
    1.81+	/* no processes yet */
    1.82+	up = nil;
    1.83+
    1.84+	p = newproc();
    1.85+	p->pgrp = newpgrp();
    1.86+	p->egrp = smalloc(sizeof(Egrp));
    1.87+	p->egrp->ref = 1;
    1.88+	p->fgrp = dupfgrp(nil);
    1.89+	p->rgrp = newrgrp();
    1.90+	p->procmode = 0640;
    1.91+
    1.92+	kstrdup(&eve, "");
    1.93+	kstrdup(&p->text, "*init*");
    1.94+	kstrdup(&p->user, eve);
    1.95+
    1.96+	/*
    1.97+	 * Kernel Stack
    1.98+	 */
    1.99+	p->sched.pc = (uintptr)init0;
   1.100+	p->sched.sp = (uintptr)p->kstack+KSTACK-sizeof(up->s.args)-sizeof(uintptr);
   1.101+	p->sched.sp = STACKALIGN(p->sched.sp);
   1.102+	*(void**)p->sched.sp = kproc; // fake
   1.103+
   1.104+	/*
   1.105+	 * User Stack
   1.106+	 *
   1.107+	 * Technically, newpage can't be called here because it
   1.108+	 * should only be called when in a user context as it may
   1.109+	 * try to sleep if there are no pages available, but that
   1.110+	 * shouldn't be the case here.
   1.111+	 */
   1.112+	s = newseg(SG_STACK, USTKTOP-USTKSIZE, USTKSIZE/BY2PG);
   1.113+	s->flushme++;
   1.114+	p->seg[SSEG] = s;
   1.115+	pg = newpage(1, 0, USTKTOP-BY2PG);
   1.116+	segpage(s, pg);
   1.117+	k = kmap(pg);
   1.118+	memset((void*)VA(k), 0, BY2PG);
   1.119+	kunmap(k);
   1.120+
   1.121+	/*
   1.122+	 * Text
   1.123+	 */
   1.124+	s = newseg(SG_TEXT, UTZERO, 1);
   1.125+	p->seg[TSEG] = s;
   1.126+	pg = newpage(1, 0, UTZERO);
   1.127+	pg->txtflush = ~0;
   1.128+	segpage(s, pg);
   1.129+	k = kmap(s->map[0]->pages[0]);
   1.130+	memmove((void*)VA(k), initcode, sizeof initcode);
   1.131+	kunmap(k);
   1.132+
   1.133+	ready(p);
   1.134+}
   1.135+
   1.136+void
   1.137+confinit(void)
   1.138+{
   1.139+	int i, userpcnt;
   1.140+	ulong kpages;
   1.141+	uintptr pa;
   1.142+	char *p;
   1.143+
   1.144+	if(p = getconf("service")){
   1.145+		if(strcmp(p, "cpu") == 0)
   1.146+			cpuserver = 1;
   1.147+		else if(strcmp(p,"terminal") == 0)
   1.148+			cpuserver = 0;
   1.149+	}
   1.150+
   1.151+	if(p = getconf("*kernelpercent"))
   1.152+		userpcnt = 100 - strtol(p, 0, 0);
   1.153+	else
   1.154+		userpcnt = 0;
   1.155+
   1.156+	if((p = getconf("*maxmem")) != nil){
   1.157+		memsize = strtoul(p, 0, 0) - PHYSDRAM;
   1.158+		if (memsize < 16*MB)		/* sanity */
   1.159+			memsize = 16*MB;
   1.160+	}
   1.161+
   1.162+	getramsize(&conf.mem[0]);
   1.163+	if(conf.mem[0].limit == 0){
   1.164+		conf.mem[0].base = PHYSDRAM;
   1.165+		conf.mem[0].limit = PHYSDRAM + memsize;
   1.166+	}else if(p != nil)
   1.167+		conf.mem[0].limit = conf.mem[0].base + memsize;
   1.168+
   1.169+	conf.npage = 0;
   1.170+	pa = PADDR(PGROUND((uintptr)end));
   1.171+
   1.172+	/*
   1.173+	 *  we assume that the kernel is at the beginning of one of the
   1.174+	 *  contiguous chunks of memory and fits therein.
   1.175+	 */
   1.176+	for(i=0; i<nelem(conf.mem); i++){
   1.177+		/* take kernel out of allocatable space */
   1.178+		if(pa > conf.mem[i].base && pa < conf.mem[i].limit)
   1.179+			conf.mem[i].base = pa;
   1.180+
   1.181+		conf.mem[i].npage = (conf.mem[i].limit - conf.mem[i].base)/BY2PG;
   1.182+		conf.npage += conf.mem[i].npage;
   1.183+	}
   1.184+
   1.185+	if(userpcnt < 10)
   1.186+		userpcnt = 60 + cpuserver*10;
   1.187+	kpages = conf.npage - (conf.npage*userpcnt)/100;
   1.188+
   1.189+	/*
   1.190+	 * can't go past the end of virtual memory
   1.191+	 * (uintptr)-KZERO is 2^32 - KZERO
   1.192+	 */
   1.193+	if(kpages > ((uintptr)-KZERO)/BY2PG)
   1.194+		kpages = ((uintptr)-KZERO)/BY2PG;
   1.195+
   1.196+	conf.upages = conf.npage - kpages;
   1.197+	conf.ialloc = (kpages/2)*BY2PG;
   1.198+
   1.199+	conf.nmach = getncpus();
   1.200+
   1.201+	/* set up other configuration parameters */
   1.202+	conf.nproc = 100 + ((conf.npage*BY2PG)/MB)*5;
   1.203+	if(cpuserver)
   1.204+		conf.nproc *= 3;
   1.205+	if(conf.nproc > 2000)
   1.206+		conf.nproc = 2000;
   1.207+	conf.nswap = conf.npage*3;
   1.208+	conf.nswppo = 4096;
   1.209+	conf.nimage = 200;
   1.210+
   1.211+	conf.copymode = conf.nmach > 1;
   1.212+
   1.213+	/*
   1.214+	 * Guess how much is taken by the large permanent
   1.215+	 * datastructures. Mntcache and Mntrpc are not accounted for.
   1.216+	 */
   1.217+	kpages = conf.npage - conf.upages;
   1.218+	kpages *= BY2PG;
   1.219+	kpages -= conf.upages*sizeof(Page)
   1.220+		+ conf.nproc*sizeof(Proc)
   1.221+		+ conf.nimage*sizeof(Image)
   1.222+		+ conf.nswap
   1.223+		+ conf.nswppo*sizeof(Page*);
   1.224+	mainmem->maxsize = kpages;
   1.225+	if(!cpuserver)
   1.226+		/*
   1.227+		 * give terminals lots of image memory, too; the dynamic
   1.228+		 * allocation will balance the load properly, hopefully.
   1.229+		 * be careful with 32-bit overflow.
   1.230+		 */
   1.231+		imagmem->maxsize = kpages;
   1.232+}
   1.233+
   1.234+void
   1.235+machinit(void)
   1.236+{
   1.237+	m->ticks = 1;
   1.238+	m->perf.period = 1;
   1.239+	active.machs[m->machno] = 1;
   1.240+}
   1.241+
   1.242+void
   1.243+mpinit(void)
   1.244+{
   1.245+	extern void _start(void);
   1.246+	int i;
   1.247+
   1.248+	for(i = 0; i < MAXMACH; i++)
   1.249+		((uintptr*)SPINTABLE)[i] = 0;
   1.250+
   1.251+	for(i = 1; i < conf.nmach; i++)
   1.252+		MACHP(i)->machno = i;
   1.253+
   1.254+	cachedwbinv();
   1.255+
   1.256+	for(i = 1; i < conf.nmach; i++)
   1.257+		((uintptr*)SPINTABLE)[i] = PADDR(_start);
   1.258+
   1.259+	cachedwbinvse((void*)SPINTABLE, MAXMACH*8);
   1.260+	sev();
   1.261+	delay(100);
   1.262+	sev();
   1.263+	synccycles();
   1.264+}
   1.265+
   1.266+void
   1.267+idlehands(void)
   1.268+{
   1.269+}
   1.270+
   1.271+void
   1.272+main(void)
   1.273+{
   1.274+	machinit();
   1.275+	if(m->machno){
   1.276+		trapinit();
   1.277+		fpuinit();
   1.278+		clockinit();
   1.279+		cpuidprint();
   1.280+		synccycles();
   1.281+		timersinit();
   1.282+		flushtlb();
   1.283+		mmu1init();
   1.284+		delay(4000);	/* usb initilization is busted multicore, let cpu0 do it */
   1.285+		m->ticks = MACHP(0)->ticks;
   1.286+		schedinit();
   1.287+		return;
   1.288+	}
   1.289+	bootargsinit();
   1.290+	confinit();
   1.291+	xinit();
   1.292+	printinit();
   1.293+	fmtinstall('H', encodefmt);
   1.294+	quotefmtinstall();
   1.295+	uartconsinit();
   1.296+	screeninit();
   1.297+	print("\nPlan 9\n");
   1.298+	xsummary();
   1.299+
   1.300+	/* set clock rate to arm_freq from config.txt */
   1.301+	setclkrate(ClkArm, 0);
   1.302+
   1.303+	trapinit();
   1.304+	fpuinit();
   1.305+	clockinit();
   1.306+	cpuidprint();
   1.307+	timersinit();
   1.308+	pageinit();
   1.309+	procinit0();
   1.310+	initseg();
   1.311+	links();
   1.312+	chandevreset();
   1.313+	userinit();
   1.314+	mpinit();
   1.315+	mmu0clear((uintptr*)L1);
   1.316+	flushtlb();
   1.317+	mmu1init();
   1.318+	schedinit();
   1.319+}
   1.320+
   1.321+void
   1.322+exit(int)
   1.323+{
   1.324+	cpushutdown();
   1.325+	for(;;);
   1.326+}
   1.327+
   1.328+void
   1.329+reboot(void*, void*, ulong)
   1.330+{
   1.331+	error(Egreg);
   1.332+}
   1.333+
   1.334+/*
   1.335+ * stub for ../omap/devether.c
   1.336+ */
   1.337+int
   1.338+isaconfig(char *, int, ISAConf *)
   1.339+{
   1.340+	return 0;
   1.341+}