云题海 - 专业文章范例文档资料分享平台

当前位置:首页 > PMON的pci设备初始化

PMON的pci设备初始化

  • 62 次阅读
  • 3 次下载
  • 2025/5/25 4:04:36

nextpciioaddr开始往下分配。分配的时候要注意不能超过最低可用的地址。 1. 北桥初始化

北桥提供了CPU和PCI设备相互访问的通道,实现了CPU空间和PCI空间的映射。_pci_hwinit() 具体地完成了这个工作。

所有的pci设备通过总线和pci桥联成一个树状结构。北桥Bonito是这棵树的根,与北桥直接相连的总线就是pcibus0。_pci_hwinit()的工作就是建立北桥和pcibus0的数据结构,同时进行CPU和PCI的地址映射。

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_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(\ return(-1); }

pd->pa.pa_flags = PCI_FLAGS_IO_ENABLED | PCI_FLAGS_MEM_ENABLED;

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;

//printf(\>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 = PCI_LOCAL_MEM_PCI_BASE; pd->pa.pa_dmat = &bus_dmamap_tag; pd->bridge.secbus = pb; _pci_head = pd;

从上面可以看到,北桥的pa.pa_flags被设置成IO_ENABLED和MEM_ENABLED,这就表示可以进行IO和内存访问。

Pa.pa_iot->bus_base被设置成BONITO_PCI_IO_BASE_VA,这个值被定义为0xbfd0.0000,它在CPU的Kseg1区间,因此是不经过TLB转换的。它的物理地址是0x1fd0.0000。Bontio规范中规定这个地址开始的1M空间是PCI的IO空间。

一个pci桥的配置体内有三个域和总线相关。分别是上游总线(Primary bus),下游总线(Secondary bus)和下级总线(Subordinate bus)。上游总线是和PCI桥相连的离CPU较近的总线。下游总线是离CPU较远的总线。下级总线则是和PCI相连的总线号最大的总线。

对于北桥来说,是没有上游总线的,而他的下游总线就是pcibus0,因此pd->bridge.secbus赋值为pb。

pb->minpcimemaddr = PCI_MEM_SPACE_PCI_BASE+0x01000000; pb->nextpcimemaddr=

PCI_MEM_SPACE_PCI_BASE+BONITO_PCILO_SIZE;

pb->minpciioaddr = PCI_IO_SPACE_BASE+0x000a000;

pb->nextpciioaddr =PCI_IO_SPACE_BASE+ BONITO_PCIIO_SIZE; pb->pci_mem_base = BONITO_PCILO_BASE_VA; //对应256M pb->pci_io_base = BONITO_PCIIO_BASE_VA; pb->max_lat = 255; pb->fast_b2b = 1; pb->prefetch = 1;

pb->bandwidth = 4000000; pb->ndev = 1;

_pci_bushead = pb;

_pci_bus[_max_pci_bus++] = pd;

Pcibus的minimemaddr被设置PCI_MEM_SPACE_PCI_BASE+0x01000000。而PCI_MEM_SPACE_PCI_BASE被定义成0,因此这个值就是16M.之所以这样做,是因为ISA设备只能使用最低16M内存空间。为了保持兼容性,这里预留最低16M的空间给ISA。

PCIbus0的nextpcimemadr被设置PCI_MEM_SPACE_PCI_BASE +

BONITO_PCILO_SIZE。这个值是192M。因此pci设备可用的空间就是16M到192M。

Pciioaddr的值是PCI_IO_SPACE_BASE+0XA000, Nextioaddr的值是

PCI_IO_SPACE_BASE+ BONITO_PCIIO_SIZE,也就是64k。因此pci设备可用的IO空间就是从地址40k到64k。

bus_dmamap_tag._dmamap_offs = 0;

/*set Bonito register*/ 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;

BONITO_PCIBASE0 = PCI_LOCAL_MEM_PCI_BASE; BONITO_PCIBASE1 = PCI_LOCAL_MEM_ISA_BASE;

BONITO_PCIBASE2 = PCI_LOCAL_MEM_PCI_BASE + 0x10000000;

return(1); }

为了说明上面代码,先要讲一下Bonito中几个寄存器的含义。 为了让CPU访问PCI空间,需要将CPU空间映射到PCI空间。在内存空间256M上方有三个连续的大小均为64M的区间,分别称为PCI_Lo0, PCI_Lo1,PCI_Lo2。这三个区间可以被北桥映射到PCI以64M对齐的任意位置。映射的关系通过设置Bonito的PCIMAP寄存器。该寄存器的格式如下图。

17 12 11 6 5 0

Pci_map2 Pci_lo2 Pci_lo1 Pci_lo0 PCIMAP寄存器

Pci_lo0,pci_lo1,Pci_lo2分别是上面所说三个区间的高6位地址(bit31-26),而Pci_map2是说明映射到2G以上的空间还是2G以下的空间。因此上面给BONITO_PCIMAP赋值就将PCI_lo0,PCI_lo1,PCI_lo2分别映射到了PCI 空间的从0,64M,128M开始的地址。

另外设备进行DMA时,还要提供一种机制将PCI地址转换成CPU地址。这是通过设置Base Address Register。Bonito中一共有三个这样的寄存器pcibas0-2。Pcibas0,pcibase1都可以映射多达256M的空间。具体映射的大小还取决于pcimembasecfg的设置。Pcibase2是映射Bonito的内部寄存器,映射区间为64k大小。

寄存器pcimembasecfg在start.S中设置。我们先看它各个域的含义。

Pcimembasecfg寄存器中的各个域

各个域的含义解释如下:

a) Io:说明示映射到IO空间还是内存空间。IO=0,则是映射到内存空间,

IO=1,则映射的是IO空间。

b) Cached:如果设置成1则使用IOBC,这样可以提高性能

c) Trans/mask各5位。用于决定pci地址的27-23位。一个pci地址,先要

拿掉高三位,然后mask取反后和27-23位相与,再或上trans。

在start.S中,pcimembasecfg的io位都为0,cached为都为1,因此pcibase寄存器映射的是内存空间,并且启用高速缓存。对于pcibase1,它的trans=00000b,mask=00000b,这样pcibase0映射的空间是256M,而pcibase0,它的trans=00000b,mask=11111b,这样pcibase0映射的空间是8M,以节省PCI空间。

现在再来看上面给PCIBASE寄存器赋值的三个语句。PCIBASE0被赋值为PCI_LOCAL_MEM_PCI_BASE(被定义为0x8000.0000),PCIBASE1被赋值PCI_LOCAL_MEM_ISA_BASE(定义为0x00800000)。这样当PCI设备访问地址在0x8000.0000-0x8FFF.FFFF时这个地址会先减掉0x80000000变成要访问的内存地址。如果设备访问地址在0x0080.0000-0x008F.FFFF,经过地址转换后,会变成内存的低8M地址。PCIBASE2被赋值为PCI_LOCAL_MEM_PCI_BASE + 0x10000000(值为0x9000.0000)。因此根据pci地址值,能正确的决定要访问的空间。

完成基本的地址映射后,就是初始化pci设备了:这包括设备的搜索和资源的分配。具体的工作在_pci_scan_dev和_setup_pcibuses完成的。

_pci_scan_dev在_pci_businit中调用。下面是它的调用方式。 for(i = 0, pb = _pci_head; i < pci_roots; i++, pb = pb->next) { //_pci_scan_dev(pb, i, 0, init); _pci_scan_dev(pb, i, 8, init);//from 8+11, hu mingchang }

前面已经说过_pci_head是指向北桥的。Pci_roots在初始化北桥后被置成1,因此_pci_scan_dev在_pci_businit中只调用一次。

再来看_pci_scan_dev static void

_pci_scan_dev(struct pci_device *dev, int bus, int device, int initialise) {

for(; device < 19; device++) //to 19+11, hu mingchang { _pci_query_dev (dev, bus, device, initialise); } }

搜索更多关于: PMON的pci设备初始化 的文档
  • 收藏
  • 违规举报
  • 版权认领
下载文档10.00 元 加入VIP免费下载
推荐下载
本文作者:...

共分享92篇相关文档

文档简介:

nextpciioaddr开始往下分配。分配的时候要注意不能超过最低可用的地址。 1. 北桥初始化 北桥提供了CPU和PCI设备相互访问的通道,实现了CPU空间和PCI空间的映射。_pci_hwinit() 具体地完成了这个工作。 所有的pci设备通过总线和pci桥联成一个树状结构。北桥Bonito是这棵树的根,与北桥直接相连的总线就是pcibus0。_pci_hwinit()的工作就是建立北桥和pcibus0的数据结构,同时进行CPU和PCI的地址映射。 int _pci_hwinit(initialise, iot, memt) int initialise; bus_space_tag_t iot; bus_space_tag_t memt; { /*pcireg_t stat;*/ <

× 游客快捷下载通道(下载后可以自由复制和排版)
单篇付费下载
限时特价:10 元/份 原价:20元
VIP包月下载
特价:29 元/月 原价:99元
低至 0.3 元/份 每月下载150
全站内容免费自由复制
VIP包月下载
特价:29 元/月 原价:99元
低至 0.3 元/份 每月下载150
全站内容免费自由复制
注:下载文档有可能“只有目录或者内容不全”等情况,请下载之前注意辨别,如果您已付费且无法下载或内容有问题,请联系我们协助你处理。
微信:fanwen365 QQ:370150219
Copyright © 云题海 All Rights Reserved. 苏ICP备16052595号-3 网站地图 客服QQ:370150219 邮箱:370150219@qq.com