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:
parent
5feac8d228
commit
c94018bcd8
Notes:
svn2git
2020-12-20 02:59:44 +00:00
svn path=/projects/altix/; revision=219632
@ -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
|
||||
|
@ -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
|
||||
;;
|
||||
|
@ -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.
|
||||
*/
|
||||
|
@ -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.
|
||||
|
@ -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);
|
||||
|
@ -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
|
||||
|
Loading…
Reference in New Issue
Block a user