科技行者

行者学院 转型私董会 科技行者专题报道 网红大战科技行者

知识库

知识库 安全导航

至顶网软件频道基础软件PCI设备初始化3

PCI设备初始化3

  • 扫一扫
    分享文章到微信

  • 扫一扫
    关注官方公众号
    至顶头条

继续初始化南桥之后,再接着下来,就要初始化PCI总线上其它的设备了。

作者:caimouse 来源:CSDN 2008年1月22日

关键字: 初始化 设备 PCI Linux

  • 评论
  • 分享微博
  • 分享邮件
上面继续初始化南桥之后,再接着下来,就要初始化PCI总线上其它的设备了。看下面的代码:
 
CPU_ConfigCache();
上面重新配置龙芯2E的缓存。
 
    _pci_businit(1); /* PCI bus initialization */
上面继续初始化PCI总线上的设备,这个函数里要初始化完成所有其它连接到PCI总线上的设备。接着看这个函数的代码如下:
 
void
_pci_businit (int init)
{
    char *v;
 
    tgt_putchar('P');
    v = getenv("pciverbose");
    if (v) {
       _pciverbose = atol(v);
    }
上面获取PCI显示值。
 
    /* intialise the PCI bridge */
    if (/*init*/ 1) {
       SBD_DISPLAY ("PCIH", CHKPNT_PCIH);
       init = _pci_hwinit (init, &def_bus_iot, &def_bus_memt);
       pci_roots = init;
       if (init < 1)
           return;
    }
上面实现PCI的分配空间,主要设置北桥。以便后面可以搜索到所有PCI的设备。
 
    if(monarch_mode) {
       int i;
       struct pci_device *pb;
 
       if (_pciverbose) {
           printf("setting up %d bus\n", init);
       }
       for(i = 0, pb = _pci_head; i < pci_roots; i++, pb = pb->next) {
           _pci_scan_dev(pb, i, 0, init);
       }
上面实现所有PCI设备的枚举。由于PCI插槽上有很多设备,并且是即插即用,并不能确定那个设备一定存在,所以只能枚举所有设备。
 
 
       _setup_pcibuses(init);
上面把发现的PCI设备全部初始化。
 
    }
}
 
 
下面是PCI函数_pci_hwinit初始化实现:
int
_pci_hwinit(initialise, iot, memt)
    int initialise;
    bus_space_tag_t iot;
    bus_space_tag_t memt;
{
    /*pcireg_t stat;*/
    struct pci_device *pd;
    struct pci_bus *pb;
 
 
    if (!initialise) {
       return(0);
    }
上面判断是否需要初始化,如果不需要分配PCI的链表,就返回去。
 
    pci_local_mem_pci_base = PCI_LOCAL_MEM_PCI_BASE;
    /*
     * Allocate and initialize PCI bus heads.
     */
 
    /*
     * PCI Bus 0
     */
    pd = pmalloc(sizeof(struct pci_device));
    pb = pmalloc(sizeof(struct pci_bus));
    if(pd == NULL || pb == NULL) {
       printf("pci: can't alloc memory. pci not initialized\n");
       return(-1);
    }
上面分配一个PCI链表的节点,由于PCI总线上的设备是可变的,只能使用链表来保存设备信息。同时还判断内存是否分配成功。
 
 
    pd->pa.pa_flags = PCI_FLAGS_IO_ENABLED | PCI_FLAGS_MEM_ENABLED;
上面设置使用IO和内存空间。
 
    pd->pa.pa_iot = pmalloc(sizeof(bus_space_tag_t));
    pd->pa.pa_iot->bus_reverse = 1;
    pd->pa.pa_iot->bus_base = BONITO_PCIIO_BASE_VA;
上面设置IOTAG配置。
 
    //printf("pd->pa.pa_iot=%p,bus_base=0x%x\n",pd->pa.pa_iot,pd->pa.pa_iot->bus_base);
    pd->pa.pa_memt = pmalloc(sizeof(bus_space_tag_t));
    pd->pa.pa_memt->bus_reverse = 1;
    //pd->pa.pa_memt->bus_base = 0xa0000000; /* pci memory start from 0x10000000 */
    pd->pa.pa_memt->bus_base = 0xb0000000; /* pci memory start from 0x00000000 */
上面设置内存空间。
 
    pd->pa.pa_dmat = &bus_dmamap_tag;
上面设置DMA配置。
 
    pd->bridge.secbus = pb;
    _pci_head = pd;
上面保存PCI设备。
 
#ifndef NEW_PCI_WINDOW
    /* reserve first window for vga mem */
    pb->minpcimemaddr = PCI_MEM_SPACE_PCI_BASE+0x04000000;
    pb->nextpcimemaddr = PCI_MEM_SPACE_PCI_BASE+BONITO_PCILO_SIZE;
#else
    pb->minpcimemaddr = PCI_MEM_SPACE_PCI_BASE;
    pb->nextpcimemaddr = PCI_MEM_SPACE_PCI_BASE+ 0x0a000000;
#endif
    pb->minpciioaddr = PCI_IO_SPACE_BASE+0x000a000;
    pb->nextpciioaddr = PCI_IO_SPACE_BASE+ BONITO_PCIIO_SIZE;
    pb->pci_mem_base   = BONITO_PCILO_BASE_VA;
    pb->pci_io_base    = BONITO_PCIIO_BASE_VA;
    pb->max_lat = 255;
    pb->fast_b2b = 1;
    pb->prefetch = 1;
    pb->bandwidth = 0x4000000;
    pb->ndev = 1;
    _pci_bushead = pb;
    _pci_bus[_max_pci_bus++] = pd;
上面保存PCI总线配置。
 
 
   
    bus_dmamap_tag._dmamap_offs = 0;
 
#ifndef NEW_PCI_WINDOW
    /*set Bonito register; first windows for 0-0x4000000 pci mem */
    BONITO_PCIMAP =
        BONITO_PCIMAP_WIN(0, /*PCI_MEM_SPACE_PCI_BASE+*/0x00000000) | 
        BONITO_PCIMAP_WIN(1, PCI_MEM_SPACE_PCI_BASE+0x04000000) |
        BONITO_PCIMAP_WIN(2, PCI_MEM_SPACE_PCI_BASE+0x08000000) |
        BONITO_PCIMAP_PCIMAP_2;
#else
    BONITO_PCIMAP = (PCI_MEM_SPACE_PCI_BASE >>27) | (((PCI_MEM_SPACE_PCI_BASE + 0x08000000) >>25)<<5);
#endif
   
    BONITO_PCIBASE0 = PCI_LOCAL_MEM_PCI_BASE;
 
    BONITO_PCIBASE1 = PCI_LOCAL_MEM_ISA_BASE;
 
    BONITO_PCIBASE2 = PCI_LOCAL_REG_PCI_BASE;
 
    /* pci base0/1 can access 256M sdram */
    BONITO_PCIMEMBASECFG = 0;
上面设置了北桥里的PCI配置内存空间分配。
 
 
    return(1);
}
 
这里的代码,先从北桥里分配PCIIO空间和内存空间,然后通过枚举所有内存空间来发现PCI的设备,最后对于发现的设备进行配置,并启动相应的设备。
后面再仔细地查看怎么样实现查询PCI设备的发现和PCI设备配置。 

查看本文来源
    • 评论
    • 分享微博
    • 分享邮件
    邮件订阅

    如果您非常迫切的想了解IT领域最新产品与技术信息,那么订阅至顶网技术邮件将是您的最佳途径之一。

    重磅专题
    往期文章
    最新文章