diff options
Diffstat (limited to 'arch/x86/kernel/microcode_amd.c')
-rw-r--r-- | arch/x86/kernel/microcode_amd.c | 232 |
1 files changed, 86 insertions, 146 deletions
diff --git a/arch/x86/kernel/microcode_amd.c b/arch/x86/kernel/microcode_amd.c index 5f8e5d75a254..c25fdb382292 100644 --- a/arch/x86/kernel/microcode_amd.c +++ b/arch/x86/kernel/microcode_amd.c | |||
@@ -10,7 +10,7 @@ | |||
10 | * This driver allows to upgrade microcode on AMD | 10 | * This driver allows to upgrade microcode on AMD |
11 | * family 0x10 and 0x11 processors. | 11 | * family 0x10 and 0x11 processors. |
12 | * | 12 | * |
13 | * Licensed unter the terms of the GNU General Public | 13 | * Licensed under the terms of the GNU General Public |
14 | * License version 2. See file COPYING for details. | 14 | * License version 2. See file COPYING for details. |
15 | */ | 15 | */ |
16 | 16 | ||
@@ -32,9 +32,9 @@ | |||
32 | #include <linux/platform_device.h> | 32 | #include <linux/platform_device.h> |
33 | #include <linux/pci.h> | 33 | #include <linux/pci.h> |
34 | #include <linux/pci_ids.h> | 34 | #include <linux/pci_ids.h> |
35 | #include <linux/uaccess.h> | ||
35 | 36 | ||
36 | #include <asm/msr.h> | 37 | #include <asm/msr.h> |
37 | #include <asm/uaccess.h> | ||
38 | #include <asm/processor.h> | 38 | #include <asm/processor.h> |
39 | #include <asm/microcode.h> | 39 | #include <asm/microcode.h> |
40 | 40 | ||
@@ -47,43 +47,38 @@ MODULE_LICENSE("GPL v2"); | |||
47 | #define UCODE_UCODE_TYPE 0x00000001 | 47 | #define UCODE_UCODE_TYPE 0x00000001 |
48 | 48 | ||
49 | struct equiv_cpu_entry { | 49 | struct equiv_cpu_entry { |
50 | unsigned int installed_cpu; | 50 | u32 installed_cpu; |
51 | unsigned int fixed_errata_mask; | 51 | u32 fixed_errata_mask; |
52 | unsigned int fixed_errata_compare; | 52 | u32 fixed_errata_compare; |
53 | unsigned int equiv_cpu; | 53 | u16 equiv_cpu; |
54 | }; | 54 | u16 res; |
55 | } __attribute__((packed)); | ||
55 | 56 | ||
56 | struct microcode_header_amd { | 57 | struct microcode_header_amd { |
57 | unsigned int data_code; | 58 | u32 data_code; |
58 | unsigned int patch_id; | 59 | u32 patch_id; |
59 | unsigned char mc_patch_data_id[2]; | 60 | u16 mc_patch_data_id; |
60 | unsigned char mc_patch_data_len; | 61 | u8 mc_patch_data_len; |
61 | unsigned char init_flag; | 62 | u8 init_flag; |
62 | unsigned int mc_patch_data_checksum; | 63 | u32 mc_patch_data_checksum; |
63 | unsigned int nb_dev_id; | 64 | u32 nb_dev_id; |
64 | unsigned int sb_dev_id; | 65 | u32 sb_dev_id; |
65 | unsigned char processor_rev_id[2]; | 66 | u16 processor_rev_id; |
66 | unsigned char nb_rev_id; | 67 | u8 nb_rev_id; |
67 | unsigned char sb_rev_id; | 68 | u8 sb_rev_id; |
68 | unsigned char bios_api_rev; | 69 | u8 bios_api_rev; |
69 | unsigned char reserved1[3]; | 70 | u8 reserved1[3]; |
70 | unsigned int match_reg[8]; | 71 | u32 match_reg[8]; |
71 | }; | 72 | } __attribute__((packed)); |
72 | 73 | ||
73 | struct microcode_amd { | 74 | struct microcode_amd { |
74 | struct microcode_header_amd hdr; | 75 | struct microcode_header_amd hdr; |
75 | unsigned int mpb[0]; | 76 | unsigned int mpb[0]; |
76 | }; | 77 | }; |
77 | 78 | ||
78 | #define UCODE_MAX_SIZE (2048) | 79 | #define UCODE_MAX_SIZE 2048 |
79 | #define DEFAULT_UCODE_DATASIZE (896) | 80 | #define UCODE_CONTAINER_SECTION_HDR 8 |
80 | #define MC_HEADER_SIZE (sizeof(struct microcode_header_amd)) | 81 | #define UCODE_CONTAINER_HEADER_SIZE 12 |
81 | #define DEFAULT_UCODE_TOTALSIZE (DEFAULT_UCODE_DATASIZE + MC_HEADER_SIZE) | ||
82 | #define DWSIZE (sizeof(u32)) | ||
83 | /* For now we support a fixed ucode total size only */ | ||
84 | #define get_totalsize(mc) \ | ||
85 | ((((struct microcode_amd *)mc)->hdr.mc_patch_data_len * 28) \ | ||
86 | + MC_HEADER_SIZE) | ||
87 | 82 | ||
88 | /* serialize access to the physical write */ | 83 | /* serialize access to the physical write */ |
89 | static DEFINE_SPINLOCK(microcode_update_lock); | 84 | static DEFINE_SPINLOCK(microcode_update_lock); |
@@ -93,31 +88,24 @@ static struct equiv_cpu_entry *equiv_cpu_table; | |||
93 | static int collect_cpu_info_amd(int cpu, struct cpu_signature *csig) | 88 | static int collect_cpu_info_amd(int cpu, struct cpu_signature *csig) |
94 | { | 89 | { |
95 | struct cpuinfo_x86 *c = &cpu_data(cpu); | 90 | struct cpuinfo_x86 *c = &cpu_data(cpu); |
91 | u32 dummy; | ||
96 | 92 | ||
97 | memset(csig, 0, sizeof(*csig)); | 93 | memset(csig, 0, sizeof(*csig)); |
98 | |||
99 | if (c->x86_vendor != X86_VENDOR_AMD || c->x86 < 0x10) { | 94 | if (c->x86_vendor != X86_VENDOR_AMD || c->x86 < 0x10) { |
100 | printk(KERN_ERR "microcode: CPU%d not a capable AMD processor\n", | 95 | printk(KERN_WARNING "microcode: CPU%d: AMD CPU family 0x%x not " |
101 | cpu); | 96 | "supported\n", cpu, c->x86); |
102 | return -1; | 97 | return -1; |
103 | } | 98 | } |
104 | 99 | rdmsr(MSR_AMD64_PATCH_LEVEL, csig->rev, dummy); | |
105 | asm volatile("movl %1, %%ecx; rdmsr" | 100 | printk(KERN_INFO "microcode: CPU%d: patch_level=0x%x\n", cpu, csig->rev); |
106 | : "=a" (csig->rev) | ||
107 | : "i" (0x0000008B) : "ecx"); | ||
108 | |||
109 | printk(KERN_INFO "microcode: collect_cpu_info_amd : patch_id=0x%x\n", | ||
110 | csig->rev); | ||
111 | |||
112 | return 0; | 101 | return 0; |
113 | } | 102 | } |
114 | 103 | ||
115 | static int get_matching_microcode(int cpu, void *mc, int rev) | 104 | static int get_matching_microcode(int cpu, void *mc, int rev) |
116 | { | 105 | { |
117 | struct microcode_header_amd *mc_header = mc; | 106 | struct microcode_header_amd *mc_header = mc; |
118 | struct pci_dev *nb_pci_dev, *sb_pci_dev; | ||
119 | unsigned int current_cpu_id; | 107 | unsigned int current_cpu_id; |
120 | unsigned int equiv_cpu_id = 0x00; | 108 | u16 equiv_cpu_id = 0; |
121 | unsigned int i = 0; | 109 | unsigned int i = 0; |
122 | 110 | ||
123 | BUG_ON(equiv_cpu_table == NULL); | 111 | BUG_ON(equiv_cpu_table == NULL); |
@@ -132,57 +120,25 @@ static int get_matching_microcode(int cpu, void *mc, int rev) | |||
132 | } | 120 | } |
133 | 121 | ||
134 | if (!equiv_cpu_id) { | 122 | if (!equiv_cpu_id) { |
135 | printk(KERN_ERR "microcode: CPU%d cpu_id " | 123 | printk(KERN_WARNING "microcode: CPU%d: cpu revision " |
136 | "not found in equivalent cpu table \n", cpu); | 124 | "not listed in equivalent cpu table\n", cpu); |
137 | return 0; | 125 | return 0; |
138 | } | 126 | } |
139 | 127 | ||
140 | if ((mc_header->processor_rev_id[0]) != (equiv_cpu_id & 0xff)) { | 128 | if (mc_header->processor_rev_id != equiv_cpu_id) { |
141 | printk(KERN_ERR | 129 | printk(KERN_ERR "microcode: CPU%d: patch mismatch " |
142 | "microcode: CPU%d patch does not match " | 130 | "(processor_rev_id: %x, equiv_cpu_id: %x)\n", |
143 | "(patch is %x, cpu extended is %x) \n", | 131 | cpu, mc_header->processor_rev_id, equiv_cpu_id); |
144 | cpu, mc_header->processor_rev_id[0], | ||
145 | (equiv_cpu_id & 0xff)); | ||
146 | return 0; | 132 | return 0; |
147 | } | 133 | } |
148 | 134 | ||
149 | if ((mc_header->processor_rev_id[1]) != ((equiv_cpu_id >> 16) & 0xff)) { | 135 | /* ucode might be chipset specific -- currently we don't support this */ |
150 | printk(KERN_ERR "microcode: CPU%d patch does not match " | 136 | if (mc_header->nb_dev_id || mc_header->sb_dev_id) { |
151 | "(patch is %x, cpu base id is %x) \n", | 137 | printk(KERN_ERR "microcode: CPU%d: loading of chipset " |
152 | cpu, mc_header->processor_rev_id[1], | 138 | "specific code not yet supported\n", cpu); |
153 | ((equiv_cpu_id >> 16) & 0xff)); | ||
154 | |||
155 | return 0; | 139 | return 0; |
156 | } | 140 | } |
157 | 141 | ||
158 | /* ucode may be northbridge specific */ | ||
159 | if (mc_header->nb_dev_id) { | ||
160 | nb_pci_dev = pci_get_device(PCI_VENDOR_ID_AMD, | ||
161 | (mc_header->nb_dev_id & 0xff), | ||
162 | NULL); | ||
163 | if ((!nb_pci_dev) || | ||
164 | (mc_header->nb_rev_id != nb_pci_dev->revision)) { | ||
165 | printk(KERN_ERR "microcode: CPU%d NB mismatch \n", cpu); | ||
166 | pci_dev_put(nb_pci_dev); | ||
167 | return 0; | ||
168 | } | ||
169 | pci_dev_put(nb_pci_dev); | ||
170 | } | ||
171 | |||
172 | /* ucode may be southbridge specific */ | ||
173 | if (mc_header->sb_dev_id) { | ||
174 | sb_pci_dev = pci_get_device(PCI_VENDOR_ID_AMD, | ||
175 | (mc_header->sb_dev_id & 0xff), | ||
176 | NULL); | ||
177 | if ((!sb_pci_dev) || | ||
178 | (mc_header->sb_rev_id != sb_pci_dev->revision)) { | ||
179 | printk(KERN_ERR "microcode: CPU%d SB mismatch \n", cpu); | ||
180 | pci_dev_put(sb_pci_dev); | ||
181 | return 0; | ||
182 | } | ||
183 | pci_dev_put(sb_pci_dev); | ||
184 | } | ||
185 | |||
186 | if (mc_header->patch_id <= rev) | 142 | if (mc_header->patch_id <= rev) |
187 | return 0; | 143 | return 0; |
188 | 144 | ||
@@ -192,12 +148,10 @@ static int get_matching_microcode(int cpu, void *mc, int rev) | |||
192 | static void apply_microcode_amd(int cpu) | 148 | static void apply_microcode_amd(int cpu) |
193 | { | 149 | { |
194 | unsigned long flags; | 150 | unsigned long flags; |
195 | unsigned int eax, edx; | 151 | u32 rev, dummy; |
196 | unsigned int rev; | ||
197 | int cpu_num = raw_smp_processor_id(); | 152 | int cpu_num = raw_smp_processor_id(); |
198 | struct ucode_cpu_info *uci = ucode_cpu_info + cpu_num; | 153 | struct ucode_cpu_info *uci = ucode_cpu_info + cpu_num; |
199 | struct microcode_amd *mc_amd = uci->mc; | 154 | struct microcode_amd *mc_amd = uci->mc; |
200 | unsigned long addr; | ||
201 | 155 | ||
202 | /* We should bind the task to the CPU */ | 156 | /* We should bind the task to the CPU */ |
203 | BUG_ON(cpu_num != cpu); | 157 | BUG_ON(cpu_num != cpu); |
@@ -206,42 +160,34 @@ static void apply_microcode_amd(int cpu) | |||
206 | return; | 160 | return; |
207 | 161 | ||
208 | spin_lock_irqsave(µcode_update_lock, flags); | 162 | spin_lock_irqsave(µcode_update_lock, flags); |
209 | 163 | wrmsrl(MSR_AMD64_PATCH_LOADER, (u64)(long)&mc_amd->hdr.data_code); | |
210 | addr = (unsigned long)&mc_amd->hdr.data_code; | ||
211 | edx = (unsigned int)(((unsigned long)upper_32_bits(addr))); | ||
212 | eax = (unsigned int)(((unsigned long)lower_32_bits(addr))); | ||
213 | |||
214 | asm volatile("movl %0, %%ecx; wrmsr" : | ||
215 | : "i" (0xc0010020), "a" (eax), "d" (edx) : "ecx"); | ||
216 | |||
217 | /* get patch id after patching */ | 164 | /* get patch id after patching */ |
218 | asm volatile("movl %1, %%ecx; rdmsr" | 165 | rdmsr(MSR_AMD64_PATCH_LEVEL, rev, dummy); |
219 | : "=a" (rev) | ||
220 | : "i" (0x0000008B) : "ecx"); | ||
221 | |||
222 | spin_unlock_irqrestore(µcode_update_lock, flags); | 166 | spin_unlock_irqrestore(µcode_update_lock, flags); |
223 | 167 | ||
224 | /* check current patch id and patch's id for match */ | 168 | /* check current patch id and patch's id for match */ |
225 | if (rev != mc_amd->hdr.patch_id) { | 169 | if (rev != mc_amd->hdr.patch_id) { |
226 | printk(KERN_ERR "microcode: CPU%d update from revision " | 170 | printk(KERN_ERR "microcode: CPU%d: update failed " |
227 | "0x%x to 0x%x failed\n", cpu_num, | 171 | "(for patch_level=0x%x)\n", cpu, mc_amd->hdr.patch_id); |
228 | mc_amd->hdr.patch_id, rev); | ||
229 | return; | 172 | return; |
230 | } | 173 | } |
231 | 174 | ||
232 | printk(KERN_INFO "microcode: CPU%d updated from revision " | 175 | printk(KERN_INFO "microcode: CPU%d: updated (new patch_level=0x%x)\n", |
233 | "0x%x to 0x%x \n", | 176 | cpu, rev); |
234 | cpu_num, uci->cpu_sig.rev, mc_amd->hdr.patch_id); | ||
235 | 177 | ||
236 | uci->cpu_sig.rev = rev; | 178 | uci->cpu_sig.rev = rev; |
237 | } | 179 | } |
238 | 180 | ||
239 | static void * get_next_ucode(u8 *buf, unsigned int size, | 181 | static int get_ucode_data(void *to, const u8 *from, size_t n) |
240 | int (*get_ucode_data)(void *, const void *, size_t), | 182 | { |
241 | unsigned int *mc_size) | 183 | memcpy(to, from, n); |
184 | return 0; | ||
185 | } | ||
186 | |||
187 | static void *get_next_ucode(const u8 *buf, unsigned int size, | ||
188 | unsigned int *mc_size) | ||
242 | { | 189 | { |
243 | unsigned int total_size; | 190 | unsigned int total_size; |
244 | #define UCODE_CONTAINER_SECTION_HDR 8 | ||
245 | u8 section_hdr[UCODE_CONTAINER_SECTION_HDR]; | 191 | u8 section_hdr[UCODE_CONTAINER_SECTION_HDR]; |
246 | void *mc; | 192 | void *mc; |
247 | 193 | ||
@@ -249,39 +195,37 @@ static void * get_next_ucode(u8 *buf, unsigned int size, | |||
249 | return NULL; | 195 | return NULL; |
250 | 196 | ||
251 | if (section_hdr[0] != UCODE_UCODE_TYPE) { | 197 | if (section_hdr[0] != UCODE_UCODE_TYPE) { |
252 | printk(KERN_ERR "microcode: error! " | 198 | printk(KERN_ERR "microcode: error: invalid type field in " |
253 | "Wrong microcode payload type field\n"); | 199 | "container file section header\n"); |
254 | return NULL; | 200 | return NULL; |
255 | } | 201 | } |
256 | 202 | ||
257 | total_size = (unsigned long) (section_hdr[4] + (section_hdr[5] << 8)); | 203 | total_size = (unsigned long) (section_hdr[4] + (section_hdr[5] << 8)); |
258 | 204 | ||
259 | printk(KERN_INFO "microcode: size %u, total_size %u\n", | 205 | printk(KERN_DEBUG "microcode: size %u, total_size %u\n", |
260 | size, total_size); | 206 | size, total_size); |
261 | 207 | ||
262 | if (total_size > size || total_size > UCODE_MAX_SIZE) { | 208 | if (total_size > size || total_size > UCODE_MAX_SIZE) { |
263 | printk(KERN_ERR "microcode: error! Bad data in microcode data file\n"); | 209 | printk(KERN_ERR "microcode: error: size mismatch\n"); |
264 | return NULL; | 210 | return NULL; |
265 | } | 211 | } |
266 | 212 | ||
267 | mc = vmalloc(UCODE_MAX_SIZE); | 213 | mc = vmalloc(UCODE_MAX_SIZE); |
268 | if (mc) { | 214 | if (mc) { |
269 | memset(mc, 0, UCODE_MAX_SIZE); | 215 | memset(mc, 0, UCODE_MAX_SIZE); |
270 | if (get_ucode_data(mc, buf + UCODE_CONTAINER_SECTION_HDR, total_size)) { | 216 | if (get_ucode_data(mc, buf + UCODE_CONTAINER_SECTION_HDR, |
217 | total_size)) { | ||
271 | vfree(mc); | 218 | vfree(mc); |
272 | mc = NULL; | 219 | mc = NULL; |
273 | } else | 220 | } else |
274 | *mc_size = total_size + UCODE_CONTAINER_SECTION_HDR; | 221 | *mc_size = total_size + UCODE_CONTAINER_SECTION_HDR; |
275 | } | 222 | } |
276 | #undef UCODE_CONTAINER_SECTION_HDR | ||
277 | return mc; | 223 | return mc; |
278 | } | 224 | } |
279 | 225 | ||
280 | 226 | ||
281 | static int install_equiv_cpu_table(u8 *buf, | 227 | static int install_equiv_cpu_table(const u8 *buf) |
282 | int (*get_ucode_data)(void *, const void *, size_t)) | ||
283 | { | 228 | { |
284 | #define UCODE_CONTAINER_HEADER_SIZE 12 | ||
285 | u8 *container_hdr[UCODE_CONTAINER_HEADER_SIZE]; | 229 | u8 *container_hdr[UCODE_CONTAINER_HEADER_SIZE]; |
286 | unsigned int *buf_pos = (unsigned int *)container_hdr; | 230 | unsigned int *buf_pos = (unsigned int *)container_hdr; |
287 | unsigned long size; | 231 | unsigned long size; |
@@ -292,14 +236,15 @@ static int install_equiv_cpu_table(u8 *buf, | |||
292 | size = buf_pos[2]; | 236 | size = buf_pos[2]; |
293 | 237 | ||
294 | if (buf_pos[1] != UCODE_EQUIV_CPU_TABLE_TYPE || !size) { | 238 | if (buf_pos[1] != UCODE_EQUIV_CPU_TABLE_TYPE || !size) { |
295 | printk(KERN_ERR "microcode: error! " | 239 | printk(KERN_ERR "microcode: error: invalid type field in " |
296 | "Wrong microcode equivalnet cpu table\n"); | 240 | "container file section header\n"); |
297 | return 0; | 241 | return 0; |
298 | } | 242 | } |
299 | 243 | ||
300 | equiv_cpu_table = (struct equiv_cpu_entry *) vmalloc(size); | 244 | equiv_cpu_table = (struct equiv_cpu_entry *) vmalloc(size); |
301 | if (!equiv_cpu_table) { | 245 | if (!equiv_cpu_table) { |
302 | printk(KERN_ERR "microcode: error, can't allocate memory for equiv CPU table\n"); | 246 | printk(KERN_ERR "microcode: failed to allocate " |
247 | "equivalent CPU table\n"); | ||
303 | return 0; | 248 | return 0; |
304 | } | 249 | } |
305 | 250 | ||
@@ -310,7 +255,6 @@ static int install_equiv_cpu_table(u8 *buf, | |||
310 | } | 255 | } |
311 | 256 | ||
312 | return size + UCODE_CONTAINER_HEADER_SIZE; /* add header length */ | 257 | return size + UCODE_CONTAINER_HEADER_SIZE; /* add header length */ |
313 | #undef UCODE_CONTAINER_HEADER_SIZE | ||
314 | } | 258 | } |
315 | 259 | ||
316 | static void free_equiv_cpu_table(void) | 260 | static void free_equiv_cpu_table(void) |
@@ -321,18 +265,20 @@ static void free_equiv_cpu_table(void) | |||
321 | } | 265 | } |
322 | } | 266 | } |
323 | 267 | ||
324 | static int generic_load_microcode(int cpu, void *data, size_t size, | 268 | static int generic_load_microcode(int cpu, const u8 *data, size_t size) |
325 | int (*get_ucode_data)(void *, const void *, size_t)) | ||
326 | { | 269 | { |
327 | struct ucode_cpu_info *uci = ucode_cpu_info + cpu; | 270 | struct ucode_cpu_info *uci = ucode_cpu_info + cpu; |
328 | u8 *ucode_ptr = data, *new_mc = NULL, *mc; | 271 | const u8 *ucode_ptr = data; |
272 | void *new_mc = NULL; | ||
273 | void *mc; | ||
329 | int new_rev = uci->cpu_sig.rev; | 274 | int new_rev = uci->cpu_sig.rev; |
330 | unsigned int leftover; | 275 | unsigned int leftover; |
331 | unsigned long offset; | 276 | unsigned long offset; |
332 | 277 | ||
333 | offset = install_equiv_cpu_table(ucode_ptr, get_ucode_data); | 278 | offset = install_equiv_cpu_table(ucode_ptr); |
334 | if (!offset) { | 279 | if (!offset) { |
335 | printk(KERN_ERR "microcode: installing equivalent cpu table failed\n"); | 280 | printk(KERN_ERR "microcode: failed to create " |
281 | "equivalent cpu table\n"); | ||
336 | return -EINVAL; | 282 | return -EINVAL; |
337 | } | 283 | } |
338 | 284 | ||
@@ -343,7 +289,7 @@ static int generic_load_microcode(int cpu, void *data, size_t size, | |||
343 | unsigned int uninitialized_var(mc_size); | 289 | unsigned int uninitialized_var(mc_size); |
344 | struct microcode_header_amd *mc_header; | 290 | struct microcode_header_amd *mc_header; |
345 | 291 | ||
346 | mc = get_next_ucode(ucode_ptr, leftover, get_ucode_data, &mc_size); | 292 | mc = get_next_ucode(ucode_ptr, leftover, &mc_size); |
347 | if (!mc) | 293 | if (!mc) |
348 | break; | 294 | break; |
349 | 295 | ||
@@ -353,7 +299,7 @@ static int generic_load_microcode(int cpu, void *data, size_t size, | |||
353 | vfree(new_mc); | 299 | vfree(new_mc); |
354 | new_rev = mc_header->patch_id; | 300 | new_rev = mc_header->patch_id; |
355 | new_mc = mc; | 301 | new_mc = mc; |
356 | } else | 302 | } else |
357 | vfree(mc); | 303 | vfree(mc); |
358 | 304 | ||
359 | ucode_ptr += mc_size; | 305 | ucode_ptr += mc_size; |
@@ -365,9 +311,9 @@ static int generic_load_microcode(int cpu, void *data, size_t size, | |||
365 | if (uci->mc) | 311 | if (uci->mc) |
366 | vfree(uci->mc); | 312 | vfree(uci->mc); |
367 | uci->mc = new_mc; | 313 | uci->mc = new_mc; |
368 | pr_debug("microcode: CPU%d found a matching microcode update with" | 314 | pr_debug("microcode: CPU%d found a matching microcode " |
369 | " version 0x%x (current=0x%x)\n", | 315 | "update with version 0x%x (current=0x%x)\n", |
370 | cpu, new_rev, uci->cpu_sig.rev); | 316 | cpu, new_rev, uci->cpu_sig.rev); |
371 | } else | 317 | } else |
372 | vfree(new_mc); | 318 | vfree(new_mc); |
373 | } | 319 | } |
@@ -377,12 +323,6 @@ static int generic_load_microcode(int cpu, void *data, size_t size, | |||
377 | return (int)leftover; | 323 | return (int)leftover; |
378 | } | 324 | } |
379 | 325 | ||
380 | static int get_ucode_fw(void *to, const void *from, size_t n) | ||
381 | { | ||
382 | memcpy(to, from, n); | ||
383 | return 0; | ||
384 | } | ||
385 | |||
386 | static int request_microcode_fw(int cpu, struct device *device) | 326 | static int request_microcode_fw(int cpu, struct device *device) |
387 | { | 327 | { |
388 | const char *fw_name = "amd-ucode/microcode_amd.bin"; | 328 | const char *fw_name = "amd-ucode/microcode_amd.bin"; |
@@ -394,12 +334,11 @@ static int request_microcode_fw(int cpu, struct device *device) | |||
394 | 334 | ||
395 | ret = request_firmware(&firmware, fw_name, device); | 335 | ret = request_firmware(&firmware, fw_name, device); |
396 | if (ret) { | 336 | if (ret) { |
397 | printk(KERN_ERR "microcode: ucode data file %s load failed\n", fw_name); | 337 | printk(KERN_ERR "microcode: failed to load file %s\n", fw_name); |
398 | return ret; | 338 | return ret; |
399 | } | 339 | } |
400 | 340 | ||
401 | ret = generic_load_microcode(cpu, (void*)firmware->data, firmware->size, | 341 | ret = generic_load_microcode(cpu, firmware->data, firmware->size); |
402 | &get_ucode_fw); | ||
403 | 342 | ||
404 | release_firmware(firmware); | 343 | release_firmware(firmware); |
405 | 344 | ||
@@ -408,8 +347,8 @@ static int request_microcode_fw(int cpu, struct device *device) | |||
408 | 347 | ||
409 | static int request_microcode_user(int cpu, const void __user *buf, size_t size) | 348 | static int request_microcode_user(int cpu, const void __user *buf, size_t size) |
410 | { | 349 | { |
411 | printk(KERN_WARNING "microcode: AMD microcode update via /dev/cpu/microcode" | 350 | printk(KERN_INFO "microcode: AMD microcode update via " |
412 | "is not supported\n"); | 351 | "/dev/cpu/microcode not supported\n"); |
413 | return -1; | 352 | return -1; |
414 | } | 353 | } |
415 | 354 | ||
@@ -433,3 +372,4 @@ struct microcode_ops * __init init_amd_microcode(void) | |||
433 | { | 372 | { |
434 | return µcode_amd_ops; | 373 | return µcode_amd_ops; |
435 | } | 374 | } |
375 | |||