SylixOS初始化PCI控制器数据结构
通过前面的几篇文章我们初始化好了PCI_DRV_FUNCS0 中的读写和中断申请这三个回调函数,现在我们要将这个操作集初始化给PCI控制器数据结构:
pci_host.PCI_iIndex = 0; pci_host.PCI_iBusMax = PCI_MAX_BUS; pci_host.PCI_pDrvFuncs0 = &pci_driver_funcs; pci_host.PCI_ucMechanism = PCI_MECHANISM_0; pci_host.PCI_pvPriv = LW_NULL;
- PCI_iIndex:SylixOS目前只支持单控制器,所以这个成员只能为0。
- PCI_iBusMax:最大总线个数,一般都为256。
- PCI_pDrvFuncs0:控制器操作函数集,使用之前初始化的全局变量来设置这个成员。
- PCI_ucMechanism:除了x86平台外,这个成员一般都为0。
- PCI_pvPriv:控制器驱动私有数据,根据实际需要设置。
初始化完pci_host 之后,调用API_PciCtrlCreate 注册控制器驱动,SylixOS会遍历各总线上的设备,但是并不会重新设置设备的BAR空间,因为一般Bootloader都会枚举设备并分配BAR空间地址,SylixOS可以直接读出来BAR地址使用即可,如何在SylixOS下重新配置BAR空间在下一章节讲解。
附源码
pci_host_driver_demo4.c源码:
#define __SYLIXOS_KERNEL #define __SYLIXOS_PCI_DRV #include <SylixOS.h> #include <module.h> #include <system/device/pci/pciBus.h> #include <system/device/pci/pciMsi.h> #include <system/device/pci/pciLib.h> static PCI_CTRL_CB pci_host; static int pci_cfg_read (int bus, int dev, int func, int offset, int len, void *data) { return 0; } static int pci_cfg_write (int bus, int dev, int func, int offset, int len, unsigned int data) { return 0; } static int pci_vector_get (int bus, int dev, int func, int msi_en, int line, int pin, void *vector) { PCI_MSI_DESC *msi_desc; if (msi_en) { msi_desc = (PCI_MSI_DESC *)vector; /* * 根据不同平台进行设置,这里以mpsoc平台为例 * msi_desc->PCIMSI_pmmMsg.uiAddressHi = 0; * msi_desc->PCIMSI_pmmMsg.uiAddressLo = 0xFE440000; * msi_desc->PCIMSI_pmmMsg.uiData = 0 & 0x1f; * msi_desc->PCIMSI_ulDevIrqVector = 146; */ } else { /* * 根据不同平台上的中断路由寻找INTx实际对应的中断向量号 */ switch (pin) { case 1: break; case 2: break; case 3: break; case 4: break; default: return -1; } } return 0; } static PCI_DRV_FUNCS0 pci_driver_funcs = { .cfgRead = pci_cfg_read, .cfgWrite = pci_cfg_write, .irqGet = pci_vector_get, }; int pci_host_probe (void) { pci_host.PCI_iIndex = 0; pci_host.PCI_iBusMax = PCI_MAX_BUS; pci_host.PCI_pDrvFuncs0 = &pci_driver_funcs; pci_host.PCI_ucMechanism = PCI_MECHANISM_0; pci_host.PCI_pvPriv = LW_NULL; API_PciCtrlCreate(&pci_host); return 0; } int module_init (void) { pci_host_probe(); return 0; } void module_exit (void) { }
评论