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