浏览代码

:new: 按照class来读取对应的pci设备的接口

fslongjin 3 年之前
父节点
当前提交
741aa09b9b
共有 6 个文件被更改,包括 124 次插入38 次删除
  1. 5 2
      kernel/Makefile
  2. 16 0
      kernel/driver/disk/ahci/ahci.c
  3. 61 33
      kernel/driver/disk/ahci/ahci.h
  4. 30 2
      kernel/driver/pci/pci.c
  5. 10 1
      kernel/driver/pci/pci.h
  6. 2 0
      kernel/main.c

+ 5 - 2
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)

+ 16 - 0
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;i<count_ahci_devices;++i)
+    {
+        kdebug("[%d]  class_code=%d, sub_class=%d, progIF=%d", i, ahci_devices[i]->Class_code, ahci_devices[i]->SubClass, ahci_devices[i]->ProgIF);
+    }
+}

+ 61 - 33
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,
-};
+};
+*/
+
+/**
+ * @brief 初始化ahci模块
+ * 
+ */
+void ahci_init();

+ 30 - 2
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);
+    }
+    
 }

+ 10 - 1
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);
+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);

+ 2 - 0
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();