aboutsummaryrefslogtreecommitdiffstats
path: root/arch/x86/kernel/microcode_amd.c
diff options
context:
space:
mode:
authorDmitry Adamushko <dmitry.adamushko@gmail.com>2008-09-23 06:08:44 -0400
committerIngo Molnar <mingo@elte.hu>2008-09-23 06:21:42 -0400
commit18dbc9160507dc7df998e00cd1dcd7889557307b (patch)
tree81262b57db5de63267762083a54a37558d8555f0 /arch/x86/kernel/microcode_amd.c
parenta1c75cc5018f17ff6d80ce45a13435b1536f76db (diff)
x86: moved microcode.c to microcode_intel.c
Combine both generic and arch-specific parts of microcode into a single module (arch-specific parts are config-dependent). Also while we are at it, move arch-specific parts from microcode.h into their respective arch-specific .c files. Signed-off-by: Dmitry Adamushko <dmitry.adamushko@gmail.com> Cc: "Peter Oruba" <peter.oruba@amd.com> Signed-off-by: Ingo Molnar <mingo@elte.hu>
Diffstat (limited to 'arch/x86/kernel/microcode_amd.c')
-rw-r--r--arch/x86/kernel/microcode_amd.c72
1 files changed, 43 insertions, 29 deletions
diff --git a/arch/x86/kernel/microcode_amd.c b/arch/x86/kernel/microcode_amd.c
index 48aec9f48e4f..03ea4e52e87a 100644
--- a/arch/x86/kernel/microcode_amd.c
+++ b/arch/x86/kernel/microcode_amd.c
@@ -46,6 +46,35 @@ MODULE_LICENSE("GPL v2");
46#define UCODE_EQUIV_CPU_TABLE_TYPE 0x00000000 46#define UCODE_EQUIV_CPU_TABLE_TYPE 0x00000000
47#define UCODE_UCODE_TYPE 0x00000001 47#define UCODE_UCODE_TYPE 0x00000001
48 48
49struct equiv_cpu_entry {
50 unsigned int installed_cpu;
51 unsigned int fixed_errata_mask;
52 unsigned int fixed_errata_compare;
53 unsigned int equiv_cpu;
54};
55
56struct microcode_header_amd {
57 unsigned int data_code;
58 unsigned int patch_id;
59 unsigned char mc_patch_data_id[2];
60 unsigned char mc_patch_data_len;
61 unsigned char init_flag;
62 unsigned int mc_patch_data_checksum;
63 unsigned int nb_dev_id;
64 unsigned int sb_dev_id;
65 unsigned char processor_rev_id[2];
66 unsigned char nb_rev_id;
67 unsigned char sb_rev_id;
68 unsigned char bios_api_rev;
69 unsigned char reserved1[3];
70 unsigned int match_reg[8];
71};
72
73struct microcode_amd {
74 struct microcode_header_amd hdr;
75 unsigned int mpb[0];
76};
77
49#define UCODE_MAX_SIZE (2048) 78#define UCODE_MAX_SIZE (2048)
50#define DEFAULT_UCODE_DATASIZE (896) 79#define DEFAULT_UCODE_DATASIZE (896)
51#define MC_HEADER_SIZE (sizeof(struct microcode_header_amd)) 80#define MC_HEADER_SIZE (sizeof(struct microcode_header_amd))
@@ -189,17 +218,18 @@ static void apply_microcode_amd(int cpu)
189 unsigned int rev; 218 unsigned int rev;
190 int cpu_num = raw_smp_processor_id(); 219 int cpu_num = raw_smp_processor_id();
191 struct ucode_cpu_info *uci = ucode_cpu_info + cpu_num; 220 struct ucode_cpu_info *uci = ucode_cpu_info + cpu_num;
221 struct microcode_amd *mc_amd = uci->mc;
192 unsigned long addr; 222 unsigned long addr;
193 223
194 /* We should bind the task to the CPU */ 224 /* We should bind the task to the CPU */
195 BUG_ON(cpu_num != cpu); 225 BUG_ON(cpu_num != cpu);
196 226
197 if (uci->mc.mc_amd == NULL) 227 if (mc_amd == NULL)
198 return; 228 return;
199 229
200 spin_lock_irqsave(&microcode_update_lock, flags); 230 spin_lock_irqsave(&microcode_update_lock, flags);
201 231
202 addr = (unsigned long)&uci->mc.mc_amd->hdr.data_code; 232 addr = (unsigned long)&mc_amd->hdr.data_code;
203 edx = (unsigned int)(((unsigned long)upper_32_bits(addr))); 233 edx = (unsigned int)(((unsigned long)upper_32_bits(addr)));
204 eax = (unsigned int)(((unsigned long)lower_32_bits(addr))); 234 eax = (unsigned int)(((unsigned long)lower_32_bits(addr)));
205 235
@@ -214,16 +244,16 @@ static void apply_microcode_amd(int cpu)
214 spin_unlock_irqrestore(&microcode_update_lock, flags); 244 spin_unlock_irqrestore(&microcode_update_lock, flags);
215 245
216 /* check current patch id and patch's id for match */ 246 /* check current patch id and patch's id for match */
217 if (rev != uci->mc.mc_amd->hdr.patch_id) { 247 if (rev != mc_amd->hdr.patch_id) {
218 printk(KERN_ERR "microcode: CPU%d update from revision " 248 printk(KERN_ERR "microcode: CPU%d update from revision "
219 "0x%x to 0x%x failed\n", cpu_num, 249 "0x%x to 0x%x failed\n", cpu_num,
220 uci->mc.mc_amd->hdr.patch_id, rev); 250 mc_amd->hdr.patch_id, rev);
221 return; 251 return;
222 } 252 }
223 253
224 printk(KERN_INFO "microcode: CPU%d updated from revision " 254 printk(KERN_INFO "microcode: CPU%d updated from revision "
225 "0x%x to 0x%x \n", 255 "0x%x to 0x%x \n",
226 cpu_num, uci->cpu_sig.rev, uci->mc.mc_amd->hdr.patch_id); 256 cpu_num, uci->cpu_sig.rev, mc_amd->hdr.patch_id);
227 257
228 uci->cpu_sig.rev = rev; 258 uci->cpu_sig.rev = rev;
229} 259}
@@ -355,12 +385,12 @@ static int generic_load_microcode(int cpu, void *data, size_t size,
355 385
356 if (new_mc) { 386 if (new_mc) {
357 if (!leftover) { 387 if (!leftover) {
358 if (uci->mc.mc_amd) 388 if (uci->mc)
359 vfree(uci->mc.mc_amd); 389 vfree(uci->mc);
360 uci->mc.mc_amd = (struct microcode_amd *)new_mc; 390 uci->mc = new_mc;
361 pr_debug("microcode: CPU%d found a matching microcode update with" 391 pr_debug("microcode: CPU%d found a matching microcode update with"
362 " version 0x%x (current=0x%x)\n", 392 " version 0x%x (current=0x%x)\n",
363 cpu, uci->mc.mc_amd->hdr.patch_id, uci->cpu_sig.rev); 393 cpu, new_rev, uci->cpu_sig.rev);
364 } else 394 } else
365 vfree(new_mc); 395 vfree(new_mc);
366 } 396 }
@@ -416,8 +446,8 @@ static void microcode_fini_cpu_amd(int cpu)
416{ 446{
417 struct ucode_cpu_info *uci = ucode_cpu_info + cpu; 447 struct ucode_cpu_info *uci = ucode_cpu_info + cpu;
418 448
419 vfree(uci->mc.mc_amd); 449 vfree(uci->mc);
420 uci->mc.mc_amd = NULL; 450 uci->mc = NULL;
421} 451}
422 452
423static struct microcode_ops microcode_amd_ops = { 453static struct microcode_ops microcode_amd_ops = {
@@ -428,23 +458,7 @@ static struct microcode_ops microcode_amd_ops = {
428 .microcode_fini_cpu = microcode_fini_cpu_amd, 458 .microcode_fini_cpu = microcode_fini_cpu_amd,
429}; 459};
430 460
431static int __init microcode_amd_module_init(void) 461struct microcode_ops * __init init_amd_microcode(void)
432{ 462{
433 struct cpuinfo_x86 *c = &cpu_data(0); 463 return &microcode_amd_ops;
434
435 equiv_cpu_table = NULL;
436 if (c->x86_vendor != X86_VENDOR_AMD) {
437 printk(KERN_ERR "microcode: CPU platform is not AMD-capable\n");
438 return -ENODEV;
439 }
440
441 return microcode_init(&microcode_amd_ops, THIS_MODULE);
442}
443
444static void __exit microcode_amd_module_exit(void)
445{
446 microcode_exit();
447} 464}
448
449module_init(microcode_amd_module_init)
450module_exit(microcode_amd_module_exit)