asmfuncs.s
来自「EFI BIOS是Intel提出的下一代的BIOS标准。这里上传的Edk源代码是」· S 代码 · 共 1,390 行 · 第 1/4 页
S
1,390 行
NESTED_SETUP(3,2+4,3,0)
mov loc2=SLOT0 // loc2 = slot index
mov loc5=in0;; // loc5 = runtime address of bundle
mov in0=1;; // in0 = success
RelocateBundleNextSlot:
cmp.ge p14, p15 = SLOT2, loc2;; // Check if maximum slot
(p15) br.sptk.few RelocateBundleDone
mov out0=loc5;; // out0 = runtime address of bundle
br.call.sptk.few b0 = GetTemplate
mov loc3=out0;; // loc3 = instruction template
mov out0=loc5 // out0 = runtime address of bundle
mov out1=loc2;; // out1 = instruction slot number
br.call.sptk.few b0 = GetSlot
mov loc4=out0;; // loc4 = instruction encoding
mov out0=loc4 // out0 = instuction encoding
mov out1=loc2 // out1 = instruction slot number
mov out2=loc3;; // out2 = instruction template
br.call.sptk.few b0 = IsSlotBranch
cmp.eq p14, p15 = 1, out0;; // Check if branch slot
(p15) add loc2=1,loc2 // Increment slot
(p15) br.sptk.few RelocateBundleNextSlot
mov out0=loc4 // out0 = instuction encoding
mov out1=in1 // out1 = IP address of previous location
mov out2=in2;; // out2 = IP address of new location
br.call.sptk.few b0 = RelocateSlot
cmp.eq p14, p15 = 1, out1;; // Check if relocated slot
(p15) mov in0=0 // in0 = failure
(p15) br.sptk.few RelocateBundleDone
mov out2=out0;; // out2 = instruction encoding
mov out0=loc5 // out0 = runtime address of bundle
mov out1=loc2;; // out1 = instruction slot number
br.call.sptk.few b0 = SetSlot
add loc2=1,loc2;; // Increment slot
br.sptk.few RelocateBundleNextSlot
RelocateBundleDone:
NESTED_RETURN
.endp RelocateBundle
/////////////////////////////////////////////
//
// Name:
// RelocateSlot
//
// Description:
// Relocates an instruction bundle by updating any ip-relative branch instructions.
//
// Arguments:
// in0 - Instruction encoding (41-bits, right justified)
// in1 - IP address of previous location of bundle
// in2 - IP address of new location of bundle
//
// Returns:
// in0 - Instruction encoding (41-bits, right justified)
// in1 - 1 if successful otherwise 0
//
// Notes:
// This procedure is a leaf routine
//
.proc RelocateSlot
RelocateSlot:
NESTED_SETUP(3,2+5,0,0)
extr.u loc2=in0, 37, 4;; // loc2 = instruction opcode
cmp.eq p14, p15 = 4, loc2;; // IP-relative branch (B1) or
// IP-relative counted branch (B2)
(p15) cmp.eq p14, p15 = 5, loc2;; // IP-relative call (B3)
(p15) cmp.eq p14, p15 = 7, loc2;; // IP-relative predict (B6)
(p15) mov in1=1 // Instruction did not need to be reencoded
(p15) br.sptk.few RelocateSlotDone
tbit.nz p14, p15 = in0, 36;; // put relative offset sign bit in p14
extr.u loc2=in0, 13, 20;; // loc2 = relative offset in instruction
(p14) movl loc3=0xfffffffffff00000;; // extend sign
(p14) or loc2=loc2, loc3;;
shl loc2=loc2,4;; // convert to byte offset instead of bundle offset
add loc3=loc2, in1;; // loc3 = physical address of branch target
(p14) sub loc2=r0,loc2;; // flip sign in loc2 if offset is negative
sub loc4=loc3,in2;; // loc4 = relative offset from new ip to branch target
cmp.lt p15, p14 = 0, loc4;; // get new sign bit
(p14) sub loc5=r0,loc4 // get absolute value of offset
(p15) mov loc5=loc4;;
movl loc6=0x0FFFFFF;; // maximum offset in bytes for ip-rel branch
cmp.gt p14, p15 = loc5, loc6;; // check to see we're not out of range for an ip-relative branch
(p14) br.sptk.few RelocateSlotError
cmp.lt p15, p14 = 0, loc4;; // store sign in p14 again
(p14) dep in0=1,in0,36,1 // store sign bit in instruction
(p15) dep in0=0,in0,36,1
shr loc4=loc4, 4;; // convert back to bundle offset
dep in0=loc4,in0,13,16;; // put first 16 bits of new offset into instruction
shr loc4=loc4,16;;
dep in0=loc4,in0,13+16,4 // put last 4 bits of new offset into instruction
mov in1=1;; // in1 = success
br.sptk.few RelocateSlotDone;;
RelocateSlotError:
mov in1=0;; // in1 = failure
RelocateSlotDone:
NESTED_RETURN
.endp RelocateSlot
/////////////////////////////////////////////
//
// Name:
// IsSlotBranch
//
// Description:
// Determines if the given instruction is a branch instruction.
//
// Arguments:
// in0 - Instruction encoding (41-bits, right justified)
// in1 - Instruction slot number
// in2 - Bundle template
//
// Returns:
// in0 - 1 if branch or 0 if not branch
//
// Notes:
// This procedure is a leaf routine
//
// IsSlotBranch recognizes all branch instructions by looking at the provided template.
// The instruction encoding is only passed to this routine for future expansion.
//
.proc IsSlotBranch
IsSlotBranch:
NESTED_SETUP (3,2+0,0,0)
mov in0=1;; // in0 = 1 which destroys the instruction
andcm in2=in2,in0;; // in2 = even template to reduce compares
mov in0=0;; // in0 = not a branch
cmp.eq p14, p15 = 0x16, in2;; // Template 0x16 is BBB
(p14) br.sptk.few IsSlotBranchTrue
cmp.eq p14, p15 = SLOT0, in1;; // Slot 0 has no other possiblities
(p14) br.sptk.few IsSlotBranchDone
cmp.eq p14, p15 = 0x12, in2;; // Template 0x12 is MBB
(p14) br.sptk.few IsSlotBranchTrue
cmp.eq p14, p15 = SLOT1, in1;; // Slot 1 has no other possiblities
(p14) br.sptk.few IsSlotBranchDone
cmp.eq p14, p15 = 0x10, in2;; // Template 0x10 is MIB
(p14) br.sptk.few IsSlotBranchTrue
cmp.eq p14, p15 = 0x18, in2;; // Template 0x18 is MMB
(p14) br.sptk.few IsSlotBranchTrue
cmp.eq p14, p15 = 0x1C, in2;; // Template 0x1C is MFB
(p14) br.sptk.few IsSlotBranchTrue
br.sptk.few IsSlotBranchDone
IsSlotBranchTrue:
mov in0=1;; // in0 = branch
IsSlotBranchDone:
NESTED_RETURN
.endp IsSlotBranch
/////////////////////////////////////////////
//
// Name:
// GetTemplate
//
// Description:
// Retrieves the instruction template for an instruction bundle
//
// Arguments:
// in0 - Runtime address of bundle
//
// Returns:
// in0 - Instruction template (5-bits, right-justified)
//
// Notes:
// This procedure is a leaf routine
//
.proc GetTemplate
GetTemplate:
NESTED_SETUP (1,2+2,0,0)
ld8 loc2=[in0], 0x8 // loc2 = first 8 bytes of branch bundle
movl loc3=MASK_0_4;; // loc3 = template mask
and loc2=loc2,loc3;; // loc2 = template, right justified
mov in0=loc2;; // in0 = template, right justified
NESTED_RETURN
.endp GetTemplate
/////////////////////////////////////////////
//
// Name:
// GetSlot
//
// Description:
// Gets the instruction encoding for an instruction slot and bundle
//
// Arguments:
// in0 - Runtime address of bundle
// in1 - Instruction slot (either 0, 1, or 2)
//
// Returns:
// in0 - Instruction encoding (41-bits, right justified)
//
// Notes:
// This procedure is a leaf routine
//
// Slot0 - [in0 + 0x8] Bits 45-5
// Slot1 - [in0 + 0x8] Bits 63-46 and [in0] Bits 22-0
// Slot2 - [in0] Bits 63-23
//
.proc GetSlot
GetSlot:
NESTED_SETUP (2,2+3,0,0)
ld8 loc2=[in0], 0x8;; // loc2 = first 8 bytes of branch bundle
ld8 loc3=[in0];; // loc3 = second 8 bytes of branch bundle
cmp.eq p14, p15 = 2, in1;; // check if slot 2 specified
(p14) br.cond.sptk.few GetSlot2;; // get slot 2
cmp.eq p14, p15 = 1, in1;; // check if slot 1 specified
(p14) br.cond.sptk.few GetSlot1;; // get slot 1
GetSlot0:
extr.u in0=loc2, 5, 45 // in0 = extracted slot 0
br.sptk.few GetSlotDone;;
GetSlot1:
extr.u in0=loc2, 46, 18 // in0 = bits 63-46 of loc2 right-justified
extr.u loc4=loc3, 0, 23;; // loc4 = bits 22-0 of loc3 right-justified
dep in0=loc4, in0, 18, 15;;
shr.u loc4=loc4,15;;
dep in0=loc4, in0, 33, 8;; // in0 = extracted slot 1
br.sptk.few GetSlotDone;;
GetSlot2:
extr.u in0=loc3, 23, 41;; // in0 = extracted slot 2
GetSlotDone:
NESTED_RETURN
.endp GetSlot
/////////////////////////////////////////////
//
// Name:
// SetSlot
//
// Description:
// Sets the instruction encoding for an instruction slot and bundle
//
// Arguments:
// in0 - Runtime address of bundle
// in1 - Instruction slot (either 0, 1, or 2)
// in2 - Instruction encoding (41-bits, right justified)
//
// Returns:
//
// Notes:
// This procedure is a leaf routine
//
.proc SetSlot
SetSlot:
NESTED_SETUP (3,2+3,0,0)
ld8 loc2=[in0], 0x8;; // loc2 = first 8 bytes of bundle
ld8 loc3=[in0];; // loc3 = second 8 bytes of bundle
cmp.eq p14, p15 = 2, in1;; // check if slot 2 specified
(p14) br.cond.sptk.few SetSlot2;; // set slot 2
cmp.eq p14, p15 = 1, in1;; // check if slot 1 specified
(p14) br.cond.sptk.few SetSlot1;; // set slot 1
SetSlot0:
dep loc2=0, loc2, 5, 41;; // remove old instruction from slot 0
shl loc4=in2, 5;; // loc4 = new instruction ready to be inserted
or loc2=loc2, loc4;; // loc2 = updated first 8 bytes of bundle
add loc4=0x8,in0;; // loc4 = address to store first 8 bytes of bundle
st8 [loc4]=loc2 // [loc4] = updated bundle
br.sptk.few SetSlotDone;;
;;
SetSlot1:
dep loc2=0, loc2, 46, 18 // remove old instruction from slot 1
dep loc3=0, loc3, 0, 23;;
shl loc4=in2, 46;; // loc4 = partial instruction ready to be inserted
or loc2=loc2, loc4;; // loc2 = updated first 8 bytes of bundle
add loc4=0x8,in0;; // loc4 = address to store first 8 bytes of bundle
st8 [loc4]=loc2;; // [loc4] = updated bundle
shr.u loc4=in2, 18;; // loc4 = partial instruction ready to be inserted
or loc3=loc3, loc4;; // loc3 = updated second 8 bytes of bundle
st8 [in0]=loc3;; // [in0] = updated bundle
br.sptk.few SetSlotDone;;
SetSlot2:
dep loc3=0, loc3, 23, 41;; // remove old instruction from slot 2
shl loc4=in2, 23;; // loc4 = instruction ready to be inserted
or loc3=loc3, loc4;; // loc3 = updated second 8 bytes of bundle
st8 [in0]=loc3;; // [in0] = updated bundle
SetSlotDone:
NESTED_RETURN
.endp SetSlot
/////////////////////////////////////////////
//
// Name:
// GetIva
//
// Description:
// C callable function to obtain the current value of IVA
//
// Returns:
// Current value if IVA
.global GetIva
.proc GetIva
GetIva:
mov r8=cr2;;
br.ret.sptk.many b0
.endp GetIva
/////////////////////////////////////////////
//
// Name:
// ProgramInterruptFlags
//
// Description:
// C callable function to enable/disable interrupts
//
// Returns:
// Previous state of psr.ic
//
.global ProgramInterruptFlags
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?