blob: 564b200c483678d87c9565d4bdf95d633aa31060 [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
26.code32
27.section ".module_parameters", "aw", @progbits
28stub_entry_params:
29stack_size:
30.long 0
31stack_top:
32.long 0
33c_handler:
34.long 0
35c_handler_arg:
36.long 0
37/* struct smm_runtime begins here. */
38smm_runtime:
39smbase:
40.long 0
41save_state_size:
42.long 0
43/* apic_to_cpu_num is a table mapping the default APIC id to cpu num. If the
44 * APIC id is found at the given index, the contiguous cpu number is index
45 * into the table. */
46apic_to_cpu_num:
47.fill CONFIG_MAX_CPUS,1,0xff
48/* end struct smm_runtime */
49
50.data
51/* Provide fallback stack to use when a valid cpu number cannot be found. */
52fallback_stack_bottom:
53.skip 128
54fallback_stack_top:
55
56.text
57.code16
Aaron Durbindde76292015-09-05 12:59:26 -050058.global _start
59_start:
Aaron Durbin50a34642013-01-03 17:38:47 -060060 movl $(smm_relocate_gdt), %ebx
61 data32 lgdt (%ebx)
62
63 movl %cr0, %eax
64 andl $0x1FFAFFD1, %eax /* CD,NW,PG,AM,WP,NE,TS,EM,MP = 0 */
65 orl $0x1, %eax /* PE = 1 */
66 movl %eax, %cr0
67
68 /* Enable protected mode */
69 data32 ljmp $0x8, $smm_trampoline32
70
71.align 4
72smm_relocate_gdt:
73 /* The first GDT entry is used for the lgdt instruction. */
74 .word smm_relocate_gdt_end - smm_relocate_gdt - 1
75 .long smm_relocate_gdt
76 .word 0x0000
77
78 /* gdt selector 0x08, flat code segment */
79 .word 0xffff, 0x0000
80 .byte 0x00, 0x9b, 0xcf, 0x00 /* G=1 and 0x0f, 4GB limit */
81
82 /* gdt selector 0x10, flat data segment */
83 .word 0xffff, 0x0000
84 .byte 0x00, 0x93, 0xcf, 0x00
85smm_relocate_gdt_end:
86
87.align 4
88.code32
89.global smm_trampoline32
90smm_trampoline32:
91 /* Use flat data segment */
92 movw $0x10, %ax
93 movw %ax, %ds
94 movw %ax, %es
95 movw %ax, %ss
96 movw %ax, %fs
97 movw %ax, %gs
98
99 /* The CPU number is calculated by reading the initial APIC id. Since
100 * the OS can maniuplate the APIC id use the non-changing cpuid result
101 * for APIC id (ebx[31:24]). A table is used to handle a discontiguous
102 * APIC id space. */
103 mov $1, %eax
104 cpuid
105 bswap %ebx /* Default APIC id in bl. */
106 mov $(apic_to_cpu_num), %eax
107 xor %ecx, %ecx
108
1091:
110 cmp (%eax, %ecx, 1), %bl
111 je 1f
112 inc %ecx
113 cmp $CONFIG_MAX_CPUS, %ecx
114 jne 1b
115 /* This is bad. One cannot find a stack entry because a cpu num could
116 * not be assigned. Use the fallback stack and check this condition in
117 * C handler. */
118 movl $(fallback_stack_top), %esp
119 jmp 2f
1201:
121 movl stack_size, %eax
122 mul %ecx
123 movl stack_top, %edx
124 subl %eax, %edx
125 mov %edx, %esp
126
1272:
128 /* Call into the c-based SMM relocation function with the platform
129 * parameters. Equivalent to:
Aaron Durbin3eb8eb72014-03-10 16:13:58 -0500130 * struct arg = { c_handler_params, cpu_num, smm_runtime {;
131 * c_handler(&arg)
Aaron Durbin50a34642013-01-03 17:38:47 -0600132 */
133 push $(smm_runtime)
134 push %ecx
135 push c_handler_arg
Aaron Durbin3eb8eb72014-03-10 16:13:58 -0500136 push %esp
Aaron Durbin50a34642013-01-03 17:38:47 -0600137 mov c_handler, %eax
138 call *%eax
139
140 /* Exit from SM mode. */
141 rsm