xref: /illumos-gate/usr/src/uts/intel/io/amdzen/amdzen.h (revision fc910014e8a32a65612105835a10995f2c13d942)
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 2023 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 #include <sys/amdzen/df.h>
26 
27 #include "amdzen_client.h"
28 
29 /*
30  * This header describes properties of the data fabric and our internal state
31  * for the Zen Nexus driver.
32  */
33 
34 #ifdef __cplusplus
35 extern "C" {
36 #endif
37 
38 /*
39  * The data fabric devices are always defined to be on PCI bus zero starting at
40  * device 0x18.
41  */
42 #define	AMDZEN_DF_BUSNO		0x00
43 #define	AMDZEN_DF_FIRST_DEVICE	0x18
44 
45 /*
46  * The maximum amount of Data Fabric node's we can see. In Zen 1 there were up
47  * to four per package.
48  */
49 #define	AMDZEN_MAX_DFS		0x8
50 
51 /*
52  * The maximum number of PCI functions we expect to encounter on the data
53  * fabric.
54  */
55 #define	AMDZEN_MAX_DF_FUNCS	0x8
56 
57 /*
58  * Northbridge registers that are relevant for the nexus, mostly for SMN.
59  */
60 #define	AMDZEN_NB_SMN_ADDR	0x60
61 #define	AMDZEN_NB_SMN_DATA	0x64
62 
63 /*
64  * AMD PCI ID for reference
65  */
66 #define	AMDZEN_PCI_VID_AMD	0x1022
67 
68 /*
69  * Hygon PCI ID for reference
70  */
71 #define	AMDZEN_PCI_VID_HYGON	0x1d94
72 
73 typedef enum {
74 	AMDZEN_STUB_TYPE_DF,
75 	AMDZEN_STUB_TYPE_NB
76 } amdzen_stub_type_t;
77 
78 typedef struct {
79 	list_node_t		azns_link;
80 	dev_info_t		*azns_dip;
81 	uint16_t		azns_vid;
82 	uint16_t		azns_did;
83 	uint16_t		azns_bus;
84 	uint16_t		azns_dev;
85 	uint16_t		azns_func;
86 	ddi_acc_handle_t	azns_cfgspace;
87 } amdzen_stub_t;
88 
89 typedef enum {
90 	AMDZEN_DFE_F_MCA	= 1 << 0,
91 	AMDZEN_DFE_F_ENABLED	= 1 << 1,
92 	AMDZEN_DFE_F_DATA_VALID	= 1 << 2
93 } amdzen_df_ent_flags_t;
94 
95 /*
96  * Data specific to a CCM.
97  */
98 typedef struct {
99 	uint32_t acd_nccds;
100 	uint8_t acd_ccd_en[DF_MAX_CCDS_PER_CCM];
101 	uint32_t acd_ccd_id[DF_MAX_CCDS_PER_CCM];
102 	void *acd_ccd_data[DF_MAX_CCDS_PER_CCM];
103 } amdzen_ccm_data_t;
104 
105 typedef union {
106 	amdzen_ccm_data_t aded_ccm;
107 } amdzen_df_ent_data_t;
108 
109 typedef struct {
110 	uint8_t adfe_drvid;
111 	amdzen_df_ent_flags_t adfe_flags;
112 	df_type_t adfe_type;
113 	uint8_t adfe_subtype;
114 	uint8_t adfe_fabric_id;
115 	uint8_t adfe_inst_id;
116 	uint32_t adfe_info0;
117 	uint32_t adfe_info1;
118 	uint32_t adfe_info2;
119 	uint32_t adfe_info3;
120 	amdzen_df_ent_data_t adfe_data;
121 } amdzen_df_ent_t;
122 
123 typedef enum {
124 	AMDZEN_DF_F_VALID		= 1 << 0,
125 	AMDZEN_DF_F_FOUND_NB		= 1 << 1,
126 } amdzen_df_flags_t;
127 
128 typedef struct {
129 	amdzen_df_flags_t	adf_flags;
130 	uint_t		adf_nb_busno;
131 	amdzen_stub_t	*adf_funcs[AMDZEN_MAX_DF_FUNCS];
132 	amdzen_stub_t	*adf_nb;
133 	uint8_t		adf_major;
134 	uint8_t		adf_minor;
135 	uint_t		adf_nents;
136 	df_rev_t	adf_rev;
137 	amdzen_df_ent_t	*adf_ents;
138 	uint32_t	adf_nodeid;
139 	uint32_t	adf_syscfg;
140 	uint32_t	adf_mask0;
141 	uint32_t	adf_mask1;
142 	uint32_t	adf_mask2;
143 	uint32_t	adf_nccm;
144 	df_fabric_decomp_t	adf_decomp;
145 } amdzen_df_t;
146 
147 typedef enum {
148 	AMDZEN_F_UNSUPPORTED		= 1 << 0,
149 	AMDZEN_F_DEVICE_ERROR		= 1 << 1,
150 	AMDZEN_F_MAP_ERROR		= 1 << 2,
151 	AMDZEN_F_SCAN_DISPATCHED	= 1 << 3,
152 	AMDZEN_F_SCAN_COMPLETE		= 1 << 4,
153 	AMDZEN_F_ATTACH_DISPATCHED	= 1 << 5,
154 	AMDZEN_F_ATTACH_COMPLETE	= 1 << 6,
155 	AMDZEN_F_APIC_DECOMP_VALID	= 1 << 7
156 } amdzen_flags_t;
157 
158 #define	AMDZEN_F_TASKQ_MASK	(AMDZEN_F_SCAN_DISPATCHED | \
159     AMDZEN_F_SCAN_COMPLETE | AMDZEN_F_ATTACH_DISPATCHED | \
160     AMDZEN_F_ATTACH_COMPLETE)
161 
162 /*
163  * These are the set of flags we want to consider when determining whether or
164  * not we're OK for receiving topo ioctls.
165  */
166 #define	AMDZEN_F_IOCTL_MASK	(AMDZEN_F_UNSUPPORTED | \
167     AMDZEN_F_DEVICE_ERROR | AMDZEN_F_MAP_ERROR | AMDZEN_F_ATTACH_COMPLETE)
168 
169 typedef struct amdzen {
170 	kmutex_t	azn_mutex;
171 	kcondvar_t	azn_cv;
172 	amdzen_flags_t	azn_flags;
173 	dev_info_t	*azn_dip;
174 	taskqid_t	azn_taskqid;
175 	uint_t		azn_nscanned;
176 	uint_t		azn_npresent;
177 	list_t		azn_df_stubs;
178 	list_t		azn_nb_stubs;
179 	uint_t		azn_ndfs;
180 	amdzen_df_t	azn_dfs[AMDZEN_MAX_DFS];
181 	uint32_t	azn_ncore_per_ccx;
182 	amdzen_apic_decomp_t azn_apic_decomp;
183 } amdzen_t;
184 
185 typedef enum {
186 	AMDZEN_C_SMNTEMP = 1,
187 	AMDZEN_C_USMN,
188 	AMDZEN_C_ZEN_UDF,
189 	AMDZEN_C_ZEN_UMC
190 } amdzen_child_t;
191 
192 /*
193  * Functions for stubs.
194  */
195 extern int amdzen_attach_stub(dev_info_t *, ddi_attach_cmd_t);
196 extern int amdzen_detach_stub(dev_info_t *, ddi_detach_cmd_t);
197 
198 #ifdef __cplusplus
199 }
200 #endif
201 
202 #endif /* _AMDZEN_H */
203