Home | History | Annotate | Download | only in Ia32
      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 .686p
     22 .model  flat
     23 
     24 include  MpEqu.inc
     25 InitializeFloatingPointUnits PROTO C
     26 
     27 .code
     28 
     29 ;-------------------------------------------------------------------------------------
     30 ;RendezvousFunnelProc  procedure follows. All APs execute their procedure. This
     31 ;procedure serializes all the AP processors through an Init sequence. It must be
     32 ;noted that APs arrive here very raw...ie: real mode, no stack.
     33 ;ALSO THIS PROCEDURE IS EXECUTED BY APs ONLY ON 16 BIT MODE. HENCE THIS PROC
     34 ;IS IN MACHINE CODE.
     35 ;-------------------------------------------------------------------------------------
     36 RendezvousFunnelProc   PROC  PUBLIC
     37 RendezvousFunnelProcStart::
     38 ; At this point CS = 0x(vv00) and ip= 0x0.
     39 ; Save BIST information to ebp firstly
     40     db 66h,  08bh, 0e8h                 ; mov        ebp, eax    ; save BIST information
     41 
     42     db 8ch,0c8h                         ; mov        ax,cs
     43     db 8eh,0d8h                         ; mov        ds,ax
     44     db 8eh,0c0h                         ; mov        es,ax
     45     db 8eh,0d0h                         ; mov        ss,ax
     46     db 33h,0c0h                         ; xor        ax,ax
     47     db 8eh,0e0h                         ; mov        fs,ax
     48     db 8eh,0e8h                         ; mov        gs,ax
     49 
     50     db 0BEh                             ; opcode of mov si, mem16
     51     dw BufferStartLocation              ; mov        si, BufferStartLocation
     52     db 66h,  8Bh, 1Ch                   ; mov        ebx,dword ptr [si]
     53 
     54     db 0BFh                             ; opcode of mov di, mem16
     55     dw PmodeOffsetLocation              ; mov        di, PmodeOffsetLocation
     56     db 66h,  8Bh, 05h                   ; mov        eax,dword ptr [di]
     57     db 8Bh,  0F8h                       ; mov        di, ax
     58     db 83h,  0EFh,06h                   ; sub        di, 06h
     59     db 66h,  03h, 0C3h                  ; add        eax, ebx
     60     db 66h,  89h, 05h                   ; mov        dword ptr [di],eax
     61 
     62     db 0BEh                             ; opcode of mov si, mem16
     63     dw GdtrLocation                     ; mov        si, GdtrLocation
     64     db 66h                              ; db         66h
     65     db 2Eh,  0Fh, 01h, 14h              ; lgdt       fword ptr cs:[si]
     66 
     67     db 0BEh
     68     dw IdtrLocation                     ; mov        si, IdtrLocation
     69     db 66h                              ; db         66h
     70     db 2Eh,0Fh, 01h, 1Ch                ; lidt       fword ptr cs:[si]
     71 
     72     db 33h,  0C0h                       ; xor        ax,  ax
     73     db 8Eh,  0D8h                       ; mov        ds,  ax
     74 
     75     db 0Fh,  20h, 0C0h                  ; mov        eax, cr0            ;Get control register 0
     76     db 66h,  83h, 0C8h, 03h             ; or         eax, 000000003h     ;Set PE bit (bit #0) & MP
     77     db 0Fh,  22h, 0C0h                  ; mov        cr0, eax
     78 
     79     db 66h,  67h, 0EAh                  ; far jump
     80     dd 0h                               ; 32-bit offset
     81     dw PROTECT_MODE_CS                  ; 16-bit selector
     82 
     83 Flat32Start::                           ; protected mode entry point
     84     mov        ax, PROTECT_MODE_DS
     85     mov        ds, ax
     86     mov        es, ax
     87     mov        fs, ax
     88     mov        gs, ax
     89     mov        ss, ax
     90 
     91     mov        esi, ebx
     92     mov        edi, esi
     93     add        edi, LockLocation
     94     mov        eax, NotVacantFlag
     95 
     96 TestLock:
     97     xchg       dword ptr [edi], eax
     98     cmp        eax, NotVacantFlag
     99     jz         TestLock
    100 
    101     mov        edi, esi
    102     add        edi, NumApsExecutingLoction
    103     inc        dword ptr [edi]
    104     mov        ebx, dword ptr [edi]
    105 
    106 ProgramStack:
    107     mov        edi, esi
    108     add        edi, StackSizeLocation
    109     mov        eax, dword ptr [edi]
    110     mov        edi, esi
    111     add        edi, StackStartAddressLocation
    112     add        eax, dword ptr [edi]
    113     mov        esp, eax
    114     mov        dword ptr [edi], eax
    115 
    116 Releaselock:
    117     mov        eax, VacantFlag
    118     mov        edi, esi
    119     add        edi, LockLocation
    120     xchg       dword ptr [edi], eax
    121 
    122 CProcedureInvoke:
    123     push       ebp               ; push BIST data at top of AP stack
    124     xor        ebp, ebp          ; clear ebp for call stack trace
    125     push       ebp
    126     mov        ebp, esp
    127 
    128     mov        eax, InitializeFloatingPointUnits
    129     call       eax               ; Call assembly function to initialize FPU per UEFI spec
    130 
    131     push       ebx               ; Push NumApsExecuting
    132     mov        eax, esi
    133     add        eax, LockLocation
    134     push       eax               ; push address of exchange info data buffer
    135 
    136     mov        edi, esi
    137     add        edi, ApProcedureLocation
    138     mov        eax, dword ptr [edi]
    139 
    140     call       eax               ; invoke C function
    141 
    142     jmp        $                  ; never reach here
    143 
    144 RendezvousFunnelProc   ENDP
    145 RendezvousFunnelProcEnd::
    146 
    147 ;-------------------------------------------------------------------------------------
    148 ;  AsmGetAddressMap (&AddressMap);
    149 ;-------------------------------------------------------------------------------------
    150 AsmGetAddressMap   PROC  near C  PUBLIC
    151     pushad
    152     mov        ebp,esp
    153 
    154     mov        ebx, dword ptr [ebp+24h]
    155     mov        dword ptr [ebx], RendezvousFunnelProcStart
    156     mov        dword ptr [ebx +  4h], Flat32Start - RendezvousFunnelProcStart
    157     mov        dword ptr [ebx +  8h], 0
    158     mov        dword ptr [ebx + 0ch], RendezvousFunnelProcEnd - RendezvousFunnelProcStart
    159 
    160     popad
    161     ret
    162 AsmGetAddressMap   ENDP
    163 
    164 PAUSE32   MACRO
    165     DB      0F3h
    166     DB      090h
    167     ENDM
    168 
    169 ;-------------------------------------------------------------------------------------
    170 ;AsmExchangeRole procedure follows. This procedure executed by current BSP, that is
    171 ;about to become an AP. It switches it'stack with the current AP.
    172 ;AsmExchangeRole (IN   CPU_EXCHANGE_INFO    *MyInfo, IN   CPU_EXCHANGE_INFO    *OthersInfo);
    173 ;-------------------------------------------------------------------------------------
    174 AsmExchangeRole   PROC  near C  PUBLIC
    175     ; DO NOT call other functions in this function, since 2 CPU may use 1 stack
    176     ; at the same time. If 1 CPU try to call a function, stack will be corrupted.
    177     pushad
    178     mov        ebp,esp
    179 
    180     ; esi contains MyInfo pointer
    181     mov        esi, dword ptr [ebp+24h]
    182 
    183     ; edi contains OthersInfo pointer
    184     mov        edi, dword ptr [ebp+28h]
    185 
    186     ;Store EFLAGS, GDTR and IDTR register to stack
    187     pushfd
    188     mov        eax, cr4
    189     push       eax       ; push cr4 firstly
    190     mov        eax, cr0
    191     push       eax
    192 
    193     sgdt       fword ptr [esi+8]
    194     sidt       fword ptr [esi+14]
    195 
    196     ; Store the its StackPointer
    197     mov        dword ptr [esi+4],esp
    198 
    199     ; update its switch state to STORED
    200     mov        byte ptr [esi], CPU_SWITCH_STATE_STORED
    201 
    202 WaitForOtherStored:
    203     ; wait until the other CPU finish storing its state
    204     cmp        byte ptr [edi], CPU_SWITCH_STATE_STORED
    205     jz         OtherStored
    206     PAUSE32
    207     jmp        WaitForOtherStored
    208 
    209 OtherStored:
    210     ; Since another CPU already stored its state, load them
    211     ; load GDTR value
    212     lgdt       fword ptr [edi+8]
    213 
    214     ; load IDTR value
    215     lidt       fword ptr [edi+14]
    216 
    217     ; load its future StackPointer
    218     mov        esp, dword ptr [edi+4]
    219 
    220     ; update the other CPU's switch state to LOADED
    221     mov        byte ptr [edi], CPU_SWITCH_STATE_LOADED
    222 
    223 WaitForOtherLoaded:
    224     ; wait until the other CPU finish loading new state,
    225     ; otherwise the data in stack may corrupt
    226     cmp        byte ptr [esi], CPU_SWITCH_STATE_LOADED
    227     jz         OtherLoaded
    228     PAUSE32
    229     jmp        WaitForOtherLoaded
    230 
    231 OtherLoaded:
    232     ; since the other CPU already get the data it want, leave this procedure
    233     pop        eax
    234     mov        cr0, eax
    235     pop        eax
    236     mov        cr4, eax
    237     popfd
    238 
    239     popad
    240     ret
    241 AsmExchangeRole   ENDP
    242 
    243 AsmInitializeGdt   PROC  near C  PUBLIC
    244   push         ebp
    245   mov          ebp, esp
    246   pushad
    247   mov          edi, [ebp + 8]      ; Load GDT register
    248 
    249   mov          ax,cs               ; Get the selector data from our code image
    250   mov          es,ax
    251   lgdt         FWORD PTR es:[edi]  ; and update the GDTR
    252 
    253   push         PROTECT_MODE_CS
    254   lea          eax, SetCodeSelectorFarJump
    255   push         eax
    256   retf
    257 SetCodeSelectorFarJump:
    258   mov          ax, PROTECT_MODE_DS ; Update the Base for the new selectors, too
    259   mov          ds, ax
    260   mov          es, ax
    261   mov          fs, ax
    262   mov          gs, ax
    263   mov          ss, ax
    264 
    265   popad
    266   pop          ebp
    267   ret
    268 AsmInitializeGdt  ENDP
    269 
    270 END
    271