Helper for registering device IRQs
[akaros.git] / kern / arch / x86 / pci.h
1 /* Copyright (c) 2009, 2010 The Regents of the University of California
2  * See LICENSE for details.
3  *
4  * Barret Rhoden <brho@cs.berkeley.edu>
5  * Original by Paul Pearce <pearce@eecs.berkeley.edu> */
6
7 #ifndef ROS_ARCH_PCI_H
8 #define ROS_ARCH_PCI_H
9
10 #include <ros/common.h>
11 #include <sys/queue.h>
12
13 #define pci_debug(...)  printk(__VA_ARGS__)  
14
15 // Macro for creating the address fed to the PCI config register 
16 // TODO: get rid of this, in favor of the helpers
17 #define MK_CONFIG_ADDR(BUS, DEV, FUNC, REG) (unsigned long)(((BUS) << 16)   |  \
18                                                             ((DEV) << 11)   |  \
19                                                             ((FUNC) << 8)   |  \
20                                                             ((REG) & 0xfc)  |  \
21                                                             (0x80000000))
22
23 #define PCI_CONFIG_ADDR     0xCF8
24 #define PCI_CONFIG_DATA     0xCFC
25 #define INVALID_VENDOR_ID   0xFFFF
26
27 /* TODO: gut this (when the IOAPIC is fixed) */
28 #define INVALID_BUS                     0xFFFF
29
30 #define PCI_IRQLINE_MASK        0x000000ff
31 #define PCI_IRQPIN_MASK         0x0000ff00
32 #define PCI_IRQPIN_SHFT         8
33 #define PCI_VENDOR_MASK         0xffff
34 #define PCI_DEVICE_OFFSET       0x10
35
36 #define PCI_NOINT                       0x00
37 #define PCI_INTA                        0x01
38 #define PCI_INTB                        0x02
39 #define PCI_INTC                        0x03
40 #define PCI_INTD                        0x04
41
42 /* PCI Register Config Space */
43 #define PCI_DEV_VEND_REG        0x00
44 #define PCI_STAT_CMD_REG        0x04
45 #define PCI_CLASS_REG           0x08
46 #define PCI_HEADER_REG          0x0c
47 /* Config space for header type 0x00  (Standard) */
48 #define PCI_BAR0_STD            0x10
49 #define PCI_BAR1_STD            0x14
50 #define PCI_BAR2_STD            0x18
51 #define PCI_BAR3_STD            0x1c
52 #define PCI_BAR4_STD            0x20
53 #define PCI_BAR5_STD            0x24
54 #define PCI_BAR_OFF                     0x04
55 #define PCI_CARDBUS_STD         0x28
56 #define PCI_SUBSYSTEM_STD       0x2C
57 #define PCI_EXPROM_STD          0x30
58 #define PCI_CAPAB_STD           0x34
59 #define PCI_IRQ_STD                     0x3c
60 /* Config space for header type 0x01 (PCI-PCI bridge) */
61 #define PCI_BAR0_BR                     0x10
62 #define PCI_BAR1_BR                     0x14
63 #define PCI_BUSINFO_BR          0x18
64 #define PCI_IOINFO_BR           0x1c
65 #define PCI_MEM_BR                      0x20
66 #define PCI_MEM_PRFC_BR         0x24
67 #define PCI_PRFC_BASE_BR        0x28
68 #define PCI_PRFC_LIM_BR         0x2C
69 #define PCI_IO_LIM_BR           0x30
70 #define PCI_CAPAB_BR            0x34
71 #define PCI_IRQ_BDG_BR          0x3c
72 /* Config space for header type 0x02 (PCI-Cardbus bridge) */
73 #define PCI_SOC_BASE_CB         0x10
74 #define PCI_SEC_STAT_CB         0x14
75 #define PCI_BUS_INFO_CB         0x18
76 #define PCI_MEM_BASE0_CB        0x1c
77 #define PCI_MEM_LIMIT0_CB       0x20
78 #define PCI_MEM_BASE1_CB        0x24
79 #define PCI_MEM_LIMIT1_CB       0x28
80 #define PCI_IO_BASE0_CB         0x2c
81 #define PCI_IO_LIMIT0_CB        0x30
82 #define PCI_IO_BASE1_CB         0x34
83 #define PCI_IO_LIMIT1_CB        0x38
84 #define PCI_IRQ_CB                      0x3c
85 #define PCI_SUBSYS_CB           0x40
86 #define PCI_16BIT_CB            0x44
87
88 /* Legacy Paul-mapping */
89 #define PCI_IRQ_REG                     PCI_IRQ_STD
90
91 /* Command Register Flags */
92 #define PCI_CMD_IO_SPC          (1 << 0)
93 #define PCI_CMD_MEM_SPC         (1 << 1)
94 #define PCI_CMD_BUS_MAS         (1 << 2)
95 #define PCI_CMD_SPC_CYC         (1 << 3)
96 #define PCI_CMD_WR_EN           (1 << 4)
97 #define PCI_CMD_VGA                     (1 << 5)
98 #define PCI_CMD_PAR_ERR         (1 << 6)
99 /* #define PCI_CMD_XXX          (1 << 7) Reserved */
100 #define PCI_CMD_SERR            (1 << 8)
101 #define PCI_CMD_FAST_EN         (1 << 9)
102 #define PCI_CMD_IRQ_DIS         (1 << 10)
103
104 /* Status Register Flags (Bits 9 and 10 are one field) */
105 /* Bits 0, 1, and 2 are reserved */
106 #define PCI_ST_IRQ_STAT         (1 << 3)
107 #define PCI_ST_CAP_LIST         (1 << 4)
108 #define PCI_ST_66MHZ            (1 << 5)
109 /* #define PCI_CMD_XXX          (1 << 6)  Reserved */
110 #define PCI_ST_FAST_CAP         (1 << 7)
111 #define PCI_ST_MASPAR_ERR       (1 << 8)
112 #define PCI_ST_DEVSEL_TIM       (3 << 9)        /* 2 bits */
113 #define PCI_ST_SIG_TAR_ABRT     (1 << 11)
114 #define PCI_ST_REC_TAR_ABRT     (1 << 12)
115 #define PCI_ST_REC_MAS_ABRT     (1 << 13)
116 #define PCI_ST_SIG_SYS_ERR      (1 << 14)
117 #define PCI_ST_PAR_ERR          (1 << 15)
118
119 /* BARS: Base Address Registers */
120 #define PCI_BAR_IO                      0x1                     /* 1 == IO, 0 == Mem */
121 #define PCI_BAR_IO_MASK         0xfffffffc
122 #define PCI_BAR_MEM_MASK        0xfffffff0
123 #define PCI_MEMBAR_TYPE         (3 << 1)
124 #define PCI_MEMBAR_32BIT        0x0
125 #define PCI_MEMBAR_RESV         0x2                     /* type 0x1 shifted to MEMBAR_TYPE */
126 #define PCI_MEMBAR_64BIT        0x4                     /* type 0x2 shifted to MEMBAR_TYPE */
127
128 #define PCI_MAX_BUS                     256
129 #define PCI_MAX_DEV                     32
130 #define PCI_MAX_FUNC            8
131
132 // Run the PCI Code to loop over the PCI BARs. For now we don't use the BARs,
133 // dont check em.
134 #define CHECK_BARS                      0
135
136 #define MAX_PCI_BAR                     6
137
138 struct pci_bar {
139         uint32_t                                        raw_bar;
140         uint32_t                                        pio_base;
141         uint32_t                                        mmio_base32;
142         uint64_t                                        mmio_base64;
143         uint32_t                                        mmio_sz;
144 };
145
146 /* Struct for some meager contents of a PCI device */
147 struct pci_device {
148         STAILQ_ENTRY(pci_device)        all_dev;        /* list of all devices */
149         SLIST_ENTRY(pci_device)         irq_dev;        /* list of all devs off an irq */
150         bool                                            in_use;         /* prevent double discovery */
151         uint8_t                                         bus;
152         uint8_t                                         dev;
153         uint8_t                                         func;
154         uint16_t                                        dev_id;
155         uint16_t                                        ven_id;
156         uint8_t                                         irqline;
157         uint8_t                                         irqpin;
158         char                                            *header_type;
159         uint8_t                                         class;
160         uint8_t                                         subclass;
161         uint8_t                                         progif;
162         uint8_t                                         nr_bars;
163         struct pci_bar                          bar[MAX_PCI_BAR];
164 };
165
166 /* List of all discovered devices */
167 STAILQ_HEAD(pcidev_stailq, pci_device);
168 SLIST_HEAD(pcidev_slist, pci_device);
169 extern struct pcidev_stailq pci_devices;
170
171 void pci_init(void);
172 void pcidev_print_info(struct pci_device *pcidev, int verbosity);
173
174 /* Read and write helpers (Eventually, we should have these be statics, since no
175  * device should touch PCI config space). */
176 uint32_t pci_read32(unsigned short bus, unsigned short dev, unsigned short func,
177                     unsigned short offset);
178 void pci_write32(unsigned short bus, unsigned short dev, unsigned short func,
179                     unsigned short offset, uint32_t value);
180 uint32_t pcidev_read32(struct pci_device *pcidev, unsigned short offset);
181 void pcidev_write32(struct pci_device *pcidev, unsigned short offset,
182                     uint32_t value);
183
184 /* BAR helpers, some more helpful than others. */
185 uint32_t pci_membar_get_sz(struct pci_device *pcidev, int bar);
186 uint32_t pci_getbar(struct pci_device *pcidev, unsigned int bar);
187 bool pci_is_iobar(uint32_t bar);
188 bool pci_is_membar32(uint32_t bar);
189 bool pci_is_membar64(uint32_t bar);
190 uint32_t pci_getmembar32(uint32_t bar);
191 uint32_t pci_getiobar32(uint32_t bar);
192
193 #endif /* ROS_ARCH_PCI_H */