/* Precise PHB model for error management */ enum pnv_phb_model {
PNV_PHB_MODEL_UNKNOWN,
PNV_PHB_MODEL_P7IOC,
PNV_PHB_MODEL_PHB3,
};
#define PNV_PCI_DIAG_BUF_SIZE 8192 #define PNV_IODA_PE_DEV (1 << 0) /* PE has single PCI device */ #define PNV_IODA_PE_BUS (1 << 1) /* PE has primary PCI bus */ #define PNV_IODA_PE_BUS_ALL (1 << 2) /* PE has subordinate buses */ #define PNV_IODA_PE_MASTER (1 << 3) /* Master PE in compound case */ #define PNV_IODA_PE_SLAVE (1 << 4) /* Slave PE in compound case */ #define PNV_IODA_PE_VF (1 << 5) /* PE for one VF */
/* * A brief note on PNV_IODA_PE_BUS_ALL * * This is needed because of the behaviour of PCIe-to-PCI bridges. The PHB uses * the Requester ID field of the PCIe request header to determine the device * (and PE) that initiated a DMA. In legacy PCI individual memory read/write * requests aren't tagged with the RID. To work around this the PCIe-to-PCI * bridge will use (secondary_bus_no << 8) | 0x00 as the RID on the PCIe side. * * PCIe-to-X bridges have a similar issue even though PCI-X requests also have * a RID in the transaction header. The PCIe-to-X bridge is permitted to "take * ownership" of a transaction by a PCI-X device when forwarding it to the PCIe * side of the bridge. * * To work around these problems we use the BUS_ALL flag since every subordinate * bus of the bridge should go into the same PE.
*/
/* Indicates operations are frozen for a PE: MMIO in PESTA & DMA in PESTB. */ #define PNV_IODA_STOPPED_STATE 0x8000000000000000
/* Data associated with a PE, including IOMMU tracking etc.. */ struct pnv_phb; struct pnv_ioda_pe { unsignedlong flags; struct pnv_phb *phb; int device_count;
/* A PE can be associated with a single device or an * entire bus (& children). In the former case, pdev * is populated, in the later case, pbus is.
*/ #ifdef CONFIG_PCI_IOV struct pci_dev *parent_dev; #endif struct pci_dev *pdev; struct pci_bus *pbus;
/* Effective RID (device RID for a device PE and base bus * RID with devfn 0 for a bus PE)
*/ unsignedint rid;
/* 64-bit TCE bypass region */ bool tce_bypass_enabled;
uint64_t tce_bypass_base;
/* * Used to track whether we've done DMA setup for this PE or not. We * want to defer allocating TCE tables, etc until we've added a * non-bridge device to the PE.
*/ bool dma_setup_done;
/* MSIs. MVE index is identical for 32 and 64 bit MSI * and -1 if not supported. (It's actually identical to the * PE number)
*/ int mve_number;
/* PEs in compound case */ struct pnv_ioda_pe *master; struct list_head slaves;
/* Link in list of PE#s */ struct list_head list;
};
#ifdef CONFIG_DEBUG_FS int has_dbgfs; struct dentry *dbgfs; #endif
unsignedint msi_base; struct msi_bitmap msi_bmp; int (*init_m64)(struct pnv_phb *phb); int (*get_pe_state)(struct pnv_phb *phb, int pe_no); void (*freeze_pe)(struct pnv_phb *phb, int pe_no); int (*unfreeze_pe)(struct pnv_phb *phb, int pe_no, int opt);
struct { /* Global bridge info */ unsignedint total_pe_num; unsignedint reserved_pe_idx; unsignedint root_pe_idx;
staticinlinebool pnv_pci_is_m64(struct pnv_phb *phb, struct resource *r)
{ /* * WARNING: We cannot rely on the resource flags. The Linux PCI * allocation code sometimes decides to put a 64-bit prefetchable * BAR in the 32-bit window, so we have to compare the addresses. * * For simplicity we only test resource start.
*/ return (r->start >= phb->ioda.m64_base &&
r->start < (phb->ioda.m64_base + phb->ioda.m64_size));
}
#ifdef CONFIG_PCI_IOV /* * For SR-IOV we want to put each VF's MMIO resource in to a separate PE. * This requires a bit of acrobatics with the MMIO -> PE configuration * and this structure is used to keep track of it all.
*/ struct pnv_iov_data { /* number of VFs enabled */
u16 num_vfs;
/* pointer to the array of VF PEs. num_vfs long*/ struct pnv_ioda_pe *vf_pe_arr;
/* Did we map the VF BAR with single-PE IODA BARs? */ bool m64_single_mode[PCI_SRIOV_NUM_BARS];
/* * True if we're using any segmented windows. In that case we need * shift the start of the IOV resource the segment corresponding to * the allocated PE.
*/ bool need_shift;
/* * Bit mask used to track which m64 windows are used to map the * SR-IOV BARs for this device.
*/
DECLARE_BITMAP(used_m64_bar_mask, MAX_M64_BARS);
/* * If we map the SR-IOV BARs with a segmented window then * parts of that window will be "claimed" by other PEs. * * "holes" here is used to reserve the leading portion * of the window that is used by other (non VF) PEs.
*/ struct resource holes[PCI_SRIOV_NUM_BARS];
};
void pnv_pci_ioda_fixup_iov(struct pci_dev *pdev);
resource_size_t pnv_pci_iov_resource_alignment(struct pci_dev *pdev, int resno);
int pnv_pcibios_sriov_enable(struct pci_dev *pdev, u16 num_vfs); int pnv_pcibios_sriov_disable(struct pci_dev *pdev); #endif/* CONFIG_PCI_IOV */
externstruct pci_ops pnv_pci_ops;
void pnv_pci_dump_phb_diag_data(struct pci_controller *hose, unsignedchar *log_buff); int pnv_pci_cfg_read(struct pci_dn *pdn, int where, int size, u32 *val); int pnv_pci_cfg_write(struct pci_dn *pdn, int where, int size, u32 val); externstruct iommu_table *pnv_pci_table_alloc(int nid);
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.