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