1#------------------------------------------------------------------------------ 2# 3# Copyright (c) 2009 - 2015, Intel Corporation. All rights reserved.<BR> 4# This program and the accompanying materials 5# are licensed and made available under the terms and conditions of the BSD License 6# which accompanies this distribution. The full text of the license may be found at 7# http://opensource.org/licenses/bsd-license.php. 8# 9# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, 10# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. 11# 12# Module Name: 13# 14# SmmInit.S 15# 16# Abstract: 17# 18# Functions for relocating SMBASE's for all processors 19# 20#------------------------------------------------------------------------------ 21 22ASM_GLOBAL ASM_PFX(gSmmCr0) 23ASM_GLOBAL ASM_PFX(gSmmCr3) 24ASM_GLOBAL ASM_PFX(gSmmCr4) 25ASM_GLOBAL ASM_PFX(gSmmJmpAddr) 26ASM_GLOBAL ASM_PFX(gcSmmInitTemplate) 27ASM_GLOBAL ASM_PFX(gcSmmInitSize) 28ASM_GLOBAL ASM_PFX(mRebasedFlagAddr32) 29ASM_GLOBAL ASM_PFX(SmmRelocationSemaphoreComplete) 30ASM_GLOBAL ASM_PFX(SmmRelocationSemaphoreComplete32) 31ASM_GLOBAL ASM_PFX(mSmmRelocationOriginalAddressPtr32) 32ASM_GLOBAL ASM_PFX(gSmmInitStack) 33ASM_GLOBAL ASM_PFX(gcSmiInitGdtr) 34 35 36 .text 37 38ASM_PFX(gcSmiInitGdtr): 39 .word 0 40 .quad 0 41 42SmmStartup: 43 .byte 0x66,0xb8 # mov eax, imm32 44ASM_PFX(gSmmCr3): .space 4 45 movq %rax, %cr3 46 .byte 0x66,0x2e 47 lgdt (ASM_PFX(gcSmiInitGdtr) - SmmStartup)(%ebp) 48 .byte 0x66,0xb8 # mov eax, imm32 49ASM_PFX(gSmmCr4): .space 4 50 orb $2, %ah # enable XMM registers access 51 movq %rax, %cr4 52 .byte 0x66 53 movl $0xc0000080,%ecx # IA32_EFER MSR 54 rdmsr 55 orb $1,%ah # set LME bit 56 wrmsr 57 .byte 0x66,0xb8 # mov eax, imm32 58ASM_PFX(gSmmCr0): .space 4 59 movq %rax, %cr0 60 .byte 0x66,0xea # far jmp to long mode 61ASM_PFX(gSmmJmpAddr): .quad LongMode 62LongMode: # long-mode starts here 63 .byte 0x48,0xbc # mov rsp, imm64 64ASM_PFX(gSmmInitStack): .space 8 65 andw $0xfff0, %sp # make sure RSP is 16-byte aligned 66 # 67 # Accoring to X64 calling convention, XMM0~5 are volatile, we need to save 68 # them before calling C-function. 69 # 70 subq $0x60, %rsp 71 movdqa %xmm0, 0x0(%rsp) 72 movdqa %xmm1, 0x10(%rsp) 73 movdqa %xmm2, 0x20(%rsp) 74 movdqa %xmm3, 0x30(%rsp) 75 movdqa %xmm4, 0x40(%rsp) 76 movdqa %xmm5, 0x50(%rsp) 77 78 79 addq $-0x20, %rsp 80 call ASM_PFX(SmmInitHandler) 81 addq $0x20, %rsp 82 # 83 # Restore XMM0~5 after calling C-function. 84 # 85 movdqa 0x0(%rsp), %xmm0 86 movdqa 0x10(%rsp), %xmm1 87 movdqa 0x20(%rsp), %xmm2 88 movdqa 0x30(%rsp), %xmm3 89 movdqa 0x40(%rsp), %xmm4 90 movdqa 0x50(%rsp), %xmm5 91 92 rsm 93 94ASM_PFX(gcSmmInitTemplate): 95 96_SmmInitTemplate: 97 .byte 0x66,0x2e,0x8b,0x2e # mov ebp, cs:[@F] 98 .word L1 - _SmmInitTemplate + 0x8000 99 .byte 0x66, 0x81, 0xed, 0, 0, 3, 0 # sub ebp, 0x30000 100 jmp *%bp # jmp ebp actually 101L1: 102 .quad SmmStartup 103 104ASM_PFX(gcSmmInitSize): .word . - ASM_PFX(gcSmmInitTemplate) 105 106ASM_PFX(SmmRelocationSemaphoreComplete): 107 # Create a simple stack frame to store RAX and the original RSM location 108 pushq %rax # Used to store return address 109 pushq %rax 110 111 # Load the original RSM location onto stack 112 movabsq $ASM_PFX(mSmmRelocationOriginalAddress), %rax 113 movq (%rax), %rax 114 movq %rax, 0x08(%rsp) 115 116 # Update rebase flag 117 movabsq $ASM_PFX(mRebasedFlag), %rax 118 movq (%rax), %rax 119 movb $1, (%rax) 120 121 #restore RAX and return to original RSM location 122 popq %rax 123 retq 124 125# 126# Semaphore code running in 32-bit mode 127# 128ASM_PFX(SmmRelocationSemaphoreComplete32): 129 # 130 # movb $1, () 131 # 132 .byte 0xc6, 0x05 133ASM_PFX(mRebasedFlagAddr32): 134 .long 0 135 .byte 1 136 # 137 # jmpd () 138 # 139 .byte 0xff, 0x25 140ASM_PFX(mSmmRelocationOriginalAddressPtr32): 141 .long 0 142