06到10年,都在做Windows WDM驱动,包括了AVSTREAM/BDA PCTV DRVIER for USB Dongle/PCI Card, USB Audio Class Lower Filter Driver.
11年,做过一个USB General functional driver, 是KMDF Arch.
15年的时候,做过一个中间件,上面是WDDM Graphic, 下面是WinUSB driver, 应用于USB Graphic Card.
所以,基本很少接触Linux/U-boot方面的东西。
最近在弄一份U-BOOT的XHC代码,在这个过程当中,有几点感觉:
1. 代码很乱:
比如说吧,有些配置,放在.h文件当中
有些配置,又放在Kconfig当中,使用make menuconfig来配置
2. 驱动模型不完善,不统一:
linux是有驱动模型的,虽然,没有WDM如此经典
这就导致了写u-boot的人,也想把驱动模型(DM - Driver Model)应用于U-BOOT的代码架构当中。
但问题是:
有些驱动,使用了DM,有些又不使用DM,比如说吧,USB BUS/Host使用了DM,而最著名的USB Gadget又没有用。
这也造成了代码混乱的局面。
3. 更新不够及时
比如说吧, U-BOOT的最新代码,还只是基于XHCI SPEC 0.9.0 还是1.0.0
而现在最新的XHCI SPEC是1.1.0
为些,我还看了一下LINUX的最新代码,4.9版本, 它是有些代码、定义部分,已经更新到1.1.0,有些还没有。
4. 写U-BOOT的人,对XHC的SPEC没有消化理解,基本是从LINUX的代码中搬的,但有没有搬对的地方:
比如,昨天看到的一点:
在LINUX代码当中为:
*****************************************************************
struct xhci_op_regs {
__le32 command;
__le32 status;
__le32 page_size;
__le32 reserved1;
__le32 reserved2;
__le32 dev_notification;
__le64 cmd_ring;
/* rsvd: offset 0x20-2F */
__le32 reserved3[4];
__le64 dcbaa_ptr;
__le32 config_reg;
/* rsvd: offset 0x3C-3FF */
__le32 reserved4[241];
/* port 1 registers, which serve as a base address for other ports */
__le32 port_status_base;
__le32 port_power_base;
__le32 port_link_base;
__le32 reserved5;
/* registers for ports 2-255 */
__le32 reserved6[NUM_PORT_REGS*254]; 《--------------------------这里是对的
};
/* Number of registers per port */
#define NUM_PORT_REGS 4
*****************************************************************
对operational register的定义
最后一句:是为后面的254组(每组为4个 32位寄存器)PORT相关寄存器保留空间,因为,每个XHC HOST最多可以包括255个PORT。
再看看U-BOOT:
******************************************************************
struct xhci_hcor {
volatile uint32_t or_usbcmd;
volatile uint32_t or_usbsts;
volatile uint32_t or_pagesize;
volatile uint32_t reserved_0[2];
volatile uint32_t or_dnctrl;
volatile uint64_t or_crcr;
volatile uint32_t reserved_1[4];
volatile uint64_t or_dcbaap;
volatile uint32_t or_config;
volatile uint32_t reserved_2[241];
struct xhci_hcor_port_regs portregs[CONFIG_SYS_USB_XHCI_MAX_ROOT_PORTS];
uint32_t reserved_4[CONFIG_SYS_USB_XHCI_MAX_ROOT_PORTS * 254]; 《---------------------- 这句是错误的
};
******************************************************************
CONFIG_SYS_USB_XHCI_MAX_ROOT_PORTS 是软件工程师,根据当前硬件的情况,设置的,
所以,struct xhci_hcor_port_regs portregs[CONFIG_SYS_USB_XHCI_MAX_ROOT_PORTS]; 已经为当前硬件保留了所有与PORT相关的寄存器组。
而后面这句,其实,是多余的,占用了一断内存。