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>