blob: 7760d2123a44c213a5f5481e46347efa7fcaf248 [file] [log] [blame]
Kevin O'Connorfaa8b6f2008-03-21 13:32:34 -04001#ifndef __PCI_H
2#define __PCI_H
3
Kevin O'Connora0dc2962008-03-16 14:29:32 -04004#include "types.h" // u32
Kevin O'Connorb98a4b12013-06-08 21:53:36 -04005#include "list.h" // hlist_node
Kevin O'Connora0dc2962008-03-16 14:29:32 -04006
Gerd Hoffmann82b39b22011-07-11 09:20:28 +02007#define PCI_ROM_SLOT 6
8#define PCI_NUM_REGIONS 7
Alexey Korolev1a9f47f2012-04-19 17:40:13 +12009#define PCI_BRIDGE_NUM_REGIONS 2
Gerd Hoffmann82b39b22011-07-11 09:20:28 +020010
Kevin O'Connor5fdaa032008-08-31 11:06:27 -040011static inline u8 pci_bdf_to_bus(u16 bdf) {
12 return bdf >> 8;
13}
Kevin O'Connorbe19cdc2008-11-09 15:33:47 -050014static inline u8 pci_bdf_to_devfn(u16 bdf) {
15 return bdf & 0xff;
16}
Kevin O'Connorb5bb9db2010-01-03 15:14:11 -050017static inline u16 pci_bdf_to_busdev(u16 bdf) {
18 return bdf & ~0x07;
19}
Kevin O'Connor5fdaa032008-08-31 11:06:27 -040020static inline u8 pci_bdf_to_dev(u16 bdf) {
21 return (bdf >> 3) & 0x1f;
22}
23static inline u8 pci_bdf_to_fn(u16 bdf) {
24 return bdf & 0x07;
25}
Kevin O'Connor423a04d2009-02-05 21:16:39 -050026static inline u16 pci_to_bdf(int bus, int dev, int fn) {
27 return (bus<<8) | (dev<<3) | fn;
28}
Isaku Yamahataedd99112010-06-22 17:57:46 +090029static inline u16 pci_bus_devfn_to_bdf(int bus, u16 devfn) {
30 return (bus << 8) | devfn;
31}
Kevin O'Connor0f803e42008-05-24 23:07:16 -040032
Kevin O'Connorbe19cdc2008-11-09 15:33:47 -050033void pci_config_writel(u16 bdf, u32 addr, u32 val);
34void pci_config_writew(u16 bdf, u32 addr, u16 val);
35void pci_config_writeb(u16 bdf, u32 addr, u8 val);
36u32 pci_config_readl(u16 bdf, u32 addr);
37u16 pci_config_readw(u16 bdf, u32 addr);
38u8 pci_config_readb(u16 bdf, u32 addr);
Kevin O'Connor59f02832009-10-12 10:09:15 -040039void pci_config_maskw(u16 bdf, u32 addr, u16 off, u16 on);
Kevin O'Connor0f803e42008-05-24 23:07:16 -040040
Kevin O'Connor0cd70052011-07-02 14:04:19 -040041struct pci_device *pci_find_device(u16 vendid, u16 devid);
42struct pci_device *pci_find_class(u16 classid);
Kevin O'Connorbe19cdc2008-11-09 15:33:47 -050043
Kevin O'Connor096a9b12011-06-19 14:09:20 -040044struct pci_device {
45 u16 bdf;
46 u8 rootbus;
Kevin O'Connorb98a4b12013-06-08 21:53:36 -040047 struct hlist_node node;
Kevin O'Connor096a9b12011-06-19 14:09:20 -040048 struct pci_device *parent;
49
50 // Configuration space device information
51 u16 vendor, device;
52 u16 class;
53 u8 prog_if, revision;
54 u8 header_type;
55 u8 secondary_bus;
Kevin O'Connor76b5e712011-06-21 22:52:51 -040056
57 // Local information on device.
58 int have_driver;
Kevin O'Connor096a9b12011-06-19 14:09:20 -040059};
Gerd Hoffmanne55c4e82012-06-07 10:34:32 +020060extern u64 pcimem_start, pcimem_end;
61extern u64 pcimem64_start, pcimem64_end;
Kevin O'Connorb98a4b12013-06-08 21:53:36 -040062extern struct hlist_head PCIDevices;
Kevin O'Connor096a9b12011-06-19 14:09:20 -040063extern int MaxPCIBus;
Jan Kiszka58e6b3f2011-09-21 08:16:21 +020064int pci_probe_host(void);
65void pci_probe_devices(void);
Kevin O'Connor9931bcc2011-06-20 22:23:02 -040066static inline u32 pci_classprog(struct pci_device *pci) {
67 return (pci->class << 8) | pci->prog_if;
68}
Kevin O'Connor096a9b12011-06-19 14:09:20 -040069
Kevin O'Connorb98a4b12013-06-08 21:53:36 -040070#define foreachpci(PCI) \
71 hlist_for_each_entry(PCI, &PCIDevices, node)
Kevin O'Connor096a9b12011-06-19 14:09:20 -040072
Kevin O'Connor2b333e42011-07-02 14:49:41 -040073int pci_next(int bdf, int bus);
74#define foreachbdf(BDF, BUS) \
75 for (BDF=pci_next(pci_bus_devfn_to_bdf((BUS), 0)-1, (BUS)) \
76 ; BDF >= 0 \
77 ; BDF=pci_next(BDF, (BUS)))
Isaku Yamahataedd99112010-06-22 17:57:46 +090078
Isaku Yamahata968d3a82010-07-07 12:14:01 +090079#define PCI_ANY_ID (~0)
80struct pci_device_id {
81 u32 vendid;
82 u32 devid;
83 u32 class;
84 u32 class_mask;
Kevin O'Connor278b19f2011-06-21 22:41:15 -040085 void (*func)(struct pci_device *pci, void *arg);
Isaku Yamahata968d3a82010-07-07 12:14:01 +090086};
87
88#define PCI_DEVICE(vendor_id, device_id, init_func) \
89 { \
90 .vendid = (vendor_id), \
91 .devid = (device_id), \
92 .class = PCI_ANY_ID, \
93 .class_mask = 0, \
94 .func = (init_func) \
95 }
96
97#define PCI_DEVICE_CLASS(vendor_id, device_id, class_code, init_func) \
98 { \
99 .vendid = (vendor_id), \
100 .devid = (device_id), \
101 .class = (class_code), \
102 .class_mask = ~0, \
103 .func = (init_func) \
104 }
105
106#define PCI_DEVICE_END \
107 { \
108 .vendid = 0, \
109 }
110
Kevin O'Connor278b19f2011-06-21 22:41:15 -0400111int pci_init_device(const struct pci_device_id *ids
112 , struct pci_device *pci, void *arg);
113struct pci_device *pci_find_init_device(const struct pci_device_id *ids
114 , void *arg);
Kevin O'Connoradaf3732010-09-13 20:22:07 -0400115void pci_reboot(void);
Isaku Yamahata968d3a82010-07-07 12:14:01 +0900116
Gerd Hoffmannf1f18eb2010-11-29 09:42:10 +0100117// helper functions to access pci mmio bars from real mode
118u32 pci_readl(u32 addr);
119void pci_writel(u32 addr, u32 val);
120
Kevin O'Connord25810a2008-06-12 22:16:35 -0400121// pirtable.c
Kevin O'Connord83c87b2013-01-21 01:14:12 -0500122void pirtable_setup(void);
Kevin O'Connord25810a2008-06-12 22:16:35 -0400123
Kevin O'Connor061d1372008-06-11 22:39:46 -0400124
125/****************************************************************
126 * PIR table
127 ****************************************************************/
128
Kevin O'Connor061d1372008-06-11 22:39:46 -0400129struct link_info {
130 u8 link;
131 u16 bitmap;
132} PACKED;
133
134struct pir_slot {
135 u8 bus;
136 u8 dev;
137 struct link_info links[4];
138 u8 slot_nr;
139 u8 reserved;
140} PACKED;
141
Kevin O'Connord25810a2008-06-12 22:16:35 -0400142struct pir_header {
143 u32 signature;
144 u16 version;
145 u16 size;
146 u8 router_bus;
147 u8 router_devfunc;
148 u16 exclusive_irqs;
149 u32 compatible_devid;
150 u32 miniport_data;
151 u8 reserved[11];
152 u8 checksum;
153 struct pir_slot slots[0];
154} PACKED;
155
Kevin O'Connorbfa02cd2012-06-09 13:36:45 -0400156extern struct pir_header *PirAddr;
157
Kevin O'Connord25810a2008-06-12 22:16:35 -0400158#define PIR_SIGNATURE 0x52495024 // $PIR
159
Kevin O'Connor061d1372008-06-11 22:39:46 -0400160
Kevin O'Connorfaa8b6f2008-03-21 13:32:34 -0400161#endif