Exemple #1
0
/*
 * The CPU ends up here when its ready to run
 * This is called from code in mptramp.s; at this point, we are running
 * in the idle pcb/idle stack of the new cpu.  When this function returns,
 * this processor will enter the idle loop and start looking for work.
 *
 * XXX should share some of this with init386 in machdep.c
 */
void
cpu_hatch(void *v)
{
	struct cpu_info *ci = (struct cpu_info *)v;
	int s;

	cpu_init_msrs(ci);

	cpu_probe_features(ci);
	cpu_feature &= ci->ci_feature_flags;

#ifdef DEBUG
	if (ci->ci_flags & CPUF_PRESENT)
		panic("%s: already running!?", ci->ci_dev->dv_xname);
#endif

	ci->ci_flags |= CPUF_PRESENT;

	lapic_enable();
	lapic_initclocks();

	while ((ci->ci_flags & CPUF_GO) == 0)
		delay(10);
#ifdef DEBUG
	if (ci->ci_flags & CPUF_RUNNING)
		panic("%s: already running!?", ci->ci_dev->dv_xname);
#endif

	lcr0(ci->ci_idle_pcb->pcb_cr0);
	cpu_init_idt();
	lapic_set_lvt();
	gdt_init_cpu(ci);
	fpuinit(ci);

	lldt(GSYSSEL(GLDT_SEL, SEL_KPL));

	cpu_init(ci);

	s = splhigh();
	lcr8(0);
	enable_intr();

	microuptime(&ci->ci_schedstate.spc_runtime);
	splx(s);

	SCHED_LOCK(s);
	cpu_switchto(NULL, sched_chooseproc());
}
/*
 * Determine i/o configuration for a machine.
 */
void
cpu_configure(void)
{
	struct pcb *pcb;

	startrtclock();

#if NBIOS32 > 0
	bios32_init();
	platform_init();
#endif
#ifdef PCIBIOS
	pcibios_init();
#endif

	if (config_rootfound("mainbus", NULL) == NULL)
		panic("configure: mainbus not configured");

#ifdef INTRDEBUG
	intr_printconfig();
#endif

#if NIOAPIC > 0
	ioapic_enable();
#endif
	fpuinit(&cpu_info_primary);
	/* resync cr0 after FPU configuration */
	pcb = lwp_getpcb(&lwp0);
	pcb->pcb_cr0 = rcr0() & ~CR0_TS;
#ifdef MULTIPROCESSOR
	/* propagate this to the idle pcb's. */
	cpu_init_idle_lwps();
#endif

	spl0();
#if NLAPIC > 0
	lapic_tpr = 0;
#endif
}
Exemple #3
0
void
squidboy(int apicno)
{
	char *n[] = {
		[NIXAC] "AC",
		[NIXTC] "TC",
		[NIXKC]	"KC"
	};
	vlong hz;

	sys->machptr[m->machno] = m;
	setmachsched(m);
	/*
	 * Need something for initial delays
	 * until a timebase is worked out.
	 */
	m->cpuhz = 2000000000ll;
	m->cpumhz = 2000;
	m->perf.period = 1;

	m->nixtype = NIXAC;

	DBG("Hello Squidboy %d %d\n", apicno, m->machno);

	vsvminit(MACHSTKSZ, m->nixtype);

	/*
	 * Beware the Curse of The Non-Interruptable Were-Temporary.
	 */
	hz = archhz();
	if(hz == 0)
		ndnr();
	m->cpuhz = hz;
	m->cyclefreq = hz;
	m->cpumhz = hz/1000000ll;

	mmuinit();
	if(!apiconline())
		ndnr();
	fpuinit();

	acmodeset(m->nixtype);
	m->splpc = 0;
	m->online = 1;

	/*
	 * CAUTION: no time sync done, etc.
	 */
	DBG("Wait for the thunderbirds!\n");
	while(!active.thunderbirdsarego)
		;
	wrmsr(0x10, sys->epoch);
	m->rdtsc = rdtsc();

	print("cpu%d color %d role %s tsc %lld\n",
		m->machno, corecolor(m->machno), n[m->nixtype], m->rdtsc);
	switch(m->nixtype){
	case NIXAC:
		acmmuswitch();
		acinit();
		adec(&active.nbooting);
		ainc(&active.nonline);	/* this was commented out */
		acsched();
		panic("squidboy");
		break;
	case NIXTC:
		/*
		 * We only need the idt and syscall entry point actually.
		 * At boot time the boot processor might set our role after
		 * we have decided to become an AC.
		 */
		vsvminit(MACHSTKSZ, NIXTC);

		/*
		 * Enable the timer interrupt.
		 */
		apicpri(0);

		timersinit();
		adec(&active.nbooting);
		ainc(&active.nonline);	/* this was commented out */

		schedinit();
		break;
	}
	panic("squidboy returns (type %d)", m->nixtype);
}
Exemple #4
0
void
main(u32int ax, u32int bx)
{
	vlong hz;

	memset(edata, 0, end - edata);

	/*
	 * ilock via i8250enable via i8250console
	 * needs m->machno, sys->machptr[] set, and
	 * also 'up' set to nil.
	 */
	cgapost(sizeof(uintptr)*8);
	memset(m, 0, sizeof(Mach));
	m->machno = 0;
	m->online = 1;
	m->nixtype = NIXTC;
	sys->machptr[m->machno] = &sys->mach;
	m->stack = PTR2UINT(sys->machstk);
	m->vsvm = sys->vsvmpage;
	up = nil;
	active.nonline = 1;
	active.exiting = 0;
	active.nbooting = 0;
	asminit();
	multiboot(ax, bx, 0);
	options(oargc, oargv);
	crapoptions();

	/*
	 * Need something for initial delays
	 * until a timebase is worked out.
	 */
	m->cpuhz = 2000000000ll;
	m->cpumhz = 2000;

	cgainit();
	i8250console("0");
	consputs = cgaconsputs;

	vsvminit(MACHSTKSZ, NIXTC);

	conf.nmach = 1;			

	fmtinit();
	print("\nNIX\n");
	if(vflag){
		print("&ax = %#p, ax = %#ux, bx = %#ux\n", &ax, ax, bx);
		multiboot(ax, bx, vflag);
	}

	m->perf.period = 1;
	if((hz = archhz()) != 0ll){
		m->cpuhz = hz;
		m->cyclefreq = hz;
		m->cpumhz = hz/1000000ll;
	}

	/*
	 * Mmuinit before meminit because it
	 * flushes the TLB via m->pml4->pa.
	 */
	mmuinit();

	ioinit();
	kbdinit();
	meminit();
	confinit();
	archinit();
	mallocinit();

	/*
	 * Acpiinit will cause the first malloc
	 * call to happen.
	 * If the system dies here it's probably due
	 * to malloc not being initialised
	 * correctly, or the data segment is misaligned
	 * (it's amazing how far you can get with
	 * things like that completely broken).
	 */
	acpiinit();
	
	umeminit();
	trapinit();
	printinit();

	/*
	 * This is necessary with GRUB and QEMU.
	 * Without it an interrupt can occur at a weird vector,
	 * because the vector base is likely different, causing
	 * havoc. Do it before any APIC initialisation.
	 */
	i8259init(32);


	procinit0();
	mpsinit(maxcores);
	apiconline();
	sipi();

	timersinit();
	kbdenable();
	fpuinit();
	psinit(conf.nproc);
	initimage();
	links();
	devtabreset();
	pageinit();
	swapinit();
	userinit();
	nixsquids();
testiccs();	
print("schedinit...\n");
	schedinit();
}
Exemple #5
0
/*
 * The CPU ends up here when its ready to run
 * This is called from code in mptramp.s; at this point, we are running
 * in the idle pcb/idle stack of the new cpu.  When this function returns,
 * this processor will enter the idle loop and start looking for work.
 *
 * XXX should share some of this with init386 in machdep.c
 */
void
cpu_hatch(void *v)
{
	struct cpu_info *ci = (struct cpu_info *)v;
	int s;

	cpu_init_msrs(ci);

#ifdef DEBUG
	if (ci->ci_flags & CPUF_PRESENT)
		panic("%s: already running!?", ci->ci_dev->dv_xname);
#endif

	ci->ci_flags |= CPUF_PRESENT;

	lapic_enable();
	lapic_startclock();

	if ((ci->ci_flags & CPUF_IDENTIFIED) == 0) {
		/*
		 * We need to wait until we can identify, otherwise dmesg
		 * output will be messy.
		 */
		while ((ci->ci_flags & CPUF_IDENTIFY) == 0)
			delay(10);

		identifycpu(ci);

		/* Signal we're done */
		atomic_clearbits_int(&ci->ci_flags, CPUF_IDENTIFY);
		/* Prevent identifycpu() from running again */
		atomic_setbits_int(&ci->ci_flags, CPUF_IDENTIFIED);
	}

	while ((ci->ci_flags & CPUF_GO) == 0)
		delay(10);
#ifdef DEBUG
	if (ci->ci_flags & CPUF_RUNNING)
		panic("%s: already running!?", ci->ci_dev->dv_xname);
#endif

	lcr0(ci->ci_idle_pcb->pcb_cr0);
	cpu_init_idt();
	lapic_set_lvt();
	gdt_init_cpu(ci);
	fpuinit(ci);

	lldt(0);

	cpu_init(ci);

	s = splhigh();
	lcr8(0);
	enable_intr();

	microuptime(&ci->ci_schedstate.spc_runtime);
	splx(s);

	SCHED_LOCK(s);
	cpu_switchto(NULL, sched_chooseproc());
}
Exemple #6
0
void
main(uint32_t mbmagic, uint32_t mbaddress)
{
	Mach *m = entrym;
	/* when we get here, entrym is set to core0 mach. */
	sys->machptr[m->machno] = m;
	// Very special case for BSP only. Too many things
	// assume this is set.
	wrmsr(GSbase, PTR2UINT(&sys->machptr[m->machno]));
	if (machp() != m)
		panic("m and machp() are different!!\n");
	assert(sizeof(Mach) <= PGSZ);

	/*
	 * Check that our data is on the right boundaries.
	 * This works because the immediate value is in code.
	 */
	if (x != 0x123456) 
		panic("Data is not set up correctly\n");
	memset(edata, 0, end - edata);

	m = (void *) (KZERO + 1048576 + 11*4096);
	sys = (void *) (KZERO + 1048576);

	/*
	 * ilock via i8250enable via i8250console
	 * needs m->machno, sys->machptr[] set, and
	 * also 'up' set to nil.
	 */
	cgapost(sizeof(uintptr_t)*8);
	memset(m, 0, sizeof(Mach));

	m->machno = 0;
	m->online = 1;
	m->nixtype = NIXTC;
	sys->machptr[m->machno] = &sys->mach;
	m->stack = PTR2UINT(sys->machstk);
	*(uintptr_t*)m->stack = STACKGUARD;
	m->vsvm = sys->vsvmpage;
	m->externup = (void *)0;
	active.nonline = 1;
	active.exiting = 0;
	active.nbooting = 0;

	asminit();
	multiboot(mbmagic, mbaddress, 0);
	options(oargc, oargv);

	/*
	 * Need something for initial delays
	 * until a timebase is worked out.
	 */
	m->cpuhz = 2000000000ll;
	m->cpumhz = 2000;

	cgainit();
	i8250console("0");
	
	consputs = cgaconsputs;

	/* It all ends here. */
	vsvminit(MACHSTKSZ, NIXTC, m);
	if (machp() != m)
		panic("After vsvminit, m and machp() are different");

	sys->nmach = 1;	
	
	fmtinit();
	print("\nHarvey\n");

	if(vflag){
		multiboot(mbmagic, mbaddress, vflag);
	}

	m->perf.period = 1;
	if((hz = archhz()) != 0ll){
		m->cpuhz = hz;
		m->cyclefreq = hz;
		m->cpumhz = hz/1000000ll;
	}
	//iprint("archhz returns 0x%lld\n", hz);
	//iprint("NOTE: if cpuidhz runs too fast, we get die early with a NULL pointer\n");
	//iprint("So, until that's fixed, we bring up AP cores slowly. Sorry!\n");

	/*
	 * Mmuinit before meminit because it
	 * flushes the TLB via m->pml4->pa.
	 */
	mmuinit();

	ioinit();
	meminit();
	confinit();
	archinit();
	mallocinit();

	/* test malloc. It's easier to find out it's broken here, 
	 * not deep in some call chain.
	 * See next note. 
	 *
	void *v = malloc(1234);
	hi("v "); put64((uint64_t)v); hi("\n");
	free(v);
	hi("free ok\n");
	 */

	/*
	 * Acpiinit will cause the first malloc
	 * call to happen.
	 * If the system dies here it's probably due
	 * to malloc not being initialised
	 * correctly, or the data segment is misaligned
	 * (it's amazing how far you can get with
	 * things like that completely broken).
	 */
if (0){	acpiinit(); hi("	acpiinit();\n");}
	
	umeminit();
	trapinit();

	/*
	 * This is necessary with GRUB and QEMU.
	 * Without it an interrupt can occur at a weird vector,
	 * because the vector base is likely different, causing
	 * havoc. Do it before any APIC initialisation.
	 */
	i8259init(32);


	procinit0();
	mpsinit(maxcores);
	apiconline();
	/* Forcing to single core if desired */
	if(!nosmp) {
		sipi();
	}
	teardownidmap(m);
	timersinit();
	fpuinit();
	psinit(conf.nproc);
	initimage();
	links();

	keybinit();
	keybenable();
	mouseenable();

	devtabreset();
	pageinit();
	swapinit();
	userinit();
	/* Forcing to single core if desired */
	if(!nosmp) {
		nixsquids();
		testiccs();
	}

	print("CPU Freq. %dMHz\n", m->cpumhz);

	print("schedinit...\n");
	schedinit();
}
Exemple #7
0
void
squidboy(int apicno, Mach *m)
{
	// FIX QEMU. extern int64_t hz;
	int64_t hz;
	sys->machptr[m->machno] = m;
	/*
	 * Need something for initial delays
	 * until a timebase is worked out.
	 */
	m->cpuhz = 2000000000ll;
	m->cpumhz = 2000;
	m->perf.period = 1;

	m->nixtype = NIXAC;
	// no NIXAC for now.
	m->nixtype = NIXTC;

	// NOTE: you can't do ANYTHING here before vsvminit.
	// PRINT WILL PANIC. So wait.
	vsvminit(MACHSTKSZ, m->nixtype, m);

	//DBG("Hello squidboy %d %d\n", apicno, m->machno);

	/*
	 * Beware the Curse of The Non-Interruptable Were-Temporary.
	 */
	hz = archhz();
	/* Intel cpu's in archk10 must be reviewed */
	if(hz == 0)
		hz = 2000000000ll;
	m->cpuhz = hz;
	m->cyclefreq = hz;
	m->cpumhz = hz/1000000ll;

	mmuinit();
	if(!apiconline())
		ndnr();
	fpuinit();

	acmodeset(m->nixtype);
	m->splpc = 0;
	m->online = 1;

	/*
	 * CAUTION: no time sync done, etc.
	 * Stupid print to avoid up = nil or
	 * last cpu couldn't start in nixquids.
	 */
	DBG("Wait for the thunderbirds!\n");
	while(!active.thunderbirdsarego)
		;
	wrmsr(0x10, sys->epoch);
	m->rdtsc = rdtsc();

	print("cpu%d color %d role %s tsc %lld\n",
		m->machno, corecolor(m->machno), rolename[m->nixtype], m->rdtsc);
	switch(m->nixtype){
	case NIXAC:
		acmmuswitch();
		acinit();
		adec(&active.nbooting);
		ainc(&active.nonline);	/* this was commented out */
		acsched();
		panic("squidboy");
		break;
	case NIXTC:
		/*
		 * We only need the idt and syscall entry point actually.
		 * At boot time the boot processor might set our role after
		 * we have decided to become an AC.
		 */
		vsvminit(MACHSTKSZ, NIXTC, m);

		/*
		 * Enable the timer interrupt.
		 */
		apictimerenab();
		apicpri(0);

		timersinit();
		adec(&active.nbooting);
		ainc(&active.nonline);

		/* Ready? steady? going to timer */
		ndnr();

		schedinit();
		break;
	}
	panic("squidboy returns (type %d)", m->nixtype);
}
Exemple #8
0
void
main(void)
{
	int machno;

	/* entry to main pushed stuff onto the stack. */

//	memset(edata, 0, (ulong)end-(ulong)edata);

	machno = getpir();
	if (machno > 0)
		startcpu(machno);

//	dcrcompile();
	if (dverify != 0x01020304) {
		uartlputs("data segment not initialised\n");
		panic("data segment not initialised");
	}
	if (bverify != 0) {
		uartlputs("bss segment not zeroed\n");
		panic("bss segment not zeroed");
	}
	mach0init();
	archreset();
	quotefmtinstall();
	optionsinit("/boot/boot boot");
//	archconsole();

	meminit();
	confinit();
	mmuinit();
	xinit();			/* xinit would print if it could */
	trapinit();
	qtminit();
	ioinit();
	uncinit();
	printinit();
	uartliteconsole();

	mainmem->flags |= POOL_ANTAGONISM;
	mainmem->panic = mypanic;
	ethermedium.maxtu = 1512;   /* must be multiple of 4 for temac's dma */

//	print("\n\nPlan 9k H\n");	/* already printed by l.s */
	plan9iniinit();
	timersinit();
	clockinit();

	dma0init();			/* does not start kprocs; see init0 */
	fpuinit();
	procinit0();
	initseg();
	links();

	chandevreset();
	okprint = 1;			/* only now can we print */
	barriers();
	dcflush((uintptr)&okprint, sizeof okprint);

	cpuidprint();

	print("%d Hz clock", HZ);
	print("; memory size %,ud (%#ux)\n", (uint)memsz, (uint)memsz);

	pageinit();
	swapinit();
	userinit();
	active.thunderbirdsarego = 1;
	dcflush((uintptr)&active.thunderbirdsarego,
		sizeof active.thunderbirdsarego);
	schedinit();
	/* no return */
	panic("schedinit returned");
}