svn commit: r221271 - in head/sys: conf ia64/ia64 ia64/include

Marcel Moolenaar marcel at FreeBSD.org
Sat Apr 30 20:49:01 UTC 2011


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 ***


More information about the svn-src-all mailing list