在考虑PCI地址映射问题时,需要理清两个概念:主机端虚拟地址和DSP端物理地址。
主机端虚拟地址是指在主机端进行任何操作时,编程人员提供给系统的地址,这个地址必须在系统的整个编址空间内,且如果是对某个设备进行操作,那么这个地址还必须在系统为这个设备分配的特定的一块(或不连续的几块)编址空间里。这个地址一般由一个基地址和编程人员提供的偏移地址组合而成。
DSP端物理地址是指,在DSP端进行任何操作时,编程人员提供给DSP的地址,这个地址必须在DSP的整个编址空间内,且如果DSP所统辖的物理资源没有占用编址空间内的所有地址(一般没有任何系统),那么这个地址就必须在为具体物理设备分配的编址空间里。这个地址在主机端一般由DSPP寄存器的值作为基址,与编程人员提供的偏移地址组合而成。
明白这两个概念后,让我们来看看具体到DM642的PCI接口的地址映射,都有哪些需要注意的事情。
一、配置空间
配置空间的一部分寄存器的内容,是在DM642被主机识别时,从EEPROM里读出信息来进行赋值的,这些值包括芯片的类型、厂商信息、版本号等信息,一般是编程人员无法修改的信息。另一部分(Base0,Base1,Base2等)则是在DM642被识别时,由主机系统底层的PCI总线驱动程序进行分配的,由系统决定,也是编程人员无法修改的。PCI接口标准规定每个PCI设备最多可以有6块编制空间,DM642用了三块,这三块空间在主机端的虚拟地址的基地址,就是由PCI总线驱动程序分配给Base0、Base1、Base2三个寄存器的值。
二、虚拟地址向物理地址转换
设备驱动程序的编程人员只需要标定Base0、Base1、Base2空间,并指定一个偏移地址就可以实现对设备分配的虚拟地址进行读写等操作。但是如果要求这个地址在DSP端可以解析成为一个自己想要的物理地址,则需要编程人员事先设定DSPP寄存器的值(对于DM642的PCI接口,只有在读写Base0空间时需要设置DSPP值,Base1和Base2空间不需要设置)。DSPP寄存器的值可以通过两种方式进行读写。第一种是通过Base1空间的0x01C1FFF8地址(Base1的物理地址的前九位是固定的0000 0001 1,只需要提供一个0x0041FFF8的偏移地址即可),第二种是通过Base2空间的0x00000008地址(Base2空间只有4个Word的空间,不足以分页,因此不需要提供DSPP)。
在Base0空间的访问过程中,DSPP寄存器和偏移地址的组合方式是:DSPP寄存器的后10位(0-9位)作为物理地址的最高10位,偏移地址的后22位(0-21位)作为物理地址的最低22位,且偏移地址的高10位必须设为0,不得越界。
三、DSP端物理地址空间的分配
根据C64x系列DSP的文档说明,0x0000000-0x0003FFFF之间的256K地址作为片内或Cache的地址,因为DM642芯片内只有256K缓存器,因此这个空间只有256K。0x00040000-0x7FFFFFFF之间的地址保留或映射到外设寄存器(DM642的Base1空间即时从这部分空间中映射出来的),因此如果对这部分编址(除了映射给外设寄存器之外的)空间进行读写,将不可能成功。0x80000000-0x8FFFFFFF之间的地址用来映射SDRAM的存储空间。0x90000000-0x9FFFFFFF之间的地址用来映射FLASH、UART(Universal Asynchronous Receiver/Transmitter,通用异步收发器,并行数据转串行数据)和FPGA(Field Programmable Gate Array,即现场可编程门阵列)寄存器。0xA0000000-AFFFFFFF之间的地址分配给Daughter Card(这个东西我也没用过)。0xB0000000-0xFFFFFFFF之间的地址分配给FPGA Sync Regs和Daughter Card。
总结一下,我们在写一个PCI设备的时候,它的主机端虚拟地址并不是重要的,而且是对用户透明的,重要的是他的DSP端物理地址。因此只需要给定一个偏移地址和设定一个DSPP值,就完全可以对设备的空间进行读写了。至于读写是否成功,要看你写的地址是否对应了一个实际存在的物理设备。至此,DM642的地址映射机制讲完了,如有不当,请批评指正。
[说明]这里所指的“编程人员”,是PCI设备驱动以及驱动以上的应用程序的开发人员,不包括操作系统和PCI总线驱动程序的开发人员。
--------------
§ 李文凯 2008年04月08日 §
§ 作于WHHIT之IMLAB §
--------------