⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 mp.c

📁 著名操作系统Plan 9的第三版的部分核心源代码。现在很难找到了。Plan 9是bell实验室开发的Unix后继者。
💻 C
📖 第 1 页 / 共 2 页
字号:
#include "u.h"#include "../port/lib.h"#include "mem.h"#include "dat.h"#include "fns.h"#include "io.h"#include "ureg.h"#include "mp.h"#include "apbootstrap.h"static Bus* mpbus;static Bus* mpbuslast;static int mpisabus = -1;static int mpeisabus = -1;extern int i8259elcr;			/* mask of level-triggered interrupts */static Apic mpapic[MaxAPICNO+1];static int machno2apicno[MaxAPICNO+1];	/* inverse map: machno -> APIC ID */static Lock mprdthilock;static int mprdthi;static Ref mpvnoref;			/* unique vector assignment */static Lock mpclocksynclock;static char* buses[] = {	"CBUSI ",	"CBUSII",	"EISA  ",	"FUTURE",	"INTERN",	"ISA   ",	"MBI   ",	"MBII  ",	"MCA   ",	"MPI   ",	"MPSA  ",	"NUBUS ",	"PCI   ",	"PCMCIA",	"TC    ",	"VL    ",	"VME   ",	"XPRESS",	0,};static Apic*mkprocessor(PCMPprocessor* p){	Apic *apic;	if(!(p->flags & PcmpEN) || p->apicno > MaxAPICNO)		return 0;	apic = &mpapic[p->apicno];	apic->type = PcmpPROCESSOR;	apic->apicno = p->apicno;	apic->flags = p->flags;	apic->lintr[0] = ApicIMASK;	apic->lintr[1] = ApicIMASK;	if(p->flags & PcmpBP){		machno2apicno[0] = p->apicno;		apic->machno = 0;	}	else{		machno2apicno[conf.nmach] = p->apicno;		apic->machno = conf.nmach;		conf.nmach++;	}	return apic;}static Bus*mkbus(PCMPbus* p){	Bus *bus;	int i;	for(i = 0; buses[i]; i++){		if(strncmp(buses[i], p->string, sizeof(p->string)) == 0)			break;	}	if(buses[i] == 0)		return 0;	bus = xalloc(sizeof(Bus));	if(mpbus)		mpbuslast->next = bus;	else		mpbus = bus;	mpbuslast = bus;	bus->type = i;	bus->busno = p->busno;	if(bus->type == BusEISA){		bus->po = PcmpLOW;		bus->el = PcmpLEVEL;		if(mpeisabus != -1)			print("mkbus: more than one EISA bus\n");		mpeisabus = bus->busno;	}	else if(bus->type == BusPCI){		bus->po = PcmpLOW;		bus->el = PcmpLEVEL;	}	else if(bus->type == BusISA){		bus->po = PcmpHIGH;		bus->el = PcmpEDGE;		if(mpisabus != -1)			print("mkbus: more than one ISA bus\n");		mpisabus = bus->busno;	}	else{		bus->po = PcmpHIGH;		bus->el = PcmpEDGE;	}	return bus;}static Bus*mpgetbus(int busno){	Bus *bus;	for(bus = mpbus; bus; bus = bus->next){		if(bus->busno == busno)			return bus;	}	print("mpgetbus: can't find bus %d\n", busno);	return 0;}static Apic*mkioapic(PCMPioapic* p){	Apic *apic;	if(!(p->flags & PcmpEN) || p->apicno > MaxAPICNO)		return 0;	/*	 * Map the I/O APIC.	 */	if(mmukmap(p->addr, 0, 1024) == 0)		return 0;	apic = &mpapic[p->apicno];	apic->type = PcmpIOAPIC;	apic->apicno = p->apicno;	apic->addr = KADDR(p->addr);	apic->flags = p->flags;	return apic;}static Aintr*mkiointr(PCMPintr* p){	Bus *bus;	Aintr *aintr;	/*	 * According to the MultiProcessor Specification, a destination	 * I/O APIC of 0xFF means the signal is routed to all I/O APICs.	 * It's unclear how that can possibly be correct so treat it as	 * an error for now.	 */	if(p->apicno == 0xFF)		return 0;	if((bus = mpgetbus(p->busno)) == 0)		return 0;	aintr = xalloc(sizeof(Aintr));	aintr->intr = p;	aintr->apic = &mpapic[p->apicno];	aintr->next = bus->aintr;	bus->aintr = aintr;	return aintr;}static intmpintrinit(Bus* bus, PCMPintr* intr, int vno, int /*irq*/){	int el, po, v;	/*	 * Parse an I/O or Local APIC interrupt table entry and	 * return the encoded vector.	 */	v = vno;	po = intr->flags & PcmpPOMASK;	el = intr->flags & PcmpELMASK;	switch(intr->intr){	default:				/* PcmpINT */		v |= ApicLOWEST;		break;	case PcmpNMI:		v |= ApicNMI;		po = PcmpHIGH;		el = PcmpEDGE;		break;	case PcmpSMI:		v |= ApicSMI;		break;	case PcmpExtINT:		v |= ApicExtINT;		/*		 * The AMI Goliath doesn't boot successfully with it's LINTR0		 * entry which decodes to low+level. The PPro manual says ExtINT		 * should be level, whereas the Pentium is edge. Setting the		 * Goliath to edge+high seems to cure the problem. Other PPro		 * MP tables (e.g. ASUS P/I-P65UP5 have a entry which decodes		 * to edge+high, so who knows.		 * Perhaps it would be best just to not set an ExtINT entry at		 * all, it shouldn't be needed for SMP mode.		 */		po = PcmpHIGH;		el = PcmpEDGE;		break;	}	/*	 */	if(bus->type == BusEISA && !po && !el /*&& !(i8259elcr & (1<<irq))*/){		po = PcmpHIGH;		el = PcmpEDGE;	}	if(!po)		po = bus->po;	if(po == PcmpLOW)		v |= ApicLOW;	else if(po != PcmpHIGH){		print("mpintrinit: bad polarity 0x%uX\n", po);		return ApicIMASK;	}	if(!el)		el = bus->el;	if(el == PcmpLEVEL)		v |= ApicLEVEL;	else if(el != PcmpEDGE){		print("mpintrinit: bad trigger 0x%uX\n", el);		return ApicIMASK;	}	return v;}static intmklintr(PCMPintr* p){	Apic *apic;	Bus *bus;	int intin, v;	/*	 * The offsets of vectors for LINT[01] are known to be	 * 0 and 1 from the local APIC vector space at VectorLAPIC.	 */	if((bus = mpgetbus(p->busno)) == 0)		return 0;	intin = p->intin;	/*	 * Pentium Pros have problems if LINT[01] are set to ExtINT	 * so just bag it, SMP mode shouldn't need ExtINT anyway.	 */	if(p->intr == PcmpExtINT || p->intr == PcmpNMI)		v = ApicIMASK;	else		v = mpintrinit(bus, p, VectorLAPIC+intin, p->irq);	if(p->apicno == 0xFF){		for(apic = mpapic; apic <= &mpapic[MaxAPICNO]; apic++){			if((apic->flags & PcmpEN)			&& apic->type == PcmpPROCESSOR)				apic->lintr[intin] = v;		}	}	else{		apic = &mpapic[p->apicno];		if((apic->flags & PcmpEN) && apic->type == PcmpPROCESSOR)			apic->lintr[intin] = v;	}	return v;}static voidcheckmtrr(void){	int i, vcnt;	Mach *mach0;	/*	 * If there are MTRR registers, snarf them for validation.	 */	if(!(m->cpuiddx & 0x1000))		return;	rdmsr(0x0FE, &m->mtrrcap);	rdmsr(0x2FF, &m->mtrrdef);	if(m->mtrrcap & 0x0100){		rdmsr(0x250, &m->mtrrfix[0]);		rdmsr(0x258, &m->mtrrfix[1]);		rdmsr(0x259, &m->mtrrfix[2]);		for(i = 0; i < 8; i++)			rdmsr(0x268+i, &m->mtrrfix[(i+3)]);	}	vcnt = m->mtrrcap & 0x00FF;	if(vcnt > nelem(m->mtrrvar))		vcnt = nelem(m->mtrrvar);	for(i = 0; i < vcnt; i++)		rdmsr(0x200+i, &m->mtrrvar[i]);	/*	 * If not the bootstrap processor, compare.	 */	if(m->machno == 0)		return;	mach0 = MACHP(0);	if(mach0->mtrrcap != m->mtrrcap)		print("mtrrcap%d: %lluX %lluX\n",			m->machno, mach0->mtrrcap, m->mtrrcap);	if(mach0->mtrrdef != m->mtrrdef)		print("mtrrdef%d: %lluX %lluX\n",			m->machno, mach0->mtrrdef, m->mtrrdef);	for(i = 0; i < 11; i++){		if(mach0->mtrrfix[i] != m->mtrrfix[i])			print("mtrrfix%d: i%d: %lluX %lluX\n",				m->machno, i, mach0->mtrrfix[i], m->mtrrfix[i]);	}	for(i = 0; i < vcnt; i++){		if(mach0->mtrrvar[i] != m->mtrrvar[i])			print("mtrrvar%d: i%d: %lluX %lluX\n",				m->machno, i, mach0->mtrrvar[i], m->mtrrvar[i]);	}}#define PDX(va)		((((ulong)(va))>>22) & 0x03FF)#define PTX(va)		((((ulong)(va))>>12) & 0x03FF)static voidsquidboy(Apic* apic){	ulong x;//	iprint("Hello Squidboy\n");	machinit();	mmuinit();	cpuidentify();	cpuidprint();	checkmtrr();	lock(&mprdthilock);	mprdthi |= (1<<apic->apicno)<<24;	unlock(&mprdthilock);	/*	 * Restrain your octopus! Don't let it go out on the sea!	 */	ilock(&mpclocksynclock);	x = MACHP(0)->ticks;	while(MACHP(0)->ticks == x)		;	wrmsr(0x10, MACHP(0)->fastclock); /* synchronize fast counters */	iunlock(&mpclocksynclock);	lapicinit(apic);	lapiconline();	lock(&active);	active.machs |= 1<<m->machno;	unlock(&active);	schedinit();}static voidmpstartap(Apic* apic)

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -