Skip to content

Commit ebadecd

Browse files
committed
PCIE & PCI双重支持
1 parent b33eda6 commit ebadecd

File tree

10 files changed

+88
-123
lines changed

10 files changed

+88
-123
lines changed

src/core/main.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -75,7 +75,7 @@ void kmain(void) {
7575
vfs_init();
7676
vdisk_init();
7777
pcie_init();
78-
nvme_setup();
78+
//nvme_setup();
7979
//ahci_setup();
8080
//xhci_setup();
8181

src/driver/iic/iic_basic_implementation.c

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -53,8 +53,7 @@ uint32_t iic_dataTransfer(IIC_Data *frame) {
5353

5454
uint8_t Get_iic_masterAddress(pci_device_t *IIC_Master_Controller) {
5555
// 获取IIC主机控制器基地址
56-
base_address_register bar = find_bar(*IIC_Master_Controller, 0);
57-
uint8_t base_address = *bar.address;
56+
uint8_t base_address = *(uint8_t*)(*IIC_Master_Controller)->bars[0].address;
5857
return base_address;
5958
}
6059

src/driver/pci/nvme.c

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -148,11 +148,15 @@ void NvmeWrite(int id, uint8_t *buf, uint32_t count, uint32_t idx) {
148148
}
149149

150150
void nvme_setup() {
151-
pcie_device_t *device = pcie_find_class(0x10802);
151+
pci_device_t device = pci_find_class(0x10802);
152152
if (device == NULL) {
153153
return;
154154
}
155155
nvme_capability *capability = (nvme_capability *) phys_to_virt(device->bars[0].address);
156+
if(capability == NULL){
157+
kerror("Nvme controller bar 0 is null\n");
158+
return;
159+
}
156160
page_map_range_to(get_kernel_pagedir(), device->bars[0].address, 0x1000, KERNEL_PTE_FLAGS);
157161

158162
if (!((capability->CAP >> 37) & 1)) {

src/driver/pci/pci.c

Lines changed: 27 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -145,7 +145,7 @@ pci_device_t pci_device[PCI_DEVICE_MAX];
145145
uint32_t device_number = 0;
146146

147147
uint32_t get_pci_num() {
148-
return PCI_NUM;
148+
return device_number;
149149
}
150150

151151
char *pci_classname(uint32_t classcode) {
@@ -212,42 +212,6 @@ void write_pci(pci_device_t device,uint8_t offset, uint32_t value){
212212
write_pci0(device->bus,device->slot,device->func,offset,value);
213213
}
214214

215-
int pci_find_capability(pci_device_t device, uint8_t cap_id) {
216-
uint8_t pos = (uint8_t)(read_pci(device, PCI_CAPABILITY_LIST) & 0xFF);
217-
if (pos == 0) {
218-
return 0;
219-
}
220-
221-
while (pos != 0) {
222-
uint8_t id = (uint8_t)(read_pci(device, pos + PCI_CAP_LIST_ID) & 0xFF);
223-
if (id == cap_id) {
224-
return pos;
225-
}
226-
pos = (uint8_t)(read_pci(device, pos + PCI_CAP_LIST_NEXT) & 0xFF);
227-
}
228-
229-
return 0;
230-
}
231-
232-
void pci_set_msi(pci_device_t device,uint8_t vector){
233-
device->msi_offset = pci_find_capability(device,PCI_CAP_ID_MSI);
234-
uint32_t msg_ctrl = read_pci(device,device->msi_offset + 2);
235-
uint8_t reg0 = 0x4;
236-
uint8_t reg1 = 0x8;
237-
238-
if (((msg_ctrl >> 7) & 1) == 1) {
239-
reg1 = 0xc;
240-
}
241-
242-
uint64_t address = (0xfee << 20) | (lapic_id() << 12);
243-
uint8_t data = vector;
244-
write_pci(device,device->msi_offset + reg0,address);
245-
write_pci(device,device->msi_offset + reg1,data);
246-
msg_ctrl |= 1;
247-
msg_ctrl &= ~(7 << 4);
248-
write_pci(device,device->msi_offset + 2,msg_ctrl);
249-
}
250-
251215
static base_address_register get_base_address_register(uint8_t bus, uint8_t device, uint8_t function, uint8_t bar) {
252216
base_address_register result = {0, NULL, 0, 0};
253217

@@ -307,6 +271,10 @@ static void load_pci_device(uint32_t BUS, uint32_t Equipment, uint32_t F){
307271
uint16_t vendor_id = value_v & 0xffff;
308272
uint16_t device_id = value_d & 0xffff;
309273

274+
if(class_code == 0x060400 || (class_code & 0xFFFF00) == 0x060400){
275+
return;
276+
}
277+
310278
pci_device_t device = malloc(sizeof(struct pci_device));
311279
device->name = pci_classname(class_code);
312280
device->vendor_id = vendor_id;
@@ -315,45 +283,59 @@ static void load_pci_device(uint32_t BUS, uint32_t Equipment, uint32_t F){
315283
device->bus = BUS;
316284
device->slot = Equipment;
317285
device->func = F;
286+
device->is_pcie = false;
287+
288+
for (size_t i = 0; i < 6; i++) {
289+
if(pci_bar_present(device,i)){
290+
base_address_register reg = get_base_address_register(BUS,Equipment,F,i);
291+
device->bars[i].address = (uint64_t)reg.address;
292+
device->bars[i].mmio = !reg.type;
293+
}
294+
}
318295

319296
if (device_number > PCI_DEVICE_MAX) {
320297
kwarn("add device full %d", device_number);
321298
return;
322299
}
323300
pci_device[device_number++] = device;
324-
325-
if(device->class_code == 0x060400 || (device->class_code & 0xFFFF00) == 0x060400){
326-
return;
327-
}
328301
}
329302

330303
void print_all_pci() {
331-
printk("Bus:Slot:Func\t[Vendor:Device]\tClass Code\tName\n");
304+
printk("Bus:Slot:Func\t[Vendor:Device]\tClass Code\tType\tName\n");
332305
for (size_t i = 0; i < device_number; i++) {
333306
pci_device_t device = pci_device[i];
334-
printk("%03d:%02d:%02d\t[0x%04X:0x%04X]\t<0x%08x>\t%s\n",
307+
printk("%03d:%02d:%02d\t[0x%04X:0x%04X]\t<0x%08x>\t%s\t%s\n",
335308
device->bus,
336309
device->slot,
337310
device->func,
338311
device->vendor_id,
339312
device->device_id,
340313
device->class_code,
314+
device->is_pcie ? "PCIE" : "PCI ",
341315
device->name);
342316
}
343317
}
344318

319+
static bool has_device(uint32_t bus,uint32_t slot,uint32_t func){
320+
for(size_t i = 0; i < device_number;i++){
321+
pci_device_t device = pci_device[i];
322+
if(device->bus == bus && device->slot == slot && device->func == func) return true;
323+
}
324+
return false;
325+
}
326+
345327
void pci_setup(){
346328
uint32_t BUS, Equipment, F;
347329
for (BUS = 0; BUS < 256; BUS++) {
348330
for (Equipment = 0; Equipment < 32; Equipment++) {
349331
for (F = 0; F < 8; F++) {
350332
pci_config0(BUS,F,Equipment,0);
351333
if(io_in32(PCI_DATA_PORT) != 0xFFFFFFFF){
352-
PCI_NUM++;
334+
if(has_device(BUS,Equipment,F)) break;
353335
load_pci_device(BUS,Equipment,F);
354336
}
355337
}
356338
}
357339
}
358-
kinfo("PCI device loaded: %d", PCI_NUM);
340+
kinfo("PCI device loaded: %d", device_number);
359341
}

src/driver/pci/pcie.c

Lines changed: 30 additions & 50 deletions
Original file line numberDiff line numberDiff line change
@@ -9,8 +9,8 @@
99
MCFG_ENTRY *mcfg_entries[PCI_MCFG_MAX_ENTRIES_LEN];
1010
MCFG *mcfg;
1111
uint64_t mcfg_entries_len = 0;
12-
pcie_device_t *pci_devices[PCI_DEVICE_MAX];
13-
uint32_t pci_device_number = 0;
12+
extern pci_device_t pci_device[PCI_DEVICE_MAX];
13+
extern uint32_t device_number;
1414
bool is_pcie = false; // 是否是PCIE模式 (CP_Kernel无法加载PCIE驱动时候会切换回默认的PCI)
1515

1616
static uint64_t
@@ -46,13 +46,13 @@ void mcfg_addr_to_entries(MCFG_ENTRY **entries) {
4646
}
4747
}
4848

49-
uint32_t pcie_read_command(pcie_device_t *device, uint8_t offset) {
49+
uint32_t pci_read_command(pci_device_t device, uint8_t offset) {
5050
uint32_t address = (1 << 31) | (device->bus << 16) | (device->slot << 11) | (device->func << 8) | (offset & 0xFC);
5151
io_out32(PCI_COMMAND_PORT,address);
5252
return io_in32(PCI_DATA_PORT);
5353
}
5454

55-
void pcie_write_command(pcie_device_t *device,uint8_t offset,uint32_t value){
55+
void pci_write_command(pci_device_t device,uint8_t offset,uint32_t value){
5656
uint32_t address = (1 << 31) | (device->bus << 16) | (device->slot << 11) | (device->func << 8) | (offset & 0xFC);
5757
io_out32(PCI_COMMAND_PORT,address);
5858
io_out32(PCI_DATA_PORT,value);
@@ -80,45 +80,46 @@ void pci_scan_function(uint16_t segment_group, uint8_t bus, uint8_t device, uint
8080
switch (*((uint8_t *) header_type_mmio_addr + 2)) {
8181
// Endpoint
8282
case 0x00: {
83-
pcie_device_t *pci_device = (pcie_device_t *) malloc(sizeof(pcie_device_t));
83+
pci_device_t pci_device0 = (pci_device_t )malloc(sizeof(struct pci_device));
8484
uint32_t class_code_24bit = (device_class << 16) | (device_subclass << 8) | device_interface;
85-
pci_device->class_code = class_code_24bit;
86-
pci_device->vendor_id = vendor_id;
87-
pci_device->device_id = device_id;
85+
pci_device0->class_code = class_code_24bit;
86+
pci_device0->vendor_id = vendor_id;
87+
pci_device0->device_id = device_id;
8888

89-
pci_device->segment = segment_group;
90-
pci_device->bus = bus;
91-
pci_device->slot = device;
92-
pci_device->func = function;
89+
pci_device0->segment = segment_group;
90+
pci_device0->bus = bus;
91+
pci_device0->slot = device;
92+
pci_device0->func = function;
9393

9494
for (int i = 0; i < 6; i++) {
9595
int offset = 0x10 + i * 4;
9696
uint64_t bars_mmio_address = get_mmio_address(pci_address, offset);
9797
uint32_t bar = *(uint32_t *) bars_mmio_address;
9898

9999
if (bar & 0x01) {
100-
pci_device->bars[i].address = bar & 0xFFFFFFFC;
101-
pci_device->bars[i].mmio = false;
100+
pci_device0->bars[i].address = bar & 0xFFFFFFFC;
101+
pci_device0->bars[i].mmio = false;
102102
} else {
103103
bool prefetchable = bar & (1 << 3);
104104
UNUSED(prefetchable);
105105
uint64_t bar_address = bar & 0xFFFFFFF0;
106106
uint16_t bit = (bar & ((1 << 3) | (1 << 2) | (1 << 1))) >> 1;
107107

108108
if(bit == 0){ //0b00
109-
pci_device->bars[i].address = bar & 0xFFFFFFFC;
110-
pci_device->bars[i].mmio = true;
109+
pci_device0->bars[i].address = bar & 0xFFFFFFFC;
110+
pci_device0->bars[i].mmio = true;
111111
} else if(bit == 2){ //0b10
112112
uint32_t bar_address_upper = *((uint32_t *) bars_mmio_address + 1);
113113
bar_address |= ((uint64_t) bar_address_upper << 32);
114-
pci_device->bars[i].address = bar_address;
115-
pci_device->bars[i].mmio = true;
114+
pci_device0->bars[i].address = bar_address;
115+
pci_device0->bars[i].mmio = true;
116116
}
117117
}
118118
}
119-
pci_device->name = pci_classname(pci_device->class_code);
120-
pci_devices[pci_device_number] = pci_device;
121-
pci_device_number++;
119+
pci_device0->name = pci_classname(pci_device0->class_code);
120+
pci_device0->is_pcie = true;
121+
pci_device[device_number] = pci_device0;
122+
device_number++;
122123
}
123124
break;
124125
// PciPciBridge
@@ -158,55 +159,34 @@ void pci_scan_segment(uint16_t segment_group) {
158159
}
159160
}
160161

161-
uint32_t get_pcie_num() {
162-
return is_pcie ? pci_device_number : get_pci_num();
163-
}
164-
165162
void print_all_pcie() {
166-
if(!is_pcie){
167-
print_all_pci();
168-
printk("Model: PCI\n");
169-
return;
170-
}
171-
printk("Bus:Slot:Func\t[Vendor:Device]\tClass Code\tName\n");
172-
for (size_t i = 0; i < pci_device_number; i++) {
173-
pcie_device_t *device = pci_devices[i];
174-
printk("%03d:%02d:%02d\t[0x%04X:0x%04X]\t<0x%08x>\t%s\n",
163+
printk("Bus:Slot:Func\t[Vendor:Device]\tClass Code\tType\tName\n");
164+
for (size_t i = 0; i < device_number; i++) {
165+
pci_device_t device = pci_device[i];
166+
printk("%03d:%02d:%02d\t[0x%04X:0x%04X]\t<0x%08x>\t%s\t%s\n",
175167
device->bus,
176168
device->slot,
177169
device->func,
178170
device->vendor_id,
179171
device->device_id,
180172
device->class_code,
173+
device->is_pcie ? "PCIE" : "PCI ",
181174
device->name);
182175
}
183-
printk("Model: PCIE\n");
184-
}
185-
186-
pcie_device_t *pcie_find_class(uint32_t class_code) {
187-
for (size_t i = 0; i < pci_device_number; i++) {
188-
if (pci_devices[i]->class_code == class_code) {
189-
return pci_devices[i];
190-
}
191-
if (class_code == (pci_devices[i]->class_code & 0xFFFF00)) {
192-
return pci_devices[i];
193-
}
194-
}
195-
return NULL;
196176
}
197177

198178
void pcie_init() {
199179
if (mcfg == NULL) {
200-
pci_setup();
201-
return;
180+
goto pci;
202181
}
203182
mcfg_addr_to_entries(mcfg_entries);
204183
for (size_t i = 0; i < mcfg_entries_len; i++) {
205184
uint16_t segment_group = mcfg_entries[i]->pci_segment_group;
206185
pci_scan_segment(segment_group);
207186
}
208187
is_pcie = true;
209-
kinfo("PCIE device find %d",pci_device_number);
188+
pci:
189+
pci_setup();
210190
}
211191

212192
/**

src/driver/pci/xhci.c

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,16 @@
11
#include "xhci.h"
2-
#include "pcie.h"
2+
#include "pci.h"
33
#include "kprint.h"
4+
#include "pcie.h"
45

56
void xhci_setup(){
6-
pcie_device_t *device = pcie_find_class(0xc0300);
7+
pci_device_t device = pci_find_class(0xc0300);
78
if(device == NULL) return;
89

9-
uint32_t command = pcie_read_command(device,2);
10+
uint32_t command = pci_read_command(device,2);
1011
command &= ~(PCI_COMMAND_IO | PCI_COMMAND_INT_DISABLE);
1112
command |= PCI_COMMAND_MASTER | PCI_COMMAND_MEMORY;
12-
pcie_write_command(device,2,command);
13+
pci_write_command(device,2,command);
1314

1415
kinfo("Loading USB 3.0 driver.");
1516
}

src/include/nvme.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@
1616

1717

1818
#include "ctype.h"
19-
#include "pcie.h"
19+
#include "pci.h"
2020

2121
typedef struct NVME_CONTROLLER nvme_controller;
2222

@@ -79,7 +79,7 @@ typedef struct _NVME_SUBMISSION_QUEUE{
7979
} __attribute__((packed)) NVME_SUBMISSION_QUEUE;
8080

8181
typedef struct NVME_CONTROLLER{
82-
pcie_device_t *DVC;
82+
pci_device_t DVC;
8383
nvme_capability *CAP;
8484
NVME_COMPLETION_QUEUE ACQ;
8585
NVME_SUBMISSION_QUEUE ASQ;

src/include/pci.h

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -24,16 +24,23 @@
2424

2525
#include "ctype.h"
2626

27+
28+
typedef struct{
29+
uint64_t address;
30+
bool mmio;
31+
} pci_bar_base_address;
32+
2733
struct pci_device{
28-
char* name;
34+
char *name;
2935
uint32_t class_code;
3036
uint16_t vendor_id;
3137
uint16_t device_id;
38+
uint16_t segment;
3239
uint8_t bus;
3340
uint8_t slot;
3441
uint8_t func;
35-
uint8_t irq_pin;
36-
uint16_t msi_offset;
42+
pci_bar_base_address bars[6];
43+
bool is_pcie;
3744
};
3845

3946
typedef struct base_address_register {
@@ -57,6 +64,4 @@ uint32_t pci_read_command_status(pci_device_t device);
5764
void print_all_pci();
5865
uint32_t get_pci_num();
5966
bool pci_bar_present(pci_device_t device,uint8_t bar);
60-
int pci_find_capability(pci_device_t device, uint8_t cap_id);
61-
void pci_set_msi(pci_device_t device,uint8_t vector);
6267
void pci_setup();

0 commit comments

Comments
 (0)