shithub: riscv

Download patch

ref: 8e1fbbeda59186f50449ae31212632b00b328af6
parent: d80cf1a4baaedf1db985d7da357d0a5b20597099
author: aiju <[email protected]>
date: Sun May 15 22:18:29 EDT 2011

added APIC ID remapping

--- a/sys/src/9/pc/mp.c
+++ b/sys/src/9/pc/mp.c
@@ -17,6 +17,7 @@
 extern int i8259elcr;			/* mask of level-triggered interrupts */
 static Apic mpapic[MaxAPICNO+1];
 static int machno2apicno[MaxAPICNO+1];	/* inverse map: machno -> APIC ID */
+static int mpapicremap[MaxAPICNO+1];
 static int mpmachno = 1;
 static Lock mpphysidlock;
 static int mpphysid;
@@ -135,11 +136,22 @@
 	return 0;
 }
 
+static int
+freeapicid(void)
+{
+	int i;
+	
+	for(i = 0; i < MaxAPICNO+1; i++)
+		if(mpapic[i].flags == 0)
+			return i;
+	return -1;
+}
+
 static Apic*
 mkioapic(PCMPioapic* p)
 {
 	void *va;
-	int apicno;
+	int apicno, new;
 	Apic *apic;
 
 	apicno = p->apicno;
@@ -153,8 +165,18 @@
 		return 0;
 
 	apic = &mpapic[apicno];
-	if(apic->flags != 0)
-		print("mkioapic: APIC ID conflict at %d\n", p->apicno);
+	if(apic->flags != 0) {
+		new = freeapicid();
+		if(new < 0)
+			print("mkioapic: out of APIC IDs\n");
+		else {
+			mpapicremap[p->apicno] = new;
+			print("mkioapic: APIC ID conflict at %d, remapping to %d\n", p->apicno, new);
+			p->apicno = apicno = new;
+			apic = &mpapic[apicno];
+		}
+	} else
+		mpapicremap[p->apicno] = p->apicno;
 	apic->type = PcmpIOAPIC;
 	apic->apicno = apicno;
 	apic->addr = va;
@@ -177,8 +199,14 @@
 	 * It's unclear how that can possibly be correct so treat it as
 	 * an error for now.
 	 */
-	if(p->apicno == 0xFF)
+	if(p->apicno > MaxAPICNO)
 		return 0;
+	
+	if(mpapicremap[p->apicno] < 0) {
+		print("iointr: non-existing IOAPIC %d\n", p->apicno);
+		return 0;
+	}
+	p->apicno = mpapicremap[p->apicno];
 	if((bus = mpgetbus(p->busno)) == 0)
 		return 0;
 
@@ -528,7 +556,7 @@
 void
 mpinit(void)
 {
-	int ncpu;
+	int ncpu, i;
 	char *cp;
 	PCMP *pcmp;
 	uchar *e, *p;
@@ -551,6 +579,9 @@
 	print("LAPIC: %.8lux %.8lux\n", pcmp->lapicbase, (ulong)va);
 
 	bpapic = nil;
+	
+	for(i = 0; i <= MaxAPICNO; i++)
+		mpapicremap[i] = -1;
 
 	/*
 	 * Run through the table saving information needed for starting