From 22d8fa371d4604c6deb3625347670dc3a3bda1ca Mon Sep 17 00:00:00 2001 From: fslongjin Date: Mon, 18 Jul 2022 21:22:06 +0800 Subject: [PATCH 1/2] =?UTF-8?q?usb=20ops=E5=AF=84=E5=AD=98=E5=99=A8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- kernel/driver/usb/xhci/xhci.c | 78 +++++++++++++++++++++++++++++++---- kernel/driver/usb/xhci/xhci.h | 64 +++++++++++++++++++++++++++- 2 files changed, 134 insertions(+), 8 deletions(-) diff --git a/kernel/driver/usb/xhci/xhci.c b/kernel/driver/usb/xhci/xhci.c index 1b88ec37..5ce992ad 100644 --- a/kernel/driver/usb/xhci/xhci.c +++ b/kernel/driver/usb/xhci/xhci.c @@ -4,6 +4,7 @@ #include #include #include +#include spinlock_t xhci_controller_init_lock; // xhci控制器初始化锁(在usb_init中被初始化) @@ -11,6 +12,62 @@ static int xhci_ctrl_count = 0; // xhci控制器计数 static struct xhci_host_controller_t xhci_hc[MAX_XHCI_HOST_CONTROLLERS] = {0}; +#define xhci_read_cap_reg8(id, offset) (*(uint8_t *)(xhci_hc[id].vbase + offset)) +#define xhci_write_cap_reg8(id, offset, value) (*(uint8_t *)(xhci_hc[id].vbase + offset) = (uint8_t)value) +#define xhci_read_cap_reg32(id, offset) (*(uint32_t *)(xhci_hc[id].vbase + offset)) +#define xhci_write_cap_reg32(id, offset, value) (*(uint32_t *)(xhci_hc[id].vbase + offset) = (uint32_t)value) +#define xhci_read_cap_reg64(id, offset) (*(uint64_t *)(xhci_hc[id].vbase + offset)) +#define xhci_write_cap_reg64(id, offset, value) (*(uint64_t *)(xhci_hc[id].vbase + offset) = (uint64_t)value) + +#define xhci_read_op_reg8(id, offset) (*(uint8_t *)(xhci_hc[id].vbase_op + offset)) +#define xhci_write_op_reg8(id, offset, value) (*(uint8_t *)(xhci_hc[id].vbase_op + offset) = (uint8_t)value) +#define xhci_read_op_reg32(id, offset) (*(uint32_t *)(xhci_hc[id].vbase_op + offset)) +#define xhci_write_op_reg32(id, offset, value) (*(uint32_t *)(xhci_hc[id].vbase_op + offset) = (uint32_t)value) +#define xhci_read_op_reg64(id, offset) (*(uint64_t *)(xhci_hc[id].vbase_op + offset)) +#define xhci_write_op_reg64(id, offset, value) (*(uint64_t *)(xhci_hc[id].vbase_op + offset) = (uint64_t)value) + +/** + * @brief 停止xhci主机控制器 + * + * @param id 主机控制器id + * @return int + */ +static int xhci_hc_stop(int id) +{ + // todo: 停止usb控制器 +} + +/** + * @brief reset xHCI主机控制器 + * + * @param id 主机控制器id + * @return int + */ +static int xhci_hc_reset(int id) +{ + int retval = 0; + // 判断HCHalted是否置位 + if ((xhci_read_op_reg32(id, XHCI_OPS_USBSTS) & (1 << 0)) == 0) + { + // 未置位,需要先尝试停止usb主机控制器 + retval = xhci_hc_stop(id); + if (retval) + return retval; + } + int timeout = 500; // wait 500ms + // reset + xhci_write_cap_reg32(id, XHCI_OPS_USBCMD, (1 << 1)); + usleep(1000); + while (xhci_read_op_reg32(id, XHCI_OPS_USBCMD) & (1 << 1)) + { + usleep(1000); + if (--timeout == 0) + return -ETIMEDOUT; + } + kdebug("reset done!, timeout=%d", timeout); + return retval; +} + /** * @brief 初始化xhci控制器 * @@ -32,19 +89,26 @@ void xhci_init(struct pci_device_structure_general_device_t *dev_hdr) // 读取xhci控制寄存器 uint16_t iversion = *(uint16_t *)(xhci_hc[xhci_ctrl_count].vbase + XHCI_CAPS_HCIVERSION); - uint32_t dboff = *(uint16_t *)(xhci_hc[xhci_ctrl_count].vbase + XHCI_CAPS_DBOFF); - - // kdebug("dboff=%ld", dboff); - // struct xhci_caps_HCSPARAMS1_reg_t hcs1 = *(struct xhci_caps_HCSPARAMS1_reg_t *)(xhci_hc[xhci_ctrl_count].vbase + XHCI_CAPS_HCSPARAMS1); - // kdebug("hcs1.max_ports=%d, hcs1.max_slots=%d, hcs1.max_intrs=%d", hcs1.max_ports, hcs1.max_slots, hcs1.max_intrs); - // kdebug("caps size=%d", *(uint8_t *)xhci_hc[xhci_ctrl_count].vbase); - // kdebug("iversion=%#06x", iversion); + // 计算operational registers的地址 + xhci_hc[xhci_ctrl_count].vbase_op = xhci_hc[xhci_ctrl_count].vbase + xhci_read_cap_reg8(xhci_ctrl_count, XHCI_CAPS_CAPLENGTH); + if (iversion < 0x95) { kwarn("Unsupported/Unknowned xHCI controller version: %#06x. This may cause unexpected behavior.", iversion); } + // if it is a Panther Point device, make sure sockets are xHCI controlled. + if (((pci_read_config(dev_hdr->header.bus, dev_hdr->header.device, dev_hdr->header.func, 0) & 0xffff) == 0x8086) && + ((pci_read_config(dev_hdr->header.bus, dev_hdr->header.device, dev_hdr->header.func, 2) & 0xffff) == 0x1E31) && + ((pci_read_config(dev_hdr->header.bus, dev_hdr->header.device, dev_hdr->header.func, 8) & 0xff) == 4)) + { + kdebug("Is a Panther Point device"); + pci_write_config(dev_hdr->header.bus, dev_hdr->header.device, dev_hdr->header.func, 0xd8, 0xffffffff); + pci_write_config(dev_hdr->header.bus, dev_hdr->header.device, dev_hdr->header.func, 0xd0, 0xffffffff); + } + + xhci_hc_reset(xhci_ctrl_count); ++xhci_ctrl_count; spin_unlock(&xhci_controller_init_lock); return; diff --git a/kernel/driver/usb/xhci/xhci.h b/kernel/driver/usb/xhci/xhci.h index 5f1981b5..5e408bd1 100644 --- a/kernel/driver/usb/xhci/xhci.h +++ b/kernel/driver/usb/xhci/xhci.h @@ -73,7 +73,68 @@ struct xhci_caps_HCCPARAMS2_reg_t unsigned Reserved : 26; } __attribute__((packed)); +// xhci operational registers offset +#define XHCI_OPS_USBCMD 0x00 // USB Command +#define XHCI_OPS_USBSTS 0x04 // USB status +#define XHCI_OPS_PAGESIZE 0x08 // Page size +#define XHCI_OPS_DNCTRL 0x14 // Device notification control +#define XHCI_OPS_CRCR 0x18 // Command ring control +#define XHCI_OPS_DCBAAP 0x30 // Device context base address array pointer +#define XHCI_OPS_CONFIG 0x38 // configuire +#define XHCI_OPS_PRS 0x400 // Port register sets +struct xhci_ops_usbcmd_reg_t +{ + unsigned rs : 1; // Run/Stop + unsigned hcrst : 1; // host controller reset + unsigned inte : 1; // Interrupt enable + unsigned hsee : 1; // Host system error enable + unsigned rsvd_psvd1 : 3; // Reserved and preserved + unsigned lhcrst : 1; // light host controller reset + unsigned css : 1; // controller save state + unsigned crs : 1; // controller restore state + unsigned ewe : 1; // enable wrap event + unsigned ue3s : 1; // enable U3 MFINDEX Stop + unsigned spe : 1; // stopped short packet enable + unsigned cme : 1; // CEM Enable + unsigned rsvd_psvd2 : 18; // Reserved and preserved +} __attribute__((packed)); + +struct xhci_ops_usbsts_reg_t +{ + unsigned HCHalted : 1; + unsigned rsvd_psvd1 : 1; // Reserved and preserved + unsigned hse : 1; // Host system error + unsigned eint : 1; // event interrupt + unsigned pcd : 1; // Port change detected + unsigned rsvd_zerod : 3; // Reserved and Zero'd + unsigned sss : 1; // Save State Status + unsigned rss : 1; // restore state status + unsigned sre : 1; // save/restore error + unsigned cnr : 1; // controller not ready + unsigned hce : 1; // host controller error + unsigned rsvd_psvd2 : 19; // Reserved and Preserved +} __attribute__((packed)); + +struct xhci_ops_pagesize_reg_t +{ + uint16_t page_size; // The actual pagesize is ((this field)<<12) + uint16_t reserved; +} __attribute__((packed)); + +struct xhci_ops_dnctrl_reg_t +{ + uint16_t value; + uint16_t reserved; +} __attribute__((packed)); + +struct xhci_ops_config_reg_t +{ + uint8_t MaxSlotsEn; // Max slots enabled + unsigned u3e : 1; // U3 Entry Enable + unsigned cie : 1; // Configuration information enable + unsigned rsvd_psvd : 22; // Reserved and Preserved +} __attribute__((packed)); /** * @brief xhci端口信息 @@ -91,7 +152,8 @@ struct xhci_host_controller_t { struct pci_device_structure_general_device_t *pci_dev_hdr; // 指向pci header结构体的指针 int controller_id; // 操作系统给controller的编号 - uint64_t vbase; // 虚拟地址base(bar0映射到的虚拟地址) + uint64_t vbase; // 虚拟地址base(bar0映射到的虚拟地址) + uint64_t vbase_op; // Operational registers 起始虚拟地址 struct xhci_port_info_t *ports; // 指向端口信息数组的指针 }; From fe42398090484b2293da342ec8fe0af0bae1fd12 Mon Sep 17 00:00:00 2001 From: fslongjin Date: Tue, 19 Jul 2022 18:26:13 +0800 Subject: [PATCH 2/2] doc: usb legacy support --- docs/index.rst | 1 + docs/kernel/cpu_arch/index.rst | 10 ++++++++++ docs/kernel/cpu_arch/x86_64/index.rst | 8 ++++++++ docs/kernel/cpu_arch/x86_64/usb_legacy_support.md | 9 +++++++++ docs/kernel/debug/index.rst | 2 +- 5 files changed, 29 insertions(+), 1 deletion(-) create mode 100644 docs/kernel/cpu_arch/index.rst create mode 100644 docs/kernel/cpu_arch/x86_64/index.rst create mode 100644 docs/kernel/cpu_arch/x86_64/usb_legacy_support.md diff --git a/docs/index.rst b/docs/index.rst index 748ce3a9..82206d7a 100644 --- a/docs/index.rst +++ b/docs/index.rst @@ -22,6 +22,7 @@ kernel/process_management/index kernel/filesystem/index kernel/debug/index + kernel/cpu_arch/index .. toctree:: diff --git a/docs/kernel/cpu_arch/index.rst b/docs/kernel/cpu_arch/index.rst new file mode 100644 index 00000000..0f8f9dde --- /dev/null +++ b/docs/kernel/cpu_arch/index.rst @@ -0,0 +1,10 @@ +处理器架构 +==================================== + + 该部分文档提供了和处理器架构相关的一些编程实现细节的描述。 + +.. toctree:: + :maxdepth: 1 + :caption: 目录 + + x86_64/index diff --git a/docs/kernel/cpu_arch/x86_64/index.rst b/docs/kernel/cpu_arch/x86_64/index.rst new file mode 100644 index 00000000..70e4c658 --- /dev/null +++ b/docs/kernel/cpu_arch/x86_64/index.rst @@ -0,0 +1,8 @@ +x86-64相关文档 +==================================== + +.. toctree:: + :maxdepth: 1 + :caption: 目录 + + usb_legacy_support diff --git a/docs/kernel/cpu_arch/x86_64/usb_legacy_support.md b/docs/kernel/cpu_arch/x86_64/usb_legacy_support.md new file mode 100644 index 00000000..7026e21c --- /dev/null +++ b/docs/kernel/cpu_arch/x86_64/usb_legacy_support.md @@ -0,0 +1,9 @@ +# USB Legacy支持 + +## 简介 + +  usb legacy support指的是,由BIOS提供的,对USB鼠标、USB键盘的支持。在支持并启用USB Legacy Support的计算机上,USB鼠标、键盘由BIOS提供模拟,在操作系统看来,就像接入了PS/2鼠标、键盘一样。 + +## 相关 + +- 在初始化USB控制器时,需要关闭它的USB Legacy Support diff --git a/docs/kernel/debug/index.rst b/docs/kernel/debug/index.rst index 2e874265..5e6a640b 100644 --- a/docs/kernel/debug/index.rst +++ b/docs/kernel/debug/index.rst @@ -7,4 +7,4 @@ :maxdepth: 1 :caption: 目录 - kernel_api + traceback