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 */