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