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

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