Skip site navigation (1)Skip section navigation (2)
Date:      Wed, 5 Nov 2003 20:15:16 -0800 (PST)
From:      Peter Wemm <peter@FreeBSD.org>
To:        Perforce Change Reviews <perforce@freebsd.org>
Subject:   PERFORCE change 41553 for review
Message-ID:  <200311060415.hA64FG3L082596@repoman.freebsd.org>

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

Change 41553 by peter@peter_daintree on 2003/11/05 20:14:42

	almost finished now.
	1) remove !@^#!%# boot_addr args.  There is no need to make
	   work for ourselves by passing it around like this.
	2) have the trampoline patch its own gdt[] since its simple.
	3) flesh out install_ap_tramp() and instead inline its two
	   remaining lines of code.  It now self-relocates, and use
	   bcopy() instead of hand-rolling it.  Also,
	   mptramp_pagetables is set earlier too.
	4) move the trampoline code to the .data section, FWIW.

Affected files ...

.. //depot/projects/hammer/sys/amd64/amd64/mp_machdep.c#24 edit
.. //depot/projects/hammer/sys/amd64/amd64/mpboot.S#4 edit

Differences ...

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

@@ -29,12 +29,6 @@
 #include "opt_cpu.h"
 #include "opt_kstack_pages.h"
 
-#if !defined(lint)
-#if !defined(SMP)
-#error How did you get here?
-#endif
-#endif /* not lint */
-
 #include <sys/param.h>
 #include <sys/systm.h>
 #include <sys/bus.h>
@@ -136,12 +130,11 @@
 } static cpu_info[MAXCPU];
 static int cpu_apic_ids[MAXCPU];
 
-static u_int boot_address;
+static u_int	boot_address;
 
 static void	set_logical_apic_ids(void);
-static int	start_all_aps(u_int boot_addr);
-static void	install_ap_tramp(u_int boot_addr);
-static int	start_ap(int apic_id, u_int boot_addr);
+static int	start_all_aps(void);
+static int	start_ap(int apic_id);
 static void	release_aps(void *dummy);
 
 static int	hlt_cpus_mask;
@@ -160,8 +153,10 @@
 	boot_address = basemem & ~PAGE_MASK;	/* 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;
 
-	return boot_address;
+	return mptramp_pagetables;
 }
 
 void
@@ -279,7 +274,7 @@
 	cpu_apic_ids[0] = boot_cpu_id;
 
 	/* Start each Application Processor */
-	start_all_aps(boot_address);
+	start_all_aps();
 
 	/* Setup the initial logical CPUs info. */
 	logical_cpus = logical_cpus_mask = 0;
@@ -457,7 +452,7 @@
  * start each AP in our list
  */
 static int
-start_all_aps(u_int boot_addr)
+start_all_aps()
 {
 	u_char mpbiosreason;
 	u_int32_t mpbioswarmvec;
@@ -467,7 +462,8 @@
 	mtx_init(&ap_boot_mtx, "ap boot", NULL, MTX_SPIN);
 
 	/* install the AP 1st level boot code */
-	install_ap_tramp(boot_addr);
+	pmap_kenter(boot_address + KERNBASE, boot_address);
+	bcopy(mptramp_start, (void *)((uintptr_t)boot_address + KERNBASE), bootMP_size);
 
 	/* save the current value of the warm-start vector */
 	mpbioswarmvec = *((u_int32_t *) WARMBOOT_OFF);
@@ -513,7 +509,7 @@
 
 		/* setup a vector to our boot code */
 		*((volatile u_short *) WARMBOOT_OFF) = WARMBOOT_TARGET;
-		*((volatile u_short *) WARMBOOT_SEG) = (boot_addr >> 4);
+		*((volatile u_short *) WARMBOOT_SEG) = (boot_address >> 4);
 		outb(CMOS_REG, BIOS_RESET);
 		outb(CMOS_DATA, BIOS_WARM);	/* 'warm-start' */
 
@@ -521,7 +517,7 @@
 		bootAP = cpu;
 
 		/* attempt to start the Application Processor */
-		if (!start_ap(apic_id, boot_addr)) {
+		if (!start_ap(apic_id)) {
 			printf("AP #%d (PHY# %d) failed!\n", cpu, apic_id);
 			/* better panic as the AP may be running loose */
 			printf("panic y/n? [y] ");
@@ -545,74 +541,6 @@
 	return mp_naps;
 }
 
-/*
- * load the 1st level AP boot code into base memory.
- */
-
-#ifdef SMP_ME_HARDER
-/* targets for relocation */
-extern void bigJump(void);
-extern void bootCodeSeg(void);
-extern void bootDataSeg(void);
-extern void MPentry(void);
-extern u_int MP_GDT;
-extern u_int mp_gdtbase;
-#endif
-
-static void
-install_ap_tramp(u_int boot_addr)
-{
-#ifdef SMP_ME_HARDER
-	int     x;
-	int     size = *(int *) ((u_long) & bootMP_size);
-	u_char *src = (u_char *) ((u_long) bootMP);
-	u_char *dst = (u_char *) boot_addr + KERNBASE;
-	u_int   boot_base = (u_int) bootMP;
-	u_int8_t *dst8;
-	u_int16_t *dst16;
-	u_int32_t *dst32;
-
-	pmap_kenter(boot_addr + KERNBASE, boot_addr);
-	for (x = 0; x < size; ++x)
-		*dst++ = *src++;
-
-	/*
-	 * modify addresses in code we just moved to basemem. unfortunately we
-	 * need fairly detailed info about mpboot.s for this to work.  changes
-	 * to mpboot.s might require changes here.
-	 */
-
-	/* boot code is located in KERNEL space */
-	dst = (u_char *) boot_addr + KERNBASE;
-
-	/* modify the lgdt arg */
-	dst32 = (u_int32_t *) (dst + ((u_int) & mp_gdtbase - boot_base));
-	*dst32 = boot_addr + ((u_int) & MP_GDT - boot_base);
-
-	/* modify the ljmp target for MPentry() */
-	dst32 = (u_int32_t *) (dst + ((u_int) bigJump - boot_base) + 1);
-	*dst32 = ((u_int) MPentry - KERNBASE);
-
-	/* modify the target for boot code segment */
-	dst16 = (u_int16_t *) (dst + ((u_int) bootCodeSeg - boot_base));
-	dst8 = (u_int8_t *) (dst16 + 1);
-	*dst16 = (u_int) boot_addr & 0xffff;
-	*dst8 = ((u_int) boot_addr >> 16) & 0xff;
-
-	/* modify the target for boot data segment */
-	dst16 = (u_int16_t *) (dst + ((u_int) bootDataSeg - boot_base));
-	dst8 = (u_int8_t *) (dst16 + 1);
-	*dst16 = (u_int) boot_addr & 0xffff;
-	*dst8 = ((u_int) boot_addr >> 16) & 0xff;
-#endif
-}
-
-void compile_hack(void);
-void
-compile_hack()
-{
-	start_ap(0, bootAP);
-}
 
 /*
  * This function starts the AP (application processor) identified
@@ -622,13 +550,13 @@
  * but it seems to work.
  */
 static int
-start_ap(int apic_id, u_int boot_addr)
+start_ap(int apic_id)
 {
 	int vector, ms;
 	int cpus;
 
 	/* calculate the vector */
-	vector = (boot_addr >> 12) & 0xff;
+	vector = (boot_address >> 12) & 0xff;
 
 	/* used as a watchpoint to signal AP startup */
 	cpus = mp_naps;

==== //depot/projects/hammer/sys/amd64/amd64/mpboot.S#4 (text+ko) ====

@@ -31,9 +31,9 @@
 
 #include "assym.s"
 
-	.section .bootcode
-	.p2align 4
+	.data				/* So we can modify it */
 
+	.p2align 4,0
 	.globl	mptramp_start
 mptramp_start:
 	.code16
@@ -47,6 +47,15 @@
 	mov	%ax, %ss
 
 	/*
+	 * Patch the descriptor table
+	 */
+	xorl	%eax,%eax
+	mov	%cs, %ax
+	sall	$4, %eax
+	orl	%eax, bootcode-gdt+2
+	orl	%eax, bootdata-gdt+2
+
+	/*
 	 * Load the descriptor table pointer.  We'll need it when running
 	 * in 16 bit protected mode.
 	 */
@@ -88,7 +97,7 @@
 	 * means we are required to use a temporary page table that is below
 	 * the 4GB limit.
 	 */
-	movl	$pagetables, %eax
+	movl	$(mptramp_pagetables-mptramp_start), %eax
 	mov	%eax, %cr3
 
 	/*
@@ -134,6 +143,7 @@
 	 * This is the descriptor for the 32 bit boot code.
 	 * %cs:  +A, +R, -C, DPL=0, +P, +D, +G
 	 * Accessed, Readable, Present, 32 bit, 4G granularity
+	 * Note that the base address is patched.
 	 */
 bootcode:
 	.long	0x0000ffff
@@ -148,6 +158,7 @@
 	 * Accessed, Writeable, Expand up, Present, 32 bit, 4GB 
 	 * For %ds, +D means 'default operand size is 32 bit'.
 	 * For %ss, +B means the stack register is %esp rather than %sp.
+	 * Note that the base address is patched.
 	 */
 bootdata:
 	.long	0x0000ffff
@@ -155,8 +166,8 @@
 
 gdtend:
 
-	.globl	pagetables
-pagetables:
+	.globl	mptramp_pagetables
+mptramp_pagetables:
 	.long	0
 	/*
 	 * The pseudo descriptor for lgdt to use.
@@ -179,6 +190,7 @@
 	 */
 	.text
 	.code64
+	.p2align 4,0
 entry_64:
 	movq	$bootSTK, %rsp
 	pushq	$init_secondary



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