61 #define UCODE_MAX_HT 8 64 #define UCODE_WAIT_MS 10 139 char text[
sizeof ( *vendor ) + 1 ];
144 u.text[
sizeof (
u.text ) - 1 ] =
'\0';
163 unsigned int id,
int optional ) {
170 if ( optional && ( !
status->signature ) )
172 DBGC ( update,
"UCODE %#08x signature %#08x ucode %#08x->%#08x\n",
176 if ( !
status->signature ) {
177 DBGC2 ( update,
"UCODE %#08x has no signature\n",
id );
183 DBGC ( update,
"UCODE %#08x wrong APIC ID %#08x\n",
189 if (
control->apic_unexpected ) {
190 DBGC ( update,
"UCODE %#08x saw unexpected APIC ID %#08x\n",
191 id,
control->apic_unexpected );
197 DBGC ( update,
"UCODE %#08x was downgraded %#08x->%#08x\n",
204 if ( (
desc->signature ==
status->signature ) &&
206 DBGC ( update,
"UCODE %#08x failed update %#08x->%#08x " 207 "(wanted %#08x)\n",
id,
status->before,
252 DBGC (
image,
"UCODE %s could not allocate %d status reports\n",
277 summary,
id, 0 ) ) != 0 ) {
278 DBGC (
image,
"UCODE %s failed on boot processor: %s\n",
295 for (
id = 0 ;
id <=
max ;
id++ ) {
297 summary,
id, 1 ) ) != 0 ) {
343 if ( update->
desc ) {
345 DBGC (
image,
"UCODE %s+%#04zx found %s %#08x version %#08x\n",
366 if ( (
len %
sizeof ( *
dword ) ) != 0 ) {
367 DBGC (
image,
"UCODE %s+%#04zx invalid length %#zx\n",
374 count = (
len /
sizeof ( *dword ) );
378 DBGC (
image,
"UCODE %s+%#04zx bad checksum %#08x\n",
409 if ( remaining <
sizeof ( *
hdr ) ) {
410 DBGC (
image,
"UCODE %s+%#04zx too small for Intel header\n",
427 (
len <
sizeof ( *
hdr ) ) ||
428 (
len > remaining ) ||
432 DBGC2 (
image,
"UCODE %s+%#04zx is not an Intel update\n",
436 DBGC2 (
image,
"UCODE %s+%#04zx is an Intel update\n",
444 desc.signature =
hdr->signature;
455 if (
offset <= (
len -
sizeof ( *exthdr ) ) ) {
459 offset +=
sizeof ( *exthdr );
462 for ( i = 0 ; i < exthdr->
count ; i++ ) {
466 DBGC (
image,
"UCODE %s+%#04zx extended " 467 "signature overrun\n",
472 offset +=
sizeof ( *ext );
475 if ( (
ext->signature ==
hdr->signature ) &&
476 (
ext->platforms ==
hdr->platforms ) ) {
481 desc.signature =
ext->signature;
483 ext->platforms, update );
513 if ( remaining <
sizeof ( *
hdr ) ) {
514 DBGC (
image,
"UCODE %s+%#04zx too small for AMD header\n",
522 DBGC2 (
image,
"UCODE %s+%#04zx is not an AMD update\n",
526 DBGC2 (
image,
"UCODE %s+%#04zx is an AMD update\n",
529 DBGC (
image,
"UCODE %s+%#04zx unsupported equivalence table " 533 if (
hdr->len > ( remaining - sizeof ( *
hdr ) ) ) {
534 DBGC (
image,
"UCODE %s+%#04zx truncated equivalence table\n",
547 DBGC2 (
image,
"UCODE %s+%#04zx has %d equivalence table entries\n",
553 while ( used <
count ) {
556 if ( (
offset +
sizeof ( *phdr ) ) > remaining ) {
557 DBGC (
image,
"UCODE %s+%#04zx truncated patch " 562 offset +=
sizeof ( *phdr );
566 DBGC (
image,
"UCODE %s+%#04zx unsupported patch type " 570 if ( phdr->
len < sizeof ( *patch ) ) {
571 DBGC (
image,
"UCODE %s+%#04zx underlength patch\n",
575 if ( phdr->
len > ( remaining -
offset ) ) {
576 DBGC (
image,
"UCODE %s+%#04zx truncated patch\n",
589 for ( i = 0 ; i <
count ; i++ ) {
590 if ( patch->
id == equiv[i].
id ) {
627 DBGC (
image,
"UCODE %s+%zx not recognised\n",
657 memset ( &update, 0,
sizeof ( update ) );
679 DBGC (
image,
"UCODE %s applying to %s %#08x",
686 DBGC (
image,
"UCODE %s found %d matching update(s)\n",
691 sizeof ( update.
desc[0] ) );
693 if ( ! update.
desc ) {
699 check = update.
count;
712 if ( summary.
low == summary.
high ) {
713 printf (
"already version %#x", summary.
low );
715 printf (
"updated version %#x->%#x",
763 ( (
header->intel.date.century == 0x19 ) ||
764 ( (
header->intel.date.century >= 0x20 ) &&
765 (
header->intel.date.century <= 0x29 ) ) ) ) {
766 DBGC (
image,
"UCODE %s+%#04zx looks like an Intel update\n",
774 DBGC (
image,
"UCODE %s+%#04zx looks like an AMD update\n",
uint16_t id
Equivalence ID.
static __always_inline void ufree(void *ptr)
Free external memory.
#define EINVAL
Invalid argument.
#define INTEL_UCODE_HVER
Intel microcode header version number.
struct arbelprm_rc_send_wqe rc
static int ucode_parse_amd(struct image *image, size_t start, struct ucode_update *update)
Parse AMD microcode image.
static int ucode_parse_intel(struct image *image, size_t start, struct ucode_update *update)
Parse Intel microcode image.
uint8_t checksum
Checksum.
int printf(const char *fmt,...)
Write a formatted string to the console.
#define CPUID_FEATURES
Get standard features.
static void ucode_describe(struct image *image, size_t start, const struct ucode_vendor *vendor, const struct ucode_descriptor *desc, uint32_t platforms, struct ucode_update *update)
Add descriptor to list (if applicable)
struct ucode_descriptor * desc
Update descriptors (if being populated)
#define MSR_UCODE_TRIGGER_INTEL
Intel microcode load trigger MSR.
static int ucode_parse(struct image *image, struct ucode_update *update)
Parse microcode image.
const void * data
Read-only data.
static struct ucode_vendor ucode_amd
AMD CPU vendor.
struct golan_inbox_hdr hdr
Message header.
#define UCODE_VERSION_MIN
Minimum possible microcode version.
#define AMD_UCODE_EQUIV_TYPE
AMD microcode equivalence table type.
#define ENOEXEC
Exec format error.
static unsigned short vendor
An Intel microcode extended signature.
static int ucode_verify(struct image *image, size_t start, size_t len)
Verify checksum.
#define CPUID_VENDOR_ID
Get vendor ID and largest standard function.
struct ucode_vendor * vendor
CPU vendor, if known.
An executable image type.
#define ENOENT
No such file or directory.
#define PROBE_NORMAL
Normal image probe priority.
unsigned long long uint64_t
A microcode update summary.
uint32_t data_len
Microcode data size (or 0 to indicate 2000 bytes)
uint8_t ver_high
Microcode version is reported via high dword.
static int ucode_exec(struct image *image)
Execute microcode update.
uint32_t platforms
Supported platforms.
unsigned int count
Number of CPUs processed.
static int ucode_probe(struct image *image)
Probe microcode update image.
char * name
Name of this image type.
#define ENOTSUP
Operation not supported.
char * cmdline
Command line to pass to image.
#define MSR_PLATFORM_ID
Platform ID MSR.
static int ucode_update_all(struct image *image, const struct ucode_update *update, struct ucode_summary *summary)
Update microcode on all CPUs.
uint32_t start
Starting offset.
void mp_start_all(mp_func_t func, void *opaque)
Start a multiprocessor function on all application processors.
struct ena_llq_option desc
Descriptor counts.
char * strstr(const char *haystack, const char *needle)
Find substring.
A microcode update descriptor.
#define ENOMEM
Not enough space.
static struct ucode_vendor ucode_intel
Intel CPU vendor.
void * memcpy(void *dest, const void *src, size_t len) __nonnull
FILE_LICENCE(GPL2_OR_LATER_OR_UBDL)
assert((readw(&hdr->flags) &(GTF_reading|GTF_writing))==0)
Access to external ("user") memory.
#define build_assert(condition)
Assert a condition at build time (after dead code elimination)
#define MSR_PLATFORM_ID_VALUE(value)
Extract platform ID from MSR value.
static unsigned int count
Number of entries.
An AMD microcode equivalence table entry.
A microcode update control.
uint8_t id
Request identifier.
unsigned int mp_max_cpuid(void)
Get maximum CPU identifier.
#define ERANGE
Result too large.
char * strerror(int errno)
Retrieve string representation of error number.
static void(* free)(struct refcnt *refcnt))
x86 CPU feature detection
void * zalloc(size_t size)
Allocate cleared memory.
uint8_t platform_id
Platform ID.
size_t len
Length of raw file image.
int32_t low
Lowest observed microcode version.
static struct ucode_vendor * ucode_vendors[]
List of known CPU vendors.
unsigned int mp_boot_cpuid(void)
Get boot CPU identifier.
#define AMD_UCODE_PATCH_TYPE
AMD patch type.
uint32_t trigger_msr
Microcode load trigger MSR.
uint32_t signature
CPU signature.
Multiprocessor functions.
#define UCODE_VERSION_MAX
Maximum possible microcode version.
uint16_t ext
Extended status.
A microcode update status report.
#define UCODE_MAX_HT
Maximum number of hyperthread siblings.
void mdelay(unsigned long msecs)
Delay for a fixed number of milliseconds.
#define AMD_UCODE_MAGIC
AMD microcode magic signature.
#define ENOTTY
Inappropriate I/O control operation.
static const char * ucode_vendor_name(const union ucode_vendor_id *vendor)
Get CPU vendor name (for debugging)
uint16_t id
Equivalence ID.
static __always_inline void * umalloc(size_t size)
Allocate external memory.
int32_t version
Microcode version.
#define EIO
Input/output error.
struct image_type ucode_image_type __image_type(PROBE_NORMAL)
Microcode update image type.
#define MSR_UCODE_TRIGGER_AMD
AMD microcode load trigger MSR.
struct ena_llq_option header
Header locations.
unsigned int count
Number of potentially relevant signatures found.
uint32_t signature
Boot processor CPU signature.
uint32_t platform
Platform ID.
#define INTEL_UCODE_LVER
Intel microcode loader version number.
union ucode_vendor_id id
Vendor string.
uint8_t string[12]
Human-readable string.
uint8_t ver_clear
Microcode version requires manual clear.
uint16_t offset
Offset to command line.
void mp_exec_boot(mp_func_t func, void *opaque)
Execute a multiprocessor function on the boot processor.
#define UCODE_WAIT_MS
Time to wait for a microcode update to complete.
static int ucode_status(const struct ucode_update *update, const struct ucode_control *control, const struct ucode_status *status, struct ucode_summary *summary, unsigned int id, int optional)
Check status report.
u8 signature
CPU signature.
int memcmp(const void *first, const void *second, size_t len)
Compare memory regions.
int32_t high
Highest observed microcode version.
#define INTEL_UCODE_DATA_LEN
Intel microcode default data length.
#define UCODE_SIGNATURE_MASK
CPUID signature applicability mask.
#define INTEL_UCODE_ALIGN
Intel microcode file alignment.
Model-specific registers.
uint32_t apic_max
Maximum expected APIC ID.
void * memset(void *dest, int character, size_t len) __nonnull