PERFORCE change 38934 for review

Peter Wemm peter at FreeBSD.org
Tue Sep 30 17:33:34 PDT 2003


http://perforce.freebsd.org/chv.cgi?CH=38934

Change 38934 by peter at peter_hammer on 2003/09/30 17:33:20

	cleanups.  use pcpu[] and common_tss[] instead of the evil vile
	horrid ugly overcomplicated obsolete *unnecessary* code to do it via
	page table tricks etc.
	move some initialization code from init_secondary() to start_ap()
	and friends.  let the AP cpus start up with their state as complete
	as possible.

Affected files ...

.. //depot/projects/hammer/sys/amd64/amd64/machdep.c#56 edit
.. //depot/projects/hammer/sys/amd64/amd64/mp_machdep.c#12 edit
.. //depot/projects/hammer/sys/amd64/include/md_var.h#16 edit
.. //depot/projects/hammer/sys/amd64/include/tss.h#6 edit

Differences ...

==== //depot/projects/hammer/sys/amd64/amd64/machdep.c#56 (text+ko) ====

@@ -147,7 +147,8 @@
 struct kva_md_info kmi;
 
 static struct trapframe proc0_tf;
-static struct pcpu __pcpu;	/* BSP pcpu data space */
+
+struct pcpu __pcpu[MAXCPU];
 
 struct mtx icu_lock;
 
@@ -588,7 +589,7 @@
 
 static char dblfault_stack[PAGE_SIZE] __aligned(16);
 
-struct amd64tss common_tss;
+struct amd64tss common_tss[MAXCPU];
 
 /* software prototypes -- in more palatable form */
 struct soft_segment_descriptor gdt_segs[] = {
@@ -1145,7 +1146,7 @@
 	/*
 	 * make gdt memory segments
 	 */
-	gdt_segs[GPROC0_SEL].ssd_base = (uintptr_t)&common_tss;
+	gdt_segs[GPROC0_SEL].ssd_base = (uintptr_t)&common_tss[0];
 
 	for (x = 0; x < NGDT; x++) {
 		if (x != GPROC0_SEL && x != (GPROC0_SEL + 1))
@@ -1156,7 +1157,7 @@
 	r_gdt.rd_limit = NGDT * sizeof(gdt[0]) - 1;
 	r_gdt.rd_base =  (long) gdt;
 	lgdt(&r_gdt);
-	pc = &__pcpu;
+	pc = &__pcpu[0];
 
 	wrmsr(MSR_FSBASE, 0);		/* User value */
 	wrmsr(MSR_GSBASE, (u_int64_t)pc);
@@ -1224,12 +1225,13 @@
 	initializecpu();	/* Initialize CPU registers */
 
 	/* make an initial tss so cpu can get interrupt stack on syscall! */
-	common_tss.tss_rsp0 = thread0.td_kstack + KSTACK_PAGES * PAGE_SIZE - sizeof(struct pcb);
+	common_tss[0].tss_rsp0 = thread0.td_kstack + \
+	    KSTACK_PAGES * PAGE_SIZE - sizeof(struct pcb);
 	/* Ensure the stack is aligned to 16 bytes */
-	common_tss.tss_rsp0 &= ~0xF;
+	common_tss[0].tss_rsp0 &= ~0xF;
 
 	/* doublefault stack space, runs on ist1 */
-	common_tss.tss_ist1 = (long)&dblfault_stack[sizeof(dblfault_stack)];
+	common_tss[0].tss_ist1 = (long)&dblfault_stack[sizeof(dblfault_stack)];
 
 	gsel_tss = GSEL(GPROC0_SEL, SEL_KPL);
 	ltr(gsel_tss);

==== //depot/projects/hammer/sys/amd64/amd64/mp_machdep.c#12 (text+ko) ====

@@ -65,6 +65,7 @@
 #include <machine/pcb.h>
 #include <machine/smp.h>
 #include <machine/specialreg.h>
+#include <machine/tss.h>
 
 #define WARMBOOT_TARGET		0
 #define WARMBOOT_OFF		(KERNBASE + 0x0467)
@@ -322,38 +323,25 @@
 void
 init_secondary(void)
 {
-#ifdef SMP_ME_HARDER
 	int	gsel_tss;
-	int	x, myid = bootAP;
-	u_int	cr0;
-	u_int32	value;
+	int	myid = bootAP;
+	u_int64_t cr0;
+	struct pcpu *pc;
 
-	gdt_segs[GPRIV_SEL].ssd_base = (long) &SMP_prvspace[myid];
-	gdt_segs[GPROC0_SEL].ssd_base =
-		(long) &SMP_prvspace[myid].pcpu.pc_common_tss;
-	SMP_prvspace[myid].pcpu.pc_prvspace =
-		&SMP_prvspace[myid].pcpu;
+	lgdt(&r_gdt);			/* does magic intra-segment return */
 
-	for (x = 0; x < NGDT; x++) {
-		ssdtosd(&gdt_segs[x], &gdt[myid * NGDT + x].sd);
-	}
+	pc = &__pcpu[myid];
 
-	r_gdt.rd_limit = NGDT * sizeof(gdt[0]) - 1;
-	r_gdt.rd_base = (long) &gdt[myid * NGDT];
-	lgdt(&r_gdt);			/* does magic intra-segment return */
+	wrmsr(MSR_FSBASE, 0);		/* User value */
+	wrmsr(MSR_GSBASE, (u_int64_t)pc);
+	wrmsr(MSR_KGSBASE, 0);		/* User value while we're in the kernel */
 
 	lidt(&r_idt);
 
-	lldt(_default_ldt);
-	PCPU_SET(currentldt, _default_ldt);
+	common_tss[myid] = common_tss[0];
+	common_tss[myid].tss_rsp0 = 0;	/* not used until after switch */
 
 	gsel_tss = GSEL(GPROC0_SEL, SEL_KPL);
-	gdt[myid * NGDT + GPROC0_SEL].sd.sd_type = SDT_SYSTSS;
-	PCPU_SET(common_tss.tss_esp0, 0); /* not used until after switch */
-	PCPU_SET(common_tss.tss_ss0, GSEL(GDATA_SEL, SEL_KPL));
-	PCPU_SET(common_tss.tss_ioopt, (sizeof (struct i386tss)) << 16);
-	PCPU_SET(tss_gdt, &gdt[myid * NGDT + GPROC0_SEL].sd);
-	PCPU_SET(common_tssd, *PCPU_GET(tss_gdt));
 	ltr(gsel_tss);
 
 	/*
@@ -366,14 +354,11 @@
 	load_cr0(cr0);
 
 	/* Disable local apic just to be sure. */
-	value = lapic->svr;
-	value &= ~(APIC_SVR_SWEN);
-	lapic->svr = value;
+	lapic_disable();
 
 	mp_naps++;
 
 	ap_init();	/* kick things off, this does not return */
-#endif
 }
 
 /*******************************************************************
@@ -442,12 +427,24 @@
 			continue;
 		cpu++;
 
-		/* allocate a new private data page */
-		pc = (struct pcpu *)kmem_alloc(kernel_map, PAGE_SIZE);
+		/* Get per-cpu data */
+		pc = &__pcpu[myid];
 
 		/* allocate and set up an idle stack data page */
 		stack = (char *)kmem_alloc(kernel_map, KSTACK_PAGES * PAGE_SIZE);
 
+		gdt_segs[GPROC0_SEL].ssd_base =
+			(long) &SMP_prvspace[myid].pcpu.pc_common_tss;
+		pc->pc_prvspace = pc;
+
+	for (x = 0; x < NGDT; x++)
+		if (x != GPROC0_SEL && x != (GPROC0_SEL + 1))
+			ssdtosd(&gdt_segs[x], &gdt[myid * NGDT + x].sd);
+	ssdtosyssd(&gdt_segs[GPROC0_SEL], (struct system_segment_descriptor *)&gdt[GPROC0_SEL]);
+
+	r_gdt.rd_limit = NGDT * sizeof(gdt[0]) - 1;
+	r_gdt.rd_base = (long) &gdt[myid * NGDT];
+
 		/* prime data page for it to use */
 		pcpu_init(pc, cpu, sizeof(struct pcpu));
 		pc->pc_apic_id = apic_id;

==== //depot/projects/hammer/sys/amd64/include/md_var.h#16 (text+ko) ====

@@ -52,6 +52,8 @@
 extern	char	sigcode[];
 extern	int	szsigcode;
 
+extern	struct pcpu __pcpu[];
+
 typedef void alias_for_inthand_t(u_int cs, u_int ef, u_int esp, u_int ss);
 struct	thread;
 struct	reg;

==== //depot/projects/hammer/sys/amd64/include/tss.h#6 (text+ko) ====

@@ -69,7 +69,7 @@
 };
 
 #ifdef _KERNEL
-extern struct amd64tss common_tss;
+extern struct amd64tss common_tss[];
 #endif
 
 #endif /* _MACHINE_TSS_H_ */


More information about the p4-projects mailing list