Powerpc-E500 看我如何消费TLB

来源:互联网 发布:3d网络播放器 编辑:程序博客网 时间:2024/04/29 09:44
    Powerpc E500 实现有两级 TLB,即:L1 TLB 和 L2 TLB。L1 TLB 可以理解为 L2 TLB 的部分缓存。访问 L1 TLB 的效率要比 L2 的效率高,相应的实现的花费也就高。L1 TLB 由硬件维护,不可编程精确控制。程序员可控制的一般是L2 TLB,因此以下的讨论皆针对 L2 TLB,为方便简称其为 TLB。
    由于L1 MMU只是一个L2MMU的一个子集,硬件负责自动更新,因此我们可以就可以通过编程控制L2 MMU中的TLB就能达到操作TLB的目的。

    通过对L2 MMU的TLB编程,我们可以进行根据虚拟地址查找匹配的TLB entry,建立虚拟页<—>物理页映射,修改TLB entry中的属性,无效TLB等等操作,这样的方式让powerpc e500的MMU更加灵活。

1. 根据一个虚拟地址找到对应的TLB Entry

  说明:我们用程序控制找到的entry指的是L2 MMU 中Tlb中的entry index。
  指令tlbsx RA,RB
  准备:
      (1) 首先配置MAS6寄存器:SPID0域和SAS域;
      (2) 把我们需要寻找的虚拟地址放到RA+RB中(一般直接放到RB中,RA置0);
      (3) 执行tlbsx RA,RB指令;
  执行:
    指令tlbsx会根据MAS6、RA+RB的值,进行如下匹配:对L2 MMU中TLB0和TLB1的每一个entry进行查询:
      (1)entry中的V域是否有效;
      (2)MAS6、RA+RB与entry对应的字段进行匹配:SPID0 == TID,SAS == TS, EPN == (RA+RB) (上面的“==”表示匹配,不一定是相等,例如:ENP == (RA+RB) ,这里需要根据entry的size域来确定EPN的位数。EPN总共20位,所以对应的最小页大小是4k,即这20位都作为虚拟页号;如果size指示页大小为4M ,即一页占22位,那么EPN只有10位有效,这时秩序匹配RA+RB的高10位就可以了)
      (3)若MAS6、RA+RB匹配到某一个entry,并且V域有效,则说明我们匹配成功,也就是命中,否则没有匹配到任何entry表示不命中。
   输出:
      (1)若tlbsx命中:将命中的entry,包括entry index输出到如下寄存器的相应字段中。MAS0 ~ MAS3:MAS1[V] = 1,MAS0[TLBSEL] = 命中的是TLB0/TLB1, MAS0[ESEL]命中的entry的index或者TLB0的哪一路。
      (2)若没有命中,则MAS1[V] = 0,MAS2[RPN] 为 0
  举例:

/* Find the index of the entry we're executing in */    bl    invstr                /* Find our address */invstr:    mflr    r6                /* Make it accessible :r6存放的便是当前正在执行代码的虚拟地址 */    mfmsr    r7    rlwinm    r4,r7,27,31,31            /* extract MSR[IS] :提取当前的[IS]地址空间 */    mfspr    r7, SPRN_PID0    slwi    r7,r7,16    or    r7,r7,r4    mtspr    SPRN_MAS6,r7        /* 设置MAS6的SAS */    tlbsx    0,r6                /* search MSR[IS], SPID=PID0 */
   上面的代码表示将我们正在执行的 标号invstr处的地址放到r6中,并在Tlb的当前(IS)地址空间中查找r6这个地址对应的entry。
    

2. 读Tlb

      如果我们想了解某个entry的内容,比如它的RPN(物理页号),就将这个entry的值读出到MAS寄存器中,然后再从MAS寄存器取出到普通寄存器就可以了。
  指令:tlbre
  准备:

      (1) 通过MAS0选择我们要读取的entry。
        配置MAS0[TLBSEL]指定读TLB0还是TLB1;
        配置MAS0[ESEL]指定命中是哪一个entry,若选择的是TLB0,还需要先借助EPN[45:51]来进行索引组,然后通过ESEL则来路选确定具体的entry项。
      (2) 执行tlbre,根据上面的信息读取指定的tlb entry。
   过程:
      tlbre指令根据MAS0中TLBSEL和ESEL域来定位某个entry,并把entry中内容读出到各个MAS寄存器的相关域中。
  举例:

  li    r6,0                /* Set Entry counter to 0 */    lis    r7,0x1000            /* Set MAS0(TLBSEL) = 1 */    rlwimi    r7,r6,16,4,15            /* Setup MAS0 = TLBSEL | ESEL(r6) */    mtspr    SPRN_MAS0,r7    tlbre
    上述代码的目的是读取tlb1中的entry0

3. 写TlB

    和读Tlb类似,要写某个Tlb entry首先要定位这个entry,然后将各个MAS0中的对应的各个域写入到这个entry。
  指令tlbwe
  准备

      (1) 通过MAS0选择我们要读取的entry。
        配置MAS0[TLBSEL]指定读TLB0还是TLB1;
        配置MAS0[ESEL]指定命中是哪一个entry,若选择的是TLB0,还需要先借助EPN[45:51]来进行索引组,然后通过ESEL则来路选确定具体的entry项。
      (2) 准备好我们需要写到entry中内容。填写好各个MAS寄存器中与entry对应的各个域,如MAS2[EPN],MAS3[RPN]等。
      (3) 执行tlbwe,根据上面的信息找到指定的tlb entry,并将这个entry的信息写到各个MAS寄存器中。  
  过程
    tlbwe指令根据MAS0中TLBSEL和ESEL域来定位某个entry,并把entry中内容读出到各个MAS寄存器的相关域中。
  举例

 li    r6,0                /* Set Entry counter to 0 */    lis    r7,0x1000            /* Set MAS0(TLBSEL) = 1 */    rlwimi    r7,r6,16,4,15            /* Setup MAS0 = TLBSEL | ESEL(r6) */    mtspr    SPRN_MAS0,r7    /* 找到TLB1的entry0 */        mfspr    r7,SPRN_MAS1    rlwinm    r7,r7,0,2,31            /* Clear MAS1 Valid and IPROT */    mtspr    SPRN_MAS1,r7    tlbwe                            /* 写TLB */
    上述代码修改(清除)TLB1中entry0的Valid和IPOROT域。

4. invalid TLB项

  指令:tlbivax RA + RB
  准备:
EA = RA + RB 为虚拟地址
  过程:
    (1) EA[32:51] 用于匹配 TLB 项 (组选 + EPN 匹配),其不进行 PID 和 AS 的比较,则若同一组内有相同的 EPN,皆会将其置无效。
    (2) EA[60] 用于选择操作的对象是 TLB0 还是 TLB1,类似 MAS0[TLBSEL];
    (3) EA[61] 为 1 则置无效 TLB0 或 TLB1 的所有项
    (4) 若 HID1[ABE] = 1 则该无效操作亦广播给其它 Core,置无效相应的项。
  注意:若TLB1的某项entry 的IPROT域为1,可以不受tlbivax的影响。
  举例:

  /* 当前进程的data地址空间中,寻找虚拟地址为0xc0000000的TLB entry */    lis        r6 , 0xc0000000@h    ori     r6 , r6 , 0xc0000000@l            mfmsr    r7    rlwinm    r4,r7,27,31,31            /* extract MSR[DS] */    mfspr    r7, SPRN_PID0    slwi    r7,r7,16    or    r7,r7,r4    mtspr    SPRN_MAS6,r7    tlbsx    0,r6                /* search MSR[DS], SPID=PID0 */    /* 设置这个entry的IPROT域,保证后面的tlbivax指令不会让自己无效 */    mfspr    r7,SPRN_MAS0    rlwinm    r3,r7,16,20,31            /* Extract MAS0(Entry) */    mfspr    r7,SPRN_MAS1            /* Insure IPROT set */    oris    r7,r7,MAS1_IPROT@h    mtspr    SPRN_MAS1,r7    tlbwe        /* 除了我们设置的0xc0000000对应的entry,TLB0和TLB1中的其他的entry全部置无效(除非某个其他的entry中也设置了IPROT位) */    /* Invalidate TLB0 */    li    r6,0x04    tlbivax    0,r6    TLBSYNC    /* Invalidate TLB1 */    li    r6,0x0c    tlbivax    0,r6    TLBSYNC





0 0
原创粉丝点击