PERFORCE change 41553 for review
Peter Wemm
peter at FreeBSD.org
Wed Nov 5 20:15:19 PST 2003
http://perforce.freebsd.org/chv.cgi?CH=41553
Change 41553 by peter at 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
More information about the p4-projects
mailing list