P2020RDB-sata移植之U-BOOT篇
来源:互联网 发布:js checkbox按钮 编辑:程序博客网 时间:2024/06/06 19:16
硬件确认OK后,U-BOOT应该可以看到预期的PCIE1控制器枚举到需要的设备
PCIe1: Root Complex of mini PCIe SLOT, x1, regs @ 0xffe0a000 01:00.0 - 1095:3132 - Mass storage controllerPCIe1: Bus 00 - 01PCIe2: Root Complex of PCIe SLOT, no link, regs @ 0xffe09000PCIe2: Bus 02 - 02
U-BOOT是依靠头文件的宏配置,来确定初始化需要的基本信息的,不像内核要依赖设备树,所以U-BOOT对于硬件调试很重要。那么U-BOOT是如何枚举到PCIE1下面的sata控制器的呢。
首先看一下函数调用路线
board_init_r(board.c)
--->pci_init(drivers/pci/pci.c)
--->pci_init_board(boar/freescale/p1_p2_rdb/pci.c)
--->fsl_pcie_init_board(drivers/pci/fsl_pci_init.c)
--->fsl_pcie_init_ctrl(drivers/pci/fsl_pci_init.c)
-->fsl_configure_pcie(drivers/pci/fsl_pci_init.c)
关键的调用是fsl_pcie_init_ctrl和fsl_configure_pcie
重点看一下这两个函数
int fsl_pcie_init_board(int busno){struct fsl_pci_info pci_info;ccsr_gur_t *gur = (void *)CONFIG_SYS_MPC8xxx_GUTS_ADDR;u32 devdisr;u32 *addr;#ifdef CONFIG_SYS_FSL_QORIQ_CHASSIS2addr = &gur->devdisr3;#elseaddr = &gur->devdisr;#endifdevdisr = in_be32(addr);#ifdef CONFIG_PCIE1SET_STD_PCIE_INFO(pci_info, 1);busno = fsl_pcie_init_ctrl(busno, devdisr, PCIE1, &pci_info);#elsesetbits_be32(addr, _DEVDISR_PCIE1); /* disable */#endif#ifdef CONFIG_PCIE2SET_STD_PCIE_INFO(pci_info, 2);busno = fsl_pcie_init_ctrl(busno, devdisr, PCIE2, &pci_info);#elsesetbits_be32(addr, _DEVDISR_PCIE2); /* disable */#endif#ifdef CONFIG_PCIE3SET_STD_PCIE_INFO(pci_info, 3);busno = fsl_pcie_init_ctrl(busno, devdisr, PCIE3, &pci_info);#elsesetbits_be32(addr, _DEVDISR_PCIE3); /* disable */#endif#ifdef CONFIG_PCIE4SET_STD_PCIE_INFO(pci_info, 4);busno = fsl_pcie_init_ctrl(busno, devdisr, PCIE4, &pci_info);#elsesetbits_be32(addr, _DEVDISR_PCIE4); /* disable */#endif return busno;}
可以看到如果有需要的话,会对每个PCIE控制器进行初始化设置,
设置的开始首先是设定PCI控制器的基本寄存器位置,这些位置在U-BOOT里通过头文件宏来提供,linux使用DTB获取。
看一下宏SET_STD_PCIE_INFO就一目了然了
#define SET_STD_PCIE_INFO(x, num) \{\x.regs = CONFIG_SYS_PCIE##num##_ADDR;\x.mem_bus = CONFIG_SYS_PCIE##num##_MEM_BUS; \x.mem_phys = CONFIG_SYS_PCIE##num##_MEM_PHYS; \x.mem_size = CONFIG_SYS_PCIE##num##_MEM_SIZE; \x.io_bus = CONFIG_SYS_PCIE##num##_IO_BUS; \x.io_phys = CONFIG_SYS_PCIE##num##_IO_PHYS; \x.io_size = CONFIG_SYS_PCIE##num##_IO_SIZE; \x.law = LAW_TRGT_IF_PCIE_##num; \x.pci_num = num; \}
U-BOOT获取了相应的寄存器位置后,就会配置对应的PCIE控制器
int fsl_pcie_init_ctrl(int busno, u32 devdisr, enum srds_prtcl dev,struct fsl_pci_info *pci_info){struct pci_controller *hose;int num = dev - PCIE1;hose = calloc(1, sizeof(struct pci_controller));if (!hose)return busno;if (is_serdes_configured(dev) && !(devdisr & devdisr_mask[num])) {busno = fsl_configure_pcie(pci_info, hose,board_serdes_name(dev), busno);} else {printf("PCIe%d: disabled\n", num + 1);}return busno;}
端口硬件禁能的会输出printf("PCIe%d: disabled\n", num + 1);
硬件使能的,开始fsl_configure_pcie枚举控制器
int fsl_configure_pcie(struct fsl_pci_info *info,struct pci_controller *hose,const char *connected, int busno){int is_endpoint;set_next_law(info->mem_phys, law_size_bits(info->mem_size), info->law);set_next_law(info->io_phys, law_size_bits(info->io_size), info->law);is_endpoint = fsl_setup_hose(hose, info->regs);printf("PCIe%u: %s", info->pci_num,is_endpoint ? "Endpoint" : "Root Complex");if (connected)printf(" of %s", connected);puts(", ");return fsl_pci_init_port(info, hose, busno);}
函数的最后调用,枚举总线。
fsl_pci_init_port
->fsl_pci_init
->pci_hose_scan_bus
int pci_hose_scan_bus(struct pci_controller *hose, int bus){unsigned int sub_bus, found_multi = 0;unsigned short vendor, device, class;unsigned char header_type;#ifndef CONFIG_PCI_PNPstruct pci_config_table *cfg;#endifpci_dev_t dev;#ifdef CONFIG_PCI_SCAN_SHOWstatic int indent = 0;#endifsub_bus = bus;for (dev = PCI_BDF(bus,0,0); dev < PCI_BDF(bus, PCI_MAX_PCI_DEVICES - 1,PCI_MAX_PCI_FUNCTIONS - 1); dev += PCI_BDF(0, 0, 1)) {if (pci_skip_dev(hose, dev))continue;if (PCI_FUNC(dev) && !found_multi)continue;pci_hose_read_config_byte(hose, dev, PCI_HEADER_TYPE, &header_type);pci_hose_read_config_word(hose, dev, PCI_VENDOR_ID, &vendor);if (vendor == 0xffff || vendor == 0x0000)continue;if (!PCI_FUNC(dev))found_multi = header_type & 0x80;debug("PCI Scan: Found Bus %d, Device %d, Function %d\n",PCI_BUS(dev), PCI_DEV(dev), PCI_FUNC(dev));pci_hose_read_config_word(hose, dev, PCI_DEVICE_ID, &device);pci_hose_read_config_word(hose, dev, PCI_CLASS_DEVICE, &class);#ifdef CONFIG_PCI_SCAN_SHOWindent++;/* Print leading space, including bus indentation */printf("%*c", indent + 1, ' ');if (pci_print_dev(hose, dev)) {printf("%02x:%02x.%-*x - %04x:%04x - %s\n", PCI_BUS(dev), PCI_DEV(dev), 6 - indent, PCI_FUNC(dev), vendor, device, pci_class_str(class >> 8));}#endif#ifdef CONFIG_PCI_PNPsub_bus = max(pciauto_config_device(hose, dev), sub_bus);#elsecfg = pci_find_config(hose, class, vendor, device, PCI_BUS(dev), PCI_DEV(dev), PCI_FUNC(dev));if (cfg) {cfg->config_device(hose, dev, cfg);sub_bus = max(sub_bus, hose->current_busno);}#endif#ifdef CONFIG_PCI_SCAN_SHOWindent--;#endifif (hose->fixup_irq)hose->fixup_irq(hose, dev);}return sub_bus;}
0 0
- P2020RDB-sata移植之U-BOOT篇
- P2020RDB-sata移植之硬件篇
- U-boot移植之U-boot概述
- P2020RDB board u-boot镜像与flash分析
- U-Boot的移植之(三)实战篇:移植U-Boot到XSBASE270开发板
- U-Boot的移植之(三)实战篇:移植U-Boot到XSBASE270开发板
- U-Boot的移植之(三)实战篇:移植U-Boot到XSBASE270开发板
- 第二篇 U-BOOT移植
- U-Boot的移植之(四)调试篇:下载U-Boot到目标板进行调试
- U-Boot的移植之(四)调试篇:下载U-Boot到目标板进行调试
- U-Boot的移植之(四)调试篇:下载U-Boot到目标板进行调试
- U-BOOT之三:u-boot移植一
- U-Boot之三:U-Boot移植过程步骤
- U-BOOT分析与移植之mkconfig分析篇
- mini2440系统移植篇之u-boot分析
- mini2440系统移植篇之u-boot第一阶段汇编
- mini2440系统移植篇之u-boot第二阶段C语言
- U-boot移植之二:预备知识
- linux 信号量使用
- 对比度保留之彩色图像去色算法---基础算法也可以上档次
- 全面进军可穿戴市场,Google 宣布 Android Wear 平台
- 俄罗斯方块(一)---Windows SDK
- java Date装成英文String后,无法再转回Date
- P2020RDB-sata移植之U-BOOT篇
- LeetCode Recover Binary Search Tree
- 排序算法:归并排序
- 手把手教您开发JAVA微信SDK-新手接入
- Primer_Four
- PHP将网址快捷方式保存到桌面
- openfire插件的编译方法
- 25个可遇不可求的jQuery插件
- 1、断箭