一、PCI总线上的保留空间:
自第一台IBM PC问世以后,图形卡经历了MDA, Mono Hercults, CGA,
EGA, VGA, XGA, SVGA等等标准,总线也由ISA, EISA, VESA, PCI, AGP直到现在的PCIE,前前后后共约30年的进程。虽然好多硬件都渐渐湮没在历史的洪流中,但是由于兼容性需要,有的东西还是作为不被公开的秘密保留了下来。下面是历史上出现的这些显卡使用的内存和I/O空间的分布情况:
Memory Space:
0xA0000 ~ 0xAFFFF: 64KB,VGA显示缓冲区
0xB0000 ~ 0xB7FFF: 32KB,MDA或Hercults单显卡显示缓冲区
0xB8000 ~ 0xBFFFF: 32KB,CGA显示缓冲区
0xC0000 ~ 0xCFFFF: 64KB,VGA BIOS
I/O Space:
0x3B0~0x3DF: 显卡控制寄存器I/O空间
为了和前辈PC兼容,在Intel制定PCI总线标准时,在PCI空间保留了从0开始连续1MB的Memory空间和从0开始连续64KB的I/O空间,其中:
PCI Memory Space:
0xA0000~0xCFFFF:留给Generic VGA模式下VGA卡使用
PCI I/O Space:
0x3B0~0x3DF: 留给Generic VGA模式下VGA卡使用
在PC机Boot的时候,BIOS程序会扫描整个PCI空间,发现有PCI显卡时,会Enable它的Mem访问和I/O访问,同时会配置它的Memory空间和I/O空间。但是上面提到的那两块保留的Memory空间和I/O空间是不需要作专门配置的,PCI显卡可以直接响应落在这两段空间上的PCI访问请求。
也因为PCI总线上存在保留区域,所以在BIOS程序扫描配置整个PCI空间的时候,必须空出这些保留区域,否则在实际应用中会发生地址冲突的现象。
二、虚地址,物理地址和PCI总线地址
有这么多年VGA显卡的应用历史,相关的书籍资料非常丰富。但是,所有这些都是针对PC机上的VGA显卡的。但实际的嵌入式应用中,基于x86体系的SoC却相当的少。龙芯,Alchemy,XScale等好多SoC都集成有PCI总线控制器(有的地方也称之为PCI桥)。在这类芯片的应用中使用PCI VGA芯片就不能照搬PC机上的经验了。
兰色数据路径上的地址是虚地址,经过MMU的映射就成了物理地址了(绿线数据路径);如果物理地址在PCI控制器的地址响应范围以内,它就会被PCI控制器映射为PCI总线地址(红线数据路径)
例如:Alchemy
Au1500,它的PCIB响应的物理地址区间为:
0x4 0000 0000~0x4 FFFF FFFF: PCI
Non-cacheable Memory Space
0x5 0000 0000~0x5 FFFF FFFF: PCI I/O Space
这样,保留给VGA显卡的PCI空间物理地址就成了:
0x4 000A 0000~0x4 000A FFFF: 显示缓冲区
0x5 0000 03B0~0x5 0000 03DF: 控制寄存器
另外,Au1500的物理地址是36bit的,所以,得将其映射成32bit的虚地址才能使用。
三、VGA卡的Bank操作
VGA卡的Bank有时也被称为Page,这个概念源自于DOS实模式时代。从0xA0000开始的连续64KB的内存空间被称为图形Window。因为在DOS实模式下每个段最大只能到64KB,所以那时的VGA显卡都采用这种图形Window结构。而在非x86的SoC中没有64KB段的限制,所以这个图形Window就很容易被人忽视了。
VGA的Bank操作是这样的:利用专门的Generic
VGA的Bank(也称page)选择寄存器,通过64KB的图形Window来访问VGA显卡上的所有显存空间。
有了这样的知识,在移植SVGA-lib时,就不会感到奇怪和不解了。
文章评论(0条评论)
登录后参与讨论