18c2ecf20Sopenharmony_ci/* SPDX-License-Identifier: GPL-2.0 */ 28c2ecf20Sopenharmony_ci#ifndef __PCI_BRIDGE_EMUL_H__ 38c2ecf20Sopenharmony_ci#define __PCI_BRIDGE_EMUL_H__ 48c2ecf20Sopenharmony_ci 58c2ecf20Sopenharmony_ci#include <linux/kernel.h> 68c2ecf20Sopenharmony_ci 78c2ecf20Sopenharmony_ci/* PCI configuration space of a PCI-to-PCI bridge. */ 88c2ecf20Sopenharmony_cistruct pci_bridge_emul_conf { 98c2ecf20Sopenharmony_ci __le16 vendor; 108c2ecf20Sopenharmony_ci __le16 device; 118c2ecf20Sopenharmony_ci __le16 command; 128c2ecf20Sopenharmony_ci __le16 status; 138c2ecf20Sopenharmony_ci __le32 class_revision; 148c2ecf20Sopenharmony_ci u8 cache_line_size; 158c2ecf20Sopenharmony_ci u8 latency_timer; 168c2ecf20Sopenharmony_ci u8 header_type; 178c2ecf20Sopenharmony_ci u8 bist; 188c2ecf20Sopenharmony_ci __le32 bar[2]; 198c2ecf20Sopenharmony_ci u8 primary_bus; 208c2ecf20Sopenharmony_ci u8 secondary_bus; 218c2ecf20Sopenharmony_ci u8 subordinate_bus; 228c2ecf20Sopenharmony_ci u8 secondary_latency_timer; 238c2ecf20Sopenharmony_ci u8 iobase; 248c2ecf20Sopenharmony_ci u8 iolimit; 258c2ecf20Sopenharmony_ci __le16 secondary_status; 268c2ecf20Sopenharmony_ci __le16 membase; 278c2ecf20Sopenharmony_ci __le16 memlimit; 288c2ecf20Sopenharmony_ci __le16 pref_mem_base; 298c2ecf20Sopenharmony_ci __le16 pref_mem_limit; 308c2ecf20Sopenharmony_ci __le32 prefbaseupper; 318c2ecf20Sopenharmony_ci __le32 preflimitupper; 328c2ecf20Sopenharmony_ci __le16 iobaseupper; 338c2ecf20Sopenharmony_ci __le16 iolimitupper; 348c2ecf20Sopenharmony_ci u8 capabilities_pointer; 358c2ecf20Sopenharmony_ci u8 reserve[3]; 368c2ecf20Sopenharmony_ci __le32 romaddr; 378c2ecf20Sopenharmony_ci u8 intline; 388c2ecf20Sopenharmony_ci u8 intpin; 398c2ecf20Sopenharmony_ci __le16 bridgectrl; 408c2ecf20Sopenharmony_ci}; 418c2ecf20Sopenharmony_ci 428c2ecf20Sopenharmony_ci/* PCI configuration space of the PCIe capabilities */ 438c2ecf20Sopenharmony_cistruct pci_bridge_emul_pcie_conf { 448c2ecf20Sopenharmony_ci u8 cap_id; 458c2ecf20Sopenharmony_ci u8 next; 468c2ecf20Sopenharmony_ci __le16 cap; 478c2ecf20Sopenharmony_ci __le32 devcap; 488c2ecf20Sopenharmony_ci __le16 devctl; 498c2ecf20Sopenharmony_ci __le16 devsta; 508c2ecf20Sopenharmony_ci __le32 lnkcap; 518c2ecf20Sopenharmony_ci __le16 lnkctl; 528c2ecf20Sopenharmony_ci __le16 lnksta; 538c2ecf20Sopenharmony_ci __le32 slotcap; 548c2ecf20Sopenharmony_ci __le16 slotctl; 558c2ecf20Sopenharmony_ci __le16 slotsta; 568c2ecf20Sopenharmony_ci __le16 rootctl; 578c2ecf20Sopenharmony_ci __le16 rootcap; 588c2ecf20Sopenharmony_ci __le32 rootsta; 598c2ecf20Sopenharmony_ci __le32 devcap2; 608c2ecf20Sopenharmony_ci __le16 devctl2; 618c2ecf20Sopenharmony_ci __le16 devsta2; 628c2ecf20Sopenharmony_ci __le32 lnkcap2; 638c2ecf20Sopenharmony_ci __le16 lnkctl2; 648c2ecf20Sopenharmony_ci __le16 lnksta2; 658c2ecf20Sopenharmony_ci __le32 slotcap2; 668c2ecf20Sopenharmony_ci __le16 slotctl2; 678c2ecf20Sopenharmony_ci __le16 slotsta2; 688c2ecf20Sopenharmony_ci}; 698c2ecf20Sopenharmony_ci 708c2ecf20Sopenharmony_cistruct pci_bridge_emul; 718c2ecf20Sopenharmony_ci 728c2ecf20Sopenharmony_citypedef enum { PCI_BRIDGE_EMUL_HANDLED, 738c2ecf20Sopenharmony_ci PCI_BRIDGE_EMUL_NOT_HANDLED } pci_bridge_emul_read_status_t; 748c2ecf20Sopenharmony_ci 758c2ecf20Sopenharmony_cistruct pci_bridge_emul_ops { 768c2ecf20Sopenharmony_ci /* 778c2ecf20Sopenharmony_ci * Called when reading from the regular PCI bridge 788c2ecf20Sopenharmony_ci * configuration space. Return PCI_BRIDGE_EMUL_HANDLED when the 798c2ecf20Sopenharmony_ci * operation has handled the read operation and filled in the 808c2ecf20Sopenharmony_ci * *value, or PCI_BRIDGE_EMUL_NOT_HANDLED when the read should 818c2ecf20Sopenharmony_ci * be emulated by the common code by reading from the 828c2ecf20Sopenharmony_ci * in-memory copy of the configuration space. 838c2ecf20Sopenharmony_ci */ 848c2ecf20Sopenharmony_ci pci_bridge_emul_read_status_t (*read_base)(struct pci_bridge_emul *bridge, 858c2ecf20Sopenharmony_ci int reg, u32 *value); 868c2ecf20Sopenharmony_ci 878c2ecf20Sopenharmony_ci /* 888c2ecf20Sopenharmony_ci * Same as ->read_base(), except it is for reading from the 898c2ecf20Sopenharmony_ci * PCIe capability configuration space. 908c2ecf20Sopenharmony_ci */ 918c2ecf20Sopenharmony_ci pci_bridge_emul_read_status_t (*read_pcie)(struct pci_bridge_emul *bridge, 928c2ecf20Sopenharmony_ci int reg, u32 *value); 938c2ecf20Sopenharmony_ci /* 948c2ecf20Sopenharmony_ci * Called when writing to the regular PCI bridge configuration 958c2ecf20Sopenharmony_ci * space. old is the current value, new is the new value being 968c2ecf20Sopenharmony_ci * written, and mask indicates which parts of the value are 978c2ecf20Sopenharmony_ci * being changed. 988c2ecf20Sopenharmony_ci */ 998c2ecf20Sopenharmony_ci void (*write_base)(struct pci_bridge_emul *bridge, int reg, 1008c2ecf20Sopenharmony_ci u32 old, u32 new, u32 mask); 1018c2ecf20Sopenharmony_ci 1028c2ecf20Sopenharmony_ci /* 1038c2ecf20Sopenharmony_ci * Same as ->write_base(), except it is for writing from the 1048c2ecf20Sopenharmony_ci * PCIe capability configuration space. 1058c2ecf20Sopenharmony_ci */ 1068c2ecf20Sopenharmony_ci void (*write_pcie)(struct pci_bridge_emul *bridge, int reg, 1078c2ecf20Sopenharmony_ci u32 old, u32 new, u32 mask); 1088c2ecf20Sopenharmony_ci}; 1098c2ecf20Sopenharmony_ci 1108c2ecf20Sopenharmony_cistruct pci_bridge_reg_behavior; 1118c2ecf20Sopenharmony_ci 1128c2ecf20Sopenharmony_cistruct pci_bridge_emul { 1138c2ecf20Sopenharmony_ci struct pci_bridge_emul_conf conf; 1148c2ecf20Sopenharmony_ci struct pci_bridge_emul_pcie_conf pcie_conf; 1158c2ecf20Sopenharmony_ci struct pci_bridge_emul_ops *ops; 1168c2ecf20Sopenharmony_ci struct pci_bridge_reg_behavior *pci_regs_behavior; 1178c2ecf20Sopenharmony_ci struct pci_bridge_reg_behavior *pcie_cap_regs_behavior; 1188c2ecf20Sopenharmony_ci void *data; 1198c2ecf20Sopenharmony_ci bool has_pcie; 1208c2ecf20Sopenharmony_ci}; 1218c2ecf20Sopenharmony_ci 1228c2ecf20Sopenharmony_cienum { 1238c2ecf20Sopenharmony_ci PCI_BRIDGE_EMUL_NO_PREFETCHABLE_BAR = BIT(0), 1248c2ecf20Sopenharmony_ci}; 1258c2ecf20Sopenharmony_ci 1268c2ecf20Sopenharmony_ciint pci_bridge_emul_init(struct pci_bridge_emul *bridge, 1278c2ecf20Sopenharmony_ci unsigned int flags); 1288c2ecf20Sopenharmony_civoid pci_bridge_emul_cleanup(struct pci_bridge_emul *bridge); 1298c2ecf20Sopenharmony_ci 1308c2ecf20Sopenharmony_ciint pci_bridge_emul_conf_read(struct pci_bridge_emul *bridge, int where, 1318c2ecf20Sopenharmony_ci int size, u32 *value); 1328c2ecf20Sopenharmony_ciint pci_bridge_emul_conf_write(struct pci_bridge_emul *bridge, int where, 1338c2ecf20Sopenharmony_ci int size, u32 value); 1348c2ecf20Sopenharmony_ci 1358c2ecf20Sopenharmony_ci#endif /* __PCI_BRIDGE_EMUL_H__ */ 136