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 + -
显示快捷键?