1 ;------------------------------------------------------------------------------ ; 2 ; Copyright (c) 2016, 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 ; MpFuncs.nasm 14 ; 15 ; Abstract: 16 ; 17 ; This is the assembly code for Multi-processor S3 support 18 ; 19 ;------------------------------------------------------------------------------- 20 21 extern ASM_PFX(InitializeFloatingPointUnits) 22 23 %define VacantFlag 0x0 24 %define NotVacantFlag 0xff 25 26 %define LockLocation RendezvousFunnelProcEnd - RendezvousFunnelProcStart 27 %define StackStartAddressLocation LockLocation + 0x8 28 %define StackSizeLocation LockLocation + 0x10 29 %define CProcedureLocation LockLocation + 0x18 30 %define GdtrLocation LockLocation + 0x20 31 %define IdtrLocation LockLocation + 0x2A 32 %define BufferStartLocation LockLocation + 0x34 33 %define Cr3OffsetLocation LockLocation + 0x38 34 35 ;------------------------------------------------------------------------------------- 36 ;RendezvousFunnelProc procedure follows. All APs execute their procedure. This 37 ;procedure serializes all the AP processors through an Init sequence. It must be 38 ;noted that APs arrive here very raw...ie: real mode, no stack. 39 ;ALSO THIS PROCEDURE IS EXECUTED BY APs ONLY ON 16 BIT MODE. HENCE THIS PROC 40 ;IS IN MACHINE CODE. 41 ;------------------------------------------------------------------------------------- 42 ;RendezvousFunnelProc (&WakeUpBuffer,MemAddress); 43 44 ;text SEGMENT 45 DEFAULT REL 46 SECTION .text 47 48 BITS 16 49 global ASM_PFX(RendezvousFunnelProc) 50 ASM_PFX(RendezvousFunnelProc): 51 RendezvousFunnelProcStart: 52 53 ; At this point CS = 0x(vv00) and ip= 0x0. 54 55 mov ax, cs 56 mov ds, ax 57 mov es, ax 58 mov ss, ax 59 xor ax, ax 60 mov fs, ax 61 mov gs, ax 62 63 flat32Start: 64 65 mov si, BufferStartLocation 66 mov edx,dword [si] ; EDX is keeping the start address of wakeup buffer 67 68 mov si, Cr3OffsetLocation 69 mov ecx,dword [si] ; ECX is keeping the value of CR3 70 71 mov si, GdtrLocation 72 o32 lgdt [cs:si] 73 74 mov si, IdtrLocation 75 o32 lidt [cs:si] 76 77 xor ax, ax 78 mov ds, ax 79 80 mov eax, cr0 ; Get control register 0 81 or eax, 0x000000001 ; Set PE bit (bit #0) 82 mov cr0, eax 83 84 FLAT32_JUMP: 85 86 a32 jmp dword 0x20:0x0 87 88 BITS 32 89 PMODE_ENTRY: ; protected mode entry point 90 91 mov ax, 0x18 92 o16 mov ds, ax 93 o16 mov es, ax 94 o16 mov fs, ax 95 o16 mov gs, ax 96 o16 mov ss, ax ; Flat mode setup. 97 98 mov eax, cr4 99 bts eax, 5 100 mov cr4, eax 101 102 mov cr3, ecx 103 104 mov esi, edx ; Save wakeup buffer address 105 106 mov ecx, 0xc0000080 ; EFER MSR number. 107 rdmsr ; Read EFER. 108 bts eax, 8 ; Set LME=1. 109 wrmsr ; Write EFER. 110 111 mov eax, cr0 ; Read CR0. 112 bts eax, 31 ; Set PG=1. 113 mov cr0, eax ; Write CR0. 114 115 LONG_JUMP: 116 117 a16 jmp dword 0x38:0x0 118 119 BITS 64 120 LongModeStart: 121 122 mov ax, 0x30 123 o16 mov ds, ax 124 o16 mov es, ax 125 o16 mov ss, ax 126 127 mov edi, esi 128 add edi, LockLocation 129 mov al, NotVacantFlag 130 TestLock: 131 xchg byte [edi], al 132 cmp al, NotVacantFlag 133 jz TestLock 134 135 ProgramStack: 136 137 mov edi, esi 138 add edi, StackSizeLocation 139 mov rax, qword [edi] 140 mov edi, esi 141 add edi, StackStartAddressLocation 142 add rax, qword [edi] 143 mov rsp, rax 144 mov qword [edi], rax 145 146 Releaselock: 147 148 mov al, VacantFlag 149 mov edi, esi 150 add edi, LockLocation 151 xchg byte [edi], al 152 153 ; 154 ; Call assembly function to initialize FPU. 155 ; 156 mov rax, ASM_PFX(InitializeFloatingPointUnits) 157 sub rsp, 0x20 158 call rax 159 add rsp, 0x20 160 161 ; 162 ; Call C Function 163 ; 164 mov edi, esi 165 add edi, CProcedureLocation 166 mov rax, qword [edi] 167 168 test rax, rax 169 jz GoToSleep 170 171 sub rsp, 0x20 172 call rax 173 add rsp, 0x20 174 175 GoToSleep: 176 cli 177 hlt 178 jmp $-2 179 180 RendezvousFunnelProcEnd: 181 182 ;------------------------------------------------------------------------------------- 183 ; AsmGetAddressMap (&AddressMap); 184 ;------------------------------------------------------------------------------------- 185 ; comments here for definition of address map 186 global ASM_PFX(AsmGetAddressMap) 187 ASM_PFX(AsmGetAddressMap): 188 mov rax, RendezvousFunnelProcStart 189 mov qword [rcx], rax 190 mov qword [rcx+0x8], PMODE_ENTRY - RendezvousFunnelProcStart 191 mov qword [rcx+0x10], FLAT32_JUMP - RendezvousFunnelProcStart 192 mov qword [rcx+0x18], RendezvousFunnelProcEnd - RendezvousFunnelProcStart 193 mov qword [rcx+0x20], LongModeStart - RendezvousFunnelProcStart 194 mov qword [rcx+0x28], LONG_JUMP - RendezvousFunnelProcStart 195 ret 196 197