]> git.kernelconcepts.de Git - karo-tx-linux.git/blob - arch/x86/kernel/cpu/microcode/core_early.c
h8300: Don't set CROSS_COMPILE unconditionally
[karo-tx-linux.git] / arch / x86 / kernel / cpu / microcode / core_early.c
1 /*
2  *      X86 CPU microcode early update for Linux
3  *
4  *      Copyright (C) 2012 Fenghua Yu <fenghua.yu@intel.com>
5  *                         H Peter Anvin" <hpa@zytor.com>
6  *                (C) 2015 Borislav Petkov <bp@alien8.de>
7  *
8  *      This driver allows to early upgrade microcode on Intel processors
9  *      belonging to IA-32 family - PentiumPro, Pentium II,
10  *      Pentium III, Xeon, Pentium 4, etc.
11  *
12  *      Reference: Section 9.11 of Volume 3, IA-32 Intel Architecture
13  *      Software Developer's Manual.
14  *
15  *      This program is free software; you can redistribute it and/or
16  *      modify it under the terms of the GNU General Public License
17  *      as published by the Free Software Foundation; either version
18  *      2 of the License, or (at your option) any later version.
19  */
20 #include <linux/module.h>
21 #include <linux/firmware.h>
22 #include <asm/microcode.h>
23 #include <asm/microcode_intel.h>
24 #include <asm/microcode_amd.h>
25 #include <asm/processor.h>
26 #include <asm/cmdline.h>
27
28 static bool __init check_loader_disabled_bsp(void)
29 {
30 #ifdef CONFIG_X86_32
31         const char *cmdline = (const char *)__pa_nodebug(boot_command_line);
32         const char *opt     = "dis_ucode_ldr";
33         const char *option  = (const char *)__pa_nodebug(opt);
34         bool *res = (bool *)__pa_nodebug(&dis_ucode_ldr);
35
36 #else /* CONFIG_X86_64 */
37         const char *cmdline = boot_command_line;
38         const char *option  = "dis_ucode_ldr";
39         bool *res = &dis_ucode_ldr;
40 #endif
41
42         if (cmdline_find_option_bool(cmdline, option))
43                 *res = true;
44
45         return *res;
46 }
47
48 extern struct builtin_fw __start_builtin_fw[];
49 extern struct builtin_fw __end_builtin_fw[];
50
51 bool get_builtin_firmware(struct cpio_data *cd, const char *name)
52 {
53 #ifdef CONFIG_FW_LOADER
54         struct builtin_fw *b_fw;
55
56         for (b_fw = __start_builtin_fw; b_fw != __end_builtin_fw; b_fw++) {
57                 if (!strcmp(name, b_fw->name)) {
58                         cd->size = b_fw->size;
59                         cd->data = b_fw->data;
60                         return true;
61                 }
62         }
63 #endif
64         return false;
65 }
66
67 void __init load_ucode_bsp(void)
68 {
69         int vendor;
70         unsigned int family;
71
72         if (check_loader_disabled_bsp())
73                 return;
74
75         if (!have_cpuid_p())
76                 return;
77
78         vendor = x86_vendor();
79         family = x86_family();
80
81         switch (vendor) {
82         case X86_VENDOR_INTEL:
83                 if (family >= 6)
84                         load_ucode_intel_bsp();
85                 break;
86         case X86_VENDOR_AMD:
87                 if (family >= 0x10)
88                         load_ucode_amd_bsp(family);
89                 break;
90         default:
91                 break;
92         }
93 }
94
95 static bool check_loader_disabled_ap(void)
96 {
97 #ifdef CONFIG_X86_32
98         return *((bool *)__pa_nodebug(&dis_ucode_ldr));
99 #else
100         return dis_ucode_ldr;
101 #endif
102 }
103
104 void load_ucode_ap(void)
105 {
106         int vendor, family;
107
108         if (check_loader_disabled_ap())
109                 return;
110
111         if (!have_cpuid_p())
112                 return;
113
114         vendor = x86_vendor();
115         family = x86_family();
116
117         switch (vendor) {
118         case X86_VENDOR_INTEL:
119                 if (family >= 6)
120                         load_ucode_intel_ap();
121                 break;
122         case X86_VENDOR_AMD:
123                 if (family >= 0x10)
124                         load_ucode_amd_ap();
125                 break;
126         default:
127                 break;
128         }
129 }
130
131 int __init save_microcode_in_initrd(void)
132 {
133         struct cpuinfo_x86 *c = &boot_cpu_data;
134
135         switch (c->x86_vendor) {
136         case X86_VENDOR_INTEL:
137                 if (c->x86 >= 6)
138                         save_microcode_in_initrd_intel();
139                 break;
140         case X86_VENDOR_AMD:
141                 if (c->x86 >= 0x10)
142                         save_microcode_in_initrd_amd();
143                 break;
144         default:
145                 break;
146         }
147
148         return 0;
149 }
150
151 void reload_early_microcode(void)
152 {
153         int vendor, family;
154
155         vendor = x86_vendor();
156         family = x86_family();
157
158         switch (vendor) {
159         case X86_VENDOR_INTEL:
160                 if (family >= 6)
161                         reload_ucode_intel();
162                 break;
163         case X86_VENDOR_AMD:
164                 if (family >= 0x10)
165                         reload_ucode_amd();
166                 break;
167         default:
168                 break;
169         }
170 }