Skip to content

Commit 0852c0c

Browse files
committed
修复AHCI错误的MMIO地址获取问题
1 parent 103f2e2 commit 0852c0c

File tree

13 files changed

+165
-23
lines changed

13 files changed

+165
-23
lines changed

src/core/main.c

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,8 @@
2727
#include "shell.h"
2828
#include "iic/iic_core.h"
2929
#include "smbios.h"
30+
#include "rtl8169.h"
31+
#include "pcnet.h"
3032

3133
// 编译器判断
3234
#if defined(__clang__)
@@ -103,15 +105,17 @@ void kmain(void) {
103105
ahci_setup();
104106
//xhci_setup();
105107

106-
108+
//rtl8169_setup();
109+
//pcnet_setup();
107110
pivfs_setup();
108111
init_pcb();
109112
smp_setup();
110113
build_stream_device();
111-
112114
init_iic();
113115

114-
/*TODO*/ create_kernel_thread(terminal_flush_service, NULL, "TerminalFlush");
116+
117+
118+
create_kernel_thread(terminal_flush_service, NULL, "TerminalFlush");
115119
create_kernel_thread((void *) shell_setup, NULL, "KernelShell");
116120
kinfo("Kernel load Done!");
117121
//beep();

src/driver/pci/ahci.c

Lines changed: 26 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -6,19 +6,25 @@
66
#include "alloc.h"
77
#include "pcie.h"
88
#include "io.h"
9+
#include "klog.h"
910

1011
static uint32_t ahci_ports[32];
1112
static uint32_t port_total = 0;
1213
static uint64_t ahci_ports_base_addr;
1314
HBA_MEM *hba_mem;
1415

1516
static int check_type(HBA_PORT *port) {
16-
uint32_t ssts = port->ssts;
17+
port->cmd &= ~HBA_PxCMD_ST;
18+
port->cmd &= ~HBA_PxCMD_FRE;
19+
while (port->cmd & HBA_PxCMD_CR);
20+
port->cmd |= HBA_PxCMD_FRE | HBA_PxCMD_ST;
1721

22+
uint32_t ssts = port->ssts;
1823
uint8_t ipm = (ssts >> 8) & 0x0F;
1924
uint8_t det = ssts & 0x0F;
20-
if (det != HBA_PORT_DET_PRESENT) return AHCI_DEV_NULL;
21-
if (ipm != HBA_PORT_IPM_ACTIVE) return AHCI_DEV_NULL;
25+
if (det != HBA_PORT_DET_PRESENT || ipm != HBA_PORT_IPM_ACTIVE) return AHCI_DEV_NULL;
26+
27+
logkf("SATA drive found at port %d\n", port_total);
2228

2329
switch (port->sig) {
2430
case SATA_SIG_ATAPI:
@@ -78,17 +84,17 @@ void ahci_port_rebase(HBA_PORT *port, int portno) {
7884
// Command list maxim size = 32*32 = 1K per port
7985
port->clb = ahci_ports_base_addr + (portno << 10);
8086
port->clbu = 0;
81-
memset((void *) (port->clb), 0, 1024);
87+
memset((void *) phys_to_virt(port->clb), 0, 1024);
8288

8389
// FIS offset: 32K+256*portno
8490
// FIS entry size = 256 bytes per port
8591
port->fb = ahci_ports_base_addr + (32 << 10) + (portno << 8);
8692
port->fbu = 0;
87-
memset((void *) (port->fb), 0, 256);
93+
memset((void *) phys_to_virt(port->fb), 0, 256);
8894

8995
// Command table offset: 40K + 8K*portno
9096
// Command table size = 256*32 = 8K per port
91-
HBA_CMD_HEADER *cmdheader = (HBA_CMD_HEADER *) (port->clb);
97+
HBA_CMD_HEADER *cmdheader = (HBA_CMD_HEADER *) phys_to_virt(port->clb);
9298
for (int i = 0; i < 32; i++) {
9399
cmdheader[i].prdtl = 8; // 8 prdt entries per command table
94100
// 256 bytes per command table, 64+16+48+16*8
@@ -107,23 +113,24 @@ bool ahci_identify(HBA_PORT *port, void *buf) {
107113
int slot = find_cmdslot(port);
108114
if (slot == -1) return false;
109115

110-
HBA_CMD_HEADER *cmdheader = (HBA_CMD_HEADER *) port->clb;
116+
HBA_CMD_HEADER *cmdheader = (HBA_CMD_HEADER *) phys_to_virt(port->clb);
117+
printk("cmdheader: %p\n",cmdheader);
111118
cmdheader += slot;
112119
cmdheader->cfl = sizeof(FIS_REG_H2D) / sizeof(uint32_t); // Command FIS size
113120
cmdheader->w = 0; // Read from device
114121
cmdheader->prdtl = 1; // PRDT entries count
115122
cmdheader->c = 1;
116123
HBA_CMD_TBL *cmdtbl = (HBA_CMD_TBL *) (cmdheader->ctba);
117124
memset(cmdtbl, 0, sizeof(HBA_CMD_TBL) + (cmdheader->prdtl - 1) * sizeof(HBA_PRDT_ENTRY));
118-
125+
printk("MEMSET cmdtbl: %p\n",cmdtbl);
119126
cmdtbl->prdt_entry[0].dba = (uint64_t) buf;
120127
cmdtbl->prdt_entry[0].dbau = 0;
121128
cmdtbl->prdt_entry[0].dbc = 0x200 - 1;
122129
cmdtbl->prdt_entry[0].i = 1;
123130

124131
// Setup command
125132
FIS_REG_H2D *cmdfis = (FIS_REG_H2D *) (&cmdtbl->cfis);
126-
133+
printk("cmdfis: %p\n",cmdfis);
127134
cmdfis->fis_type = FIS_TYPE_REG_H2D;
128135
cmdfis->c = 1; // Command
129136
cmdfis->command = 0xec; // ATA IDENTIFY
@@ -140,6 +147,7 @@ bool ahci_identify(HBA_PORT *port, void *buf) {
140147

141148
port->ci = 1 << slot; // Issue command
142149

150+
printk("III slot: %d\n",slot);
143151
// Wait for completion
144152
while (1) {
145153
// In some longer duration reads, it may be helpful to spin on the DPS bit
@@ -152,6 +160,8 @@ bool ahci_identify(HBA_PORT *port, void *buf) {
152160
}
153161
}
154162

163+
printk("I\n");
164+
155165
// Check again
156166
if (port->is & HBA_PxIS_TFES) {
157167
kwarn("Read ahci disk error\n");
@@ -171,14 +181,17 @@ void ahci_search_ports(HBA_MEM *abar) {
171181
int dt = check_type(&abar->ports[i]);
172182
if (dt == AHCI_DEV_SATA) {
173183
ahci_ports[port_total++] = i;
184+
logkf("SATA drive found at port %d\n", i);
174185
} else if (dt == AHCI_DEV_SATAPI) {
175186
ahci_ports[port_total++] = i;
187+
logkf("SATAPI drive found at port %d\n", i);
176188
} else if (dt == AHCI_DEV_SEMB) {
189+
logkf("SEMB drive found at port %d\n", i);
177190
} else if (dt == AHCI_DEV_PM) {
191+
logkf("PM drive found at port %d\n", i);
178192
} else {
179193
}
180194
}
181-
182195
pi >>= 1;
183196
i++;
184197
}
@@ -212,10 +225,12 @@ void ahci_setup() {
212225
hba_mem = (HBA_MEM*)device->bars[5].address;
213226
}
214227

215-
hba_mem->ghc |= AHCI_GHC_AE;
228+
hba_mem->ghc |= (1 << 31);
216229

217230
ahci_ports_base_addr = (uint64_t) malloc(1048576);
218231

232+
logkf("AHCI cap %x, vs %x\n", hba_mem->cap,hba_mem->vs);
233+
219234
ahci_search_ports(hba_mem);
220235
uint32_t i;
221236
for (i = 0; i < port_total; i++) {

src/driver/pci/nvme.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -164,7 +164,7 @@ void nvme_setup() {
164164
capability = (nvme_capability *) phys_to_virt(device->bars[0].address);
165165
}
166166

167-
page_map_range_to(get_kernel_pagedir(), device->bars[0].address, 0x1000, KERNEL_PTE_FLAGS);
167+
page_map_range_to(get_kernel_pagedir(), device->bars[0].address, 0x1000 * 2, KERNEL_PTE_FLAGS);
168168

169169
if (!((capability->CAP >> 37) & 1)) {
170170
kerror("Nvme controller does not support nvme command set.\n");

src/driver/pci/pci.c

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -298,6 +298,11 @@ bool pci_bar_present(pci_device_t device,uint8_t bar){
298298
return read_pci(device,reg_index) != 0;
299299
}
300300

301+
uint8_t pci_get_drive_irq(uint8_t bus, uint8_t slot, uint8_t func) {
302+
return (uint8_t)
303+
read_pci0(bus, slot, func, 0x3c);
304+
}
305+
301306
static void load_pci_device(uint32_t BUS, uint32_t Equipment, uint32_t F){
302307
uint32_t value_c = read_pci0(BUS, Equipment, F, PCI_CONF_REVISION);
303308
uint32_t class_code = value_c >> 8;

src/driver/pci/pcnet.c

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
#include "pcnet.h"
2+
#include "pcie.h"
3+
#include "pci.h"
4+
#include "kprint.h"
5+
#include "isr.h"
6+
#include "acpi.h"
7+
#include "io.h"
8+
9+
void pcnet_setup(){
10+
pcie_device_t *device = pcie_find_class(0x10220000);
11+
if(device == NULL) {
12+
pci_device_t pci_device = pci_find_class(0x10220000);
13+
if (pci_device == NULL) return;
14+
uint32_t conf = pci_read_command_status(pci_device);
15+
conf |= PCI_COMMAND_MEMORY;
16+
conf |= PCI_RCMD_BUS_MASTER;
17+
conf |= PCI_COMMAND_IO;
18+
pci_write_command_status(pci_device, conf);
19+
base_address_register reg = find_bar(pci_device, 0);
20+
if (reg.address == NULL) {
21+
kerror("Pcnet pci bar 0 is null.");
22+
return;
23+
}
24+
ioapic_add(pcnet, pci_get_drive_irq(pci_device->bus, pci_device->slot, pci_device->func));
25+
} else {
26+
ioapic_add(pcnet, pci_get_drive_irq(device->bus, device->slot, device->func));
27+
}
28+
}

src/driver/pci/rtl8169.c

Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
#include "rtl8169.h"
2+
#include "pci.h"
3+
#include "pcie.h"
4+
#include "hhdm.h"
5+
#include "io.h"
6+
#include "kprint.h"
7+
8+
RTL8169_Regs *rtl8169;
9+
RTL8169_Desc tx_desc[TX_DESC_COUNT] __attribute__((aligned(256)));
10+
RTL8169_Desc rx_desc[RX_DESC_COUNT] __attribute__((aligned(256)));
11+
12+
void rtl8169_reset() {
13+
rtl8169->Command = 0x10;
14+
while (rtl8169->Command & 0x10) __asm__ volatile("pause");
15+
}
16+
17+
void rtl8169_setup_descriptors() {
18+
rtl8169->TxDesc = (uint32_t) virt_to_phys((uint64_t)&tx_desc); // 设置 TX 描述符基地址
19+
rtl8169->RxDesc = (uint32_t)&rx_desc; // 设置 RX 描述符基地址
20+
}
21+
22+
void rtl8169_setup(){
23+
pcie_device_t *device = pcie_find_class(0x020000);
24+
if(device == NULL){
25+
pci_device_t pci_device = pci_find_class(0x020000);
26+
if(pci_device == NULL) return;
27+
uint32_t conf = pci_read_command_status(pci_device);
28+
conf |= PCI_COMMAND_MEMORY;
29+
conf |= PCI_RCMD_BUS_MASTER;
30+
conf |= PCI_COMMAND_IO;
31+
pci_write_command_status(pci_device, conf);
32+
base_address_register reg = find_bar(pci_device,0);
33+
if(reg.address == NULL){
34+
kerror("Rtl8169 pci bar 0 is null.");
35+
return;
36+
}
37+
rtl8169 = (RTL8169_Regs *) phys_to_virt((uint64_t)reg.address);
38+
}else{
39+
uint32_t conf = pcie_read_command(device, 0x04);
40+
conf |= PCI_RCMD_BUS_MASTER;
41+
conf |= PCI_COMMAND_MEMORY;
42+
conf |= PCI_COMMAND_IO;
43+
pcie_write_command(device, 0x04, conf);
44+
rtl8169 = (RTL8169_Regs *)device->bars[0].address;
45+
if(rtl8169 == NULL){
46+
kerror("Rtl8169 pci bar 0 is null.");
47+
return;
48+
}
49+
rtl8169 = phys_to_virt((uint64_t)rtl8169);
50+
}
51+
52+
rtl8169->Command = 0x0C;
53+
rtl8169_setup_descriptors();
54+
55+
kinfo("Rtl8169 mac: %x:%x:%x:%x:%x:%x",rtl8169->MAC[0] & 0xFF,
56+
(rtl8169->MAC[0] >> 8) & 0xFF,
57+
(rtl8169->MAC[0] >> 16) & 0xFF,
58+
(rtl8169->MAC[0] >> 24) & 0xFF,
59+
rtl8169->MAC[1] & 0xFF,
60+
(rtl8169->MAC[1] >> 8) & 0xFF);
61+
}

src/include/ahci.h

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -68,9 +68,9 @@ typedef struct tagHBA_CMD_HEADER {
6868
} __attribute__((packed)) HBA_CMD_HEADER;
6969

7070
typedef volatile struct tagHBA_PORT {
71-
uint64_t clb; // 0x00, command list base address, 1K-byte aligned
72-
uint64_t clbu; // 0x04, command list base address upper 32 bits
73-
uint64_t fb; // 0x08, FIS base address, 256-byte aligned
71+
uint32_t clb; // 0x00, command list base address, 1K-byte aligned
72+
uint32_t clbu; // 0x04, command list base address upper 32 bits
73+
uint32_t fb; // 0x08, FIS base address, 256-byte aligned
7474
uint32_t fbu; // 0x0C, FIS base address upper 32 bits
7575
uint32_t is; // 0x10, interrupt status
7676
uint32_t ie; // 0x14, interrupt enable

src/include/isr.h

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,5 @@
11
#pragma once
22

3-
4-
53
#include "ctype.h"
64

75
enum InterruptIndex {
@@ -10,7 +8,8 @@ enum InterruptIndex {
108
mouse,
119
hpet_timer,
1210
ide_primary,
13-
ide_secondary
11+
ide_secondary,
12+
pcnet,
1413
};
1514

1615
struct interrupt_frame {

src/include/pci.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -59,4 +59,5 @@ uint32_t get_pci_num();
5959
bool pci_bar_present(pci_device_t device,uint8_t bar);
6060
int pci_find_capability(pci_device_t device, uint8_t cap_id);
6161
void pci_set_msi(pci_device_t device,uint8_t vector);
62+
uint8_t pci_get_drive_irq(uint8_t bus, uint8_t slot, uint8_t func);
6263
void pci_setup();

src/include/pcnet.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
#pragma once
2+
3+
void pcnet_setup();

0 commit comments

Comments
 (0)