windows-nt/Source/XPSP1/NT/base/boot/efi/ia64/miscs.s
2020-09-26 16:20:57 +08:00

583 lines
12 KiB
ArmAsm
Raw Permalink Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

//++
//
// 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)