1/**
2 * \file
3 * \brief PCI configuration library.
4 */
5
6/*
7 * Copyright (c) 2007, 2008, 2009, ETH Zurich.
8 * All rights reserved.
9 *
10 * This file is distributed under the terms in the attached LICENSE file.
11 * If you do not find this file, copies can be found by writing to:
12 * ETH Zurich D-INFK, Haldeneggsteig 4, CH-8092 Zurich. Attn: Systems Group.
13 */
14
15#ifndef PCI_H
16#define PCI_H
17
18#include <barrelfish/inthandler.h>
19#include <pci/mem.h>
20#include <pci/devids.h>
21#include <pci/pci_types.h>
22
23/**
24 * Kaluga passes a CNode with capabilities to the pci driver. The offset
25 * in this CNode are defined here
26 */
27#define PCIARG_SLOT_INT    0
28#define PCIARG_SLOT_PCI_EP 1
29#define PCIARG_SLOT_BAR0   2
30#define PCIARG_SLOT_BAR1   3
31#define PCIARG_SLOT_BAR2   4
32#define PCIARG_SLOT_BAR3   5
33#define PCIARG_SLOT_BAR4   6
34#define PCIARG_SLOT_BAR5   7
35#define PCIARG_SLOT_BAR6   8
36
37
38typedef void (*pci_driver_init_fn)(void *user_state, struct device_mem *bar_info,
39                                   int nr_mapped_bars);
40typedef void (*legacy_driver_init_fn)(void);
41
42
43errval_t pci_get_bar_caps_for_device(
44        struct pci_addr addr,
45        struct device_mem **bars_out,
46        size_t *bars_len
47        );
48
49errval_t pci_parse_int_arg(int argc, char ** argv);
50
51errval_t pci_reregister_irq_for_device(uint32_t class, uint32_t subclass, uint32_t prog_if,
52                                       uint32_t vendor, uint32_t device,
53                                       uint32_t bus, uint32_t dev, uint32_t fun,
54                                       interrupt_handler_fn handler,
55                                       void *handler_arg,
56                                       interrupt_handler_fn reloc_handler,
57                                       void *reloc_handler_arg);
58
59errval_t pci_register_driver_noirq(pci_driver_init_fn init_func,
60                                   void *user_state, uint32_t class,
61                                   uint32_t subclass, uint32_t prog_if,
62                                   uint32_t vendor, uint32_t device,
63                                   uint32_t bus, uint32_t dev, uint32_t fun);
64
65errval_t pci_register_driver_movable_irq(pci_driver_init_fn init_func,
66                                         void *user_state, uint32_t class,
67                                         uint32_t subclass, uint32_t prog_if,
68                                         uint32_t vendor, uint32_t device,
69                                         uint32_t bus, uint32_t dev, uint32_t fun,
70                                         interrupt_handler_fn handler,
71                                         void *handler_arg,
72                                         interrupt_handler_fn reloc_handler,
73                                         void *reloc_handler_arg);
74
75errval_t pci_register_driver_irq(pci_driver_init_fn init_func,
76                                 void *user_state, uint32_t class,
77                                 uint32_t subclass, uint32_t prog_if,
78                                 uint32_t vendor, uint32_t device,
79                                 uint32_t bus, uint32_t dev, uint32_t fun,
80                                 interrupt_handler_fn handler, void *handler_arg);
81
82/**
83 * Setup interrupt routing manually. If interrupt handler
84 * function is passed to register_driver it will be called called from there.
85 * Use this in your init function (or any later point) if you want to:
86 *  * MSIx
87 *  * Unusual interrupt routing.
88 *  * Activate interrupts later
89 */
90errval_t pci_setup_int_routing(int irq_idx, interrupt_handler_fn handler,
91                                         void *handler_arg,
92                                         interrupt_handler_fn reloc_handler,
93                                         void *reloc_handler_arg);
94
95/**
96 * Deprecated. Use pci_register_legacy_driver_irq_cap.
97 */
98errval_t pci_register_legacy_driver_irq(legacy_driver_init_fn init_func,
99                                        uint16_t iomin, uint16_t iomax, int irq,
100                                        interrupt_handler_fn handler,
101                                        void *handler_arg);
102
103/**
104 * Register a legacy device driver. The driver can specify a range of IO ports
105 * that he wants to access.
106 *
107 * @param init_func          Callback function that will be called once pci_client is initialized.
108 * @param iomin              I/O range minimum
109 * @param iomax              I/O range maximum
110 * @param irq_idx            Interrupt cap index
111 * @param interrupt_handler  The handler function when a interrupt is triggered.
112 * @param handler_arg        Argument for interrupt_handler
113 *
114 */
115errval_t pci_register_legacy_driver_irq_cap(legacy_driver_init_fn init_func,
116                                        uint16_t iomin, uint16_t iomax, int irq_idx,
117                                        interrupt_handler_fn handler,
118                                        void *handler_arg);
119
120errval_t pci_setup_inthandler(interrupt_handler_fn handler, void *handler_arg,
121                              uint8_t *ret_vector);
122
123
124errval_t pci_read_conf_header(uint32_t dword, uint32_t *val);
125
126errval_t pci_write_conf_header(uint32_t dword, uint32_t val);
127
128errval_t pci_client_connect(void);
129
130
131/**
132 * Enable MSI-X for the PCI device
133 * @param count Memory location where the number of supported vectors is written
134 */
135errval_t pci_msix_enable(uint16_t *count);
136
137/**
138 * \brief enables MSI-X interupts for a given device
139 *
140 * \param addr  PCI address of the device to activate or NULL if don't care
141 * \param count returns the number of supported MSI-X interrupts
142 *
143 * \returns SYS_ERR_OK on success
144 *          errval on FAILURE
145 */
146errval_t pci_msix_enable_addr(struct pci_addr *addr, uint16_t *count);
147
148/**
149 * Configure an MSI-X vector
150 * @param index       MSI-X Vector index
151 * @param destination Destination APIC where the interrupt should be sent
152 * @param vector      Interrupt vector to send
153 */
154errval_t pci_msix_vector_init(uint16_t index, uint8_t destination,
155                              uint8_t vector);
156/**
157 * Configure an MSI-X vector
158 * \param addr  PCI address of the device to activate or NULL if don't care
159 * \param index       MSI-X Vector index
160 * \param destination Destination APIC where the interrupt should be sent
161 * \param vector      Interrupt vector to send
162 */
163errval_t pci_msix_vector_init_addr(struct pci_addr *addr, uint16_t index,
164                                   uint8_t destination, uint8_t vector);
165
166errval_t pci_setup_int_routing_with_cap(int irq_idx,
167                                        struct capref irq_src_cap,
168                                        interrupt_handler_fn handler,
169                                        void *handler_arg,
170                                        interrupt_handler_fn reloc_handler,
171                                        void *reloc_handler_arg);
172
173#endif
174