Mercurial > illumos > git > illumos-gate
comparison usr/src/uts/intel/io/amdzen/amdzen.h @ 20101:1a5588aae48c
13144 refactor amdf17nbdf into a nexus
13145 rewrite amdf17nbdf to use the ksensor framework
13146 Want a driver for AMD SMN user access
Reviewed by: Patrick Mooney <pmooney@pfmooney.com>
Reviewed by: Mike Zeller <mike.zeller@joyent.com>
Reviewed by: Robert French <robert@robertdfrench.me>
Approved by: Richard Lowe <richlowe@richlowe.net>
author | Robert Mustacchi <rm@fingolfin.org> |
---|---|
date | Wed, 08 Apr 2020 21:35:09 -0700 |
parents | |
children | 4bb6be08390f |
comparison
equal
deleted
inserted
replaced
20100:6d24e460e13d | 20101:1a5588aae48c |
---|---|
1 /* | |
2 * This file and its contents are supplied under the terms of the | |
3 * Common Development and Distribution License ("CDDL"), version 1.0. | |
4 * You may only use this file in accordance with the terms of version | |
5 * 1.0 of the CDDL. | |
6 * | |
7 * A full copy of the text of the CDDL should have accompanied this | |
8 * source. A copy of the CDDL is also available via the Internet at | |
9 * http://www.illumos.org/license/CDDL. | |
10 */ | |
11 | |
12 /* | |
13 * Copyright 2020 Oxide Computer Company | |
14 */ | |
15 | |
16 #ifndef _AMDZEN_H | |
17 #define _AMDZEN_H | |
18 | |
19 #include <sys/ddi.h> | |
20 #include <sys/sunddi.h> | |
21 #include <sys/list.h> | |
22 #include <sys/pci.h> | |
23 #include <sys/taskq.h> | |
24 #include <sys/bitmap.h> | |
25 | |
26 /* | |
27 * This header describes properties of the data fabric and our internal state | |
28 * for the Zen Nexus driver. | |
29 */ | |
30 | |
31 #ifdef __cplusplus | |
32 extern "C" { | |
33 #endif | |
34 | |
35 /* | |
36 * The data fabric devices are always defined to be on PCI bus zero starting at | |
37 * device 0x18. | |
38 */ | |
39 #define AMDZEN_DF_BUSNO 0x00 | |
40 #define AMDZEN_DF_FIRST_DEVICE 0x18 | |
41 | |
42 /* | |
43 * The maximum amount of Data Fabric node's we can see. In Zen 1 there were up | |
44 * to four per package. | |
45 */ | |
46 #define AMDZEN_MAX_DFS 0x8 | |
47 | |
48 /* | |
49 * The maximum number of PCI functions we expect to encounter on the data | |
50 * fabric. | |
51 */ | |
52 #define AMDZEN_MAX_DF_FUNCS 0x8 | |
53 | |
54 | |
55 /* | |
56 * Registers in the data fabric space that we care about for the purposes of the | |
57 * nexus driver understanding itself. | |
58 */ | |
59 | |
60 /* | |
61 * This set of registers provides us access to the count of instances in the | |
62 * data fabric and then a number of different pieces of information about them | |
63 * like their type. Note, these registers require indirect access because the | |
64 * information cannot be broadcast. | |
65 */ | |
66 #define AMDZEN_DF_F0_FBICNT 0x40 | |
67 #define AMDZEN_DF_F0_FBICNT_COUNT(x) BITX(x, 7, 0) | |
68 #define AMDZEN_DF_F0_FBIINFO0 0x44 | |
69 #define AMDZEN_DF_F0_FBIINFO0_TYPE(x) BITX(x, 3, 0) | |
70 typedef enum { | |
71 AMDZEN_DF_TYPE_CCM = 0, | |
72 AMDZEN_DF_TYPE_GCM, | |
73 AMDZEN_DF_TYPE_NCM, | |
74 AMDZEN_DF_TYPE_IOMS, | |
75 AMDZEN_DF_TYPE_CS, | |
76 AMDZEN_DF_TYPE_TCDX, | |
77 AMDZEN_DF_TYPE_PIE, | |
78 AMDZEN_DF_TYPE_SPF, | |
79 AMDZEN_DF_TYPE_LLC, | |
80 AMDZEN_DF_TYPE_CAKE | |
81 } amdzen_df_type_t; | |
82 #define AMDZEN_DF_F0_FBIINFO0_SDP_WIDTH(x) BITX(x, 5, 4) | |
83 typedef enum { | |
84 AMDZEN_DF_SDP_W_64 = 0, | |
85 AMDZEN_DF_SDP_W_128, | |
86 AMDZEN_DF_SDP_W_256, | |
87 AMDZEN_DF_SDP_W_512 | |
88 } amdzen_df_sdp_width_t; | |
89 #define AMDZEN_DF_F0_FBIINFO0_ENABLED(x) BITX(x, 6, 6) | |
90 #define AMDZEN_DF_F0_FBIINFO0_FTI_WIDTH(x) BITX(x, 9, 8) | |
91 typedef enum { | |
92 AMDZEN_DF_FTI_W_64 = 0, | |
93 AMDZEN_DF_FTI_W_128, | |
94 AMDZEN_DF_FTI_W_256, | |
95 AMDZEN_DF_FTI_W_512 | |
96 } amdzen_df_fti_width_t; | |
97 #define AMDZEN_DF_F0_FBIINFO0_SDP_PCOUNT(x) BITX(x, 13, 12) | |
98 #define AMDZEN_DF_F0_FBIINFO0_FTI_PCOUNT(x) BITX(x, 18, 16) | |
99 #define AMDZEN_DF_F0_FBIINFO0_HAS_MCA(x) BITX(x, 23, 23) | |
100 #define AMDZEN_DF_F0_FBIINFO0_SUBTYPE(x) BITX(x, 26, 24) | |
101 #define AMDZEN_DF_SUBTYPE_NONE 0 | |
102 typedef enum { | |
103 AMDZEN_DF_CAKE_SUBTYPE_GMI = 1, | |
104 AMDZEN_DF_CAKE_SUBTYPE_xGMI = 2 | |
105 } amdzen_df_cake_subtype_t; | |
106 | |
107 typedef enum { | |
108 AMDZEN_DF_IOM_SUBTYPE_IOHUB = 1, | |
109 } amdzen_df_iom_subtype_t; | |
110 | |
111 typedef enum { | |
112 AMDZEN_DF_CS_SUBTYPE_UMC = 1, | |
113 AMDZEN_DF_CS_SUBTYPE_CCIX = 2 | |
114 } amdzen_df_cs_subtype_t; | |
115 | |
116 #define AMDZEN_DF_F0_FBIINFO1 0x48 | |
117 #define AMDZEN_DF_F0_FBIINFO1_FTI0_NINSTID(x) BITX(x, 7, 0) | |
118 #define AMDZEN_DF_F0_FBIINFO1_FTI1_NINSTID(x) BITX(x, 15, 8) | |
119 #define AMDZEN_DF_F0_FBIINFO1_FTI2_NINSTID(x) BITX(x, 23, 16) | |
120 #define AMDZEN_DF_F0_FBIINFO1_FTI3_NINSTID(x) BITX(x, 31, 24) | |
121 #define AMDZEN_DF_F0_FBIINFO2 0x4c | |
122 #define AMDZEN_DF_F0_FBIINFO2_FTI4_NINSTID(x) BITX(x, 7, 0) | |
123 #define AMDZEN_DF_F0_FBIINFO2_FTI5_NINSTID(x) BITX(x, 15, 8) | |
124 #define AMDZEN_DF_F0_FBIINFO3 0x50 | |
125 #define AMDZEN_DF_F0_FBIINFO3_INSTID(x) BITX(x, 7, 0) | |
126 #define AMDZEN_DF_F0_FBIINFO3_FABID(x) BITX(x, 13, 8) | |
127 | |
128 /* | |
129 * This register contains the information about the configuration of PCIe buses. | |
130 * We care about finding which one has our BUS A, which is required to map it to | |
131 * the northbridge. | |
132 */ | |
133 #define AMDZEN_DF_F0_CFG_ADDR_CTL 0x84 | |
134 #define AMDZEN_DF_F0_CFG_ADDR_CTL_BUS_NUM(x) BITX(x, 7, 0) | |
135 | |
136 /* | |
137 * Registers that describe how the system is actually put together. | |
138 */ | |
139 #define AMDZEN_DF_F1_SYSCFG 0x200 | |
140 #define AMDZEN_DF_F1_SYSCFG_DIE_PRESENT(X) BITX(x, 7, 0) | |
141 #define AMDZEN_DF_F1_SYSCFG_DIE_TYPE(x) BITX(x, 18, 11) | |
142 #define AMDZEN_DF_F1_SYSCFG_MYDIE_TYPE(x) BITX(x, 24, 23) | |
143 typedef enum { | |
144 AMDZEN_DF_DIE_TYPE_CPU = 0, | |
145 AMDZEN_DF_DIE_TYPE_APU, | |
146 AMDZEN_DF_DIE_TYPE_dGPU | |
147 } amdzen_df_die_type_t; | |
148 #define AMDZEN_DF_F1_SYSCFG_OTHERDIE_TYPE(x) BITX(x, 26, 25) | |
149 #define AMDZEN_DF_F1_SYSCFG_OTHERSOCK(x) BITX(x, 27, 27) | |
150 #define AMDZEN_DF_F1_SYSCFG_NODEID(x) BITX(x, 30, 28) | |
151 | |
152 #define AMDZEN_DF_F1_FIDMASK0 0x208 | |
153 #define AMDZEN_DF_F1_FIDMASK0_COMP_MASK(x) BITX(x, 9, 0) | |
154 #define AMDZEN_DF_F1_FIDMASK0_NODE_MASK(x) BITX(x, 25, 16) | |
155 #define AMDZEN_DF_F1_FIDMASK1 0x20C | |
156 #define AMDZEN_DF_F1_FIDMASK1_NODE_SHIFT(x) BITX(x, 3, 0) | |
157 #define AMDZEN_DF_F1_FIDMASK1_SKT_SHIFT(x) BITX(x, 9, 8) | |
158 #define AMDZEN_DF_F1_FIDMASK1_DIE_MASK(x) BITX(x, 18, 16) | |
159 #define AMDZEN_DF_F1_FIDMASK1_SKT_MASK(x) BITX(x, 26, 24) | |
160 | |
161 /* | |
162 * These two registers define information about the PSP and SMU on local and | |
163 * remote dies (from the context of the DF instance). The bits are the same. | |
164 */ | |
165 #define AMDZEN_DF_F1_PSPSMU_LOCAL 0x268 | |
166 #define AMDZEN_DF_F1_PSPSMU_REMOTE 0x268 | |
167 #define AMDZEN_DF_F1_PSPSMU_SMU_VALID(x) BITX(x, 0, 0) | |
168 #define AMDZEN_DF_F1_PSPSMU_SMU_UNITID(x) BITX(x, 6, 1) | |
169 #define AMDZEN_DF_F1_PSPSMU_SMU_COMPID(x) BITX(x, 15, 8) | |
170 #define AMDZEN_DF_F1_PSPSMU_PSP_VALID(x) BITX(x, 16, 16) | |
171 #define AMDZEN_DF_F1_PSPSMU_PSP_UNITID(x) BITX(x, 22, 17) | |
172 #define AMDZEN_DF_F1_PSPSMU_PSP_COMPID(x) BITX(x, 31, 24) | |
173 | |
174 #define AMDZEN_DF_F1_CAKE_ENCR 0x2cc | |
175 | |
176 /* | |
177 * These registers are used to define Indirect Access, commonly known as FICAA | |
178 * and FICAD for the system. While there are multiple copies of the indirect | |
179 * access registers in device 4, we're only allowed access to one set of those | |
180 * (which are the ones present here). Specifically the OS is given access to set | |
181 * 3. | |
182 */ | |
183 #define AMDZEN_DF_F4_FICAA 0x5c | |
184 #define AMDZEN_DF_F4_FICAA_TARG_INST (1 << 0) | |
185 #define AMDZEN_DF_F4_FICAA_SET_REG(x) ((x) & 0x3fc) | |
186 #define AMDZEN_DF_F4_FICAA_SET_FUNC(x) (((x) & 0x7) << 11) | |
187 #define AMDZEN_DF_F4_FICAA_SET_64B (1 << 14) | |
188 #define AMDZEN_DF_F4_FICAA_SET_INST(x) (((x) & 0xff) << 16) | |
189 #define AMDZEN_DF_F4_FICAD_LO 0x98 | |
190 #define AMDZEN_DF_F4_FICAD_HI 0x9c | |
191 | |
192 /* | |
193 * Northbridge registers that are relevant for the nexus, mostly for SMN. | |
194 */ | |
195 #define AMDZEN_NB_SMN_ADDR 0x60 | |
196 #define AMDZEN_NB_SMN_DATA 0x64 | |
197 | |
198 /* | |
199 * AMD PCI ID for reference | |
200 */ | |
201 #define AMDZEN_PCI_VID_AMD 0x1022 | |
202 | |
203 typedef enum { | |
204 AMDZEN_STUB_TYPE_DF, | |
205 AMDZEN_STUB_TYPE_NB | |
206 } amdzen_stub_type_t; | |
207 | |
208 typedef struct { | |
209 list_node_t azns_link; | |
210 dev_info_t *azns_dip; | |
211 uint16_t azns_vid; | |
212 uint16_t azns_did; | |
213 uint16_t azns_bus; | |
214 uint16_t azns_dev; | |
215 uint16_t azns_func; | |
216 ddi_acc_handle_t azns_cfgspace; | |
217 } amdzen_stub_t; | |
218 | |
219 typedef enum { | |
220 AMDZEN_DFE_F_MCA = 1 << 0, | |
221 AMDZEN_DFE_F_ENABLED = 1 << 1 | |
222 } amdzen_df_ent_flags_t; | |
223 | |
224 typedef struct { | |
225 uint8_t adfe_drvid; | |
226 amdzen_df_ent_flags_t adfe_flags; | |
227 amdzen_df_type_t adfe_type; | |
228 uint8_t adfe_subtype; | |
229 uint8_t adfe_fabric_id; | |
230 uint8_t adfe_inst_id; | |
231 amdzen_df_sdp_width_t adfe_sdp_width; | |
232 amdzen_df_fti_width_t adfe_fti_width; | |
233 uint8_t adfe_sdp_count; | |
234 uint8_t adfe_fti_count; | |
235 uint32_t adfe_info0; | |
236 uint32_t adfe_info1; | |
237 uint32_t adfe_info2; | |
238 uint32_t adfe_info3; | |
239 uint32_t adfe_syscfg; | |
240 uint32_t adfe_mask0; | |
241 uint32_t adfe_mask1; | |
242 } amdzen_df_ent_t; | |
243 | |
244 typedef enum { | |
245 AMDZEN_DF_F_VALID = 1 << 0, | |
246 AMDZEN_DF_F_FOUND_NB = 1 << 1 | |
247 } amdzen_df_flags_t; | |
248 | |
249 typedef struct { | |
250 amdzen_df_flags_t adf_flags; | |
251 uint_t adf_nb_busno; | |
252 amdzen_stub_t *adf_funcs[AMDZEN_MAX_DF_FUNCS]; | |
253 amdzen_stub_t *adf_nb; | |
254 uint_t adf_nents; | |
255 amdzen_df_ent_t *adf_ents; | |
256 uint32_t adf_nodeid; | |
257 uint32_t adf_syscfg; | |
258 uint32_t adf_mask0; | |
259 uint32_t adf_mask1; | |
260 } amdzen_df_t; | |
261 | |
262 typedef enum { | |
263 AMDZEN_F_UNSUPPORTED = 1 << 0, | |
264 AMDZEN_F_DEVICE_ERROR = 1 << 1, | |
265 AMDZEN_F_MAP_ERROR = 1 << 2, | |
266 AMDZEN_F_SCAN_DISPATCHED = 1 << 3, | |
267 AMDZEN_F_SCAN_COMPLETE = 1 << 4, | |
268 AMDZEN_F_ATTACH_DISPATCHED = 1 << 5, | |
269 AMDZEN_F_ATTACH_COMPLETE = 1 << 6 | |
270 } amdzen_flags_t; | |
271 | |
272 #define AMDZEN_F_TASKQ_MASK (AMDZEN_F_SCAN_DISPATCHED | \ | |
273 AMDZEN_F_SCAN_COMPLETE | AMDZEN_F_ATTACH_DISPATCHED | \ | |
274 AMDZEN_F_ATTACH_COMPLETE) | |
275 | |
276 typedef struct amdzen { | |
277 kmutex_t azn_mutex; | |
278 kcondvar_t azn_cv; | |
279 amdzen_flags_t azn_flags; | |
280 dev_info_t *azn_dip; | |
281 taskqid_t azn_taskqid; | |
282 uint_t azn_nscanned; | |
283 uint_t azn_npresent; | |
284 list_t azn_df_stubs; | |
285 list_t azn_nb_stubs; | |
286 uint_t azn_ndfs; | |
287 amdzen_df_t azn_dfs[AMDZEN_MAX_DFS]; | |
288 } amdzen_t; | |
289 | |
290 typedef enum { | |
291 AMDZEN_C_SMNTEMP = 1, | |
292 AMDZEN_C_USMN | |
293 } amdzen_child_t; | |
294 | |
295 /* | |
296 * Functions for stubs. | |
297 */ | |
298 extern int amdzen_attach_stub(dev_info_t *, ddi_attach_cmd_t); | |
299 extern int amdzen_detach_stub(dev_info_t *, ddi_detach_cmd_t); | |
300 | |
301 #ifdef __cplusplus | |
302 } | |
303 #endif | |
304 | |
305 #endif /* _AMDZEN_H */ |