xref: /onnv-gate/usr/src/uts/common/sys/ucode.h (revision 4581:b6104e41b06c)
1*4581Ssherrym /*
2*4581Ssherrym  * CDDL HEADER START
3*4581Ssherrym  *
4*4581Ssherrym  * The contents of this file are subject to the terms of the
5*4581Ssherrym  * Common Development and Distribution License (the "License").
6*4581Ssherrym  * You may not use this file except in compliance with the License.
7*4581Ssherrym  *
8*4581Ssherrym  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9*4581Ssherrym  * or http://www.opensolaris.org/os/licensing.
10*4581Ssherrym  * See the License for the specific language governing permissions
11*4581Ssherrym  * and limitations under the License.
12*4581Ssherrym  *
13*4581Ssherrym  * When distributing Covered Code, include this CDDL HEADER in each
14*4581Ssherrym  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15*4581Ssherrym  * If applicable, add the following below this CDDL HEADER, with the
16*4581Ssherrym  * fields enclosed by brackets "[]" replaced with your own identifying
17*4581Ssherrym  * information: Portions Copyright [yyyy] [name of copyright owner]
18*4581Ssherrym  *
19*4581Ssherrym  * CDDL HEADER END
20*4581Ssherrym  */
21*4581Ssherrym /*
22*4581Ssherrym  * Copyright 2007 Sun Microsystems, Inc.  All rights reserved.
23*4581Ssherrym  * Use is subject to license terms.
24*4581Ssherrym  */
25*4581Ssherrym 
26*4581Ssherrym #ifndef	_SYS_UCODE_H
27*4581Ssherrym #define	_SYS_UCODE_H
28*4581Ssherrym 
29*4581Ssherrym #pragma ident	"%Z%%M%	%I%	%E% SMI"
30*4581Ssherrym 
31*4581Ssherrym #include <sys/types.h>
32*4581Ssherrym #include <sys/priv.h>
33*4581Ssherrym #include <sys/processor.h>
34*4581Ssherrym #ifndef _KERNEL
35*4581Ssherrym #include <limits.h>
36*4581Ssherrym #endif
37*4581Ssherrym #include <ucode/ucode_errno.h>
38*4581Ssherrym 
39*4581Ssherrym #ifdef __cplusplus
40*4581Ssherrym extern "C" {
41*4581Ssherrym #endif
42*4581Ssherrym 
43*4581Ssherrym /*
44*4581Ssherrym  *	/dev/ucode
45*4581Ssherrym  */
46*4581Ssherrym #define	UCODE_DRIVER_NAME	"ucode"
47*4581Ssherrym #define	UCODE_NODE_NAME		"ucode"
48*4581Ssherrym #define	UCODE_MINOR		((minor_t)0x3fffful)
49*4581Ssherrym 
50*4581Ssherrym /*
51*4581Ssherrym  * Where to install the microcode
52*4581Ssherrym  */
53*4581Ssherrym #define	UCODE_INSTALL_PATH		"platform/i86pc/ucode"
54*4581Ssherrym #define	UCODE_INSTALL_COMMON_PATH	".f"
55*4581Ssherrym 
56*4581Ssherrym /*
57*4581Ssherrym  * ioctl numbers
58*4581Ssherrym  */
59*4581Ssherrym #define	UCODE_IOC		(('u'<<24)|('c'<<16)|('o'<<8))
60*4581Ssherrym 
61*4581Ssherrym #define	UCODE_GET_VERSION	(UCODE_IOC|0)
62*4581Ssherrym #define	UCODE_UPDATE		(UCODE_IOC|1)
63*4581Ssherrym 
64*4581Ssherrym struct ucode_get_rev_struct {
65*4581Ssherrym 	uint32_t *ugv_rev;		/* microcode revision array */
66*4581Ssherrym 	int ugv_size;			/* size of the array */
67*4581Ssherrym 	ucode_errno_t ugv_errno;	/* EUC error code */
68*4581Ssherrym };
69*4581Ssherrym 
70*4581Ssherrym struct ucode_write_struct {
71*4581Ssherrym 	uint32_t uw_size;	/* size of the uw_code buffer */
72*4581Ssherrym 	uint8_t *uw_ucode;	/* pointer to the undigested microcode */
73*4581Ssherrym 	ucode_errno_t uw_errno;	/* EUC error code */
74*4581Ssherrym };
75*4581Ssherrym 
76*4581Ssherrym #if defined(_SYSCALL32_IMPL)
77*4581Ssherrym 
78*4581Ssherrym #include <sys/types32.h>
79*4581Ssherrym 
80*4581Ssherrym struct ucode_get_rev_struct32 {
81*4581Ssherrym 	caddr32_t ugv_rev;		/* microcode revision array */
82*4581Ssherrym 	int ugv_size;			/* size of the array */
83*4581Ssherrym 	ucode_errno_t ugv_errno;	/* EUC error code */
84*4581Ssherrym };
85*4581Ssherrym 
86*4581Ssherrym struct ucode_write_struct32 {
87*4581Ssherrym 	uint32_t uw_size;	/* size of the uw_code buffer */
88*4581Ssherrym 	caddr32_t uw_ucode;	/* pointer to the undigested microcode */
89*4581Ssherrym 	ucode_errno_t uw_errno;	/* EUC error code */
90*4581Ssherrym };
91*4581Ssherrym 
92*4581Ssherrym #endif	/* _SYSCALL32_IMPL */
93*4581Ssherrym 
94*4581Ssherrym /*
95*4581Ssherrym  * Microcode file information
96*4581Ssherrym  */
97*4581Ssherrym typedef struct ucode_header {
98*4581Ssherrym 	uint32_t	uh_header_ver;
99*4581Ssherrym 	uint32_t	uh_rev;
100*4581Ssherrym 	uint32_t	uh_date;
101*4581Ssherrym 	uint32_t	uh_signature;
102*4581Ssherrym 	uint32_t	uh_checksum;
103*4581Ssherrym 	uint32_t	uh_loader_ver;
104*4581Ssherrym 	uint32_t	uh_proc_flags;
105*4581Ssherrym 	uint32_t	uh_body_size;
106*4581Ssherrym 	uint32_t	uh_total_size;
107*4581Ssherrym 	uint32_t	uh_reserved[3];
108*4581Ssherrym } ucode_header_t;
109*4581Ssherrym 
110*4581Ssherrym typedef struct ucode_ext_sig {
111*4581Ssherrym 	uint32_t	ues_signature;
112*4581Ssherrym 	uint32_t	ues_proc_flags;
113*4581Ssherrym 	uint32_t	ues_checksum;
114*4581Ssherrym } ucode_ext_sig_t;
115*4581Ssherrym 
116*4581Ssherrym typedef struct ucode_ext_table {
117*4581Ssherrym 	uint32_t	uet_count;
118*4581Ssherrym 	uint32_t	uet_checksum;
119*4581Ssherrym 	uint32_t	uet_reserved[3];
120*4581Ssherrym 	ucode_ext_sig_t uet_ext_sig[1];
121*4581Ssherrym } ucode_ext_table_t;
122*4581Ssherrym 
123*4581Ssherrym typedef struct ucode_file {
124*4581Ssherrym 	ucode_header_t		uf_header;
125*4581Ssherrym 	uint8_t			*uf_body;
126*4581Ssherrym 	ucode_ext_table_t	*uf_ext_table;
127*4581Ssherrym } ucode_file_t;
128*4581Ssherrym 
129*4581Ssherrym 
130*4581Ssherrym #define	UCODE_SHORT_NAME_LEN	12	/* "32-bit-sig"-"8-bit-platid"\0 */
131*4581Ssherrym /*
132*4581Ssherrym  * Length of UCODE_INSTALL_COMMON_PATH/short-name
133*4581Ssherrym  *	strlen(UCODE_INSTALL_COMMON_PATH) + 1 + UCODE_SHORT_NAME_LEN
134*4581Ssherrym  * Use sizeof which will give us the additional byte for the '/' in between
135*4581Ssherrym  * the common path and the file name.
136*4581Ssherrym  */
137*4581Ssherrym #define	UCODE_COMMON_NAME_LEN	\
138*4581Ssherrym 	(sizeof (UCODE_INSTALL_COMMON_PATH) + (UCODE_SHORT_NAME_LEN))
139*4581Ssherrym #define	UCODE_MAX_PATH_LEN	(PATH_MAX - UCODE_COMMON_NAME_LEN)
140*4581Ssherrym 
141*4581Ssherrym 
142*4581Ssherrym #define	UCODE_HEADER_SIZE	(sizeof (struct ucode_header))
143*4581Ssherrym #define	UCODE_EXT_TABLE_SIZE	(20)	/* 20-bytes */
144*4581Ssherrym #define	UCODE_EXT_SIG_SIZE	(sizeof (struct ucode_ext_sig))
145*4581Ssherrym 
146*4581Ssherrym #define	UCODE_KB(a)	((a) << 10)	/* KB */
147*4581Ssherrym #define	UCODE_MB(a)	((a) << 20)	/* MB */
148*4581Ssherrym #define	UCODE_DEFAULT_TOTAL_SIZE	UCODE_KB(2)
149*4581Ssherrym #define	UCODE_DEFAULT_BODY_SIZE		(UCODE_KB(2) - UCODE_HEADER_SIZE)
150*4581Ssherrym 
151*4581Ssherrym /*
152*4581Ssherrym  * For a single microcode file, the minimum size is 1K, maximum size is 16K.
153*4581Ssherrym  * Such limitations, while somewhat artificial, are not only to provide better
154*4581Ssherrym  * sanity checks, but also avoid wasting precious memory at startup time as the
155*4581Ssherrym  * microcode buffer for the first processor has to be statically allocated.
156*4581Ssherrym  *
157*4581Ssherrym  * For the concatenation of all the microcode binary files, the maximum size
158*4581Ssherrym  * is 16M.
159*4581Ssherrym  */
160*4581Ssherrym #define	UCODE_MIN_SIZE			UCODE_KB(1)
161*4581Ssherrym #define	UCODE_MAX_SIZE			UCODE_KB(16)
162*4581Ssherrym #define	UCODE_MAX_COMBINED_SIZE		UCODE_MB(16)
163*4581Ssherrym 
164*4581Ssherrym #define	UCODE_SIZE_CONVERT(size, default_size) \
165*4581Ssherrym 	((size) == 0 ? (default_size) : (size))
166*4581Ssherrym 
167*4581Ssherrym #define	UCODE_BODY_SIZE(size) \
168*4581Ssherrym 	UCODE_SIZE_CONVERT((size), UCODE_DEFAULT_BODY_SIZE)
169*4581Ssherrym 
170*4581Ssherrym #define	UCODE_TOTAL_SIZE(size) \
171*4581Ssherrym 	UCODE_SIZE_CONVERT((size), UCODE_DEFAULT_TOTAL_SIZE)
172*4581Ssherrym 
173*4581Ssherrym #define	UCODE_MATCH(sig1, sig2, pf1, pf2) \
174*4581Ssherrym 	(((sig1) == (sig2)) && \
175*4581Ssherrym 	(((pf1) & (pf2)) || (((pf1) == 0) && ((pf2) == 0))))
176*4581Ssherrym 
177*4581Ssherrym extern ucode_errno_t ucode_header_validate(ucode_header_t *);
178*4581Ssherrym extern uint32_t ucode_checksum(uint32_t, uint32_t, uint8_t *);
179*4581Ssherrym extern ucode_errno_t ucode_validate(uint8_t *, int);
180*4581Ssherrym extern ucode_errno_t ucode_get_rev(uint32_t *);
181*4581Ssherrym extern ucode_errno_t ucode_update(uint8_t *, int);
182*4581Ssherrym 
183*4581Ssherrym #define	UCODE_MAX_VENDORS_NAME_LEN		20
184*4581Ssherrym 
185*4581Ssherrym #define	UCODE_VENDORS				\
186*4581Ssherrym static struct {					\
187*4581Ssherrym 	char *filestr;				\
188*4581Ssherrym 	char *vendorstr;			\
189*4581Ssherrym 	int  supported;				\
190*4581Ssherrym } ucode_vendors[] = {				\
191*4581Ssherrym 	{ "intel", "GenuineIntel", 1 },		\
192*4581Ssherrym 	{ "amd", "AuthenticAMD", 0 },		\
193*4581Ssherrym 	{ NULL, NULL, 0 }				\
194*4581Ssherrym }
195*4581Ssherrym 
196*4581Ssherrym #ifdef __cplusplus
197*4581Ssherrym }
198*4581Ssherrym #endif
199*4581Ssherrym 
200*4581Ssherrym #endif	/* _SYS_UCODE_H */
201