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 ***
_______________________________________________
svn-src-head@freebsd.org mailing list
http://lists.freebsd.org/mailman/listinfo/svn-src-head
To unsubscribe, send any mail to "svn-src-head-unsubscr...@freebsd.org"

Reply via email to