583 lines
12 KiB
ArmAsm
583 lines
12 KiB
ArmAsm
|
//++
|
|||
|
//
|
|||
|
// Module name
|
|||
|
// miscs.s
|
|||
|
// Author
|
|||
|
// Allen Kay (allen.m.kay@intel.com) Jun-12-95
|
|||
|
// Description
|
|||
|
// Misc. assembly functions.
|
|||
|
//
|
|||
|
//---
|
|||
|
|
|||
|
#include "ksia64.h"
|
|||
|
|
|||
|
.file "miscs.s"
|
|||
|
|
|||
|
.global PalProcPhysical
|
|||
|
.global PalPhysicalBase
|
|||
|
.global PalTrPs
|
|||
|
.global IoPortPhysicalBase
|
|||
|
.global IoPortTrPs
|
|||
|
.global BdPcr
|
|||
|
|
|||
|
//
|
|||
|
// Setup CPU state to go from physical to virtual
|
|||
|
//
|
|||
|
|
|||
|
LEAF_ENTRY(MempGoVirtual)
|
|||
|
|
|||
|
rpT0 = t21
|
|||
|
rpT1 = t20
|
|||
|
rTrPs = t19
|
|||
|
rPPN = t18
|
|||
|
rPsr = t17
|
|||
|
|
|||
|
mov ar.rsc = r0
|
|||
|
mov rPsr = psr
|
|||
|
;;
|
|||
|
|
|||
|
rsm (1 << PSR_I)
|
|||
|
;;
|
|||
|
rsm (1 << PSR_IC)
|
|||
|
;;
|
|||
|
srlz.i
|
|||
|
;;
|
|||
|
|
|||
|
movl t0 = FPSR_FOR_KERNEL
|
|||
|
;;
|
|||
|
mov ar.fpsr = t0 // initialize fpsr
|
|||
|
;;
|
|||
|
|
|||
|
//
|
|||
|
// Initialize Region Registers
|
|||
|
//
|
|||
|
mov t1 = (START_GLOBAL_RID << RR_RID) | (PAGE_SHIFT << RR_PS) | RR_PS_VE
|
|||
|
movl t3 = KSEG0_BASE
|
|||
|
;;
|
|||
|
mov rr[t3] = t1
|
|||
|
|
|||
|
//
|
|||
|
// Invalidate all protection key registers
|
|||
|
//
|
|||
|
mov t1 = zero
|
|||
|
;;
|
|||
|
|
|||
|
Bl_PKRLoop:
|
|||
|
mov pkr[t1] = zero
|
|||
|
;;
|
|||
|
add t1 = 1, t1
|
|||
|
add t2 = 1, t2
|
|||
|
;;
|
|||
|
cmp.gtu pt0, pt1 = PKRNUM - 1, t1
|
|||
|
;;
|
|||
|
(pt0) br.cond.sptk.few.clr Bl_PKRLoop
|
|||
|
;;
|
|||
|
|
|||
|
#if 0
|
|||
|
//
|
|||
|
// Setup the 1-to-1 translation for the loader
|
|||
|
//
|
|||
|
movl t0 = BL_16M
|
|||
|
;;
|
|||
|
|
|||
|
movl t2 = ITIR_VALUE(0,PS_16M)
|
|||
|
mov cr.ifa = t0
|
|||
|
;;
|
|||
|
mov cr.itir = t2
|
|||
|
;;
|
|||
|
|
|||
|
mov t3 = BL_LOADER_INDEX
|
|||
|
movl t2 = TR_VALUE(1,BL_16M,3,0,1,1,0,1)
|
|||
|
;;
|
|||
|
|
|||
|
itr.d dtr[t3] = t2
|
|||
|
;;
|
|||
|
itr.i itr[t3] = t2
|
|||
|
|
|||
|
#endif
|
|||
|
|
|||
|
//
|
|||
|
//
|
|||
|
// Setup the first 16MB translation for the drivers.
|
|||
|
//
|
|||
|
movl t0 = KSEG0_BASE + BL_16M
|
|||
|
;;
|
|||
|
|
|||
|
movl t2 = ITIR_VALUE(0,PS_16M)
|
|||
|
mov cr.ifa = t0
|
|||
|
;;
|
|||
|
mov cr.itir = t2
|
|||
|
;;
|
|||
|
|
|||
|
mov t3 = DTR_DRIVER0_INDEX
|
|||
|
movl t2 = TR_VALUE(1,BL_16M,3,0,1,1,0,1)
|
|||
|
;;
|
|||
|
|
|||
|
itr.d dtr[t3] = t2
|
|||
|
;;
|
|||
|
itr.i itr[t3] = t2
|
|||
|
|
|||
|
//
|
|||
|
// Setup the second 16MB translation for the drivers.
|
|||
|
//
|
|||
|
movl t0 = KSEG0_BASE + BL_32M;
|
|||
|
;;
|
|||
|
|
|||
|
movl t2 = ITIR_VALUE(0,PS_16M)
|
|||
|
mov cr.ifa = t0
|
|||
|
;;
|
|||
|
mov cr.itir = t2
|
|||
|
;;
|
|||
|
|
|||
|
mov t3 = DTR_DRIVER1_INDEX
|
|||
|
movl t2 = TR_VALUE(1,BL_32M,3,0,1,1,0,1)
|
|||
|
;;
|
|||
|
|
|||
|
itr.d dtr[t3] = t2
|
|||
|
;;
|
|||
|
itr.i itr[t3] = t2
|
|||
|
|
|||
|
|
|||
|
//
|
|||
|
// Setup 16MB translation for kernel/hal binary.
|
|||
|
//
|
|||
|
movl t0 = KSEG0_BASE + BL_48M;
|
|||
|
;;
|
|||
|
|
|||
|
movl t2 = ITIR_VALUE(0,PS_16M)
|
|||
|
mov cr.ifa = t0
|
|||
|
;;
|
|||
|
mov cr.itir = t2
|
|||
|
;;
|
|||
|
|
|||
|
mov t3 = DTR_KERNEL_INDEX
|
|||
|
movl t2 = TR_VALUE(1,BL_48M,3,0,1,1,0,1)
|
|||
|
;;
|
|||
|
|
|||
|
itr.d dtr[t3] = t2
|
|||
|
;;
|
|||
|
itr.i itr[t3] = t2
|
|||
|
|
|||
|
//
|
|||
|
// Setup 16MB translation for decompression buffer used by setupldr.
|
|||
|
//
|
|||
|
movl t0 = KSEG0_BASE + BL_64M;
|
|||
|
;;
|
|||
|
|
|||
|
movl t2 = ITIR_VALUE(0,PS_16M)
|
|||
|
mov cr.ifa = t0
|
|||
|
;;
|
|||
|
mov cr.itir = t2
|
|||
|
;;
|
|||
|
|
|||
|
mov t3 = BL_DECOMPRESS_INDEX
|
|||
|
movl t2 = TR_VALUE(1,BL_64M,3,0,1,1,0,1)
|
|||
|
;;
|
|||
|
|
|||
|
itr.d dtr[t3] = t2
|
|||
|
;;
|
|||
|
itr.i itr[t3] = t2
|
|||
|
|
|||
|
//
|
|||
|
//
|
|||
|
// Setup translation for PAL.
|
|||
|
//
|
|||
|
movl rpT0 = PalPhysicalBase // PAL base addr
|
|||
|
movl rpT1 = PalTrPs // PAL page size
|
|||
|
movl t1 = VIRTUAL_PAL_BASE
|
|||
|
;;
|
|||
|
|
|||
|
ld8 t0 = [rpT0]
|
|||
|
ld8 rTrPs = [rpT1]
|
|||
|
mov cr.ifa = t1
|
|||
|
|
|||
|
movl t4 = IITR_ATTRIBUTE_PPN_MASK // construct GR[r]
|
|||
|
movl t5 = TR_VALUE(1,0,3,0,1,1,0,1)
|
|||
|
;;
|
|||
|
|
|||
|
shl t2 = rTrPs, ITIR_PS
|
|||
|
and t6 = t0, t4 // t6 is PPN in GR[r]
|
|||
|
;;
|
|||
|
|
|||
|
mov cr.itir = t2
|
|||
|
;;
|
|||
|
|
|||
|
mov t3 = DTR_HAL_INDEX // pre-assigned index
|
|||
|
or t2 = t5, t6 // t2 is now GR[r]
|
|||
|
;;
|
|||
|
|
|||
|
itr.d dtr[t3] = t2
|
|||
|
|
|||
|
//
|
|||
|
// Setup translation for I/O port space
|
|||
|
//
|
|||
|
movl rpT0 = IoPortPhysicalBase // IO Port base addr
|
|||
|
movl rpT1 = IoPortTrPs // IO Port page size
|
|||
|
movl t1 = VIRTUAL_IO_BASE
|
|||
|
;;
|
|||
|
|
|||
|
ld8 t0 = [rpT0]
|
|||
|
ld8 rTrPs = [rpT1]
|
|||
|
mov cr.ifa = t1
|
|||
|
|
|||
|
movl t4 = IITR_ATTRIBUTE_PPN_MASK // construct GR[r]
|
|||
|
movl t5 = TR_VALUE(1,0,3,0,1,1,4,1)
|
|||
|
;;
|
|||
|
|
|||
|
shl t2 = rTrPs, ITIR_PS
|
|||
|
and t6 = t0, t4 // t6 is PPN in GR[r]
|
|||
|
;;
|
|||
|
|
|||
|
mov cr.itir = t2
|
|||
|
;;
|
|||
|
|
|||
|
mov t3 = DTR_IO_PORT_INDEX // pre-assigned index
|
|||
|
or t2 = t5, t6 // t2 is now GR[r]
|
|||
|
;;
|
|||
|
|
|||
|
itr.d dtr[t3] = t2
|
|||
|
|
|||
|
//
|
|||
|
// Setup translation for BdPcr
|
|||
|
//
|
|||
|
movl t0 = BdPcr
|
|||
|
movl rTrPs = PS_4M
|
|||
|
;;
|
|||
|
|
|||
|
mov cr.ifa = t0
|
|||
|
|
|||
|
movl t4 = IITR_ATTRIBUTE_PPN_MASK // construct GR[r]
|
|||
|
movl t5 = TR_VALUE(1,0,3,0,1,1,0,1)
|
|||
|
;;
|
|||
|
|
|||
|
shl t2 = rTrPs, ITIR_PS
|
|||
|
and t6 = t0, t4 // t6 is PPN in GR[r]
|
|||
|
;;
|
|||
|
|
|||
|
mov cr.itir = t2
|
|||
|
;;
|
|||
|
|
|||
|
mov t3 = DTR_KIPCR_INDEX
|
|||
|
or t2 = t5, t6 // t2 is now GR[r]
|
|||
|
;;
|
|||
|
|
|||
|
itr.d dtr[t3] = t2
|
|||
|
|
|||
|
//
|
|||
|
// Turn on address translation, interrupt, psr.ed, protection key.
|
|||
|
//
|
|||
|
movl t1 = MASK_IA64(PSR_BN,1) | MASK_IA64(PSR_RT,1) | MASK_IA64(PSR_DT,1) | MASK_IA64(PSR_IC,1) | MASK_IA64(PSR_AC,1) | MASK_IA64(PSR_DB,1)
|
|||
|
;;
|
|||
|
or t1 = t1, rPsr
|
|||
|
;;
|
|||
|
mov cr.ipsr = t1
|
|||
|
|
|||
|
//
|
|||
|
// Initialize DCR to defer all speculation faults
|
|||
|
//
|
|||
|
mov t0 = DCR_DEFER_ALL
|
|||
|
;;
|
|||
|
mov cr.dcr = t0
|
|||
|
|
|||
|
//
|
|||
|
// Prepare to do RFI to return to the caller.
|
|||
|
//
|
|||
|
|
|||
|
|
|||
|
movl t0 = return_label
|
|||
|
;;
|
|||
|
|
|||
|
mov cr.iip = t0
|
|||
|
;;
|
|||
|
|
|||
|
mov cr.ifs = r0
|
|||
|
;;
|
|||
|
|
|||
|
rfi
|
|||
|
;;
|
|||
|
|
|||
|
return_label:
|
|||
|
mov v0 = zero
|
|||
|
;;
|
|||
|
|
|||
|
LEAF_RETURN
|
|||
|
LEAF_EXIT(MempGoVirtual)
|
|||
|
|
|||
|
|
|||
|
//
|
|||
|
// Flip psr.it bit from virtual to physical addressing mode.
|
|||
|
//
|
|||
|
|
|||
|
LEAF_ENTRY(FlipToPhysical)
|
|||
|
|
|||
|
rPsr = t17
|
|||
|
|
|||
|
rsm (1 << PSR_I)
|
|||
|
;;
|
|||
|
rsm (1 << PSR_IC)
|
|||
|
;;
|
|||
|
srlz.i
|
|||
|
;;
|
|||
|
|
|||
|
mov rPsr = psr
|
|||
|
movl t1 = MASK_IA64(PSR_RT,1) | MASK_IA64(PSR_DT,1)
|
|||
|
movl t2 = MASK_IA64(PSR_BN,1) | MASK_IA64(PSR_IC,1)
|
|||
|
;;
|
|||
|
|
|||
|
xor t1 = t1, rPsr
|
|||
|
;;
|
|||
|
or t1 = t1, t2
|
|||
|
;;
|
|||
|
mov cr.ipsr = t1
|
|||
|
|
|||
|
|
|||
|
|
|||
|
//
|
|||
|
// Prepare to do RFI to return to the caller.
|
|||
|
//
|
|||
|
|
|||
|
|
|||
|
movl t0 = FlipToPhysicalReturn
|
|||
|
;;
|
|||
|
|
|||
|
mov cr.iip = t0
|
|||
|
;;
|
|||
|
|
|||
|
mov cr.ifs = r0
|
|||
|
;;
|
|||
|
|
|||
|
rfi
|
|||
|
;;
|
|||
|
|
|||
|
FlipToPhysicalReturn:
|
|||
|
mov v0 = zero
|
|||
|
;;
|
|||
|
|
|||
|
LEAF_RETURN
|
|||
|
LEAF_EXIT(FlipToPhysical)
|
|||
|
|
|||
|
|
|||
|
//
|
|||
|
// Flip psr.it bit from physical to virtual addressing mode.
|
|||
|
//
|
|||
|
|
|||
|
LEAF_ENTRY(FlipToVirtual)
|
|||
|
|
|||
|
rPsr = t17
|
|||
|
|
|||
|
rsm (1 << PSR_I)
|
|||
|
;;
|
|||
|
rsm (1 << PSR_IC)
|
|||
|
;;
|
|||
|
srlz.i
|
|||
|
;;
|
|||
|
|
|||
|
mov rPsr = psr
|
|||
|
movl t1 = MASK_IA64(PSR_RT,1) | MASK_IA64(PSR_DT,1) | MASK_IA64(PSR_BN,1) | MASK_IA64(PSR_IC,1)
|
|||
|
;;
|
|||
|
|
|||
|
or t1 = t1, rPsr
|
|||
|
;;
|
|||
|
mov cr.ipsr = t1
|
|||
|
|
|||
|
|
|||
|
|
|||
|
//
|
|||
|
// Prepare to do RFI to return to the caller.
|
|||
|
//
|
|||
|
|
|||
|
|
|||
|
movl t0 = FlipToVirtualReturn
|
|||
|
;;
|
|||
|
|
|||
|
mov cr.iip = t0
|
|||
|
;;
|
|||
|
|
|||
|
mov cr.ifs = r0
|
|||
|
;;
|
|||
|
|
|||
|
rfi
|
|||
|
;;
|
|||
|
|
|||
|
FlipToVirtualReturn:
|
|||
|
mov v0 = zero
|
|||
|
;;
|
|||
|
|
|||
|
LEAF_RETURN
|
|||
|
LEAF_EXIT(FlipToVirtual)
|
|||
|
|
|||
|
|
|||
|
//
|
|||
|
// Clean up TR mappings used only by NT loader.
|
|||
|
//
|
|||
|
|
|||
|
LEAF_ENTRY(BlTrCleanUp)
|
|||
|
|
|||
|
rpT0 = t22
|
|||
|
rPsr = t17
|
|||
|
|
|||
|
//
|
|||
|
// purge BL_DECOMPRESS_INDEX
|
|||
|
//
|
|||
|
movl t0 = PS_16M << PS_SHIFT
|
|||
|
movl t1 = KSEG0_BASE + BL_64M
|
|||
|
;;
|
|||
|
|
|||
|
ptr.d t1, t0
|
|||
|
;;
|
|||
|
|
|||
|
#if 0
|
|||
|
//
|
|||
|
// purge BL_LOADER_INDEX
|
|||
|
//
|
|||
|
movl t0 = PS_16M << PS_SHIFT
|
|||
|
movl t1 = BL_16M
|
|||
|
;;
|
|||
|
|
|||
|
ptr.i t1, t0
|
|||
|
;;
|
|||
|
ptr.d t1, t0
|
|||
|
|
|||
|
#endif
|
|||
|
|
|||
|
//
|
|||
|
// purge BdPcr translation.
|
|||
|
//
|
|||
|
movl t0 = BdPcr
|
|||
|
movl t1 = PS_4M << PS_SHIFT
|
|||
|
;;
|
|||
|
|
|||
|
ptr.d t0, t1
|
|||
|
;;
|
|||
|
|
|||
|
//
|
|||
|
// Turn on address translation, interrupt, psr.ed, protection key.
|
|||
|
//
|
|||
|
rsm (1 << PSR_I)
|
|||
|
;;
|
|||
|
rsm (1 << PSR_IC)
|
|||
|
;;
|
|||
|
srlz.i
|
|||
|
;;
|
|||
|
|
|||
|
//
|
|||
|
// At this point, turn on psr.it so that we can pass control to
|
|||
|
// the kernel.
|
|||
|
//
|
|||
|
mov rPsr = psr
|
|||
|
movl t1 = MASK_IA64(PSR_BN,1) | MASK_IA64(PSR_IT,1) | MASK_IA64(PSR_RT,1) | MASK_IA64(PSR_DT,1) | MASK_IA64(PSR_IC,1) | MASK_IA64(PSR_AC,1) | MASK_IA64(PSR_DB,1)
|
|||
|
;;
|
|||
|
or t1 = t1, rPsr
|
|||
|
;;
|
|||
|
mov cr.ipsr = t1
|
|||
|
|
|||
|
//
|
|||
|
// Prepare to do RFI to return to the caller.
|
|||
|
//
|
|||
|
|
|||
|
movl t0 = BlTrCleanupReturn
|
|||
|
;;
|
|||
|
|
|||
|
mov cr.iip = t0
|
|||
|
;;
|
|||
|
|
|||
|
mov cr.ifs = r0
|
|||
|
;;
|
|||
|
|
|||
|
rfi
|
|||
|
;;
|
|||
|
|
|||
|
BlTrCleanupReturn:
|
|||
|
mov v0 = zero
|
|||
|
;;
|
|||
|
|
|||
|
LEAF_RETURN
|
|||
|
LEAF_EXIT (BlTrCleanUp)
|
|||
|
|
|||
|
|
|||
|
//++
|
|||
|
//
|
|||
|
// VOID
|
|||
|
// BlpPalProc(
|
|||
|
// LONGLONG a0, /* PAL function ID */
|
|||
|
// LONGLONG a1, /* PAL argument */
|
|||
|
// LONGLONG a2, /* PAL argument */
|
|||
|
// LONGLONG a3 /* PAL argument */
|
|||
|
// );
|
|||
|
//
|
|||
|
// Routine Description
|
|||
|
// This routine sets up the correct registers for input into PAL depending on
|
|||
|
// if the call uses static or stacked registers, turns off interrupts, ensures
|
|||
|
// the correct bank registers are being used and calls into the PAL.
|
|||
|
//
|
|||
|
// Return Values:
|
|||
|
// r8->r11 contain the 4 64-bit return values for PAL, r8 is the status
|
|||
|
//--
|
|||
|
|
|||
|
NESTED_ENTRY(BlpPalProc)
|
|||
|
NESTED_SETUP(4,3,4,0)
|
|||
|
PROLOGUE_END
|
|||
|
|
|||
|
// For both the static and stacked register conventions, load r28 with FunctionID
|
|||
|
|
|||
|
mov r28 = a0
|
|||
|
|
|||
|
// If static register calling convention (1-255, 512-767), copy arguments to r29->r31
|
|||
|
// Otherwise, copy to out0->out3 so they are in r32->r35 in PAL_PROC
|
|||
|
|
|||
|
mov t0 = a0
|
|||
|
;;
|
|||
|
shr t0 = t0, 8
|
|||
|
;;
|
|||
|
tbit.z pt0, pt1 = t0, 0
|
|||
|
;;
|
|||
|
|
|||
|
//
|
|||
|
// Static proc: do br not call
|
|||
|
//
|
|||
|
(pt0) mov r29 = a1
|
|||
|
(pt0) mov r30 = a2
|
|||
|
(pt0) mov r31 = a3
|
|||
|
|
|||
|
//
|
|||
|
// Stacked call
|
|||
|
//
|
|||
|
(pt1) mov out0 = a0
|
|||
|
(pt1) mov out1 = a1
|
|||
|
(pt1) mov out2 = a2
|
|||
|
(pt1) mov out3 = a3
|
|||
|
|
|||
|
// Load up the address of PAL_PROC and call it
|
|||
|
|
|||
|
addl t1 = @gprel(PalProcPhysical), gp
|
|||
|
;;
|
|||
|
ld8 t0 = [t1]
|
|||
|
;;
|
|||
|
mov bt0 = t0
|
|||
|
|
|||
|
// Call into PAL_PROC
|
|||
|
|
|||
|
(pt0) addl t1 = @ltoff(PalReturn), gp
|
|||
|
;;
|
|||
|
(pt0) ld8 t0 = [t1]
|
|||
|
;;
|
|||
|
(pt0) mov brp = t0
|
|||
|
;;
|
|||
|
// Disable interrupts
|
|||
|
|
|||
|
DISABLE_INTERRUPTS(loc2)
|
|||
|
;;
|
|||
|
srlz.d
|
|||
|
;;
|
|||
|
(pt0) br.sptk.many bt0
|
|||
|
;;
|
|||
|
(pt1) br.call.sptk brp = bt0
|
|||
|
;;
|
|||
|
PalReturn:
|
|||
|
// Restore the interrupt state
|
|||
|
|
|||
|
RESTORE_INTERRUPTS(loc2)
|
|||
|
;;
|
|||
|
NESTED_RETURN
|
|||
|
NESTED_EXIT(BlpPalProc)
|