|
|
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: };
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.