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.
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
21 /* The SIPI vector is responsible for initializing the APs in the sytem. It
22 * loads microcode, sets up MSRs, and enables caching before calling into
25 /* These segment selectors need to match the gdt entries in c_start.S. */
29 #define IA32_UPDT_TRIG 0x79
30 #define IA32_BIOS_SIGN_ID 0x8b
32 .section ".module_parameters", "aw", @progbits
60 .global __rmodule_entry
65 movl %eax, %cr3 /* Invalidate TLB*/
67 /* On hyper threaded cpus, invalidating the cache here is
68 * very very bad. Don't.
71 /* setup the data segment */
75 /* The gdtaddr needs to be releative to the data segment in order
76 * to properly dereference it. The .text section comes first in an
77 * rmodule so ap_start can be used as a proxy for the load address. */
84 andl $0x7FFAFFD1, %eax /* PG,AM,WP,NE,TS,EM,MP = 0 */
85 orl $0x60000001, %eax /* CD, NW, PE = 1 */
98 /* Load the Interrupt descriptor table */
102 /* Obtain cpu number. */
107 lock cmpxchg %ecx, ap_count
110 /* Setup stacks for each CPU. */
111 movl stack_size, %eax
116 /* Save cpu number. */
119 /* Determine if one should check microcode versions. */
120 mov microcode_ptr, %edi
122 jz microcode_done /* Bypass if no microde exists. */
124 /* Get the Microcode version. */
127 mov $IA32_BIOS_SIGN_ID, %ecx
129 /* If something already loaded skip loading again. */
133 /* Determine if parallel microcode loading is allowed. */
134 cmp $0xffffffff, microcode_lock
137 /* Protect microcode loading. */
139 lock bts $0, microcode_lock
143 /* Load new microcode. */
144 mov $IA32_UPDT_TRIG, %ecx
147 /* The microcode pointer is passed in pointing to the header. Adjust
148 * pointer to reflect the payload (header size is 48 bytes). */
154 /* Unconditionally unlock microcode loading. */
155 cmp $0xffffffff, microcode_lock
159 mov %eax, microcode_lock
163 * Load MSRs. Each entry in the table consists of:
168 mov msr_table_ptr, %edi
182 /* Enable caching. */
184 and $0x9fffffff, %eax /* CD, NW = 0 */
187 /* c_handler(cpu_num) */
188 push %esi /* cpu_num */