Merge tag 'efi-2020-07-rc6' of https://gitlab.denx.de/u-boot/custodians/u-boot-efi
[oweals/u-boot.git] / arch / x86 / cpu / i386 / cpu.c
1 // SPDX-License-Identifier: GPL-2.0+
2 /*
3  * (C) Copyright 2008-2011
4  * Graeme Russ, <graeme.russ@gmail.com>
5  *
6  * (C) Copyright 2002
7  * Daniel Engström, Omicron Ceti AB, <daniel@omicron.se>
8  *
9  * (C) Copyright 2002
10  * Sysgo Real-Time Solutions, GmbH <www.elinos.com>
11  * Marius Groeger <mgroeger@sysgo.de>
12  *
13  * (C) Copyright 2002
14  * Sysgo Real-Time Solutions, GmbH <www.elinos.com>
15  * Alex Zuepke <azu@sysgo.de>
16  *
17  * Part of this file is adapted from coreboot
18  * src/arch/x86/lib/cpu.c
19  */
20
21 #include <common.h>
22 #include <cpu_func.h>
23 #include <init.h>
24 #include <malloc.h>
25 #include <spl.h>
26 #include <asm/control_regs.h>
27 #include <asm/coreboot_tables.h>
28 #include <asm/cpu.h>
29 #include <asm/mp.h>
30 #include <asm/msr.h>
31 #include <asm/mtrr.h>
32 #include <asm/processor-flags.h>
33
34 DECLARE_GLOBAL_DATA_PTR;
35
36 /*
37  * Constructor for a conventional segment GDT (or LDT) entry
38  * This is a macro so it can be used in initialisers
39  */
40 #define GDT_ENTRY(flags, base, limit)                   \
41         ((((base)  & 0xff000000ULL) << (56-24)) |       \
42          (((flags) & 0x0000f0ffULL) << 40) |            \
43          (((limit) & 0x000f0000ULL) << (48-16)) |       \
44          (((base)  & 0x00ffffffULL) << 16) |            \
45          (((limit) & 0x0000ffffULL)))
46
47 struct gdt_ptr {
48         u16 len;
49         u32 ptr;
50 } __packed;
51
52 struct cpu_device_id {
53         unsigned vendor;
54         unsigned device;
55 };
56
57 struct cpuinfo_x86 {
58         uint8_t x86;            /* CPU family */
59         uint8_t x86_vendor;     /* CPU vendor */
60         uint8_t x86_model;
61         uint8_t x86_mask;
62 };
63
64 /* gcc 7.3 does not wwant to drop x86_vendors, so use #ifdef */
65 #ifndef CONFIG_TPL_BUILD
66 /*
67  * List of cpu vendor strings along with their normalized
68  * id values.
69  */
70 static const struct {
71         int vendor;
72         const char *name;
73 } x86_vendors[] = {
74         { X86_VENDOR_INTEL,     "GenuineIntel", },
75         { X86_VENDOR_CYRIX,     "CyrixInstead", },
76         { X86_VENDOR_AMD,       "AuthenticAMD", },
77         { X86_VENDOR_UMC,       "UMC UMC UMC ", },
78         { X86_VENDOR_NEXGEN,    "NexGenDriven", },
79         { X86_VENDOR_CENTAUR,   "CentaurHauls", },
80         { X86_VENDOR_RISE,      "RiseRiseRise", },
81         { X86_VENDOR_TRANSMETA, "GenuineTMx86", },
82         { X86_VENDOR_TRANSMETA, "TransmetaCPU", },
83         { X86_VENDOR_NSC,       "Geode by NSC", },
84         { X86_VENDOR_SIS,       "SiS SiS SiS ", },
85 };
86 #endif
87
88 static void load_ds(u32 segment)
89 {
90         asm volatile("movl %0, %%ds" : : "r" (segment * X86_GDT_ENTRY_SIZE));
91 }
92
93 static void load_es(u32 segment)
94 {
95         asm volatile("movl %0, %%es" : : "r" (segment * X86_GDT_ENTRY_SIZE));
96 }
97
98 static void load_fs(u32 segment)
99 {
100         asm volatile("movl %0, %%fs" : : "r" (segment * X86_GDT_ENTRY_SIZE));
101 }
102
103 static void load_gs(u32 segment)
104 {
105         asm volatile("movl %0, %%gs" : : "r" (segment * X86_GDT_ENTRY_SIZE));
106 }
107
108 static void load_ss(u32 segment)
109 {
110         asm volatile("movl %0, %%ss" : : "r" (segment * X86_GDT_ENTRY_SIZE));
111 }
112
113 static void load_gdt(const u64 *boot_gdt, u16 num_entries)
114 {
115         struct gdt_ptr gdt;
116
117         gdt.len = (num_entries * X86_GDT_ENTRY_SIZE) - 1;
118         gdt.ptr = (ulong)boot_gdt;
119
120         asm volatile("lgdtl %0\n" : : "m" (gdt));
121 }
122
123 void arch_setup_gd(gd_t *new_gd)
124 {
125         u64 *gdt_addr;
126
127         gdt_addr = new_gd->arch.gdt;
128
129         /*
130          * CS: code, read/execute, 4 GB, base 0
131          *
132          * Some OS (like VxWorks) requires GDT entry 1 to be the 32-bit CS
133          */
134         gdt_addr[X86_GDT_ENTRY_UNUSED] = GDT_ENTRY(0xc09b, 0, 0xfffff);
135         gdt_addr[X86_GDT_ENTRY_32BIT_CS] = GDT_ENTRY(0xc09b, 0, 0xfffff);
136
137         /* DS: data, read/write, 4 GB, base 0 */
138         gdt_addr[X86_GDT_ENTRY_32BIT_DS] = GDT_ENTRY(0xc093, 0, 0xfffff);
139
140         /*
141          * FS: data, read/write, sizeof (Global Data Pointer),
142          * base (Global Data Pointer)
143          */
144         new_gd->arch.gd_addr = new_gd;
145         gdt_addr[X86_GDT_ENTRY_32BIT_FS] = GDT_ENTRY(0x8093,
146                                         (ulong)&new_gd->arch.gd_addr,
147                                         sizeof(new_gd->arch.gd_addr) - 1);
148
149         /* 16-bit CS: code, read/execute, 64 kB, base 0 */
150         gdt_addr[X86_GDT_ENTRY_16BIT_CS] = GDT_ENTRY(0x009b, 0, 0x0ffff);
151
152         /* 16-bit DS: data, read/write, 64 kB, base 0 */
153         gdt_addr[X86_GDT_ENTRY_16BIT_DS] = GDT_ENTRY(0x0093, 0, 0x0ffff);
154
155         gdt_addr[X86_GDT_ENTRY_16BIT_FLAT_CS] = GDT_ENTRY(0x809b, 0, 0xfffff);
156         gdt_addr[X86_GDT_ENTRY_16BIT_FLAT_DS] = GDT_ENTRY(0x8093, 0, 0xfffff);
157
158         load_gdt(gdt_addr, X86_GDT_NUM_ENTRIES);
159         load_ds(X86_GDT_ENTRY_32BIT_DS);
160         load_es(X86_GDT_ENTRY_32BIT_DS);
161         load_gs(X86_GDT_ENTRY_32BIT_DS);
162         load_ss(X86_GDT_ENTRY_32BIT_DS);
163         load_fs(X86_GDT_ENTRY_32BIT_FS);
164 }
165
166 #ifdef CONFIG_HAVE_FSP
167 /*
168  * Setup FSP execution environment GDT
169  *
170  * Per Intel FSP external architecture specification, before calling any FSP
171  * APIs, we need make sure the system is in flat 32-bit mode and both the code
172  * and data selectors should have full 4GB access range. Here we reuse the one
173  * we used in arch/x86/cpu/start16.S, and reload the segement registers.
174  */
175 void setup_fsp_gdt(void)
176 {
177         load_gdt((const u64 *)(gdt_rom + CONFIG_RESET_SEG_START), 4);
178         load_ds(X86_GDT_ENTRY_32BIT_DS);
179         load_ss(X86_GDT_ENTRY_32BIT_DS);
180         load_es(X86_GDT_ENTRY_32BIT_DS);
181         load_fs(X86_GDT_ENTRY_32BIT_DS);
182         load_gs(X86_GDT_ENTRY_32BIT_DS);
183 }
184 #endif
185
186 /*
187  * Cyrix CPUs without cpuid or with cpuid not yet enabled can be detected
188  * by the fact that they preserve the flags across the division of 5/2.
189  * PII and PPro exhibit this behavior too, but they have cpuid available.
190  */
191
192 /*
193  * Perform the Cyrix 5/2 test. A Cyrix won't change
194  * the flags, while other 486 chips will.
195  */
196 static inline int test_cyrix_52div(void)
197 {
198         unsigned int test;
199
200         __asm__ __volatile__(
201              "sahf\n\t"         /* clear flags (%eax = 0x0005) */
202              "div %b2\n\t"      /* divide 5 by 2 */
203              "lahf"             /* store flags into %ah */
204              : "=a" (test)
205              : "0" (5), "q" (2)
206              : "cc");
207
208         /* AH is 0x02 on Cyrix after the divide.. */
209         return (unsigned char) (test >> 8) == 0x02;
210 }
211
212 #ifndef CONFIG_TPL_BUILD
213 /*
214  *      Detect a NexGen CPU running without BIOS hypercode new enough
215  *      to have CPUID. (Thanks to Herbert Oppmann)
216  */
217 static int deep_magic_nexgen_probe(void)
218 {
219         int ret;
220
221         __asm__ __volatile__ (
222                 "       movw    $0x5555, %%ax\n"
223                 "       xorw    %%dx,%%dx\n"
224                 "       movw    $2, %%cx\n"
225                 "       divw    %%cx\n"
226                 "       movl    $0, %%eax\n"
227                 "       jnz     1f\n"
228                 "       movl    $1, %%eax\n"
229                 "1:\n"
230                 : "=a" (ret) : : "cx", "dx");
231         return  ret;
232 }
233 #endif
234
235 static bool has_cpuid(void)
236 {
237         return flag_is_changeable_p(X86_EFLAGS_ID);
238 }
239
240 static bool has_mtrr(void)
241 {
242         return cpuid_edx(0x00000001) & (1 << 12) ? true : false;
243 }
244
245 #ifndef CONFIG_TPL_BUILD
246 static int build_vendor_name(char *vendor_name)
247 {
248         struct cpuid_result result;
249         result = cpuid(0x00000000);
250         unsigned int *name_as_ints = (unsigned int *)vendor_name;
251
252         name_as_ints[0] = result.ebx;
253         name_as_ints[1] = result.edx;
254         name_as_ints[2] = result.ecx;
255
256         return result.eax;
257 }
258 #endif
259
260 static void identify_cpu(struct cpu_device_id *cpu)
261 {
262         cpu->device = 0; /* fix gcc 4.4.4 warning */
263
264         /*
265          * Do a quick and dirty check to save space - Intel and AMD only and
266          * just the vendor. This is enough for most TPL code.
267          */
268         if (spl_phase() == PHASE_TPL) {
269                 struct cpuid_result result;
270
271                 result = cpuid(0x00000000);
272                 switch (result.ecx >> 24) {
273                 case 'l': /* GenuineIntel */
274                         cpu->vendor = X86_VENDOR_INTEL;
275                         break;
276                 case 'D': /* AuthenticAMD */
277                         cpu->vendor = X86_VENDOR_AMD;
278                         break;
279                 default:
280                         cpu->vendor = X86_VENDOR_ANY;
281                         break;
282                 }
283                 return;
284         }
285
286 /* gcc 7.3 does not want to drop x86_vendors, so use #ifdef */
287 #ifndef CONFIG_TPL_BUILD
288         char vendor_name[16];
289         int i;
290
291         vendor_name[0] = '\0'; /* Unset */
292
293         /* Find the id and vendor_name */
294         if (!has_cpuid()) {
295                 /* Its a 486 if we can modify the AC flag */
296                 if (flag_is_changeable_p(X86_EFLAGS_AC))
297                         cpu->device = 0x00000400; /* 486 */
298                 else
299                         cpu->device = 0x00000300; /* 386 */
300                 if ((cpu->device == 0x00000400) && test_cyrix_52div()) {
301                         memcpy(vendor_name, "CyrixInstead", 13);
302                         /* If we ever care we can enable cpuid here */
303                 }
304                 /* Detect NexGen with old hypercode */
305                 else if (deep_magic_nexgen_probe())
306                         memcpy(vendor_name, "NexGenDriven", 13);
307         } else {
308                 int cpuid_level;
309
310                 cpuid_level = build_vendor_name(vendor_name);
311                 vendor_name[12] = '\0';
312
313                 /* Intel-defined flags: level 0x00000001 */
314                 if (cpuid_level >= 0x00000001) {
315                         cpu->device = cpuid_eax(0x00000001);
316                 } else {
317                         /* Have CPUID level 0 only unheard of */
318                         cpu->device = 0x00000400;
319                 }
320         }
321         cpu->vendor = X86_VENDOR_UNKNOWN;
322         for (i = 0; i < ARRAY_SIZE(x86_vendors); i++) {
323                 if (memcmp(vendor_name, x86_vendors[i].name, 12) == 0) {
324                         cpu->vendor = x86_vendors[i].vendor;
325                         break;
326                 }
327         }
328 #endif
329 }
330
331 static inline void get_fms(struct cpuinfo_x86 *c, uint32_t tfms)
332 {
333         c->x86 = (tfms >> 8) & 0xf;
334         c->x86_model = (tfms >> 4) & 0xf;
335         c->x86_mask = tfms & 0xf;
336         if (c->x86 == 0xf)
337                 c->x86 += (tfms >> 20) & 0xff;
338         if (c->x86 >= 0x6)
339                 c->x86_model += ((tfms >> 16) & 0xF) << 4;
340 }
341
342 u32 cpu_get_family_model(void)
343 {
344         return gd->arch.x86_device & 0x0fff0ff0;
345 }
346
347 u32 cpu_get_stepping(void)
348 {
349         return gd->arch.x86_mask;
350 }
351
352 /* initialise FPU, reset EM, set MP and NE */
353 static void setup_cpu_features(void)
354 {
355         const u32 em_rst = ~X86_CR0_EM;
356         const u32 mp_ne_set = X86_CR0_MP | X86_CR0_NE;
357
358         asm ("fninit\n" \
359         "movl %%cr0, %%eax\n" \
360         "andl %0, %%eax\n" \
361         "orl  %1, %%eax\n" \
362         "movl %%eax, %%cr0\n" \
363         : : "i" (em_rst), "i" (mp_ne_set) : "eax");
364 }
365
366 static void setup_identity(void)
367 {
368         /* identify CPU via cpuid and store the decoded info into gd->arch */
369         if (has_cpuid()) {
370                 struct cpu_device_id cpu;
371                 struct cpuinfo_x86 c;
372
373                 identify_cpu(&cpu);
374                 get_fms(&c, cpu.device);
375                 gd->arch.x86 = c.x86;
376                 gd->arch.x86_vendor = cpu.vendor;
377                 gd->arch.x86_model = c.x86_model;
378                 gd->arch.x86_mask = c.x86_mask;
379                 gd->arch.x86_device = cpu.device;
380
381                 gd->arch.has_mtrr = has_mtrr();
382         }
383 }
384
385 /* Don't allow PCI region 3 to use memory in the 2-4GB memory hole */
386 static void setup_pci_ram_top(void)
387 {
388         gd->pci_ram_top = 0x80000000U;
389 }
390
391 static void setup_mtrr(void)
392 {
393         u64 mtrr_cap;
394
395         /* Configure fixed range MTRRs for some legacy regions */
396         if (!gd->arch.has_mtrr)
397                 return;
398
399         mtrr_cap = native_read_msr(MTRR_CAP_MSR);
400         if (mtrr_cap & MTRR_CAP_FIX) {
401                 /* Mark the VGA RAM area as uncacheable */
402                 native_write_msr(MTRR_FIX_16K_A0000_MSR,
403                                  MTRR_FIX_TYPE(MTRR_TYPE_UNCACHEABLE),
404                                  MTRR_FIX_TYPE(MTRR_TYPE_UNCACHEABLE));
405
406                 /*
407                  * Mark the PCI ROM area as cacheable to improve ROM
408                  * execution performance.
409                  */
410                 native_write_msr(MTRR_FIX_4K_C0000_MSR,
411                                  MTRR_FIX_TYPE(MTRR_TYPE_WRBACK),
412                                  MTRR_FIX_TYPE(MTRR_TYPE_WRBACK));
413                 native_write_msr(MTRR_FIX_4K_C8000_MSR,
414                                  MTRR_FIX_TYPE(MTRR_TYPE_WRBACK),
415                                  MTRR_FIX_TYPE(MTRR_TYPE_WRBACK));
416                 native_write_msr(MTRR_FIX_4K_D0000_MSR,
417                                  MTRR_FIX_TYPE(MTRR_TYPE_WRBACK),
418                                  MTRR_FIX_TYPE(MTRR_TYPE_WRBACK));
419                 native_write_msr(MTRR_FIX_4K_D8000_MSR,
420                                  MTRR_FIX_TYPE(MTRR_TYPE_WRBACK),
421                                  MTRR_FIX_TYPE(MTRR_TYPE_WRBACK));
422
423                 /* Enable the fixed range MTRRs */
424                 msr_setbits_64(MTRR_DEF_TYPE_MSR, MTRR_DEF_TYPE_FIX_EN);
425         }
426 }
427
428 int x86_cpu_init_tpl(void)
429 {
430         setup_cpu_features();
431         setup_identity();
432
433         return 0;
434 }
435
436 int x86_cpu_init_f(void)
437 {
438         if (ll_boot_init())
439                 setup_cpu_features();
440         setup_identity();
441         setup_mtrr();
442         setup_pci_ram_top();
443
444         /* Set up the i8254 timer if required */
445         if (IS_ENABLED(CONFIG_I8254_TIMER))
446                 i8254_init();
447
448         return 0;
449 }
450
451 int x86_cpu_reinit_f(void)
452 {
453         setup_identity();
454         setup_pci_ram_top();
455         if (locate_coreboot_table() >= 0)
456                 gd->flags |= GD_FLG_SKIP_LL_INIT;
457
458         return 0;
459 }
460
461 void x86_enable_caches(void)
462 {
463         unsigned long cr0;
464
465         cr0 = read_cr0();
466         cr0 &= ~(X86_CR0_NW | X86_CR0_CD);
467         write_cr0(cr0);
468         wbinvd();
469 }
470 void enable_caches(void) __attribute__((weak, alias("x86_enable_caches")));
471
472 void x86_disable_caches(void)
473 {
474         unsigned long cr0;
475
476         cr0 = read_cr0();
477         cr0 |= X86_CR0_NW | X86_CR0_CD;
478         wbinvd();
479         write_cr0(cr0);
480         wbinvd();
481 }
482 void disable_caches(void) __attribute__((weak, alias("x86_disable_caches")));
483
484 int dcache_status(void)
485 {
486         return !(read_cr0() & X86_CR0_CD);
487 }
488
489 void cpu_enable_paging_pae(ulong cr3)
490 {
491         __asm__ __volatile__(
492                 /* Load the page table address */
493                 "movl   %0, %%cr3\n"
494                 /* Enable pae */
495                 "movl   %%cr4, %%eax\n"
496                 "orl    $0x00000020, %%eax\n"
497                 "movl   %%eax, %%cr4\n"
498                 /* Enable paging */
499                 "movl   %%cr0, %%eax\n"
500                 "orl    $0x80000000, %%eax\n"
501                 "movl   %%eax, %%cr0\n"
502                 :
503                 : "r" (cr3)
504                 : "eax");
505 }
506
507 void cpu_disable_paging_pae(void)
508 {
509         /* Turn off paging */
510         __asm__ __volatile__ (
511                 /* Disable paging */
512                 "movl   %%cr0, %%eax\n"
513                 "andl   $0x7fffffff, %%eax\n"
514                 "movl   %%eax, %%cr0\n"
515                 /* Disable pae */
516                 "movl   %%cr4, %%eax\n"
517                 "andl   $0xffffffdf, %%eax\n"
518                 "movl   %%eax, %%cr4\n"
519                 :
520                 :
521                 : "eax");
522 }
523
524 static bool can_detect_long_mode(void)
525 {
526         return cpuid_eax(0x80000000) > 0x80000000UL;
527 }
528
529 static bool has_long_mode(void)
530 {
531         return cpuid_edx(0x80000001) & (1 << 29) ? true : false;
532 }
533
534 int cpu_has_64bit(void)
535 {
536         return has_cpuid() && can_detect_long_mode() &&
537                 has_long_mode();
538 }
539
540 #define PAGETABLE_BASE          0x80000
541 #define PAGETABLE_SIZE          (6 * 4096)
542
543 /**
544  * build_pagetable() - build a flat 4GiB page table structure for 64-bti mode
545  *
546  * @pgtable: Pointer to a 24iKB block of memory
547  */
548 static void build_pagetable(uint32_t *pgtable)
549 {
550         uint i;
551
552         memset(pgtable, '\0', PAGETABLE_SIZE);
553
554         /* Level 4 needs a single entry */
555         pgtable[0] = (ulong)&pgtable[1024] + 7;
556
557         /* Level 3 has one 64-bit entry for each GiB of memory */
558         for (i = 0; i < 4; i++)
559                 pgtable[1024 + i * 2] = (ulong)&pgtable[2048] + 0x1000 * i + 7;
560
561         /* Level 2 has 2048 64-bit entries, each repesenting 2MiB */
562         for (i = 0; i < 2048; i++)
563                 pgtable[2048 + i * 2] = 0x183 + (i << 21UL);
564 }
565
566 int cpu_jump_to_64bit(ulong setup_base, ulong target)
567 {
568         uint32_t *pgtable;
569
570         pgtable = memalign(4096, PAGETABLE_SIZE);
571         if (!pgtable)
572                 return -ENOMEM;
573
574         build_pagetable(pgtable);
575         cpu_call64((ulong)pgtable, setup_base, target);
576         free(pgtable);
577
578         return -EFAULT;
579 }
580
581 /*
582  * Jump from SPL to U-Boot
583  *
584  * This function is work-in-progress with many issues to resolve.
585  *
586  * It works by setting up several regions:
587  *   ptr      - a place to put the code that jumps into 64-bit mode
588  *   gdt      - a place to put the global descriptor table
589  *   pgtable  - a place to put the page tables
590  *
591  * The cpu_call64() code is copied from ROM and then manually patched so that
592  * it has the correct GDT address in RAM. U-Boot is copied from ROM into
593  * its pre-relocation address. Then we jump to the cpu_call64() code in RAM,
594  * which changes to 64-bit mode and starts U-Boot.
595  */
596 int cpu_jump_to_64bit_uboot(ulong target)
597 {
598         typedef void (*func_t)(ulong pgtable, ulong setup_base, ulong target);
599         uint32_t *pgtable;
600         func_t func;
601         char *ptr;
602
603         pgtable = (uint32_t *)PAGETABLE_BASE;
604
605         build_pagetable(pgtable);
606
607         extern long call64_stub_size;
608         ptr = malloc(call64_stub_size);
609         if (!ptr) {
610                 printf("Failed to allocate the cpu_call64 stub\n");
611                 return -ENOMEM;
612         }
613         memcpy(ptr, cpu_call64, call64_stub_size);
614
615         func = (func_t)ptr;
616
617         /* Jump to U-Boot */
618         func((ulong)pgtable, 0, (ulong)target);
619
620         return -EFAULT;
621 }
622
623 #ifdef CONFIG_SMP
624 static int enable_smis(struct udevice *cpu, void *unused)
625 {
626         return 0;
627 }
628
629 static struct mp_flight_record mp_steps[] = {
630         MP_FR_BLOCK_APS(mp_init_cpu, NULL, mp_init_cpu, NULL),
631         /* Wait for APs to finish initialization before proceeding */
632         MP_FR_BLOCK_APS(NULL, NULL, enable_smis, NULL),
633 };
634
635 int x86_mp_init(void)
636 {
637         struct mp_params mp_params;
638
639         mp_params.parallel_microcode_load = 0,
640         mp_params.flight_plan = &mp_steps[0];
641         mp_params.num_records = ARRAY_SIZE(mp_steps);
642         mp_params.microcode_pointer = 0;
643
644         if (mp_init(&mp_params)) {
645                 printf("Warning: MP init failure\n");
646                 return -EIO;
647         }
648
649         return 0;
650 }
651 #endif