Skip site navigation (1)Skip section navigation (2)
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>