소스 검색

Merge branch 'usb'

fslongjin 2 년 전
부모
커밋
4deb85369f
7개의 변경된 파일76개의 추가작업 그리고 10개의 파일을 삭제
  1. 2 2
      kernel/debug/bug.h
  2. 2 2
      kernel/driver/disk/ahci/ahci.c
  3. 6 1
      kernel/driver/usb/usb.c
  4. 19 2
      kernel/driver/usb/xhci/xhci.c
  5. 45 2
      kernel/driver/usb/xhci/xhci.h
  6. 1 0
      kernel/mm/mm.h
  7. 1 1
      kernel/smp/smp.c

+ 2 - 2
kernel/debug/bug.h

@@ -4,11 +4,11 @@
 
 /**
  * @brief 当condition为true时输出警告信息
- * 
+ *
  */
 #define WARN_ON(condition) ({                                   \
     int __ret_warn_on = !!(condition);                          \
     if (unlikely(__ret_warn_on))                                \
         kwarn("Assertion failed at %s:%d", __FILE__, __LINE__); \
     unlikely(__ret_warn_on);                                    \
-})
+})

+ 2 - 2
kernel/driver/disk/ahci/ahci.c

@@ -10,8 +10,8 @@ struct block_device_request_queue ahci_req_queue;
 
 uint32_t count_ahci_devices = 0;
 
-uint64_t ahci_port_base_vaddr;     // 端口映射base addr
-uint64_t ahci_port_base_phys_addr; // 端口映射的物理基地址(ahci控制器的参数的地址都是物理地址)
+static uint64_t ahci_port_base_vaddr;     // 端口映射base addr
+static uint64_t ahci_port_base_phys_addr; // 端口映射的物理基地址(ahci控制器的参数的地址都是物理地址)
 
 static void start_cmd(HBA_PORT *port);
 static void stop_cmd(HBA_PORT *port);

+ 6 - 1
kernel/driver/usb/usb.c

@@ -3,6 +3,9 @@
 #include <common/kprint.h>
 #include <driver/pci/pci.h>
 #include <debug/bug.h>
+#include <process/spinlock.h>
+
+extern spinlock_t xhci_controller_init_lock; // xhci控制器初始化锁
 
 #define MAX_USB_NUM 8 // pci总线上的usb设备的最大数量
 
@@ -17,6 +20,8 @@ static int usb_pdevs_count = 0;
 void usb_init()
 {
     kinfo("Initializing usb driver...");
+    spin_init(&xhci_controller_init_lock);
+
     // 获取所有usb-pci设备的列表
     pci_get_device_structure(USB_CLASS, USB_SUBCLASS, usb_pdevs, &usb_pdevs_count);
 
@@ -41,7 +46,7 @@ void usb_init()
 
         case USB_TYPE_XHCI:
             // 初始化对应的xhci控制器
-            xhci_init(usb_pdevs[i]);
+            xhci_init((struct pci_device_structure_general_device_t *)usb_pdevs[i]);
             break;
 
         default:

+ 19 - 2
kernel/driver/usb/xhci/xhci.c

@@ -1,11 +1,28 @@
 #include "xhci.h"
+#include <common/kprint.h>
+#include <debug/bug.h>
+#include <process/spinlock.h>
+
+spinlock_t xhci_controller_init_lock; // xhci控制器初始化锁(在usb_init中被初始化)
+
+static int xhci_ctrl_count = 0;    // xhci控制器计数
+
+
 
 /**
  * @brief 初始化xhci控制器
- * 
+ *
  * @param header 指定控制器的pci device头部
  */
-void xhci_init(struct pci_device_structure_header_t *header)
+void xhci_init(struct pci_device_structure_general_device_t *dev_hdr)
 {
+    spin_lock(&xhci_controller_init_lock);
+    kinfo("Initializing xhci host controller: bus=%#02x, device=%#02x, func=%#02x, VendorID=%#04x, irq_line=%d, irq_pin=%d", dev_hdr->header.bus, dev_hdr->header.device, dev_hdr->header.func, dev_hdr->header.Vendor_ID, dev_hdr->Interrupt_Line, dev_hdr->Interrupt_PIN );
+
+    pci_write_config(dev_hdr->header.bus, dev_hdr->header.device, dev_hdr->header.func, 0x4, 0x0006); // mem I/O access enable and bus master enable
+
+
     
+    ++xhci_ctrl_count;
+    spin_unlock(&xhci_controller_init_lock);
 }

+ 45 - 2
kernel/driver/usb/xhci/xhci.h

@@ -1,9 +1,52 @@
 #pragma once
 #include <driver/usb/usb.h>
+#include <driver/pci/pci.h>
+
+// xhci Capability Registers offset
+#define XHCI_CAPS_CAPLENGTH 0x00 // Cap 寄存器组的长度
+#define XHCI_CAPS_RESERVED 0x01
+#define XHCI_CAPS_HCIVERSION 0x02 // 接口版本号
+#define XHCI_CAPS_HCSPARAMS1 0x04
+#define XHCI_CAPS_HCSPARAMS2 0x08
+#define XHCI_CAPS_HCSPARAMS3 0x0c
+#define XHCI_CAPS_HCCPARAMS1 0x10 // capability params 1
+#define XHCI_CAPS_DBOFF 0x14      // Doorbell offset
+#define XHCI_CAPS_RTSOFF 0x18     // Runtime register space offset
+#define XHCI_CAPS_HCCPARAMS2 0x1c // capability params 2
+
+
+struct xhci_caps_HCSPARAMS1_reg_t
+{
+    unsigned max_slots : 8;  // 最大插槽数
+    unsigned max_intrs : 11; // 最大中断数
+    unsigned reserved : 5;
+    unsigned max_ports : 8; // 最大端口数
+}__attribute__((packed));
+
+
+/**
+ * @brief xhci端口信息
+ *
+ */
+struct xhci_port_info_t
+{
+    uint8_t flags;           // port flags
+    uint8_t paired_port_num; // 与当前端口所配对的另一个端口(相同物理接口的不同速度的port)
+    uint8_t offset;          // offset of this port within this protocal
+    uint8_t reserved;
+} __attribute__((packed));
+
+struct xhci_controller_t
+{
+    struct pci_device_structure_general_device_t *pci_dev_hdr; // 指向pci header结构体的指针
+    int controller_id;                                         // 操作系统给controller的编号
+    int vbase;                                                 // 虚拟地址base(bar0映射到的虚拟地址)
+    struct xhci_port_info_t *ports;                            // 指向端口信息数组的指针
+};
 
 /**
  * @brief 初始化xhci控制器
- * 
+ *
  * @param header 指定控制器的pci device头部
  */
-void xhci_init(struct pci_device_structure_header_t *header);
+void xhci_init(struct pci_device_structure_general_device_t *header);

+ 1 - 0
kernel/mm/mm.h

@@ -44,6 +44,7 @@
 #define IO_APIC_MAPPING_OFFSET 0xfec00000UL
 #define LOCAL_APIC_MAPPING_OFFSET 0xfee00000UL
 #define AHCI_MAPPING_OFFSET 0xff200000UL // AHCI 映射偏移量,之后使用了4M的地址
+#define XHCI_MAPPING_OFFSET 0x100000000  // XHCI控制器映射偏移量(后方请预留1GB的虚拟空间来映射不同的controller)
 
 // ===== 内存区域属性 =====
 // DMA区域

+ 1 - 1
kernel/smp/smp.c

@@ -156,7 +156,7 @@ void smp_ap_start()
     spin_unlock(&multi_core_starting_lock);
     preempt_disable();// 由于ap处理器的pcb与bsp的不同,因此ap处理器放锁时,需要手动恢复preempt count
     sti();
-    kdebug("1212221212");
+
     while (1)
         hlt();