Пример #1
0
/*
 * called on a cpu other than 0 from cpureset in l.s,
 * from _vrst in lexception.s.
 * mmu and l1 (and system-wide l2) caches and coherency (smpon) are on,
 * but interrupts are disabled.
 * our mmu is using an exact copy of cpu0's l1 page table
 * as it was after userinit ran.
 */
void
cpustart(void)
{
	int ms;
	ulong *evp;
	Power *pwr;

	up = nil;
	if (active.machs & (1<<m->machno)) {
		serialputc('?');
		serialputc('r');
		panic("cpu%d: resetting after start", m->machno);
	}
	assert(m->machno != 0);

	errata();
	cortexa9cachecfg();
	memdiag(&testmem);

	machinit();			/* bumps nmach, adds bit to machs */
	machoff(m->machno);		/* not ready to go yet */

	/* clock signals and scu are system-wide and already on */
	clockshutdown();		/* kill any watch-dog timer */

	trapinit();
	clockinit();			/* sets loop delay */
	timersinit();
	cpuidprint();

	/*
	 * notify cpu0 that we're up so it can proceed to l1diag.
	 */
	evp = (ulong *)soc.exceptvec;	/* magic */
	*evp = m->machno;
	coherence();

	l1diag();		/* contend with other cpus to verify sanity */

	/*
	 * pwr->noiopwr == 0
	 * pwr->detect == 0x1ff (default, all disabled)
	 */
	pwr = (Power *)soc.power;
	assert(pwr->gatests == MASK(7)); /* everything has power */

	/*
	 * 8169 has to initialise before we get past this, thus cpu0
	 * has to schedule processes first.
	 */
	if (Debug)
		iprint("cpu%d: waiting for 8169\n", m->machno);
	for (ms = 0; !l1ptstable.word && ms < 5000; ms += 10) {
		delay(10);
		cachedinvse(&l1ptstable.word, sizeof l1ptstable.word);
	}
	if (!l1ptstable.word)
		iprint("cpu%d: 8169 unreasonably slow; proceeding\n", m->machno);
	/* now safe to copy cpu0's l1 pt in mmuinit */

	mmuinit();			/* update our l1 pt from cpu0's */
	fpon();
	machon(m->machno);		/* now ready to go and be scheduled */

	if (Debug)
		iprint("cpu%d: scheding\n", m->machno);
	schedinit();
	panic("cpu%d: schedinit returned", m->machno);
}
Пример #2
0
/*
 * at entry, l.s has set m for cpu0 and printed "Plan 9 from Be"
 * but has not zeroed bss.
 */
void
main(void)
{
	int cpu;
	static ulong vfy = 0xcafebabe;

	up = nil;
	if (vfy != 0xcafebabe) {
		serialputc('?');
		serialputc('d');
		panic("data segment misaligned");
	}

	memset(edata, 0, end - edata);

	/*
	 * we can't lock until smpon has run, but we're supposed to wait
	 * until l1 & l2 are on.  too bad.  l1 is on, l2 will soon be.
	 */
	smpon();
	iprint("ll Labs ");
	cacheinit();

	/*
	 * data segment is aligned, bss is zeroed, caches' characteristics
	 * are known.  begin initialisation.
	 */
	mach0init();
	l2pageinit();
	mmuinit();

	optionsinit("/boot/boot boot");
	quotefmtinstall();

	/* want plan9.ini to be able to affect memory sizing in confinit */
	plan9iniinit();		/* before we step on plan9.ini in low memory */

	/* l2 looks for *l2off= in plan9.ini */
	l2cache->on();		/* l2->on requires locks to work, thus smpon */
	l2cache->info(&cachel[2]);
	allcache->on();

	cortexa9cachecfg();

	trapinit();		/* so confinit can probe memory to size it */
	confinit();		/* figures out amount of memory */
	/* xinit prints (if it can), so finish up the banner here. */
	delay(100);
	navailcpus = getncpus();
	iprint("(mp arm; %d cpus)\n\n", navailcpus);
	delay(100);

	for (cpu = 1; cpu < navailcpus; cpu++)
		stopcpu(cpu);

	xinit();
	irqtooearly = 0;	/* now that xinit and trapinit have run */

	mainmem->flags |= POOL_ANTAGONISM /* | POOL_PARANOIA */ ;

	/*
	 * Printinit will cause the first malloc call.
	 * (printinit->qopen->malloc) unless any of the
	 * above (like clockinit) do an irqenable, which
	 * will call malloc.
	 * If the system dies here it's probably due
	 * to malloc(->xalloc) not being initialised
	 * correctly, or the data segment is misaligned
	 * (it's amazing how far you can get with
	 * things like that completely broken).
	 *
	 * (Should be) boilerplate from here on.
	 */

	archreset();			/* cfg clock signals, print cache cfg */
	clockinit();			/* start clocks */
	timersinit();

	delay(50);			/* let uart catch up */
	printinit();
	kbdenable();

	cpuidprint();
	chkmissing();

	procinit0();
	initseg();

//	dmainit();
	links();
	conf.monitor = 1;
//	screeninit();

	iprint("pcireset...");
	pcireset();			/* this tends to hang after a reboot */
	iprint("ok\n");

	chandevreset();			/* most devices are discovered here */
//	i8250console();			/* too early; see init0 */

	pageinit();			/* prints "1020M memory: ⋯ */
	swapinit();
	userinit();

	/*
	 * starting a cpu will eventually result in it calling schedinit,
	 * so everything necessary to run user processes should be set up
	 * before starting secondary cpus.
	 */
	launchinit();
	/* SMP & FW are already on when we get here; u-boot set them? */
	for (cpu = 1; cpu < navailcpus; cpu++)
		if (startcpu(cpu) < 0)
			panic("cpu%d didn't start", cpu);
	l1diag();

	schedinit();
	panic("cpu%d: schedinit returned", m->machno);
}