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.
This commit is contained in:
Marcel Moolenaar 2011-03-14 05:29:45 +00:00
parent 5feac8d228
commit c94018bcd8
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/projects/altix/; revision=219632
6 changed files with 110 additions and 84 deletions

View File

@ -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, 0x0c00)
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.eq p13,p0=4,r17 // RR4?
(p13) br.cond.sptk.few 4f
;;
cmp.ge p13,p0=5,r17 // RR0-RR5?
cmp.eq p15,p14=7,r17 // RR7->p15, RR6->p14
(p13) br.spnt 9f
cmp.eq p14,p15=7,r17 // RR7?
(p13) br.cond.spnt.few 9f
;;
(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
(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=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.eq p13,p0=4,r17 // RR4?
(p13) br.cond.sptk.few 4f
;;
cmp.ge p13,p0=5,r17 // RR0-RR5?
cmp.eq p15,p14=7,r17 // RR7->p15, RR6->p14
(p13) br.spnt 9f
cmp.eq p14,p15=7,r17 // RR7?
(p13) br.cond.spnt.few 9f
;;
(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
(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=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

View File

@ -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
;;

View File

@ -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.
*/

View File

@ -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.

View File

@ -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);

View File

@ -131,17 +131,6 @@
#define IA64_PHYS_TO_RR6(x) ((x) | IA64_RR_BASE(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