2023-11-02 00:26:06 +03:00
|
|
|
|
#include <system.h>
|
|
|
|
|
|
2023-11-07 22:34:26 +03:00
|
|
|
|
typedef struct {
|
|
|
|
|
char *name;
|
|
|
|
|
uint16_t id;
|
|
|
|
|
} vendor_t;
|
|
|
|
|
|
2023-11-18 19:38:04 +03:00
|
|
|
|
static vendor_t **vendor_list;
|
2023-11-26 18:23:58 +03:00
|
|
|
|
static uint64_t num_vendors;
|
|
|
|
|
|
|
|
|
|
static char *find_vendor(uint16_t id) {
|
2023-11-28 23:55:40 +03:00
|
|
|
|
for (uint64_t i = 0; i < num_vendors; i++) {
|
2023-11-26 18:23:58 +03:00
|
|
|
|
if (vendor_list[i]->id == id) { return vendor_list[i]->name; }
|
|
|
|
|
}
|
2023-11-28 23:55:40 +03:00
|
|
|
|
return "Нет в базе";
|
2023-11-26 18:23:58 +03:00
|
|
|
|
}
|
2023-11-18 19:38:04 +03:00
|
|
|
|
|
2023-12-12 21:11:06 +03:00
|
|
|
|
static inline uint16_t pci_read_word(uint16_t bus, uint16_t slot, uint16_t func, uint16_t offset) {
|
2023-11-02 00:26:06 +03:00
|
|
|
|
uint64_t address;
|
|
|
|
|
uint64_t lbus = (uint64_t)bus;
|
|
|
|
|
uint64_t lslot = (uint64_t)slot;
|
|
|
|
|
uint64_t lfunc = (uint64_t)func;
|
|
|
|
|
uint16_t tmp = 0;
|
2023-12-12 21:11:06 +03:00
|
|
|
|
address = (uint64_t)((lbus << 16) | (lslot << 11) | (lfunc << 8) | (offset & 0xFC) | ((uint32_t)0x80000000));
|
2023-11-02 00:26:06 +03:00
|
|
|
|
outl(0xCF8, address);
|
|
|
|
|
tmp = (uint16_t)((inl(0xCFC) >> ((offset & 2) * 8)) & 0xFFFF);
|
|
|
|
|
return (tmp);
|
|
|
|
|
}
|
|
|
|
|
|
2023-12-14 12:48:27 +03:00
|
|
|
|
static inline uint16_t get_vendor_id(uint16_t bus, uint16_t slot, uint16_t function) {
|
|
|
|
|
uint32_t r0 = pci_read_word(bus, slot, function, 0);
|
2023-11-02 00:26:06 +03:00
|
|
|
|
return r0;
|
|
|
|
|
}
|
|
|
|
|
|
2023-12-14 12:48:27 +03:00
|
|
|
|
static inline uint16_t get_device_id(uint16_t bus, uint16_t slot, uint16_t function) {
|
|
|
|
|
uint32_t r0 = pci_read_word(bus, slot, function, 2);
|
2023-11-02 00:26:06 +03:00
|
|
|
|
return r0;
|
|
|
|
|
}
|
|
|
|
|
|
2023-12-14 12:48:27 +03:00
|
|
|
|
static inline uint16_t get_class_id(uint16_t bus, uint16_t slot, uint16_t function) {
|
|
|
|
|
uint32_t r0 = pci_read_word(bus, slot, function, 0xA);
|
2023-11-02 00:26:06 +03:00
|
|
|
|
return (r0 & ~0x00FF) >> 8;
|
|
|
|
|
}
|
|
|
|
|
|
2023-12-14 12:48:27 +03:00
|
|
|
|
static inline uint16_t get_sub_class_id(uint16_t bus, uint16_t slot, uint16_t function) {
|
|
|
|
|
uint32_t r0 = pci_read_word(bus, slot, function, 0xA);
|
2023-11-02 00:26:06 +03:00
|
|
|
|
return (r0 & ~0xFF00);
|
|
|
|
|
}
|
|
|
|
|
|
2023-11-28 23:55:40 +03:00
|
|
|
|
static char *get_class_name(uint16_t number) {
|
|
|
|
|
switch (number) {
|
|
|
|
|
case 0x0: return "Неклассифицирован";
|
|
|
|
|
case 0x1: return "Контроллер устройства хранения";
|
|
|
|
|
case 0x2: return "Контроллер сети";
|
|
|
|
|
case 0x3: return "Контроллер дисплея";
|
|
|
|
|
case 0x4: return "Мультимедийный контроллер";
|
|
|
|
|
case 0x5: return "Контроллер памяти";
|
|
|
|
|
case 0x6: return "Мост";
|
|
|
|
|
case 0x7: return "Простой коммуникационный контроллер";
|
|
|
|
|
case 0x8: return "Периферийное устройство базовой системы";
|
|
|
|
|
case 0x9: return "Устройство ввода";
|
|
|
|
|
case 0xA: return "Док-станция";
|
|
|
|
|
case 0xB: return "Процессор";
|
|
|
|
|
case 0xC: return "Контроллер последовательной шины";
|
|
|
|
|
case 0xD: return "Беспроводной контроллер";
|
|
|
|
|
case 0xE: return "Интеллектуальный контроллер ввода/вывода";
|
|
|
|
|
case 0xF: return "Контроллер спутниковой связи";
|
|
|
|
|
case 0x10: return "Контроллер шифрования/дешифрования";
|
|
|
|
|
case 0x11: return "Контроллер сбора данных и обработки сигналов";
|
|
|
|
|
default: return "Неизвестный";
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2023-11-13 22:54:24 +03:00
|
|
|
|
static inline void scan( ) {
|
2023-11-02 00:26:06 +03:00
|
|
|
|
uint64_t devices = 0;
|
|
|
|
|
for (uint32_t bus = 0; bus < 256; bus++) {
|
|
|
|
|
for (uint32_t slot = 0; slot < 32; slot++) {
|
|
|
|
|
for (uint32_t function = 0; function < 8; function++) {
|
|
|
|
|
uint16_t vendor = get_vendor_id(bus, slot, function);
|
2023-11-07 22:34:26 +03:00
|
|
|
|
|
2023-11-02 00:26:06 +03:00
|
|
|
|
if (vendor == 0xFFFF) { continue; }
|
2023-11-07 22:34:26 +03:00
|
|
|
|
|
2023-11-02 00:26:06 +03:00
|
|
|
|
uint16_t device_id = get_device_id(bus, slot, function);
|
|
|
|
|
uint16_t class_id = get_class_id(bus, slot, function);
|
2023-12-17 00:51:17 +03:00
|
|
|
|
|
2023-12-14 12:48:27 +03:00
|
|
|
|
uint16_t status = pci_read_word(bus, slot, function, 0x6);
|
2023-12-17 15:21:27 +03:00
|
|
|
|
/*
|
2023-12-14 12:48:27 +03:00
|
|
|
|
uint32_t mem_addr_0 = pci_read_word(bus, slot, function, 0x1C);
|
|
|
|
|
uint32_t mem_addr_1 = pci_read_word(bus, slot, function, 0x24);
|
|
|
|
|
uint32_t mem_lim_0 = pci_read_word(bus, slot, function, 0x20);
|
|
|
|
|
uint32_t mem_lim_1 = pci_read_word(bus, slot, function, 0x28);
|
|
|
|
|
uint32_t io_addr_0 = pci_read_word(bus, slot, function, 0x2C);
|
|
|
|
|
uint32_t io_addr_1 = pci_read_word(bus, slot, function, 0x34);
|
|
|
|
|
uint32_t io_lim_0 = pci_read_word(bus, slot, function, 0x30);
|
|
|
|
|
uint32_t io_lim_1 = pci_read_word(bus, slot, function, 0x38);
|
2023-12-17 00:51:17 +03:00
|
|
|
|
*/
|
2023-11-28 23:55:40 +03:00
|
|
|
|
|
2023-11-26 18:23:58 +03:00
|
|
|
|
char *name = find_vendor(vendor);
|
2024-03-03 14:43:11 +03:00
|
|
|
|
log_printf("[%4u] %4x [%10s], устройство: %x, %u.%u.%u | ", devices, vendor, name, device_id, bus, slot,
|
|
|
|
|
function);
|
|
|
|
|
log_printf("%32s", get_class_name(class_id));
|
2023-12-17 00:51:17 +03:00
|
|
|
|
|
|
|
|
|
/*
|
2024-03-03 14:43:11 +03:00
|
|
|
|
log_printf(" | %8x : %8x", mem_addr_0, mem_lim_0);
|
|
|
|
|
log_printf(" | %8x : %8x", mem_addr_1, mem_lim_1);
|
|
|
|
|
log_printf(" | %8x : %8x", io_addr_0, io_lim_0);
|
|
|
|
|
log_printf(" | %8x : %8x", io_addr_1, io_lim_1);
|
2023-12-17 00:51:17 +03:00
|
|
|
|
*/
|
2023-12-17 15:21:27 +03:00
|
|
|
|
|
2024-03-03 14:43:11 +03:00
|
|
|
|
log_printf(" | %4x\n", status);
|
2023-11-02 00:26:06 +03:00
|
|
|
|
devices++;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2024-09-16 21:42:47 +03:00
|
|
|
|
void __attribute__((section(".minit"))) init(env_t *env) {
|
2023-11-02 00:26:06 +03:00
|
|
|
|
init_env(env);
|
2023-11-18 19:38:04 +03:00
|
|
|
|
|
2024-09-16 21:42:47 +03:00
|
|
|
|
log_printf("pci_data %x\n", 1);
|
2023-11-26 13:12:57 +03:00
|
|
|
|
module_info_t *pci_data = get_module("[PCI][ADAPTER]");
|
2024-09-16 21:42:47 +03:00
|
|
|
|
log_printf("pci_data %x\n", pci_data);
|
2023-11-18 19:38:04 +03:00
|
|
|
|
|
|
|
|
|
if (pci_data == NULL) {
|
2024-03-03 14:43:11 +03:00
|
|
|
|
log_printf("Адаптер PCI данных не найден!\n");
|
2023-11-28 23:55:40 +03:00
|
|
|
|
num_vendors = 0;
|
2023-11-18 19:38:04 +03:00
|
|
|
|
} else {
|
2024-01-17 12:45:27 +03:00
|
|
|
|
num_vendors = pci_data->data_size - 1;
|
2024-03-03 14:43:11 +03:00
|
|
|
|
log_printf("Записей в базе PCI: %u\n", pci_data->data_size);
|
2023-11-18 19:38:04 +03:00
|
|
|
|
vendor_list = (vendor_t **)pci_data->data;
|
|
|
|
|
}
|
|
|
|
|
|
2023-11-02 00:26:06 +03:00
|
|
|
|
scan( );
|
2024-09-17 21:29:52 +03:00
|
|
|
|
env->ret = &((module_info_t){ .name = "[PCI]",
|
|
|
|
|
.message = "PCI драйвер",
|
|
|
|
|
.type = 0,
|
|
|
|
|
.data_size = 0,
|
|
|
|
|
.data = 0,
|
|
|
|
|
.err_code = 0,
|
|
|
|
|
.module_id = 0,
|
|
|
|
|
.irq = 0,
|
|
|
|
|
.irq_handler = 0,
|
|
|
|
|
.get_func = 0,
|
|
|
|
|
.after_init = 0 });
|
2024-09-17 10:05:22 +03:00
|
|
|
|
mod_update_info(env);
|
2024-09-16 21:42:47 +03:00
|
|
|
|
delete_thread( );
|
2023-11-02 00:26:06 +03:00
|
|
|
|
}
|