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

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

unix.superglobalmegacorp.com

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