blob: 184dc4fcc12775a81041d9b8e8796bce59a313c6 [file] [log] [blame]
Aaron Durbine0785c02013-10-21 12:15:29 -05001/*
2 * This file is part of the coreboot project.
3 *
4 * Copyright (C) 2013 Google Inc.
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 Durbine0785c02013-10-21 12:15:29 -050015 */
16
17#include <console/console.h>
18#include <stdint.h>
19#include <rmodule.h>
20#include <arch/cpu.h>
21#include <cpu/cpu.h>
22#include <cpu/intel/microcode.h>
23#include <cpu/x86/cache.h>
Kyösti Mälkkibae775a2014-12-18 10:36:33 +020024#include <cpu/x86/gdt.h>
Aaron Durbine0785c02013-10-21 12:15:29 -050025#include <cpu/x86/lapic.h>
26#include <cpu/x86/name.h>
27#include <cpu/x86/msr.h>
28#include <cpu/x86/mtrr.h>
29#include <cpu/x86/smm.h>
30#include <cpu/x86/mp.h>
31#include <delay.h>
32#include <device/device.h>
33#include <device/path.h>
34#include <lib.h>
35#include <smp/atomic.h>
36#include <smp/spinlock.h>
Julius Wernerec5e5e02014-08-20 15:29:56 -070037#include <symbols.h>
Aaron Durbine0785c02013-10-21 12:15:29 -050038#include <thread.h>
39
40#define MAX_APIC_IDS 256
41/* This needs to match the layout in the .module_parametrs section. */
42struct sipi_params {
43 uint16_t gdtlimit;
44 uint32_t gdt;
45 uint16_t unused;
46 uint32_t idt_ptr;
47 uint32_t stack_top;
48 uint32_t stack_size;
49 uint32_t microcode_lock; /* 0xffffffff means parallel loading. */
50 uint32_t microcode_ptr;
51 uint32_t msr_table_ptr;
52 uint32_t msr_count;
53 uint32_t c_handler;
54 atomic_t ap_count;
55} __attribute__((packed));
56
57/* This also needs to match the assembly code for saved MSR encoding. */
58struct saved_msr {
59 uint32_t index;
60 uint32_t lo;
61 uint32_t hi;
62} __attribute__((packed));
63
64
65/* The sipi vector rmodule is included in the ramstage using 'objdump -B'. */
66extern char _binary_sipi_vector_start[];
Aaron Durbine0785c02013-10-21 12:15:29 -050067
68/* The SIPI vector is loaded at the SMM_DEFAULT_BASE. The reason is at the
69 * memory range is already reserved so the OS cannot use it. That region is
70 * free to use for AP bringup before SMM is initialized. */
71static const uint32_t sipi_vector_location = SMM_DEFAULT_BASE;
72static const int sipi_vector_location_size = SMM_DEFAULT_SIZE;
73
74struct mp_flight_plan {
75 int num_records;
76 struct mp_flight_record *records;
77};
78
79static struct mp_flight_plan mp_info;
80
81struct cpu_map {
Edward O'Callaghan2c9d2cf2014-10-27 23:29:29 +110082 struct device *dev;
Aaron Durbine0785c02013-10-21 12:15:29 -050083 int apic_id;
84};
85
86/* Keep track of apic and device structure for each cpu. */
87static struct cpu_map cpus[CONFIG_MAX_CPUS];
88
89static inline void barrier_wait(atomic_t *b)
90{
91 while (atomic_read(b) == 0) {
92 asm ("pause");
93 }
94 mfence();
95}
96
97static inline void release_barrier(atomic_t *b)
98{
99 mfence();
100 atomic_set(b, 1);
101}
102
103/* Returns 1 if timeout waiting for APs. 0 if target aps found. */
104static int wait_for_aps(atomic_t *val, int target, int total_delay,
105 int delay_step)
106{
107 int timeout = 0;
108 int delayed = 0;
109 while (atomic_read(val) != target) {
110 udelay(delay_step);
111 delayed += delay_step;
112 if (delayed >= total_delay) {
113 timeout = 1;
114 break;
115 }
116 }
117
118 return timeout;
119}
120
121static void ap_do_flight_plan(void)
122{
123 int i;
124
125 for (i = 0; i < mp_info.num_records; i++) {
126 struct mp_flight_record *rec = &mp_info.records[i];
127
128 atomic_inc(&rec->cpus_entered);
129 barrier_wait(&rec->barrier);
130
131 if (rec->ap_call != NULL) {
132 rec->ap_call(rec->ap_arg);
133 }
134 }
135}
136
137/* By the time APs call ap_init() caching has been setup, and microcode has
138 * been loaded. */
139static void asmlinkage ap_init(unsigned int cpu)
140{
141 struct cpu_info *info;
142 int apic_id;
143
144 /* Ensure the local apic is enabled */
145 enable_lapic();
146
147 info = cpu_info();
148 info->index = cpu;
149 info->cpu = cpus[cpu].dev;
150 thread_init_cpu_info_non_bsp(info);
151
152 apic_id = lapicid();
153 info->cpu->path.apic.apic_id = apic_id;
154 cpus[cpu].apic_id = apic_id;
155
156 printk(BIOS_INFO, "AP: slot %d apic_id %x.\n", cpu, apic_id);
157
158 /* Walk the flight plan */
159 ap_do_flight_plan();
160
161 /* Park the AP. */
162 stop_this_cpu();
163}
164
165static void setup_default_sipi_vector_params(struct sipi_params *sp)
166{
167 sp->gdt = (uint32_t)&gdt;
168 sp->gdtlimit = (uint32_t)&gdt_end - (u32)&gdt - 1;
169 sp->idt_ptr = (uint32_t)&idtarg;
170 sp->stack_size = CONFIG_STACK_SIZE;
171 sp->stack_top = (uint32_t)&_estack;
172 /* Adjust the stack top to take into account cpu_info. */
173 sp->stack_top -= sizeof(struct cpu_info);
174}
175
176#define NUM_FIXED_MTRRS 11
177static const unsigned int fixed_mtrrs[NUM_FIXED_MTRRS] = {
Alexandru Gagniuc86091f92015-09-30 20:23:09 -0700178 MTRR_FIX_64K_00000, MTRR_FIX_16K_80000, MTRR_FIX_16K_A0000,
179 MTRR_FIX_4K_C0000, MTRR_FIX_4K_C8000, MTRR_FIX_4K_D0000,
180 MTRR_FIX_4K_D8000, MTRR_FIX_4K_E0000, MTRR_FIX_4K_E8000,
181 MTRR_FIX_4K_F0000, MTRR_FIX_4K_F8000,
Aaron Durbine0785c02013-10-21 12:15:29 -0500182};
183
184static inline struct saved_msr *save_msr(int index, struct saved_msr *entry)
185{
186 msr_t msr;
187
188 msr = rdmsr(index);
189 entry->index = index;
190 entry->lo = msr.lo;
191 entry->hi = msr.hi;
192
193 /* Return the next entry. */
194 entry++;
195 return entry;
196}
197
198static int save_bsp_msrs(char *start, int size)
199{
200 int msr_count;
201 int num_var_mtrrs;
202 struct saved_msr *msr_entry;
203 int i;
204 msr_t msr;
205
206 /* Determine number of MTRRs need to be saved. */
Alexandru Gagniuc86091f92015-09-30 20:23:09 -0700207 msr = rdmsr(MTRR_CAP_MSR);
Aaron Durbine0785c02013-10-21 12:15:29 -0500208 num_var_mtrrs = msr.lo & 0xff;
209
210 /* 2 * num_var_mtrrs for base and mask. +1 for IA32_MTRR_DEF_TYPE. */
211 msr_count = 2 * num_var_mtrrs + NUM_FIXED_MTRRS + 1;
212
213 if ((msr_count * sizeof(struct saved_msr)) > size) {
214 printk(BIOS_CRIT, "Cannot mirror all %d msrs.\n", msr_count);
215 return -1;
216 }
217
218 msr_entry = (void *)start;
219 for (i = 0; i < NUM_FIXED_MTRRS; i++) {
220 msr_entry = save_msr(fixed_mtrrs[i], msr_entry);
221 }
222
223 for (i = 0; i < num_var_mtrrs; i++) {
Alexandru Gagniuc86091f92015-09-30 20:23:09 -0700224 msr_entry = save_msr(MTRR_PHYS_BASE(i), msr_entry);
225 msr_entry = save_msr(MTRR_PHYS_MASK(i), msr_entry);
Aaron Durbine0785c02013-10-21 12:15:29 -0500226 }
227
Alexandru Gagniuc86091f92015-09-30 20:23:09 -0700228 msr_entry = save_msr(MTRR_DEF_TYPE_MSR, msr_entry);
Aaron Durbine0785c02013-10-21 12:15:29 -0500229
230 return msr_count;
231}
232
233static atomic_t *load_sipi_vector(struct mp_params *mp_params)
234{
235 struct rmodule sipi_mod;
236 int module_size;
237 int num_msrs;
238 struct sipi_params *sp;
239 char *mod_loc = (void *)sipi_vector_location;
240 const int loc_size = sipi_vector_location_size;
241 atomic_t *ap_count = NULL;
242
243 if (rmodule_parse(&_binary_sipi_vector_start, &sipi_mod)) {
244 printk(BIOS_CRIT, "Unable to parse sipi module.\n");
245 return ap_count;
246 }
247
248 if (rmodule_entry_offset(&sipi_mod) != 0) {
249 printk(BIOS_CRIT, "SIPI module entry offset is not 0!\n");
250 return ap_count;
251 }
252
253 if (rmodule_load_alignment(&sipi_mod) != 4096) {
254 printk(BIOS_CRIT, "SIPI module load alignment(%d) != 4096.\n",
255 rmodule_load_alignment(&sipi_mod));
256 return ap_count;
257 }
258
259 module_size = rmodule_memory_size(&sipi_mod);
260
261 /* Align to 4 bytes. */
262 module_size = ALIGN(module_size, 4);
263
264 if (module_size > loc_size) {
265 printk(BIOS_CRIT, "SIPI module size (%d) > region size (%d).\n",
266 module_size, loc_size);
267 return ap_count;
268 }
269
270 num_msrs = save_bsp_msrs(&mod_loc[module_size], loc_size - module_size);
271
272 if (num_msrs < 0) {
273 printk(BIOS_CRIT, "Error mirroring BSP's msrs.\n");
274 return ap_count;
275 }
276
277 if (rmodule_load(mod_loc, &sipi_mod)) {
278 printk(BIOS_CRIT, "Unable to load SIPI module.\n");
279 return ap_count;
280 }
281
282 sp = rmodule_parameters(&sipi_mod);
283
284 if (sp == NULL) {
285 printk(BIOS_CRIT, "SIPI module has no parameters.\n");
286 return ap_count;
287 }
288
289 setup_default_sipi_vector_params(sp);
290 /* Setup MSR table. */
291 sp->msr_table_ptr = (uint32_t)&mod_loc[module_size];
292 sp->msr_count = num_msrs;
293 /* Provide pointer to microcode patch. */
294 sp->microcode_ptr = (uint32_t)mp_params->microcode_pointer;
295 /* Pass on abiility to load microcode in parallel. */
296 if (mp_params->parallel_microcode_load) {
297 sp->microcode_lock = 0;
298 } else {
299 sp->microcode_lock = ~0;
300 }
301 sp->c_handler = (uint32_t)&ap_init;
302 ap_count = &sp->ap_count;
303 atomic_set(ap_count, 0);
304
305 return ap_count;
306}
307
308static int allocate_cpu_devices(struct bus *cpu_bus, struct mp_params *p)
309{
310 int i;
311 int max_cpus;
312 struct cpu_info *info;
313
314 max_cpus = p->num_cpus;
315 if (max_cpus > CONFIG_MAX_CPUS) {
316 printk(BIOS_CRIT, "CPU count(%d) exceeds CONFIG_MAX_CPUS(%d)\n",
317 max_cpus, CONFIG_MAX_CPUS);
318 max_cpus = CONFIG_MAX_CPUS;
319 }
320
321 info = cpu_info();
322 for (i = 1; i < max_cpus; i++) {
323 struct device_path cpu_path;
Edward O'Callaghan2c9d2cf2014-10-27 23:29:29 +1100324 struct device *new;
Aaron Durbine0785c02013-10-21 12:15:29 -0500325 int apic_id;
326
327 /* Build the cpu device path */
328 cpu_path.type = DEVICE_PATH_APIC;
329
330 /* Assuming linear APIC space allocation. */
331 apic_id = info->cpu->path.apic.apic_id + i;
332 if (p->adjust_apic_id != NULL) {
333 apic_id = p->adjust_apic_id(i, apic_id);
334 }
335 cpu_path.apic.apic_id = apic_id;
336
337 /* Allocate the new cpu device structure */
338 new = alloc_find_dev(cpu_bus, &cpu_path);
339 if (new == NULL) {
Jacob Laskaaad9b6a082016-01-17 19:47:54 -0600340 printk(BIOS_CRIT, "Could not allocate cpu device\n");
Aaron Durbine0785c02013-10-21 12:15:29 -0500341 max_cpus--;
342 }
343 cpus[i].dev = new;
344 }
345
346 return max_cpus;
347}
348
349/* Returns 1 for timeout. 0 on success. */
350static int apic_wait_timeout(int total_delay, int delay_step)
351{
352 int total = 0;
353 int timeout = 0;
354
355 while (lapic_read(LAPIC_ICR) & LAPIC_ICR_BUSY) {
356 udelay(delay_step);
357 total += delay_step;
358 if (total >= total_delay) {
359 timeout = 1;
360 break;
361 }
362 }
363
364 return timeout;
365}
366
367static int start_aps(struct bus *cpu_bus, int ap_count, atomic_t *num_aps)
368{
369 int sipi_vector;
370 /* Max location is 4KiB below 1MiB */
371 const int max_vector_loc = ((1 << 20) - (1 << 12)) >> 12;
372
373 if (ap_count == 0)
374 return 0;
375
376 /* The vector is sent as a 4k aligned address in one byte. */
377 sipi_vector = sipi_vector_location >> 12;
378
379 if (sipi_vector > max_vector_loc) {
380 printk(BIOS_CRIT, "SIPI vector too large! 0x%08x\n",
381 sipi_vector);
382 return -1;
383 }
384
385 printk(BIOS_DEBUG, "Attempting to start %d APs\n", ap_count);
386
387 if ((lapic_read(LAPIC_ICR) & LAPIC_ICR_BUSY)) {
388 printk(BIOS_DEBUG, "Waiting for ICR not to be busy...");
389 if (apic_wait_timeout(1000 /* 1 ms */, 50)) {
390 printk(BIOS_DEBUG, "timed out. Aborting.\n");
391 return -1;
392 } else
393 printk(BIOS_DEBUG, "done.\n");
394 }
395
396 /* Send INIT IPI to all but self. */
397 lapic_write_around(LAPIC_ICR2, SET_LAPIC_DEST_FIELD(0));
398 lapic_write_around(LAPIC_ICR, LAPIC_DEST_ALLBUT | LAPIC_INT_ASSERT |
399 LAPIC_DM_INIT);
400 printk(BIOS_DEBUG, "Waiting for 10ms after sending INIT.\n");
401 mdelay(10);
402
403 /* Send 1st SIPI */
404 if ((lapic_read(LAPIC_ICR) & LAPIC_ICR_BUSY)) {
405 printk(BIOS_DEBUG, "Waiting for ICR not to be busy...");
406 if (apic_wait_timeout(1000 /* 1 ms */, 50)) {
407 printk(BIOS_DEBUG, "timed out. Aborting.\n");
408 return -1;
409 } else
410 printk(BIOS_DEBUG, "done.\n");
411 }
412
413 lapic_write_around(LAPIC_ICR2, SET_LAPIC_DEST_FIELD(0));
414 lapic_write_around(LAPIC_ICR, LAPIC_DEST_ALLBUT | LAPIC_INT_ASSERT |
415 LAPIC_DM_STARTUP | sipi_vector);
416 printk(BIOS_DEBUG, "Waiting for 1st SIPI to complete...");
417 if (apic_wait_timeout(10000 /* 10 ms */, 50 /* us */)) {
418 printk(BIOS_DEBUG, "timed out.\n");
419 return -1;
420 } else {
421 printk(BIOS_DEBUG, "done.\n");
422 }
423
424 /* Wait for CPUs to check in up to 200 us. */
425 wait_for_aps(num_aps, ap_count, 200 /* us */, 15 /* us */);
426
427 /* Send 2nd SIPI */
428 if ((lapic_read(LAPIC_ICR) & LAPIC_ICR_BUSY)) {
429 printk(BIOS_DEBUG, "Waiting for ICR not to be busy...");
430 if (apic_wait_timeout(1000 /* 1 ms */, 50)) {
431 printk(BIOS_DEBUG, "timed out. Aborting.\n");
432 return -1;
433 } else
434 printk(BIOS_DEBUG, "done.\n");
435 }
436
437 lapic_write_around(LAPIC_ICR2, SET_LAPIC_DEST_FIELD(0));
438 lapic_write_around(LAPIC_ICR, LAPIC_DEST_ALLBUT | LAPIC_INT_ASSERT |
439 LAPIC_DM_STARTUP | sipi_vector);
440 printk(BIOS_DEBUG, "Waiting for 2nd SIPI to complete...");
441 if (apic_wait_timeout(10000 /* 10 ms */, 50 /* us */)) {
442 printk(BIOS_DEBUG, "timed out.\n");
443 return -1;
444 } else {
445 printk(BIOS_DEBUG, "done.\n");
446 }
447
448 /* Wait for CPUs to check in. */
449 if (wait_for_aps(num_aps, ap_count, 10000 /* 10 ms */, 50 /* us */)) {
450 printk(BIOS_DEBUG, "Not all APs checked in: %d/%d.\n",
451 atomic_read(num_aps), ap_count);
452 return -1;
453 }
454
455 return 0;
456}
457
458static int bsp_do_flight_plan(struct mp_params *mp_params)
459{
460 int i;
461 int ret = 0;
462 const int timeout_us = 100000;
463 const int step_us = 100;
464 int num_aps = mp_params->num_cpus - 1;
465
466 for (i = 0; i < mp_params->num_records; i++) {
467 struct mp_flight_record *rec = &mp_params->flight_plan[i];
468
469 /* Wait for APs if the record is not released. */
470 if (atomic_read(&rec->barrier) == 0) {
471 /* Wait for the APs to check in. */
472 if (wait_for_aps(&rec->cpus_entered, num_aps,
473 timeout_us, step_us)) {
474 printk(BIOS_ERR, "MP record %d timeout.\n", i);
475 ret = -1;
476 }
477 }
478
479 if (rec->bsp_call != NULL) {
480 rec->bsp_call(rec->bsp_arg);
481 }
482
483 release_barrier(&rec->barrier);
484 }
485 return ret;
486}
487
488static void init_bsp(struct bus *cpu_bus)
489{
490 struct device_path cpu_path;
491 struct cpu_info *info;
492 char processor_name[49];
493
494 /* Print processor name */
495 fill_processor_name(processor_name);
496 printk(BIOS_INFO, "CPU: %s.\n", processor_name);
497
498 /* Ensure the local apic is enabled */
499 enable_lapic();
500
501 /* Set the device path of the boot cpu. */
502 cpu_path.type = DEVICE_PATH_APIC;
503 cpu_path.apic.apic_id = lapicid();
504
505 /* Find the device structure for the boot cpu. */
506 info = cpu_info();
507 info->cpu = alloc_find_dev(cpu_bus, &cpu_path);
508
509 if (info->index != 0)
510 printk(BIOS_CRIT, "BSP index(%d) != 0!\n", info->index);
511
512 /* Track BSP in cpu_map structures. */
513 cpus[info->index].dev = info->cpu;
514 cpus[info->index].apic_id = cpu_path.apic.apic_id;
515}
516
517int mp_init(struct bus *cpu_bus, struct mp_params *p)
518{
519 int num_cpus;
520 int num_aps;
521 atomic_t *ap_count;
522
523 init_bsp(cpu_bus);
524
525 if (p == NULL || p->flight_plan == NULL || p->num_records < 1) {
526 printk(BIOS_CRIT, "Invalid MP parameters\n");
527 return -1;
528 }
529
530 /* Default to currently running CPU. */
531 num_cpus = allocate_cpu_devices(cpu_bus, p);
532
533 if (num_cpus < p->num_cpus) {
534 printk(BIOS_CRIT,
535 "ERROR: More cpus requested (%d) than supported (%d).\n",
536 p->num_cpus, num_cpus);
537 return -1;
538 }
539
540 /* Copy needed parameters so that APs have a reference to the plan. */
541 mp_info.num_records = p->num_records;
542 mp_info.records = p->flight_plan;
543
544 /* Load the SIPI vector. */
545 ap_count = load_sipi_vector(p);
546 if (ap_count == NULL)
547 return -1;
548
549 /* Make sure SIPI data hits RAM so the APs that come up will see
550 * the startup code even if the caches are disabled. */
551 wbinvd();
552
553 /* Start the APs providing number of APs and the cpus_entered field. */
554 num_aps = p->num_cpus - 1;
555 if (start_aps(cpu_bus, num_aps, ap_count) < 0) {
556 mdelay(1000);
557 printk(BIOS_DEBUG, "%d/%d eventually checked in?\n",
558 atomic_read(ap_count), num_aps);
559 return -1;
560 }
561
562 /* Walk the flight plan for the BSP. */
563 return bsp_do_flight_plan(p);
564}
565
566void mp_initialize_cpu(void *unused)
567{
568 /* Call back into driver infrastructure for the AP initialization. */
569 struct cpu_info *info = cpu_info();
570 cpu_initialize(info->index);
571}
572
573int mp_get_apic_id(int cpu_slot)
574{
575 if (cpu_slot >= CONFIG_MAX_CPUS || cpu_slot < 0)
576 return -1;
577
578 return cpus[cpu_slot].apic_id;
579}
Aaron Durbincd3f8ad2013-10-21 22:24:40 -0500580
581void smm_initiate_relocation_parallel(void)
582{
583 if ((lapic_read(LAPIC_ICR) & LAPIC_ICR_BUSY)) {
584 printk(BIOS_DEBUG, "Waiting for ICR not to be busy...");
585 if (apic_wait_timeout(1000 /* 1 ms */, 50)) {
586 printk(BIOS_DEBUG, "timed out. Aborting.\n");
587 return;
588 } else
589 printk(BIOS_DEBUG, "done.\n");
590 }
591
592 lapic_write_around(LAPIC_ICR2, SET_LAPIC_DEST_FIELD(lapicid()));
593 lapic_write_around(LAPIC_ICR, LAPIC_INT_ASSERT | LAPIC_DM_SMI);
594 if (apic_wait_timeout(1000 /* 1 ms */, 100 /* us */)) {
595 printk(BIOS_DEBUG, "SMI Relocation timed out.\n");
596 } else
597 printk(BIOS_DEBUG, "Relocation complete.\n");
598
599}
600
601DECLARE_SPIN_LOCK(smm_relocation_lock);
602
603/* Send SMI to self with single user serialization. */
604void smm_initiate_relocation(void)
605{
606 spin_lock(&smm_relocation_lock);
607 smm_initiate_relocation_parallel();
608 spin_unlock(&smm_relocation_lock);
609}