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

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.8 ! root        9: #include <array>
        !            10: #include <mutex>
        !            11: #include "fixedqueue.h"
1.1.1.6   root       12: 
1.1.1.8 ! root       13: class MPU680x0Device;
1.1       root       14: 
                     15: // SRP, CRP
                     16: class m68030RP
                     17: {
                     18:        //        6                   5                   4               3
                     19:        //  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
                     20:        // +-+-----------------------------+---------------------------+---+
                     21:        // |U|           LIMIT             |          unused           |DT |
                     22:        // +-+-----------------------------+---------------------------+---+
                     23:        //
                     24:        //    3                   2                   1                   0
                     25:        //  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
                     26:        // +-------------------------------------------------------+-------+
                     27:        // |           TABLE ADDRESS (PA31-PA4)                    |unused |
                     28:        // +-------------------------------------------------------+-------+
                     29:  public:
1.1.1.6   root       30:        static const uint32 DT_MASK     = 0x00000003;
1.1       root       31:        static const uint32 H_MASK      = 0xffff0003;
                     32:        static const uint32 L_MASK      = 0xfffffff0;
                     33: };
                     34: 
                     35: // TT レジスタの各フィールドを束ねた構造体のようなもの。
1.1.1.6   root       36: // MPU680x0Device::SetTT(), GetTT() で読み書きする。
1.1       root       37: class m68030TT
                     38: {
                     39:        //    3                   2                   1                   0
                     40:        //  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
                     41:        // +---------------+---------------+-+-+-+-+-+-+-+-+-+-----+-+-----+
                     42:        // |LogicalAddrBase|LogicalAddrMask|E|       |C|R|M| | FCB | | FCM |
                     43:        // +---------------+---------------+-+-+-+-+-+-+-+-+-+-----+-+-----+
                     44: 
                     45:  public:
                     46:        static const uint32 MASK                = 0xffff8777;
                     47: 
                     48:        static const uint32 LBASE_MASK  = 0xff000000;
                     49:        static const uint32 LMASK_MASK  = 0x00ff0000;
                     50:        static const uint32 E                   = 0x00008000;
                     51:        static const uint32 CI                  = 0x00000400;
                     52:        static const uint32 RW                  = 0x00000200;
                     53:        static const uint32 RWM                 = 0x00000100;
                     54:        static const uint32 FCBASE_MASK = 0x00000070;
                     55:        static const uint32 FCMASK_MASK = 0x00000007;
                     56: 
1.1.1.7   root       57:        bool e {};                              // イネーブル
                     58:        bool ci {};                             // キャッシュ禁止
1.1.1.3   root       59:        uint64 base {};                 // ベース
                     60:        uint64 mask {};                 // マスク
1.1       root       61: 
                     62:        // アクセスがこの TT と一致するか調べる。
1.1.1.7   root       63:        bool Match(busaddr addr) const;
1.1       root       64: };
                     65: 
                     66: // TC レジスタの各フィールドを束ねた構造体のようなもの。
                     67: // m68kcpu::SetTC(), GetTC() で読み書きする。
                     68: class m68030TC
                     69: {
1.1.1.7   root       70:        //    3                   2                   1                   0
                     71:        //  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
                     72:        // +-+---------+-+-+-------+-------+-------+-------+-------+-------+
                     73:        // |E|    0    |S|F|  PS   |  IS   |  TIA  |  TIB  |  TIC  |  TID  |
                     74:        // +-+---------+-+-+-------+-------+-------+-------+-------+-------+
                     75:        //  |           | +-- FCL (Function Code Lookup Enable)
                     76:        //  |           +---- SRE (Supervisor Root Pointer Enable)
                     77:        //  +-- Enable
1.1       root       78:  public:
                     79:        static const uint32 MASK        = 0x83ffffff;
                     80:        static const uint32 TC_E        = 0x80000000;
                     81:        static const uint32 TC_SRE      = 0x02000000;
                     82:        static const uint32 TC_FCL      = 0x01000000;
                     83: 
                     84:        // レジスタの各フィールド
1.1.1.3   root       85:        uint32 e {};            // TC_E   の位置
                     86:        uint32 sre {};          // TC_SRE の位置
                     87:        uint32 fcl {};          // TC_FCL の位置
                     88:        uint ps {};
                     89:        uint is {};
1.1       root       90:        union {
                     91:                uint tix[4] {};
                     92:                struct {
                     93:                        uint tia;
                     94:                        uint tib;
                     95:                        uint tic;
                     96:                        uint tid;
                     97:                } __packed;
                     98:        };
                     99: 
                    100:        int shift[4] {};                // TIA-TID の各部分のシフト量
                    101:        uint32 mask[4] {};              // TIA-TID の各部分のマスク
1.1.1.3   root      102:        uint32 lmask {};                // TIA-TID 全体のマスク
                    103:        uint32 pgmask {};               // PS 部分のマスク
1.1       root      104: 
                    105:  public:
                    106:        void Set(uint32);
                    107:        bool Check() const;
                    108:        void MakeMask();
                    109: };
                    110: 
                    111: class m68030MMUSR
                    112: {
                    113:  public:
                    114:        static const uint16 MASK = 0xee43;
                    115:        static const uint16 B    = 0x8000;      // バスエラー
                    116:        static const uint16 L    = 0x4000;      // リミット違反
                    117:        static const uint16 S    = 0x2000;      // スーパバイザ専用
                    118:        static const uint16 W    = 0x0800;      // 書き込み保護
                    119:        static const uint16 I    = 0x0400;      // 無効
                    120:        static const uint16 M    = 0x0200;      // 修正
                    121:        static const uint16 T    = 0x0040;      // 透過アクセス
                    122:        static const uint16 N    = 0x0007;      // レベル数
                    123: };
                    124: 
                    125: // ATC の1エントリ
                    126: struct m68030ATCLine
                    127: {
1.1.1.7   root      128:        // tag
1.1.1.8 ! root      129:        //  LLLLLLLL'LLLLLLLL'LLLLLLLL'0000FFFI
1.1       root      130:        //
1.1.1.8 ! root      131:        //  I は Invalid (%1で無効)
        !           132:        //  L は論理アドレス
        !           133:        //  F は busaddr 形式の FC (3ビット) だが、FC 別のテーブルなので未使用
1.1       root      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:        uint32 paddr;
                    155:        uint32 data;
1.1.1.8 ! root      156:        uint32 age;
1.1       root      157: 
                    158:        uint32 GetTag() const           { return tag; }
                    159: 
                    160:        void Invalidate()                       { tag |= INVALID; }
                    161:        bool   IsInvalid() const        { return tag & INVALID; }
                    162:        bool   IsValid() const          { return !IsInvalid(); }
                    163: 
                    164:        uint32 GetLAddr() const         { return tag & LADDR_MASK; }
                    165:        uint32 GetPAddr() const         { return paddr; }
                    166:        bool   IsBusError() const       { return data & BUSERROR; }
                    167:        bool   IsCInhibit() const       { return data & CINHIBIT; }
                    168:        bool   IsWProtect() const       { return data & WPROTECT; }
                    169:        bool   IsModified() const       { return data & MODIFIED; }
1.1.1.8 ! root      170: };
1.1       root      171: 
1.1.1.8 ! root      172: // ATC の統計情報
        !           173: struct m68030ATCStat
        !           174: {
        !           175:        uint32 total {};
        !           176:        uint32 tthit {};
        !           177:        uint32 miss {};
1.1       root      178: };
                    179: 
                    180: // ATC のテーブル
1.1.1.2   root      181: class m68030ATCTable final
1.1       root      182: {
                    183:  public:
                    184:        static const int LINES = 22;
                    185: 
1.1.1.8 ! root      186:        // ATC ハッシュ
        !           187:        enum : uint8 {
        !           188:                HASH_ATC_BASE   = 0,            // ATC #0-
        !           189:                HASH_NONE               = 0xff,         // 対応なし
        !           190:                HASH_TT                 = 0xfe,         // TT
        !           191:                HASH_SUB                = 0xfd,         // PS<4KB
        !           192:        };
1.1       root      193: 
1.1.1.8 ! root      194:        m68030ATCTable(MPU680x0Device *cpu_, uint fc_);
        !           195:        ~m68030ATCTable();
1.1       root      196: 
                    197:        // フラッシュ
1.1.1.8 ! root      198:        // Flush() はこのテーブルのすべてのエントリが対象。
        !           199:        // Flush(addr) はこのテーブルのアドレスが一致するエントリが対象。
        !           200:        void Flush();
        !           201:        void Flush(uint32 addr);
        !           202: 
        !           203:        // PS<4KB の時に ATC を検索。
        !           204:        m68030ATCLine *FindSub(const busaddr laddr);
        !           205: 
        !           206:        // テーブルサーチ。
        !           207:        // テーブルという用語がぶつかってしまったので MMU サーチと呼ぶ。
        !           208:        m68030ATCLine *MMUSearch(busaddr laddr);
        !           209: 
        !           210:        void Invalidate(m68030ATCLine *a);
        !           211:        void InvalidateSub(const m68030ATCLine *);
        !           212: 
        !           213:        void MakeHash(m68030ATCLine *);
        !           214:        void MoveHead(m68030ATCLine *);
        !           215:        m68030ATCLine *RemoveTail();
        !           216: 
        !           217:        // デバッグ表示
        !           218:        std::string LineToStr(const m68030ATCLine *a) const;
1.1       root      219: 
                    220:        // ATC 実体
                    221:        m68030ATCLine line[LINES] {};
                    222: 
1.1.1.8 ! root      223:        uint32 latest_age {};
        !           224: 
        !           225:        // このテーブルの FC
        !           226:        uint fc {};
        !           227: 
        !           228:        // PS(ページのビット長) - 12。負数なら PS<4KB
        !           229:        int ps4k {};
        !           230: 
        !           231:        // 統計
        !           232:        m68030ATCStat atcstat {};
1.1       root      233: 
1.1.1.8 ! root      234:        // 移動平均用バッファ。(こっちは排他制御が必要)
        !           235:        FixedQueue<m68030ATCStat, 3> atchist {};
        !           236:        bool atchist_tt_once_hit {};
        !           237:        std::mutex atchist_mtx {};
1.1.1.7   root      238: 
                    239:        int loglevel {};
                    240: 
                    241:        MPU680x0Device *cpu {};
1.1.1.8 ! root      242: 
        !           243:        // ATC ハッシュ (他のメンバより後ろに置く?)
        !           244:        std::array<uint8, 1024 * 1024> hash {};
1.1       root      245: };
                    246: 
                    247: // ATC (Address Translation Cache)
1.1.1.2   root      248: class m68030ATC final
1.1       root      249: {
                    250:  public:
1.1.1.8 ! root      251:        explicit m68030ATC(MPU680x0Device *);
1.1.1.6   root      252:        ~m68030ATC();
1.1       root      253: 
1.1.1.7   root      254:        // ログレベルを設定する。Object のとは同じ使い方だけど別物。
                    255:        void SetLogLevel(int loglevel_);
                    256: 
1.1       root      257:        // フラッシュ (pflush* 命令から呼ばれる)
                    258:        void flush();
                    259:        void flush(uint32 fc, uint32 mask);
                    260:        void flush(uint32 fc, uint32 mask, uint32 addr);
                    261: 
1.1.1.8 ! root      262:        // テーブルの実体。
        !           263:        std::unique_ptr<m68030ATCTable> tables[4] {};
        !           264: 
1.1       root      265:        // FC ごとのテーブル。
1.1.1.8 ! root      266:        // 実際に使うのはこのうち4つだけ。
        !           267:        std::array<m68030ATCTable *, 8> fctables {};
1.1       root      268: 
1.1.1.7   root      269:        int loglevel {};
                    270: 
1.1.1.8 ! root      271:  private:
1.1.1.6   root      272:        MPU680x0Device *cpu {};
1.1       root      273: };

unix.superglobalmegacorp.com

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