svn commit: r219632 - in projects/altix/sys/ia64: ia64 include
Marcel Moolenaar
marcel at FreeBSD.org
Mon Mar 14 05:29:46 UTC 2011
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
More information about the svn-src-projects
mailing list