new: xhci get descriptor

This commit is contained in:
fslongjin 2022-08-30 20:34:52 +08:00
parent 3d5fe966d3
commit 416a802b9c
7 changed files with 980 additions and 128 deletions

View File

@ -1,18 +1,22 @@
SUBDIRS = kernel user SUBDIRS = kernel user
# ifndef $(EMULATOR)
ifeq ($(EMULATOR), )
export EMULATOR=__NO_EMULATION__
endif
export ARCH=__x86_64__ export ARCH=__x86_64__
export ROOT_PATH=$(shell pwd) export ROOT_PATH=$(shell pwd)
export DEBUG=DEBUG export DEBUG=DEBUG
export GLOBAL_CFLAGS := -mcmodel=large -fno-builtin -m64 -fno-stack-protector -D $(ARCH) -O1 export GLOBAL_CFLAGS := -mcmodel=large -fno-builtin -m64 -fno-stack-protector -D $(ARCH) -D $(EMULATOR) -O1
ifeq ($(DEBUG), DEBUG) ifeq ($(DEBUG), DEBUG)
GLOBAL_CFLAGS += -g GLOBAL_CFLAGS += -g
endif endif
.PHONY: all .PHONY: all
all: kernel user all: kernel user

View File

@ -164,6 +164,7 @@ int pci_enable_msi(struct msi_desc_t *msi_desc)
if (msi_desc->pci.msi_attribute.is_msix) // MSI-X if (msi_desc->pci.msi_attribute.is_msix) // MSI-X
{ {
kdebug("is msix");
// 读取msix的信息 // 读取msix的信息
struct pci_msix_cap_t cap = __msi_read_msix_cap_list(msi_desc, cap_ptr); struct pci_msix_cap_t cap = __msi_read_msix_cap_list(msi_desc, cap_ptr);
// 映射msix table // 映射msix table
@ -181,6 +182,7 @@ int pci_enable_msi(struct msi_desc_t *msi_desc)
} }
else else
{ {
kdebug("is msi");
tmp = pci_read_config(ptr->bus, ptr->device, ptr->func, cap_ptr); // 读取cap+0x0处的值 tmp = pci_read_config(ptr->bus, ptr->device, ptr->func, cap_ptr); // 读取cap+0x0处的值
message_control = (tmp >> 16) & 0xffff; message_control = (tmp >> 16) & 0xffff;

View File

@ -1,4 +1,5 @@
#pragma once #pragma once
#include <common/sys/types.h>
// usb设备在pci总线上的class // usb设备在pci总线上的class
#define USB_CLASS 0xC #define USB_CLASS 0xC
@ -9,17 +10,127 @@
#define USB_TYPE_OHCI 0x10 #define USB_TYPE_OHCI 0x10
#define USB_TYPE_EHCI 0x20 #define USB_TYPE_EHCI 0x20
#define USB_TYPE_XHCI 0x30 #define USB_TYPE_XHCI 0x30
#define USB_TYPE_UNSPEC 0x80 // Unspecified #define USB_TYPE_UNSPEC 0x80 // Unspecified
#define USB_TYPE_DEVICE 0xfe // USB Device(Not controller) #define USB_TYPE_DEVICE 0xfe // USB Device(Not controller)
// Reset wait times(milliseconds) ,USB 2.0 specs, page 153, section 7.1.7.5, paragraph 3 // Reset wait times(milliseconds) ,USB 2.0 specs, page 153, section 7.1.7.5, paragraph 3
#define USB_TIME_RST_RH 50 // reset on a root hub #define USB_TIME_RST_RH 50 // reset on a root hub
#define USB_TIME_RST_MIN 10 // minimum delay for a reset #define USB_TIME_RST_MIN 10 // minimum delay for a reset
#define USB_TIME_RST_NOMORE 3 // No more than this between resets for root hubs #define USB_TIME_RST_NOMORE 3 // No more than this between resets for root hubs
#define USB_TIME_RST_REC 10 // reset recovery #define USB_TIME_RST_REC 10 // reset recovery
/**
* @brief usb
*
*/
struct usb_device_desc
{
uint8_t len;
uint8_t type;
uint16_t usb_version;
uint8_t _class;
uint8_t subclass;
uint8_t protocol;
uint8_t max_packet_size;
uint16_t vendor_id;
uint16_t product_id;
uint16_t device_rel;
uint8_t manufacturer_index;
uint8_t procuct_index;
uint8_t serial_index;
uint8_t config; // number of configurations
};
/**
* @brief usb设备请求包
*
*/
struct usb_request_packet_t
{
uint8_t request_type;
uint8_t request;
uint16_t value;
uint16_t index;
uint16_t length;
};
// usb设备请求包的request_type字段的值
#define __USB_REQ_TYPE_H2D 0x00
#define __USB_REQ_TYPE_D2H 0x80
#define __USB_REQ_TYPE_STANDARD 0x00
#define __USB_REQ_TYPE_CLASS 0x20
#define __USB_REQ_TYPE_VENDOR 0x40
#define __USB_REQ_TYPE_RSVD 0x60
#define __USB_REQ_TYPE_DEVICE 0x00
#define __USB_REQ_TYPE_INTERFACE 0x01
#define __USB_REQ_TYPE_ENDPOINT 0x02
#define __USB_REQ_TYPE_OTHER 0x03
#define USB_REQ_TYPE_GET_REQUEST (__USB_REQ_TYPE_D2H | __USB_REQ_TYPE_STANDARD | __USB_REQ_TYPE_DEVICE)
#define USB_REQ_TYPE_SET_REQUEST (__USB_REQ_TYPE_H2D | __USB_REQ_TYPE_STANDARD | __USB_REQ_TYPE_DEVICE)
#define USB_REQ_TYPE_SET_INTERFACE (__USB_REQ_TYPE_H2D | __USB_REQ_TYPE_STANDARD | __USB_REQ_TYPE_INTERFACE)
// device requests
enum
{
USB_REQ_GET_STATUS = 0,
USB_REQ_CLEAR_FEATURE,
USB_REQ_SET_FEATURE = 3,
USB_REQ_SET_ADDRESS = 5,
USB_REQ_GET_DESCRIPTOR = 6,
USB_REQ_SET_DESCRIPTOR,
USB_REQ_GET_CONFIGURATION,
USB_REQ_SET_CONFIGURATION,
// interface requests
USB_REQ_GET_INTERFACE,
USB_REQ_SET_INTERFACE,
// standard endpoint requests
USB_REQ_SYNCH_FRAME,
// Device specific
USB_REQ_GET_MAX_LUNS = 0xFE,
USB_REQ_BULK_ONLY_RESET
};
// Descriptor types
enum
{
USB_DT_DEVICE = 1,
USB_DT_CONFIG,
USB_DT_STRING,
USB_DT_INTERFACE,
USB_DT_ENDPOINT,
USB_DT_DEVICE_QUALIFIER,
USB_DT_OTHER_SPEED_CONFIG,
USB_DT_INTERFACE_POWER,
USB_DT_OTG,
USB_DT_DEBUG,
USB_DT_INTERFACE_ASSOSIATION,
USB_DT_HID = 0x21,
USB_DT_HID_REPORT,
USB_DT_HID_PHYSICAL,
USB_DT_INTERFACE_FUNCTION = 0x24,
USB_DT_ENDPOINT_FUNCTION,
HUB = 0x29
};
// transfer types (Endpoint types) (USB 2.0 page 270)
enum
{
USB_EP_CONTROL = 0,
USB_EP_ISOCHRONOUS,
USB_EP_BULK,
USB_EP_INTERRUPT
};
/** /**
* @brief usb驱动程序 * @brief usb驱动程序
* *
*/ */
void usb_init(); void usb_init();

File diff suppressed because it is too large Load Diff

View File

@ -8,7 +8,7 @@
// ========== irq BEGIN =========== // ========== irq BEGIN ===========
#define XHCI_IRQ_DONE (1<<31) // 当command trb 的status的第31位被驱动程序置位时表明该trb已经执行完成这是由于xhci规定第31位可以由驱动程序自行决定用途 #define XHCI_IRQ_DONE (1 << 31) // 当command trb 的status的第31位被驱动程序置位时表明该trb已经执行完成这是由于xhci规定第31位可以由驱动程序自行决定用途
/** /**
* @brief xhci控制器的中断向量号 * @brief xhci控制器的中断向量号
* *
@ -188,6 +188,10 @@ struct xhci_ops_config_reg_t
#define XHCI_TRB_CYCLE_OFF 0 #define XHCI_TRB_CYCLE_OFF 0
#define XHCI_TRB_CYCLE_ON 1 #define XHCI_TRB_CYCLE_ON 1
// 获取、设置trb中的status部分的complete code
#define xhci_get_comp_code(status) (((status) >> 24) & 0x7f)
#define xhci_set_comp_code(code) ((code & 0x7f) << 24)
/** /**
* @brief xhci通用TRB结构 * @brief xhci通用TRB结构
* *
@ -220,7 +224,7 @@ struct xhci_TRB_normal_t
uint16_t Reserved; // 保留且置为0 uint16_t Reserved; // 保留且置为0
} __attribute__((packed)); } __attribute__((packed));
struct xhci_TRB_setup_state_t struct xhci_TRB_setup_stage_t
{ {
uint8_t bmRequestType; uint8_t bmRequestType;
uint8_t bRequest; uint8_t bRequest;
@ -229,14 +233,14 @@ struct xhci_TRB_setup_state_t
uint16_t wIndex; uint16_t wIndex;
uint16_t wLength; uint16_t wLength;
unsigned transfer_legth : 17; unsigned transfer_legth : 17; // TRB transfer length
unsigned resv1 : 5; // Reserved and zero'd unsigned resv1 : 5; // Reserved and zero'd
unsigned intr_target : 10; unsigned intr_target : 10;
unsigned cycle : 1; unsigned cycle : 1;
unsigned resv2 : 4; // Reserved and zero'd unsigned resv2 : 4; // Reserved and zero'd
unsigned ioc : 1; unsigned ioc : 1; // interrupt on complete
unsigned idt : 1; unsigned idt : 1; // immediate data (should always set for setup TRB)
unsigned resv3 : 3; // Reserved and zero'd unsigned resv3 : 3; // Reserved and zero'd
unsigned TRB_type : 6; unsigned TRB_type : 6;
unsigned trt : 2; // Transfer type unsigned trt : 2; // Transfer type
@ -354,8 +358,132 @@ struct xhci_intr_moderation_t
#define XHCI_PORTUSB_CHANGE_BITS ((1 << 17) | (1 << 18) | (1 << 20) | (1 << 21) | (1 << 22)) #define XHCI_PORTUSB_CHANGE_BITS ((1 << 17) | (1 << 18) | (1 << 20) | (1 << 21) | (1 << 22))
// 存储于portsc中的端口速度的可用值
#define XHCI_PORT_SPEED_FULL 1
#define XHCI_PORT_SPEED_LOW 2
#define XHCI_PORT_SPEED_HI 3
#define XHCI_PORT_SPEED_SUPER 4
// ======= Port status and control registers END ==== // ======= Port status and control registers END ====
// ======= Device Slot Context BEGIN ====
/**
* @brief
*
*/
struct xhci_slot_context_t
{
unsigned route_string : 20;
unsigned speed : 4;
unsigned Rsvd0 : 1; // Reserved and zero'd
unsigned mtt : 1; // multi-TT
unsigned hub : 1;
unsigned entries : 5; // count of context entries
uint16_t max_exit_latency;
uint8_t rh_port_num; // root hub port number
uint8_t num_ports; // number of ports
uint8_t tt_hub_slot_id;
uint8_t tt_port_num;
unsigned ttt : 2; // TT Think Time
unsigned Rsvd2 : 4;
unsigned int_target : 10; // Interrupter target
uint8_t device_address;
unsigned Rsvd1 : 19;
unsigned slot_state : 5;
} __attribute__((packed));
#define XHCI_SLOT_STATE_DISABLED_OR_ENABLED 0
#define XHCI_SLOT_STATE_DEFAULT 1
#define XHCI_SLOT_STATE_ADDRESSED 2
#define XHCI_SLOT_STATE_CONFIGURED 3
// ======= Device Slot Context END ====
// ======= Device Endpoint Context BEGIN ====
#define XHCI_EP_STATE_DISABLED 0
#define XHCI_EP_STATE_RUNNING 1
#define XHCI_EP_STATE_HALTED 2
#define XHCI_EP_STATE_STOPPED 3
#define XHCI_EP_STATE_ERROR 4
// End Point Doorbell numbers
#define XHCI_SLOT_CNTX 0
#define XHCI_EP_CONTROL 1
#define XHCI_EP1_OUT 2
#define XHCI_EP1_IN 3
#define XHCI_EP2_OUT 4
#define XHCI_EP2_IN 5
#define XHCI_EP3_OUT 6
#define XHCI_EP3_IN 7
#define XHCI_EP4_OUT 8
#define XHCI_EP4_IN 9
#define XHCI_EP5_OUT 10
#define XHCI_EP5_IN 11
#define XHCI_EP6_OUT 12
#define XHCI_EP6_IN 13
#define XHCI_EP7_OUT 14
#define XHCI_EP7_IN 15
#define XHCI_EP8_OUT 16
#define XHCI_EP8_IN 17
#define XHCI_EP9_OUT 18
#define XHCI_EP9_IN 19
#define XHCI_EP10_OUT 20
#define XHCI_EP10_IN 21
#define XHCI_EP11_OUT 22
#define XHCI_EP11_IN 23
#define XHCI_EP12_OUT 24
#define XHCI_EP12_IN 25
#define XHCI_EP13_OUT 26
#define XHCI_EP13_IN 27
#define XHCI_EP14_OUT 28
#define XHCI_EP14_IN 29
#define XHCI_EP15_OUT 30
#define XHCI_EP15_IN 31
// xhci 传输方向(用于setup stage TRB)
#define XHCI_DIR_NO_DATA 0
#define XHCI_DIR_OUT 2
#define XHCI_DIR_IN 3
// xhci传输方向单个bit的表示
#define XHCI_DIR_OUT_BIT 0
#define XHCI_DIR_IN_BIT 1
/**
* @brief xhci
*
*/
struct xhci_ep_context_t
{
unsigned ep_state : 3;
unsigned Rsvd0 : 5; // Reserved and zero'd
unsigned mult : 2; // the maximum supported number of bursts within an interval
unsigned max_primary_streams : 5;
unsigned linear_stream_array : 1;
uint8_t interval;
uint8_t max_esti_payload_hi; // Max Endpoint Service Time Interval Payload (High 8bit)
unsigned Rsvd1 : 1;
unsigned err_cnt : 2; // error count. 当错误发生时该位会自减。当减为0时控制器会把这个端点挂起
unsigned ep_type : 3; // endpoint type
unsigned Rsvd2 : 1;
unsigned hid : 1; // Host Initiate Disable
uint8_t max_burst_size;
uint16_t max_packet_size;
uint64_t tr_dequeue_ptr; // 第0bit为dequeue cycle state 第1~3bit应保留。
uint16_t average_trb_len; // 平均TRB长度。该部分不应为0
uint16_t max_esti_payload_lo; // Max Endpoint Service Time Interval Payload (Low 16bit)
} __attribute__((packed));
// ======= Device Endpoint Context END ====
// 端口信息标志位 // 端口信息标志位
#define XHCI_PROTOCOL_USB2 0 #define XHCI_PROTOCOL_USB2 0
#define XHCI_PROTOCOL_USB3 1 #define XHCI_PROTOCOL_USB3 1
@ -376,6 +504,12 @@ struct xhci_port_info_t
uint8_t reserved; uint8_t reserved;
} __attribute__((packed)); } __attribute__((packed));
struct xhci_ep_ring_info_t
{
uint64_t ep_ring_vbase; // transfer ring的基地址
uint64_t current_ep_ring_vaddr; // transfer ring下一个要写入的地址
uint8_t current_ep_ring_cycle; // 当前ep的cycle bit
};
struct xhci_host_controller_t struct xhci_host_controller_t
{ {
struct pci_device_structure_general_device_t *pci_dev_hdr; // 指向pci header结构体的指针 struct pci_device_structure_general_device_t *pci_dev_hdr; // 指向pci header结构体的指针
@ -385,7 +519,7 @@ struct xhci_host_controller_t
uint32_t rts_offset; // Runtime Register Space offset uint32_t rts_offset; // Runtime Register Space offset
uint32_t db_offset; // Doorbell offset uint32_t db_offset; // Doorbell offset
uint32_t ext_caps_off; // 扩展能力寄存器偏移量 uint32_t ext_caps_off; // 扩展能力寄存器偏移量
uint8_t context_size; // 上下文大小 uint8_t context_size; // 设备上下文大小
uint16_t port_num; // 总的端口数量 uint16_t port_num; // 总的端口数量
uint8_t port_num_u2; // usb 2.0端口数量 uint8_t port_num_u2; // usb 2.0端口数量
uint8_t port_num_u3; // usb 3端口数量 uint8_t port_num_u3; // usb 3端口数量
@ -399,6 +533,7 @@ struct xhci_host_controller_t
uint8_t cmd_trb_cycle; // 当前command ring cycle uint8_t cmd_trb_cycle; // 当前command ring cycle
uint8_t current_event_ring_cycle; // 当前event ring cycle uint8_t current_event_ring_cycle; // 当前event ring cycle
struct xhci_port_info_t ports[XHCI_MAX_ROOT_HUB_PORTS]; // 指向端口信息数组的指针(由于端口offset是从1开始的因此该数组第0项为空) struct xhci_port_info_t ports[XHCI_MAX_ROOT_HUB_PORTS]; // 指向端口信息数组的指针(由于端口offset是从1开始的因此该数组第0项为空)
struct xhci_ep_ring_info_t control_ep_info; // 控制端点的信息
}; };
// Common TRB types // Common TRB types

View File

@ -88,22 +88,21 @@ void system_initialize()
cpu_core_info[0].stack_start = _stack_start; cpu_core_info[0].stack_start = _stack_start;
cpu_core_info[0].tss_vaddr = (uint64_t)&initial_tss[0]; cpu_core_info[0].tss_vaddr = (uint64_t)&initial_tss[0];
kdebug("cpu_core_info[0].tss_vaddr=%#018lx", cpu_core_info[0].tss_vaddr); // kdebug("cpu_core_info[0].tss_vaddr=%#018lx", cpu_core_info[0].tss_vaddr);
kdebug("cpu_core_info[0].stack_start%#018lx", cpu_core_info[0].stack_start); // kdebug("cpu_core_info[0].stack_start%#018lx", cpu_core_info[0].stack_start);
// 初始化中断描述符表 // 初始化中断描述符表
sys_vector_init(); sys_vector_init();
// 初始化内存管理单元 // 初始化内存管理单元
mm_init(); mm_init();
// 内存管理单元初始化完毕后,需要立即重新初始化显示驱动。 // 内存管理单元初始化完毕后,需要立即重新初始化显示驱动。
// 原因是系统启动初期framebuffer被映射到48M地址处 // 原因是系统启动初期framebuffer被映射到48M地址处
// mm初始化完毕后若不重新初始化显示驱动将会导致错误的数据写入内存从而造成其他模块崩溃 // mm初始化完毕后若不重新初始化显示驱动将会导致错误的数据写入内存从而造成其他模块崩溃
// 对显示模块进行低级初始化不启用double buffer // 对显示模块进行低级初始化不启用double buffer
scm_reinit(); scm_reinit();
// =========== 重新设置initial_tss[0]的ist // =========== 重新设置initial_tss[0]的ist
uchar *ptr = (uchar *)kzalloc(STACK_SIZE, 0) + STACK_SIZE; uchar *ptr = (uchar *)kzalloc(STACK_SIZE, 0) + STACK_SIZE;
((struct process_control_block *)(ptr - STACK_SIZE))->cpu_id = 0; ((struct process_control_block *)(ptr - STACK_SIZE))->cpu_id = 0;
@ -158,7 +157,7 @@ void system_initialize()
io_mfence(); io_mfence();
// current_pcb->preempt_count = 0; // current_pcb->preempt_count = 0;
// kdebug("cpu_get_core_crysral_freq()=%ld", cpu_get_core_crysral_freq()); // kdebug("cpu_get_core_crysral_freq()=%ld", cpu_get_core_crysral_freq());
process_init(); process_init();
// 启用double buffer // 启用double buffer
scm_enable_double_buffer(); scm_enable_double_buffer();

22
run.sh
View File

@ -7,6 +7,16 @@ fi
GENERATE_ISO=0 GENERATE_ISO=0
IN_DOCKER=0 IN_DOCKER=0
IA32_USE_QEMU=1
bochsrc="./bochsrc"
ARCH="x86_64"
if [ ${IA32_USE_QEMU} == "1" ];then
export EMULATOR=__QEMU_EMULATION__
else
export EMULATOR=__NO_EMULATION__
fi
# 第一个参数如果是--notbuild 那就不构建,直接运行 # 第一个参数如果是--notbuild 那就不构建,直接运行
if [ ! "$1" == "--nobuild" ]; then if [ ! "$1" == "--nobuild" ]; then
echo "开始构建..." echo "开始构建..."
@ -28,9 +38,6 @@ if [ ! "$1" == "--nobuild" ]; then
fi fi
fi fi
IA32_USE_QEMU=1
bochsrc="./bochsrc"
ARCH="x86_64"
# 内核映像 # 内核映像
root_folder="$(pwd)" root_folder="$(pwd)"
@ -128,8 +135,13 @@ flag_can_run=1
allflags=$(qemu-system-x86_64 -cpu help | awk '/flags/ {y=1; getline}; y {print}' | tr ' ' '\n' | grep -Ev "^$" | sed -r 's|^|+|' | tr '\n' ',' | sed -r "s|,$||") allflags=$(qemu-system-x86_64 -cpu help | awk '/flags/ {y=1; getline}; y {print}' | tr ' ' '\n' | grep -Ev "^$" | sed -r 's|^|+|' | tr '\n' ',' | sed -r "s|,$||")
# 请根据自己的需要,在-d 后方加入所需的trace事件
# 标准的trace events
qemu_trace_std=cpu_reset,guest_errors,trace:check_exception,exec,cpu
# 调试usb的trace # 调试usb的trace
qemu_trace_usb=trace:usb_xhci_reset,trace:usb_xhci_run,trace:usb_xhci_stop,trace:usb_xhci_irq_msi,trace:usb_xhci_irq_msix,trace:usb_xhci_port_reset qemu_trace_usb=trace:usb_xhci_reset,trace:usb_xhci_run,trace:usb_xhci_stop,trace:usb_xhci_irq_msi,trace:usb_xhci_irq_msix,trace:usb_xhci_port_reset,trace:msix_write_config,trace:usb_xhci_irq_msix,trace:usb_xhci_irq_msix_use,trace:usb_xhci_irq_msix_unuse,trace:usb_xhci_irq_msi,trace:usb_xhci_*
qemu_accel=kvm qemu_accel=kvm
if [ "${OS}" == "Darwin" ]; then if [ "${OS}" == "Darwin" ]; then
@ -142,7 +154,7 @@ if [ $flag_can_run -eq 1 ]; then
else else
qemu-system-x86_64 -d bin/disk.img -m 512M -smp 2,cores=2,threads=1,sockets=1 \ qemu-system-x86_64 -d bin/disk.img -m 512M -smp 2,cores=2,threads=1,sockets=1 \
-boot order=d \ -boot order=d \
-monitor stdio -d cpu_reset,guest_errors,trace:check_exception,exec,cpu,out_asm,in_asm,${qemu_trace_usb} \ -monitor stdio -d ${qemu_trace_std} \
-s -S -cpu IvyBridge,apic,x2apic,+fpu,check,${allflags} -rtc clock=host,base=localtime -serial file:serial_opt.txt \ -s -S -cpu IvyBridge,apic,x2apic,+fpu,check,${allflags} -rtc clock=host,base=localtime -serial file:serial_opt.txt \
-drive id=disk,file=bin/disk.img,if=none \ -drive id=disk,file=bin/disk.img,if=none \
-device ahci,id=ahci \ -device ahci,id=ahci \