Source-Changes-HG archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

[src/trunk]: src Extend the CPU microcode update framework to support Intel x...



details:   https://anonhg.NetBSD.org/src/rev/d4a8ac2a9512
branches:  trunk
changeset: 781249:d4a8ac2a9512
user:      drochner <drochner%NetBSD.org@localhost>
date:      Wed Aug 29 17:13:21 2012 +0000

description:
Extend the CPU microcode update framework to support Intel x86 CPUs.
Contrary to the AMD implementation, it doesn't use xcalls to distribute
the update to all CPUs but relies on cpuctl(8) to bind itself to the
right CPU -- to keep it simple and avoid possible problems with
hyperthreading.
Also, it doesn't parse the vendor supplied file to pick the right
part for the present CPU model but relies on userland to prepare
files with specific filenames. I'll commit a pkg for this in a minute
(pkgsrc/sysutils/intel-microcode).
The ioctl interface changed; compatibility is provided (should be
limited to COMPAT_NETBSD6 as soon as this is available).

diffstat:

 distrib/sets/lists/comp/md.amd64   |    3 +-
 distrib/sets/lists/comp/md.i386    |    3 +-
 sys/arch/x86/conf/files.x86        |    3 +-
 sys/arch/x86/include/Makefile      |    3 +-
 sys/arch/x86/include/cpu_ucode.h   |   51 +++++++++++-
 sys/arch/x86/x86/cpu_ucode.c       |   67 +++++++++++++--
 sys/arch/x86/x86/cpu_ucode_amd.c   |   35 ++++++-
 sys/arch/x86/x86/cpu_ucode_intel.c |  152 +++++++++++++++++++++++++++++++++++++
 sys/arch/xen/conf/files.xen        |    3 +-
 sys/arch/xen/xen/xen_ucode.c       |   66 +++++++++++++--
 sys/compat/sys/cpuio.h             |    9 ++
 sys/kern/kern_cpu.c                |   26 +++++-
 sys/sys/cpu.h                      |   17 +++-
 sys/sys/cpuio.h                    |   17 +++-
 usr.sbin/cpuctl/arch/i386.c        |   74 +++++++++++++++++-
 usr.sbin/cpuctl/arch/noarch.c      |   13 ++-
 usr.sbin/cpuctl/cpuctl.c           |   44 +++++++---
 usr.sbin/cpuctl/cpuctl.h           |    5 +-
 18 files changed, 516 insertions(+), 75 deletions(-)

diffs (truncated from 1043 to 300 lines):

diff -r 05d5f741978f -r d4a8ac2a9512 distrib/sets/lists/comp/md.amd64
--- a/distrib/sets/lists/comp/md.amd64  Wed Aug 29 17:08:41 2012 +0000
+++ b/distrib/sets/lists/comp/md.amd64  Wed Aug 29 17:13:21 2012 +0000
@@ -1,4 +1,4 @@
-# $NetBSD: md.amd64,v 1.175 2012/08/10 16:22:33 joerg Exp $
+# $NetBSD: md.amd64,v 1.176 2012/08/29 17:13:21 drochner Exp $
 ./usr/include/amd64                            comp-c-include
 ./usr/include/amd64/ansi.h                     comp-c-include
 ./usr/include/amd64/aout_machdep.h             comp-c-include
@@ -283,6 +283,7 @@
 ./usr/include/x86/bus.h                                comp-obsolete           obsolete
 ./usr/include/x86/cacheinfo.h                  comp-c-include
 ./usr/include/x86/cpu.h                                comp-c-include
+./usr/include/x86/cpu_ucode.h                  comp-c-include
 ./usr/include/x86/cputypes.h                   comp-c-include
 ./usr/include/x86/cpuvar.h                     comp-c-include
 ./usr/include/x86/float.h                      comp-c-include
diff -r 05d5f741978f -r d4a8ac2a9512 distrib/sets/lists/comp/md.i386
--- a/distrib/sets/lists/comp/md.i386   Wed Aug 29 17:08:41 2012 +0000
+++ b/distrib/sets/lists/comp/md.i386   Wed Aug 29 17:13:21 2012 +0000
@@ -1,4 +1,4 @@
-# $NetBSD: md.i386,v 1.126 2012/08/08 18:37:51 drochner Exp $
+# $NetBSD: md.i386,v 1.127 2012/08/29 17:13:21 drochner Exp $
 ./usr/include/clang-3.0/avxintrin.h            comp-obsolete           obsolete
 ./usr/include/clang-3.0/avx2intrin.h           comp-obsolete           obsolete
 ./usr/include/clang-3.0/bmi2intrin.h           comp-obsolete           obsolete
@@ -165,6 +165,7 @@
 ./usr/include/x86/bus.h                                comp-obsolete           obsolete
 ./usr/include/x86/cacheinfo.h                  comp-c-include
 ./usr/include/x86/cpu.h                                comp-c-include
+./usr/include/x86/cpu_ucode.h                  comp-c-include
 ./usr/include/x86/cputypes.h                   comp-c-include
 ./usr/include/x86/cpuvar.h                     comp-c-include
 ./usr/include/x86/float.h                      comp-c-include
diff -r 05d5f741978f -r d4a8ac2a9512 sys/arch/x86/conf/files.x86
--- a/sys/arch/x86/conf/files.x86       Wed Aug 29 17:08:41 2012 +0000
+++ b/sys/arch/x86/conf/files.x86       Wed Aug 29 17:13:21 2012 +0000
@@ -1,4 +1,4 @@
-#      $NetBSD: files.x86,v 1.78 2012/05/07 17:45:29 jym Exp $
+#      $NetBSD: files.x86,v 1.79 2012/08/29 17:13:21 drochner Exp $
 
 # options for MP configuration through the MP spec
 defflag opt_mpbios.h MPBIOS MPVERBOSE MPDEBUG MPBIOS_SCANPCI
@@ -96,6 +96,7 @@
 
 file   arch/x86/x86/cpu_ucode.c        cpu_ucode needs-flag
 file   arch/x86/x86/cpu_ucode_amd.c    cpu_ucode needs-flag
+file   arch/x86/x86/cpu_ucode_intel.c  cpu_ucode needs-flag
 
 define lapic
 file   arch/x86/x86/lapic.c            lapic needs-flag
diff -r 05d5f741978f -r d4a8ac2a9512 sys/arch/x86/include/Makefile
--- a/sys/arch/x86/include/Makefile     Wed Aug 29 17:08:41 2012 +0000
+++ b/sys/arch/x86/include/Makefile     Wed Aug 29 17:13:21 2012 +0000
@@ -1,4 +1,4 @@
-#      $NetBSD: Makefile,v 1.16 2011/07/17 23:38:32 dyoung Exp $
+#      $NetBSD: Makefile,v 1.17 2012/08/29 17:13:22 drochner Exp $
 
 INCSDIR=/usr/include/x86
 
@@ -6,6 +6,7 @@
        bootinfo.h \
        cacheinfo.h \
        cpu.h \
+       cpu_ucode.h \
        cputypes.h \
        cpuvar.h \
        float.h \
diff -r 05d5f741978f -r d4a8ac2a9512 sys/arch/x86/include/cpu_ucode.h
--- a/sys/arch/x86/include/cpu_ucode.h  Wed Aug 29 17:08:41 2012 +0000
+++ b/sys/arch/x86/include/cpu_ucode.h  Wed Aug 29 17:13:21 2012 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: cpu_ucode.h,v 1.1 2012/01/13 16:05:14 cegger Exp $ */
+/* $NetBSD: cpu_ucode.h,v 1.2 2012/08/29 17:13:22 drochner Exp $ */
 /*
  * Copyright (c) 2012 The NetBSD Foundation, Inc.
  * All rights reserved.
@@ -31,12 +31,57 @@
 #ifndef _X86_CPU_UCODE_H_
 #define _X86_CPU_UCODE_H_
 
+#define CPU_UCODE_LOADER_AMD 0
+struct cpu_ucode_version_amd {
+       uint64_t version;
+};
+
+#define CPU_UCODE_LOADER_INTEL1 1
+struct cpu_ucode_version_intel1 {
+       uint32_t ucodeversion;
+       int platformid;
+};
+
+#ifdef _KERNEL
 #include <sys/cpu.h>
 #include <sys/cpuio.h>
 #include <dev/firmload.h>
 
-int cpu_ucode_amd_get_version(struct cpu_ucode *);
+int cpu_ucode_amd_get_version(struct cpu_ucode_version *);
+/* XXX COMPAT */
+int compat6_cpu_ucode_amd_get_version(struct compat6_cpu_ucode *);
 int cpu_ucode_amd_firmware_open(firmware_handle_t *, const char *);
-int cpu_ucode_amd_apply(struct cpu_ucode_softc *);
+int cpu_ucode_amd_apply(struct cpu_ucode_softc *, int);
+
+int cpu_ucode_intel_get_version(struct cpu_ucode_version *);
+int cpu_ucode_intel_firmware_open(firmware_handle_t *, const char *);
+int cpu_ucode_intel_apply(struct cpu_ucode_softc *, int);
+#endif /* _KERNEL */
+
+struct intel1_ucode_header {
+       uint32_t        uh_header_ver;
+       uint32_t        uh_rev;
+       uint32_t        uh_date;
+       uint32_t        uh_signature;
+       uint32_t        uh_checksum;
+       uint32_t        uh_loader_rev;
+       uint32_t        uh_proc_flags;
+       uint32_t        uh_data_size;
+       uint32_t        uh_total_size;
+       uint32_t        uh_reserved[3];
+};
+
+struct intel1_ucode_proc_signature {
+       uint32_t        ups_signature;
+       uint32_t        ups_proc_flags;
+       uint32_t        ups_checksum;
+};
+
+struct intel1_ucode_ext_table {
+       uint32_t        uet_count;
+       uint32_t        uet_checksum;
+       uint32_t        uet_reserved[3];
+       struct intel1_ucode_proc_signature uet_proc_sig[1];
+};
 
 #endif
diff -r 05d5f741978f -r d4a8ac2a9512 sys/arch/x86/x86/cpu_ucode.c
--- a/sys/arch/x86/x86/cpu_ucode.c      Wed Aug 29 17:08:41 2012 +0000
+++ b/sys/arch/x86/x86/cpu_ucode.c      Wed Aug 29 17:13:21 2012 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: cpu_ucode.c,v 1.1 2012/01/13 16:05:15 cegger Exp $ */
+/* $NetBSD: cpu_ucode.c,v 1.2 2012/08/29 17:13:22 drochner Exp $ */
 /*
  * Copyright (c) 2012 The NetBSD Foundation, Inc.
  * All rights reserved.
@@ -29,7 +29,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: cpu_ucode.c,v 1.1 2012/01/13 16:05:15 cegger Exp $");
+__KERNEL_RCSID(0, "$NetBSD: cpu_ucode.c,v 1.2 2012/08/29 17:13:22 drochner Exp $");
 
 #include "opt_cpu_ucode.h"
 
@@ -47,15 +47,30 @@
 static struct cpu_ucode_softc ucode_softc;
 
 int
-cpu_ucode_get_version(void *data)
+cpu_ucode_get_version(struct cpu_ucode_version *data)
 {
-       struct cpu_ucode *ucode = data;
 
        switch (cpu_vendor) {
        case CPUVENDOR_AMD:
-               return cpu_ucode_amd_get_version(ucode);
+               return cpu_ucode_amd_get_version(data);
+       case CPUVENDOR_INTEL:
+               return cpu_ucode_intel_get_version(data);
        default:
-               ucode->version = (uint64_t)-1;
+               return EOPNOTSUPP;
+       }
+
+       return 0;
+}
+
+/* XXX COMPAT */
+int
+compat6_cpu_ucode_get_version(struct compat6_cpu_ucode *data)
+{
+
+       switch (cpu_vendor) {
+       case CPUVENDOR_AMD:
+               return compat6_cpu_ucode_amd_get_version(data);
+       default:
                return EOPNOTSUPP;
        }
 
@@ -63,32 +78,36 @@
 }
 
 int
-cpu_ucode_md_open(firmware_handle_t *fwh, const char *fwname)
+cpu_ucode_md_open(firmware_handle_t *fwh, int loader_version, const char *fwname)
 {
        switch (cpu_vendor) {
        case CPUVENDOR_AMD:
                return cpu_ucode_amd_firmware_open(fwh, fwname);
        case CPUVENDOR_INTEL:
-               return EOPNOTSUPP; /* not yet supported */
+               return cpu_ucode_intel_firmware_open(fwh, fwname);
        default:
                return EOPNOTSUPP;
        }
 }
 
 int
-cpu_ucode_apply(void *data)
+cpu_ucode_apply(const struct cpu_ucode *data)
 {
-       struct cpu_ucode *ucode = data;
        struct cpu_ucode_softc *sc = &ucode_softc;
        int error;
 
-       error = cpu_ucode_load(sc, ucode->fwname);
+       sc->loader_version = data->loader_version;
+
+       error = cpu_ucode_load(sc, data->fwname);
        if (error)
                return error;
 
        switch (cpu_vendor) {
        case CPUVENDOR_AMD:
-               error = cpu_ucode_amd_apply(sc);
+               error = cpu_ucode_amd_apply(sc, data->cpu_nr);
+               break;
+       case CPUVENDOR_INTEL:
+               error = cpu_ucode_intel_apply(sc, data->cpu_nr);
                break;
        default:
                return EOPNOTSUPP;
@@ -100,3 +119,27 @@
        sc->sc_blobsize = 0;
        return error;
 }
+
+/* XXX COMPAT */
+int
+compat6_cpu_ucode_apply(const struct compat6_cpu_ucode *data)
+{
+       struct cpu_ucode_softc *sc = &ucode_softc;
+       int error;
+
+       if (cpu_vendor != CPUVENDOR_AMD)
+               return EOPNOTSUPP;
+
+       sc->loader_version = CPU_UCODE_LOADER_AMD;
+       error = cpu_ucode_load(sc, data->fwname);
+       if (error)
+               return error;
+
+       error = cpu_ucode_amd_apply(sc, CPU_UCODE_ALL_CPUS);
+
+       if (sc->sc_blob != NULL)
+               firmware_free(sc->sc_blob, 0);
+       sc->sc_blob = NULL;
+       sc->sc_blobsize = 0;
+       return error;
+}
diff -r 05d5f741978f -r d4a8ac2a9512 sys/arch/x86/x86/cpu_ucode_amd.c
--- a/sys/arch/x86/x86/cpu_ucode_amd.c  Wed Aug 29 17:08:41 2012 +0000
+++ b/sys/arch/x86/x86/cpu_ucode_amd.c  Wed Aug 29 17:13:21 2012 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: cpu_ucode_amd.c,v 1.3 2012/05/10 12:35:53 cegger Exp $ */
+/* $NetBSD: cpu_ucode_amd.c,v 1.4 2012/08/29 17:13:22 drochner Exp $ */
 /*
  * Copyright (c) 2012 The NetBSD Foundation, Inc.
  * All rights reserved.
@@ -29,7 +29,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: cpu_ucode_amd.c,v 1.3 2012/05/10 12:35:53 cegger Exp $");
+__KERNEL_RCSID(0, "$NetBSD: cpu_ucode_amd.c,v 1.4 2012/08/29 17:13:22 drochner Exp $");
 
 #include "opt_xen.h"
 #include "opt_cpu_ucode.h"
@@ -102,14 +102,29 @@
 }
 
 int
-cpu_ucode_amd_get_version(struct cpu_ucode *ucode)
+cpu_ucode_amd_get_version(struct cpu_ucode_version *ucode)
 {
-       if (amd_cpufamily() < 0x10) {
-               ucode->version = (uint64_t)-1;
+       struct cpu_ucode_version_amd data;
+
+       if (ucode->loader_version != CPU_UCODE_LOADER_AMD || amd_cpufamily() < 0x10)
                return EOPNOTSUPP;
-       }
+       if (!ucode->data)
+               return 0;
+
+       data.version = rdmsr(MSR_UCODE_AMD_PATCHLEVEL);
+       return copyout(&data, ucode->data, sizeof(data));
+}
 



Home | Main Index | Thread Index | Old Index