Date: Wed, 01 Oct 2003 00:33:34 -0000 From: Peter Wemm <peter@FreeBSD.org> To: Perforce Change Reviews <perforce@freebsd.org> Subject: PERFORCE change 38934 for review Message-ID: <200310010033.h910XQSU041412@repoman.freebsd.org>
next in thread | raw e-mail | index | archive | help
http://perforce.freebsd.org/chv.cgi?CH=38934 Change 38934 by peter@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_ */
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200310010033.h910XQSU041412>