Commit b591ee3913b7eeef851451641c85e1e014d2103f

Authored by Simon Glass
1 parent cf29e3e303

x86: Correct problems in the microcode loading

There are several problems in the code. The device tree decode is incorrect
in ways that are masked due to a matching bug. Both are fixed. Also
microcode_read_rev() should be inline and called before the microcode is
written.

Note: microcode writing does not work correctly on ivybridge for me. Further
work is needed to resolve this. But this patch tidies up the existing code
so that will be easier.

Signed-off-by: Simon Glass <sjg@chromium.org>

Showing 1 changed file with 15 additions and 10 deletions Side-by-side Diff

arch/x86/cpu/ivybridge/microcode_intel.c
... ... @@ -50,17 +50,17 @@
50 50 update->date_code = fdtdec_get_int(blob, node,
51 51 "intel,date-code", 0);
52 52 update->processor_signature = fdtdec_get_int(blob, node,
53   - "intel.processor-signature", 0);
  53 + "intel,processor-signature", 0);
54 54 update->checksum = fdtdec_get_int(blob, node, "intel,checksum", 0);
55 55 update->loader_revision = fdtdec_get_int(blob, node,
56   - "loader-revision", 0);
  56 + "intel,loader-revision", 0);
57 57 update->processor_flags = fdtdec_get_int(blob, node,
58   - "processor-flags", 0);
  58 + "intel,processor-flags", 0);
59 59  
60 60 return 0;
61 61 }
62 62  
63   -static uint32_t microcode_read_rev(void)
  63 +static inline uint32_t microcode_read_rev(void)
64 64 {
65 65 /*
66 66 * Some Intel CPUs can be very finicky about the CPUID sequence used.
... ... @@ -116,6 +116,7 @@
116 116 {
117 117 struct microcode_update cpu, update;
118 118 const void *blob = gd->fdt_blob;
  119 + int skipped;
119 120 int count;
120 121 int node;
121 122 int ret;
122 123  
... ... @@ -123,12 +124,13 @@
123 124 microcode_read_cpu(&cpu);
124 125 node = 0;
125 126 count = 0;
  127 + skipped = 0;
126 128 do {
127 129 node = fdtdec_next_compatible(blob, node,
128 130 COMPAT_INTEL_MICROCODE);
129 131 if (node < 0) {
130 132 debug("%s: Found %d updates\n", __func__, count);
131   - return count ? 0 : -ENOENT;
  133 + return count ? 0 : skipped ? -EEXIST : -ENOENT;
132 134 }
133 135  
134 136 ret = microcode_decode_node(blob, node, &update);
135 137  
... ... @@ -137,12 +139,15 @@
137 139 ret);
138 140 return ret;
139 141 }
140   - if (update.processor_signature == cpu.processor_signature &&
141   - (update.processor_flags & cpu.processor_flags)) {
142   - debug("%s: Update already exists\n", __func__);
143   - return -EEXIST;
  142 + if (!(update.processor_signature == cpu.processor_signature &&
  143 + (update.processor_flags & cpu.processor_flags))) {
  144 + debug("%s: Skipping non-matching update, sig=%x, pf=%x\n",
  145 + __func__, update.processor_signature,
  146 + update.processor_flags);
  147 + skipped++;
  148 + continue;
144 149 }
145   -
  150 + ret = microcode_read_rev();
146 151 wrmsr(0x79, (ulong)update.data, 0);
147 152 debug("microcode: updated to revision 0x%x date=%04x-%02x-%02x\n",
148 153 microcode_read_rev(), update.date_code & 0xffff,