summaryrefslogtreecommitdiffstats
path: root/src/arch/x86/include/ipxe/ucode.h
blob: 964e8d7b1ac758a459a0ec855c605981ee26ff34 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
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
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
#ifndef _IPXE_UCODE_H
#define _IPXE_UCODE_H

/** @file
 *
 * Microcode updates
 *
 */

FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );

#include <stdint.h>
#include <ipxe/mp.h>

/** Platform ID MSR */
#define MSR_PLATFORM_ID 0x00000017UL

/** Extract platform ID from MSR value */
#define MSR_PLATFORM_ID_VALUE( value ) ( ( (value) >> 50 ) & 0x7 )

/** Intel microcode load trigger MSR */
#define MSR_UCODE_TRIGGER_INTEL 0x00000079UL

/** AMD microcode load trigger MSR */
#define MSR_UCODE_TRIGGER_AMD 0xc0010020UL

/** CPUID signature applicability mask
 *
 * We assume that only steppings may vary between the boot CPU and any
 * application processors.
 */
#define UCODE_SIGNATURE_MASK 0xfffffff0UL

/** Minimum possible microcode version */
#define UCODE_VERSION_MIN -0x80000000L

/** Maximum possible microcode version */
#define UCODE_VERSION_MAX 0x7fffffffL

/** A microcode update control
 *
 * This must match the layout as used by the assembly code in
 * ucode_mp.S.
 */
struct ucode_control {
	/** Microcode descriptor list physical address */
	uint64_t desc;
	/** Microcode status array physical address */
	uint64_t status;
	/** Microcode load trigger MSR */
	uint32_t trigger_msr;
	/** Maximum expected APIC ID */
	uint32_t apic_max;
	/** Unexpected APIC ID
	 *
	 * Any application processor may set this to indicate that its
	 * APIC ID was higher than the maximum expected APIC ID.
	 */
	uint32_t apic_unexpected;
	/** APIC ID eligibility mask bits */
	uint32_t apic_mask;
	/** APIC ID eligibility test bits */
	uint32_t apic_test;
	/** Microcode version requires manual clear */
	uint8_t ver_clear;
	/** Microcode version is reported via high dword */
	uint8_t ver_high;
} __attribute__ (( packed ));

/** A microcode update descriptor
 *
 * This must match the layout as used by the assembly code in
 * ucode_mp.S.
 */
struct ucode_descriptor {
	/** CPUID signature (or 0 to terminate list) */
	uint32_t signature;
	/** Microcode version */
	int32_t version;
	/** Microcode physical address */
	uint64_t address;
} __attribute__ (( packed ));

/** A microcode update status report
 *
 * This must match the layout as used by the assembly code in
 * ucode_mp.S.
 */
struct ucode_status {
	/** CPU signature */
	uint32_t signature;
	/** APIC ID (for sanity checking) */
	uint32_t id;
	/** Initial microcode version */
	int32_t before;
	/** Final microcode version */
	int32_t after;
} __attribute__ (( packed ));

/** A microcode date */
struct ucode_date {
	/** Year (BCD) */
	uint8_t year;
	/** Century (BCD) */
	uint8_t century;
	/** Day (BCD) */
	uint8_t day;
	/** Month (BCD) */
	uint8_t month;
} __attribute__ (( packed ));

/** An Intel microcode update file header */
struct intel_ucode_header {
	/** Header version number */
	uint32_t hver;
	/** Microcode version */
	int32_t version;
	/** Date */
	struct ucode_date date;
	/** CPUID signature */
	uint32_t signature;
	/** Checksum */
	uint32_t checksum;
	/** Loader version */
	uint32_t lver;
	/** Supported platforms */
	uint32_t platforms;
	/** Microcode data size (or 0 to indicate 2000 bytes) */
	uint32_t data_len;
	/** Total size (or 0 to indicate 2048 bytes) */
	uint32_t len;
	/** Reserved */
	uint8_t reserved[12];
} __attribute__ (( packed ));

/** Intel microcode header version number */
#define INTEL_UCODE_HVER 0x00000001UL

/** Intel microcode loader version number */
#define INTEL_UCODE_LVER 0x00000001UL

/** Intel microcode default data length */
#define INTEL_UCODE_DATA_LEN 2000

/** Intel microcode file alignment */
#define INTEL_UCODE_ALIGN 1024

/** An Intel microcode update file extended header */
struct intel_ucode_ext_header {
	/** Extended signature count */
	uint32_t count;
	/** Extended checksum */
	uint32_t checksum;
	/** Reserved */
	uint8_t reserved[12];
} __attribute__ (( packed ));

/** An Intel microcode extended signature */
struct intel_ucode_ext {
	/** CPUID signature */
	uint32_t signature;
	/** Supported platforms */
	uint32_t platforms;
	/** Checksum */
	uint32_t checksum;
} __attribute__ (( packed ));

/** An AMD microcode update file header */
struct amd_ucode_header {
	/** Magic signature */
	uint32_t magic;
	/** Equivalence table type */
	uint32_t type;
	/** Equivalence table length */
	uint32_t len;
} __attribute__ (( packed ));

/** AMD microcode magic signature */
#define AMD_UCODE_MAGIC ( ( 'A' << 16 ) | ( 'M' << 8 ) | ( 'D' << 0 ) )

/** AMD microcode equivalence table type */
#define AMD_UCODE_EQUIV_TYPE 0x00000000UL

/** An AMD microcode equivalence table entry */
struct amd_ucode_equivalence {
	/** CPU signature */
	uint32_t signature;
	/** Reserved */
	uint8_t reserved_a[8];
	/** Equivalence ID */
	uint16_t id;
	/** Reserved */
	uint8_t reserved_b[2];
} __attribute__ (( packed ));

/** An AMD microcode patch header */
struct amd_ucode_patch_header {
	/** Patch type */
	uint32_t type;
	/** Patch length */
	uint32_t len;
} __attribute__ (( packed ));

/** An AMD microcode patch */
struct amd_ucode_patch {
	/** Date */
	struct ucode_date date;
	/** Microcode version */
	int32_t version;
	/** Reserved */
	uint8_t reserved_a[16];
	/** Equivalence ID */
	uint16_t id;
	/** Reserved */
	uint8_t reserved_b[14];
} __attribute__ (( packed ));

/** AMD patch type */
#define AMD_UCODE_PATCH_TYPE 0x00000001UL

extern mp_func_t ucode_update;

#endif /* _IPXE_UCODE_H */