龙芯3A4000处理器解读 ②

龙芯3A4000处理器解读 2

第一章简述了3A4000的芯片结构,并对照结构图举例了访问7A的通道,那么本章节主要梳理CPU如何获取到一条分配给到7A的地址如何通过窗口命中正确访问到有效数据.

文章目录

地址窗口(X1 & X2)

每个Master端口接收到的请求都通过路由配置,然后访问对应的slave端,无论X1还是X2,每个master端口都拥有8个地址窗口,可以完成8个地址窗口的目标路由.
3A4000的 master端 (X1+X2) : CORE0, CORE1, CORE2, CORE3, SCACHE0, SCACHE1, SCACHE2, SCACHE3, IO_L1X(默认写死),IO_L2X, HT0_LO, HT0_HI, MISC, SE, HT1_LO, HT1_HI,以上是可被地址窗口路由的.

地址窗口路由: 假设你想访问一个端口A,而你访问到A必须经过B,那么B如何配置,才可以识别处理器给的地址是访问的A的地址呢,这就相当于一个路由器,所有地址都发到了该端口,再由端口进行分发,该是发往哪个设备的发往哪个设备.

由以上可被地址窗口路由的信息可知: 龙芯3A4000的路由主要通过系统的两级交叉开关与IO-RING实现.
以一个Core为例:

Core0.i \ Data WinBase WinMask WinMmap
Core0.0Win 0x10000000 0xffff f8000000 0x0000 0e00 1000008e
Core0.1Win 0x40000000 0xffff c0000000 0x0000 0e00 4000008e
Core0.2Win 0x18000000 0xffff fc000000 0x0000 0efd fc00008e
Core0.3Win 0x1e000000 0xffff ff000000 0x0000 0e00 0000008e

窗口命中公式: (IN_ADDR & MASK) == BASE
新地址换算公式: OUT_ADDR = (IN_ADDR & ~MASK) | {MMAP[63:10], 10’h0}

我们以目前3A4000上的7A的Pci的IO空间: 0x90000efdfc000000 为例.
IN_ADDR: master上游地址.

缺省配置:

  • 0x0000 0000 ~ 0x0fff ffff 的地址区间(256M)映射到DDR的0x00000000 ~ 0x0fff ffff
  • 0x1000 0000 ~ 0x17ff ffff 映射到桥片的PCI_MEM空间
  • **0x1800 0000 ~ 0x19ff ffff 映射到桥片的PCI_IO空间 **
  • 0x1a00 0000 ~ 0x1aff ffff 映射到桥片的PCI配置空间(Type0)
  • 0x1b00 0000 ~ 0x1bff ffff 映射到桥片的PCI配置空间(Type1)
  • 0x4000 0000 ~ 0x7fff ffff 映射到桥片的PCI_MEM空间

IN_ADDR: 0x1800 0000 & 0xffff fc00 0000 = 0x1800 0000 可覆盖范围: 0x1800 0000 ~ 0x1bff ffff,
OUT_ADDR: (0x1800 0000 & 0x300 0000) = 0x0 | 0x0000 0efd fc000000 = 0x0000 0efd fc00 0000 0x8e(窗口使能,slave HT1_LO.)
OUT_ADDR 相当于除去开窗口的基地址,将该窗口的偏移大小路由到了另一个地址+该偏移. 0x0efd fc000000就是路由到HT1_LO的地址.
以 0x4000 0000, 0x4000 0000 & 0xffff c000 0000 = 0x4000 0000, 可覆盖的范围 IN_ADDR 0x4000 0000 ~ 0x7fff ffff.

0x0e00 0000 008e: 路由到从设备HT1_LO, HT1_LO接收到的地址是0e00 0000 0000, 然后进行HT窗口命中.
0x0efdfc000000, 0xfd fc00 0000该40位地址如何路由的? 0xfdfc00 0000 在HT1_LO窗口中,命中了内部窗口I/O空间的窗口.

Base是窗口的命中路由的基地址,mask是窗口的大小.

TLB

在LA平台上,当我们写Code时,访问了一个非法地址,一般情况下会出发Tlb例外,即我们访问的地址Cpu不认识。

我们平台上的主存物理地址划分:
0x00000000 - 0x10000000 ==> 0x80000000 - 0x90000000 :低256M内存区域
0x90000000 - MaxMem : 256M以上内存条的Size

我们编写的Code都是给Cpu’s Core看的,而LA平台上电时我们已将Cpu从直接物理地址访问模式切换到了虚实地址映射的方式,所以我们看到只能使用对应的64Bit虚拟地址进行访问。
恰好 0x90000000 - MaxMem 的内存被映射到了 0x8000000090000000 - Max (uncache,不过cache窗口).

所以比较下面两条Asm代码:

li.d a0, 0x8000000090000000
ld.d t0, a0, 0 /*1*/
li.d a0, 0x90000000
ld.d t0, a0, 0 /*2*/
  1. 可以正常load物理地址为0x90000000(即主存的256M位置的一个64Bit的数据)
    2)会触发Tlb例外,说白了就是Core不认识该地址。
    那么针对 2 我们怎么操作可以让其识别呢?
  • 1 取消虚实地址映射,但是这样我们64Bit虚地址都会产生地址错误.
  • 2 添加Tlb表项,即当我们再次使用2方式时,MMU会首先将0x90000000的64bit虚拟地址翻译成0x90000000的正确物理地址,然后返回有效数据.
    龙芯3A4000处理器解读 ②

固件下Tlb例外后暂时没有操作,即直接异常Assert, CPU记录下异常地址; 而内核中,如果TLB会去查TLB内存表项,然后填表,将进程的虚拟地址切换到一段真正的物理地址(自身理解,有问题请指出).

关于虚拟内存管理技术

随着计算机的发展,应用程序的规模逐渐增大,一个难题出现在程序员的面前,那就是应用程序太大以至于内存容纳不下该程序,通常解决的办法是把程序分割成许多称为覆盖块(overlay)的片段。覆盖块0首先运行,结束时他将调用另一个覆盖块。虽然覆盖块的交换是由OS完成的,但是必须先由程序员把程序先进行分割,这是一个费时费力的工作,而且相当枯燥。人们必须找到更好的办法从根本上解决这个问题。

人们找到了另外一个办法,这就是虚拟内存管理(Virtual Memory Management)技术。虚拟内存管理技术的基本思想是程序,数据,堆栈的总的大小可以超过物理存储器的大小,操作系统把当前使用的部分保留在内存中,而把其他未被使用的部分保存在磁盘上。比如对一个16MB的程序和一个内存只有4MB的机器,OS通过选择,可以决定各个时刻将哪4M的内容保留在内存中,并在需要时在内存和磁盘间交换程序片段,这样就可以把这个16M的程序运行在一个只具有4M内存机器上了。而这个16M的程序在运行前不必由程序员进行分割。需要说明的一点,操作系统的内核是常驻内存的。

围绕着虚拟内存管理(Virtual Memory Management)技术,就产生了分页技术,虚拟地址,地址空间,TLB,MMU等概念

Tip: 成长路上必定经历很多风雨,加油吧,打工人 ~

上一篇:3.Java基础语法


下一篇:原码、反码、补码知识详细讲解