9815 Want basic AHCI enclosure services
[unleashed.git] / usr / src / uts / common / sys / ucode.h
blob8bbace2b997b30d7a35c318c5e48a7fd90717b9a
1 /*
2 * CDDL HEADER START
4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License (the "License").
6 * You may not use this file except in compliance with the License.
8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 * or http://www.opensolaris.org/os/licensing.
10 * See the License for the specific language governing permissions
11 * and limitations under the License.
13 * When distributing Covered Code, include this CDDL HEADER in each
14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 * If applicable, add the following below this CDDL HEADER, with the
16 * fields enclosed by brackets "[]" replaced with your own identifying
17 * information: Portions Copyright [yyyy] [name of copyright owner]
19 * CDDL HEADER END
22 * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
23 * Use is subject to license terms.
26 #ifndef _SYS_UCODE_H
27 #define _SYS_UCODE_H
29 #ifdef _KERNEL
30 #include <sys/cpuvar.h>
31 #endif
32 #include <sys/types.h>
33 #include <sys/priv.h>
34 #include <sys/processor.h>
35 #ifndef _KERNEL
36 #include <limits.h>
37 #endif
38 #include <ucode/ucode_errno.h>
40 #ifdef __cplusplus
41 extern "C" {
42 #endif
45 * /dev/ucode
47 #define UCODE_DRIVER_NAME "ucode"
48 #define UCODE_NODE_NAME "ucode"
49 #define UCODE_MINOR ((minor_t)0x3fffful)
52 * Where to install the microcode
54 #define UCODE_INSTALL_PATH "platform/i86pc/ucode"
55 #define UCODE_INSTALL_COMMON_PATH ".f"
58 * ioctl numbers
60 #define UCODE_IOC (('u'<<24)|('c'<<16)|('o'<<8))
62 #define UCODE_GET_VERSION (UCODE_IOC|0)
63 #define UCODE_UPDATE (UCODE_IOC|1)
65 struct ucode_get_rev_struct {
66 uint32_t *ugv_rev; /* microcode revision array */
67 int ugv_size; /* size of the array */
68 ucode_errno_t ugv_errno; /* EUC error code */
71 struct ucode_write_struct {
72 uint32_t uw_size; /* size of the uw_code buffer */
73 uint8_t *uw_ucode; /* pointer to the undigested microcode */
74 ucode_errno_t uw_errno; /* EUC error code */
77 #if defined(_SYSCALL32_IMPL)
79 #include <sys/types32.h>
81 struct ucode_get_rev_struct32 {
82 caddr32_t ugv_rev; /* microcode revision array */
83 int ugv_size; /* size of the array */
84 ucode_errno_t ugv_errno; /* EUC error code */
87 struct ucode_write_struct32 {
88 uint32_t uw_size; /* size of the uw_code buffer */
89 caddr32_t uw_ucode; /* pointer to the undigested microcode */
90 ucode_errno_t uw_errno; /* EUC error code */
93 #endif /* _SYSCALL32_IMPL */
96 * AMD Microcode file information
98 typedef struct ucode_header_amd {
99 uint32_t uh_date;
100 uint32_t uh_patch_id;
101 uint32_t uh_internal; /* patch data id & length, init flag */
102 uint32_t uh_cksum;
103 uint32_t uh_nb_id;
104 uint32_t uh_sb_id;
105 uint16_t uh_cpu_rev;
106 uint8_t uh_nb_rev;
107 uint8_t uh_sb_rev;
108 uint32_t uh_bios_rev;
109 uint32_t uh_match[8];
110 } ucode_header_amd_t;
112 typedef struct ucode_file_amd {
113 #ifndef __xpv
114 ucode_header_amd_t uf_header;
115 uint8_t uf_data[896];
116 uint8_t uf_resv[896];
117 uint8_t uf_code_present;
118 uint8_t uf_code[191];
119 uint8_t uf_encr[2048];
120 #else
121 uint8_t *ucodep;
122 uint32_t usize;
123 #endif
124 } ucode_file_amd_t;
126 typedef struct ucode_eqtbl_amd {
127 uint32_t ue_inst_cpu;
128 uint32_t ue_fixed_mask;
129 uint32_t ue_fixed_comp;
130 uint16_t ue_equiv_cpu;
131 uint16_t ue_reserved;
132 } ucode_eqtbl_amd_t;
135 * Intel Microcode file information
137 typedef struct ucode_header_intel {
138 uint32_t uh_header_ver;
139 uint32_t uh_rev;
140 uint32_t uh_date;
141 uint32_t uh_signature;
142 uint32_t uh_checksum;
143 uint32_t uh_loader_ver;
144 uint32_t uh_proc_flags;
145 uint32_t uh_body_size;
146 uint32_t uh_total_size;
147 uint32_t uh_reserved[3];
148 } ucode_header_intel_t;
150 typedef struct ucode_ext_sig_intel {
151 uint32_t ues_signature;
152 uint32_t ues_proc_flags;
153 uint32_t ues_checksum;
154 } ucode_ext_sig_intel_t;
156 typedef struct ucode_ext_table_intel {
157 uint32_t uet_count;
158 uint32_t uet_checksum;
159 uint32_t uet_reserved[3];
160 ucode_ext_sig_intel_t uet_ext_sig[1];
161 } ucode_ext_table_intel_t;
163 typedef struct ucode_file_intel {
164 ucode_header_intel_t *uf_header;
165 uint8_t *uf_body;
166 ucode_ext_table_intel_t *uf_ext_table;
167 } ucode_file_intel_t;
170 * common container
172 typedef union ucode_file {
173 ucode_file_amd_t *amd;
174 ucode_file_intel_t intel;
175 } ucode_file_t;
178 #define UCODE_SHORT_NAME_LEN 12 /* "32-bit-sig"-"8-bit-platid"\0 */
180 * Length of UCODE_INSTALL_COMMON_PATH/short-name
181 * strlen(UCODE_INSTALL_COMMON_PATH) + 1 + UCODE_SHORT_NAME_LEN
182 * Use sizeof which will give us the additional byte for the '/' in between
183 * the common path and the file name.
185 #define UCODE_COMMON_NAME_LEN \
186 (sizeof (UCODE_INSTALL_COMMON_PATH) + (UCODE_SHORT_NAME_LEN))
187 #define UCODE_MAX_PATH_LEN (PATH_MAX - UCODE_COMMON_NAME_LEN)
190 #define UCODE_HEADER_SIZE_INTEL (sizeof (struct ucode_header_intel))
191 #define UCODE_EXT_TABLE_SIZE_INTEL (20) /* 20-bytes */
192 #define UCODE_EXT_SIG_SIZE_INTEL (sizeof (struct ucode_ext_sig_intel))
194 #define UCODE_KB(a) ((a) << 10) /* KB */
195 #define UCODE_MB(a) ((a) << 20) /* MB */
196 #define UCODE_DEFAULT_TOTAL_SIZE UCODE_KB(2)
197 #define UCODE_DEFAULT_BODY_SIZE (UCODE_KB(2) - UCODE_HEADER_SIZE_INTEL)
200 * For a single microcode file, the minimum size is 1K, maximum size is 128K.
201 * Such limitations, while somewhat artificial, are not only to provide better
202 * sanity checks, but also avoid wasting precious memory at startup time as the
203 * microcode buffer for the first processor has to be statically allocated.
205 * For the concatenation of all the microcode binary files, the maximum size
206 * is 16M.
208 #define UCODE_MIN_SIZE UCODE_KB(1)
209 #define UCODE_MAX_SIZE UCODE_KB(128)
210 #define UCODE_MAX_COMBINED_SIZE UCODE_MB(16)
212 #define UCODE_SIZE_CONVERT(size, default_size) \
213 ((size) == 0 ? (default_size) : (size))
215 #define UCODE_BODY_SIZE_INTEL(size) \
216 UCODE_SIZE_CONVERT((size), UCODE_DEFAULT_BODY_SIZE)
218 #define UCODE_TOTAL_SIZE_INTEL(size) \
219 UCODE_SIZE_CONVERT((size), UCODE_DEFAULT_TOTAL_SIZE)
221 #define UCODE_MATCH_INTEL(sig1, sig2, pf1, pf2) \
222 (((sig1) == (sig2)) && \
223 (((pf1) & (pf2)) || (((pf1) == 0) && ((pf2) == 0))))
225 extern ucode_errno_t ucode_header_validate_intel(ucode_header_intel_t *);
226 extern uint32_t ucode_checksum_intel(uint32_t, uint32_t, uint8_t *);
228 extern ucode_errno_t ucode_validate_amd(uint8_t *, int);
229 extern ucode_errno_t ucode_validate_intel(uint8_t *, int);
231 #ifdef _KERNEL
232 extern ucode_errno_t ucode_get_rev(uint32_t *);
233 extern ucode_errno_t ucode_update(uint8_t *, int);
236 * Microcode specific information per core
238 typedef struct cpu_ucode_info {
239 uint32_t cui_platid; /* platform id */
240 uint32_t cui_rev; /* microcode revision */
241 } cpu_ucode_info_t;
244 * Data structure used for xcall
246 typedef struct ucode_update {
247 uint32_t sig; /* signature */
248 cpu_ucode_info_t info; /* ucode info */
249 uint32_t expected_rev;
250 uint32_t new_rev;
251 uint8_t *ucodep; /* pointer to ucode */
252 uint32_t usize;
253 } ucode_update_t;
256 * Microcode kernel operations
258 struct ucode_ops {
259 uint32_t write_msr;
260 int (*capable)(cpu_t *);
261 void (*file_reset)(ucode_file_t *, processorid_t);
262 void (*read_rev)(cpu_ucode_info_t *);
263 uint32_t (*load)(ucode_file_t *, cpu_ucode_info_t *, cpu_t *);
264 ucode_errno_t (*validate)(uint8_t *, int);
265 ucode_errno_t (*extract)(ucode_update_t *, uint8_t *, int);
266 ucode_errno_t (*locate)(cpu_t *, cpu_ucode_info_t *, ucode_file_t *);
268 #else
270 #define UCODE_MAX_VENDORS_NAME_LEN 20
272 #define UCODE_VENDORS \
273 static struct { \
274 char *filestr; \
275 char *extstr; \
276 char *vendorstr; \
277 int supported; \
278 } ucode_vendors[] = { \
279 { "intel", "txt", "GenuineIntel", 1 }, \
280 { "amd", "bin", "AuthenticAMD", 1 }, \
281 { NULL, NULL, NULL, 0 } \
285 * Microcode user operations
287 struct ucode_ops {
288 int (*convert)(const char *, uint8_t *, size_t);
289 ucode_errno_t (*gen_files)(uint8_t *, int, char *);
290 ucode_errno_t (*validate)(uint8_t *, int);
292 #endif
294 extern const struct ucode_ops *ucode;
296 #ifdef __cplusplus
298 #endif
300 #endif /* _SYS_UCODE_H */