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 /* The SIPI vector is responsible for initializing the APs in the sytem. It
18 * loads microcode, sets up MSRs, and enables caching before calling into
21 /* These segment selectors need to match the gdt entries in c_start.S. */
25 #define IA32_UPDT_TRIG 0x79
26 #define IA32_BIOS_SIGN_ID 0x8b
28 .section ".module_parameters", "aw", @progbits
59 movl %eax, %cr3 /* Invalidate TLB*/
61 /* On hyper threaded cpus, invalidating the cache here is
62 * very very bad. Don't.
65 /* setup the data segment */
69 /* The gdtaddr needs to be releative to the data segment in order
70 * to properly dereference it. The .text section comes first in an
71 * rmodule so _start can be used as a proxy for the load address. */
78 andl $0x7FFAFFD1, %eax /* PG,AM,WP,NE,TS,EM,MP = 0 */
79 orl $0x60000001, %eax /* CD, NW, PE = 1 */
92 /* Load the Interrupt descriptor table */
96 /* Obtain cpu number. */
101 lock cmpxchg %ecx, ap_count
104 /* Setup stacks for each CPU. */
105 movl stack_size, %eax
110 /* Save cpu number. */
113 /* Determine if one should check microcode versions. */
114 mov microcode_ptr, %edi
116 jz microcode_done /* Bypass if no microde exists. */
118 /* Get the Microcode version. */
121 mov $IA32_BIOS_SIGN_ID, %ecx
123 /* If something already loaded skip loading again. */
127 /* Determine if parallel microcode loading is allowed. */
128 cmp $0xffffffff, microcode_lock
131 /* Protect microcode loading. */
133 lock bts $0, microcode_lock
137 /* Load new microcode. */
138 mov $IA32_UPDT_TRIG, %ecx
141 /* The microcode pointer is passed in pointing to the header. Adjust
142 * pointer to reflect the payload (header size is 48 bytes). */
148 /* Unconditionally unlock microcode loading. */
149 cmp $0xffffffff, microcode_lock
153 mov %eax, microcode_lock
157 * Load MSRs. Each entry in the table consists of:
162 mov msr_table_ptr, %edi
176 /* Enable caching. */
178 and $0x9fffffff, %eax /* CD, NW = 0 */
181 /* c_handler(cpu_num) */
182 push %esi /* cpu_num */