xref: /illumos-gate/usr/src/uts/intel/sys/ucode.h (revision d32f26ee)
1*d32f26eeSAndy Fiddaman /*
2*d32f26eeSAndy Fiddaman  * CDDL HEADER START
3*d32f26eeSAndy Fiddaman  *
4*d32f26eeSAndy Fiddaman  * The contents of this file are subject to the terms of the
5*d32f26eeSAndy Fiddaman  * Common Development and Distribution License (the "License").
6*d32f26eeSAndy Fiddaman  * You may not use this file except in compliance with the License.
7*d32f26eeSAndy Fiddaman  *
8*d32f26eeSAndy Fiddaman  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9*d32f26eeSAndy Fiddaman  * or http://www.opensolaris.org/os/licensing.
10*d32f26eeSAndy Fiddaman  * See the License for the specific language governing permissions
11*d32f26eeSAndy Fiddaman  * and limitations under the License.
12*d32f26eeSAndy Fiddaman  *
13*d32f26eeSAndy Fiddaman  * When distributing Covered Code, include this CDDL HEADER in each
14*d32f26eeSAndy Fiddaman  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15*d32f26eeSAndy Fiddaman  * If applicable, add the following below this CDDL HEADER, with the
16*d32f26eeSAndy Fiddaman  * fields enclosed by brackets "[]" replaced with your own identifying
17*d32f26eeSAndy Fiddaman  * information: Portions Copyright [yyyy] [name of copyright owner]
18*d32f26eeSAndy Fiddaman  *
19*d32f26eeSAndy Fiddaman  * CDDL HEADER END
20*d32f26eeSAndy Fiddaman  */
21*d32f26eeSAndy Fiddaman /*
22*d32f26eeSAndy Fiddaman  * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
23*d32f26eeSAndy Fiddaman  * Use is subject to license terms.
24*d32f26eeSAndy Fiddaman  *
25*d32f26eeSAndy Fiddaman  * Copyright 2021 OmniOS Community Edition (OmniOSce) Association.
26*d32f26eeSAndy Fiddaman  * Copyright 2022 Joyent, Inc.
27*d32f26eeSAndy Fiddaman  * Copyright 2023 Oxide Computer Company
28*d32f26eeSAndy Fiddaman  */
29*d32f26eeSAndy Fiddaman 
30*d32f26eeSAndy Fiddaman #ifndef	_SYS_UCODE_H
31*d32f26eeSAndy Fiddaman #define	_SYS_UCODE_H
32*d32f26eeSAndy Fiddaman 
33*d32f26eeSAndy Fiddaman #ifdef _KERNEL
34*d32f26eeSAndy Fiddaman #include <sys/cpuvar.h>
35*d32f26eeSAndy Fiddaman #include <sys/linker_set.h>
36*d32f26eeSAndy Fiddaman #endif
37*d32f26eeSAndy Fiddaman #include <sys/stdbool.h>
38*d32f26eeSAndy Fiddaman #include <sys/types.h>
39*d32f26eeSAndy Fiddaman #include <sys/priv.h>
40*d32f26eeSAndy Fiddaman #include <sys/processor.h>
41*d32f26eeSAndy Fiddaman #include <ucode/ucode_errno.h>
42*d32f26eeSAndy Fiddaman 
43*d32f26eeSAndy Fiddaman #ifdef __cplusplus
44*d32f26eeSAndy Fiddaman extern "C" {
45*d32f26eeSAndy Fiddaman #endif
46*d32f26eeSAndy Fiddaman 
47*d32f26eeSAndy Fiddaman /*
48*d32f26eeSAndy Fiddaman  *	/dev/ucode
49*d32f26eeSAndy Fiddaman  */
50*d32f26eeSAndy Fiddaman #define	UCODE_DRIVER_NAME	"ucode"
51*d32f26eeSAndy Fiddaman #define	UCODE_NODE_NAME		"ucode"
52*d32f26eeSAndy Fiddaman #define	UCODE_MINOR		((minor_t)0x3fffful)
53*d32f26eeSAndy Fiddaman 
54*d32f26eeSAndy Fiddaman /*
55*d32f26eeSAndy Fiddaman  * ioctl numbers
56*d32f26eeSAndy Fiddaman  */
57*d32f26eeSAndy Fiddaman #define	UCODE_IOC		(('u'<<24)|('c'<<16)|('o'<<8))
58*d32f26eeSAndy Fiddaman 
59*d32f26eeSAndy Fiddaman #define	UCODE_GET_VERSION	(UCODE_IOC|0)
60*d32f26eeSAndy Fiddaman #define	UCODE_UPDATE		(UCODE_IOC|1)
61*d32f26eeSAndy Fiddaman 
62*d32f26eeSAndy Fiddaman struct ucode_get_rev_struct {
63*d32f26eeSAndy Fiddaman 	uint32_t *ugv_rev;		/* microcode revision array */
64*d32f26eeSAndy Fiddaman 	int ugv_size;			/* size of the array */
65*d32f26eeSAndy Fiddaman 	ucode_errno_t ugv_errno;	/* EUC error code */
66*d32f26eeSAndy Fiddaman };
67*d32f26eeSAndy Fiddaman 
68*d32f26eeSAndy Fiddaman struct ucode_write_struct {
69*d32f26eeSAndy Fiddaman 	uint32_t uw_size;	/* size of the uw_code buffer */
70*d32f26eeSAndy Fiddaman 	uint8_t *uw_ucode;	/* pointer to the undigested microcode */
71*d32f26eeSAndy Fiddaman 	ucode_errno_t uw_errno;	/* EUC error code */
72*d32f26eeSAndy Fiddaman };
73*d32f26eeSAndy Fiddaman 
74*d32f26eeSAndy Fiddaman #if defined(_SYSCALL32_IMPL)
75*d32f26eeSAndy Fiddaman 
76*d32f26eeSAndy Fiddaman #include <sys/types32.h>
77*d32f26eeSAndy Fiddaman 
78*d32f26eeSAndy Fiddaman struct ucode_get_rev_struct32 {
79*d32f26eeSAndy Fiddaman 	caddr32_t ugv_rev;		/* microcode revision array */
80*d32f26eeSAndy Fiddaman 	int ugv_size;			/* size of the array */
81*d32f26eeSAndy Fiddaman 	ucode_errno_t ugv_errno;	/* EUC error code */
82*d32f26eeSAndy Fiddaman };
83*d32f26eeSAndy Fiddaman 
84*d32f26eeSAndy Fiddaman struct ucode_write_struct32 {
85*d32f26eeSAndy Fiddaman 	uint32_t uw_size;	/* size of the uw_code buffer */
86*d32f26eeSAndy Fiddaman 	caddr32_t uw_ucode;	/* pointer to the undigested microcode */
87*d32f26eeSAndy Fiddaman 	ucode_errno_t uw_errno;	/* EUC error code */
88*d32f26eeSAndy Fiddaman };
89*d32f26eeSAndy Fiddaman 
90*d32f26eeSAndy Fiddaman #endif	/* _SYSCALL32_IMPL */
91*d32f26eeSAndy Fiddaman 
92*d32f26eeSAndy Fiddaman #define	UCODE_KB(a)	((a) << 10)	/* KiB */
93*d32f26eeSAndy Fiddaman #define	UCODE_MB(a)	((a) << 20)	/* MiB */
94*d32f26eeSAndy Fiddaman 
95*d32f26eeSAndy Fiddaman /*
96*d32f26eeSAndy Fiddaman  * For a single microcode file, the following minimum and maximum sizes are
97*d32f26eeSAndy Fiddaman  * defined. Such limitations, while somewhat artificial, are not only to
98*d32f26eeSAndy Fiddaman  * provide better sanity checks, but also avoid wasting precious memory at
99*d32f26eeSAndy Fiddaman  * startup time as the microcode buffer for the first processor has to be
100*d32f26eeSAndy Fiddaman  * statically allocated.
101*d32f26eeSAndy Fiddaman  *
102*d32f26eeSAndy Fiddaman  * The last limit is for the concatenation of all the microcode binary files.
103*d32f26eeSAndy Fiddaman  */
104*d32f26eeSAndy Fiddaman #define	UCODE_MIN_SIZE			UCODE_KB(1)
105*d32f26eeSAndy Fiddaman #define	UCODE_MAX_SIZE			UCODE_MB(2)
106*d32f26eeSAndy Fiddaman #define	UCODE_MAX_COMBINED_SIZE		UCODE_MB(16)
107*d32f26eeSAndy Fiddaman 
108*d32f26eeSAndy Fiddaman #ifdef _KERNEL
109*d32f26eeSAndy Fiddaman 
110*d32f26eeSAndy Fiddaman extern ucode_errno_t ucode_get_rev(uint32_t *);
111*d32f26eeSAndy Fiddaman extern ucode_errno_t ucode_validate(uint8_t *, int);
112*d32f26eeSAndy Fiddaman extern ucode_errno_t ucode_update(uint8_t *, int);
113*d32f26eeSAndy Fiddaman 
114*d32f26eeSAndy Fiddaman /*
115*d32f26eeSAndy Fiddaman  * Microcode specific information per core
116*d32f26eeSAndy Fiddaman  */
117*d32f26eeSAndy Fiddaman typedef struct cpu_ucode_info {
118*d32f26eeSAndy Fiddaman 	uint32_t	cui_platid;	/* platform id */
119*d32f26eeSAndy Fiddaman 	uint32_t	cui_rev;	/* microcode revision */
120*d32f26eeSAndy Fiddaman } cpu_ucode_info_t;
121*d32f26eeSAndy Fiddaman 
122*d32f26eeSAndy Fiddaman /*
123*d32f26eeSAndy Fiddaman  * Data structure used for xcall
124*d32f26eeSAndy Fiddaman  */
125*d32f26eeSAndy Fiddaman typedef struct ucode_update {
126*d32f26eeSAndy Fiddaman 	uint32_t		sig;	/* signature */
127*d32f26eeSAndy Fiddaman 	cpu_ucode_info_t	info;	/* ucode info */
128*d32f26eeSAndy Fiddaman 	uint32_t		expected_rev;
129*d32f26eeSAndy Fiddaman 	uint32_t		new_rev;
130*d32f26eeSAndy Fiddaman 	uint8_t			*ucodep; /* pointer to ucode */
131*d32f26eeSAndy Fiddaman 	uint32_t		usize;
132*d32f26eeSAndy Fiddaman } ucode_update_t;
133*d32f26eeSAndy Fiddaman 
134*d32f26eeSAndy Fiddaman /*
135*d32f26eeSAndy Fiddaman  * To register a microcode update method, a ucode_source_t instance should be
136*d32f26eeSAndy Fiddaman  * created and passed to UCODE_SOURCE() to include it in the list of sources
137*d32f26eeSAndy Fiddaman  * that are tried.
138*d32f26eeSAndy Fiddaman  */
139*d32f26eeSAndy Fiddaman typedef struct ucode_source {
140*d32f26eeSAndy Fiddaman 	const char	*us_name;
141*d32f26eeSAndy Fiddaman 	uint32_t	us_write_msr;
142*d32f26eeSAndy Fiddaman 	bool		us_invalidate;
143*d32f26eeSAndy Fiddaman 	bool		(*us_select)(cpu_t *);
144*d32f26eeSAndy Fiddaman 	bool		(*us_capable)(cpu_t *);
145*d32f26eeSAndy Fiddaman 	void		(*us_file_reset)(processorid_t);
146*d32f26eeSAndy Fiddaman 	void		(*us_read_rev)(cpu_ucode_info_t *);
147*d32f26eeSAndy Fiddaman 	uint32_t	(*us_load)(cpu_ucode_info_t *);
148*d32f26eeSAndy Fiddaman 	ucode_errno_t	(*us_validate)(uint8_t *, int);
149*d32f26eeSAndy Fiddaman 	ucode_errno_t	(*us_extract)(ucode_update_t *, uint8_t *, int);
150*d32f26eeSAndy Fiddaman 	ucode_errno_t	(*us_locate)(cpu_t *, cpu_ucode_info_t *);
151*d32f26eeSAndy Fiddaman } ucode_source_t;
152*d32f26eeSAndy Fiddaman #define	UCODE_SOURCE(x) DATA_SET(ucode_source_set, x)
153*d32f26eeSAndy Fiddaman 
154*d32f26eeSAndy Fiddaman #endif /* _KERNEL */
155*d32f26eeSAndy Fiddaman 
156*d32f26eeSAndy Fiddaman #ifdef __cplusplus
157*d32f26eeSAndy Fiddaman }
158*d32f26eeSAndy Fiddaman #endif
159*d32f26eeSAndy Fiddaman 
160*d32f26eeSAndy Fiddaman #endif	/* _SYS_UCODE_H */
161