intel_microcode.h 5.44 KB
Newer Older
1 2 3 4 5
/*
 *  Intel CPU Microcode data manipulation
 *
 *  Copyright (c) 2000-2006 Tigran Aivazian <[email protected]>
 *                2006      Shaohua Li <[email protected]>
6
 *                2010-2017 Henrique de Moraes Holschuh <[email protected]>
7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24
 *
 *  Based on Linux kernel Intel Microcode driver v2.6.36-rc3 (1.14)
 *  Based on Linux microcode.ctl version 1.17
 *
 *  Reference: Section 9.11 of Volume 3a, IA-32 Intel Architecture
 *  Software Developer's Manual
 *  Order Number 253668 or free download from:
 *  http://developer.intel.com/design/pentium4/manuals/253668.htm
 *
 *  This program is free software; you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation; either version 2 of the License, or
 *  (at your option) any later version.
 */

#ifndef INTEL_MICROCODE_H
#define INTEL_MICROCODE_H

25 26
#include "iucode_tool_config.h"

27 28 29
#include <stdint.h>
#include <sys/types.h>

30 31 32
/* Minimum object size that could have a valid production microcode */
#define INTEL_UC_MINSIZE 1024

33 34 35 36 37
typedef enum { /* status result codes */
	INTEL_UCODE_NOERROR = 0,
	INTEL_UCODE_BAD_PARAMETERS,
	INTEL_UCODE_INVALID_DATA,
	INTEL_UCODE_UNKNOWN_FORMAT,
38
	/* only returned by intel_ucode_check_microcode() */
39 40 41 42
	INTEL_UCODE_BAD_EXTENDED_TABLE,
	INTEL_UCODE_BAD_EXTENDED_TABLE_CHECKSUM,
	INTEL_UCODE_BAD_EXTENDED_SIG_CHECKSUM,
	INTEL_UCODE_BAD_CHECKSUM,
43
	/* only returned by the foreach functions */
44
	INTEL_UCODE_CALLBACK_ERROR,
45
	INTEL_UCODE_COUNTEROVERFLOW,
46 47 48
} intel_ucode_status_t;

struct intel_ucode_metadata {
49 50 51
	uint16_t	date_year;	/* 4-bit packed BCD format */
	uint8_t		date_day;	/* 4-bit packed BCD format */
	uint8_t		date_month;	/* 4-bit packed BCD format */
52 53
	int32_t		revision;
	uint32_t	size;
54
	uint32_t	extsig_count;
55 56 57
};

intel_ucode_status_t intel_ucode_getmetadata(const void * const uc,
58
				struct intel_ucode_metadata * const metadata);
59

60 61
uint32_t intel_ucode_getdate_bcd(const void * const uc);

62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77
/**
 * intel_ucode_sigmatch() - match signature against processor signature
 *
 * @s1:    CPUID 0x01, EAX
 * @s2:    microcode signature/extended signature "sig" field
 * @p1:    1 << (MSR IA32_PLATFORM_ID[52:50])
 * @p2:    microcode signature/extended signature "pf" mask
 *
 * Returns true if the microcode can be used in a given processor.
 *
 * The kernel driver exports through sysfs the processor flags already
 * in the format expected by this macro.
 */
#define intel_ucode_sigmatch(s1, s2, p1, p2) \
	(((s1) == (s2)) && (((p1) & (p2)) || (((p1) == 0) && ((p2) == 0))))

78
const char * intel_ucode_errstr(const intel_ucode_status_t status) __attribute__((const));
79 80

intel_ucode_status_t intel_ucode_check_microcode(const void * const uc,
81 82
						 const size_t maxlen,
						 const int strict);
83

84 85
int intel_ucode_compare(const void * const uc1, const void * const uc2);

86 87 88 89
int intel_ucode_scan_for_microcode(const void ** const bs,
				   const void ** const be,
				   size_t * const blen,
				   size_t * const alen);
90

91 92 93 94 95 96
/* Iterators */

/**
 * intel_ucode_sig_callback() - callback function for the
 *                             intel_ucode_foreach_microcode() function
 *
97 98 99 100
 * @userdata:    pointer as passed to intel_ucode_foreach_microcode()
 * @uc_count:    one-based counter of microcode entries
 * @uc:          pointer to start of microcode entry
 * @uc_max_size: maximum bound for microcode entry size
101 102 103 104 105 106 107 108 109 110 111 112 113
 *
 * @uc is a pointer to somewhere inside the original bundle passed to
 * intel_ucode_foreach_microcode(), where a microcode entry starts.
 * DO NOT MODIFY the memory area pointed by @uc.
 *
 * Note that it is very likely that the callback will HAVE to call
 * intel_ucode_check_microcode(uc) to check the microcode entry, and
 * return non-zero should it is faulty, otherwise nasty things can
 * happen.
 *
 * If the callback returns a non-zero value, the foreach operation
 * is aborted with a INTEL_UCODE_CALLBACK_ERROR error.
 */
114 115
typedef int (intel_ucode_uc_callback)(void * const userdata,
					const unsigned int uc_count,
116 117
					const void * const uc,
					const size_t uc_max_size);
118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145

intel_ucode_status_t intel_ucode_foreach_microcode(
			const void * const uc_bundle,
			const size_t uc_bundle_size,
			intel_ucode_uc_callback * const action,
			void * const userdata);

/**
 * intel_ucode_sig_callback() - callback function for the
 *                             intel_ucode_foreach_signature() function
 *
 * @userdata:		pointer as passed to intel_ucode_foreach_signature()
 * @sig_count:		zero-based counter of signatures on this microcode
 * @cpuid:		cpuid this microcode applies to
 * @pf_mask:		processor flags mask this microcode applies to
 * @uc_data:		microcode data
 * @uc_data_size:	microcode data size
 * @uc:			microcode entry (headers and data)
 * @uc_size:		microcode entry size
 *
 * DO NOT MODIFY THE MEMORY AREAS REFERENCED BY @uc_data and @uc.
 *
 * The callback can obtain data about the microcode through
 * a call to intel_ucode_getmetadata(uc, metadata).
 *
 * If the callback returns a non-zero value, the foreach operation
 * is aborted with a INTEL_UCODE_CALLBACK_ERROR error.
 */
146 147 148 149
typedef int (intel_ucode_sig_callback)(void * const userdata,
				const unsigned int sig_count,
				const uint32_t cpuid,
				const uint32_t pf_mask,
150
				const void * const uc_data,
151
				const unsigned int uc_data_size,
152
				const void * const uc,
153
				const unsigned int uc_size);
154 155 156 157 158 159

intel_ucode_status_t intel_ucode_foreach_signature(const void * const uc,
				intel_ucode_sig_callback * const action,
				void * const userdata);

#endif /* INTEL_MICROCODE_H */