FPGA開発日記

カテゴリ別記事インデックス https://msyksphinz.github.io/github_pages , English Version https://fpgadevdiary.hatenadiary.com/

MIPSのTLBについて勉強(シンプルなアドレス変換をISSに実行する)

MIPSのブートについて理解するためには、まずはMIPSアーキテクチャのメモリマップについて理解しなければ。

このあたりに、メモリマップの説明がある。

ファイル:MIPS32 MemoryMap.png - Wikipedia

https://upload.wikimedia.org/wikipedia/ja/8/84/MIPS32_MemoryMap.png

これを見ると、0xA000_0000-0xBFFF_FFFF, 0x8000_0000-0x9FFF_FFFF は実際には物理メモリの0x0000_0000からマップされるようになっているらしい。

Each Segment of an Address Space is classified as “Mapped” or “Unmapped”. A “Mapped” address is one that is
translated through the TLB or other address translation unit. An “Unmapped” address is one which is not translated
through the TLB and which provides a window into the lowest portion of the physical address space, starting at physical
address zero, and with a size corresponding to the size of the unmapped Segment.
Additionally, the kseg1 Segment is classified as “Uncached”. References to this Segment bypass all levels of the
cache hierarchy and allow direct access to memory without any interference from the caches

つまり、kseg0とkseg1は、問答無用で0x0000_0000にマップしても良いということか。

github.com

mips_env.cpp に仮想アドレスから物理アドレスに変換する関数を追加した。

Addr_t MipsEnv::ConvertVirtualAddress (Addr_t vaddr)
{
    if (0x80000000 <= vaddr && vaddr <= 0x9fffffff) {
        return vaddr - 0x80000000;
    } else if (0xA0000000 <= vaddr && vaddr <= 0xbfffffff) {
        return vaddr - 0xa0000000;
    } else {
        return vaddr;
    }
}

実行すると、仮想アドレスと物理アドレスを両方表示するようにしておく。

<Load Image /home/vagrant/xv6-mips/xv6.img>
<Info: NewMemory Region 1fc00000 is defined.>
         0 : [Vbfc00000:P1fc00000] 40086000 : mfc0    r12,0x0c,0x0            Wired=>00007ffd r08<=00007ffd
         1 : [Vbfc00004:P1fc00004] 24090001 : addiu   r09,r00,0x0001          r00=>00000000 r09<=00000001
         2 : [Vbfc00008:P1fc00008] 01294025 : or      r08,r09,r09             r09=>00000001 r09=>00000001 r08<=00000001
         3 : [Vbfc0000c:P1fc0000c] 01094026 : xor     r08,r08,r09             r08=>00000001 r09=>00000001 r08<=00000000
         4 : [Vbfc00010:P1fc00010] 3508ff00 : ori     r08,r08,0xff00          r08=>00000000 r08<=0000ff00
         5 : [Vbfc00014:P1fc00014] 3c091000 : lui     r09,0x1000              r09<=10000000
         6 : [Vbfc00018:P1fc00018] 01094025 : or      r08,r08,r09             r08=>0000ff00 r09=>10000000 r08<=1000ff00
         7 : [Vbfc0001c:P1fc0001c] 40886000 : mtc0    r12,0x0c,0x0            r08=>1000ff00 Wired<=1000ff00
         8 : [Vbfc00020:P1fc00020] 3c1d1fc0 : lui     r29,0x1fc0              r29<=1fc00000
         9 : [Vbfc00024:P1fc00024] 27bd0000 : addiu   r29,r29,0x0000          r29=>1fc00000 r29<=1fc00000
        10 : [Vbfc00028:P1fc00028] 3c181fc0 : lui     r24,0x1fc0              r24<=1fc00000
        11 : [Vbfc0002c:P1fc0002c] 27180124 : addiu   r24,r24,0x0124          r24=>1fc00000 r24<=1fc00124
        12 : [Vbfc00030:P1fc00030] 0300f809 : jalr    r24,r31                 r24=>1fc00124 r31<=bfc00038 pc<=bfc00034 pc<=1fc00124
        13 : [Vbfc00034:P1fc00034] 00000000 : sll     r00,r00,0x00            r00=>00000000
        14 : [V1fc00124:P1fc00124] 27bdffe8 : addiu   r29,r29,0xffe8          r29=>1fc00000 r29<=1fbfffe8
        15 : [V1fc00128:P1fc00128] 3c040001 : lui     r04,0x0001              r04<=00010000
        16 : [V1fc0012c:P1fc0012c] 00003021 : addu    r06,r00,r00             r00=>00000000 r00=>00000000 r06<=00000000
        17 : [V1fc00130:P1fc00130] afbf0014 : sw      r31,0x0014(r31)         r29=>1fbfffe8 r31=>bfc00038 (1fbffffc)<=bfc00038
        18 : [V1fc00134:P1fc00134] 0ff00037 : jal     0x3f00037               r31<=1fc0013c pc<=1fc00138 pc<=1fc000dc
        19 : [V1fc00138:P1fc00138] 24051000 : addiu   r05,r00,0x1000          r00=>00000000 r05<=00001000
        20 : [V1fc000dc:P1fc000dc] 27bdffe8 : addiu   r29,r29,0xffe8          r29=>1fbfffe8 r29<=1fbfffd0
        21 : [V1fc000e0:P1fc000e0] 30c901ff : andi    r09,r06,0x01ff          r06=>00000000 r09<=00000000
        22 : [V1fc000e4:P1fc000e4] 00063242 : srl     r06,r06,0x09            r06=>00000000 r06<=00000000
        23 : [V1fc000e8:P1fc000e8] 00855021 : addu    r10,r04,r05             r04=>00010000 r05=>00001000 r10<=00011000
        24 : [V1fc000ec:P1fc000ec] afbf0014 : sw      r31,0x0014(r31)         r29=>1fbfffd0 r31=>1fc0013c (1fbfffe4)<=1fc0013c
        25 : [V1fc000f0:P1fc000f0] 00894823 : subu    r09,r04,r09             r04=>00010000 r09=>00000000 r09<=00010000
        26 : [V1fc000f4:P1fc000f4] 24c80001 : addiu   r08,r06,0x0001          r06=>00000000 r08<=00000001
        27 : [V1fc000f8:P1fc000f8] 012a102b : sltu    r02,r09,r10             r09=>00010000 r10=>00011000 r02<=00000001
        28 : [V1fc000fc:P1fc000fc] 10400006 : beq     r02,r00,0x0006          r02=>00000001 r00=>00000000 pc<=1fc00100
        29 : [V1fc00100:P1fc00100] 01002821 : addu    r05,r08,r00             r08=>00000001 r00=>00000000 r05<=00000001

まずはここまで、シンプルな