2018-10-18 18:37:16 +03:00
/* SPDX-License-Identifier: GPL-2.0 */
# ifndef __PCI_BRIDGE_EMUL_H__
# define __PCI_BRIDGE_EMUL_H__
# include <linux/kernel.h>
/* PCI configuration space of a PCI-to-PCI bridge. */
struct pci_bridge_emul_conf {
2019-07-16 15:13:46 +03:00
__le16 vendor ;
__le16 device ;
__le16 command ;
__le16 status ;
__le32 class_revision ;
2018-10-18 18:37:16 +03:00
u8 cache_line_size ;
u8 latency_timer ;
u8 header_type ;
u8 bist ;
2019-07-16 15:13:46 +03:00
__le32 bar [ 2 ] ;
2018-10-18 18:37:16 +03:00
u8 primary_bus ;
u8 secondary_bus ;
u8 subordinate_bus ;
u8 secondary_latency_timer ;
u8 iobase ;
u8 iolimit ;
2019-07-16 15:13:46 +03:00
__le16 secondary_status ;
__le16 membase ;
__le16 memlimit ;
__le16 pref_mem_base ;
__le16 pref_mem_limit ;
__le32 prefbaseupper ;
__le32 preflimitupper ;
__le16 iobaseupper ;
__le16 iolimitupper ;
2018-10-18 18:37:16 +03:00
u8 capabilities_pointer ;
u8 reserve [ 3 ] ;
2019-07-16 15:13:46 +03:00
__le32 romaddr ;
2018-10-18 18:37:16 +03:00
u8 intline ;
u8 intpin ;
2019-07-16 15:13:46 +03:00
__le16 bridgectrl ;
2018-10-18 18:37:16 +03:00
} ;
/* PCI configuration space of the PCIe capabilities */
struct pci_bridge_emul_pcie_conf {
u8 cap_id ;
u8 next ;
2019-07-16 15:13:46 +03:00
__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 ;
2018-10-18 18:37:16 +03:00
} ;
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 ) ;
} ;
2019-02-20 12:48:40 +03:00
struct pci_bridge_reg_behavior ;
2018-10-18 18:37:16 +03:00
struct pci_bridge_emul {
struct pci_bridge_emul_conf conf ;
struct pci_bridge_emul_pcie_conf pcie_conf ;
struct pci_bridge_emul_ops * ops ;
2019-02-20 12:48:40 +03:00
struct pci_bridge_reg_behavior * pci_regs_behavior ;
struct pci_bridge_reg_behavior * pcie_cap_regs_behavior ;
2018-10-18 18:37:16 +03:00
void * data ;
bool has_pcie ;
} ;
2019-02-20 12:48:41 +03:00
enum {
PCI_BRIDGE_EMUL_NO_PREFETCHABLE_BAR = BIT ( 0 ) ,
} ;
int pci_bridge_emul_init ( struct pci_bridge_emul * bridge ,
unsigned int flags ) ;
2019-02-20 12:48:40 +03:00
void pci_bridge_emul_cleanup ( struct pci_bridge_emul * bridge ) ;
2018-10-18 18:37:16 +03:00
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__ */