1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19#if !defined(__HW_SPAPR_H__)
20#error Please include spapr.h before this file!
21#endif
22
23#if !defined(__HW_SPAPR_PCI_H__)
24#define __HW_SPAPR_PCI_H__
25
26#include "hw/pci/pci.h"
27#include "hw/pci/pci_host.h"
28#include "hw/ppc/xics.h"
29
30#define SPAPR_MSIX_MAX_DEVS 32
31
32#define TYPE_SPAPR_PCI_HOST_BRIDGE "spapr-pci-host-bridge"
33
34#define SPAPR_PCI_HOST_BRIDGE(obj) \
35 OBJECT_CHECK(sPAPRPHBState, (obj), TYPE_SPAPR_PCI_HOST_BRIDGE)
36
37typedef struct sPAPRPHBState {
38 PCIHostState parent_obj;
39
40 int32_t index;
41 uint64_t buid;
42 char *dtbusname;
43
44 MemoryRegion memspace, iospace;
45 hwaddr mem_win_addr, mem_win_size, io_win_addr, io_win_size;
46 MemoryRegion memwindow, iowindow;
47
48 uint32_t dma_liobn;
49 uint64_t dma_window_start;
50 uint64_t dma_window_size;
51 sPAPRTCETable *tcet;
52 AddressSpace iommu_as;
53
54 struct spapr_pci_lsi {
55 uint32_t irq;
56 } lsi_table[PCI_NUM_PINS];
57
58 struct spapr_pci_msi {
59 uint32_t config_addr;
60 uint32_t irq;
61 uint32_t nvec;
62 } msi_table[SPAPR_MSIX_MAX_DEVS];
63
64 QLIST_ENTRY(sPAPRPHBState) list;
65} sPAPRPHBState;
66
67#define SPAPR_PCI_BASE_BUID 0x800000020000000ULL
68
69#define SPAPR_PCI_WINDOW_BASE 0x10000000000ULL
70#define SPAPR_PCI_WINDOW_SPACING 0x1000000000ULL
71#define SPAPR_PCI_MMIO_WIN_OFF 0xA0000000
72#define SPAPR_PCI_MMIO_WIN_SIZE 0x20000000
73#define SPAPR_PCI_IO_WIN_OFF 0x80000000
74#define SPAPR_PCI_IO_WIN_SIZE 0x10000
75
76#define SPAPR_PCI_MSI_WINDOW 0x40000000000ULL
77
78#define SPAPR_PCI_MEM_WIN_BUS_OFFSET 0x80000000ULL
79
80static inline qemu_irq spapr_phb_lsi_qirq(struct sPAPRPHBState *phb, int pin)
81{
82 return xics_get_qirq(spapr->icp, phb->lsi_table[pin].irq);
83}
84
85PCIHostState *spapr_create_phb(sPAPREnvironment *spapr, int index);
86
87int spapr_populate_pci_dt(sPAPRPHBState *phb,
88 uint32_t xics_phandle,
89 void *fdt);
90
91void spapr_pci_msi_init(sPAPREnvironment *spapr, hwaddr addr);
92
93void spapr_pci_rtas_init(void);
94
95#endif
96