123a5fba4SThomas Petazzoni /* SPDX-License-Identifier: GPL-2.0 */ 223a5fba4SThomas Petazzoni #ifndef __PCI_BRIDGE_EMUL_H__ 323a5fba4SThomas Petazzoni #define __PCI_BRIDGE_EMUL_H__ 423a5fba4SThomas Petazzoni 523a5fba4SThomas Petazzoni #include <linux/kernel.h> 623a5fba4SThomas Petazzoni 723a5fba4SThomas Petazzoni /* PCI configuration space of a PCI-to-PCI bridge. */ 823a5fba4SThomas Petazzoni struct pci_bridge_emul_conf { 9e0d9d30bSGrzegorz Jaszczyk __le16 vendor; 10e0d9d30bSGrzegorz Jaszczyk __le16 device; 11e0d9d30bSGrzegorz Jaszczyk __le16 command; 12e0d9d30bSGrzegorz Jaszczyk __le16 status; 13e0d9d30bSGrzegorz Jaszczyk __le32 class_revision; 1423a5fba4SThomas Petazzoni u8 cache_line_size; 1523a5fba4SThomas Petazzoni u8 latency_timer; 1623a5fba4SThomas Petazzoni u8 header_type; 1723a5fba4SThomas Petazzoni u8 bist; 18e0d9d30bSGrzegorz Jaszczyk __le32 bar[2]; 1923a5fba4SThomas Petazzoni u8 primary_bus; 2023a5fba4SThomas Petazzoni u8 secondary_bus; 2123a5fba4SThomas Petazzoni u8 subordinate_bus; 2223a5fba4SThomas Petazzoni u8 secondary_latency_timer; 2323a5fba4SThomas Petazzoni u8 iobase; 2423a5fba4SThomas Petazzoni u8 iolimit; 25e0d9d30bSGrzegorz Jaszczyk __le16 secondary_status; 26e0d9d30bSGrzegorz Jaszczyk __le16 membase; 27e0d9d30bSGrzegorz Jaszczyk __le16 memlimit; 28e0d9d30bSGrzegorz Jaszczyk __le16 pref_mem_base; 29e0d9d30bSGrzegorz Jaszczyk __le16 pref_mem_limit; 30e0d9d30bSGrzegorz Jaszczyk __le32 prefbaseupper; 31e0d9d30bSGrzegorz Jaszczyk __le32 preflimitupper; 32e0d9d30bSGrzegorz Jaszczyk __le16 iobaseupper; 33e0d9d30bSGrzegorz Jaszczyk __le16 iolimitupper; 3423a5fba4SThomas Petazzoni u8 capabilities_pointer; 3523a5fba4SThomas Petazzoni u8 reserve[3]; 36e0d9d30bSGrzegorz Jaszczyk __le32 romaddr; 3723a5fba4SThomas Petazzoni u8 intline; 3823a5fba4SThomas Petazzoni u8 intpin; 39e0d9d30bSGrzegorz Jaszczyk __le16 bridgectrl; 4023a5fba4SThomas Petazzoni }; 4123a5fba4SThomas Petazzoni 4223a5fba4SThomas Petazzoni /* PCI configuration space of the PCIe capabilities */ 4323a5fba4SThomas Petazzoni struct pci_bridge_emul_pcie_conf { 4423a5fba4SThomas Petazzoni u8 cap_id; 4523a5fba4SThomas Petazzoni u8 next; 46e0d9d30bSGrzegorz Jaszczyk __le16 cap; 47e0d9d30bSGrzegorz Jaszczyk __le32 devcap; 48e0d9d30bSGrzegorz Jaszczyk __le16 devctl; 49e0d9d30bSGrzegorz Jaszczyk __le16 devsta; 50e0d9d30bSGrzegorz Jaszczyk __le32 lnkcap; 51e0d9d30bSGrzegorz Jaszczyk __le16 lnkctl; 52e0d9d30bSGrzegorz Jaszczyk __le16 lnksta; 53e0d9d30bSGrzegorz Jaszczyk __le32 slotcap; 54e0d9d30bSGrzegorz Jaszczyk __le16 slotctl; 55e0d9d30bSGrzegorz Jaszczyk __le16 slotsta; 56e0d9d30bSGrzegorz Jaszczyk __le16 rootctl; 57e902bb7cSPali Rohár __le16 rootcap; 58e0d9d30bSGrzegorz Jaszczyk __le32 rootsta; 59e0d9d30bSGrzegorz Jaszczyk __le32 devcap2; 60e0d9d30bSGrzegorz Jaszczyk __le16 devctl2; 61e0d9d30bSGrzegorz Jaszczyk __le16 devsta2; 62e0d9d30bSGrzegorz Jaszczyk __le32 lnkcap2; 63e0d9d30bSGrzegorz Jaszczyk __le16 lnkctl2; 64e0d9d30bSGrzegorz Jaszczyk __le16 lnksta2; 65e0d9d30bSGrzegorz Jaszczyk __le32 slotcap2; 66e0d9d30bSGrzegorz Jaszczyk __le16 slotctl2; 67e0d9d30bSGrzegorz Jaszczyk __le16 slotsta2; 6823a5fba4SThomas Petazzoni }; 6923a5fba4SThomas Petazzoni 7023a5fba4SThomas Petazzoni struct pci_bridge_emul; 7123a5fba4SThomas Petazzoni 7223a5fba4SThomas Petazzoni typedef enum { PCI_BRIDGE_EMUL_HANDLED, 7323a5fba4SThomas Petazzoni PCI_BRIDGE_EMUL_NOT_HANDLED } pci_bridge_emul_read_status_t; 7423a5fba4SThomas Petazzoni 7523a5fba4SThomas Petazzoni struct pci_bridge_emul_ops { 7623a5fba4SThomas Petazzoni /* 7723a5fba4SThomas Petazzoni * Called when reading from the regular PCI bridge 7823a5fba4SThomas Petazzoni * configuration space. Return PCI_BRIDGE_EMUL_HANDLED when the 7923a5fba4SThomas Petazzoni * operation has handled the read operation and filled in the 8023a5fba4SThomas Petazzoni * *value, or PCI_BRIDGE_EMUL_NOT_HANDLED when the read should 8123a5fba4SThomas Petazzoni * be emulated by the common code by reading from the 8223a5fba4SThomas Petazzoni * in-memory copy of the configuration space. 8323a5fba4SThomas Petazzoni */ 8423a5fba4SThomas Petazzoni pci_bridge_emul_read_status_t (*read_base)(struct pci_bridge_emul *bridge, 8523a5fba4SThomas Petazzoni int reg, u32 *value); 8623a5fba4SThomas Petazzoni 8723a5fba4SThomas Petazzoni /* 8823a5fba4SThomas Petazzoni * Same as ->read_base(), except it is for reading from the 8923a5fba4SThomas Petazzoni * PCIe capability configuration space. 9023a5fba4SThomas Petazzoni */ 9123a5fba4SThomas Petazzoni pci_bridge_emul_read_status_t (*read_pcie)(struct pci_bridge_emul *bridge, 9223a5fba4SThomas Petazzoni int reg, u32 *value); 93*c0bd4197SRussell King 94*c0bd4197SRussell King /* 95*c0bd4197SRussell King * Same as ->read_base(), except it is for reading from the 96*c0bd4197SRussell King * PCIe extended capability configuration space. 97*c0bd4197SRussell King */ 98*c0bd4197SRussell King pci_bridge_emul_read_status_t (*read_ext)(struct pci_bridge_emul *bridge, 99*c0bd4197SRussell King int reg, u32 *value); 100*c0bd4197SRussell King 10123a5fba4SThomas Petazzoni /* 10223a5fba4SThomas Petazzoni * Called when writing to the regular PCI bridge configuration 10323a5fba4SThomas Petazzoni * space. old is the current value, new is the new value being 10423a5fba4SThomas Petazzoni * written, and mask indicates which parts of the value are 10523a5fba4SThomas Petazzoni * being changed. 10623a5fba4SThomas Petazzoni */ 10723a5fba4SThomas Petazzoni void (*write_base)(struct pci_bridge_emul *bridge, int reg, 10823a5fba4SThomas Petazzoni u32 old, u32 new, u32 mask); 10923a5fba4SThomas Petazzoni 11023a5fba4SThomas Petazzoni /* 11123a5fba4SThomas Petazzoni * Same as ->write_base(), except it is for writing from the 11223a5fba4SThomas Petazzoni * PCIe capability configuration space. 11323a5fba4SThomas Petazzoni */ 11423a5fba4SThomas Petazzoni void (*write_pcie)(struct pci_bridge_emul *bridge, int reg, 11523a5fba4SThomas Petazzoni u32 old, u32 new, u32 mask); 116*c0bd4197SRussell King 117*c0bd4197SRussell King /* 118*c0bd4197SRussell King * Same as ->write_base(), except it is for writing from the 119*c0bd4197SRussell King * PCIe extended capability configuration space. 120*c0bd4197SRussell King */ 121*c0bd4197SRussell King void (*write_ext)(struct pci_bridge_emul *bridge, int reg, 122*c0bd4197SRussell King u32 old, u32 new, u32 mask); 12323a5fba4SThomas Petazzoni }; 12423a5fba4SThomas Petazzoni 12559f81c35SThomas Petazzoni struct pci_bridge_reg_behavior; 12659f81c35SThomas Petazzoni 12723a5fba4SThomas Petazzoni struct pci_bridge_emul { 12823a5fba4SThomas Petazzoni struct pci_bridge_emul_conf conf; 12923a5fba4SThomas Petazzoni struct pci_bridge_emul_pcie_conf pcie_conf; 13064a70f52SPali Rohár const struct pci_bridge_emul_ops *ops; 13159f81c35SThomas Petazzoni struct pci_bridge_reg_behavior *pci_regs_behavior; 13259f81c35SThomas Petazzoni struct pci_bridge_reg_behavior *pcie_cap_regs_behavior; 13323a5fba4SThomas Petazzoni void *data; 13423a5fba4SThomas Petazzoni bool has_pcie; 13523a5fba4SThomas Petazzoni }; 13623a5fba4SThomas Petazzoni 13733776d05SThomas Petazzoni enum { 138d3f332b5SPali Rohár /* 139d3f332b5SPali Rohár * PCI bridge does not support forwarding of prefetchable memory 140d3f332b5SPali Rohár * requests between primary and secondary buses. 141d3f332b5SPali Rohár */ 142d3f332b5SPali Rohár PCI_BRIDGE_EMUL_NO_PREFMEM_FORWARD = BIT(0), 14305241c13SPali Rohár 14405241c13SPali Rohár /* 14505241c13SPali Rohár * PCI bridge does not support forwarding of IO requests between 14605241c13SPali Rohár * primary and secondary buses. 14705241c13SPali Rohár */ 14805241c13SPali Rohár PCI_BRIDGE_EMUL_NO_IO_FORWARD = BIT(1), 14933776d05SThomas Petazzoni }; 15033776d05SThomas Petazzoni 15133776d05SThomas Petazzoni int pci_bridge_emul_init(struct pci_bridge_emul *bridge, 15233776d05SThomas Petazzoni unsigned int flags); 15359f81c35SThomas Petazzoni void pci_bridge_emul_cleanup(struct pci_bridge_emul *bridge); 15459f81c35SThomas Petazzoni 15523a5fba4SThomas Petazzoni int pci_bridge_emul_conf_read(struct pci_bridge_emul *bridge, int where, 15623a5fba4SThomas Petazzoni int size, u32 *value); 15723a5fba4SThomas Petazzoni int pci_bridge_emul_conf_write(struct pci_bridge_emul *bridge, int where, 15823a5fba4SThomas Petazzoni int size, u32 value); 15923a5fba4SThomas Petazzoni 16023a5fba4SThomas Petazzoni #endif /* __PCI_BRIDGE_EMUL_H__ */ 161