Skip to content

Commit 75c8905

Browse files
leoliu-ocopsiff
authored andcommitted
x86/microcode: Add Zhaoxin cpu microcode update driver
zhaoxin inclusion category: feature -------------------- Add support for Zhaoxin CPU in the x86 microcode loading facility to enable microcode loading during the OS stage. Currently, Zhaoxin CPU only support early microcode loading. Signed-off-by: leoliu-oc <[email protected]>
1 parent 40f39f0 commit 75c8905

File tree

5 files changed

+673
-7
lines changed

5 files changed

+673
-7
lines changed

arch/x86/Kconfig

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1318,7 +1318,7 @@ config X86_REBOOTFIXUPS
13181318

13191319
config MICROCODE
13201320
def_bool y
1321-
depends on CPU_SUP_AMD || CPU_SUP_INTEL || CPU_SUP_HYGON
1321+
depends on CPU_SUP_AMD || CPU_SUP_INTEL || CPU_SUP_HYGON || CPU_SUP_ZHAOXIN || CPU_SUP_CENTAUR
13221322
select CRYPTO_LIB_SHA256 if CPU_SUP_AMD
13231323

13241324
config MICROCODE_INITRD32

arch/x86/kernel/cpu/microcode/Makefile

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,3 +3,6 @@ microcode-y := core.o
33
obj-$(CONFIG_MICROCODE) += microcode.o
44
microcode-$(CONFIG_CPU_SUP_INTEL) += intel.o
55
microcode-$(CONFIG_CPU_SUP_AMD) += amd.o
6+
ifneq ($(CONFIG_CPU_SUP_ZHAOXIN)$(CONFIG_CPU_SUP_CENTAUR),)
7+
microcode-y += zhaoxin.o
8+
endif

arch/x86/kernel/cpu/microcode/core.c

Lines changed: 34 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -135,14 +135,15 @@ static bool __init check_loader_disabled_bsp(void)
135135
void __init load_ucode_bsp(void)
136136
{
137137
unsigned int cpuid_1_eax;
138-
bool intel = true;
138+
unsigned int x86_vendor;
139139

140140
if (!have_cpuid_p())
141141
return;
142142

143143
cpuid_1_eax = native_cpuid_eax(1);
144+
x86_vendor = x86_cpuid_vendor();
144145

145-
switch (x86_cpuid_vendor()) {
146+
switch (x86_vendor) {
146147
case X86_VENDOR_INTEL:
147148
if (x86_family(cpuid_1_eax) < 6)
148149
return;
@@ -151,11 +152,15 @@ void __init load_ucode_bsp(void)
151152
case X86_VENDOR_AMD:
152153
if (x86_family(cpuid_1_eax) < 0x10)
153154
return;
154-
intel = false;
155155
break;
156156

157157
case X86_VENDOR_HYGON:
158-
intel = false;
158+
break;
159+
160+
case X86_VENDOR_ZHAOXIN:
161+
case X86_VENDOR_CENTAUR:
162+
if ((cpuid_eax(0xC0000000) < 0xC0000004) || !(cpuid_edx(0xC0000004) & 0x1))
163+
return;
159164
break;
160165

161166
default:
@@ -165,10 +170,21 @@ void __init load_ucode_bsp(void)
165170
if (check_loader_disabled_bsp())
166171
return;
167172

168-
if (intel)
173+
switch (x86_vendor) {
174+
case X86_VENDOR_INTEL:
169175
load_ucode_intel_bsp(&early_data);
170-
else
176+
break;
177+
case X86_VENDOR_AMD:
178+
case X86_VENDOR_HYGON:
171179
load_ucode_amd_bsp(&early_data, cpuid_1_eax);
180+
break;
181+
case X86_VENDOR_ZHAOXIN:
182+
case X86_VENDOR_CENTAUR:
183+
load_ucode_zhaoxin_bsp(&early_data);
184+
break;
185+
default:
186+
return;
187+
}
172188
}
173189

174190
void load_ucode_ap(void)
@@ -192,6 +208,11 @@ void load_ucode_ap(void)
192208
case X86_VENDOR_HYGON:
193209
load_ucode_amd_ap(cpuid_1_eax);
194210
break;
211+
case X86_VENDOR_ZHAOXIN:
212+
case X86_VENDOR_CENTAUR:
213+
if ((cpuid_eax(0xC0000000) >= 0xC0000004) && (cpuid_edx(0xC0000004) & 0x1))
214+
load_ucode_zhaoxin_ap();
215+
break;
195216
default:
196217
break;
197218
}
@@ -254,6 +275,10 @@ static void reload_early_microcode(unsigned int cpu)
254275
case X86_VENDOR_HYGON:
255276
reload_ucode_amd(cpu);
256277
break;
278+
case X86_VENDOR_ZHAOXIN:
279+
case X86_VENDOR_CENTAUR:
280+
reload_ucode_zhaoxin();
281+
break;
257282
default:
258283
break;
259284
}
@@ -843,6 +868,9 @@ static int __init microcode_init(void)
843868
microcode_ops = init_amd_microcode();
844869
else if (c->x86_vendor == X86_VENDOR_HYGON)
845870
microcode_ops = init_hygon_microcode();
871+
else if (c->x86_vendor == X86_VENDOR_ZHAOXIN ||
872+
c->x86_vendor == X86_VENDOR_CENTAUR)
873+
microcode_ops = init_zhaoxin_microcode();
846874
else
847875
pr_err("no support for this CPU vendor\n");
848876

arch/x86/kernel/cpu/microcode/internal.h

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,12 @@ struct cpio_data find_microcode_in_initrd(const char *path);
5858
#define CPUID_HYGON1 QCHAR('H', 'y', 'g', 'o')
5959
#define CPUID_HYGON2 QCHAR('n', 'G', 'e', 'n')
6060
#define CPUID_HYGON3 QCHAR('u', 'i', 'n', 'e')
61+
#define CPUID_ZHAOXIN1 QCHAR(' ', ' ', 'S', 'h')
62+
#define CPUID_ZHAOXIN2 QCHAR('a', 'n', 'g', 'h')
63+
#define CPUID_ZHAOXIN3 QCHAR('a', 'i', ' ', ' ')
64+
#define CPUID_CENTAUR1 QCHAR('C', 'e', 'n', 't')
65+
#define CPUID_CENTAUR2 QCHAR('a', 'u', 'r', 'H')
66+
#define CPUID_CENTAUR3 QCHAR('a', 'u', 'l', 's')
6167

6268
#define CPUID_IS(a, b, c, ebx, ecx, edx) \
6369
(!(((ebx) ^ (a)) | ((edx) ^ (b)) | ((ecx) ^ (c))))
@@ -87,6 +93,12 @@ static inline int x86_cpuid_vendor(void)
8793
if (CPUID_IS(CPUID_HYGON1, CPUID_HYGON2, CPUID_HYGON3, ebx, ecx, edx))
8894
return X86_VENDOR_HYGON;
8995

96+
if (CPUID_IS(CPUID_ZHAOXIN1, CPUID_ZHAOXIN2, CPUID_ZHAOXIN3, ebx, ecx, edx))
97+
return X86_VENDOR_ZHAOXIN;
98+
99+
if (CPUID_IS(CPUID_CENTAUR1, CPUID_CENTAUR2, CPUID_CENTAUR3, ebx, ecx, edx))
100+
return X86_VENDOR_CENTAUR;
101+
90102
return X86_VENDOR_UNKNOWN;
91103
}
92104

@@ -137,4 +149,19 @@ static inline void reload_ucode_intel(void) { }
137149
static inline struct microcode_ops *init_intel_microcode(void) { return NULL; }
138150
#endif /* !CONFIG_CPU_SUP_INTEL */
139151

152+
#if defined(CONFIG_CPU_SUP_ZHAOXIN) || defined(CONFIG_CPU_SUP_CENTAUR)
153+
void load_ucode_zhaoxin_bsp(struct early_load_data *ed);
154+
void load_ucode_zhaoxin_ap(void);
155+
void reload_ucode_zhaoxin(void);
156+
struct microcode_ops *init_zhaoxin_microcode(void);
157+
#else /* CONFIG_CPU_SUP_ZHAOXIN || CONFIG_CPU_SUP_CENTAUR */
158+
static inline void load_ucode_zhaoxin_bsp(struct early_load_data *ed) { }
159+
static inline void load_ucode_zhaoxin_ap(void) { }
160+
static inline void reload_ucode_zhaoxin(void) { }
161+
static inline struct microcode_ops *init_zhaoxin_microcode(void)
162+
{
163+
return NULL;
164+
}
165+
#endif /* !CONFIG_CPU_SUP_ZHAOXIN && !CONFIG_CPU_SUP_CENTAUR */
166+
140167
#endif /* _X86_MICROCODE_INTERNAL_H */

0 commit comments

Comments
 (0)