1 | // SPDX-License-Identifier: GPL-3.0-or-later |
2 | |
3 | #include "dm_common.hpp" |
4 | |
5 | #include <iostream> |
6 | #include <libconfig/libconfig.h> |
7 | #include <spawn.h> |
8 | #include <stdio.h> |
9 | #include <stdlib.h> |
10 | #include <string.h> |
11 | |
12 | bool start_load_drivers() |
13 | { |
14 | const auto loads = dm_config.get_entries(section_name: "loads" ); |
15 | |
16 | for (const auto &[_, driver] : loads) |
17 | { |
18 | pid_t driver_pid; |
19 | posix_spawn(pid: &driver_pid, path: driver.c_str(), NULL, NULL, NULL, NULL); |
20 | if (driver_pid <= 0) |
21 | std::cerr << "Failed to start driver: " << driver << std::endl; |
22 | } |
23 | |
24 | return true; |
25 | } |
26 | |
27 | bool try_start_driver(u16 vendor, u16 device, u32 location, u64 mmio_base) |
28 | { |
29 | char vendor_str[5]; |
30 | char vendor_device_str[10]; |
31 | snprintf(buffer: vendor_str, max_size: sizeof(vendor_str), format: "%04x" , vendor); |
32 | snprintf(buffer: vendor_device_str, max_size: sizeof(vendor_device_str), format: "%04x:%04x" , vendor, device); |
33 | |
34 | // first try to find a driver for the specific device |
35 | auto driver_paths = dm_config.get_entry(section_name: "drivers" , key: vendor_device_str); |
36 | |
37 | // if that fails, try to find a driver for the vendor |
38 | if (driver_paths.empty()) |
39 | driver_paths = dm_config.get_entry(section_name: "drivers" , key: vendor_str); |
40 | |
41 | // if the driver is still not found, leave |
42 | if (driver_paths.empty()) |
43 | return false; |
44 | |
45 | if (driver_paths.size() > 1) |
46 | puts(string: "Multiple drivers found for device, using the first one" ); |
47 | |
48 | const auto driver_path = driver_paths[0].second; |
49 | |
50 | char device_str[16]; |
51 | char location_str[16]; |
52 | char mmio_base_str[16]; |
53 | snprintf(buffer: device_str, max_size: sizeof(device_str), format: "%04x" , device); |
54 | snprintf(buffer: location_str, max_size: sizeof(location_str), format: "%04x" , location); |
55 | snprintf(buffer: mmio_base_str, max_size: sizeof(mmio_base_str), format: "%llx" , mmio_base); |
56 | |
57 | const char *argv[] = { |
58 | driver_path.c_str(), // |
59 | "--vendor-id" , vendor_str, // |
60 | "--device-id" , device_str, // |
61 | "--location" , location_str, // |
62 | "--mmio-base" , mmio_base_str, NULL, // |
63 | }; |
64 | printf(format: "Starting driver:" ); |
65 | for (size_t i = 0; argv[i]; i++) |
66 | printf(format: " %s" , argv[i]); |
67 | putchar(c: '\n'); |
68 | |
69 | pid_t driver_pid; |
70 | posix_spawn(pid: &driver_pid, path: driver_path.c_str(), NULL, NULL, argv: (char *const *) argv, NULL); |
71 | |
72 | return driver_pid > 0; |
73 | } |
74 | |