Re: [U-Boot] [PATCH 32/39] x86: ivybridge: Perform Intel microcode update on boot

2014-11-10 Thread Simon Glass
Hi Bin,

On 9 November 2014 19:54, Bin Meng bmeng...@gmail.com wrote:
 Hi Simon,

 On Fri, Nov 7, 2014 at 4:20 AM, Simon Glass s...@chromium.org wrote:
 Microcode updates are stored in the device tree. Work through these and
 apply any that are needed.

 Signed-off-by: Simon Glass s...@chromium.org
 ---

  arch/x86/cpu/ivybridge/Makefile |   1 +
  arch/x86/cpu/ivybridge/cpu.c|   5 +
  arch/x86/cpu/ivybridge/microcode_intel.c| 150 
 
  arch/x86/include/asm/arch-ivybridge/microcode.h |  20 
  include/fdtdec.h|   1 +
  lib/fdtdec.c|   1 +
  6 files changed, 178 insertions(+)
  create mode 100644 arch/x86/cpu/ivybridge/microcode_intel.c
  create mode 100644 arch/x86/include/asm/arch-ivybridge/microcode.h

 diff --git a/arch/x86/cpu/ivybridge/Makefile 
 b/arch/x86/cpu/ivybridge/Makefile
 index ce16697..a3ea566 100644
 --- a/arch/x86/cpu/ivybridge/Makefile
 +++ b/arch/x86/cpu/ivybridge/Makefile
 @@ -7,4 +7,5 @@
  obj-y += car.o
  obj-y += cpu.o
  obj-y += lpc.o
 +obj-y += microcode_intel.o
  obj-y += sdram.o
 diff --git a/arch/x86/cpu/ivybridge/cpu.c b/arch/x86/cpu/ivybridge/cpu.c
 index e73ccb7..bd2660f 100644
 --- a/arch/x86/cpu/ivybridge/cpu.c
 +++ b/arch/x86/cpu/ivybridge/cpu.c
 @@ -19,6 +19,7 @@
  #include asm/post.h
  #include asm/processor.h
  #include asm/arch/model_206ax.h
 +#include asm/arch/microcode.h
  #include asm/arch/pch.h

  DECLARE_GLOBAL_DATA_PTR;
 @@ -198,6 +199,10 @@ int print_cpuinfo(void)
 if (ret)
 return ret;

 +   ret = microcode_update_intel();
 +   if (ret  ret != -ENOENT  ret != -EEXIST)
 +   return ret;
 +
 /* Print processor name */
 name = cpu_get_name(processor_name);
 printf(CPU:   %s\n, name);
 diff --git a/arch/x86/cpu/ivybridge/microcode_intel.c 
 b/arch/x86/cpu/ivybridge/microcode_intel.c
 new file mode 100644
 index 000..fbb55f2
 --- /dev/null
 +++ b/arch/x86/cpu/ivybridge/microcode_intel.c
 @@ -0,0 +1,150 @@
 +/*
 + * Copyright (c) 2014 Google, Inc
 + * Copyright (C) 2000 Ronald G. Minnich
 + *
 + * Microcode update for Intel PIII and later CPUs

 This comment suggests that the code is generic for all Intel CPUs, so
 should we move this code to arch/x86/lib?

Actually I think a lot of code is in that category, or at least I
fervently hope so! We may end up with an 'intel-common' directory, I'm
not sure. But I'd rather leave common discussions until we know things
are common.

Regards,
Simon
___
U-Boot mailing list
U-Boot@lists.denx.de
http://lists.denx.de/mailman/listinfo/u-boot


Re: [U-Boot] [PATCH 32/39] x86: ivybridge: Perform Intel microcode update on boot

2014-11-09 Thread Bin Meng
Hi Simon,

On Fri, Nov 7, 2014 at 4:20 AM, Simon Glass s...@chromium.org wrote:
 Microcode updates are stored in the device tree. Work through these and
 apply any that are needed.

 Signed-off-by: Simon Glass s...@chromium.org
 ---

  arch/x86/cpu/ivybridge/Makefile |   1 +
  arch/x86/cpu/ivybridge/cpu.c|   5 +
  arch/x86/cpu/ivybridge/microcode_intel.c| 150 
 
  arch/x86/include/asm/arch-ivybridge/microcode.h |  20 
  include/fdtdec.h|   1 +
  lib/fdtdec.c|   1 +
  6 files changed, 178 insertions(+)
  create mode 100644 arch/x86/cpu/ivybridge/microcode_intel.c
  create mode 100644 arch/x86/include/asm/arch-ivybridge/microcode.h

 diff --git a/arch/x86/cpu/ivybridge/Makefile b/arch/x86/cpu/ivybridge/Makefile
 index ce16697..a3ea566 100644
 --- a/arch/x86/cpu/ivybridge/Makefile
 +++ b/arch/x86/cpu/ivybridge/Makefile
 @@ -7,4 +7,5 @@
  obj-y += car.o
  obj-y += cpu.o
  obj-y += lpc.o
 +obj-y += microcode_intel.o
  obj-y += sdram.o
 diff --git a/arch/x86/cpu/ivybridge/cpu.c b/arch/x86/cpu/ivybridge/cpu.c
 index e73ccb7..bd2660f 100644
 --- a/arch/x86/cpu/ivybridge/cpu.c
 +++ b/arch/x86/cpu/ivybridge/cpu.c
 @@ -19,6 +19,7 @@
  #include asm/post.h
  #include asm/processor.h
  #include asm/arch/model_206ax.h
 +#include asm/arch/microcode.h
  #include asm/arch/pch.h

  DECLARE_GLOBAL_DATA_PTR;
 @@ -198,6 +199,10 @@ int print_cpuinfo(void)
 if (ret)
 return ret;

 +   ret = microcode_update_intel();
 +   if (ret  ret != -ENOENT  ret != -EEXIST)
 +   return ret;
 +
 /* Print processor name */
 name = cpu_get_name(processor_name);
 printf(CPU:   %s\n, name);
 diff --git a/arch/x86/cpu/ivybridge/microcode_intel.c 
 b/arch/x86/cpu/ivybridge/microcode_intel.c
 new file mode 100644
 index 000..fbb55f2
 --- /dev/null
 +++ b/arch/x86/cpu/ivybridge/microcode_intel.c
 @@ -0,0 +1,150 @@
 +/*
 + * Copyright (c) 2014 Google, Inc
 + * Copyright (C) 2000 Ronald G. Minnich
 + *
 + * Microcode update for Intel PIII and later CPUs

This comment suggests that the code is generic for all Intel CPUs, so
should we move this code to arch/x86/lib?

[snip]

Regards,
Bin
___
U-Boot mailing list
U-Boot@lists.denx.de
http://lists.denx.de/mailman/listinfo/u-boot


[U-Boot] [PATCH 32/39] x86: ivybridge: Perform Intel microcode update on boot

2014-11-06 Thread Simon Glass
Microcode updates are stored in the device tree. Work through these and
apply any that are needed.

Signed-off-by: Simon Glass s...@chromium.org
---

 arch/x86/cpu/ivybridge/Makefile |   1 +
 arch/x86/cpu/ivybridge/cpu.c|   5 +
 arch/x86/cpu/ivybridge/microcode_intel.c| 150 
 arch/x86/include/asm/arch-ivybridge/microcode.h |  20 
 include/fdtdec.h|   1 +
 lib/fdtdec.c|   1 +
 6 files changed, 178 insertions(+)
 create mode 100644 arch/x86/cpu/ivybridge/microcode_intel.c
 create mode 100644 arch/x86/include/asm/arch-ivybridge/microcode.h

diff --git a/arch/x86/cpu/ivybridge/Makefile b/arch/x86/cpu/ivybridge/Makefile
index ce16697..a3ea566 100644
--- a/arch/x86/cpu/ivybridge/Makefile
+++ b/arch/x86/cpu/ivybridge/Makefile
@@ -7,4 +7,5 @@
 obj-y += car.o
 obj-y += cpu.o
 obj-y += lpc.o
+obj-y += microcode_intel.o
 obj-y += sdram.o
diff --git a/arch/x86/cpu/ivybridge/cpu.c b/arch/x86/cpu/ivybridge/cpu.c
index e73ccb7..bd2660f 100644
--- a/arch/x86/cpu/ivybridge/cpu.c
+++ b/arch/x86/cpu/ivybridge/cpu.c
@@ -19,6 +19,7 @@
 #include asm/post.h
 #include asm/processor.h
 #include asm/arch/model_206ax.h
+#include asm/arch/microcode.h
 #include asm/arch/pch.h
 
 DECLARE_GLOBAL_DATA_PTR;
@@ -198,6 +199,10 @@ int print_cpuinfo(void)
if (ret)
return ret;
 
+   ret = microcode_update_intel();
+   if (ret  ret != -ENOENT  ret != -EEXIST)
+   return ret;
+
/* Print processor name */
name = cpu_get_name(processor_name);
printf(CPU:   %s\n, name);
diff --git a/arch/x86/cpu/ivybridge/microcode_intel.c 
b/arch/x86/cpu/ivybridge/microcode_intel.c
new file mode 100644
index 000..fbb55f2
--- /dev/null
+++ b/arch/x86/cpu/ivybridge/microcode_intel.c
@@ -0,0 +1,150 @@
+/*
+ * Copyright (c) 2014 Google, Inc
+ * Copyright (C) 2000 Ronald G. Minnich
+ *
+ * Microcode update for Intel PIII and later CPUs
+ *
+ * SPDX-License-Identifier:GPL-2.0
+ */
+
+#include common.h
+#include errno.h
+#include fdtdec.h
+#include libfdt.h
+#include asm/msr.h
+#include asm/processor.h
+
+/**
+ * struct microcode_update - standard microcode header from Intel
+ *
+ * We read this information out of the device tree and use it to determine
+ * whether the update is applicable or not. We also use the same structure
+ * to read information from the CPU.
+ */
+struct microcode_update {
+   uint header_version;
+   uint update_revision;
+   uint date_code;
+   uint processor_signature;
+   uint checksum;
+   uint loader_revision;
+   uint processor_flags;
+   const void *data;
+   int size;
+};
+
+static int microcode_decode_node(const void *blob, int node,
+struct microcode_update *update)
+{
+   update-data = fdt_getprop(blob, node, data, update-size);
+   if (!update-data)
+   return -EINVAL;
+
+   update-header_version = fdtdec_get_int(blob, node,
+   intel,header-version, 0);
+   update-update_revision = fdtdec_get_int(blob, node,
+intel,update-revision, 0);
+   update-date_code = fdtdec_get_int(blob, node,
+  intel,date-code, 0);
+   update-processor_signature = fdtdec_get_int(blob, node,
+   intel.processor-signature, 0);
+   update-checksum = fdtdec_get_int(blob, node, intel,checksum, 0);
+   update-loader_revision = fdtdec_get_int(blob, node,
+loader-revision, 0);
+   update-processor_flags = fdtdec_get_int(blob, node,
+processor-flags, 0);
+
+   return 0;
+}
+
+static uint32_t microcode_read_rev(void)
+{
+   /*
+* Some Intel CPUs can be very finicky about the CPUID sequence used.
+* So this is implemented in assembly so that it works reliably.
+*/
+   uint32_t low, high;
+
+   asm volatile (
+   xorl %%eax, %%eax\n
+   xorl %%edx, %%edx\n
+   movl $0x8b, %%ecx\n
+   wrmsr\n
+   movl $0x01, %%eax\n
+   cpuid\n
+   movl $0x8b, %%ecx\n
+   rdmsr\n
+   : /* outputs */
+   =a (low), =d (high)
+   : /* inputs */
+   : /* clobbers */
+ebx, ecx
+   );
+
+   return high;
+}
+
+static void microcode_read_cpu(struct microcode_update *cpu)
+{
+   /* CPUID sets MSR 0x8B iff a microcode update has been loaded. */
+   unsigned int x86_model, x86_family;
+   struct cpuid_result result;
+   uint32_t low, high;
+
+   wrmsr(0x8b, 0, 0);
+   result = cpuid(1);
+   rdmsr(0x8b, low, cpu-update_revision);
+   x86_model = (result.eax  4)  0x0f;
+