1 /*
2  * This program is free software; you can redistribute it and/or modify
3  * it under the terms of the GNU General Public License version 2 as
4  * published by the Free Software Foundation.
5  *
6  * This program is distributed in the hope that it will be useful,
7  * but WITHOUT ANY WARRANTY; without even the implied warranty of
8  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
9  * GNU General Public License for more details.
10  *
11  * You should have received a copy of the GNU General Public License
12  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
13  */
14 
15 #ifndef __ARM_PCI_H__
16 #define __ARM_PCI_H__
17 
18 #ifdef CONFIG_HAS_PCI
19 
20 #include <asm/p2m.h>
21 #include <xen/err.h>
22 
23 #define pci_to_dev(pcidev) (&(pcidev)->arch.dev)
24 
25 extern bool pci_passthrough_enabled;
26 
27 struct rangeset;
28 
29 /* Arch pci dev struct */
30 struct arch_pci_dev {
31     struct device dev;
32 };
33 
34 /* Arch-specific MSI data for vPCI. */
35 struct vpci_arch_msi {
36 };
37 
38 /* Arch-specific MSI-X entry data for vPCI. */
39 struct vpci_arch_msix_entry {
40 };
41 
42 /*
43  * Because of the header cross-dependencies, e.g. we need both
44  * struct pci_dev and struct arch_pci_dev at the same time, this cannot be
45  * done with an inline here. Macro can be implemented, but looks scary.
46  */
47 struct pci_dev *dev_to_pci(struct device *dev);
48 
49 /*
50  * struct to hold the mappings of a config space window. This
51  * is expected to be used as sysdata for PCI controllers that
52  * use ECAM.
53  */
54 struct pci_config_window {
55     paddr_t         phys_addr;
56     paddr_t         size;
57     uint8_t         busn_start;
58     uint8_t         busn_end;
59     void __iomem    *win;
60 };
61 
62 /*
63  * struct to hold pci host bridge information
64  * for a PCI controller.
65  */
66 struct pci_host_bridge {
67     struct dt_device_node *dt_node;  /* Pointer to the associated DT node */
68     struct list_head node;           /* Node in list of host bridges */
69     uint16_t segment;                /* Segment number */
70     struct pci_config_window* cfg;   /* Pointer to the bridge config window */
71     const struct pci_ops *ops;
72     /* Child bus */
73     struct pci_config_window *child_cfg;
74     const struct pci_ops *child_ops;
75     void *priv;                      /* Private data of the bridge. */
76 };
77 
78 struct pci_ops {
79     void __iomem *(*map_bus)(struct pci_host_bridge *bridge, pci_sbdf_t sbdf,
80                              uint32_t offset);
81     int (*read)(struct pci_host_bridge *bridge, pci_sbdf_t sbdf,
82                 uint32_t reg, uint32_t len, uint32_t *value);
83     int (*write)(struct pci_host_bridge *bridge, pci_sbdf_t sbdf,
84                  uint32_t reg, uint32_t len, uint32_t value);
85     bool (*need_p2m_hwdom_mapping)(struct domain *d,
86                                    struct pci_host_bridge *bridge,
87                                    uint64_t addr);
88     void (*init_bus_range)(struct dt_device_node *dev,
89                            struct pci_host_bridge *bridge,
90                            struct pci_config_window *cfg);
91 };
92 
93 /*
94  * struct to hold pci ops and bus shift of the config window
95  * for a PCI controller.
96  */
97 struct pci_ecam_ops {
98     unsigned int            bus_shift;
99     struct pci_ops          pci_ops;
100     int (*cfg_reg_index)(struct dt_device_node *dev);
101     int (*init)(struct pci_config_window *);
102 };
103 
104 /* Default ECAM ops */
105 extern const struct pci_ecam_ops pci_generic_ecam_ops;
106 
107 struct pci_host_bridge *
108 pci_host_common_probe(struct dt_device_node *dev,
109                       const struct pci_ecam_ops *ops,
110                       const struct pci_ecam_ops *child_ops);
111 int pci_generic_config_read(struct pci_host_bridge *bridge, pci_sbdf_t sbdf,
112                             uint32_t reg, uint32_t len, uint32_t *value);
113 int pci_generic_config_write(struct pci_host_bridge *bridge, pci_sbdf_t sbdf,
114                              uint32_t reg, uint32_t len, uint32_t value);
115 void __iomem *pci_ecam_map_bus(struct pci_host_bridge *bridge,
116                                pci_sbdf_t sbdf, uint32_t where);
117 bool pci_ecam_need_p2m_hwdom_mapping(struct domain *d,
118                                      struct pci_host_bridge *bridge,
119                                      uint64_t addr);
120 struct pci_host_bridge *pci_find_host_bridge(uint16_t segment, uint8_t bus);
121 const struct dt_device_node *
122 pci_find_host_bridge_node(const struct pci_dev *pdev);
123 int pci_get_host_bridge_segment(const struct dt_device_node *node,
124                                 uint16_t *segment);
125 
is_pci_passthrough_enabled(void)126 static always_inline bool is_pci_passthrough_enabled(void)
127 {
128     return pci_passthrough_enabled;
129 }
130 
131 void arch_pci_init_pdev(struct pci_dev *pdev);
132 
133 int pci_get_new_domain_nr(void);
134 
135 int pci_host_iterate_bridges_and_count(struct domain *d,
136                                        int (*cb)(struct domain *d,
137                                                  struct pci_host_bridge *bridge));
138 
139 int pci_host_bridge_mappings(struct domain *d);
140 
141 bool pci_check_bar(const struct pci_dev *pdev, mfn_t start, mfn_t end);
142 
pci_sanitize_bar_memory(struct rangeset * r)143 static inline int pci_sanitize_bar_memory(struct rangeset *r)
144 { return 0; }
145 
146 void pci_generic_init_bus_range(struct dt_device_node *dev,
147                                 struct pci_host_bridge *bridge,
148                                 struct pci_config_window *cfg);
149 
150 void pci_generic_init_bus_range_child(struct dt_device_node *dev,
151                                       struct pci_host_bridge *bridge,
152                                       struct pci_config_window *cfg);
153 
154 bool arch_pci_device_physdevop(void);
155 
156 #else   /*!CONFIG_HAS_PCI*/
157 
158 struct pci_dev;
159 
arch_pci_init_pdev(struct pci_dev * pdev)160 static inline void arch_pci_init_pdev(struct pci_dev *pdev) {}
161 
pci_get_host_bridge_segment(const struct dt_device_node * node,uint16_t * segment)162 static inline int pci_get_host_bridge_segment(const struct dt_device_node *node,
163                                               uint16_t *segment)
164 {
165     ASSERT_UNREACHABLE();
166     return -EINVAL;
167 }
168 
pci_get_new_domain_nr(void)169 static inline int pci_get_new_domain_nr(void)
170 {
171     ASSERT_UNREACHABLE();
172     return -1;
173 }
174 
175 #endif  /*!CONFIG_HAS_PCI*/
176 #endif /* __ARM_PCI_H__ */
177