1 /*
2  * Copyright (c) 2021 Travis Geiselbrecht
3  *
4  * Use of this source code is governed by a MIT-style
5  * license that can be found in the LICENSE file or at
6  * https://opensource.org/licenses/MIT
7  */
8 #pragma once
9 
10 #include <stdint.h>
11 #include <lk/compiler.h>
12 #include <lk/cpp.h>
13 #include <lk/err.h>
14 #include <dev/bus/pci.h>
15 
16 // Default implementation of a particular PCI bus/config accessor method.
17 // Intended to be subclassed and specialized based on specific method.
18 
19 class pci_backend {
20 public:
21     constexpr pci_backend() = default;
22     virtual ~pci_backend() = default;
23 
24     DISALLOW_COPY_ASSIGN_AND_MOVE(pci_backend);
25 
26 public:
get_last_bus()27     int get_last_bus() const { return last_bus_; }
28 
29     // virtuals that a concrete implementation should override
find_pci_device(pci_location_t * state,uint16_t device_id,uint16_t vendor_id,uint16_t index)30     virtual int find_pci_device(pci_location_t *state, uint16_t device_id, uint16_t vendor_id, uint16_t index) {
31         return ERR_NOT_CONFIGURED;
32     }
33 
find_pci_class_code(pci_location_t * state,uint32_t class_code,uint16_t index)34     virtual int find_pci_class_code(pci_location_t *state, uint32_t class_code, uint16_t index) {
35         return ERR_NOT_CONFIGURED;
36     }
37 
read_config_byte(const pci_location_t * state,uint32_t reg,uint8_t * value)38     virtual int read_config_byte(const pci_location_t *state, uint32_t reg, uint8_t *value) {
39         return ERR_NOT_CONFIGURED;
40     }
read_config_half(const pci_location_t * state,uint32_t reg,uint16_t * value)41     virtual int read_config_half(const pci_location_t *state, uint32_t reg, uint16_t *value) {
42         return ERR_NOT_CONFIGURED;
43     }
read_config_word(const pci_location_t * state,uint32_t reg,uint32_t * value)44     virtual int read_config_word(const pci_location_t *state, uint32_t reg, uint32_t *value) {
45         return ERR_NOT_CONFIGURED;
46     }
47 
write_config_byte(const pci_location_t * state,uint32_t reg,uint8_t value)48     virtual int write_config_byte(const pci_location_t *state, uint32_t reg, uint8_t value) {
49         return ERR_NOT_CONFIGURED;
50     }
write_config_half(const pci_location_t * state,uint32_t reg,uint16_t value)51     virtual int write_config_half(const pci_location_t *state, uint32_t reg, uint16_t value) {
52         return ERR_NOT_CONFIGURED;
53     }
write_config_word(const pci_location_t * state,uint32_t reg,uint32_t value)54     virtual int write_config_word(const pci_location_t *state, uint32_t reg, uint32_t value) {
55         return ERR_NOT_CONFIGURED;
56     }
57 
58     // TODO: highly bios32 specific
59     struct irq_routing_options_t {
60         uint16_t size;
61         void *offset;
62         uint16_t selector;
63     } __PACKED;
64 
get_irq_routing_options(irq_routing_options_t * options,uint16_t * pci_irqs)65     virtual int get_irq_routing_options(irq_routing_options_t *options, uint16_t *pci_irqs) {
66         return ERR_NOT_CONFIGURED;
67     }
set_irq_hw_int(const pci_location_t * state,uint8_t int_pin,uint8_t irq)68     virtual int set_irq_hw_int(const pci_location_t *state, uint8_t int_pin, uint8_t irq) {
69         return ERR_NOT_CONFIGURED;
70     }
71 
72 protected:
73     // detection should find the last bus
set_last_bus(int last_bus)74     void set_last_bus(int last_bus) { last_bus_ = last_bus; }
75     int last_bus_ = -1;
76 };
77