Page Menu
Home
FreeBSD
Search
Configure Global Search
Log In
Files
F102053544
D43318.id133533.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Flag For Later
Award Token
Size
20 KB
Referenced Files
None
Subscribers
None
D43318.id133533.diff
View Options
diff --git a/sys/conf/files.x86 b/sys/conf/files.x86
--- a/sys/conf/files.x86
+++ b/sys/conf/files.x86
@@ -347,6 +347,7 @@
x86/x86/stack_machdep.c optional ddb | stack
x86/x86/tsc.c standard
x86/x86/ucode.c standard
+x86/x86/ucode_subr.c standard
x86/x86/delay.c standard
x86/xen/hvm.c optional xenhvm
x86/xen/xen_apic.c optional xenhvm smp
diff --git a/sys/x86/include/ucode.h b/sys/x86/include/ucode.h
--- a/sys/x86/include/ucode.h
+++ b/sys/x86/include/ucode.h
@@ -56,7 +56,12 @@
} entries[0];
};
-int ucode_intel_load(void *data, bool unsafe,
+const void *ucode_amd_find(const char *path, uint32_t signature,
+ uint32_t revision, const uint8_t *fw_data, size_t fw_size,
+ size_t *selected_sizep);
+int ucode_intel_load(const void *data, bool unsafe,
+ uint64_t *nrevp, uint64_t *orevp);
+int ucode_amd_load(const void *data, bool unsafe,
uint64_t *nrevp, uint64_t *orevp);
size_t ucode_load_bsp(uintptr_t free);
void ucode_load_ap(int cpu);
diff --git a/sys/x86/x86/ucode.c b/sys/x86/x86/ucode.c
--- a/sys/x86/x86/ucode.c
+++ b/sys/x86/x86/ucode.c
@@ -50,25 +50,32 @@
#include <vm/vm_kern.h>
#include <vm/vm_param.h>
-static void *ucode_intel_match(uint8_t *data, size_t *len);
-static int ucode_intel_verify(struct ucode_intel_header *hdr,
+static const void *ucode_intel_match(const uint8_t *data, size_t *len);
+static int ucode_intel_verify(const struct ucode_intel_header *hdr,
size_t resid);
+static const void *ucode_amd_match(const uint8_t *data, size_t *len);
+
static struct ucode_ops {
const char *vendor;
- int (*load)(void *, bool, uint64_t *, uint64_t *);
- void *(*match)(uint8_t *, size_t *);
+ int (*load)(const void *, bool, uint64_t *, uint64_t *);
+ const void *(*match)(const uint8_t *, size_t *);
} loaders[] = {
{
.vendor = INTEL_VENDOR_ID,
.load = ucode_intel_load,
.match = ucode_intel_match,
},
+ {
+ .vendor = AMD_VENDOR_ID,
+ .load = ucode_amd_load,
+ .match = ucode_amd_match,
+ },
};
/* Selected microcode update data. */
-static void *early_ucode_data;
-static void *ucode_data;
+static const void *early_ucode_data;
+static const void *ucode_data;
static struct ucode_ops *ucode_loader;
/* Variables used for reporting success or failure. */
@@ -103,7 +110,7 @@
SYSINIT(ucode_log, SI_SUB_CPU, SI_ORDER_FIRST, log_msg, NULL);
int
-ucode_intel_load(void *data, bool unsafe, uint64_t *nrevp, uint64_t *orevp)
+ucode_intel_load(const void *data, bool unsafe, uint64_t *nrevp, uint64_t *orevp)
{
uint64_t nrev, orev;
uint32_t cpuid[4];
@@ -140,9 +147,10 @@
}
static int
-ucode_intel_verify(struct ucode_intel_header *hdr, size_t resid)
+ucode_intel_verify(const struct ucode_intel_header *hdr, size_t resid)
{
- uint32_t cksum, *data, size;
+ const uint32_t *data;
+ uint32_t cksum, size;
int i;
if (resid < sizeof(struct ucode_intel_header))
@@ -160,7 +168,7 @@
return (1);
cksum = 0;
- data = (uint32_t *)hdr;
+ data = (const uint32_t *)hdr;
for (i = 0; i < size / sizeof(uint32_t); i++)
cksum += data[i];
if (cksum != 0)
@@ -168,12 +176,12 @@
return (0);
}
-static void *
-ucode_intel_match(uint8_t *data, size_t *len)
+static const void *
+ucode_intel_match(const uint8_t *data, size_t *len)
{
- struct ucode_intel_header *hdr;
- struct ucode_intel_extsig_table *table;
- struct ucode_intel_extsig *entry;
+ const struct ucode_intel_header *hdr;
+ const struct ucode_intel_extsig_table *table;
+ const struct ucode_intel_extsig *entry;
uint64_t platformid;
size_t resid;
uint32_t data_size, flags, regs[4], sig, total_size;
@@ -186,7 +194,7 @@
flags = 1 << ((platformid >> 50) & 0x7);
for (resid = *len; resid > 0; data += total_size, resid -= total_size) {
- hdr = (struct ucode_intel_header *)data;
+ hdr = (const struct ucode_intel_header *)data;
if (ucode_intel_verify(hdr, resid) != 0) {
ucode_error = VERIFICATION_FAILED;
break;
@@ -200,8 +208,8 @@
total_size = UCODE_INTEL_DEFAULT_DATA_SIZE +
sizeof(struct ucode_intel_header);
if (data_size > total_size + sizeof(struct ucode_intel_header))
- table = (struct ucode_intel_extsig_table *)
- ((uint8_t *)(hdr + 1) + data_size);
+ table = (const struct ucode_intel_extsig_table *)
+ ((const uint8_t *)(hdr + 1) + data_size);
else
table = NULL;
@@ -224,6 +232,54 @@
return (NULL);
}
+int
+ucode_amd_load(const void *data, bool unsafe, uint64_t *nrevp, uint64_t *orevp)
+{
+ uint64_t nrev, orev;
+ uint32_t cpuid[4];
+
+ orev = rdmsr(MSR_BIOS_SIGN);
+
+ /*
+ * Perform update.
+ */
+ if (unsafe)
+ wrmsr_safe(MSR_K8_UCODE_UPDATE, (uint64_t)(uintptr_t)data);
+ else
+ wrmsr(MSR_K8_UCODE_UPDATE, (uint64_t)(uintptr_t)data);
+
+ /*
+ * Serialize instruction flow.
+ */
+ do_cpuid(0, cpuid);
+
+ /*
+ * Verify that the microcode revision changed.
+ */
+ nrev = rdmsr(MSR_BIOS_SIGN);
+ if (nrevp != NULL)
+ *nrevp = nrev;
+ if (orevp != NULL)
+ *orevp = orev;
+ if (nrev <= orev)
+ return (EEXIST);
+ return (0);
+
+}
+
+static const void *
+ucode_amd_match(const uint8_t *data, size_t *len)
+{
+ uint32_t signature, revision;
+ uint32_t regs[4];
+
+ do_cpuid(1, regs);
+ signature = regs[0];
+ revision = rdmsr(MSR_BIOS_SIGN);
+
+ return (ucode_amd_find("loader blob", signature, revision, data, *len, len));
+}
+
/*
* Release any memory backing unused microcode blobs back to the system.
* We copy the selected update and free the entire microcode file.
@@ -317,7 +373,8 @@
uint32_t regs[4];
char vendor[13];
} cpuid;
- uint8_t *addr, *fileaddr, *match;
+ const uint8_t *fileaddr, *match;
+ uint8_t *addr;
char *type;
uint64_t nrev, orev;
caddr_t file;
diff --git a/usr.sbin/cpucontrol/amd10h.c b/sys/x86/x86/ucode_subr.c
copy from usr.sbin/cpucontrol/amd10h.c
copy to sys/x86/x86/ucode_subr.c
--- a/usr.sbin/cpucontrol/amd10h.c
+++ b/sys/x86/x86/ucode_subr.c
@@ -1,4 +1,8 @@
/*-
+ * SPDX-License-Identifier: BSD-2-Clause
+ *
+ * Copyright (c) 2006, 2008 Stanislav Sedov <stas@FreeBSD.org>.
+ * All rights reserved.
* Copyright (c) 2012 Andriy Gapon <avg@FreeBSD.org>.
* All rights reserved.
*
@@ -23,115 +27,85 @@
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <sys/mman.h>
-#include <sys/ioctl.h>
-#include <sys/ioccom.h>
-#include <sys/cpuctl.h>
+#include <sys/param.h>
+#include <sys/systm.h>
-#include <machine/cpufunc.h>
-#include <machine/specialreg.h>
+#ifndef _KERNEL
+#include <stdbool.h>
-#include <assert.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <unistd.h>
-#include <fcntl.h>
#include <err.h>
#include "cpucontrol.h"
-#include "amd.h"
+#endif
-int
-amd10h_probe(int fd)
-{
- char vendor[13];
- cpuctl_cpuid_args_t idargs;
- uint32_t family;
- uint32_t signature;
- int error;
+#include <x86/ucode.h>
- idargs.level = 0;
- error = ioctl(fd, CPUCTL_CPUID, &idargs);
- if (error < 0) {
- WARN(0, "ioctl()");
- return (1);
+#ifdef _KERNEL
+#define WARNX(level, ...) \
+ if (bootverbose) { \
+ printf(__VA_ARGS__); \
+ printf("\n"); \
}
- ((uint32_t *)vendor)[0] = idargs.data[1];
- ((uint32_t *)vendor)[1] = idargs.data[3];
- ((uint32_t *)vendor)[2] = idargs.data[2];
- vendor[12] = '\0';
- if (strncmp(vendor, AMD_VENDOR_ID, sizeof(AMD_VENDOR_ID)) != 0)
- return (1);
+#endif
- idargs.level = 1;
- error = ioctl(fd, CPUCTL_CPUID, &idargs);
- if (error < 0) {
- WARN(0, "ioctl()");
- return (1);
- }
- signature = idargs.data[0];
- family = ((signature >> 8) & 0x0f) + ((signature >> 20) & 0xff);
- if (family < 0x10)
- return (1);
- return (0);
-}
+/*
+ * AMD family 10h and later.
+ */
+typedef struct amd_10h_fw_header {
+ uint32_t data_code;
+ uint32_t patch_id;
+ uint16_t mc_patch_data_id;
+ uint8_t mc_patch_data_len;
+ uint8_t init_flag;
+ uint32_t mc_patch_data_checksum;
+ uint32_t nb_dev_id;
+ uint32_t sb_dev_id;
+ uint16_t processor_rev_id;
+ uint8_t nb_rev_id;
+ uint8_t sb_rev_id;
+ uint8_t bios_api_rev;
+ uint8_t reserved1[3];
+ uint32_t match_reg[8];
+} amd_10h_fw_header_t;
+
+typedef struct equiv_cpu_entry {
+ uint32_t installed_cpu;
+ uint32_t fixed_errata_mask;
+ uint32_t fixed_errata_compare;
+ uint16_t equiv_cpu;
+ uint16_t res;
+} equiv_cpu_entry_t;
+
+typedef struct section_header {
+ uint32_t type;
+ uint32_t size;
+} section_header_t;
+
+typedef struct container_header {
+ uint32_t magic;
+} container_header_t;
+
+#define AMD_10H_MAGIC 0x414d44
+#define AMD_10H_EQUIV_TABLE_TYPE 0
+#define AMD_10H_uCODE_TYPE 1
/*
* NB: the format of microcode update files is not documented by AMD.
* It has been reverse engineered from studying Coreboot, illumos and Linux
* source code.
*/
-void
-amd10h_update(const struct ucode_update_params *params)
+const void *
+ucode_amd_find(const char *path, uint32_t signature, uint32_t revision,
+ const uint8_t *fw_data, size_t fw_size, size_t *selected_sizep)
{
- cpuctl_cpuid_args_t idargs;
- cpuctl_msr_args_t msrargs;
- cpuctl_update_args_t args;
const amd_10h_fw_header_t *fw_header;
const amd_10h_fw_header_t *selected_fw;
const equiv_cpu_entry_t *equiv_cpu_table;
const section_header_t *section_header;
const container_header_t *container_header;
- const uint8_t *fw_data;
- const uint8_t *fw_image;
- const char *dev, *path;
- size_t fw_size;
size_t selected_size;
- uint32_t revision;
- uint32_t new_rev;
- uint32_t signature;
uint16_t equiv_id;
- int devfd;
- unsigned int i;
- int error;
-
- dev = params->dev_path;
- path = params->fw_path;
- devfd = params->devfd;
- fw_image = params->fwimage;
- fw_size = params->fwsize;
-
- assert(path);
- assert(dev);
-
- idargs.level = 1;
- error = ioctl(devfd, CPUCTL_CPUID, &idargs);
- if (error < 0) {
- WARN(0, "ioctl()");
- goto done;
- }
- signature = idargs.data[0];
-
- msrargs.msr = MSR_BIOS_SIGN;
- error = ioctl(devfd, CPUCTL_RDMSR, &msrargs);
- if (error < 0) {
- WARN(0, "ioctl(%s)", dev);
- goto done;
- }
- revision = (uint32_t)msrargs.data;
+ int i;
WARNX(1, "found cpu family %#x model %#x "
"stepping %#x extfamily %#x extmodel %#x.",
@@ -141,24 +115,19 @@
(signature >> 16) & 0x0f);
WARNX(1, "microcode revision %#x", revision);
- /*
- * Open the firmware file.
- */
+nextfile:
WARNX(1, "checking %s for update.", path);
+ WARNX(3, "processing next container file");
if (fw_size <
(sizeof(*container_header) + sizeof(*section_header))) {
WARNX(2, "file too short: %s", path);
- goto done;
+ return (NULL);
}
- /*
- * mmap the whole image.
- */
- fw_data = fw_image;
container_header = (const container_header_t *)fw_data;
if (container_header->magic != AMD_10H_MAGIC) {
WARNX(2, "%s is not a valid amd firmware: bad magic", path);
- goto done;
+ return (NULL);
}
fw_data += sizeof(*container_header);
fw_size -= sizeof(*container_header);
@@ -167,12 +136,12 @@
if (section_header->type != AMD_10H_EQUIV_TABLE_TYPE) {
WARNX(2, "%s is not a valid amd firmware: "
"first section is not CPU equivalence table", path);
- goto done;
+ return (NULL);
}
if (section_header->size == 0) {
WARNX(2, "%s is not a valid amd firmware: "
"first section is empty", path);
- goto done;
+ return (NULL);
}
fw_data += sizeof(*section_header);
fw_size -= sizeof(*section_header);
@@ -180,12 +149,12 @@
if (section_header->size > fw_size) {
WARNX(2, "%s is not a valid amd firmware: "
"file is truncated", path);
- goto done;
+ return (NULL);
}
if (section_header->size < sizeof(*equiv_cpu_table)) {
WARNX(2, "%s is not a valid amd firmware: "
"first section is too short", path);
- goto done;
+ return (NULL);
}
equiv_cpu_table = (const equiv_cpu_entry_t *)fw_data;
fw_data += section_header->size;
@@ -193,6 +162,9 @@
equiv_id = 0;
for (i = 0; equiv_cpu_table[i].installed_cpu != 0; i++) {
+ WARNX(3, "signature 0x%x i %d installed_cpu 0x%x equiv 0x%x",
+ signature, i, equiv_cpu_table[i].installed_cpu,
+ equiv_cpu_table[i].equiv_cpu);
if (signature == equiv_cpu_table[i].installed_cpu) {
equiv_id = equiv_cpu_table[i].equiv_cpu;
WARNX(3, "equiv_id: %x, signature %8x,"
@@ -203,29 +175,34 @@
}
if (equiv_id == 0) {
WARNX(2, "CPU is not found in the equivalence table");
- goto done;
}
- selected_fw = NULL;
- selected_size = 0;
while (fw_size >= sizeof(*section_header)) {
section_header = (const section_header_t *)fw_data;
+ if (section_header->type == AMD_10H_MAGIC) {
+ WARNX(2, "%s next section is actually a new container",
+ path);
+ if (selected_fw != NULL)
+ goto found;
+ else
+ goto nextfile;
+ }
fw_data += sizeof(*section_header);
fw_size -= sizeof(*section_header);
if (section_header->type != AMD_10H_uCODE_TYPE) {
WARNX(2, "%s is not a valid amd firmware: "
"section has incorrect type", path);
- goto done;
+ break;
}
if (section_header->size > fw_size) {
WARNX(2, "%s is not a valid amd firmware: "
"file is truncated", path);
- goto done;
+ break;
}
if (section_header->size < sizeof(*fw_header)) {
WARNX(2, "%s is not a valid amd firmware: "
"section is too short", path);
- goto done;
+ break;
}
fw_header = (const amd_10h_fw_header_t *)fw_data;
fw_data += section_header->size;
@@ -254,35 +231,10 @@
if (fw_size != 0) {
WARNX(2, "%s is not a valid amd firmware: "
"file is truncated", path);
- goto done;
- }
-
- if (selected_fw != NULL) {
- WARNX(1, "selected ucode size is %zu", selected_size);
- fprintf(stderr, "%s: updating cpu %s to revision %#x... ",
- path, dev, revision);
-
- args.data = __DECONST(void *, selected_fw);
- args.size = selected_size;
- error = ioctl(devfd, CPUCTL_UPDATE, &args);
- if (error < 0) {
- fprintf(stderr, "failed.\n");
- warn("ioctl()");
- goto done;
- }
- fprintf(stderr, "done.\n");
- }
-
- msrargs.msr = MSR_BIOS_SIGN;
- error = ioctl(devfd, CPUCTL_RDMSR, &msrargs);
- if (error < 0) {
- WARN(0, "ioctl(%s)", dev);
- goto done;
+ selected_fw = NULL;
}
- new_rev = (uint32_t)msrargs.data;
- if (new_rev != revision)
- WARNX(0, "revision after update %#x", new_rev);
-done:
- return;
+found:
+ *selected_sizep = selected_size;
+ return (selected_fw);
}
diff --git a/usr.sbin/cpucontrol/Makefile b/usr.sbin/cpucontrol/Makefile
--- a/usr.sbin/cpucontrol/Makefile
+++ b/usr.sbin/cpucontrol/Makefile
@@ -1,8 +1,12 @@
PROG= cpucontrol
MAN= cpucontrol.8
-SRCS= cpucontrol.c intel.c amd.c amd10h.c via.c
+SRCS= cpucontrol.c intel.c amd.c amd10h.c via.c ucode_subr.c
+
+.PATH: ${SRCTOP}/sys/x86/x86
NO_WCAST_ALIGN=
+CFLAGS+= -I${.CURDIR}
+
.include <bsd.prog.mk>
diff --git a/usr.sbin/cpucontrol/amd.h b/usr.sbin/cpucontrol/amd.h
--- a/usr.sbin/cpucontrol/amd.h
+++ b/usr.sbin/cpucontrol/amd.h
@@ -48,45 +48,4 @@
#define AMD_MAGIC 0xaaaaaa
-/*
- * AMD family 10h and later.
- */
-typedef struct amd_10h_fw_header {
- uint32_t data_code;
- uint32_t patch_id;
- uint16_t mc_patch_data_id;
- uint8_t mc_patch_data_len;
- uint8_t init_flag;
- uint32_t mc_patch_data_checksum;
- uint32_t nb_dev_id;
- uint32_t sb_dev_id;
- uint16_t processor_rev_id;
- uint8_t nb_rev_id;
- uint8_t sb_rev_id;
- uint8_t bios_api_rev;
- uint8_t reserved1[3];
- uint32_t match_reg[8];
-} amd_10h_fw_header_t;
-
-typedef struct equiv_cpu_entry {
- uint32_t installed_cpu;
- uint32_t fixed_errata_mask;
- uint32_t fixed_errata_compare;
- uint16_t equiv_cpu;
- uint16_t res;
-} equiv_cpu_entry_t;
-
-typedef struct section_header {
- uint32_t type;
- uint32_t size;
-} section_header_t;
-
-typedef struct container_header {
- uint32_t magic;
-} container_header_t;
-
-#define AMD_10H_MAGIC 0x414d44
-#define AMD_10H_EQUIV_TABLE_TYPE 0
-#define AMD_10H_uCODE_TYPE 1
-
#endif /* !AMD_H */
diff --git a/usr.sbin/cpucontrol/amd10h.c b/usr.sbin/cpucontrol/amd10h.c
--- a/usr.sbin/cpucontrol/amd10h.c
+++ b/usr.sbin/cpucontrol/amd10h.c
@@ -33,6 +33,9 @@
#include <machine/cpufunc.h>
#include <machine/specialreg.h>
+#include <stdbool.h>
+#include <x86/ucode.h>
+
#include <assert.h>
#include <stdio.h>
#include <stdlib.h>
@@ -79,33 +82,21 @@
return (0);
}
-/*
- * NB: the format of microcode update files is not documented by AMD.
- * It has been reverse engineered from studying Coreboot, illumos and Linux
- * source code.
- */
void
amd10h_update(const struct ucode_update_params *params)
{
cpuctl_cpuid_args_t idargs;
cpuctl_msr_args_t msrargs;
cpuctl_update_args_t args;
- const amd_10h_fw_header_t *fw_header;
- const amd_10h_fw_header_t *selected_fw;
- const equiv_cpu_entry_t *equiv_cpu_table;
- const section_header_t *section_header;
- const container_header_t *container_header;
- const uint8_t *fw_data;
const uint8_t *fw_image;
const char *dev, *path;
+ const void *selected_fw;
size_t fw_size;
size_t selected_size;
uint32_t revision;
uint32_t new_rev;
uint32_t signature;
- uint16_t equiv_id;
int devfd;
- unsigned int i;
int error;
dev = params->dev_path;
@@ -133,129 +124,8 @@
}
revision = (uint32_t)msrargs.data;
- WARNX(1, "found cpu family %#x model %#x "
- "stepping %#x extfamily %#x extmodel %#x.",
- ((signature >> 8) & 0x0f) + ((signature >> 20) & 0xff),
- (signature >> 4) & 0x0f,
- (signature >> 0) & 0x0f, (signature >> 20) & 0xff,
- (signature >> 16) & 0x0f);
- WARNX(1, "microcode revision %#x", revision);
-
- /*
- * Open the firmware file.
- */
- WARNX(1, "checking %s for update.", path);
- if (fw_size <
- (sizeof(*container_header) + sizeof(*section_header))) {
- WARNX(2, "file too short: %s", path);
- goto done;
- }
-
- /*
- * mmap the whole image.
- */
- fw_data = fw_image;
- container_header = (const container_header_t *)fw_data;
- if (container_header->magic != AMD_10H_MAGIC) {
- WARNX(2, "%s is not a valid amd firmware: bad magic", path);
- goto done;
- }
- fw_data += sizeof(*container_header);
- fw_size -= sizeof(*container_header);
-
- section_header = (const section_header_t *)fw_data;
- if (section_header->type != AMD_10H_EQUIV_TABLE_TYPE) {
- WARNX(2, "%s is not a valid amd firmware: "
- "first section is not CPU equivalence table", path);
- goto done;
- }
- if (section_header->size == 0) {
- WARNX(2, "%s is not a valid amd firmware: "
- "first section is empty", path);
- goto done;
- }
- fw_data += sizeof(*section_header);
- fw_size -= sizeof(*section_header);
-
- if (section_header->size > fw_size) {
- WARNX(2, "%s is not a valid amd firmware: "
- "file is truncated", path);
- goto done;
- }
- if (section_header->size < sizeof(*equiv_cpu_table)) {
- WARNX(2, "%s is not a valid amd firmware: "
- "first section is too short", path);
- goto done;
- }
- equiv_cpu_table = (const equiv_cpu_entry_t *)fw_data;
- fw_data += section_header->size;
- fw_size -= section_header->size;
-
- equiv_id = 0;
- for (i = 0; equiv_cpu_table[i].installed_cpu != 0; i++) {
- if (signature == equiv_cpu_table[i].installed_cpu) {
- equiv_id = equiv_cpu_table[i].equiv_cpu;
- WARNX(3, "equiv_id: %x, signature %8x,"
- " equiv_cpu_table[%d] %8x", equiv_id, signature,
- i, equiv_cpu_table[i].installed_cpu);
- break;
- }
- }
- if (equiv_id == 0) {
- WARNX(2, "CPU is not found in the equivalence table");
- goto done;
- }
-
- selected_fw = NULL;
- selected_size = 0;
- while (fw_size >= sizeof(*section_header)) {
- section_header = (const section_header_t *)fw_data;
- fw_data += sizeof(*section_header);
- fw_size -= sizeof(*section_header);
- if (section_header->type != AMD_10H_uCODE_TYPE) {
- WARNX(2, "%s is not a valid amd firmware: "
- "section has incorrect type", path);
- goto done;
- }
- if (section_header->size > fw_size) {
- WARNX(2, "%s is not a valid amd firmware: "
- "file is truncated", path);
- goto done;
- }
- if (section_header->size < sizeof(*fw_header)) {
- WARNX(2, "%s is not a valid amd firmware: "
- "section is too short", path);
- goto done;
- }
- fw_header = (const amd_10h_fw_header_t *)fw_data;
- fw_data += section_header->size;
- fw_size -= section_header->size;
-
- if (fw_header->processor_rev_id != equiv_id) {
- WARNX(1, "firmware processor_rev_id %x, equiv_id %x",
- fw_header->processor_rev_id, equiv_id);
- continue; /* different cpu */
- }
- if (fw_header->patch_id <= revision) {
- WARNX(1, "patch_id %x, revision %x",
- fw_header->patch_id, revision);
- continue; /* not newer revision */
- }
- if (fw_header->nb_dev_id != 0 || fw_header->sb_dev_id != 0) {
- WARNX(2, "Chipset-specific microcode is not supported");
- }
-
- WARNX(3, "selecting revision: %x", fw_header->patch_id);
- revision = fw_header->patch_id;
- selected_fw = fw_header;
- selected_size = section_header->size;
- }
-
- if (fw_size != 0) {
- WARNX(2, "%s is not a valid amd firmware: "
- "file is truncated", path);
- goto done;
- }
+ selected_fw = ucode_amd_find(path, signature, revision, fw_image,
+ fw_size, &selected_size);
if (selected_fw != NULL) {
WARNX(1, "selected ucode size is %zu", selected_size);
File Metadata
Details
Attached
Mime Type
text/plain
Expires
Fri, Nov 8, 1:05 AM (17 h, 36 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
14524444
Default Alt Text
D43318.id133533.diff (20 KB)
Attached To
Mode
D43318: x86/ucode: add support for early loading of CPU ucode on AMD.
Attached
Detach File
Event Timeline
Log In to Comment