e68e723490a30cc3cc3e0d5ff9bc13748e4b75b0
[firefly-linux-kernel-4.4.55.git] / arch / x86 / kernel / microcode_amd.c
1 /*
2  *  AMD CPU Microcode Update Driver for Linux
3  *  Copyright (C) 2008 Advanced Micro Devices Inc.
4  *
5  *  Author: Peter Oruba <peter.oruba@amd.com>
6  *
7  *  Based on work by:
8  *  Tigran Aivazian <tigran@aivazian.fsnet.co.uk>
9  *
10  *  This driver allows to upgrade microcode on AMD
11  *  family 0x10 and 0x11 processors.
12  *
13  *  Licensed under the terms of the GNU General Public
14  *  License version 2. See file COPYING for details.
15 */
16
17 #include <linux/capability.h>
18 #include <linux/kernel.h>
19 #include <linux/init.h>
20 #include <linux/sched.h>
21 #include <linux/cpumask.h>
22 #include <linux/module.h>
23 #include <linux/slab.h>
24 #include <linux/vmalloc.h>
25 #include <linux/miscdevice.h>
26 #include <linux/spinlock.h>
27 #include <linux/mm.h>
28 #include <linux/fs.h>
29 #include <linux/mutex.h>
30 #include <linux/cpu.h>
31 #include <linux/firmware.h>
32 #include <linux/platform_device.h>
33 #include <linux/pci.h>
34 #include <linux/pci_ids.h>
35 #include <linux/uaccess.h>
36
37 #include <asm/msr.h>
38 #include <asm/processor.h>
39 #include <asm/microcode.h>
40
41 MODULE_DESCRIPTION("AMD Microcode Update Driver");
42 MODULE_AUTHOR("Peter Oruba");
43 MODULE_LICENSE("GPL v2");
44
45 #define UCODE_MAGIC                0x00414d44
46 #define UCODE_EQUIV_CPU_TABLE_TYPE 0x00000000
47 #define UCODE_UCODE_TYPE           0x00000001
48
49 struct 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
56 struct 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         u16 processor_rev_id;
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
73 struct microcode_amd {
74         struct microcode_header_amd hdr;
75         unsigned int mpb[0];
76 };
77
78 #define UCODE_MAX_SIZE                  2048
79 #define UCODE_CONTAINER_SECTION_HDR     8
80 #define UCODE_CONTAINER_HEADER_SIZE     12
81
82 /* serialize access to the physical write */
83 static DEFINE_SPINLOCK(microcode_update_lock);
84
85 static struct equiv_cpu_entry *equiv_cpu_table;
86
87 static int collect_cpu_info_amd(int cpu, struct cpu_signature *csig)
88 {
89         struct cpuinfo_x86 *c = &cpu_data(cpu);
90         u32 dummy;
91
92         memset(csig, 0, sizeof(*csig));
93
94         if (c->x86_vendor != X86_VENDOR_AMD || c->x86 < 0x10) {
95                 printk(KERN_ERR "microcode: CPU%d not a capable AMD processor\n",
96                        cpu);
97                 return -1;
98         }
99
100         rdmsr(MSR_AMD64_PATCH_LEVEL, csig->rev, dummy);
101
102         printk(KERN_INFO "microcode: collect_cpu_info_amd : patch_id=0x%x\n",
103                 csig->rev);
104
105         return 0;
106 }
107
108 static int get_matching_microcode(int cpu, void *mc, int rev)
109 {
110         struct microcode_header_amd *mc_header = mc;
111         struct pci_dev *nb_pci_dev, *sb_pci_dev;
112         unsigned int current_cpu_id;
113         unsigned int equiv_cpu_id = 0x00;
114         unsigned int i = 0;
115
116         BUG_ON(equiv_cpu_table == NULL);
117         current_cpu_id = cpuid_eax(0x00000001);
118
119         while (equiv_cpu_table[i].installed_cpu != 0) {
120                 if (current_cpu_id == equiv_cpu_table[i].installed_cpu) {
121                         equiv_cpu_id = equiv_cpu_table[i].equiv_cpu & 0xffff;
122                         break;
123                 }
124                 i++;
125         }
126
127         if (!equiv_cpu_id) {
128                 printk(KERN_ERR "microcode: CPU%d cpu_id "
129                        "not found in equivalent cpu table\n", cpu);
130                 return 0;
131         }
132
133         if (mc_header->processor_rev_id != equiv_cpu_id) {
134                 printk(KERN_ERR "microcode: CPU%d patch does not match "
135                        "(processor_rev_id: %x, eqiv_cpu_id: %x)\n",
136                        cpu, mc_header->processor_rev_id, equiv_cpu_id);
137                 return 0;
138         }
139
140         /* ucode may be northbridge specific */
141         if (mc_header->nb_dev_id) {
142                 nb_pci_dev = pci_get_device(PCI_VENDOR_ID_AMD,
143                                             (mc_header->nb_dev_id & 0xff),
144                                             NULL);
145                 if ((!nb_pci_dev) ||
146                     (mc_header->nb_rev_id != nb_pci_dev->revision)) {
147                         printk(KERN_ERR "microcode: CPU%d NB mismatch\n", cpu);
148                         pci_dev_put(nb_pci_dev);
149                         return 0;
150                 }
151                 pci_dev_put(nb_pci_dev);
152         }
153
154         /* ucode may be southbridge specific */
155         if (mc_header->sb_dev_id) {
156                 sb_pci_dev = pci_get_device(PCI_VENDOR_ID_AMD,
157                                             (mc_header->sb_dev_id & 0xff),
158                                             NULL);
159                 if ((!sb_pci_dev) ||
160                     (mc_header->sb_rev_id != sb_pci_dev->revision)) {
161                         printk(KERN_ERR "microcode: CPU%d SB mismatch\n", cpu);
162                         pci_dev_put(sb_pci_dev);
163                         return 0;
164                 }
165                 pci_dev_put(sb_pci_dev);
166         }
167
168         if (mc_header->patch_id <= rev)
169                 return 0;
170
171         return 1;
172 }
173
174 static void apply_microcode_amd(int cpu)
175 {
176         unsigned long flags;
177         u32 rev, dummy;
178         int cpu_num = raw_smp_processor_id();
179         struct ucode_cpu_info *uci = ucode_cpu_info + cpu_num;
180         struct microcode_amd *mc_amd = uci->mc;
181
182         /* We should bind the task to the CPU */
183         BUG_ON(cpu_num != cpu);
184
185         if (mc_amd == NULL)
186                 return;
187
188         spin_lock_irqsave(&microcode_update_lock, flags);
189         wrmsrl(MSR_AMD64_PATCH_LOADER, &mc_amd->hdr.data_code);
190         /* get patch id after patching */
191         rdmsr(MSR_AMD64_PATCH_LEVEL, rev, dummy);
192         spin_unlock_irqrestore(&microcode_update_lock, flags);
193
194         /* check current patch id and patch's id for match */
195         if (rev != mc_amd->hdr.patch_id) {
196                 printk(KERN_ERR "microcode: CPU%d update from revision "
197                        "0x%x to 0x%x failed\n", cpu_num,
198                        mc_amd->hdr.patch_id, rev);
199                 return;
200         }
201
202         printk(KERN_INFO "microcode: CPU%d updated from revision "
203                "0x%x to 0x%x\n",
204                cpu_num, uci->cpu_sig.rev, mc_amd->hdr.patch_id);
205
206         uci->cpu_sig.rev = rev;
207 }
208
209 static int get_ucode_data(void *to, const u8 *from, size_t n)
210 {
211         memcpy(to, from, n);
212         return 0;
213 }
214
215 static void *get_next_ucode(const u8 *buf, unsigned int size,
216                             unsigned int *mc_size)
217 {
218         unsigned int total_size;
219         u8 section_hdr[UCODE_CONTAINER_SECTION_HDR];
220         void *mc;
221
222         if (get_ucode_data(section_hdr, buf, UCODE_CONTAINER_SECTION_HDR))
223                 return NULL;
224
225         if (section_hdr[0] != UCODE_UCODE_TYPE) {
226                 printk(KERN_ERR "microcode: error! "
227                        "Wrong microcode payload type field\n");
228                 return NULL;
229         }
230
231         total_size = (unsigned long) (section_hdr[4] + (section_hdr[5] << 8));
232
233         printk(KERN_INFO "microcode: size %u, total_size %u\n",
234                 size, total_size);
235
236         if (total_size > size || total_size > UCODE_MAX_SIZE) {
237                 printk(KERN_ERR "microcode: error! Bad data in microcode data file\n");
238                 return NULL;
239         }
240
241         mc = vmalloc(UCODE_MAX_SIZE);
242         if (mc) {
243                 memset(mc, 0, UCODE_MAX_SIZE);
244                 if (get_ucode_data(mc, buf + UCODE_CONTAINER_SECTION_HDR,
245                                    total_size)) {
246                         vfree(mc);
247                         mc = NULL;
248                 } else
249                         *mc_size = total_size + UCODE_CONTAINER_SECTION_HDR;
250         }
251         return mc;
252 }
253
254
255 static int install_equiv_cpu_table(const u8 *buf)
256 {
257         u8 *container_hdr[UCODE_CONTAINER_HEADER_SIZE];
258         unsigned int *buf_pos = (unsigned int *)container_hdr;
259         unsigned long size;
260
261         if (get_ucode_data(&container_hdr, buf, UCODE_CONTAINER_HEADER_SIZE))
262                 return 0;
263
264         size = buf_pos[2];
265
266         if (buf_pos[1] != UCODE_EQUIV_CPU_TABLE_TYPE || !size) {
267                 printk(KERN_ERR "microcode: error! "
268                        "Wrong microcode equivalent cpu table\n");
269                 return 0;
270         }
271
272         equiv_cpu_table = (struct equiv_cpu_entry *) vmalloc(size);
273         if (!equiv_cpu_table) {
274                 printk(KERN_ERR "microcode: error, can't allocate memory for equiv CPU table\n");
275                 return 0;
276         }
277
278         buf += UCODE_CONTAINER_HEADER_SIZE;
279         if (get_ucode_data(equiv_cpu_table, buf, size)) {
280                 vfree(equiv_cpu_table);
281                 return 0;
282         }
283
284         return size + UCODE_CONTAINER_HEADER_SIZE; /* add header length */
285 }
286
287 static void free_equiv_cpu_table(void)
288 {
289         if (equiv_cpu_table) {
290                 vfree(equiv_cpu_table);
291                 equiv_cpu_table = NULL;
292         }
293 }
294
295 static int generic_load_microcode(int cpu, const u8 *data, size_t size)
296 {
297         struct ucode_cpu_info *uci = ucode_cpu_info + cpu;
298         const u8 *ucode_ptr = data;
299         void *new_mc = NULL;
300         void *mc;
301         int new_rev = uci->cpu_sig.rev;
302         unsigned int leftover;
303         unsigned long offset;
304
305         offset = install_equiv_cpu_table(ucode_ptr);
306         if (!offset) {
307                 printk(KERN_ERR "microcode: installing equivalent cpu table failed\n");
308                 return -EINVAL;
309         }
310
311         ucode_ptr += offset;
312         leftover = size - offset;
313
314         while (leftover) {
315                 unsigned int uninitialized_var(mc_size);
316                 struct microcode_header_amd *mc_header;
317
318                 mc = get_next_ucode(ucode_ptr, leftover, &mc_size);
319                 if (!mc)
320                         break;
321
322                 mc_header = (struct microcode_header_amd *)mc;
323                 if (get_matching_microcode(cpu, mc, new_rev)) {
324                         if (new_mc)
325                                 vfree(new_mc);
326                         new_rev = mc_header->patch_id;
327                         new_mc  = mc;
328                 } else
329                         vfree(mc);
330
331                 ucode_ptr += mc_size;
332                 leftover  -= mc_size;
333         }
334
335         if (new_mc) {
336                 if (!leftover) {
337                         if (uci->mc)
338                                 vfree(uci->mc);
339                         uci->mc = new_mc;
340                         pr_debug("microcode: CPU%d found a matching microcode "
341                                  "update with version 0x%x (current=0x%x)\n",
342                                  cpu, new_rev, uci->cpu_sig.rev);
343                 } else
344                         vfree(new_mc);
345         }
346
347         free_equiv_cpu_table();
348
349         return (int)leftover;
350 }
351
352 static int request_microcode_fw(int cpu, struct device *device)
353 {
354         const char *fw_name = "amd-ucode/microcode_amd.bin";
355         const struct firmware *firmware;
356         int ret;
357
358         /* We should bind the task to the CPU */
359         BUG_ON(cpu != raw_smp_processor_id());
360
361         ret = request_firmware(&firmware, fw_name, device);
362         if (ret) {
363                 printk(KERN_ERR "microcode: ucode data file %s load failed\n",
364                        fw_name);
365                 return ret;
366         }
367
368         ret = generic_load_microcode(cpu, firmware->data, firmware->size);
369
370         release_firmware(firmware);
371
372         return ret;
373 }
374
375 static int request_microcode_user(int cpu, const void __user *buf, size_t size)
376 {
377         printk(KERN_WARNING "microcode: AMD microcode update via "
378                "/dev/cpu/microcode is not supported\n");
379         return -1;
380 }
381
382 static void microcode_fini_cpu_amd(int cpu)
383 {
384         struct ucode_cpu_info *uci = ucode_cpu_info + cpu;
385
386         vfree(uci->mc);
387         uci->mc = NULL;
388 }
389
390 static struct microcode_ops microcode_amd_ops = {
391         .request_microcode_user           = request_microcode_user,
392         .request_microcode_fw             = request_microcode_fw,
393         .collect_cpu_info                 = collect_cpu_info_amd,
394         .apply_microcode                  = apply_microcode_amd,
395         .microcode_fini_cpu               = microcode_fini_cpu_amd,
396 };
397
398 struct microcode_ops * __init init_amd_microcode(void)
399 {
400         return &microcode_amd_ops;
401 }