Merge branch 'usb'

This commit is contained in:
fslongjin 2022-07-19 18:33:40 +08:00
commit 11bb8fb505
6 changed files with 162 additions and 8 deletions

View File

@ -22,6 +22,7 @@
kernel/process_management/index
kernel/filesystem/index
kernel/debug/index
kernel/cpu_arch/index
.. toctree::

View File

@ -0,0 +1,10 @@
处理器架构
====================================
该部分文档提供了和处理器架构相关的一些编程实现细节的描述。
.. toctree::
:maxdepth: 1
:caption: 目录
x86_64/index

View File

@ -0,0 +1,8 @@
x86-64相关文档
====================================
.. toctree::
:maxdepth: 1
:caption: 目录
usb_legacy_support

View File

@ -0,0 +1,9 @@
# USB Legacy支持
## 简介
  usb legacy support指的是由BIOS提供的对USB鼠标、USB键盘的支持。在支持并启用USB Legacy Support的计算机上USB鼠标、键盘由BIOS提供模拟在操作系统看来就像接入了PS/2鼠标、键盘一样。
## 相关
- 在初始化USB控制器时需要关闭它的USB Legacy Support

View File

@ -4,6 +4,7 @@
#include <process/spinlock.h>
#include <mm/mm.h>
#include <debug/traceback/traceback.h>
#include <common/time.h>
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);
// 计算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);
// 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);
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;

View File

@ -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端口信息
@ -92,6 +153,7 @@ struct xhci_host_controller_t
struct pci_device_structure_general_device_t *pci_dev_hdr; // 指向pci header结构体的指针
int controller_id; // 操作系统给controller的编号
uint64_t vbase; // 虚拟地址basebar0映射到的虚拟地址
uint64_t vbase_op; // Operational registers 起始虚拟地址
struct xhci_port_info_t *ports; // 指向端口信息数组的指针
};