blob: 32435a04b5d11049821d6a6c6ab8386746c36359 [file] [log] [blame]
Aaron Durbin50a34642013-01-03 17:38:47 -06001/*
2 * This file is part of the coreboot project.
3 *
4 * Copyright (C) 2012 ChromeOS Authors
5 *
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public License as
8 * published by the Free Software Foundation; version 2 of
9 * the License.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
Aaron Durbin50a34642013-01-03 17:38:47 -060015 */
16
17/*
18 * The stub is a generic wrapper for bootstrapping a C-based SMM handler. Its
19 * primary purpose is to put the CPU into protected mode with a stack and call
20 * into the C handler.
21 *
22 * The stub_entry_params structure needs to correspond to the C structure
23 * found in smm.h.
24 */
25
Aaron Durbin9e01a0b2017-06-16 14:12:55 -050026#include <cpu/x86/cr.h>
27
Aaron Durbin50a34642013-01-03 17:38:47 -060028.code32
29.section ".module_parameters", "aw", @progbits
30stub_entry_params:
31stack_size:
32.long 0
33stack_top:
34.long 0
35c_handler:
36.long 0
37c_handler_arg:
38.long 0
Aaron Durbin8ade68a2017-06-16 15:16:13 -050039fxsave_area:
40.long 0
41fxsave_area_size:
42.long 0
Aaron Durbin50a34642013-01-03 17:38:47 -060043/* struct smm_runtime begins here. */
44smm_runtime:
45smbase:
46.long 0
47save_state_size:
48.long 0
Elyes HAOUASd82be922016-07-28 18:58:27 +020049/* apic_to_cpu_num is a table mapping the default APIC id to CPU num. If the
50 * APIC id is found at the given index, the contiguous CPU number is index
Aaron Durbin50a34642013-01-03 17:38:47 -060051 * into the table. */
52apic_to_cpu_num:
53.fill CONFIG_MAX_CPUS,1,0xff
54/* end struct smm_runtime */
55
56.data
Elyes HAOUASd82be922016-07-28 18:58:27 +020057/* Provide fallback stack to use when a valid CPU number cannot be found. */
Aaron Durbin50a34642013-01-03 17:38:47 -060058fallback_stack_bottom:
59.skip 128
60fallback_stack_top:
61
Aaron Durbin9e01a0b2017-06-16 14:12:55 -050062#define CR0_CLEAR_FLAGS \
63 (CR0_CD | CR0_NW | CR0_PG | CR0_AM | CR0_WP | \
64 CR0_NE | CR0_TS | CR0_EM | CR0_MP)
65
Aaron Durbin50a34642013-01-03 17:38:47 -060066.text
67.code16
Aaron Durbindde76292015-09-05 12:59:26 -050068.global _start
69_start:
Aaron Durbin50a34642013-01-03 17:38:47 -060070 movl $(smm_relocate_gdt), %ebx
Edward O'Callaghan4e2294b2017-01-08 19:14:42 +110071 lgdtl (%ebx)
Aaron Durbin50a34642013-01-03 17:38:47 -060072
73 movl %cr0, %eax
Aaron Durbin9e01a0b2017-06-16 14:12:55 -050074 andl $~CR0_CLEAR_FLAGS, %eax
75 orl $CR0_PE, %eax
Aaron Durbin50a34642013-01-03 17:38:47 -060076 movl %eax, %cr0
77
78 /* Enable protected mode */
Edward O'Callaghan4e2294b2017-01-08 19:14:42 +110079 ljmpl $0x8, $smm_trampoline32
Aaron Durbin50a34642013-01-03 17:38:47 -060080
81.align 4
82smm_relocate_gdt:
83 /* The first GDT entry is used for the lgdt instruction. */
84 .word smm_relocate_gdt_end - smm_relocate_gdt - 1
85 .long smm_relocate_gdt
86 .word 0x0000
87
88 /* gdt selector 0x08, flat code segment */
89 .word 0xffff, 0x0000
90 .byte 0x00, 0x9b, 0xcf, 0x00 /* G=1 and 0x0f, 4GB limit */
91
92 /* gdt selector 0x10, flat data segment */
93 .word 0xffff, 0x0000
94 .byte 0x00, 0x93, 0xcf, 0x00
95smm_relocate_gdt_end:
96
97.align 4
98.code32
99.global smm_trampoline32
100smm_trampoline32:
101 /* Use flat data segment */
102 movw $0x10, %ax
103 movw %ax, %ds
104 movw %ax, %es
105 movw %ax, %ss
106 movw %ax, %fs
107 movw %ax, %gs
108
109 /* The CPU number is calculated by reading the initial APIC id. Since
110 * the OS can maniuplate the APIC id use the non-changing cpuid result
111 * for APIC id (ebx[31:24]). A table is used to handle a discontiguous
112 * APIC id space. */
113 mov $1, %eax
114 cpuid
115 bswap %ebx /* Default APIC id in bl. */
116 mov $(apic_to_cpu_num), %eax
117 xor %ecx, %ecx
118
1191:
120 cmp (%eax, %ecx, 1), %bl
121 je 1f
122 inc %ecx
123 cmp $CONFIG_MAX_CPUS, %ecx
124 jne 1b
Elyes HAOUASd82be922016-07-28 18:58:27 +0200125 /* This is bad. One cannot find a stack entry because a CPU num could
Aaron Durbin50a34642013-01-03 17:38:47 -0600126 * not be assigned. Use the fallback stack and check this condition in
127 * C handler. */
128 movl $(fallback_stack_top), %esp
Aaron Durbin8ade68a2017-06-16 15:16:13 -0500129 /* Clear fxsave location as there will be no saving/restoring. */
130 xor %edi, %edi
Aaron Durbin50a34642013-01-03 17:38:47 -0600131 jmp 2f
1321:
133 movl stack_size, %eax
134 mul %ecx
135 movl stack_top, %edx
136 subl %eax, %edx
137 mov %edx, %esp
138
Aaron Durbin8ade68a2017-06-16 15:16:13 -0500139 /* calculate fxsave location */
140 mov fxsave_area, %edi
141 test %edi, %edi
142 jz 2f
143 movl fxsave_area_size, %eax
144 mul %ecx
145 add %eax, %edi
146
Aaron Durbin50a34642013-01-03 17:38:47 -06001472:
Aaron Durbin8ade68a2017-06-16 15:16:13 -0500148 /* Save location of fxsave area. */
149 push %edi
150 mov %esp, %ebp
151 test %edi, %edi
152 jz 1f
153
154 /* Enable sse instructions. */
155 mov %cr4, %eax
156 orl $(CR4_OSFXSR | CR4_OSXMMEXCPT), %eax
157 mov %eax, %cr4
158
159 /* Save FP state. */
160 fxsave (%edi)
161
1621:
163 /* Align stack to 16 bytes. Another 16 bytes are pushed below. */
164 andl $0xfffffff0, %esp
165
Aaron Durbin50a34642013-01-03 17:38:47 -0600166 /* Call into the c-based SMM relocation function with the platform
167 * parameters. Equivalent to:
Aaron Durbin3eb8eb72014-03-10 16:13:58 -0500168 * struct arg = { c_handler_params, cpu_num, smm_runtime {;
169 * c_handler(&arg)
Aaron Durbin50a34642013-01-03 17:38:47 -0600170 */
171 push $(smm_runtime)
172 push %ecx
173 push c_handler_arg
Aaron Durbin3eb8eb72014-03-10 16:13:58 -0500174 push %esp
Aaron Durbin50a34642013-01-03 17:38:47 -0600175 mov c_handler, %eax
176 call *%eax
177
Aaron Durbin8ade68a2017-06-16 15:16:13 -0500178 /* Restore stack from call frame */
179 mov %ebp, %esp
180 /* Retrieve fxsave location. */
181 pop %edi
182 test %edi, %edi
183 jz 1f
184
185 /* Restore FP state. */
186 fxrstor (%edi)
187
1881:
Aaron Durbin50a34642013-01-03 17:38:47 -0600189 /* Exit from SM mode. */
190 rsm