|
18 | 18 | #ifndef KERNEL_SOLO5_MANAGER_HPP |
19 | 19 | #define KERNEL_SOLO5_MANAGER_HPP |
20 | 20 |
|
21 | | -#include <vector> |
22 | | -#include <cstdio> |
23 | | -#include <unordered_map> |
| 21 | +#include <memory> |
24 | 22 | #include <delegate> |
25 | | - |
26 | | -#include <hw/pci_device.hpp> |
27 | 23 | #include <hw/devices.hpp> |
28 | 24 |
|
29 | 25 | class Solo5_manager { |
30 | | -private: |
31 | | - using Device_registry = std::unordered_map<PCI::classcode, std::vector<hw::PCI_Device>>; |
32 | | - |
33 | 26 | public: |
34 | | - template <PCI::classcode CLASS> |
35 | | - static hw::PCI_Device& device(const int n) noexcept { |
36 | | - return devices_[CLASS][n]; |
37 | | - }; |
38 | | - |
39 | | - template <PCI::classcode CLASS> |
40 | | - static size_t num_of_devices() noexcept { |
41 | | - return devices_[CLASS].size(); |
42 | | - } |
43 | | - |
44 | | - /** Whats being stored and returned is a unique_ptr of the given device */ |
45 | | - template <typename Device_type> |
46 | | - using Dev_ptr = std::unique_ptr<Device_type>; |
47 | | - |
48 | | - /** The function (factory) thats create the Dev_ptr from PCI_Device, supplied by the driver */ |
49 | | - template <typename Device_type> |
50 | | - using Driver_factory = delegate< Dev_ptr<Device_type>(hw::PCI_Device&) >; |
51 | | - |
52 | | - /** |
53 | | - * @brief Register a specific type of driver factory |
54 | | - * @details Register a specific type of driver factory |
55 | | - * (function that creates a pointer to the given Device, with its full driver implementation) |
56 | | - * Indexed as a combination of vendor + product |
57 | | - * |
58 | | - * @param vendor Driver vendor id |
59 | | - * @param product Driver product id |
60 | | - * @param driver_factory Function for creating a driver |
61 | | - * @tparam Device_type The specific type of Device the driver is for |
62 | | - */ |
63 | | - template <typename Device_type> |
64 | | - static void register_driver(uint16_t vendor, uint16_t product, |
65 | | - Driver_factory<Device_type> driver_factory) |
66 | | - { |
67 | | - drivers<Device_type>().emplace(get_driver_id(vendor, product), driver_factory); |
68 | | - } |
69 | | - |
70 | | - /** Currently a combination of Model + Product (we don't care about the revision etc. atm.)*/ |
71 | | - using driver_id_t = uint32_t; |
72 | | - |
73 | | - /** Combine vendor and product id to represent a driver id */ |
74 | | - static driver_id_t get_driver_id(uint16_t vendor, uint16_t product) |
75 | | - { return (uint32_t)(vendor) << 16 | product; } |
| 27 | + using Nic_ptr = std::unique_ptr<hw::Nic>; |
| 28 | + using Blk_ptr = std::unique_ptr<hw::Block_device>; |
76 | 29 |
|
77 | | - static driver_id_t get_driver_id(hw::PCI_Device& dev) |
78 | | - { return get_driver_id(dev.vendor_id(), dev.product_id()); } |
| 30 | + static void register_net(delegate<Nic_ptr()>); |
| 31 | + static void register_blk(delegate<Blk_ptr()>); |
79 | 32 |
|
80 | | -private: |
81 | | - static Device_registry devices_; |
82 | | - |
83 | | - /** A register for a specific type of drivers: map[driver_id, driver_factory]*/ |
84 | | - template <typename Device_type> |
85 | | - using Driver_registry = std::unordered_map<driver_id_t, Driver_factory<Device_type> >; |
86 | | - |
87 | | - /** |
88 | | - * @brief Retrieve drivers (factories) of a given type of device |
89 | | - * |
90 | | - * @return A collection of driver factories indexed by driver_id |
91 | | - */ |
92 | | - template <typename Device_type> |
93 | | - static Driver_registry<Device_type>& drivers() { |
94 | | - static Driver_registry<Device_type> drivers_; |
95 | | - return drivers_; |
96 | | - } |
97 | | - |
98 | | - template <typename Device_type> |
99 | | - inline static bool register_device(hw::PCI_Device& dev); |
100 | | - |
101 | | - /** |
102 | | - * Keep track of certain devices |
103 | | - * |
104 | | - * The PCI manager can probe and keep track of devices which can (possibly) |
105 | | - * be specialized by the Dev-class later. |
106 | | - */ |
107 | 33 | static void init(); |
108 | | - |
109 | | - friend class OS; |
110 | 34 | }; //< class Solo5_manager |
111 | 35 |
|
112 | | -template <typename Device_type> |
113 | | -inline bool Solo5_manager::register_device(hw::PCI_Device& dev) { |
114 | | - try { |
115 | | - auto driver_factory = drivers<Device_type>().at(get_driver_id(dev)); |
116 | | - INFO2("| +--+ Driver: Found"); |
117 | | - |
118 | | - hw::Devices::register_device(driver_factory(dev)); |
119 | | - return true; |
120 | | - } catch(std::out_of_range) { |
121 | | - INFO2("| +--+ Driver: Not found"); |
122 | | - } |
123 | | - return false; |
124 | | -} |
125 | | - |
126 | 36 | #endif //< KERNEL_SOLO5_MANAGER_HPP |
0 commit comments