2 * This file is part of the coreboot project.
4 * Copyright (C) 2013 Google Inc.
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
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.
17 #include <cpu/x86/cr.h>
19 /* The SIPI vector is responsible for initializing the APs in the sytem. It
20 * loads microcode, sets up MSRs, and enables caching before calling into
23 /* These segment selectors need to match the gdt entries in c_start.S. */
27 #define IA32_UPDT_TRIG 0x79
28 #define IA32_BIOS_SIGN_ID 0x8b
30 .section ".module_parameters", "aw", @progbits
55 #define CR0_CLEAR_FLAGS_CACHE_ENABLE (CR0_CD | CR0_NW)
56 #define CR0_SET_FLAGS (CR0_CLEAR_FLAGS_CACHE_ENABLE | CR0_PE)
57 #define CR0_CLEAR_FLAGS \
58 (CR0_PG | CR0_AM | CR0_WP | CR0_NE | CR0_TS | CR0_EM | CR0_MP)
66 movl %eax, %cr3 /* Invalidate TLB*/
68 /* On hyper threaded cpus, invalidating the cache here is
69 * very very bad. Don't.
72 /* setup the data segment */
76 /* The gdtaddr needs to be releative to the data segment in order
77 * to properly dereference it. The .text section comes first in an
78 * rmodule so _start can be used as a proxy for the load address. */
85 andl $~CR0_CLEAR_FLAGS, %eax
86 orl $CR0_SET_FLAGS, %eax
99 /* Load the Interrupt descriptor table */
103 /* Obtain CPU number. */
108 lock cmpxchg %ecx, ap_count
111 /* Setup stacks for each CPU. */
112 movl stack_size, %eax
117 /* Save CPU number. */
120 /* Determine if one should check microcode versions. */
121 mov microcode_ptr, %edi
123 jz microcode_done /* Bypass if no microde exists. */
125 /* Get the Microcode version. */
128 mov $IA32_BIOS_SIGN_ID, %ecx
130 /* If something already loaded skip loading again. */
134 /* Determine if parallel microcode loading is allowed. */
135 cmpl $0xffffffff, microcode_lock
138 /* Protect microcode loading. */
140 lock bts $0, microcode_lock
144 /* Load new microcode. */
145 mov $IA32_UPDT_TRIG, %ecx
148 /* The microcode pointer is passed in pointing to the header. Adjust
149 * pointer to reflect the payload (header size is 48 bytes). */
155 /* Unconditionally unlock microcode loading. */
156 cmpl $0xffffffff, microcode_lock
160 mov %eax, microcode_lock
164 * Load MSRs. Each entry in the table consists of:
169 mov msr_table_ptr, %edi
183 /* Enable caching. */
185 and $~(CR0_CLEAR_FLAGS_CACHE_ENABLE), %eax
188 #if IS_ENABLED(CONFIG_SSE)
189 /* Enable sse instructions. */
191 orl $(CR4_OSFXSR | CR4_OSXMMEXCPT), %eax
195 /* c_handler(cpu_num) */
196 push %esi /* cpu_num */