new: stop legacy

This commit is contained in:
fslongjin 2022-07-19 21:17:44 +08:00
parent fe42398090
commit 7af8711bbb
2 changed files with 208 additions and 32 deletions

View File

@ -10,22 +10,68 @@ spinlock_t xhci_controller_init_lock; // xhci控制器初始化锁(在usb_init
static int xhci_ctrl_count = 0; // xhci控制器计数
static struct xhci_host_controller_t xhci_hc[MAX_XHCI_HOST_CONTROLLERS] = {0};
static struct xhci_host_controller_t xhci_hc[XHCI_MAX_HOST_CONTROLLERS] = {0};
/*
MMI/O的方式访问寄存器
32bit的寄存器中的偏移量8的位置开始读取1个字节
32bit的寄存器的0地址处开始读取32bit
*/
#define xhci_read_cap_reg8(id, offset) (*(uint8_t *)(xhci_hc[id].vbase + offset))
#define xhci_get_ptr_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_get_ptr_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_get_ptr_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_get_ptr_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_get_ptr_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_get_ptr_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)
#define FAIL_ON(value, to) \
do \
{ \
if (unlikely(value != 0)) \
goto to; \
} while (0)
/**
* @brief controller数组之中寻找可用插槽
*
* init锁的进程所调用
* @return int id(-1)
*/
static int xhci_hc_find_available_id()
{
if (unlikely(xhci_ctrl_count >= XHCI_MAX_HOST_CONTROLLERS))
return -1;
for (int i = 0; i < XHCI_MAX_HOST_CONTROLLERS; ++i)
{
if (xhci_hc[i].pci_dev_hdr = NULL)
return i;
}
return -1;
}
/**
* @brief xhci主机控制器
*
@ -34,7 +80,21 @@ static struct xhci_host_controller_t xhci_hc[MAX_XHCI_HOST_CONTROLLERS] = {0};
*/
static int xhci_hc_stop(int id)
{
// todo: 停止usb控制器
// 判断是否已经停止
if (unlikely((xhci_read_op_reg32(id, XHCI_OPS_USBSTS) & (1 << 0)) == 1))
return 0;
xhci_write_op_reg32(id, XHCI_OPS_USBCMD, 0x00000000);
char timeout = 17;
while ((xhci_read_op_reg32(id, XHCI_OPS_USBSTS) & (1 << 0)) == 0)
{
usleep(1000);
if (--timeout == 0)
return -ETIMEDOUT;
}
return 0;
}
/**
@ -51,23 +111,94 @@ static int xhci_hc_reset(int id)
{
// 未置位需要先尝试停止usb主机控制器
retval = xhci_hc_stop(id);
if (retval)
if (unlikely(retval))
return retval;
}
int timeout = 500; // wait 500ms
// reset
xhci_write_cap_reg32(id, XHCI_OPS_USBCMD, (1 << 1));
usleep(1000);
xhci_write_op_reg32(id, XHCI_OPS_USBCMD, (1 << 1));
while (xhci_read_op_reg32(id, XHCI_OPS_USBCMD) & (1 << 1))
{
usleep(1000);
if (--timeout == 0)
return -ETIMEDOUT;
}
kdebug("reset done!, timeout=%d", timeout);
// kdebug("reset done!, timeout=%d", timeout);
return retval;
}
/**
* @brief xhci控制器的legacy support
*
* @param id id
* @return int
*/
static int xhci_hc_stop_legacy(int id)
{
uint64_t current_offset = xhci_hc[id].ext_caps_off;
do
{
// 判断当前entry是否为legacy support entry
if (xhci_read_cap_reg8(id, current_offset) == XHCI_XECP_ID_LEGACY)
{
// 接管控制权
xhci_write_cap_reg32(id, current_offset, xhci_read_cap_reg32(id, current_offset) | XHCI_XECP_LEGACY_OS_OWNED);
// 等待响应完成
int timeout = XHCI_XECP_LEGACY_TIMEOUT;
while ((xhci_read_cap_reg32(id, current_offset) & XHCI_XECP_LEGACY_OWNING_MASK) != XHCI_XECP_LEGACY_OS_OWNED)
{
usleep(1000);
if (--timeout == 0)
{
kerror("The BIOS doesn't stop legacy support.");
return -ETIMEDOUT;
}
}
// 处理完成
return 0;
}
// 读取下一个entry的偏移增加量
int next_off = ((xhci_read_cap_reg32(id, current_offset) & 0xff00) >> 8) << 2;
// 将指针跳转到下一个entry
current_offset = next_off ? (current_offset + next_off) : 0;
} while (current_offset);
// 当前controller不存在legacy支持也问题不大不影响
return 0;
}
/**
* @brief xhci主机控制器的usb2usb3端口
*
* @param id id
* @return int
*/
static int xhci_hc_pair_ports(int id)
{
struct xhci_caps_HCCPARAMS1_reg_t hcc1;
struct xhci_caps_HCCPARAMS2_reg_t hcc2;
struct xhci_caps_HCSPARAMS1_reg_t hcs1;
struct xhci_caps_HCSPARAMS2_reg_t hcs2;
memcpy(&hcc1, xhci_get_ptr_cap_reg32(id, XHCI_CAPS_HCCPARAMS1), sizeof(struct xhci_caps_HCCPARAMS1_reg_t));
memcpy(&hcc2, xhci_get_ptr_cap_reg32(id, XHCI_CAPS_HCCPARAMS2), sizeof(struct xhci_caps_HCCPARAMS1_reg_t));
memcpy(&hcs1, xhci_get_ptr_cap_reg32(id, XHCI_CAPS_HCSPARAMS1), sizeof(struct xhci_caps_HCCPARAMS1_reg_t));
memcpy(&hcs2, xhci_get_ptr_cap_reg32(id, XHCI_CAPS_HCSPARAMS2), sizeof(struct xhci_caps_HCCPARAMS1_reg_t));
// 从hcs1获取端口数量
xhci_hc[id].port_num = hcs1.max_ports;
kinfo("Found %d ports on xhci root hub.", hcs1.max_ports);
// 找到所有的端口并标记其端口信息
return 0;
}
/**
* @brief xhci控制器
*
@ -75,23 +206,39 @@ static int xhci_hc_reset(int id)
*/
void xhci_init(struct pci_device_structure_general_device_t *dev_hdr)
{
if (xhci_ctrl_count >= XHCI_MAX_HOST_CONTROLLERS)
{
kerror("Initialize xhci controller failed: exceed the limit of max controllers.");
return;
}
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);
xhci_hc[xhci_ctrl_count].controller_id = xhci_ctrl_count;
xhci_hc[xhci_ctrl_count].pci_dev_hdr = dev_hdr;
int cid = xhci_hc_find_available_id();
memset(&xhci_hc[cid], 0, sizeof(struct xhci_host_controller_t));
xhci_hc[cid].controller_id = cid;
xhci_hc[cid].pci_dev_hdr = dev_hdr;
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_hc[xhci_ctrl_count].vbase = SPECIAL_MEMOEY_MAPPING_VIRT_ADDR_BASE + XHCI_MAPPING_OFFSET + PAGE_2M_SIZE * xhci_hc[xhci_ctrl_count].controller_id;
xhci_hc[cid].vbase = SPECIAL_MEMOEY_MAPPING_VIRT_ADDR_BASE + XHCI_MAPPING_OFFSET + PAGE_2M_SIZE * xhci_hc[cid].controller_id;
kdebug("dev_hdr->BAR0 & (~0xf)=%#018lx", dev_hdr->BAR0 & (~0xf));
mm_map_phys_addr(xhci_hc[xhci_ctrl_count].vbase, dev_hdr->BAR0 & (~0xf), 65536, PAGE_KERNEL_PAGE | PAGE_PWT | PAGE_PCD, true);
mm_map_phys_addr(xhci_hc[cid].vbase, dev_hdr->BAR0 & (~0xf), 65536, PAGE_KERNEL_PAGE | PAGE_PWT | PAGE_PCD, true);
// 读取xhci控制寄存器
uint16_t iversion = *(uint16_t *)(xhci_hc[xhci_ctrl_count].vbase + XHCI_CAPS_HCIVERSION);
uint16_t iversion = *(uint16_t *)(xhci_hc[cid].vbase + XHCI_CAPS_HCIVERSION);
uint32_t hcc1 = xhci_read_cap_reg32(cid, XHCI_CAPS_HCCPARAMS1);
// 计算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);
xhci_hc[cid].vbase_op = xhci_hc[cid].vbase + xhci_read_cap_reg8(cid, XHCI_CAPS_CAPLENGTH);
xhci_hc[cid].db_offset = xhci_read_cap_reg32(cid, XHCI_CAPS_DBOFF) & (~0x3); // bits [1:0] reserved
xhci_hc[cid].rts_offset = xhci_read_cap_reg32(cid, XHCI_CAPS_RTSOFF) & (~0x1f); // bits [4:0] reserved.
xhci_hc[cid].ext_caps_off = ((hcc1 & 0xffff0000) >> 16) * 4;
xhci_hc[cid].context_size = (hcc1 & (1 << 2)) ? 64 : 32;
if (iversion < 0x95)
{
@ -107,17 +254,21 @@ void xhci_init(struct pci_device_structure_general_device_t *dev_hdr)
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控制器
FAIL_ON(xhci_hc_reset(cid), failed);
FAIL_ON(xhci_hc_stop_legacy(cid), failed);
FAIL_ON(xhci_hc_pair_ports(cid), failed);
++xhci_ctrl_count;
spin_unlock(&xhci_controller_init_lock);
return;
failed:;
// 取消地址映射
mm_unmap(xhci_hc[xhci_ctrl_count].vbase, 65536);
mm_unmap(xhci_hc[cid].vbase, 65536);
// 清空数组
memset((void *)&xhci_hc[xhci_ctrl_count], 0, sizeof(struct xhci_host_controller_t));
memset((void *)&xhci_hc[cid], 0, sizeof(struct xhci_host_controller_t));
kerror("Failed to initialize controller: bus=%d, dev=%d, func=%d", dev_hdr->header.bus, dev_hdr->header.device, dev_hdr->header.func);
spin_unlock(&xhci_controller_init_lock);
}

View File

@ -2,7 +2,8 @@
#include <driver/usb/usb.h>
#include <driver/pci/pci.h>
#define MAX_XHCI_HOST_CONTROLLERS 8
#define XHCI_MAX_HOST_CONTROLLERS 8
#define XHCI_MAX_ROOT_HUB_PORTS 128
// xhci Capability Registers offset
#define XHCI_CAPS_CAPLENGTH 0x00 // Cap 寄存器组的长度
@ -43,20 +44,20 @@ struct xhci_caps_HCSPARAMS3_reg_t
struct xhci_caps_HCCPARAMS1_reg_t
{
unsigned ac64 : 1; // 64-bit addressing capability
unsigned bnc : 1; // bw negotiation capability
unsigned csz : 1; // context size
unsigned ppc : 1; // 端口电源控制
unsigned pind : 1; // port indicators
unsigned lhrc : 1; // Light HC reset capability
unsigned ltc : 1; // latency tolerance messaging capability
unsigned nss : 1; // no secondary SID support
unsigned int ac64 : 1; // 64-bit addressing capability
unsigned int bnc : 1; // bw negotiation capability
unsigned int csz : 1; // context size
unsigned int ppc : 1; // 端口电源控制
unsigned int pind : 1; // port indicators
unsigned int lhrc : 1; // Light HC reset capability
unsigned int ltc : 1; // latency tolerance messaging capability
unsigned int nss : 1; // no secondary SID support
unsigned pae : 1; // parse all event data
unsigned spc : 1; // Stopped - Short packet capability
unsigned sec : 1; // Stopped EDTLA capability
unsigned cfc : 1; // Continuous Frame ID capability
unsigned MaxPSASize : 4; // Max Primary Stream Array Size
unsigned int pae : 1; // parse all event data
unsigned int spc : 1; // Stopped - Short packet capability
unsigned int sec : 1; // Stopped EDTLA capability
unsigned int cfc : 1; // Continuous Frame ID capability
unsigned int MaxPSASize : 4; // Max Primary Stream Array Size
uint16_t xECP; // xhci extended capabilities pointer
@ -136,6 +137,23 @@ struct xhci_ops_config_reg_t
unsigned rsvd_psvd : 22; // Reserved and Preserved
} __attribute__((packed));
// xhci Extended Capabilities List ID
// ID 部分的含义定义
#define XHCI_XECP_ID_RESERVED 0
#define XHCI_XECP_ID_LEGACY 1 // USB Legacy Support
#define XHCI_XECP_ID_PROTOCAL 2 // Supported protocal
#define XHCI_XECP_ID_POWER 3 // Extended power management
#define XHCI_XECP_ID_IOVIRT 4 // I/0 virtualization
#define XHCI_XECP_ID_MSG 5 // Message interrupt
#define XHCI_XECP_ID_LOCAL_MEM 6 // local memory
#define XHCI_XECP_ID_DEBUG 10 // USB Debug capability
#define XHCI_XECP_ID_EXTMSG 17 // Extended message interrupt
#define XHCI_XECP_LEGACY_TIMEOUT 10 // 设置legacy状态的等待时间
#define XHCI_XECP_LEGACY_BIOS_OWNED (1 << 16) // 当bios控制着该hc时该位被置位
#define XHCI_XECP_LEGACY_OS_OWNED (1 << 24) // 当系统控制着该hc时该位被置位
#define XHCI_XECP_LEGACY_OWNING_MASK (XHCI_XECP_LEGACY_BIOS_OWNED | XHCI_XECP_LEGACY_OS_OWNED)
/**
* @brief xhci端口信息
*
@ -154,7 +172,14 @@ struct xhci_host_controller_t
int controller_id; // 操作系统给controller的编号
uint64_t vbase; // 虚拟地址basebar0映射到的虚拟地址
uint64_t vbase_op; // Operational registers 起始虚拟地址
struct xhci_port_info_t *ports; // 指向端口信息数组的指针
uint32_t rts_offset; // Runtime Register Space offset
uint32_t db_offset; // Doorbell offset
uint32_t ext_caps_off; // 扩展能力寄存器偏移量
uint8_t context_size; // 上下文大小
uint16_t port_num; // 总的端口数量
uint8_t port_num_u2; // usb 2.0端口数量
uint8_t port_num_u3; // usb 3端口数量
struct xhci_port_info_t ports[XHCI_MAX_ROOT_HUB_PORTS]; // 指向端口信息数组的指针
};
/**