Annotation of nono/m680x0/m68030mmu.h, revision 1.1.1.4

1.1       root        1: //
                      2: // nono
1.1.1.2   root        3: // Copyright (C) 2020 nono project
                      4: // Licensed under nono-license.txt
1.1       root        5: //
                      6: 
                      7: #pragma once
                      8: 
                      9: // ATC_SINGLE は過去との比較のために残してある、双方向リストによる
                     10: // FC 混合 22 エントリ実装。
                     11: // 定義しない場合(デフォルト)は、FC 別の世代付き配列みたいなもの。
                     12: //#define ATC_SINGLE 1
                     13: 
                     14: // SRP, CRP
                     15: class m68030RP
                     16: {
                     17:        //        6                   5                   4               3
                     18:        //  3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2
                     19:        // +-+-----------------------------+---------------------------+---+
                     20:        // |U|           LIMIT             |          unused           |DT |
                     21:        // +-+-----------------------------+---------------------------+---+
                     22:        //
                     23:        //    3                   2                   1                   0
                     24:        //  1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0
                     25:        // +-------------------------------------------------------+-------+
                     26:        // |           TABLE ADDRESS (PA31-PA4)                    |unused |
                     27:        // +-------------------------------------------------------+-------+
                     28:  public:
                     29:        static const uint32 H_MASK      = 0xffff0003;
                     30:        static const uint32 L_MASK      = 0xfffffff0;
                     31: };
                     32: 
                     33: // TT レジスタの各フィールドを束ねた構造体のようなもの。
                     34: // m68kcpu::SetTT(), GetTT() で読み書きする。
                     35: class m68030TT
                     36: {
                     37:        //    3                   2                   1                   0
                     38:        //  1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0
                     39:        // +---------------+---------------+-+-+-+-+-+-+-+-+-+-----+-+-----+
                     40:        // |LogicalAddrBase|LogicalAddrMask|E|       |C|R|M| | FCB | | FCM |
                     41:        // +---------------+---------------+-+-+-+-+-+-+-+-+-+-----+-+-----+
                     42: 
                     43:  public:
                     44:        static const uint32 MASK                = 0xffff8777;
                     45: 
                     46:        static const uint32 LBASE_MASK  = 0xff000000;
                     47:        static const uint32 LMASK_MASK  = 0x00ff0000;
                     48:        static const uint32 E                   = 0x00008000;
                     49:        static const uint32 CI                  = 0x00000400;
                     50:        static const uint32 RW                  = 0x00000200;
                     51:        static const uint32 RWM                 = 0x00000100;
                     52:        static const uint32 FCBASE_MASK = 0x00000070;
                     53:        static const uint32 FCMASK_MASK = 0x00000007;
                     54: 
1.1.1.3   root       55:        uint32 e {};                    // 00008000 イネーブル
                     56:        uint32 ci {};                   // 00000400 キャッシュ禁止
                     57:        uint64 base {};                 // ベース
                     58:        uint64 mask {};                 // マスク
1.1       root       59: 
                     60:        // アクセスがこの TT と一致するか調べる。
                     61:        bool Match(uint64 ssw_laddr);
                     62: };
                     63: 
                     64: // TC レジスタの各フィールドを束ねた構造体のようなもの。
                     65: // m68kcpu::SetTC(), GetTC() で読み書きする。
                     66: class m68030TC
                     67: {
                     68:  public:
                     69:        static const uint32 MASK        = 0x83ffffff;
                     70:        static const uint32 TC_E        = 0x80000000;
                     71:        static const uint32 TC_SRE      = 0x02000000;
                     72:        static const uint32 TC_FCL      = 0x01000000;
                     73: 
                     74:        // レジスタの各フィールド
1.1.1.3   root       75:        uint32 e {};            // TC_E   の位置
                     76:        uint32 sre {};          // TC_SRE の位置
                     77:        uint32 fcl {};          // TC_FCL の位置
                     78:        uint ps {};
                     79:        uint is {};
1.1       root       80:        union {
                     81:                uint tix[4] {};
                     82:                struct {
                     83:                        uint tia;
                     84:                        uint tib;
                     85:                        uint tic;
                     86:                        uint tid;
                     87:                } __packed;
                     88:        };
                     89: 
                     90:        int shift[4] {};                // TIA-TID の各部分のシフト量
                     91:        uint32 mask[4] {};              // TIA-TID の各部分のマスク
1.1.1.3   root       92:        uint32 lmask {};                // TIA-TID 全体のマスク
                     93:        uint32 pgmask {};               // PS 部分のマスク
1.1       root       94: 
                     95:  public:
                     96:        void Set(uint32);
                     97:        bool Check() const;
                     98:        void MakeMask();
                     99: };
                    100: 
                    101: class m68030MMUSR
                    102: {
                    103:  public:
                    104:        static const uint16 MASK = 0xee43;
                    105:        static const uint16 B    = 0x8000;      // バスエラー
                    106:        static const uint16 L    = 0x4000;      // リミット違反
                    107:        static const uint16 S    = 0x2000;      // スーパバイザ専用
                    108:        static const uint16 W    = 0x0800;      // 書き込み保護
                    109:        static const uint16 I    = 0x0400;      // 無効
                    110:        static const uint16 M    = 0x0200;      // 修正
                    111:        static const uint16 T    = 0x0040;      // 透過アクセス
                    112:        static const uint16 N    = 0x0007;      // レベル数
                    113: };
                    114: 
                    115: // ATC の1エントリ
                    116: struct m68030ATCLine
                    117: {
                    118:        // 1エントリはタグとデータの計64ビット。
                    119:        //
                    120:        // タグ
                    121:        //  LLLLLLLL_LLLLLLLL_LLLLLLLL_0000000I : L は論理アドレス
                    122:        //                                    +-- invalid (%1で無効)
                    123:        //
                    124:        //   FC はテーブル選択の時点で確定しているのでタグには不要。
                    125:        //
                    126:        // データ
                    127:        //  PPPPPPPP_PPPPPPPP_PPPPPPPP_0000BCPM : P は物理アドレス
                    128:        //                                 |||+-- Modified
                    129:        //                                 ||+--- Write Protect
                    130:        //                                 |+---- Cache Inhibit
                    131:        //                                 +----- Bus Error
                    132: 
                    133:        static const uint32 LADDR_MASK  = 0xffffff00;
                    134:        static const uint32 INVALID             = 0x00000001;
                    135:        static const uint32 PADDR_MASK  = 0xffffff00;
                    136:        static const uint32 BUSERROR    = 0x00000008;
                    137:        static const uint32 CINHIBIT    = 0x00000004;
                    138:        static const uint32 WPROTECT    = 0x00000002;
                    139:        static const uint32 MODIFIED    = 0x00000001;
                    140: 
                    141:        uint32 tag;
                    142: #if defined(ATC_SINGLE)
                    143:        uint32 fc;
                    144: #endif
                    145:        uint32 paddr;
                    146:        uint32 data;
                    147: 
                    148:        uint32 GetTag() const           { return tag; }
                    149: 
                    150:        void Invalidate()                       { tag |= INVALID; }
                    151:        bool   IsInvalid() const        { return tag & INVALID; }
                    152:        bool   IsValid() const          { return !IsInvalid(); }
                    153: 
                    154:        uint32 GetLAddr() const         { return tag & LADDR_MASK; }
                    155:        uint32 GetPAddr() const         { return paddr; }
                    156:        bool   IsBusError() const       { return data & BUSERROR; }
                    157:        bool   IsCInhibit() const       { return data & CINHIBIT; }
                    158:        bool   IsWProtect() const       { return data & WPROTECT; }
                    159:        bool   IsModified() const       { return data & MODIFIED; }
                    160: 
                    161: #if !defined(ATC_SINGLE)
                    162:        // LRU 用カウンタ
                    163:        uint32 age;
                    164: #else
                    165:        m68030ATCLine *prev;
                    166:        m68030ATCLine *next;
                    167: #endif
                    168: 
                    169:        // デバッグ表示
                    170:        void fill_print(uint fc);
                    171: };
                    172: 
                    173: // ATC のテーブル
1.1.1.2   root      174: class m68030ATCTable final
1.1       root      175: {
                    176:  public:
                    177:        static const int LINES = 22;
                    178: 
                    179:        m68030ATCTable();
1.1.1.2   root      180:        ~m68030ATCTable() { }
1.1       root      181: 
                    182: #if !defined(ATC_SINGLE)
                    183:        // 空きエントリを取得。
                    184:        m68030ATCLine *Lookup();
                    185:        // a をエントリの先頭に
                    186:        m68030ATCLine *MoveHead(m68030ATCLine *a);
                    187: #else
                    188:        // 空きエントリを取得。
                    189:        m68030ATCLine *lookup();
                    190:        // LRU の先頭、2番目に追加
                    191:        void insert_head(m68030ATCLine *);
                    192:        void insert_second(m68030ATCLine *);
                    193:        // LRU の先頭、2番目に移動
                    194:        void move_head(m68030ATCLine *);
                    195:        void move_second(m68030ATCLine *);
                    196:        // LRU の末尾に追加
                    197:        void insert_tail(m68030ATCLine *);
                    198:        // LRU から削除
                    199:        void remove(m68030ATCLine *);
                    200: #endif
                    201: 
                    202:        // フラッシュ
                    203:        // flush() はこのテーブルのすべてのエントリが対象。
                    204:        // flush(addr) はこのテーブルのアドレスが一致するエントリが対象。
                    205:        // flush_fc(fc) はこのテーブルの FC が fc であるエントリが対象。
                    206:        // flush(fc, addr) はこのテーブルの fc と addr が一致するエントリが対象。
                    207:        // いずれも ATC クラスから呼ばれるが、ATC_SINGLE によって、一致する FC が
                    208:        // 呼び出し前に決定されているかこちらで比較しないといけないかが変わる。
                    209:        void flush();
                    210: #if !defined(ATC_SINGLE)
                    211:        void flush(uint32 addr);
                    212: #else
                    213:        void flush_fc(uint32 fc);
                    214:        void flush(uint32 fc, uint32 addr);
                    215: #endif
                    216: 
                    217:        // ATC 実体
                    218:        m68030ATCLine line[LINES] {};
                    219: 
                    220:        // 先頭から何エントリ目でヒットしたかの統計。最後の +1 はキャッシュミス。
                    221:        uint64 hit[LINES + 1] {};
                    222: 
                    223:        // ATC_SINGLE ならリストの先頭。
                    224:        // !ATC_SINGLE なら注目エントリ。
1.1.1.3   root      225:        m68030ATCLine *head {};
1.1       root      226: 
                    227: #if !defined(ATC_SINGLE)
                    228:        // LRU 用の更新カウンタ
                    229:        uint32 counter = 0;
                    230:        // head のヒット回数。
                    231:        uint64 hit_head = 0;
                    232: #endif
                    233: };
                    234: 
                    235: // ATC (Address Translation Cache)
1.1.1.2   root      236: class m68030ATC final
1.1       root      237: {
1.1.1.4 ! root      238:        friend class MPU680x0Device;
1.1       root      239:  public:
                    240:        m68030ATC(m68kcpu *);
1.1.1.2   root      241:        ~m68030ATC() { }
1.1       root      242: 
                    243:        // エントリをサーチ&更新
                    244:        const m68030ATCLine& fill_fetch();
                    245:        const m68030ATCLine& fill_read();
                    246:        const m68030ATCLine& fill_write();
                    247:        // デバッグ用にエントリを検索
                    248:        uint64 fill_peek(uint32 laddr, uint fc);
                    249: 
                    250:        // フラッシュ (pflush* 命令から呼ばれる)
                    251:        void flush();
                    252:        void flush(uint32 fc, uint32 mask);
                    253:        void flush(uint32 fc, uint32 mask, uint32 addr);
                    254: 
                    255:  private:
                    256: #if !defined(ATC_SINGLE)
                    257:        // FC ごとのテーブル。
                    258:        // 8個確保してあるが実際に使うのはこのうち4つだけ。
                    259:        m68030ATCTable tables[8] {};
                    260: #else
                    261:        // FC 混合のテーブル。
                    262:        m68030ATCTable tables[1] {};
                    263: #endif
                    264: 
1.1.1.3   root      265:        m68kcpu *cpu {};
1.1       root      266: };
                    267: 
                    268: extern bool m68030_mmu_translate_fetch(m68kcpu *cpu);
                    269: extern bool m68030_mmu_translate_read(m68kcpu *cpu);
                    270: extern bool m68030_mmu_translate_write(m68kcpu *cpu);
                    271: extern uint64 m68030_mmu_translate_peek(m68kcpu *cpu, uint32 laddr, uint fc,
                    272:        bool do_search);
                    273: extern void mmu_op_pflush(m68kcpu *cpu);
                    274: extern void mmu_op_pflush_ea(m68kcpu *cpu);
                    275: extern void mmu_op_pload(m68kcpu *cpu);
                    276: extern void mmu_op_ptest(m68kcpu *cpu);

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.