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

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

unix.superglobalmegacorp.com

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