diff --git a/kernel/Makefile b/kernel/Makefile index 94cf8d32..0babca39 100644 --- a/kernel/Makefile +++ b/kernel/Makefile @@ -19,10 +19,10 @@ all: kernel objcopy -I elf64-x86-64 -S -R ".comment" -R ".eh_frame" -O elf64-x86-64 kernel ../bin/kernel/kernel.elf -kernel: head.o entry.o main.o printk.o trap.o mm.o slab.o irq.o pic.o process.o syscall.o multiboot2.o cpu.o acpi.o ps2_keyboard.o ps2_mouse.o ata.o pci.o +kernel: head.o entry.o main.o printk.o trap.o mm.o slab.o irq.o pic.o process.o syscall.o multiboot2.o cpu.o acpi.o ps2_keyboard.o ps2_mouse.o ata.o pci.o ahci.o ld -b elf64-x86-64 -z muldefs -o kernel head.o exception/entry.o main.o common/printk.o exception/trap.o exception/irq.o mm/mm.o mm/slab.o process/process.o syscall/syscall.o driver/multiboot2/multiboot2.o \ common/cpu.o \ - driver/acpi/acpi.o driver/interrupt/pic.o driver/keyboard/ps2_keyboard.o driver/mouse/ps2_mouse.o driver/disk/ata.o driver/pci/pci.o \ + driver/acpi/acpi.o driver/interrupt/pic.o driver/keyboard/ps2_keyboard.o driver/mouse/ps2_mouse.o driver/disk/ata.o driver/pci/pci.o driver/disk/ahci/ahci.o \ -T link.lds head.o: head.S @@ -97,6 +97,9 @@ ata.o: driver/disk/ata.c pci.o: driver/pci/pci.c gcc $(CFLAGS) -c driver/pci/pci.c -o driver/pci/pci.o +ahci.o: driver/disk/ahci/ahci.c + gcc $(CFLAGS) -c driver/disk/ahci/ahci.c -o driver/disk/ahci/ahci.o + clean: rm -rf $(GARBAGE) \ No newline at end of file diff --git a/kernel/driver/disk/ahci/ahci.c b/kernel/driver/disk/ahci/ahci.c index 627c472b..a0977ece 100644 --- a/kernel/driver/disk/ahci/ahci.c +++ b/kernel/driver/disk/ahci/ahci.c @@ -1,3 +1,19 @@ #include "ahci.h" #include "../../../common/kprint.h" +struct pci_device_structure_header_t *ahci_devices[100]; +uint32_t count_ahci_devices = 0; + +/** + * @brief 初始化ahci模块 + * + */ +void ahci_init() +{ + pci_get_device_structure(0x1, 0x6, ahci_devices, &count_ahci_devices); + + for(int i=0;iClass_code, ahci_devices[i]->SubClass, ahci_devices[i]->ProgIF); + } +} \ No newline at end of file diff --git a/kernel/driver/disk/ahci/ahci.h b/kernel/driver/disk/ahci/ahci.h index fef6905c..335bd401 100644 --- a/kernel/driver/disk/ahci/ahci.h +++ b/kernel/driver/disk/ahci/ahci.h @@ -1,6 +1,7 @@ #pragma once #include "../block_device.h" +#include "../../pci/pci.h" /** * @brief 在SATA3.0规范中定义的Frame Information Structure类型 @@ -177,6 +178,28 @@ typedef struct tagFIS_DMA_SETUP } FIS_DMA_SETUP; +typedef volatile struct tagHBA_PORT +{ + uint32_t clb; // 0x00, command list base address, 1K-byte aligned + uint32_t clbu; // 0x04, command list base address upper 32 bits + uint32_t fb; // 0x08, FIS base address, 256-byte aligned + uint32_t fbu; // 0x0C, FIS base address upper 32 bits + uint32_t is; // 0x10, interrupt status + uint32_t ie; // 0x14, interrupt enable + uint32_t cmd; // 0x18, command and status + uint32_t rsv0; // 0x1C, Reserved + uint32_t tfd; // 0x20, task file data + uint32_t sig; // 0x24, signature + uint32_t ssts; // 0x28, SATA status (SCR0:SStatus) + uint32_t sctl; // 0x2C, SATA control (SCR2:SControl) + uint32_t serr; // 0x30, SATA error (SCR1:SError) + uint32_t sact; // 0x34, SATA active (SCR3:SActive) + uint32_t ci; // 0x38, command issue + uint32_t sntf; // 0x3C, SATA notification (SCR4:SNotification) + uint32_t fbs; // 0x40, FIS-based switch control + uint32_t rsv1[11]; // 0x44 ~ 0x6F, Reserved + uint32_t vendor[4]; // 0x70 ~ 0x7F, vendor specific +} HBA_PORT; typedef volatile struct tagHBA_MEM { // 0x00 - 0x2B, Generic Host Control @@ -202,28 +225,6 @@ typedef volatile struct tagHBA_MEM HBA_PORT ports[1]; // 1 ~ 32 } HBA_MEM; -typedef volatile struct tagHBA_PORT -{ - uint32_t clb; // 0x00, command list base address, 1K-byte aligned - uint32_t clbu; // 0x04, command list base address upper 32 bits - uint32_t fb; // 0x08, FIS base address, 256-byte aligned - uint32_t fbu; // 0x0C, FIS base address upper 32 bits - uint32_t is; // 0x10, interrupt status - uint32_t ie; // 0x14, interrupt enable - uint32_t cmd; // 0x18, command and status - uint32_t rsv0; // 0x1C, Reserved - uint32_t tfd; // 0x20, task file data - uint32_t sig; // 0x24, signature - uint32_t ssts; // 0x28, SATA status (SCR0:SStatus) - uint32_t sctl; // 0x2C, SATA control (SCR2:SControl) - uint32_t serr; // 0x30, SATA error (SCR1:SError) - uint32_t sact; // 0x34, SATA active (SCR3:SActive) - uint32_t ci; // 0x38, command issue - uint32_t sntf; // 0x3C, SATA notification (SCR4:SNotification) - uint32_t fbs; // 0x40, FIS-based switch control - uint32_t rsv1[11]; // 0x44 ~ 0x6F, Reserved - uint32_t vendor[4]; // 0x70 ~ 0x7F, vendor specific -} HBA_PORT; // There are four kinds of FIS which may be sent to the host by the device as indicated in the following structure declaration. // @@ -279,6 +280,19 @@ typedef struct tagHBA_CMD_HEADER uint32_t rsv1[4]; // Reserved } HBA_CMD_HEADER; +typedef struct tagHBA_PRDT_ENTRY +{ + uint32_t dba; // Data base address + uint32_t dbau; // Data base address upper 32 bits + uint32_t rsv0; // Reserved + + // DW3 + uint32_t dbc:22; // Byte count, 4M max + uint32_t rsv1:9; // Reserved + uint32_t i:1; // Interrupt on completion +} HBA_PRDT_ENTRY; + + typedef struct tagHBA_CMD_TBL { // 0x00 @@ -294,24 +308,38 @@ typedef struct tagHBA_CMD_TBL HBA_PRDT_ENTRY prdt_entry[1]; // Physical region descriptor table entries, 0 ~ 65535 } HBA_CMD_TBL; -typedef struct tagHBA_PRDT_ENTRY -{ - uint32_t dba; // Data base address - uint32_t dbau; // Data base address upper 32 bits - uint32_t rsv0; // Reserved + + +#define SATA_SIG_ATA 0x00000101 // SATA drive +#define SATA_SIG_ATAPI 0xEB140101 // SATAPI drive +#define SATA_SIG_SEMB 0xC33C0101 // Enclosure management bridge +#define SATA_SIG_PM 0x96690101 // Port multiplier - // DW3 - uint32_t dbc:22; // Byte count, 4M max - uint32_t rsv1:9; // Reserved - uint32_t i:1; // Interrupt on completion -} HBA_PRDT_ENTRY; +#define AHCI_DEV_NULL 0 +#define AHCI_DEV_SATA 1 +#define AHCI_DEV_SEMB 2 +#define AHCI_DEV_PM 3 +#define AHCI_DEV_SATAPI 4 + +#define HBA_PORT_IPM_ACTIVE 1 +#define HBA_PORT_DET_PRESENT 3 + + struct block_device_request_queue ahci_req_queue; +/* struct block_device_operation ahci_operation = { .open = ahci_open, .close = ahci_close, .ioctl = ahci_ioctl, .transfer = ahci_transfer, -}; \ No newline at end of file +}; +*/ + +/** + * @brief 初始化ahci模块 + * + */ +void ahci_init(); \ No newline at end of file diff --git a/kernel/driver/pci/pci.c b/kernel/driver/pci/pci.c index c8f1e235..75660902 100644 --- a/kernel/driver/pci/pci.c +++ b/kernel/driver/pci/pci.c @@ -436,7 +436,7 @@ void pci_checkAllBuses() void pci_init() { - kinfo("Initializing PCI bus!"); + kinfo("Initializing PCI bus..."); pci_checkAllBuses(); kinfo("Total pci device and function num = %d", count_device_list); @@ -531,7 +531,7 @@ int pci_enable_msi(void *header, uint8_t vector, uint32_t processor, uint8_t edg pci_write_config(ptr->bus, ptr->device, ptr->func, cap_ptr, tmp); break; - + case 0x01: // pci to pci bridge if (!(ptr->Status & 0x10)) return E_NOT_SUPPORT_MSI; @@ -574,4 +574,32 @@ int pci_enable_msi(void *header, uint8_t vector, uint32_t processor, uint8_t edg } return 0; +} + +/** + * @brief 获取 device structure + * + * @param class_code + * @param sub_class + * @param res 返回的结果数组 + */ +void pci_get_device_structure(uint8_t class_code, uint8_t sub_class, struct pci_device_structure_header_t *res[], uint32_t *count_res) +{ + + struct pci_device_structure_header_t *ptr_begin = container_of(pci_device_structure_list, struct pci_device_structure_header_t, list); + struct pci_device_structure_header_t *ptr = container_of(pci_device_structure_list, struct pci_device_structure_header_t, list); + *count_res = 0; + + for (int i = 0; i < count_device_list; ++i) + { + if ((ptr->Class_code == 1) && (ptr->SubClass == 6)) + { + kdebug("[%d] class_code=%d, sub_class=%d, progIF=%d", i, ptr->Class_code, ptr->SubClass, ptr->ProgIF); + + res[*count_res] = ptr; + ++(*count_res); + } + ptr = container_of(list_next(&(ptr->list)), struct pci_device_structure_header_t, list); + } + } \ No newline at end of file diff --git a/kernel/driver/pci/pci.h b/kernel/driver/pci/pci.h index 053e40e0..4f0c76e1 100644 --- a/kernel/driver/pci/pci.h +++ b/kernel/driver/pci/pci.h @@ -216,4 +216,13 @@ void pci_checkAllBuses(); * * @return 返回码 */ -int pci_enable_msi(void * header, uint8_t vector, uint32_t processor, uint8_t edge_trigger, uint8_t assert); \ No newline at end of file +int pci_enable_msi(void * header, uint8_t vector, uint32_t processor, uint8_t edge_trigger, uint8_t assert); + +/** + * @brief 获取 device structure + * + * @param class_code + * @param sub_class + * @param res 返回的结果数组 + */ +void pci_get_device_structure(uint8_t class_code, uint8_t sub_class, struct pci_device_structure_header_t* res[], uint32_t* count_res); diff --git a/kernel/main.c b/kernel/main.c index f8d9e6de..d621408b 100644 --- a/kernel/main.c +++ b/kernel/main.c @@ -19,6 +19,7 @@ #include "driver/mouse/ps2_mouse.h" #include "driver/disk/ata.h" #include "driver/pci/pci.h" +#include "driver/disk/ahci/ahci.h" unsigned int *FR_address = (unsigned int *)0xb8000; //帧缓存区的地址 @@ -168,6 +169,7 @@ void system_initialize() //ps2_mouse_init(); ata_init(); pci_init(); + ahci_init(); // test_slab(); // test_mm();