/** * DOC: cxl objects * * The CXL core objects like ports, decoders, and regions are shared * between the subsystem drivers cxl_acpi, cxl_pci, and core drivers * (port-driver, region-driver, nvdimm object-drivers... etc).
*/
/* * cxl_decoder flags that define the type of memory / devices this * decoder supports as well as configuration lock status See "CXL 2.0 * 8.2.5.12.7 CXL HDM Decoder 0 Control Register" for details. * Additionally indicate whether decoder settings were autodetected, * user customized.
*/ #define CXL_DECODER_F_RAM BIT(0) #define CXL_DECODER_F_PMEM BIT(1) #define CXL_DECODER_F_TYPE2 BIT(2) #define CXL_DECODER_F_TYPE3 BIT(3) #define CXL_DECODER_F_LOCK BIT(4) #define CXL_DECODER_F_ENABLE BIT(5) #define CXL_DECODER_F_MASK GENMASK(5, 0)
/* * Current specification goes up to 8, double that seems a reasonable * software max for the foreseeable future
*/ #define CXL_DECODER_MAX_INTERLEAVE 16
#define CXL_QOS_CLASS_INVALID -1
/** * struct cxl_decoder - Common CXL HDM Decoder Attributes * @dev: this decoder's device * @id: kernel device name id * @hpa_range: Host physical address range mapped by this decoder * @interleave_ways: number of cxl_dports in this decode * @interleave_granularity: data stride per dport * @target_type: accelerator vs expander (type2 vs type3) selector * @region: currently assigned region for this decoder * @flags: memory type capabilities and locking * @commit: device/decoder-type specific callback to commit settings to hw * @reset: device/decoder-type specific callback to reset hw settings
*/ struct cxl_decoder { struct device dev; int id; struct range hpa_range; int interleave_ways; int interleave_granularity; enum cxl_decoder_type target_type; struct cxl_region *region; unsignedlong flags; int (*commit)(struct cxl_decoder *cxld); void (*reset)(struct cxl_decoder *cxld);
};
/* * Track whether this decoder is reserved for region autodiscovery, or * free for userspace provisioning.
*/ enum cxl_decoder_state {
CXL_DECODER_STATE_MANUAL,
CXL_DECODER_STATE_AUTO,
};
/** * struct cxl_endpoint_decoder - Endpoint / SPA to DPA decoder * @cxld: base cxl_decoder_object * @dpa_res: actively claimed DPA span of this decoder * @skip: offset into @dpa_res where @cxld.hpa_range maps * @state: autodiscovery state * @part: partition index this decoder maps * @pos: interleave position in @cxld.region
*/ struct cxl_endpoint_decoder { struct cxl_decoder cxld; struct resource *dpa_res;
resource_size_t skip; enum cxl_decoder_state state; int part; int pos;
};
/** * struct cxl_switch_decoder - Switch specific CXL HDM Decoder * @cxld: base cxl_decoder object * @nr_targets: number of elements in @target * @target: active ordered target list in current decoder configuration * * The 'switch' decoder type represents the decoder instances of cxl_port's that * route from the root of a CXL memory decode topology to the endpoints. They * come in two flavors, root-level decoders, statically defined by platform * firmware, and mid-level decoders, where interleave-granularity, * interleave-width, and the target list are mutable.
*/ struct cxl_switch_decoder { struct cxl_decoder cxld; int nr_targets; struct cxl_dport *target[];
};
/** * struct cxl_root_decoder - Static platform CXL address decoder * @res: host / parent resource for region allocations * @cache_size: extended linear cache size if exists, otherwise zero. * @region_id: region id for next region provisioning event * @hpa_to_spa: translate CXL host-physical-address to Platform system-physical-address * @platform_data: platform specific configuration data * @range_lock: sync region autodiscovery by address range * @qos_class: QoS performance class cookie * @cxlsd: base cxl switch decoder
*/ struct cxl_root_decoder { struct resource *res;
resource_size_t cache_size;
atomic_t region_id;
cxl_hpa_to_spa_fn hpa_to_spa; void *platform_data; struct mutex range_lock; int qos_class; struct cxl_switch_decoder cxlsd;
};
/* * enum cxl_config_state - State machine for region configuration * @CXL_CONFIG_IDLE: Any sysfs attribute can be written freely * @CXL_CONFIG_INTERLEAVE_ACTIVE: region size has been set, no more * changes to interleave_ways or interleave_granularity * @CXL_CONFIG_ACTIVE: All targets have been added the region is now * active * @CXL_CONFIG_RESET_PENDING: see commit_store() * @CXL_CONFIG_COMMIT: Soft-config has been committed to hardware
*/ enum cxl_config_state {
CXL_CONFIG_IDLE,
CXL_CONFIG_INTERLEAVE_ACTIVE,
CXL_CONFIG_ACTIVE,
CXL_CONFIG_RESET_PENDING,
CXL_CONFIG_COMMIT,
};
/** * struct cxl_region_params - region settings * @state: allow the driver to lockdown further parameter changes * @uuid: unique id for persistent regions * @interleave_ways: number of endpoints in the region * @interleave_granularity: capacity each endpoint contributes to a stripe * @res: allocated iomem capacity for this region * @targets: active ordered targets in current decoder configuration * @nr_targets: number of targets * @cache_size: extended linear cache size if exists, otherwise zero. * * State transitions are protected by cxl_rwsem.region
*/ struct cxl_region_params { enum cxl_config_state state;
uuid_t uuid; int interleave_ways; int interleave_granularity; struct resource *res; struct cxl_endpoint_decoder *targets[CXL_DECODER_MAX_INTERLEAVE]; int nr_targets;
resource_size_t cache_size;
};
/* * Indicate whether this region has been assembled by autodetection or * userspace assembly. Prevent endpoint decoders outside of automatic * detection from being added to the region.
*/ #define CXL_REGION_F_AUTO 0
/* * Require that a committed region successfully complete a teardown once * any of its associated decoders have been torn down. This maintains * the commit state for the region since there are committed decoders, * but blocks cxl_region_probe().
*/ #define CXL_REGION_F_NEEDS_RESET 1
/** * struct cxl_region - CXL region * @dev: This region's device * @id: This region's id. Id is globally unique across all regions * @mode: Operational mode of the mapped capacity * @type: Endpoint decoder target type * @cxl_nvb: nvdimm bridge for coordinating @cxlr_pmem setup / shutdown * @cxlr_pmem: (for pmem regions) cached copy of the nvdimm bridge * @flags: Region state flags * @params: active + config params for the region * @coord: QoS access coordinates for the region * @node_notifier: notifier for setting the access coordinates to node * @adist_notifier: notifier for calculating the abstract distance of node
*/ struct cxl_region { struct device dev; int id; enum cxl_partition_mode mode; enum cxl_decoder_type type; struct cxl_nvdimm_bridge *cxl_nvb; struct cxl_pmem_region *cxlr_pmem; unsignedlong flags; struct cxl_region_params params; struct access_coordinate coord[ACCESS_COORDINATE_MAX]; struct notifier_block node_notifier; struct notifier_block adist_notifier;
};
/** * struct cxl_port - logical collection of upstream port devices and * downstream port devices to construct a CXL memory * decode hierarchy. * @dev: this port's device * @uport_dev: PCI or platform device implementing the upstream port capability * @host_bridge: Shortcut to the platform attach point for this port * @id: id for port device-name * @dports: cxl_dport instances referenced by decoders * @endpoints: cxl_ep instances, endpoints that are a descendant of this port * @regions: cxl_region_ref instances, regions mapped by this port * @parent_dport: dport that points to this port in the parent * @decoder_ida: allocator for decoder ids * @reg_map: component and ras register mapping parameters * @nr_dports: number of entries in @dports * @hdm_end: track last allocated HDM decoder instance for allocation ordering * @commit_end: cursor to track highest committed decoder for commit ordering * @dead: last ep has been removed, force port re-creation * @depth: How deep this port is relative to the root. depth 0 is the root. * @cdat: Cached CDAT data * @cdat_available: Should a CDAT attribute be available in sysfs * @pci_latency: Upstream latency in picoseconds
*/ struct cxl_port { struct device dev; struct device *uport_dev; struct device *host_bridge; int id; struct xarray dports; struct xarray endpoints; struct xarray regions; struct cxl_dport *parent_dport; struct ida decoder_ida; struct cxl_register_map reg_map; int nr_dports; int hdm_end; int commit_end; bool dead; unsignedint depth; struct cxl_cdat { void *table;
size_t length;
} cdat; bool cdat_available; long pci_latency;
};
/** * struct cxl_dport - CXL downstream port * @dport_dev: PCI bridge or firmware device representing the downstream link * @reg_map: component and ras register mapping parameters * @port_id: unique hardware identifier for dport in decoder target list * @rcrb: Data about the Root Complex Register Block layout * @rch: Indicate whether this dport was enumerated in RCH or VH mode * @port: reference to cxl_port that contains this downstream port * @regs: Dport parsed register blocks * @coord: access coordinates (bandwidth and latency performance attributes) * @link_latency: calculated PCIe downstream latency * @gpf_dvsec: Cached GPF port DVSEC
*/ struct cxl_dport { struct device *dport_dev; struct cxl_register_map reg_map; int port_id; struct cxl_rcrb_info rcrb; bool rch; struct cxl_port *port; struct cxl_regs regs; struct access_coordinate coord[ACCESS_COORDINATE_MAX]; long link_latency; int gpf_dvsec;
};
/** * struct cxl_ep - track an endpoint's interest in a port * @ep: device that hosts a generic CXL endpoint (expander or accelerator) * @dport: which dport routes to this endpoint on @port * @next: cxl switch port across the link attached to @dport NULL if * attached to an endpoint
*/ struct cxl_ep { struct device *ep; struct cxl_dport *dport; struct cxl_port *next;
};
/** * struct cxl_region_ref - track a region's interest in a port * @port: point in topology to install this reference * @decoder: decoder assigned for @region in @port * @region: region for this reference * @endpoints: cxl_ep references for region members beneath @port * @nr_targets_set: track how many targets have been programmed during setup * @nr_eps: number of endpoints beneath @port * @nr_targets: number of distinct targets needed to reach @nr_eps
*/ struct cxl_region_ref { struct cxl_port *port; struct cxl_decoder *decoder; struct cxl_region *region; struct xarray endpoints; int nr_targets_set; int nr_eps; int nr_targets;
};
/* * The platform firmware device hosting the root is also the top of the * CXL port topology. All other CXL ports have another CXL port as their * parent and their ->uport_dev / host device is out-of-line of the port * ancestry.
*/ staticinlinebool is_cxl_root(struct cxl_port *port)
{ return port->uport_dev == port->dev.parent;
}
/** * struct cxl_endpoint_dvsec_info - Cached DVSEC info * @mem_enabled: cached value of mem_enabled in the DVSEC at init time * @ranges: Number of active HDM ranges this device uses. * @port: endpoint port associated with this info instance * @dvsec_range: cached attributes of the ranges in the DVSEC, PCIE_DEVICE
*/ struct cxl_endpoint_dvsec_info { bool mem_enabled; int ranges; struct cxl_port *port; struct range dvsec_range[2];
};
struct cxl_hdm; struct cxl_hdm *devm_cxl_setup_hdm(struct cxl_port *port, struct cxl_endpoint_dvsec_info *info); int devm_cxl_enumerate_decoders(struct cxl_hdm *cxlhdm, struct cxl_endpoint_dvsec_info *info); int devm_cxl_add_passthrough_decoder(struct cxl_port *port); struct cxl_dev_state; int cxl_dvsec_rr_decode(struct cxl_dev_state *cxlds, struct cxl_endpoint_dvsec_info *info);
bool is_cxl_region(struct device *dev);
externconststruct bus_type cxl_bus_type;
struct cxl_driver { constchar *name; int (*probe)(struct device *dev); void (*remove)(struct device *dev); struct device_driver drv; int id;
};
/* * Unit test builds overrides this to __weak, find the 'strong' version * of these symbols in tools/testing/cxl/.
*/ #ifndef __mock #define __mock static #endif
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.