Home | History | Annotate | Download | only in X64
      1 ;------------------------------------------------------------------------------
      2 ; X64 assembly file for AP startup vector.
      3 ;
      4 ; Copyright (c) 2009 - 2010, Intel Corporation. All rights reserved.<BR>
      5 ; This program and the accompanying materials
      6 ; are licensed and made available under the terms and conditions of the BSD License
      7 ; which accompanies this distribution.  The full text of the license may be found at
      8 ; http://opensource.org/licenses/bsd-license.php
      9 ;
     10 ; THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
     11 ; WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
     12 ;
     13 ;------------------------------------------------------------------------------
     14 
     15 .code
     16 
     17 include  AsmInclude.inc
     18 ;-------------------------------------------------------------------------------------
     19 
     20 ;-------------------------------------------------------------------------------------
     21 ;RendezvousFunnelProc  procedure follows. All APs execute their procedure. This
     22 ;procedure serializes all the AP processors through an Init sequence. It must be
     23 ;noted that APs arrive here very raw...ie: real mode, no stack.
     24 ;ALSO THIS PROCEDURE IS EXECUTED BY APs ONLY ON 16 BIT MODE. HENCE THIS PROC
     25 ;IS IN MACHINE CODE.
     26 ;-------------------------------------------------------------------------------------
     27 ;RendezvousFunnelProc (&WakeUpBuffer,MemAddress);
     28 
     29 RendezvousFunnelProc   PROC  PUBLIC
     30 RendezvousFunnelProcStart::
     31 
     32 ; At this point CS = 0x(vv00) and ip= 0x0.
     33 
     34         db 8ch,  0c8h                 ; mov        ax,  cs
     35         db 8eh,  0d8h                 ; mov        ds,  ax
     36         db 8eh,  0c0h                 ; mov        es,  ax
     37         db 8eh,  0d0h                 ; mov        ss,  ax
     38         db 33h,  0c0h                 ; xor        ax,  ax
     39         db 8eh,  0e0h                 ; mov        fs,  ax
     40         db 8eh,  0e8h                 ; mov        gs,  ax
     41 
     42 ; Switch to flat mode.
     43 
     44         db 0BEh
     45         dw BufferStartLocation        ; mov        si, BufferStartLocation
     46         db 66h,  8Bh, 14h             ; mov        edx,dword ptr [si]          ; EDX is keeping the start address of wakeup buffer
     47 
     48         db 0BEh
     49         dw Cr3OffsetLocation          ; mov        si, Cr3Location
     50         db 66h,  8Bh, 0Ch             ; mov        ecx,dword ptr [si]          ; ECX is keeping the value of CR3
     51 
     52         db 0BEh
     53         dw GdtrLocation               ; mov        si, GdtrProfile
     54         db 66h                        ; db         66h
     55         db 2Eh,  0Fh, 01h, 14h        ; lgdt       fword ptr cs:[si]
     56 
     57         db 0BEh
     58         dw IdtrLocation               ; mov        si, IdtrProfile
     59         db 66h                        ; db         66h
     60         db 2Eh,  0Fh, 01h, 1Ch        ; lidt       fword ptr cs:[si]
     61 
     62         db 33h,  0C0h                 ; xor        ax,  ax
     63         db 8Eh,  0D8h                 ; mov        ds,  ax
     64 
     65         db 0Fh,  20h, 0C0h            ; mov        eax, cr0                    ; Get control register 0
     66         db 66h,  83h, 0C8h, 01h       ; or         eax, 000000001h             ; Set PE bit (bit #0)
     67         db 0Fh,  22h, 0C0h            ; mov        cr0, eax
     68 
     69 FLAT32_JUMP::
     70 
     71         db 66h,  67h, 0EAh            ; far jump
     72         dd 0h                         ; 32-bit offset
     73         dw 20h                        ; 16-bit selector
     74 
     75 ProtectedModeStart::
     76 
     77         db 66h,  0B8h, 18h,  00h      ; mov        ax,  18h
     78         db 66h,  8Eh,  0D8h           ; mov        ds,  ax
     79         db 66h,  8Eh,  0C0h           ; mov        es,  ax
     80         db 66h,  8Eh,  0E0h           ; mov        fs,  ax
     81         db 66h,  8Eh,  0E8h           ; mov        gs,  ax
     82         db 66h,  8Eh,  0D0h           ; mov        ss,  ax                     ; Flat mode setup.
     83 
     84         db 0Fh,  20h,  0E0h           ; mov        eax, cr4
     85         db 0Fh,  0BAh, 0E8h, 05h      ; bts        eax, 5
     86         db 0Fh,  22h,  0E0h           ; mov        cr4, eax
     87 
     88         db 0Fh,  22h,  0D9h           ; mov        cr3, ecx
     89 
     90         db 8Bh,  0F2h                 ; mov        esi, edx                    ; Save wakeup buffer address
     91 
     92         db 0B9h
     93         dd 0C0000080h                 ; mov        ecx, 0c0000080h             ; EFER MSR number.
     94         db 0Fh,  32h                  ; rdmsr                                  ; Read EFER.
     95         db 0Fh,  0BAh, 0E8h, 08h      ; bts        eax, 8                      ; Set LME=1.
     96         db 0Fh,  30h                  ; wrmsr                                  ; Write EFER.
     97 
     98         db 0Fh,  20h,  0C0h           ; mov        eax, cr0                    ; Read CR0.
     99         db 0Fh,  0BAh, 0E8h, 1Fh      ; bts        eax, 31                     ; Set PG=1.
    100         db 0Fh,  22h,  0C0h           ; mov        cr0, eax                    ; Write CR0.
    101 
    102 LONG_JUMP::
    103 
    104         db 67h,  0EAh                 ; far jump
    105         dd 0h                         ; 32-bit offset
    106         dw 38h                        ; 16-bit selector
    107 
    108 LongModeStart::
    109 
    110         mov         ax,  30h
    111         mov         ds,  ax
    112         mov         es,  ax
    113         mov         ss,  ax
    114 
    115         ;
    116         ; ProgramStack
    117         ;
    118         mov         ecx, 1bh                          ; Read IA32_APIC_BASE MSR
    119         rdmsr
    120 
    121         bt          eax, 10                           ; Check for x2apic mode
    122         jnc         LegacyApicMode
    123         mov         ecx, 802h                         ; Read APIC_ID
    124         rdmsr
    125         mov         ebx, eax                          ; ebx == apicid
    126         jmp         GetCpuNumber
    127 
    128 LegacyApicMode::
    129 
    130         and         eax, 0fffff000h
    131         add         eax, 20h
    132         mov         ebx, dword ptr [eax]
    133         shr         ebx, 24                           ; ebx == apicid
    134 
    135 GetCpuNumber::
    136 
    137         xor         rcx, rcx
    138         mov         edi, esi
    139         add         edi, ProcessorNumberLocation
    140         mov         ecx, dword ptr [edi + 4 * ebx]    ; RCX = CpuNumber
    141 
    142         mov         edi, esi
    143         add         edi, StackSizeLocation
    144         mov         rax, qword ptr [edi]
    145         inc         rcx
    146         mul         rcx                               ; RAX = StackSize * (CpuNumber + 1)
    147 
    148         mov         edi, esi
    149         add         edi, StackStartAddressLocation
    150         mov         rbx, qword ptr [edi]
    151         add         rax, rbx                          ; RAX = StackStart + StackSize * (CpuNumber + 1)
    152 
    153         mov         rsp, rax
    154 
    155         ;
    156         ; Call C Function
    157         ;
    158         mov         edi, esi
    159         add         edi, CProcedureLocation
    160         mov         rax, qword ptr [edi]
    161 
    162         test        rax, rax
    163         jz          GoToSleep
    164 
    165         sub         rsp, 20h
    166         call        rax
    167         add         rsp, 20h
    168 
    169 GoToSleep::
    170 
    171         cli
    172         hlt
    173         jmp         $-2
    174 
    175 RendezvousFunnelProc   ENDP
    176 RendezvousFunnelProcEnd::
    177 
    178 
    179 ;-------------------------------------------------------------------------------------
    180 ;  AsmGetAddressMap (&AddressMap);
    181 ;-------------------------------------------------------------------------------------
    182 AsmGetAddressMap   PROC
    183 
    184         mov         rax, offset RendezvousFunnelProcStart
    185         mov         qword ptr [rcx], rax
    186         mov         qword ptr [rcx+8h], ProtectedModeStart - RendezvousFunnelProcStart
    187         mov         qword ptr [rcx+10h], FLAT32_JUMP - RendezvousFunnelProcStart
    188         mov         qword ptr [rcx+18h], LongModeStart - RendezvousFunnelProcStart
    189         mov         qword ptr [rcx+20h], LONG_JUMP - RendezvousFunnelProcStart
    190         mov         qword ptr [rcx+28h], RendezvousFunnelProcEnd - RendezvousFunnelProcStart
    191 
    192         ret
    193 
    194 AsmGetAddressMap   ENDP
    195 
    196 END
    197