PERFORCE change 42581 for review
Peter Wemm
peter at FreeBSD.org
Sun Nov 16 13:42:54 PST 2003
http://perforce.freebsd.org/chv.cgi?CH=42581
Change 42581 by peter at peter_overcee on 2003/11/16 13:41:58
checkpoint, with all its WIP in full glory.
Affected files ...
.. //depot/projects/hammer/sys/amd64/amd64/mp_machdep.c#33 edit
Differences ...
==== //depot/projects/hammer/sys/amd64/amd64/mp_machdep.c#33 (text+ko) ====
@@ -1,5 +1,6 @@
/*-
* Copyright (c) 1996, by Steve Passe
+ * Copyright (c) 2003, by Steve Passe
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -104,6 +105,8 @@
volatile int smp_tlb_wait;
struct mtx smp_tlb_mtx;
+extern inthand_t IDTVEC(fast_syscall), IDTVEC(fast_syscall32);
+
/*
* Local data and functions.
*/
@@ -307,23 +310,59 @@
void
init_secondary(void)
{
- int gsel_tss;
- int myid;
+ int cpu, gsel_tss;
+ u_int64_t msr;
+#if 1
+ int x;
+#endif
u_int64_t cr0;
struct pcpu *pc;
- /* bootAP is set in start_ap() to our ID. */
- myid = bootAP;
+ /* Set by the startup code for us to use */
+ cpu = bootAP;
+
+ /* Init tss */
+ common_tss[cpu] = common_tss[0];
+ common_tss[cpu].tss_rsp0 = 0; /* not used until after switch */
+
+ gdt_segs[GPROC0_SEL].ssd_base = (long) &common_tss[cpu];
+
+#if 1
+ for (x = 0; x < NGDT; x++)
+ if (x != GPROC0_SEL && x != (GPROC0_SEL + 1))
+ ssdtosd(&gdt_segs[x], &gdt[cpu * NGDT + x]);
+#endif
+ ssdtosyssd(&gdt_segs[GPROC0_SEL],
+ (struct system_segment_descriptor *)&gdt[cpu * NGDT + GPROC0_SEL]);
+
+#if 1
+ r_gdt.rd_limit = NGDT * sizeof(gdt[0]) - 1;
+ r_gdt.rd_base = (long) &gdt[cpu * NGDT];
+#endif
+
lgdt(&r_gdt); /* does magic intra-segment return */
- pc = &__pcpu[myid];
+ /* Get per-cpu data */
+ pc = &__pcpu[cpu];
+
+ /* prime data page for it to use */
+ pcpu_init(pc, cpu, sizeof(struct pcpu));
+ pc->pc_apic_id = cpu_apic_ids[cpu];
+ pc->pc_prvspace = pc;
+ pc->pc_curthread = 0;
+ pc->pc_tssp = &common_tss[cpu];
+ pc->pc_rsp0 = 0;
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 */
+ wrmsr(MSR_KGSBASE, (u_int64_t)pc); /* User value while we're in the kernel */
lidt(&r_idt);
+#if 1
+ /* Every 'ltr' changes the type from SDT_SYSTSS to SDT_SYSBSY */
+ ((struct system_segment_descriptor *)&gdt[cpu * NGDT + GPROC0_SEL])->sd_type = SDT_SYSTSS;
+#endif
gsel_tss = GSEL(GPROC0_SEL, SEL_KPL);
ltr(gsel_tss);
@@ -337,6 +376,16 @@
cr0 &= ~(CR0_CD | CR0_NW | CR0_EM);
load_cr0(cr0);
+ /* Set up the fast syscall stuff */
+ msr = rdmsr(MSR_EFER) | EFER_SCE;
+ wrmsr(MSR_EFER, msr);
+ wrmsr(MSR_LSTAR, (u_int64_t)IDTVEC(fast_syscall));
+ wrmsr(MSR_CSTAR, (u_int64_t)IDTVEC(fast_syscall32));
+ msr = ((u_int64_t)GSEL(GCODE_SEL, SEL_KPL) << 32) |
+ ((u_int64_t)GSEL(GUCODE32_SEL, SEL_UPL) << 48);
+ wrmsr(MSR_STAR, msr);
+ wrmsr(MSR_SF_MASK, PSL_NT|PSL_T|PSL_I|PSL_C|PSL_D);
+
/* Disable local apic just to be sure. */
lapic_disable();
@@ -453,8 +502,7 @@
{
u_char mpbiosreason;
u_int32_t mpbioswarmvec;
- struct pcpu *pc;
- int x, apic_id, cpu, i;
+ int apic_id, cpu, i;
u_int64_t *pt4, *pt3, *pt2;
mtx_init(&ap_boot_mtx, "ap boot", NULL, MTX_SPIN);
@@ -488,6 +536,12 @@
outb(CMOS_REG, BIOS_RESET);
mpbiosreason = inb(CMOS_DATA);
+ /* setup a vector to our boot code */
+ *((volatile u_short *) WARMBOOT_OFF) = WARMBOOT_TARGET;
+ *((volatile u_short *) WARMBOOT_SEG) = (boot_address >> 4);
+ outb(CMOS_REG, BIOS_RESET);
+ outb(CMOS_DATA, BIOS_WARM); /* 'warm-start' */
+
/* start each AP */
cpu = 0;
for (apic_id = 0; apic_id < MAXCPU; apic_id++) {
@@ -499,40 +553,9 @@
/* save APIC ID for this logical ID */
cpu_apic_ids[cpu] = apic_id;
- /* Get per-cpu data */
- pc = &__pcpu[cpu];
-
/* allocate and set up an idle stack data page */
bootstacks[cpu] = (char *)kmem_alloc(kernel_map, KSTACK_PAGES * PAGE_SIZE);
- /* Init tss */
- common_tss[cpu] = common_tss[0];
- common_tss[cpu].tss_rsp0 = 0; /* not used until after switch */
-
- /* XXX not so fast there sonny! */
- gdt_segs[GPROC0_SEL].ssd_base = (long) &common_tss[cpu];
-
- for (x = 0; x < NGDT; x++)
- if (x != GPROC0_SEL && x != (GPROC0_SEL + 1))
- ssdtosd(&gdt_segs[x], &gdt[cpu * NGDT + x]);
- ssdtosyssd(&gdt_segs[GPROC0_SEL],
- (struct system_segment_descriptor *)&gdt[cpu * NGDT + GPROC0_SEL]);
-
- r_gdt.rd_limit = NGDT * sizeof(gdt[0]) - 1;
- r_gdt.rd_base = (long) &gdt[cpu * NGDT];
-
- /* prime data page for it to use */
- pcpu_init(pc, cpu, sizeof(struct pcpu));
- pc->pc_apic_id = apic_id;
- pc->pc_prvspace = pc;
- pc->pc_curthread = 0;
-
- /* setup a vector to our boot code */
- *((volatile u_short *) WARMBOOT_OFF) = WARMBOOT_TARGET;
- *((volatile u_short *) WARMBOOT_SEG) = (boot_address >> 4);
- outb(CMOS_REG, BIOS_RESET);
- outb(CMOS_DATA, BIOS_WARM); /* 'warm-start' */
-
bootSTK = (char *)bootstacks[cpu] + KSTACK_PAGES * PAGE_SIZE - 8;
bootAP = cpu;
@@ -631,10 +654,10 @@
DELAY(200); /* wait ~200uS */
/* Wait up to 5 seconds for it to start. */
- for (ms = 0; ms < 5000; ms++) {
+ for (ms = 0; ms < 50; ms++) {
if (mp_naps > cpus)
return 1; /* return SUCCESS */
- DELAY(1000);
+ DELAY(100000);
}
return 0; /* return FAILURE */
}
@@ -806,7 +829,9 @@
{
struct thread *td;
+#if 0
CTR0(KTR_SMP, "forwarded_statclock");
+#endif
td = curthread;
td->td_intr_nesting_level++;
if (profprocs != 0)
@@ -820,12 +845,18 @@
forward_statclock(void)
{
int map;
+ static int foocnt;
+#if 0
CTR0(KTR_SMP, "forward_statclock");
+#endif
if (!smp_started || cold || panicstr)
return;
+ foocnt++;
+ if ((foocnt % 100) != 0)
+ return;
map = PCPU_GET(other_cpus) & ~(stopped_cpus|hlt_cpus_mask);
if (map != 0)
ipi_selected(map, IPI_STATCLOCK);
@@ -843,7 +874,9 @@
{
struct thread *td;
+#if 0
CTR0(KTR_SMP, "forwarded_hardclock");
+#endif
td = curthread;
td->td_intr_nesting_level++;
hardclock_process(&frame);
@@ -854,12 +887,18 @@
forward_hardclock(void)
{
u_int map;
+ static int foocnt;
+#if 0
CTR0(KTR_SMP, "forward_hardclock");
+#endif
if (!smp_started || cold || panicstr)
return;
+ foocnt++;
+ if ((foocnt % 100) != 0)
+ return;
map = PCPU_GET(other_cpus) & ~(stopped_cpus|hlt_cpus_mask);
if (map != 0)
ipi_selected(map, IPI_HARDCLOCK);
More information about the p4-projects
mailing list