Home | History | Annotate | Download | only in IA32
      1 #------------------------------------------------------------------------------
      2 # IA32 assembly file for AP startup vector.
      3 #
      4 # Copyright (c) 2009 - 2012, 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 #define VacantFlag       0x0
     16 #define NotVacantFlag    0xff
     17 
     18 #define LockLocation     RendezvousFunnelProcEnd - RendezvousFunnelProcStart
     19 #define StackStart       RendezvousFunnelProcEnd - RendezvousFunnelProcStart + 0x04
     20 #define StackSize        RendezvousFunnelProcEnd - RendezvousFunnelProcStart + 0x08
     21 #define RendezvousProc   RendezvousFunnelProcEnd - RendezvousFunnelProcStart + 0x0C
     22 #define GdtrProfile      RendezvousFunnelProcEnd - RendezvousFunnelProcStart + 0x10
     23 #define IdtrProfile      RendezvousFunnelProcEnd - RendezvousFunnelProcStart + 0x16
     24 #define BufferStart      RendezvousFunnelProcEnd - RendezvousFunnelProcStart + 0x1C
     25 #define ProcessorNumber  RendezvousFunnelProcEnd - RendezvousFunnelProcStart + 0x20
     26 
     27 #-------------------------------------------------------------------------------------
     28 #RendezvousFunnelProc  procedure follows. All APs execute their procedure. This
     29 #procedure serializes all the AP processors through an Init sequence. It must be
     30 #noted that APs arrive here very raw...ie: real mode, no stack.
     31 #ALSO THIS PROCEDURE IS EXECUTED BY APs ONLY ON 16 BIT MODE. HENCE THIS PROC
     32 #IS IN MACHINE CODE.
     33 #-------------------------------------------------------------------------------------
     34 #RendezvousFunnelProc (&WakeUpBuffer,MemAddress);
     35 
     36 ASM_GLOBAL ASM_PFX(RendezvousFunnelProc)
     37 ASM_PFX(RendezvousFunnelProc):
     38 RendezvousFunnelProcStart:
     39 
     40 
     41 # At this point CS = 0x(vv00) and ip= 0x0.
     42 
     43         .byte 0x8c,0xc8               # mov        ax,  cs
     44         .byte 0x8e,0xd8               # mov        ds,  ax
     45         .byte 0x8e,0xc0               # mov        es,  ax
     46         .byte 0x8e,0xd0               # mov        ss,  ax
     47         .byte 0x33,0xc0               # xor        ax,  ax
     48         .byte 0x8e,0xe0               # mov        fs,  ax
     49         .byte 0x8e,0xe8               # mov        gs,  ax
     50 
     51 # Switch to flat mode.
     52 
     53         .byte 0xBE
     54         .word BufferStart
     55         .byte 0x66,0x8B,0xC           # mov        ecx,dword ptr [si]          ; ECX is keeping the start address of wakeup buffer
     56 
     57         .byte 0xFA                    # cli
     58         .byte 0xBE
     59         .word GdtrProfile
     60         .byte 0x66                    # db         66h
     61         .byte 0x2E,0xF,0x1,0x14       # lgdt       fword ptr cs:[si]
     62 
     63         .byte 0xBE
     64         .word IdtrProfile
     65         .byte 0x66                    # db         66h
     66         .byte 0x2E,0xF,0x1,0x1C       # lidt       fword ptr cs:[si]
     67 
     68         .byte 0x33,0xC0               # xor        ax,  ax
     69         .byte 0x8E,0xD8               # mov        ds,  ax
     70         .byte 0xF,0x20,0xC0           # mov        eax, cr0                    ; Get control register 0
     71         .byte 0x66,0x83,0xC8,0x1      # or         eax, 000000001h             ; Set PE bit (bit #0)
     72         .byte 0xF,0x22,0xC0           # mov        cr0, eax
     73 
     74 
     75 #step-4:
     76 
     77 FLAT32_JUMP:
     78         .byte 0x66
     79         .byte 0x67
     80         .byte 0xEA              # far jump
     81         .long 0x0
     82         .word 0x10
     83 
     84 ProtectedModeStart:                   # protected mode entry point
     85 
     86         movw        $0x8,%ax
     87         .byte       0x66
     88         movw        %ax,%ds
     89         .byte       0x66
     90         movw        %ax,%es
     91         .byte       0x66
     92         movw        %ax,%fs
     93         .byte       0x66
     94         movw        %ax,%gs
     95         .byte       0x66
     96         movw        %ax,%ss           # Flat mode setup.
     97 
     98         #
     99         # ProgramStack
    100         #
    101         movl        $0x1b, %ecx
    102         rdmsr
    103 
    104         btl         $10, %eax         # Check for x2apic mode
    105         jnc         LegacyApicMode
    106         movl        $0x802, %ecx      # Read APIC_ID
    107         rdmsr
    108         movl        %eax, %ebx        # ebx == apicid
    109         jmp         GetCpuNumber
    110 
    111 LegacyApicMode:
    112         andl        $0xfffff000, %eax
    113         addl        $0x20, %eax
    114         movl        (%eax), %ebx
    115         shrl        $24, %ebx         # ebx == apicid
    116 
    117 GetCpuNumber:
    118         xorl        %ecx, %ecx
    119         movl        %esi,%edi
    120         addl        $ProcessorNumber, %edi
    121         movl        (%edi, %ebx, 4), %ecx
    122 
    123         movl        %esi,%edi
    124         addl        $StackSize, %edi
    125         movl        (%edi), %eax
    126         incl        %ecx
    127         mull        %ecx
    128 
    129         movl        %esi,%edi
    130         addl        $StackStart, %edi
    131         movl        (%edi), %ebx
    132         addl        %ebx, %eax
    133 
    134         movl        %eax, %esp
    135 
    136         #
    137         # Call C Function
    138         #
    139         movl        %esi,%edi
    140         addl        $RendezvousProc, %edi
    141         movl        (%edi), %ebx
    142 
    143         testl       %ebx,%ebx
    144         jz          GoToSleep
    145         call        *%ebx                         # Call C function
    146 
    147 #Step-6: Sleep
    148 
    149 GoToSleep:
    150 
    151         cli
    152         hlt
    153         jmp         GoToSleep
    154 
    155 RendezvousFunnelProcEnd:
    156 #-------------------------------------------------------------------------------------
    157 #  AsmGetAddressMap (&AddressMap);
    158 #-------------------------------------------------------------------------------------
    159 ASM_GLOBAL ASM_PFX(AsmGetAddressMap)
    160 ASM_PFX(AsmGetAddressMap):
    161 
    162         pushal
    163         movl        %esp,%ebp
    164 
    165         movl        0x24(%ebp), %ebx
    166         movl        $RendezvousFunnelProcStart, (%ebx)
    167         movl        $(ProtectedModeStart - RendezvousFunnelProcStart), 0x4(%ebx)
    168         movl        $(FLAT32_JUMP - RendezvousFunnelProcStart), 0x8(%ebx)
    169         movl        $0, 0x0c(%ebx)
    170         movl        $0, 0x10(%ebx)
    171         movl        $(RendezvousFunnelProcEnd - RendezvousFunnelProcStart), 0x14(%ebx)
    172 
    173         popal
    174         ret
    175