1/*
2 * Copyright 2017, Data61
3 * Commonwealth Scientific and Industrial Research Organisation (CSIRO)
4 * ABN 41 687 119 230.
5 *
6 * This software may be distributed and modified according to the terms of
7 * the BSD 2-Clause license. Note that NO WARRANTY is provided.
8 * See "LICENSE_BSD2.txt" for details.
9 *
10 * @TAG(DATA61_BSD)
11 */
12#pragma once
13
14#include <assert.h>
15#include <stdio.h>
16#include <stdint.h>
17#include <pci/pci_config.h>
18#include <platsupport/io.h>
19
20#define PCI_CONF_PORT_ADDR     0x0CF8
21#define PCI_CONF_PORT_DATA     0x0CFC
22#define PCI_CONF_PORT_ADDR_END (PCI_CONF_PORT_ADDR + 4)
23#define PCI_CONF_PORT_DATA_END (PCI_CONF_PORT_DATA + 4)
24#define PCI_MAX_DEVICES 128
25
26/* Structure containing information about a device. When a device is found during scanning,
27 * one of these structs is populated from the information read off the device. */
28typedef struct libpci_device {
29    uint8_t bus;
30    uint8_t dev;
31    uint8_t fun;
32
33    uint16_t vendor_id;
34    uint16_t device_id;
35    uint16_t subsystem_id;
36    uint8_t interrupt_pin;
37    uint8_t interrupt_line;
38
39    const char* vendor_name;
40    const char* device_name;
41    libpci_device_iocfg_t cfg;
42} libpci_device_t;
43
44uint32_t libpci_ioread(uint32_t port_no, uint32_t* val, uint32_t size);
45uint32_t libpci_iowrite(uint32_t port_no, uint32_t val, uint32_t size);
46
47/* The global list of devices that have been found in the last PCI scan. */
48extern libpci_device_t libpci_device_list[PCI_MAX_DEVICES];
49extern uint32_t libpci_num_devices;
50
51/* Return the first device found matching given vendor and device ID. */
52libpci_device_t* libpci_find_device(uint16_t vendor_id, uint16_t device_id);
53
54/* Return an array of all devices found matching vendor and device ID. The out parameter should
55 * be of at least size PCI_MAX_DEVICES to be safe. */
56int libpci_find_device_all(uint16_t vendor_id, uint16_t device_id, libpci_device_t** out);
57
58/* Return the first device matching the bus, dev, fun, vendor and device id of given device struct. */
59libpci_device_t* libpci_find_device_matching(libpci_device_t *device);
60
61/* Return a device, if one exists, on the given bus, dev and fun */
62libpci_device_t* libpci_find_device_bdf(uint8_t bus, uint8_t dev, uint8_t fun);
63
64/* Scan the entire PCI space, find every device and popular device structures. */
65void libpci_scan(ps_io_port_ops_t port_ops);
66
67/* Read base addr info from give device, and populate a base addr info structure. */
68void libpci_read_ioconfig(libpci_device_iocfg_t *cfg, uint8_t bus, uint8_t dev, uint8_t fun);
69