Skip site navigation (1)Skip section navigation (2)
Date:      Mon, 14 Mar 2011 05:29:46 +0000 (UTC)
From:      Marcel Moolenaar <marcel@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-projects@freebsd.org
Subject:   svn commit: r219632 - in projects/altix/sys/ia64: ia64 include
Message-ID:  <201103140529.p2E5Tkhc078301@svn.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: marcel
Date: Mon Mar 14 05:29:45 2011
New Revision: 219632
URL: http://svn.freebsd.org/changeset/base/219632

Log:
  o   Deal with unmapped PBVM in the alternate instruction and data TLB fault
      handlers.
  o   Put the IVT in its own section and keep the supporting code close.
  o   Make sure the VHPT is sized so that it can be mapped using a single
      translation.
  o   Map the PAL code and VHPT with a translation that has the right size.
      Assume the platform has a PAL code size that can be mapped with a
      single translations.
  o   Pass the pointer to the bootinfo structure as an argument to ia64_init().
  o   Get rid of LOG2_ID_PAGE_SIZE and IA64_ID_PAGE_SIZE. It was used to map
      the regions 6 & 7 and was as large as possible. The problem is that we
      can't support memory attributes easily if the granuratity is not a page.
      We need to support memory attributes because the new USB stack violates
      the BUS_DMA(9) interface.
  o   Update some comments...
  
  NOTE:	this is broken for SMP kernels, because the AP startup code hasn't
  	been updated yet.

Modified:
  projects/altix/sys/ia64/ia64/exception.S
  projects/altix/sys/ia64/ia64/locore.S
  projects/altix/sys/ia64/ia64/machdep.c
  projects/altix/sys/ia64/ia64/pmap.c
  projects/altix/sys/ia64/include/md_var.h
  projects/altix/sys/ia64/include/vmparam.h

Modified: projects/altix/sys/ia64/ia64/exception.S
==============================================================================
--- projects/altix/sys/ia64/ia64/exception.S	Mon Mar 14 05:18:27 2011	(r219631)
+++ projects/altix/sys/ia64/ia64/exception.S	Mon Mar 14 05:29:45 2011	(r219632)
@@ -101,7 +101,7 @@ xhead:	data8	xtrace
 
 #endif
 
-	.text
+	.section .text.ivt, "ax"
 
 /*
  * exception_save: save interrupted state
@@ -725,7 +725,7 @@ ivt_##name:					\
  * bundles per vector and 48 slots with 16 bundles per vector.
  */
 
-	.section .text.ivt,"ax"
+	.section .ivt, "ax"
 
 	.align	32768
 	.global ia64_vector_table
@@ -812,7 +812,7 @@ IVT_ENTRY(Instruction_TLB, 0x0400)
 3:	add	r20=24,r20		// next in chain
 	;;
 	ld8	r20=[r20]		// read chain
-	br.cond.sptk.few 2b		// loop
+	br.sptk	2b			// loop
 	;;
 9:	ssm	psr.dt
 	mov	pr=r17,0x1ffff		// restore predicates
@@ -898,7 +898,7 @@ IVT_ENTRY(Data_TLB, 0x0800)
 3:	add	r20=24,r20		// next in chain
 	;;
 	ld8	r20=[r20]		// read chain
-	br.cond.sptk.few 2b		// loop
+	br.sptk	2b			// loop
 	;;
 9:	ssm	psr.dt
 	mov	pr=r17,0x1ffff		// restore predicates
@@ -913,25 +913,40 @@ IVT_ENTRY(Alternate_Instruction_TLB, 0x0
 	mov	r18=pr			// save predicates
 	;;
 	extr.u	r17=r16,61,3		// get region number
+	mov	r19=PTE_PRESENT+PTE_ACCESSED+PTE_DIRTY+PTE_PL_KERN+PTE_AR_RWX
 	;;
-	cmp.ge	p13,p0=5,r17		// RR0-RR5?
-	cmp.eq	p15,p14=7,r17		// RR7->p15, RR6->p14
-(p13)	br.spnt	9f
+	cmp.eq	p13,p0=4,r17		// RR4?
+(p13)	br.cond.sptk.few	4f
 	;;
-(p15)	movl	r17=PTE_PRESENT+PTE_MA_WB+PTE_ACCESSED+PTE_DIRTY+PTE_PL_KERN+ \
-			PTE_AR_RX+PTE_ED
-(p14)	movl	r17=PTE_PRESENT+PTE_MA_UC+PTE_ACCESSED+PTE_DIRTY+PTE_PL_KERN+ \
-			PTE_AR_RX
+	cmp.ge	p13,p0=5,r17		// RR0-RR5?
+	cmp.eq	p14,p15=7,r17		// RR7?
+(p13)	br.cond.spnt.few	9f
 	;;
-	dep	r16=0,r16,50,14		// clear bits above PPN
+(p14)	add	r19=PTE_MA_WB,r19
+(p15)	add	r19=PTE_MA_UC,r19
+	dep	r17=0,r16,50,14		// clear bits above PPN
 	;;
-	dep	r16=r17,r16,0,12	// put pte bits in 0..11
+1:	dep	r16=r19,r17,0,12	// put pte bits in 0..11
 	;;
 	itc.i	r16
 	mov	pr=r18,0x1ffff		// restore predicates
 	;;
 	rfi
 	;;
+4:
+	add	r19=PTE_MA_WB,r19
+	movl	r17=IA64_PBVM_BASE
+	;;
+	sub	r17=r16,r17
+	movl	r16=IA64_PBVM_PGTBL
+	;;
+	extr.u	r17=r17,IA64_PBVM_PAGE_SHIFT,61-IA64_PBVM_PAGE_SHIFT
+	;;
+	shladd	r16=r17,3,r16
+	;;
+	ld8	r17=[r16]
+	br.sptk	1b
+	;;
 9:	mov	pr=r18,0x1ffff		// restore predicates
 	CALL(trap, 3, cr.ifa)
 IVT_END(Alternate_Instruction_TLB)
@@ -941,25 +956,40 @@ IVT_ENTRY(Alternate_Data_TLB, 0x1000)
 	mov	r18=pr			// save predicates
 	;;
 	extr.u	r17=r16,61,3		// get region number
+	mov	r19=PTE_PRESENT+PTE_ACCESSED+PTE_DIRTY+PTE_PL_KERN+PTE_AR_RWX
 	;;
-	cmp.ge	p13,p0=5,r17		// RR0-RR5?
-	cmp.eq	p15,p14=7,r17		// RR7->p15, RR6->p14
-(p13)	br.spnt	9f
+	cmp.eq	p13,p0=4,r17		// RR4?
+(p13)	br.cond.sptk.few	4f
 	;;
-(p15)	movl	r17=PTE_PRESENT+PTE_MA_WB+PTE_ACCESSED+PTE_DIRTY+PTE_PL_KERN+ \
-			PTE_AR_RW+PTE_ED
-(p14)	movl	r17=PTE_PRESENT+PTE_MA_UC+PTE_ACCESSED+PTE_DIRTY+PTE_PL_KERN+ \
-			PTE_AR_RW
+	cmp.ge	p13,p0=5,r17		// RR0-RR5?
+	cmp.eq	p14,p15=7,r17		// RR7?
+(p13)	br.cond.spnt.few	9f
 	;;
-	dep	r16=0,r16,50,14		// clear bits above PPN
+(p14)	add	r19=PTE_MA_WB,r19
+(p15)	add	r19=PTE_MA_UC,r19
+	dep	r17=0,r16,50,14		// clear bits above PPN
 	;;
-	dep	r16=r17,r16,0,12	// put pte bits in 0..11
+1:	dep	r16=r19,r17,0,12	// put pte bits in 0..11
 	;;
 	itc.d	r16
 	mov	pr=r18,0x1ffff		// restore predicates
 	;;
 	rfi
 	;;
+4:
+	add	r19=PTE_MA_WB,r19
+	movl	r17=IA64_PBVM_BASE
+	;;
+	sub	r17=r16,r17
+	movl	r16=IA64_PBVM_PGTBL
+	;;
+	extr.u	r17=r17,IA64_PBVM_PAGE_SHIFT,61-IA64_PBVM_PAGE_SHIFT
+	;;
+	shladd	r16=r17,3,r16
+	;;
+	ld8	r17=[r16]
+	br.sptk	1b
+	;;
 9:	mov	pr=r18,0x1ffff		// restore predicates
 	CALL(trap, 4, cr.ifa)
 IVT_END(Alternate_Data_TLB)
@@ -1045,13 +1075,13 @@ IVT_ENTRY(Data_Nested_TLB, 0x1400)
 {	.mib
 	srlz.d
 	cmp.eq		p13,p0=r29,r27
-(p12)	br.sptk		exception_save_restart
+(p12)	br.cond.sptk.few	exception_save_restart
 	;;
 }
 {	.mib
 	nop		0
 	nop		0
-(p13)	br.sptk		exception_restore_restart
+(p13)	br.cond.sptk.few	exception_restore_restart
 	;;
 }
 {	.mlx
@@ -1147,7 +1177,7 @@ IVT_ENTRY(Dirty_Bit, 0x2000)
 2:	add	r20=24,r20		// next in chain
 	;;
 	ld8	r20=[r20]		// read chain
-	br.cond.sptk.few 1b		// loop
+	br.sptk	1b			// loop
 	;;
 9:	ssm	psr.dt
 	mov	pr=r17,0x1ffff		// restore predicates
@@ -1221,7 +1251,7 @@ IVT_ENTRY(Instruction_Access_Bit, 0x2400
 2:	add	r20=24,r20		// next in chain
 	;;
 	ld8	r20=[r20]		// read chain
-	br.cond.sptk.few 1b		// loop
+	br.sptk	1b			// loop
 	;;
 9:	ssm	psr.dt
 	mov	pr=r17,0x1ffff		// restore predicates
@@ -1295,7 +1325,7 @@ IVT_ENTRY(Data_Access_Bit, 0x2800)
 2:	add	r20=24,r20		// next in chain
 	;;
 	ld8	r20=[r20]		// read chain
-	br.cond.sptk.few 1b		// loop
+	br.sptk	1b			// loop
 	;;
 9:	ssm	psr.dt
 	mov	pr=r17,0x1ffff		// restore predicates

Modified: projects/altix/sys/ia64/ia64/locore.S
==============================================================================
--- projects/altix/sys/ia64/ia64/locore.S	Mon Mar 14 05:18:27 2011	(r219631)
+++ projects/altix/sys/ia64/ia64/locore.S	Mon Mar 14 05:29:45 2011	(r219632)
@@ -77,17 +77,13 @@ ENTRY_NOPROFILE(__start, 1)
 	movl	gp=__gp			// find kernel globals
 	;;
 }
-{	.mlx
+
 	mov	ar.bspstore=r16		// switch backing store
-	movl	r16=bootinfo
 	;;
-}
-{	.mmi
-	st8	[r16]=r8		// save the PA of the bootinfo block
 	loadrs				// invalidate regs
 	mov	r17=IA64_DCR_DEFAULT
 	;;
-}
+
 {	.mmi
 	mov	cr.dcr=r17
 	mov	ar.rsc=3		// turn rse back on
@@ -101,13 +97,13 @@ ENTRY_NOPROFILE(__start, 1)
 	;;				// we just need to process fptrs
 }
 {	.mib
-	nop	0
+	mov	r9=r8			// Save pointer to bootinfo.
 	nop	0
 	br.call.sptk.many rp=_reloc
 	;;
 }
 {	.mib
-	nop	0
+	mov	out0=r9			// Pass pointer to bootinfo.
 	nop	0
 	br.call.sptk.many rp=ia64_init
 	;;

Modified: projects/altix/sys/ia64/ia64/machdep.c
==============================================================================
--- projects/altix/sys/ia64/ia64/machdep.c	Mon Mar 14 05:18:27 2011	(r219631)
+++ projects/altix/sys/ia64/ia64/machdep.c	Mon Mar 14 05:29:45 2011	(r219632)
@@ -127,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;
 
@@ -627,13 +628,13 @@ 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("mov   psr.l=%0" :: "r" (psr));
@@ -644,27 +645,38 @@ 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"(3), "r"(pte));
 	ia64_srlz_d();
-	__asm __volatile("itr.i	itr[%0]=%1" :: "r"(1), "r"(pte));
+	__asm __volatile("itr.i	itr[%0]=%1" :: "r"(3), "r"(pte));
 	__asm __volatile("mov	psr.l=%0" :: "r" (psr));
 	ia64_srlz_i();
 }
@@ -688,9 +700,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"(4), "r"(pte));
 	ia64_srlz_d();
-	__asm __volatile("itr.i	itr[%0]=%1" :: "r"(3), "r"(pte));
+	__asm __volatile("itr.i	itr[%0]=%1" :: "r"(4), "r"(pte));
 	__asm __volatile("mov	psr.l=%0" :: "r" (psr));
 	ia64_srlz_i();
 
@@ -736,7 +748,7 @@ calculate_frequencies(void)
 }
 
 struct ia64_init_return
-ia64_init(void)
+ia64_init(struct bootinfo *bi)
 {
 	struct ia64_init_return ret;
 	int phys_avail_cnt;
@@ -748,6 +760,8 @@ ia64_init(void)
 
 	/* NO OUTPUT ALLOWED UNTIL FURTHER NOTICE */
 
+	bootinfo = bi;
+
 	/*
 	 * TODO: Disable interrupts, floating point etc.
 	 * Maybe flush cache and tlb
@@ -770,6 +784,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;
 		}
@@ -819,7 +834,6 @@ ia64_init(void)
         ia64_set_rr(IA64_RR_BASE(7), (7 << 8) | (PAGE_SHIFT << 2));
         ia64_srlz_d();
 
-
 	/*
 	 * Wire things up so we can call the firmware.
 	 */

Modified: projects/altix/sys/ia64/ia64/pmap.c
==============================================================================
--- projects/altix/sys/ia64/ia64/pmap.c	Mon Mar 14 05:18:27 2011	(r219631)
+++ projects/altix/sys/ia64/ia64/pmap.c	Mon Mar 14 05:29:45 2011	(r219632)
@@ -102,17 +102,11 @@ __FBSDID("$FreeBSD$");
  * We reserve region ID 0 for the kernel and allocate the remaining
  * IDs for user pmaps.
  *
- * Region 0..4
- *	User virtually mapped
- *
- * Region 5
- *	Kernel virtually mapped
- *
- * Region 6
- *	Kernel physically mapped uncacheable
- *
- * Region 7
- *	Kernel physically mapped cacheable
+ * Region 0..3:	User virtually mapped [VHPT]
+ * Region 4:	Pre-Boot Virtual Memory (PBVM) and wired mappings [non-VHPT]
+ * Region 5:	Kernel Virtual Memory (KVM) [VHPT]
+ * Region 6:	Uncacheable identity mappings [non-VHPT]
+ * Region 7:	Cacheable identity mappings [non-VHPT]
  */
 
 /* XXX move to a header. */
@@ -346,9 +340,9 @@ pmap_bootstrap()
 	 * Setup RIDs. RIDs 0..7 are reserved for the kernel.
 	 *
 	 * We currently need at least 19 bits in the RID because PID_MAX
-	 * can only be encoded in 17 bits and we need RIDs for 5 regions
+	 * can only be encoded in 17 bits and we need RIDs for 4 regions
 	 * per process. With PID_MAX equalling 99999 this means that we
-	 * need to be able to encode 499995 (=5*PID_MAX).
+	 * need to be able to encode 399996 (=4*PID_MAX).
 	 * The Itanium processor only has 18 bits and the architected
 	 * minimum is exactly that. So, we cannot use a PID based scheme
 	 * in those cases. Enter pmap_ridmap...
@@ -396,13 +390,18 @@ pmap_bootstrap()
 		;
 	count = i+2;
 
+	/*
+	 * Determine a valid (mappable) VHPT size.
+	 */
 	TUNABLE_INT_FETCH("machdep.vhpt.log2size", &pmap_vhpt_log2size);
 	if (pmap_vhpt_log2size == 0)
 		pmap_vhpt_log2size = 20;
-	else if (pmap_vhpt_log2size < 15)
-		pmap_vhpt_log2size = 15;
-	else if (pmap_vhpt_log2size > 61)
-		pmap_vhpt_log2size = 61;
+	else if (pmap_vhpt_log2size < 16)
+		pmap_vhpt_log2size = 16;
+	else if (pmap_vhpt_log2size > 28)
+		pmap_vhpt_log2size = 28;
+	if (pmap_vhpt_log2size & 1)
+		pmap_vhpt_log2size--;
 
 	base = 0;
 	size = 1UL << pmap_vhpt_log2size;
@@ -456,11 +455,8 @@ pmap_bootstrap()
 	TAILQ_INIT(&kernel_pmap->pm_pvlist);
 	PCPU_SET(md.current_pmap, kernel_pmap);
 
-	/*
-	 * Region 5 is mapped via the vhpt.
-	 */
-	ia64_set_rr(IA64_RR_BASE(5),
-		    (5 << 8) | (PAGE_SHIFT << 2) | 1);
+	/* Region 5 is mapped via the vhpt. */
+	ia64_set_rr(IA64_RR_BASE(5), (5 << 8) | (PAGE_SHIFT << 2) | 1);
 
 	/*
 	 * Clear out any random TLB entries left over from booting.

Modified: projects/altix/sys/ia64/include/md_var.h
==============================================================================
--- projects/altix/sys/ia64/include/md_var.h	Mon Mar 14 05:18:27 2011	(r219631)
+++ projects/altix/sys/ia64/include/md_var.h	Mon Mar 14 05:29:45 2011	(r219632)
@@ -61,6 +61,7 @@ ia64_bsp_adjust(uint64_t bsp, int nslots
 #ifdef _KERNEL
 
 struct _special;
+struct bootinfo;
 struct pcpu;
 struct thread;
 struct trapframe;
@@ -93,7 +94,7 @@ int	ia64_highfp_drop(struct thread *);
 int	ia64_highfp_enable(struct thread *, struct trapframe *);
 int	ia64_highfp_save(struct thread *);
 int	ia64_highfp_save_ipi(void);
-struct ia64_init_return ia64_init(void);
+struct ia64_init_return ia64_init(struct bootinfo *);
 u_int	ia64_itc_freq(void);
 void	ia64_probe_sapics(void);
 void	ia64_sync_icache(vm_offset_t, vm_size_t);

Modified: projects/altix/sys/ia64/include/vmparam.h
==============================================================================
--- projects/altix/sys/ia64/include/vmparam.h	Mon Mar 14 05:18:27 2011	(r219631)
+++ projects/altix/sys/ia64/include/vmparam.h	Mon Mar 14 05:29:45 2011	(r219632)
@@ -132,17 +132,6 @@
 #define	IA64_PHYS_TO_RR7(x)	((x) | IA64_RR_BASE(7))
 
 /*
- * Page size of the identity mappings in region 7.
- */
-#ifndef LOG2_ID_PAGE_SIZE
-#define	LOG2_ID_PAGE_SIZE	28		/* 256M */
-#endif
-
-#define	IA64_ID_PAGE_SHIFT	(LOG2_ID_PAGE_SIZE)
-#define	IA64_ID_PAGE_SIZE	(1<<(LOG2_ID_PAGE_SIZE))
-#define	IA64_ID_PAGE_MASK	(IA64_ID_PAGE_SIZE-1)
-
-/*
  * The Itanium architecture defines that all implementations support at
  * least 51 virtual address bits (i.e. IMPL_VA_MSB=50). The unimplemented
  * bits are sign-extended from VA{IMPL_VA_MSB}. As such, there's a gap in



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201103140529.p2E5Tkhc078301>