/* SPDX-License-Identifier: GPL-2.0 */ #ifndef __PCI_BRIDGE_EMUL_H__ #define __PCI_BRIDGE_EMUL_H__ #include /* PCI configuration space of a PCI-to-PCI bridge. */ struct pci_bridge_emul_conf { __le16 vendor; __le16 device; __le16 command; __le16 status; __le32 class_revision; u8 cache_line_size; u8 latency_timer; u8 header_type; u8 bist; __le32 bar[2]; u8 primary_bus; u8 secondary_bus; u8 subordinate_bus; u8 secondary_latency_timer; u8 iobase; u8 iolimit; __le16 secondary_status; __le16 membase; __le16 memlimit; __le16 pref_mem_base; __le16 pref_mem_limit; __le32 prefbaseupper; __le32 preflimitupper; __le16 iobaseupper; __le16 iolimitupper; u8 capabilities_pointer; u8 reserve[3]; __le32 romaddr; u8 intline; u8 intpin; __le16 bridgectrl; }; /* PCI configuration space of the PCIe capabilities */ struct pci_bridge_emul_pcie_conf { u8 cap_id; u8 next; __le16 cap; __le32 devcap; __le16 devctl; __le16 devsta; __le32 lnkcap; __le16 lnkctl; __le16 lnksta; __le32 slotcap; __le16 slotctl; __le16 slotsta; __le16 rootctl; __le16 rsvd; __le32 rootsta; __le32 devcap2; __le16 devctl2; __le16 devsta2; __le32 lnkcap2; __le16 lnkctl2; __le16 lnksta2; __le32 slotcap2; __le16 slotctl2; __le16 slotsta2; }; struct pci_bridge_emul; typedef enum { PCI_BRIDGE_EMUL_HANDLED, PCI_BRIDGE_EMUL_NOT_HANDLED } pci_bridge_emul_read_status_t; struct pci_bridge_emul_ops { /* * Called when reading from the regular PCI bridge * configuration space. Return PCI_BRIDGE_EMUL_HANDLED when the * operation has handled the read operation and filled in the * *value, or PCI_BRIDGE_EMUL_NOT_HANDLED when the read should * be emulated by the common code by reading from the * in-memory copy of the configuration space. */ pci_bridge_emul_read_status_t (*read_base)(struct pci_bridge_emul *bridge, int reg, u32 *value); /* * Same as ->read_base(), except it is for reading from the * PCIe capability configuration space. */ pci_bridge_emul_read_status_t (*read_pcie)(struct pci_bridge_emul *bridge, int reg, u32 *value); /* * Called when writing to the regular PCI bridge configuration * space. old is the current value, new is the new value being * written, and mask indicates which parts of the value are * being changed. */ void (*write_base)(struct pci_bridge_emul *bridge, int reg, u32 old, u32 new, u32 mask); /* * Same as ->write_base(), except it is for writing from the * PCIe capability configuration space. */ void (*write_pcie)(struct pci_bridge_emul *bridge, int reg, u32 old, u32 new, u32 mask); }; struct pci_bridge_reg_behavior; struct pci_bridge_emul { struct pci_bridge_emul_conf conf; struct pci_bridge_emul_pcie_conf pcie_conf; struct pci_bridge_emul_ops *ops; struct pci_bridge_reg_behavior *pci_regs_behavior; struct pci_bridge_reg_behavior *pcie_cap_regs_behavior; void *data; bool has_pcie; }; enum { PCI_BRIDGE_EMUL_NO_PREFETCHABLE_BAR = BIT(0), }; int pci_bridge_emul_init(struct pci_bridge_emul *bridge, unsigned int flags); void pci_bridge_emul_cleanup(struct pci_bridge_emul *bridge); int pci_bridge_emul_conf_read(struct pci_bridge_emul *bridge, int where, int size, u32 *value); int pci_bridge_emul_conf_write(struct pci_bridge_emul *bridge, int where, int size, u32 value); #endif /* __PCI_BRIDGE_EMUL_H__ */