mirror of
https://github.com/DragonOS-Community/DragonOS.git
synced 2025-06-09 07:06:47 +00:00
Merge branch 'usb'
This commit is contained in:
commit
11bb8fb505
@ -22,6 +22,7 @@
|
||||
kernel/process_management/index
|
||||
kernel/filesystem/index
|
||||
kernel/debug/index
|
||||
kernel/cpu_arch/index
|
||||
|
||||
|
||||
.. toctree::
|
||||
|
10
docs/kernel/cpu_arch/index.rst
Normal file
10
docs/kernel/cpu_arch/index.rst
Normal file
@ -0,0 +1,10 @@
|
||||
处理器架构
|
||||
====================================
|
||||
|
||||
该部分文档提供了和处理器架构相关的一些编程实现细节的描述。
|
||||
|
||||
.. toctree::
|
||||
:maxdepth: 1
|
||||
:caption: 目录
|
||||
|
||||
x86_64/index
|
8
docs/kernel/cpu_arch/x86_64/index.rst
Normal file
8
docs/kernel/cpu_arch/x86_64/index.rst
Normal file
@ -0,0 +1,8 @@
|
||||
x86-64相关文档
|
||||
====================================
|
||||
|
||||
.. toctree::
|
||||
:maxdepth: 1
|
||||
:caption: 目录
|
||||
|
||||
usb_legacy_support
|
9
docs/kernel/cpu_arch/x86_64/usb_legacy_support.md
Normal file
9
docs/kernel/cpu_arch/x86_64/usb_legacy_support.md
Normal file
@ -0,0 +1,9 @@
|
||||
# USB Legacy支持
|
||||
|
||||
## 简介
|
||||
|
||||
  usb legacy support指的是,由BIOS提供的,对USB鼠标、USB键盘的支持。在支持并启用USB Legacy Support的计算机上,USB鼠标、键盘由BIOS提供模拟,在操作系统看来,就像接入了PS/2鼠标、键盘一样。
|
||||
|
||||
## 相关
|
||||
|
||||
- 在初始化USB控制器时,需要关闭它的USB Legacy Support
|
@ -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);
|
||||
|
||||
// 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;
|
||||
|
@ -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; // 指向端口信息数组的指针
|
||||
};
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user