Bug 16021

Summary: [i386] [patch] To support SMP on NEC PC98, call mp_probe() after pmap_bootstrap()
Product: Base System Reporter: hnokubi <hnokubi>
Component: kernAssignee: Warner Losh <imp>
Status: Closed FIXED    
Severity: Affects Only Me    
Priority: Normal    
Version: 4.0-CURRENT   
Hardware: Any   
OS: Any   
Attachments:
Description Flags
file.diff none

Description hnokubi 2000-01-10 08:30:01 UTC
MP Configuration Table is placed at the top of the physical memory on
NEC PC98. It's one of the suggested areas for MPCT in Intel's MP Spec V1.4.
(NEC PC98 uses Intel x86 processor, but not PC-AT compatible architecture.)

Because FreeBSD's SMP code assumes that MPCT is in lowest 1Mbyte area, it
can't read MPCT on NEC PC98.

Fix: This patch is same as it I've already posted to freebsd-smp
(Message-Id: <19991225153517.9109915206@hub.freebsd.org>).

It so defers calling mp_probe() after pmap_bootstrap() that mp_probe()
uses pmap_enter() to read MPCT. If MPCT is above lowest 1Mbyte area,
map a page which includes MPCT to CADDR1 and read from there.

Latter half of pmap_bootstrap() is moved to mptable_pass1() except pgeflag.
PTE Global bit is not used on SMP kernel, it's not needed just now (need
to consider in the future release ?).

It also adds a entry NEC98 bus to bus_type table[]. NEC98 bus is similar
to ISA.
Comment 1 NOKUBI Hirotaka 2000-04-15 09:15:06 UTC
Would someone commit this? I'll attach a patch for newer revision files.
If there is problem, suspicion or suggestion, tell me about it.
I'll seek solution.

Thanks.
----
NOKUBI Hirotaka
Fingerprint20 = DEBC 0793 7CD6 92F1 0A1F  A792 9E2F EEEE A41B 171D

Index: i386/i386/machdep.c
===================================================================
RCS file: /home/ncvs/src/sys/i386/i386/machdep.c,v
retrieving revision 1.388
diff -u -u -r1.388 machdep.c
--- machdep.c	2000/03/30 07:16:59	1.388
+++ machdep.c	2000/04/15 07:37:01
@@ -1599,9 +1599,6 @@
 #ifdef SMP
 	/* make hole for AP bootstrap code */
 	physmap[1] = mp_bootaddress(physmap[1] / 1024);
-
-	/* look for the MP hardware - needed for apic addresses */
-	mp_probe();
 #endif
 
 	/*
@@ -1662,6 +1659,11 @@
 
 	/* call pmap initialization to make new kernel address space */
 	pmap_bootstrap(first, 0);
+
+#ifdef SMP
+	/* look for the MP hardware - needed for apic addresses */
+	mp_probe();
+#endif
 
 	/*
 	 * Size up each available chunk of physical memory.
Index: i386/i386/mp_machdep.c
===================================================================
RCS file: /home/ncvs/src/sys/i386/i386/mp_machdep.c,v
retrieving revision 1.116
diff -u -u -r1.116 mp_machdep.c
--- mp_machdep.c	2000/03/28 07:16:15	1.116
+++ mp_machdep.c	2000/04/15 07:37:01
@@ -392,7 +392,7 @@
 
 found:
 	/* calculate needed resources */
-	mpfps = (mpfps_t)x;
+	mpfps = (mpfps_t)(x + KERNBASE);
 	if (mptable_pass1())
 		panic("you must reconfigure your kernel");
 
@@ -691,12 +691,12 @@
 	{MCA, "MCA"},
 	{UNKNOWN_BUSTYPE, "---"},
 	{ISA, "ISA"},
+	{ISA, "NEC98"},
 	{MCA, "MCA"},
 	{UNKNOWN_BUSTYPE, "---"},
 	{UNKNOWN_BUSTYPE, "---"},
 	{UNKNOWN_BUSTYPE, "---"},
 	{UNKNOWN_BUSTYPE, "---"},
-	{UNKNOWN_BUSTYPE, "---"},
 	{PCI, "PCI"},
 	{UNKNOWN_BUSTYPE, "---"},
 	{UNKNOWN_BUSTYPE, "---"},
@@ -758,6 +758,8 @@
 	int	count;
 	int	type;
 	int	mustpanic;
+	int i, j;
+	struct globaldata *gd;
 
 	POSTCODE(MPTABLE_PASS1_POST);
 
@@ -792,6 +794,15 @@
 		if ((cth = mpfps->pap) == 0)
 			panic("MP Configuration Table Header MISSING!");
 
+		if (cth >= (mpcth_t)0x100000) {
+			pmap_enter(kernel_pmap, (vm_offset_t)CADDR1,
+				   trunc_page((vm_offset_t)cth), VM_PROT_READ, TRUE);
+			/* XXX do not support MPCT across page boundary */
+			cth = (mpcth_t)(CADDR1 + ((int)cth & PAGE_MASK));
+		} else {
+			cth = (mpcth_t)((u_int)cth + KERNBASE);
+		}
+
 		cpu_apic_address = (vm_offset_t) cth->apic_address;
 
 		/* walk the table, recording info of interest */
@@ -858,6 +869,46 @@
 
 	--mp_naps;	/* subtract the BSP */
 
+	if (cpu_apic_address == 0)
+		panic("pmap_bootstrap: no local apic!");
+
+	/* local apic is mapped on last page */
+	SMPpt[NPTEPG - 1] = (pt_entry_t)(PG_V | PG_RW | PG_N | /*pgeflag |*/
+	    (cpu_apic_address & PG_FRAME));
+
+	for (i = 0; i < mp_napics; i++) {
+		for (j = 0; j < mp_napics; j++) {
+			/* same page frame as a previous IO apic? */
+			if (((vm_offset_t)SMPpt[NPTEPG-2-j] & PG_FRAME) ==
+			    (io_apic_address[0] & PG_FRAME)) {
+				ioapic[i] = (ioapic_t *)((u_int)SMP_prvspace
+					+ (NPTEPG-2-j)*PAGE_SIZE);
+				break;
+			}
+			/* use this slot if available */
+			if (((vm_offset_t)SMPpt[NPTEPG-2-j] & PG_FRAME) == 0) {
+				SMPpt[NPTEPG-2-j] = (pt_entry_t)(PG_V | PG_RW |
+				/*pgeflag |*/ (io_apic_address[i] & PG_FRAME));
+				ioapic[i] = (ioapic_t *)((u_int)SMP_prvspace
+					+ (NPTEPG-2-j)*PAGE_SIZE);
+				break;
+			}
+		}
+	}
+
+	/* BSP does this itself, AP's get it pre-set */
+	gd = &SMP_prvspace[0].globaldata;
+	gd->gd_prv_CMAP1 = &SMPpt[1];
+	gd->gd_prv_CMAP2 = &SMPpt[2];
+	gd->gd_prv_CMAP3 = &SMPpt[3];
+	gd->gd_prv_PMAP1 = &SMPpt[4];
+	gd->gd_prv_CADDR1 = SMP_prvspace[0].CPAGE1;
+	gd->gd_prv_CADDR2 = SMP_prvspace[0].CPAGE2;
+	gd->gd_prv_CADDR3 = SMP_prvspace[0].CPAGE3;
+	gd->gd_prv_PADDR1 = (unsigned *)SMP_prvspace[0].PPAGE1;
+
+	invltlb();
+
 	return mustpanic;
 }
 
@@ -915,6 +966,15 @@
 
 	if ((cth = mpfps->pap) == 0)
 		panic("MP Configuration Table Header MISSING!");
+
+	if (cth >= (mpcth_t)0x100000) {
+		pmap_enter(kernel_pmap, (vm_offset_t)CADDR1,
+			   trunc_page((vm_offset_t)cth), VM_PROT_READ, TRUE);
+		/* XXX do not support MPCT across page boundary */
+		cth = (mpcth_t)(CADDR1 + ((int)cth & PAGE_MASK));
+	} else {
+		cth = (mpcth_t)((u_int)cth + KERNBASE);
+	}
 
 	/* walk the table, recording info of interest */
 	totalSize = cth->base_table_length - sizeof(struct MPCTH);
Index: i386/i386/pmap.c
===================================================================
RCS file: /home/ncvs/src/sys/i386/i386/pmap.c,v
retrieving revision 1.252
diff -u -u -r1.252 pmap.c
--- pmap.c	2000/03/16 08:51:49	1.252
+++ pmap.c	2000/04/15 07:37:02
@@ -283,10 +283,6 @@
 {
 	vm_offset_t va;
 	pt_entry_t *pte;
-#ifdef SMP
-	int i, j;
-	struct globaldata *gd;
-#endif
 
 	avail_start = firstaddr;
 
@@ -412,46 +408,6 @@
 		invltlb();
 #endif
 	}
-#endif
-
-#ifdef SMP
-	if (cpu_apic_address == 0)
-		panic("pmap_bootstrap: no local apic!");
-
-	/* local apic is mapped on last page */
-	SMPpt[NPTEPG - 1] = (pt_entry_t)(PG_V | PG_RW | PG_N | pgeflag |
-	    (cpu_apic_address & PG_FRAME));
-
-	for (i = 0; i < mp_napics; i++) {
-		for (j = 0; j < mp_napics; j++) {
-			/* same page frame as a previous IO apic? */
-			if (((vm_offset_t)SMPpt[NPTEPG-2-j] & PG_FRAME) ==
-			    (io_apic_address[0] & PG_FRAME)) {
-				ioapic[i] = (ioapic_t *)((u_int)SMP_prvspace
-					+ (NPTEPG-2-j)*PAGE_SIZE);
-				break;
-			}
-			/* use this slot if available */
-			if (((vm_offset_t)SMPpt[NPTEPG-2-j] & PG_FRAME) == 0) {
-				SMPpt[NPTEPG-2-j] = (pt_entry_t)(PG_V | PG_RW |
-				    pgeflag | (io_apic_address[i] & PG_FRAME));
-				ioapic[i] = (ioapic_t *)((u_int)SMP_prvspace
-					+ (NPTEPG-2-j)*PAGE_SIZE);
-				break;
-			}
-		}
-	}
-
-	/* BSP does this itself, AP's get it pre-set */
-	gd = &SMP_prvspace[0].globaldata;
-	gd->gd_prv_CMAP1 = &SMPpt[1];
-	gd->gd_prv_CMAP2 = &SMPpt[2];
-	gd->gd_prv_CMAP3 = &SMPpt[3];
-	gd->gd_prv_PMAP1 = &SMPpt[4];
-	gd->gd_prv_CADDR1 = SMP_prvspace[0].CPAGE1;
-	gd->gd_prv_CADDR2 = SMP_prvspace[0].CPAGE2;
-	gd->gd_prv_CADDR3 = SMP_prvspace[0].CPAGE3;
-	gd->gd_prv_PADDR1 = (unsigned *)SMP_prvspace[0].PPAGE1;
 #endif
 
 	invltlb();
Index: i386/include/smp.h
===================================================================
RCS file: /home/ncvs/src/sys/i386/include/smp.h,v
retrieving revision 1.51
diff -u -u -r1.51 smp.h
--- smp.h	2000/03/28 18:06:38	1.51
+++ smp.h	2000/04/15 07:37:03
@@ -34,6 +34,7 @@
 
 #ifndef LOCORE
 
+#ifndef	PC98
 /*
  * For sending values to POST displays.
  * XXX FIXME: where does this really belong, isa.h/isa.c perhaps?
@@ -47,7 +48,11 @@
 #define POSTCODE_HI(X)	current_postcode &= 0x0f, \
 			current_postcode |= (((X) << 4) & 0xf0), \
 			outb(0x80, current_postcode)
-
+#else
+#define POSTCODE(X)
+#define POSTCODE_LO(X)
+#define POSTCODE_HI(X)
+#endif
 
 #include <machine/apic.h>
 
Index: pc98/i386/machdep.c
===================================================================
RCS file: /home/ncvs/src/sys/pc98/i386/machdep.c,v
retrieving revision 1.155
diff -u -u -r1.155 machdep.c
--- machdep.c	2000/03/30 07:17:05	1.155
+++ machdep.c	2000/04/15 07:37:20
@@ -1475,14 +1475,14 @@
 	}
 #endif
 
+	/* call pmap initialization to make new kernel address space */
+	pmap_bootstrap (first, 0);
+
 #ifdef SMP
 	/* look for the MP hardware - needed for apic addresses */
 	mp_probe();
 #endif
 
-	/* call pmap initialization to make new kernel address space */
-	pmap_bootstrap (first, 0);
-
 	/*
 	 * Size up each available chunk of physical memory.
 	 */
Comment 2 K. Macy freebsd_committer freebsd_triage 2007-11-16 08:38:56 UTC
State Changed
From-To: open->feedback


Is pc98 still UP-only?
Comment 3 K. Macy freebsd_committer freebsd_triage 2007-11-16 08:53:50 UTC
Responsible Changed
From-To: freebsd-bugs->imp


Give to imp to close or forward.
Comment 4 Warner Losh freebsd_committer freebsd_triage 2009-04-13 15:59:58 UTC
State Changed
From-To: feedback->closed

Has been in feedback state for 2 years.