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