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 2026 Oxide Computer Company 14 */ 15 16 #ifndef _TOPO_PCIE_IMPL_H 17 #define _TOPO_PCIE_IMPL_H 18 19 #include <libdevinfo.h> 20 #include <libnvpair.h> 21 #include <stdbool.h> 22 #include <fm/topo_mod.h> 23 #include <sys/bitext.h> 24 #include <sys/pci.h> 25 #include "topo_pcie.h" 26 27 /* 28 * Implementation-specific PCIe module header file. 29 */ 30 31 #ifdef __cplusplus 32 extern "C" { 33 #endif 34 35 #define PCI_MAX_BUS 0xff 36 #define PCI_MAX_DEV 0x1f 37 #define PCI_MAX_FUNC 0x7 38 39 typedef enum { 40 PCIE_NODE_ROOTNEXUS, 41 PCIE_NODE_ROOTPORT, 42 PCIE_NODE_PCI_DEV, 43 PCIE_NODE_PCIE_DEV, 44 PCIE_NODE_SWITCH_UP, 45 PCIE_NODE_SWITCH_DOWN, 46 PCIE_NODE_PCIE_PCI, 47 PCIE_NODE_PCI_PCIE, 48 } pcie_node_type_t; 49 50 typedef enum { 51 TOPO_PORT_DOWNSTREAM, 52 TOPO_PORT_UPSTREAM, 53 } topo_port_type_t; 54 55 typedef struct pcie { 56 di_node_t tp_devinfo; 57 pcidb_hdl_t *tp_pcidb_hdl; 58 topo_list_t tp_rootnexus; 59 bool tp_enumdone; 60 uint8_t tp_nchip; 61 nvlist_t *tp_cpupcidata; 62 void *tp_privdata; 63 } pcie_t; 64 65 typedef struct pcie_node { 66 topo_list_t pn_link; 67 68 pcie_t *pn_pcie; 69 di_node_t pn_did; 70 pcie_node_type_t pn_type; 71 topo_instance_t pn_inst; 72 topo_instance_t pn_cpu; 73 int pn_class; 74 int pn_subclass; 75 int pn_intf; 76 int pn_bus; 77 int pn_dev; 78 int pn_func; 79 bool pn_is_pcie; 80 const char *pn_path; 81 char *pn_drvname; 82 int pn_drvinst; 83 84 /* 85 * These two keep track of devices that have already been seen 86 * underneath this node, and the topology function number that was last 87 * allocated. They are both indexed by the PCI device ID of the child. 88 */ 89 tnode_t *pn_devices[PCI_MAX_DEV + 1]; 90 topo_instance_t pn_devfunc[PCI_MAX_DEV + 1]; 91 92 topo_list_t pn_children; 93 struct pcie_node *pn_parent; 94 } pcie_node_t; 95 96 typedef enum { 97 PCI_LINK_UNKNOWN, 98 PCI_LINK_UP, 99 PCI_LINK_DOWN, 100 } topo_pcie_link_status_t; 101 102 #define TOPO_PCIE_LINK_UP_STR "up" 103 #define TOPO_PCIE_LINK_DOWN_STR "down" 104 105 extern bool pcie_set_platdata(pcie_t *, void *); 106 extern void *pcie_get_platdata(const pcie_t *); 107 108 /* 109 * Each architecture must provide implementations of the following 110 * mod_pcie_*() functions that can be used to decorate or extend topology nodes 111 * based on system-specific knowledge. 112 */ 113 114 extern bool mod_pcie_platform_init(topo_mod_t *, pcie_t *); 115 extern void mod_pcie_platform_fini(topo_mod_t *, pcie_t *); 116 117 /* 118 * This hook is called to create the authority information for the node. 119 */ 120 extern nvlist_t *mod_pcie_platform_auth(topo_mod_t *, const pcie_t *, 121 tnode_t *); 122 123 /* 124 * This hook is called for every newly created topology node, after the core 125 * module has populated common properties. The return value is the topology 126 * node from which to continue, allowing additional nodes to be inserted 127 * into the hierarchy by the module if required. 128 */ 129 extern tnode_t *mod_pcie_platform_topo_node_decorate(topo_mod_t *, 130 const pcie_t *, const pcie_node_t *, tnode_t *); 131 132 /* topo_pcie_util.c */ 133 134 extern bool topo_pcie_set_io_props(topo_mod_t *, pcie_t *, pcie_node_t *, 135 tnode_t *); 136 extern bool topo_pcie_set_pci_props(topo_mod_t *, pcie_t *, pcie_node_t *, 137 tnode_t *); 138 extern bool topo_pcie_set_port_props(topo_mod_t *, pcie_t *, pcie_node_t *, 139 tnode_t *, topo_port_type_t); 140 extern bool topo_pcie_set_link_props(topo_mod_t *, pcie_t *, pcie_node_t *, 141 tnode_t *); 142 143 extern const char *pcie_type_name(pcie_node_type_t); 144 extern uint_t pcie_speed2gen(int64_t); 145 extern const char *pcie_speed2str(int64_t); 146 147 /* topo_pcie_prop.c */ 148 149 extern bool pcie_topo_pgroup_create(topo_mod_t *, tnode_t *, 150 const topo_pgroup_info_t *); 151 extern bool pcie_topo_range_create(topo_mod_t *, tnode_t *, const char *, 152 topo_instance_t, topo_instance_t); 153 154 extern int32_t pcie_devinfo_get32(topo_mod_t *, di_node_t, const char *); 155 extern int64_t pcie_devinfo_get64(topo_mod_t *, di_node_t, const char *); 156 extern bool pcie_devinfo_getbool(topo_mod_t *, di_node_t, const char *); 157 158 extern bool pcie_topo_prop_set32(topo_mod_t *, tnode_t *, 159 const topo_pgroup_info_t *, const char *, uint32_t); 160 extern bool pcie_topo_prop_set64(topo_mod_t *, tnode_t *, 161 const topo_pgroup_info_t *, const char *, uint64_t); 162 extern bool pcie_topo_prop_set32_array(topo_mod_t *, tnode_t *, 163 const topo_pgroup_info_t *, const char *, uint32_t *, int); 164 extern bool pcie_topo_prop_set64_array(topo_mod_t *, tnode_t *, 165 const topo_pgroup_info_t *, const char *, uint64_t *, int); 166 extern bool pcie_topo_prop_setstr(topo_mod_t *, tnode_t *, 167 const topo_pgroup_info_t *, const char *, const char *); 168 169 extern bool pcie_topo_prop_copy(topo_mod_t *, di_node_t, tnode_t *, 170 const topo_pgroup_info_t *, topo_type_t, const char *, const char *); 171 172 /* topo_pcie_cfgspace.c */ 173 174 extern topo_pcie_link_status_t topo_pcie_link_status(topo_mod_t *, 175 pcie_node_t *); 176 177 #define GETCLASS(x) bitx32((x), 23, 16); 178 #define GETSUBCLASS(x) bitx32((x), 15, 8); 179 #define GETINTF(x) bitx32((x), 7, 0); 180 181 #define PCIE "pcie" 182 #define PCIE_VERSION 1 183 184 #define PCIE_ROOT_NEXUS "pciex_root_complex" 185 186 /* 187 * Devinfo properties 188 */ 189 190 #define DI_COMPATPROP "compatible" 191 #define DI_DEVTYPPROP "device_type" 192 #define DI_PCIETYPPROP "pcie-type" 193 #define DI_VENDIDPROP "vendor-id" 194 #define DI_SUBVENDIDPROP "subsystem-vendor-id" 195 #define DI_SUBSYSTEMID "subsystem-id" 196 #define DI_REVIDPROP "revision-id" 197 #define DI_DEVIDPROP "device-id" 198 #define DI_CLASSPROP "class-code" 199 #define DI_REGPROP "reg" 200 #define DI_PHYSPROP "physical-slot#" 201 #define DI_AADDRPROP "assigned-addresses" 202 #define DI_MODELNAME "model" 203 #define DI_VENDORNAME "vendor-name" 204 #define DI_DEVICENAME "device-name" 205 #define DI_SUBSYSNAME "subsystem-name" 206 #define DI_BUSRANGE "bus-range" 207 208 #define DI_PCIE_MAX_WIDTH "pcie-link-maximum-width" 209 #define DI_PCIE_CUR_WIDTH "pcie-link-current-width" 210 #define DI_PCIE_MAX_SPEED "pcie-link-maximum-speed" 211 #define DI_PCIE_CUR_SPEED "pcie-link-current-speed" 212 #define DI_PCIE_SUP_SPEEDS "pcie-link-supported-speeds" 213 #define DI_PCIE_TARG_SPEED "pcie-link-target-speed" 214 #define DI_PCIE_ADMIN_TAG "pcie-link-admin-target-speed" 215 216 #define DI_PCI_66MHZ_CAPABLE "66mhz-capable" 217 218 #ifdef __cplusplus 219 } 220 #endif 221 222 #endif /* _TOPO_PCIE_IMPL_H */ 223