Home | History | Annotate | Download | only in X64
      1 ;------------------------------------------------------------------------------ ;
      2 ; Copyright (c) 2015, Intel Corporation. All rights reserved.<BR>
      3 ; This program and the accompanying materials
      4 ; are licensed and made available under the terms and conditions of the BSD License
      5 ; which accompanies this distribution.  The full text of the license may be found at
      6 ; http://opensource.org/licenses/bsd-license.php.
      7 ;
      8 ; THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
      9 ; WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
     10 ;
     11 ; Module Name:
     12 ;
     13 ;   MpFuncs32.asm
     14 ;
     15 ; Abstract:
     16 ;
     17 ;   This is the assembly code for MP support
     18 ;
     19 ;-------------------------------------------------------------------------------
     20 
     21 include  MpEqu.inc
     22 extern   InitializeFloatingPointUnits:PROC
     23 
     24 .code
     25 ;-------------------------------------------------------------------------------------
     26 ;RendezvousFunnelProc  procedure follows. All APs execute their procedure. This
     27 ;procedure serializes all the AP processors through an Init sequence. It must be
     28 ;noted that APs arrive here very raw...ie: real mode, no stack.
     29 ;ALSO THIS PROCEDURE IS EXECUTED BY APs ONLY ON 16 BIT MODE. HENCE THIS PROC
     30 ;IS IN MACHINE CODE.
     31 ;-------------------------------------------------------------------------------------
     32 RendezvousFunnelProc   PROC  PUBLIC
     33 RendezvousFunnelProcStart::
     34 ; At this point CS = 0x(vv00) and ip= 0x0.
     35 ; Save BIST information to ebp firstly
     36     db 66h,  08bh, 0e8h               ; mov        ebp, eax    ; save BIST information
     37 
     38     db 8ch,0c8h                       ; mov        ax,cs
     39     db 8eh,0d8h                       ; mov        ds,ax
     40     db 8eh,0c0h                       ; mov        es,ax
     41     db 8eh,0d0h                       ; mov        ss,ax
     42     db 33h,0c0h                       ; xor        ax,ax
     43     db 8eh,0e0h                       ; mov        fs,ax
     44     db 8eh,0e8h                       ; mov        gs,ax
     45 
     46     db 0BEh                           ; opcode of mov si, mem16
     47     dw BufferStartLocation            ; mov        si, BufferStartLocation
     48     db 66h,  8Bh, 1Ch                 ; mov        ebx,dword ptr [si]
     49 
     50     db 0BFh                           ; opcode of mov di, mem16
     51     dw PmodeOffsetLocation            ; mov        di, PmodeOffsetLocation
     52     db 66h,  8Bh, 05h                 ; mov        eax,dword ptr [di]
     53     db 8Bh,  0F8h                     ; mov        di, ax
     54     db 83h,  0EFh,06h                 ; sub        di, 06h
     55     db 66h,  03h, 0C3h                ; add        eax, ebx
     56     db 66h,  89h, 05h                 ; mov        dword ptr [di],eax
     57 
     58     db 0BFh                           ; opcode of mov di, mem16
     59     dw LmodeOffsetLocation            ; mov        di, LmodeOffsetLocation
     60     db 66h,  8Bh, 05h                 ; mov        eax,dword ptr [di]
     61     db 8Bh,  0F8h                     ; mov        di, ax
     62     db 83h,  0EFh,06h                 ; sub        di, 06h
     63     db 66h,  03h, 0C3h                ; add        eax, ebx
     64     db 66h,  89h, 05h                 ; mov        dword ptr [di],eax
     65 
     66     db 0BEh
     67     dw Cr3Location                    ; mov        si, Cr3Location
     68     db 66h,  8Bh, 0Ch                 ; mov        ecx,dword ptr [si]     ; ECX is keeping the value of CR3
     69 
     70     db 0BEh                           ; opcode of mov si, mem16
     71     dw GdtrLocation                   ; mov        si, GdtrLocation
     72     db 66h                            ; db         66h
     73     db 2Eh,  0Fh, 01h, 14h            ; lgdt       fword ptr cs:[si]
     74 
     75     db 0BEh
     76     dw IdtrLocation                   ; mov        si, IdtrLocation
     77     db 66h                            ; db         66h
     78     db 2Eh,0Fh, 01h, 1Ch              ; lidt       fword ptr cs:[si]
     79 
     80     db 33h,  0C0h                     ; xor        ax,  ax
     81     db 8Eh,  0D8h                     ; mov        ds,  ax
     82 
     83     db 0Fh,  20h, 0C0h                ; mov        eax, cr0               ;Get control register 0
     84     db 66h,  83h, 0C8h, 03h           ; or         eax, 000000003h        ;Set PE bit (bit #0) & MP
     85     db 0Fh,  22h, 0C0h                ; mov        cr0, eax
     86 
     87     db 66h,  67h, 0EAh                ; far jump
     88     dd 0h                             ; 32-bit offset
     89     dw PROTECT_MODE_CS                ; 16-bit selector
     90 
     91 Flat32Start::                         ; protected mode entry point
     92     mov        ax, PROTECT_MODE_DS
     93     mov        ds, ax
     94     mov        es, ax
     95     mov        fs, ax
     96     mov        gs, ax
     97     mov        ss, ax
     98 
     99     db 0Fh,  20h,  0E0h           ; mov        eax, cr4
    100     db 0Fh,  0BAh, 0E8h, 05h      ; bts        eax, 5
    101     db 0Fh,  22h,  0E0h           ; mov        cr4, eax
    102 
    103     db 0Fh,  22h,  0D9h           ; mov        cr3, ecx
    104 
    105     db 0B9h
    106     dd 0C0000080h                 ; mov        ecx, 0c0000080h     ; EFER MSR number.
    107     db 0Fh,  32h                  ; rdmsr                          ; Read EFER.
    108     db 0Fh,  0BAh, 0E8h, 08h      ; bts        eax, 8              ; Set LME=1.
    109     db 0Fh,  30h                  ; wrmsr                          ; Write EFER.
    110 
    111     db 0Fh,  20h,  0C0h           ; mov        eax, cr0            ; Read CR0.
    112     db 0Fh,  0BAh, 0E8h, 1Fh      ; bts        eax, 31             ; Set PG=1.
    113     db 0Fh,  22h,  0C0h           ; mov        cr0, eax            ; Write CR0.
    114 
    115 LONG_JUMP:
    116     db 67h,  0EAh                 ; far jump
    117     dd 0h                         ; 32-bit offset
    118     dw LONG_MODE_CS               ; 16-bit selector
    119 
    120 LongModeStart::
    121     mov        ax,  LONG_MODE_DS
    122     mov        ds,  ax
    123     mov        es,  ax
    124     mov        ss,  ax
    125 
    126     mov        esi, ebx
    127     mov        edi, esi
    128     add        edi, LockLocation
    129     mov        rax, NotVacantFlag
    130 
    131 TestLock:
    132     xchg       qword ptr [edi], rax
    133     cmp        rax, NotVacantFlag
    134     jz         TestLock
    135 
    136     mov        edi, esi
    137     add        edi, NumApsExecutingLoction
    138     inc        dword ptr [edi]
    139     mov        ebx, dword ptr [edi]
    140 
    141 ProgramStack:
    142     mov        edi, esi
    143     add        edi, StackSizeLocation
    144     mov        rax, qword ptr [edi]
    145     mov        edi, esi
    146     add        edi, StackStartAddressLocation
    147     add        rax, qword ptr [edi]
    148     mov        rsp, rax
    149     mov        qword ptr [edi], rax
    150 
    151 Releaselock:
    152     mov        rax, VacantFlag
    153     mov        edi, esi
    154     add        edi, LockLocation
    155     xchg       qword ptr [edi], rax
    156 
    157 CProcedureInvoke:
    158     push       rbp               ; push BIST data
    159     xor        rbp, rbp          ; clear ebp for call stack trace
    160     push       rbp
    161     mov        rbp, rsp
    162 
    163     mov        rax, InitializeFloatingPointUnits
    164     sub        rsp, 20h
    165     call       rax               ; Call assembly function to initialize FPU per UEFI spec
    166     add        rsp, 20h
    167 
    168     mov        edx, ebx          ; edx is NumApsExecuting
    169     mov        ecx, esi
    170     add        ecx, LockLocation ; rcx is address of exchange info data buffer
    171 
    172     mov        edi, esi
    173     add        edi, ApProcedureLocation
    174     mov        rax, qword ptr [edi]
    175 
    176     sub        rsp, 20h
    177     call       rax               ; invoke C function
    178     add        rsp, 20h
    179     jmp        $
    180 
    181 RendezvousFunnelProc   ENDP
    182 RendezvousFunnelProcEnd::
    183 
    184 ;-------------------------------------------------------------------------------------
    185 ;  AsmGetAddressMap (&AddressMap);
    186 ;-------------------------------------------------------------------------------------
    187 AsmGetAddressMap   PROC
    188     mov        rax, offset RendezvousFunnelProcStart
    189     mov        qword ptr [rcx], rax
    190     mov        qword ptr [rcx +  8h], Flat32Start - RendezvousFunnelProcStart
    191     mov        qword ptr [rcx + 10h], LongModeStart - RendezvousFunnelProcStart
    192     mov        qword ptr [rcx + 18h], RendezvousFunnelProcEnd - RendezvousFunnelProcStart
    193     ret
    194 AsmGetAddressMap   ENDP
    195 
    196 ;-------------------------------------------------------------------------------------
    197 ;AsmExchangeRole procedure follows. This procedure executed by current BSP, that is
    198 ;about to become an AP. It switches it'stack with the current AP.
    199 ;AsmExchangeRole (IN   CPU_EXCHANGE_INFO    *MyInfo, IN   CPU_EXCHANGE_INFO    *OthersInfo);
    200 ;-------------------------------------------------------------------------------------
    201 AsmExchangeRole   PROC
    202     ; DO NOT call other functions in this function, since 2 CPU may use 1 stack
    203     ; at the same time. If 1 CPU try to call a function, stack will be corrupted.
    204 
    205     push       rax
    206     push       rbx
    207     push       rcx
    208     push       rdx
    209     push       rsi
    210     push       rdi
    211     push       rbp
    212     push       r8
    213     push       r9
    214     push       r10
    215     push       r11
    216     push       r12
    217     push       r13
    218     push       r14
    219     push       r15
    220 
    221     mov        rax, cr0
    222     push       rax
    223 
    224     mov        rax, cr4
    225     push       rax
    226 
    227     ; rsi contains MyInfo pointer
    228     mov        rsi, rcx
    229 
    230     ; rdi contains OthersInfo pointer
    231     mov        rdi, rdx
    232 
    233     ;Store EFLAGS, GDTR and IDTR regiter to stack
    234     pushfq
    235     sgdt       fword ptr [rsi + 16]
    236     sidt       fword ptr [rsi + 26]
    237 
    238     ; Store the its StackPointer
    239     mov        qword ptr [rsi + 8], rsp
    240 
    241     ; update its switch state to STORED
    242     mov        byte ptr [rsi], CPU_SWITCH_STATE_STORED
    243 
    244 WaitForOtherStored:
    245     ; wait until the other CPU finish storing its state
    246     cmp        byte ptr [rdi], CPU_SWITCH_STATE_STORED
    247     jz         OtherStored
    248     pause
    249     jmp        WaitForOtherStored
    250 
    251 OtherStored:
    252     ; Since another CPU already stored its state, load them
    253     ; load GDTR value
    254     lgdt       fword ptr [rdi + 16]
    255 
    256     ; load IDTR value
    257     lidt       fword ptr [rdi + 26]
    258 
    259     ; load its future StackPointer
    260     mov        rsp, qword ptr [rdi + 8]
    261 
    262     ; update the other CPU's switch state to LOADED
    263     mov        byte ptr [rdi], CPU_SWITCH_STATE_LOADED
    264 
    265 WaitForOtherLoaded:
    266     ; wait until the other CPU finish loading new state,
    267     ; otherwise the data in stack may corrupt
    268     cmp        byte ptr [rsi], CPU_SWITCH_STATE_LOADED
    269     jz         OtherLoaded
    270     pause
    271     jmp        WaitForOtherLoaded
    272 
    273 OtherLoaded:
    274     ; since the other CPU already get the data it want, leave this procedure
    275     popfq
    276 
    277     pop        rax
    278     mov        cr4, rax
    279 
    280     pop        rax
    281     mov        cr0, rax
    282 
    283     pop        r15
    284     pop        r14
    285     pop        r13
    286     pop        r12
    287     pop        r11
    288     pop        r10
    289     pop        r9
    290     pop        r8
    291     pop        rbp
    292     pop        rdi
    293     pop        rsi
    294     pop        rdx
    295     pop        rcx
    296     pop        rbx
    297     pop        rax
    298 
    299     ret
    300 AsmExchangeRole   ENDP
    301 
    302 AsmInitializeGdt   PROC
    303     push       rbp
    304     mov        rbp, rsp
    305 
    306     lgdt       fword PTR [rcx]  ; update the GDTR
    307 
    308     sub        rsp, 0x10
    309     lea        rax, SetCodeSelectorFarJump
    310     mov        [rsp], rax
    311     mov        rdx, LONG_MODE_CS
    312     mov        [rsp + 4], dx    ; get new CS
    313     jmp        fword ptr [rsp]
    314 SetCodeSelectorFarJump:
    315     add        rsp, 0x10
    316 
    317     mov        rax, LONG_MODE_DS          ; get new DS
    318     mov        ds, ax
    319     mov        es, ax
    320     mov        fs, ax
    321     mov        gs, ax
    322     mov        ss, ax
    323 
    324     pop        rbp
    325     ret
    326 AsmInitializeGdt  ENDP
    327 
    328 END
    329