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