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