您的位置:首页 > 其它

龙芯软件开发(25)-- PCI设备初始化3

2007-01-16 00:37 369 查看
上面继续初始化南桥之后,再接着下来,就要初始化PCI总线上其它的设备了。看下面的代码:

[align=left]CPU_ConfigCache();[/align]
上面重新配置龙芯2E的缓存。
[align=left] [/align]
_pci_businit(1); /* PCI bus initialization */
上面继续初始化PCI总线上的设备,这个函数里要初始化完成所有其它连接到PCI总线上的设备。接着看这个函数的代码如下:

[align=left]void[/align]
[align=left]_pci_businit (int init)[/align]
[align=left]{[/align]
[align=left] char *v;[/align]
[align=left] [/align]
[align=left] tgt_putchar('P');[/align]
[align=left] v = getenv("pciverbose");[/align]
[align=left] if (v) {[/align]
[align=left] _pciverbose = atol(v);[/align]
[align=left] }[/align]
上面获取PCI显示值。
[align=left] [/align]
[align=left] /* intialise the PCI bridge */[/align]
[align=left] if (/*init*/ 1) {[/align]
[align=left] SBD_DISPLAY ("PCIH", CHKPNT_PCIH);[/align]
[align=left] init = _pci_hwinit (init, &def_bus_iot, &def_bus_memt);[/align]
[align=left] pci_roots = init;[/align]
[align=left] if (init < 1)[/align]
[align=left] return;[/align]
[align=left] }[/align]
上面实现PCI的分配空间,主要设置北桥。以便后面可以搜索到所有PCI的设备。
[align=left] [/align]
[align=left] if(monarch_mode) {[/align]
[align=left] int i;[/align]
[align=left] struct pci_device *pb;[/align]
[align=left] [/align]
[align=left] if (_pciverbose) {[/align]
[align=left] printf("setting up %d bus/n", init);[/align]
[align=left] }[/align]
[align=left] for(i = 0, pb = _pci_head; i < pci_roots; i++, pb = pb->next) {[/align]
[align=left] _pci_scan_dev(pb, i, 0, init);[/align]
[align=left] }[/align]
上面实现所有PCI设备的枚举。由于PCI插槽上有很多设备,并且是即插即用,并不能确定那个设备一定存在,所以只能枚举所有设备。
[align=left] [/align]
[align=left] [/align]
[align=left] _setup_pcibuses(init);[/align]
上面把发现的PCI设备全部初始化。
[align=left] [/align]
[align=left] }[/align]
}

下面是PCI函数_pci_hwinit初始化实现:
[align=left]int[/align]
[align=left]_pci_hwinit(initialise, iot, memt)[/align]
[align=left] int initialise;[/align]
[align=left] bus_space_tag_t iot;[/align]
[align=left] bus_space_tag_t memt;[/align]
[align=left]{[/align]
[align=left] /*pcireg_t stat;*/[/align]
[align=left] struct pci_device *pd;[/align]
[align=left] struct pci_bus *pb;[/align]
[align=left] [/align]
[align=left] [/align]
[align=left] if (!initialise) {[/align]
[align=left] return(0);[/align]
[align=left] }[/align]
上面判断是否需要初始化,如果不需要分配PCI的链表,就返回去。
[align=left] [/align]
[align=left] pci_local_mem_pci_base = PCI_LOCAL_MEM_PCI_BASE;[/align]
[align=left] /*[/align]
[align=left] * Allocate and initialize PCI bus heads.[/align]
[align=left] */[/align]
[align=left] [/align]
[align=left] /*[/align]
[align=left] * PCI Bus 0[/align]
[align=left] */[/align]
[align=left] pd = pmalloc(sizeof(struct pci_device));[/align]
[align=left] pb = pmalloc(sizeof(struct pci_bus));[/align]
[align=left] if(pd == NULL || pb == NULL) {[/align]
[align=left] printf("pci: can't alloc memory. pci not initialized/n");[/align]
[align=left] return(-1);[/align]
[align=left] }[/align]
上面分配一个PCI链表的节点,由于PCI总线上的设备是可变的,只能使用链表来保存设备信息。同时还判断内存是否分配成功。
[align=left] [/align]
[align=left] [/align]
[align=left] pd->pa.pa_flags = PCI_FLAGS_IO_ENABLED | PCI_FLAGS_MEM_ENABLED;[/align]
上面设置使用IO和内存空间。
[align=left] [/align]
[align=left] pd->pa.pa_iot = pmalloc(sizeof(bus_space_tag_t));[/align]
[align=left] pd->pa.pa_iot->bus_reverse = 1;[/align]
[align=left] pd->pa.pa_iot->bus_base = BONITO_PCIIO_BASE_VA;[/align]
上面设置IO的TAG配置。
[align=left] [/align]
[align=left] //printf("pd->pa.pa_iot=%p,bus_base=0x%x/n",pd->pa.pa_iot,pd->pa.pa_iot->bus_base);[/align]
[align=left] pd->pa.pa_memt = pmalloc(sizeof(bus_space_tag_t));[/align]
[align=left] pd->pa.pa_memt->bus_reverse = 1;[/align]
[align=left] //pd->pa.pa_memt->bus_base = 0xa0000000; /* pci memory start from 0x10000000 */[/align]
[align=left] pd->pa.pa_memt->bus_base = 0xb0000000; /* pci memory start from 0x00000000 */[/align]
上面设置内存空间。
[align=left] [/align]
[align=left] pd->pa.pa_dmat = &bus_dmamap_tag;[/align]
上面设置DMA配置。
[align=left] [/align]
[align=left] pd->bridge.secbus = pb;[/align]
[align=left] _pci_head = pd;[/align]
上面保存PCI设备。
[align=left] [/align]
[align=left]#ifndef NEW_PCI_WINDOW[/align]
[align=left] /* reserve first window for vga mem */[/align]
[align=left] pb->minpcimemaddr = PCI_MEM_SPACE_PCI_BASE+0x04000000;[/align]
[align=left] pb->nextpcimemaddr = PCI_MEM_SPACE_PCI_BASE+BONITO_PCILO_SIZE;[/align]
[align=left]#else[/align]
[align=left] pb->minpcimemaddr = PCI_MEM_SPACE_PCI_BASE;[/align]
[align=left] pb->nextpcimemaddr = PCI_MEM_SPACE_PCI_BASE+ 0x0a000000;[/align]
[align=left]#endif[/align]
[align=left] pb->minpciioaddr = PCI_IO_SPACE_BASE+0x000a000;[/align]
[align=left] pb->nextpciioaddr = PCI_IO_SPACE_BASE+ BONITO_PCIIO_SIZE;[/align]
[align=left] pb->pci_mem_base = BONITO_PCILO_BASE_VA;[/align]
[align=left] pb->pci_io_base = BONITO_PCIIO_BASE_VA;[/align]
[align=left] pb->max_lat = 255;[/align]
[align=left] pb->fast_b2b = 1;[/align]
[align=left] pb->prefetch = 1;[/align]
[align=left] pb->bandwidth = 0x4000000;[/align]
[align=left] pb->ndev = 1;[/align]
[align=left] _pci_bushead = pb;[/align]
[align=left] _pci_bus[_max_pci_bus++] = pd;[/align]
上面保存PCI总线配置。
[align=left] [/align]
[align=left] [/align]
[align=left] [/align]
[align=left] bus_dmamap_tag._dmamap_offs = 0;[/align]
[align=left] [/align]
[align=left]#ifndef NEW_PCI_WINDOW[/align]
[align=left] /*set Bonito register; first windows for 0-0x4000000 pci mem */[/align]
[align=left] BONITO_PCIMAP =[/align]
[align=left] BONITO_PCIMAP_WIN(0, /*PCI_MEM_SPACE_PCI_BASE+*/0x00000000) | [/align]
[align=left] BONITO_PCIMAP_WIN(1, PCI_MEM_SPACE_PCI_BASE+0x04000000) |[/align]
[align=left] BONITO_PCIMAP_WIN(2, PCI_MEM_SPACE_PCI_BASE+0x08000000) |[/align]
[align=left] BONITO_PCIMAP_PCIMAP_2;[/align]
[align=left]#else[/align]
[align=left] BONITO_PCIMAP = (PCI_MEM_SPACE_PCI_BASE >>27) | (((PCI_MEM_SPACE_PCI_BASE + 0x08000000) >>25)<<5);[/align]
[align=left]#endif[/align]
[align=left] [/align]
[align=left] BONITO_PCIBASE0 = PCI_LOCAL_MEM_PCI_BASE;[/align]
[align=left] [/align]
[align=left] BONITO_PCIBASE1 = PCI_LOCAL_MEM_ISA_BASE;[/align]
[align=left] [/align]
[align=left] BONITO_PCIBASE2 = PCI_LOCAL_REG_PCI_BASE;[/align]
[align=left] [/align]
[align=left] /* pci base0/1 can access 256M sdram */[/align]
[align=left] BONITO_PCIMEMBASECFG = 0;[/align]
上面设置了北桥里的PCI配置内存空间分配。
[align=left] [/align]
[align=left] [/align]
[align=left] return(1);[/align]
}

这里的代码,先从北桥里分配PCI的IO空间和内存空间,然后通过枚举所有内存空间来发现PCI的设备,最后对于发现的设备进行配置,并启动相应的设备。
后面再仔细地查看怎么样实现查询PCI设备的发现和PCI设备配置。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: