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 { 923a5fba4SThomas Petazzoni u16 vendor; 1023a5fba4SThomas Petazzoni u16 device; 1123a5fba4SThomas Petazzoni u16 command; 1223a5fba4SThomas Petazzoni u16 status; 1323a5fba4SThomas Petazzoni u32 class_revision; 1423a5fba4SThomas Petazzoni u8 cache_line_size; 1523a5fba4SThomas Petazzoni u8 latency_timer; 1623a5fba4SThomas Petazzoni u8 header_type; 1723a5fba4SThomas Petazzoni u8 bist; 1823a5fba4SThomas Petazzoni u32 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; 2523a5fba4SThomas Petazzoni u16 secondary_status; 2623a5fba4SThomas Petazzoni u16 membase; 2723a5fba4SThomas Petazzoni u16 memlimit; 2823a5fba4SThomas Petazzoni u16 pref_mem_base; 2923a5fba4SThomas Petazzoni u16 pref_mem_limit; 3023a5fba4SThomas Petazzoni u32 prefbaseupper; 3123a5fba4SThomas Petazzoni u32 preflimitupper; 3223a5fba4SThomas Petazzoni u16 iobaseupper; 3323a5fba4SThomas Petazzoni u16 iolimitupper; 3423a5fba4SThomas Petazzoni u8 capabilities_pointer; 3523a5fba4SThomas Petazzoni u8 reserve[3]; 3623a5fba4SThomas Petazzoni u32 romaddr; 3723a5fba4SThomas Petazzoni u8 intline; 3823a5fba4SThomas Petazzoni u8 intpin; 3923a5fba4SThomas Petazzoni u16 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; 4623a5fba4SThomas Petazzoni u16 cap; 4723a5fba4SThomas Petazzoni u32 devcap; 4823a5fba4SThomas Petazzoni u16 devctl; 4923a5fba4SThomas Petazzoni u16 devsta; 5023a5fba4SThomas Petazzoni u32 lnkcap; 5123a5fba4SThomas Petazzoni u16 lnkctl; 5223a5fba4SThomas Petazzoni u16 lnksta; 5323a5fba4SThomas Petazzoni u32 slotcap; 5423a5fba4SThomas Petazzoni u16 slotctl; 5523a5fba4SThomas Petazzoni u16 slotsta; 5623a5fba4SThomas Petazzoni u16 rootctl; 5723a5fba4SThomas Petazzoni u16 rsvd; 5823a5fba4SThomas Petazzoni u32 rootsta; 5923a5fba4SThomas Petazzoni u32 devcap2; 6023a5fba4SThomas Petazzoni u16 devctl2; 6123a5fba4SThomas Petazzoni u16 devsta2; 6223a5fba4SThomas Petazzoni u32 lnkcap2; 6323a5fba4SThomas Petazzoni u16 lnkctl2; 6423a5fba4SThomas Petazzoni u16 lnksta2; 6523a5fba4SThomas Petazzoni u32 slotcap2; 6623a5fba4SThomas Petazzoni u16 slotctl2; 6723a5fba4SThomas Petazzoni u16 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); 9323a5fba4SThomas Petazzoni /* 9423a5fba4SThomas Petazzoni * Called when writing to the regular PCI bridge configuration 9523a5fba4SThomas Petazzoni * space. old is the current value, new is the new value being 9623a5fba4SThomas Petazzoni * written, and mask indicates which parts of the value are 9723a5fba4SThomas Petazzoni * being changed. 9823a5fba4SThomas Petazzoni */ 9923a5fba4SThomas Petazzoni void (*write_base)(struct pci_bridge_emul *bridge, int reg, 10023a5fba4SThomas Petazzoni u32 old, u32 new, u32 mask); 10123a5fba4SThomas Petazzoni 10223a5fba4SThomas Petazzoni /* 10323a5fba4SThomas Petazzoni * Same as ->write_base(), except it is for writing from the 10423a5fba4SThomas Petazzoni * PCIe capability configuration space. 10523a5fba4SThomas Petazzoni */ 10623a5fba4SThomas Petazzoni void (*write_pcie)(struct pci_bridge_emul *bridge, int reg, 10723a5fba4SThomas Petazzoni u32 old, u32 new, u32 mask); 10823a5fba4SThomas Petazzoni }; 10923a5fba4SThomas Petazzoni 11023a5fba4SThomas Petazzoni struct pci_bridge_emul { 11123a5fba4SThomas Petazzoni struct pci_bridge_emul_conf conf; 11223a5fba4SThomas Petazzoni struct pci_bridge_emul_pcie_conf pcie_conf; 11323a5fba4SThomas Petazzoni struct pci_bridge_emul_ops *ops; 11423a5fba4SThomas Petazzoni void *data; 11523a5fba4SThomas Petazzoni bool has_pcie; 11623a5fba4SThomas Petazzoni }; 11723a5fba4SThomas Petazzoni 11823a5fba4SThomas Petazzoni void pci_bridge_emul_init(struct pci_bridge_emul *bridge); 11923a5fba4SThomas Petazzoni int pci_bridge_emul_conf_read(struct pci_bridge_emul *bridge, int where, 12023a5fba4SThomas Petazzoni int size, u32 *value); 12123a5fba4SThomas Petazzoni int pci_bridge_emul_conf_write(struct pci_bridge_emul *bridge, int where, 12223a5fba4SThomas Petazzoni int size, u32 value); 12323a5fba4SThomas Petazzoni 12423a5fba4SThomas Petazzoni #endif /* __PCI_BRIDGE_EMUL_H__ */ 125