Skip site navigation (1)Skip section navigation (2)
Date:      Sun, 16 Nov 2003 09:22:17 -0800 (PST)
From:      Peter Wemm <peter@FreeBSD.org>
To:        Perforce Change Reviews <perforce@freebsd.org>
Subject:   PERFORCE change 42554 for review
Message-ID:  <200311161722.hAGHMHB3000200@repoman.freebsd.org>

next in thread | raw e-mail | index | archive | help
http://perforce.freebsd.org/chv.cgi?CH=42554

Change 42554 by peter@peter_overcee on 2003/11/16 09:21:27

	fix some bugs:
	- basemem is in K, not bytes (argh, not again!)
	- access the pagetables in KERNBASE
	- actually or in the pte bits
	- it would be useful to set %rsp to the end of the stack.
	- restore the warmstart vector prior to panic() so that
	  resetting the BSP will not cause it to try and do AP startup

Affected files ...

.. //depot/projects/hammer/sys/amd64/amd64/mp_machdep.c#32 edit

Differences ...

==== //depot/projects/hammer/sys/amd64/amd64/mp_machdep.c#32 (text+ko) ====

@@ -147,11 +147,11 @@
 {
 
 	bootMP_size = mptramp_end - mptramp_start;
-	boot_address = trunc_page(basemem);	/* round down to 4k boundary */
+	boot_address = trunc_page(basemem * 1024); /* round down to 4k boundary */
 	if ((basemem - boot_address) < bootMP_size)
 		boot_address -= PAGE_SIZE;	/* not enough, lower by 4k */
 	/* 3 levels of page table pages */
-	mptramp_pagetables = boot_address - PAGE_SIZE * 3;
+	mptramp_pagetables = boot_address - (PAGE_SIZE * 3);
 
 	return mptramp_pagetables;
 }
@@ -464,26 +464,24 @@
 	bcopy(mptramp_start, (void *)((uintptr_t)boot_address + KERNBASE), bootMP_size);
 
 	/* Locate the page tables, they'll be below the trampoline */
-	pt4 = (u_int64_t *)(uintptr_t)mptramp_pagetables;
+	pt4 = (u_int64_t *)(uintptr_t)(mptramp_pagetables + KERNBASE);
 	pt3 = pt4 + 512;
 	pt2 = pt3 + 512;
-	printf("pt4 = %p; pt3 = %p; pt2 = %p\n", pt4, pt3, pt2);
 
 	/* Create the initial 1GB replicated page tables */
 	for (i = 0; i < 512; i++) {
 		/* Each slot of the level 4 pages points to the same level 3 page */
-		pt4[i] = (u_int64_t)(uintptr_t)pt3;
-		pt4[i] = PG_V | PG_RW | PG_U;
+		pt4[i] = (u_int64_t)(uintptr_t)(mptramp_pagetables + PAGE_SIZE);
+		pt4[i] |= PG_V | PG_RW | PG_U;
 
 		/* Each slot of the level 3 pages points to the same level 2 page */
-		pt3[i] = (u_int64_t)(uintptr_t)pt2;
-		pt3[i] = PG_V | PG_RW | PG_U;
+		pt3[i] = (u_int64_t)(uintptr_t)(mptramp_pagetables + 2 * PAGE_SIZE);
+		pt3[i] |= PG_V | PG_RW | PG_U;
 
 		/* The level 2 page slots are mapped with 2MB pages for 1GB. */
 		pt2[i] = i * (2 * 1024 * 1024);
-		pt2[i] = PG_V | PG_RW | PG_PS | PG_U;
+		pt2[i] |= PG_V | PG_RW | PG_PS | PG_U;
 	}
-	printf("pagetables created\n");
 
 	/* save the current value of the warm-start vector */
 	mpbioswarmvec = *((u_int32_t *) WARMBOOT_OFF);
@@ -491,7 +489,8 @@
 	mpbiosreason = inb(CMOS_DATA);
 
 	/* start each AP */
-	for (cpu = 0, apic_id = 0; apic_id < MAXCPU; apic_id++) {
+	cpu = 0;
+	for (apic_id = 0; apic_id < MAXCPU; apic_id++) {
 		if (!cpu_info[apic_id].cpu_present ||
 		    cpu_info[apic_id].cpu_bsp)
 			continue;
@@ -534,12 +533,15 @@
 		outb(CMOS_REG, BIOS_RESET);
 		outb(CMOS_DATA, BIOS_WARM);	/* 'warm-start' */
 
-		bootSTK = bootstacks[cpu];
+		bootSTK = (char *)bootstacks[cpu] + KSTACK_PAGES * PAGE_SIZE - 8;
 		bootAP = cpu;
 
 		/* attempt to start the Application Processor */
-		if (!start_ap(apic_id))
+		if (!start_ap(apic_id)) {
+			/* restore the warmstart vector */
+			*(u_int32_t *) WARMBOOT_OFF = mpbioswarmvec;
 			panic("AP #%d (PHY# %d) failed!", cpu, apic_id);
+		}
 
 		all_cpus |= (1 << cpu);		/* record AP in CPU map */
 	}



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200311161722.hAGHMHB3000200>