Date: Sat, 30 Apr 2011 20:49:01 +0000 (UTC) From: Marcel Moolenaar <marcel@FreeBSD.org> To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org Subject: svn commit: r221271 - in head/sys: conf ia64/ia64 ia64/include Message-ID: <201104302049.p3UKn1GO061687@svn.freebsd.org>
next in thread | raw e-mail | index | archive | help
Author: marcel Date: Sat Apr 30 20:49:00 2011 New Revision: 221271 URL: http://svn.freebsd.org/changeset/base/221271 Log: Stop linking against a direct-mapped virtual address and instead use the PBVM. This eliminates the implied hardcoding of the physical address at which the kernel needs to be loaded. Using the PBVM makes it possible to load the kernel irrespective of the physical memory organization and allows us to replicate kernel text on NUMA machines. While here, reduce the direct-mapped page size to the kernel's page size so that we can support memory attributes better. Added: head/sys/ia64/ia64/mp_locore.S (contents, props changed) Modified: head/sys/conf/files.ia64 head/sys/conf/ldscript.ia64 head/sys/ia64/ia64/efi.c head/sys/ia64/ia64/exception.S head/sys/ia64/ia64/genassym.c head/sys/ia64/ia64/locore.S head/sys/ia64/ia64/machdep.c head/sys/ia64/ia64/mp_machdep.c head/sys/ia64/ia64/pmap.c head/sys/ia64/ia64/sal.c head/sys/ia64/include/ia64_cpu.h head/sys/ia64/include/smp.h head/sys/ia64/include/vmparam.h Modified: head/sys/conf/files.ia64 ============================================================================== --- head/sys/conf/files.ia64 Sat Apr 30 20:34:52 2011 (r221270) +++ head/sys/conf/files.ia64 Sat Apr 30 20:49:00 2011 (r221271) @@ -92,6 +92,7 @@ ia64/ia64/locore.S standard no-obj ia64/ia64/machdep.c standard ia64/ia64/mca.c standard ia64/ia64/mem.c optional mem +ia64/ia64/mp_locore.S optional smp ia64/ia64/mp_machdep.c optional smp ia64/ia64/nexus.c standard ia64/ia64/pal.S standard Modified: head/sys/conf/ldscript.ia64 ============================================================================== --- head/sys/conf/ldscript.ia64 Sat Apr 30 20:34:52 2011 (r221270) +++ head/sys/conf/ldscript.ia64 Sat Apr 30 20:49:00 2011 (r221271) @@ -3,7 +3,7 @@ OUTPUT_FORMAT("elf64-ia64-freebsd", "elf OUTPUT_ARCH(ia64) ENTRY(__start) SEARCH_DIR(/usr/lib); -kernel_text = 0xe000000004000000; +kernel_text = 0x9ffc000000000000; SECTIONS { /* Read-only sections, merged into text segment: */ @@ -11,10 +11,10 @@ SECTIONS .interp : { *(.interp) } PROVIDE (btext = .); - .ivt : { *(.ivt) } .text : { - *(.text.ivt) + *(.ivt) + *(.ivt.text) *(.text .stub .text.* .gnu.linkonce.t.*) /* .gnu.warning sections are handled specially by elf32.em. */ *(.gnu.warning) @@ -60,9 +60,11 @@ SECTIONS page in the loader virtual memory. */ . = ALIGN(65536); + PROVIDE (bdata = .); .data : { - *(.data.kstack .data .data.* .gnu.linkonce.d.*) + *(.ivt.data) + *(.data .data.* .gnu.linkonce.d.*) SORT(CONSTRUCTORS) } .data1 : { *(.data1) } Modified: head/sys/ia64/ia64/efi.c ============================================================================== --- head/sys/ia64/ia64/efi.c Sat Apr 30 20:34:52 2011 (r221270) +++ head/sys/ia64/ia64/efi.c Sat Apr 30 20:49:00 2011 (r221271) @@ -129,7 +129,7 @@ efi_boot_minimal(uint64_t systbl) setvirt = (void *)IA64_PHYS_TO_RR7((u_long)efi_runtime->rt_setvirtual); status = ia64_efi_physical(setvirt, bootinfo->bi_memmap_size, bootinfo->bi_memdesc_size, bootinfo->bi_memdesc_version, - bootinfo->bi_memmap); + ia64_tpa(bootinfo->bi_memmap)); return ((status < 0) ? EFAULT : 0); } @@ -164,7 +164,7 @@ efi_md_first(void) if (bootinfo->bi_memmap == 0) return (NULL); - return ((struct efi_md *)IA64_PHYS_TO_RR7(bootinfo->bi_memmap)); + return ((struct efi_md *)bootinfo->bi_memmap); } struct efi_md * @@ -172,7 +172,7 @@ efi_md_next(struct efi_md *md) { uint64_t plim; - plim = IA64_PHYS_TO_RR7(bootinfo->bi_memmap + bootinfo->bi_memmap_size); + plim = bootinfo->bi_memmap + bootinfo->bi_memmap_size; md = (struct efi_md *)((uintptr_t)md + bootinfo->bi_memdesc_size); return ((md >= (struct efi_md *)plim) ? NULL : md); } Modified: head/sys/ia64/ia64/exception.S ============================================================================== --- head/sys/ia64/ia64/exception.S Sat Apr 30 20:34:52 2011 (r221270) +++ head/sys/ia64/ia64/exception.S Sat Apr 30 20:49:00 2011 (r221271) @@ -48,9 +48,16 @@ __FBSDID("$FreeBSD$"); * ar.k4 = PCPU data */ + .section .ivt.data, "aw" + + .global pmap_ptc_g_sem +pmap_ptc_g_sem: data8 0 + + .global ia64_kptdir +ia64_kptdir: data8 0 + #ifdef EXCEPTION_TRACING - .data .global xtrace, xhead xtrace: .space 1024*5*8 xhead: data8 xtrace @@ -101,7 +108,7 @@ xhead: data8 xtrace #endif - .section .text.ivt, "ax" + .section .ivt.text, "ax" /* * exception_save: save interrupted state @@ -129,7 +136,7 @@ ENTRY_NOPROFILE(exception_save, 0) ;; } { .mmi - cmp.le p14,p15=5,r31 + cmp.le p14,p15=IA64_VM_MINKERN_REGION,r31 ;; (p15) mov r23=ar.k7 // kernel memory stack (p14) mov r23=sp @@ -233,7 +240,7 @@ exception_save_restart: { .mmi st8 [r30]=r19,16 // rnat st8 [r31]=r0,16 // __spare - cmp.le p12,p13=5,r24 + cmp.le p12,p13=IA64_VM_MINKERN_REGION,r24 ;; } { .mmi @@ -602,7 +609,7 @@ ENTRY_NOPROFILE(exception_restore, 0) { .mmi ld8.fill r1=[r30],16 // gp ld8 r27=[r31],16 // ndirty - cmp.le p14,p15=5,r28 + cmp.le p14,p15=IA64_VM_MINKERN_REGION,r28 ;; } { .mmi @@ -915,7 +922,7 @@ IVT_ENTRY(Alternate_Instruction_TLB, 0x0 extr.u r17=r16,61,3 // get region number mov r19=PTE_PRESENT+PTE_ACCESSED+PTE_DIRTY+PTE_PL_KERN+PTE_AR_RWX ;; - cmp.eq p13,p0=4,r17 // RR4? + cmp.eq p13,p0=IA64_PBVM_RR,r17 // RR4? (p13) br.cond.sptk.few 4f ;; cmp.ge p13,p0=5,r17 // RR0-RR5? @@ -958,7 +965,7 @@ IVT_ENTRY(Alternate_Data_TLB, 0x1000) extr.u r17=r16,61,3 // get region number mov r19=PTE_PRESENT+PTE_ACCESSED+PTE_DIRTY+PTE_PL_KERN+PTE_AR_RWX ;; - cmp.eq p13,p0=4,r17 // RR4? + cmp.eq p13,p0=IA64_PBVM_RR,r17 // RR4? (p13) br.cond.sptk.few 4f ;; cmp.ge p13,p0=5,r17 // RR0-RR5? @@ -1007,21 +1014,22 @@ IVT_ENTRY(Data_Nested_TLB, 0x1400) // double nested faults. Since all virtual addresses we encounter // here are direct mapped region 7 addresses, we have no problem // constructing physical addresses. + { .mlx - rsm psr.dt + nop 0 movl r27=ia64_kptdir ;; } { .mii - srlz.d - dep r27=0,r27,61,3 - ;; + ld8 r27=[r27] extr.u r28=r30,3*PAGE_SHIFT-8, PAGE_SHIFT-3 // dir L0 index -} -{ .mii - ld8 r27=[r27] // dir L0 page extr.u r26=r30,2*PAGE_SHIFT-5, PAGE_SHIFT-3 // dir L1 index ;; +} +{ .mmi + rsm psr.dt + ;; + srlz.d dep r27=0,r27,61,3 ;; } Modified: head/sys/ia64/ia64/genassym.c ============================================================================== --- head/sys/ia64/ia64/genassym.c Sat Apr 30 20:34:52 2011 (r221270) +++ head/sys/ia64/ia64/genassym.c Sat Apr 30 20:49:00 2011 (r221271) @@ -77,13 +77,13 @@ ASSYM(ERESTART, ERESTART); ASSYM(FRAME_SYSCALL, FRAME_SYSCALL); -ASSYM(IA64_ID_PAGE_SHIFT, IA64_ID_PAGE_SHIFT); - ASSYM(IA64_PBVM_BASE, IA64_PBVM_BASE); ASSYM(IA64_PBVM_PAGE_SHIFT, IA64_PBVM_PAGE_SHIFT); ASSYM(IA64_PBVM_PGTBL, IA64_PBVM_PGTBL); ASSYM(IA64_PBVM_RR, IA64_PBVM_RR); +ASSYM(IA64_VM_MINKERN_REGION, IA64_VM_MINKERN_REGION); + ASSYM(KSTACK_PAGES, KSTACK_PAGES); ASSYM(MC_PRESERVED, offsetof(mcontext_t, mc_preserved)); Modified: head/sys/ia64/ia64/locore.S ============================================================================== --- head/sys/ia64/ia64/locore.S Sat Apr 30 20:34:52 2011 (r221270) +++ head/sys/ia64/ia64/locore.S Sat Apr 30 20:49:00 2011 (r221271) @@ -1,4 +1,5 @@ /*- + * Copyright (c) 2001-2011 Marcel Moolenaar * Copyright (c) 1998 Doug Rabson * All rights reserved. * @@ -26,12 +27,10 @@ * $FreeBSD$ */ -#include <sys/syscall.h> #include <machine/asm.h> #include <machine/ia64_cpu.h> #include <machine/intrcnt.h> #include <machine/pte.h> -#include <machine/intrcnt.h> #include <assym.s> /* @@ -40,7 +39,7 @@ */ #define FW_STACK_SIZE 3*PAGE_SIZE - .section .data.kstack, "aw" + .section .ivt.data, "aw" .align PAGE_SIZE .global kstack kstack: .space FW_STACK_SIZE @@ -82,7 +81,7 @@ ENTRY_NOPROFILE(__start, 1) } { .mlx mov ar.bspstore=r16 // switch backing store - movl r16=pa_bootinfo + movl r16=bootinfo ;; } { .mmi @@ -187,124 +186,6 @@ enter_userland: } END(fork_trampoline) -#ifdef SMP -/* - * AP wake-up entry point. The handoff state is similar as for the BSP, - * as described on page 3-9 of the IPF SAL Specification. The difference - * lies in the contents of register b0. For APs this register holds the - * return address into the SAL rendezvous routine. - * - * Note that we're responsible for clearing the IRR bit by reading cr.ivr - * and issuing the EOI to the local SAPIC. - */ - .align 32 -ENTRY_NOPROFILE(os_boot_rendez,0) - mov r16=cr.ivr // clear IRR bit - ;; - srlz.d - mov cr.eoi=r0 // ACK the wake-up - ;; - srlz.d - rsm IA64_PSR_IC|IA64_PSR_I - ;; - mov r16 = (5<<8)|(PAGE_SHIFT<<2)|1 - movl r17 = 5<<61 - ;; - mov rr[r17] = r16 - ;; - srlz.d - mov r16 = (6<<8)|(IA64_ID_PAGE_SHIFT<<2) - movl r17 = 6<<61 - ;; - mov rr[r17] = r16 - ;; - srlz.d - mov r16 = (7<<8)|(IA64_ID_PAGE_SHIFT<<2) - movl r17 = 7<<61 - ;; - mov rr[r17] = r16 - ;; - srlz.d - mov r18 = 28<<2 - movl r16 = PTE_PRESENT+PTE_MA_WB+PTE_ACCESSED+PTE_DIRTY+ \ - PTE_PL_KERN+PTE_AR_RWX+PTE_ED - ;; - mov cr.ifa = r17 - mov cr.itir = r18 - ptr.d r17, r18 - ptr.i r17, r18 - ;; - srlz.i - ;; - itr.d dtr[r0] = r16 - mov r18 = IA64_DCR_DEFAULT - ;; - itr.i itr[r0] = r16 - mov cr.dcr = r18 - ;; - srlz.i - ;; -1: mov r16 = ip - add r17 = 2f-1b, r17 - movl r18 = (IA64_PSR_AC|IA64_PSR_BN|IA64_PSR_DFH|IA64_PSR_DT|IA64_PSR_IC|IA64_PSR_IT|IA64_PSR_RT) - ;; - add r17 = r17, r16 - mov cr.ipsr = r18 - mov cr.ifs = r0 - ;; - mov cr.iip = r17 - ;; - rfi - - .align 32 -2: -{ .mlx - mov ar.rsc = 0 - movl r16 = ia64_vector_table // set up IVT early - ;; -} -{ .mlx - mov cr.iva = r16 - movl r16 = ap_stack - ;; -} -{ .mmi - srlz.i - ;; - ld8 r16 = [r16] - mov r18 = KSTACK_PAGES*PAGE_SIZE-SIZEOF_PCB-SIZEOF_TRAPFRAME-16 - ;; -} -{ .mlx - mov ar.bspstore = r16 - movl gp = __gp - ;; -} -{ .mmi - loadrs - ;; - alloc r17 = ar.pfs, 0, 0, 0, 0 - add sp = r18, r16 - ;; -} -{ .mib - mov ar.rsc = 3 - nop 0 - br.call.sptk.few rp = ia64_ap_startup - ;; -} - /* NOT REACHED */ -9: -{ .mib - nop 0 - nop 0 - br.sptk 9b - ;; -} -END(os_boot_rendez) - -#endif /* !SMP */ - /* * Create a default interrupt name table. The first entry (vector 0) is * hardwaired to the clock interrupt. Modified: head/sys/ia64/ia64/machdep.c ============================================================================== --- head/sys/ia64/ia64/machdep.c Sat Apr 30 20:34:52 2011 (r221270) +++ head/sys/ia64/ia64/machdep.c Sat Apr 30 20:49:00 2011 (r221271) @@ -115,7 +115,6 @@ SYSCTL_UINT(_hw_freq, OID_AUTO, itc, CTL int cold = 1; -u_int64_t pa_bootinfo; struct bootinfo *bootinfo; struct pcpu pcpu0; @@ -128,8 +127,9 @@ extern u_int64_t epc_sigtramp[]; struct fpswa_iface *fpswa_iface; -u_int64_t ia64_pal_base; -u_int64_t ia64_port_base; +vm_size_t ia64_pal_size; +vm_paddr_t ia64_pal_base; +vm_offset_t ia64_port_base; u_int64_t ia64_lapic_addr = PAL_PIB_DEFAULT_ADDR; @@ -548,15 +548,15 @@ map_vhpt(uintptr_t vhpt) pte |= vhpt & PTE_PPN_MASK; __asm __volatile("ptr.d %0,%1" :: "r"(vhpt), - "r"(IA64_ID_PAGE_SHIFT<<2)); + "r"(pmap_vhpt_log2size << 2)); __asm __volatile("mov %0=psr" : "=r"(psr)); __asm __volatile("rsm psr.ic|psr.i"); ia64_srlz_i(); ia64_set_ifa(vhpt); - ia64_set_itir(IA64_ID_PAGE_SHIFT << 2); + ia64_set_itir(pmap_vhpt_log2size << 2); ia64_srlz_d(); - __asm __volatile("itr.d dtr[%0]=%1" :: "r"(2), "r"(pte)); + __asm __volatile("itr.d dtr[%0]=%1" :: "r"(3), "r"(pte)); __asm __volatile("mov psr.l=%0" :: "r" (psr)); ia64_srlz_i(); } @@ -565,25 +565,36 @@ void map_pal_code(void) { pt_entry_t pte; + vm_offset_t va; + vm_size_t sz; uint64_t psr; + u_int shft; - if (ia64_pal_base == 0) + if (ia64_pal_size == 0) return; + va = IA64_PHYS_TO_RR7(ia64_pal_base); + + sz = ia64_pal_size; + shft = 0; + while (sz > 1) { + shft++; + sz >>= 1; + } + pte = PTE_PRESENT | PTE_MA_WB | PTE_ACCESSED | PTE_DIRTY | PTE_PL_KERN | PTE_AR_RWX; pte |= ia64_pal_base & PTE_PPN_MASK; - __asm __volatile("ptr.d %0,%1; ptr.i %0,%1" :: - "r"(IA64_PHYS_TO_RR7(ia64_pal_base)), "r"(IA64_ID_PAGE_SHIFT<<2)); + __asm __volatile("ptr.d %0,%1; ptr.i %0,%1" :: "r"(va), "r"(shft<<2)); __asm __volatile("mov %0=psr" : "=r"(psr)); __asm __volatile("rsm psr.ic|psr.i"); ia64_srlz_i(); - ia64_set_ifa(IA64_PHYS_TO_RR7(ia64_pal_base)); - ia64_set_itir(IA64_ID_PAGE_SHIFT << 2); + ia64_set_ifa(va); + ia64_set_itir(shft << 2); ia64_srlz_d(); - __asm __volatile("itr.d dtr[%0]=%1" :: "r"(1), "r"(pte)); + __asm __volatile("itr.d dtr[%0]=%1" :: "r"(4), "r"(pte)); ia64_srlz_d(); __asm __volatile("itr.i itr[%0]=%1" :: "r"(1), "r"(pte)); __asm __volatile("mov psr.l=%0" :: "r" (psr)); @@ -598,7 +609,7 @@ map_gateway_page(void) pte = PTE_PRESENT | PTE_MA_WB | PTE_ACCESSED | PTE_DIRTY | PTE_PL_KERN | PTE_AR_X_RX; - pte |= (uint64_t)ia64_gateway_page & PTE_PPN_MASK; + pte |= ia64_tpa((uint64_t)ia64_gateway_page) & PTE_PPN_MASK; __asm __volatile("ptr.d %0,%1; ptr.i %0,%1" :: "r"(VM_MAXUSER_ADDRESS), "r"(PAGE_SHIFT << 2)); @@ -609,9 +620,9 @@ map_gateway_page(void) ia64_set_ifa(VM_MAXUSER_ADDRESS); ia64_set_itir(PAGE_SHIFT << 2); ia64_srlz_d(); - __asm __volatile("itr.d dtr[%0]=%1" :: "r"(3), "r"(pte)); + __asm __volatile("itr.d dtr[%0]=%1" :: "r"(5), "r"(pte)); ia64_srlz_d(); - __asm __volatile("itr.i itr[%0]=%1" :: "r"(3), "r"(pte)); + __asm __volatile("itr.i itr[%0]=%1" :: "r"(2), "r"(pte)); __asm __volatile("mov psr.l=%0" :: "r" (psr)); ia64_srlz_i(); @@ -681,17 +692,6 @@ ia64_init(void) */ /* - * pa_bootinfo is the physical address of the bootinfo block as - * passed to us by the loader and set in locore.s. - */ - bootinfo = (struct bootinfo *)(IA64_PHYS_TO_RR7(pa_bootinfo)); - - if (bootinfo->bi_magic != BOOTINFO_MAGIC || bootinfo->bi_version != 1) { - bzero(bootinfo, sizeof(*bootinfo)); - bootinfo->bi_kernend = (vm_offset_t)round_page(_end); - } - - /* * Look for the I/O ports first - we need them for console * probing. */ @@ -702,6 +702,7 @@ ia64_init(void) md->md_pages * EFI_PAGE_SIZE); break; case EFI_MD_TYPE_PALCODE: + ia64_pal_size = md->md_pages * EFI_PAGE_SIZE; ia64_pal_base = md->md_phys; break; } @@ -742,6 +743,25 @@ ia64_init(void) kernend = round_page(bootinfo->bi_kernend); /* + * Region 6 is direct mapped UC and region 7 is direct mapped + * WC. The details of this is controlled by the Alt {I,D}TLB + * handlers. Here we just make sure that they have the largest + * possible page size to minimise TLB usage. + */ + ia64_set_rr(IA64_RR_BASE(6), (6 << 8) | (PAGE_SHIFT << 2)); + ia64_set_rr(IA64_RR_BASE(7), (7 << 8) | (PAGE_SHIFT << 2)); + ia64_srlz_d(); + + /* + * Wire things up so we can call the firmware. + */ + map_pal_code(); + efi_boot_minimal(bootinfo->bi_systab); + ia64_xiv_init(); + ia64_sal_init(); + calculate_frequencies(); + + /* * Setup the PCPU data for the bootstrap processor. It is needed * by printf(). Also, since printf() has critical sections, we * need to initialize at least pc_curthread. @@ -750,6 +770,7 @@ ia64_init(void) ia64_set_k4((u_int64_t)pcpup); pcpu_init(pcpup, 0, sizeof(pcpu0)); dpcpu_init((void *)kernend, 0); + PCPU_SET(md.lid, ia64_get_lid()); kernend += DPCPU_SIZE; PCPU_SET(curthread, &thread0); @@ -760,26 +781,6 @@ ia64_init(void) /* OUTPUT NOW ALLOWED */ - if (ia64_pal_base != 0) { - ia64_pal_base &= ~IA64_ID_PAGE_MASK; - /* - * We use a TR to map the first 256M of memory - this might - * cover the palcode too. - */ - if (ia64_pal_base == 0) - printf("PAL code mapped by the kernel's TR\n"); - } else - printf("PAL code not found\n"); - - /* - * Wire things up so we can call the firmware. - */ - map_pal_code(); - efi_boot_minimal(bootinfo->bi_systab); - ia64_xiv_init(); - ia64_sal_init(); - calculate_frequencies(); - if (metadata_missing) printf("WARNING: loader(8) metadata is missing!\n"); Added: head/sys/ia64/ia64/mp_locore.S ============================================================================== --- /dev/null 00:00:00 1970 (empty, because file is newly added) +++ head/sys/ia64/ia64/mp_locore.S Sat Apr 30 20:49:00 2011 (r221271) @@ -0,0 +1,275 @@ +/*- + * Copyright (c) 2011 Marcel Moolenaar + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * $FreeBSD$ + */ + +#include <machine/asm.h> +#include <machine/ia64_cpu.h> +#include <machine/pte.h> +#include <assym.s> + +/* + * AP wake-up entry point. The handoff state is similar as for the BSP, + * as described on page 3-9 of the IPF SAL Specification. The difference + * lies in the contents of register b0. For APs this register holds the + * return address into the SAL rendezvous routine. + * + * Note that we're responsible for clearing the IRR bit by reading cr.ivr + * and issuing the EOI to the local SAPIC. + */ + .align 32 +ENTRY_NOPROFILE(os_boot_rendez,0) +{ .mmi + st8 [gp] = gp // trace = 0x00 + mov r8 = cr.ivr // clear IRR bit + add r2 = 8, gp + ;; +} +{ .mmi + srlz.d + mov cr.eoi = r0 // ACK the wake-up + add r3 = 16, gp + ;; +} +{ .mmi + srlz.d + rsm IA64_PSR_IC | IA64_PSR_I + mov r16 = (IA64_PBVM_RR << 8) | (IA64_PBVM_PAGE_SHIFT << 2) + ;; +} +{ .mmi + srlz.d + st8 [gp] = r2 // trace = 0x08 + dep.z r17 = IA64_PBVM_RR, 61, 3 + ;; +} +{ .mlx + mov rr[r17] = r16 + movl r18 = IA64_PBVM_PGTBL + ;; +} +{ .mmi + srlz.i + ;; + st8 [gp] = r3 // trace = 0x10 + nop 0 + ;; +} +{ .mmi + ld8 r16 = [r2], 16 // as_pgtbl_pte + ld8 r17 = [r3], 16 // as_pgtbl_itir + nop 0 + ;; +} +{ .mmi + mov cr.itir = r17 + mov cr.ifa = r18 + nop 0 + ;; +} +{ .mmi + srlz.d + ptr.d r18, r17 + nop 0 + ;; +} +{ .mmi + srlz.d + st8 [gp] = r2 // trace = 0x18 + mov r8 = r0 + ;; +} +{ .mmi + itr.d dtr[r8] = r16 + ;; + srlz.d + mov r9 = r0 + ;; +} +{ .mmi + ld8 r16 = [r2], 16 // as_text_va + st8 [gp] = r3 // trace = 0x20 + add r8 = 1, r8 + ;; +} +{ .mmi + ld8 r17 = [r3], 16 // as_text_pte + ld8 r18 = [r2], 16 // as_text_itir + nop 0 + ;; +} +{ .mmi + mov cr.ifa = r16 + mov cr.itir = r18 + nop 0 + ;; +} +{ .mmi + srlz.d + ptr.d r16, r18 + nop 0 + ;; +} +{ .mmi + srlz.d + st8 [gp] = r3 // trace = 0x30 + nop 0 + ;; +} +{ .mmi + itr.d dtr[r8] = r17 + ;; + srlz.d + nop 0 +} +{ .mmi + st8 [gp] = r2 // trace = 0x38 + ptr.i r16, r18 + add r8 = 1, r8 + ;; +} +{ .mmi + srlz.i + ;; + itr.i itr[r9] = r17 + nop 0 + ;; +} +{ .mmi + srlz.i + ;; + ld8 r16 = [r3], 16 // as_data_va + add r9 = 1, r9 + ;; +} +{ .mmi + st8 [gp] = r3 // trace = 0x40 + ld8 r17 = [r2], 16 // as_data_pte + nop 0 + ;; +} +{ .mmi + mov cr.ifa = r16 + ld8 r18 = [r3], 16 // as_data_itir + nop 0 + ;; +} +{ .mmi + mov cr.itir = r18 + ;; + srlz.d + nop 0 + ;; +} +{ .mmi + ptr.d r16, r18 + ;; + srlz.d + mov r19 = IA64_DCR_DEFAULT + ;; +} +{ .mmi + itr.d dtr[r8] = r17 + ;; + srlz.d + add r8 = 1, r8 + ;; +} +{ .mmi + st8 [gp] = r2 // trace = 0x48 + ;; + ld8 r16 = [r2], 16 // as_kstack + nop 0 +} +{ .mmi + ld8 r17 = [r3], 16 // as_kstack_top + mov cr.dcr = r19 + nop 0 + ;; +} +{ .mlx + srlz.i + movl r18 = IA64_PSR_BN | IA64_PSR_IT | IA64_PSR_DT | IA64_PSR_IC | \ + IA64_PSR_RT | IA64_PSR_DFH + ;; +} +{ .mlx + mov cr.ipsr = r18 + movl r19 = ia64_vector_table // set up IVT early + ;; +} +{ .mlx + mov cr.iva = r19 + movl r18 = 1f + ;; +} +{ .mmi + mov cr.iip = r18 + mov cr.ifs = r0 + nop 0 + ;; +} +{ .mmb + srlz.d + st8 [gp] = r2 // trace = 0x58 + rfi + ;; +} + + .align 32 +1: +{ .mlx + mov ar.bspstore = r16 + movl gp = __gp + ;; +} +{ .mmi + loadrs + add sp = -16, r17 + nop 0 + ;; +} +{ .mmi + mov ar.rsc = 3 + ;; + alloc r18 = ar.pfs, 0, 0, 0, 0 + ;; +} +{ .mib + nop 0 + nop 0 + br.call.sptk.few rp = ia64_ap_startup + ;; +} + /* NOT REACHED */ +9: +{ .mib + nop 0 + nop 0 + br.sptk 9b + ;; +} +END(os_boot_rendez) Modified: head/sys/ia64/ia64/mp_machdep.c ============================================================================== --- head/sys/ia64/ia64/mp_machdep.c Sat Apr 30 20:34:52 2011 (r221270) +++ head/sys/ia64/ia64/mp_machdep.c Sat Apr 30 20:49:00 2011 (r221271) @@ -47,6 +47,7 @@ __FBSDID("$FreeBSD$"); #include <sys/uuid.h> #include <machine/atomic.h> +#include <machine/bootinfo.h> #include <machine/cpu.h> #include <machine/fpu.h> #include <machine/intr.h> @@ -62,22 +63,18 @@ __FBSDID("$FreeBSD$"); #include <vm/vm_extern.h> #include <vm/vm_kern.h> +extern uint64_t bdata[]; + MALLOC_DEFINE(M_SMP, "SMP", "SMP related allocations"); void ia64_ap_startup(void); -#define LID_SAPIC(x) ((u_int)((x) >> 16)) -#define LID_SAPIC_ID(x) ((u_int)((x) >> 24) & 0xff) -#define LID_SAPIC_EID(x) ((u_int)((x) >> 16) & 0xff) -#define LID_SAPIC_SET(id,eid) (((id & 0xff) << 8 | (eid & 0xff)) << 16); -#define LID_SAPIC_MASK 0xffff0000UL - -/* Variables used by os_boot_rendez and ia64_ap_startup */ -struct pcpu *ap_pcpu; -void *ap_stack; -volatile int ap_delay; -volatile int ap_awake; -volatile int ap_spin; +#define SAPIC_ID_GET_ID(x) ((u_int)((x) >> 8) & 0xff) +#define SAPIC_ID_GET_EID(x) ((u_int)(x) & 0xff) +#define SAPIC_ID_SET(id, eid) ((u_int)(((id) & 0xff) << 8) | ((eid) & 0xff)) + +/* State used to wake and bootstrap APs. */ +struct ia64_ap_state ia64_ap_state; int ia64_ipi_ast; int ia64_ipi_highfp; @@ -87,6 +84,21 @@ int ia64_ipi_rndzvs; int ia64_ipi_stop; static u_int +sz2shft(uint64_t sz) +{ + uint64_t s; + u_int shft; + + shft = 12; /* Start with 4K */ + s = 1 << shft; + while (s < sz) { + shft++; + s <<= 1; + } + return (shft); +} + +static u_int ia64_ih_ast(struct thread *td, u_int xiv, struct trapframe *tf) { @@ -180,16 +192,27 @@ ia64_ap_startup(void) { uint64_t vhpt; - pcpup = ap_pcpu; + ia64_ap_state.as_trace = 0x100; + + ia64_set_rr(IA64_RR_BASE(5), (5 << 8) | (PAGE_SHIFT << 2) | 1); + ia64_set_rr(IA64_RR_BASE(6), (6 << 8) | (PAGE_SHIFT << 2)); + ia64_set_rr(IA64_RR_BASE(7), (7 << 8) | (PAGE_SHIFT << 2)); + ia64_srlz_d(); + + pcpup = ia64_ap_state.as_pcpu; ia64_set_k4((intptr_t)pcpup); + ia64_ap_state.as_trace = 0x108; + vhpt = PCPU_GET(md.vhpt); map_vhpt(vhpt); ia64_set_pta(vhpt + (1 << 8) + (pmap_vhpt_log2size << 2) + 1); ia64_srlz_i(); - ap_awake = 1; - ap_delay = 0; + ia64_ap_state.as_trace = 0x110; + + ia64_ap_state.as_awake = 1; + ia64_ap_state.as_delay = 0; map_pal_code(); map_gateway_page(); @@ -197,14 +220,14 @@ ia64_ap_startup(void) ia64_set_fpsr(IA64_FPSR_DEFAULT); /* Wait until it's time for us to be unleashed */ - while (ap_spin) + while (ia64_ap_state.as_spin) cpu_spinwait(); /* Initialize curthread. */ KASSERT(PCPU_GET(idlethread) != NULL, ("no idle thread")); PCPU_SET(curthread, PCPU_GET(idlethread)); - atomic_add_int(&ap_awake, 1); + atomic_add_int(&ia64_ap_state.as_awake, 1); while (!smp_started) cpu_spinwait(); @@ -253,18 +276,18 @@ cpu_mp_probe(void) } void -cpu_mp_add(u_int acpiid, u_int apicid, u_int apiceid) +cpu_mp_add(u_int acpi_id, u_int id, u_int eid) { struct pcpu *pc; - u_int64_t lid; void *dpcpu; - u_int cpuid; + u_int cpuid, sapic_id; - lid = LID_SAPIC_SET(apicid, apiceid); - cpuid = ((ia64_get_lid() & LID_SAPIC_MASK) == lid) ? 0 : smp_cpus++; + sapic_id = SAPIC_ID_SET(id, eid); + cpuid = (IA64_LID_GET_SAPIC_ID(ia64_get_lid()) == sapic_id) + ? 0 : smp_cpus++; KASSERT((all_cpus & (1UL << cpuid)) == 0, - ("%s: cpu%d already in CPU map", __func__, acpiid)); + ("%s: cpu%d already in CPU map", __func__, acpi_id)); if (cpuid != 0) { pc = (struct pcpu *)malloc(sizeof(*pc), M_SMP, M_WAITOK); @@ -274,23 +297,26 @@ cpu_mp_add(u_int acpiid, u_int apicid, u } else pc = pcpup; - pc->pc_acpi_id = acpiid; - pc->pc_md.lid = lid; - all_cpus |= (1UL << cpuid); + pc->pc_acpi_id = acpi_id; + pc->pc_md.lid = IA64_LID_SET_SAPIC_ID(sapic_id); + + all_cpus |= (1UL << pc->pc_cpuid); } void cpu_mp_announce() { struct pcpu *pc; + uint32_t sapic_id; int i; for (i = 0; i <= mp_maxid; i++) { pc = pcpu_find(i); if (pc != NULL) { + sapic_id = IA64_LID_GET_SAPIC_ID(pc->pc_md.lid); printf("cpu%d: ACPI Id=%x, SAPIC Id=%x, SAPIC Eid=%x", - i, pc->pc_acpi_id, LID_SAPIC_ID(pc->pc_md.lid), - LID_SAPIC_EID(pc->pc_md.lid)); + i, pc->pc_acpi_id, SAPIC_ID_GET_ID(sapic_id), + SAPIC_ID_GET_EID(sapic_id)); if (i == 0) printf(" (BSP)\n"); else *** DIFF OUTPUT TRUNCATED AT 1000 LINES ***
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201104302049.p3UKn1GO061687>