Date: Sun, 16 Nov 2003 13:42:51 -0800 (PST) From: Peter Wemm <peter@FreeBSD.org> To: Perforce Change Reviews <perforce@freebsd.org> Subject: PERFORCE change 42581 for review Message-ID: <200311162142.hAGLgpWg022045@repoman.freebsd.org>
next in thread | raw e-mail | index | archive | help
http://perforce.freebsd.org/chv.cgi?CH=42581 Change 42581 by peter@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);
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200311162142.hAGLgpWg022045>