|
|
1.1 root 1: //
2: // nono
3: // Copyright (C) 2020 nono project
4: // Licensed under nono-license.txt
5: //
6:
7: // MC88200(CMMU)
8:
9: #pragma once
10:
11: #include "bus.h"
1.1.1.6 root 12: #include "monitor.h"
1.1 root 13: #include <array>
14:
15: class m88kcpu;
16:
17: // SAPR, UAPR レジスタ
18: struct m88200APR
19: {
20: bool enable;
21: uint32 addr;
22: uint32 stat;
23: const char *name; // 自分の名前(ログ表示用)
24: };
25:
26: // BATC
27: struct m88200BATC
28: {
29: // LBA には S, V ビットを混ぜておく。比較を1回で済ませるため。
30: // V ビットは invalid なら %1 にして一致しなくしておく。
31: // 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
32: // +-------------------------+-------------------------+-+-------+--+
33: // | LBA | 0 |S| 0 |~V|
34: // +-------------------------+-------------------------+-+-------+--+
1.1.1.7 ! root 35: static const uint32 S = 0x00000020;
! 36: static const uint32 INVALID = 0x00000001;
! 37: uint32 lba; // LBA,S,~V
1.1 root 38: uint32 pba; // PBA
39: // stat は ACC_STAT_MASK と同じ WT,G,CI,WP のみ使用。
1.1.1.7 ! root 40: // BWP (BATC Write Port) のビット位置とは違うので注意。
1.1 root 41: uint32 stat;
42: bool wp; // WP (比較で使うのでこれだけ抜き出しておく)
1.1.1.7 ! root 43:
! 44: // このエントリが有効なら true を返す
! 45: bool IsValid() const { return (lba & INVALID) == 0; }
! 46: // S ビットが立っていれば true を返す
! 47: bool IsS() const { return (lba & S); }
1.1 root 48: };
49:
50: // PATC
51: struct m88200PATC
52: {
1.1.1.7 ! root 53: // LPA には S, V ビットを混ぜておく。比較を1回で済ませるため。
1.1 root 54: // V ビットは invalid なら %1 にして一致しなくしておく。実際の
55: // PATC エントリの有効/無効は 46ビットの PATC 構造の外で管理されている?
56: // 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
57: // +---------------------------------------+-----------+-+-------+--+
1.1.1.7 ! root 58: // | LPA | 0 |S| 0 |~V|
1.1 root 59: // +---------------------------------------+-----------+-+-------+--+
1.1.1.7 ! root 60: static const uint32 S = 0x00000020;
! 61: static const uint32 INVALID = 0x00000001;
! 62: uint32 lpa; // LPA,S,~V
1.1 root 63: uint32 pfa; // PFA
64: uint32 stat; // ACC_STAT_MASK と同じ WT,G,CI,WP のみ使用。
65: bool m; // Modified
66: bool wp; // Write Protect (比較で使うのでこれだけ抜き出しておく)
1.1.1.7 ! root 67:
! 68: // このエントリが有効なら true を返す
! 69: bool IsValid() const { return (lpa & INVALID) == 0; }
! 70: // S ビットが立っていれば true を返す
! 71: bool IsS() const { return (lpa & S); }
1.1 root 72: };
73:
74: // キャッシュの1セット
75: class m88200CacheSet
76: {
77: public:
78: enum Status {
79: EU = 0, // Exclusive Unmodified
80: EM = 1, // Exclusive Modified
81: SU = 2, // Shared Unmodified
82: IV = 3, // Invalid
83: };
84:
85: //
86: // 3 2 1
87: // 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
88: // +---------------------------------------+---------------+----+---+
89: // | tag | set |Word| |
90: // +---------------------------------------+---------------+----+---+
91:
92: // タグはアドレスの上位 20ビット。
93: // ただし無効なラインかどうかのチェックも一度で済ませるために
94: // 無効(vv[]==IV)ならビット 0 を 1 にしておく。比較対象の paddr は
95: // 下位12ビットを落としているため、これで絶対に一致しなくなる。
96: static const uint32 TAG_INVALID = 0x00000001;
1.1.1.3 root 97: uint32 tag[4] {};
1.1 root 98:
99: // LRU
100: // CSSP の L ビットのロジックに従う。
101: int L {};
102:
103: // ステータス
1.1.1.3 root 104: Status vv[4] {};
1.1 root 105:
106: // データ。word[] は以下の順
107: // Word
108: // +0 +1 +2 +3
109: // line0 [ 0] [ 1] [ 2] [ 3]
110: // line1 [ 4] [ 5] [ 6] [ 7]
111: // :
1.1.1.3 root 112: uint32 word[16] {};
1.1 root 113:
114: // 自身のセットインデックス
1.1.1.3 root 115: uint32 setidx {};
1.1 root 116:
117: // 引数 L の状態から line を最新にしたらどうなるか、を返す。
118: // 表示処理で一時変数に対して処理が必要なため static 分離してある。
119: static int TryUseLine(int L, int line);
120:
121: // 引数 L の状態から line を最古にしたらどうなるか、を返す。
122: // 対称性のため static 分離してある。
123: static int TryUnuseLine(int L, int line);
124:
125: // 引数 L の状態で、最新の line を返す。
126: // 表示処理で一時変数に対して処理が必要なため static 分離してある。
127: static int TryGetOldestLine(int L);
128:
129: void Use(int line) {
130: L = TryUseLine(L, line);
131: }
132:
133: // 更新用に最も古いラインを選んで差し出す
134: int SelectOldestLine() const;
135:
136: void Update(int line, Status status);
137:
138: void Write(int line, uint32 paddr, uint32 data, int size);
139:
140: // キャッシュを検索して、ヒットした line を返す。
141: int Lookup(uint32 tagaddr) const;
142: };
143:
144: class m88200 : public Object
145: {
1.1.1.6 root 146: using inherited = Object;
1.1 root 147: public:
148: m88200();
149: ~m88200() override;
150:
151: // 本当はコンストラクタ渡ししたかったもの
152: void Ctor(m88kcpu *parent_);
153:
154: // リセット
155: void Reset();
156:
1.1.1.6 root 157: // モニター
158: Monitor reg_monitor { this };
159: Monitor atc_monitor { this };
160: Monitor cache_monitor { this };
1.1 root 161:
162: private:
1.1.1.6 root 163: DECLARE_MONITOR_CALLBACK(MonitorUpdateReg);
164: DECLARE_MONITOR_CALLBACK(MonitorUpdateATC);
165: DECLARE_MONITOR_CALLBACK(MonitorUpdateCache);
166:
1.1.1.3 root 167: m88kcpu *parent {};
1.1 root 168:
169: public:
170: //
171: // レジスタ
172: //
173:
174: // IDR (ID Register) +$000
175: // 3 2 1
176: // 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
177: // +---------------+-----+---------+-------------------------------+
178: // | ID | Type| Version | reserved |
179: // +---------------+-----+---------+-------------------------------+
180: //
181: // ID はリセット時、下位7ビットはハードウェアで初期化、最上位ビットは
182: // 0 で初期化。その後は全ビット変更可能。
183: // Type は $5 = 88200、$6 = 88204。ここでは 88200 固定。
184: // Version は不明。
1.1.1.3 root 185: uint32 id {};
186: uint32 version {};
1.1 root 187:
188: // IDR レジスタの内容を返す
189: uint32 GetIDR() const {
190: return (id << 24) | (0x5 << 21);
191: }
192: // ID を設定する (IDR ではない)
193: void SetID(uint id_);
194: // Version フィールドを設定する
195: void SetVersion(uint version_);
196:
197: // SCR (System Command Register) +$004
198: // 3 2 1
199: // 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
200: // +---------------------------------------------------+-----------+
201: // | reserved |CommandCode|
202: // +---------------------------------------------------+-----------+
1.1.1.3 root 203: uint32 command {};
1.1 root 204: uint32 GetSCR() const;
205: void SetSCR(uint32 val);
206: private:
207: static const char * const commandname[];
208: static const uint32 GG_LINE = 0;
209: static const uint32 GG_PAGE = 1;
210: static const uint32 GG_SEG = 2;
211: static const uint32 GG_ALL = 3;
212: void FlushCache();
213: void InvalidatePATC();
214:
215: public:
216: // SSR (System Status Register) +$008
217: // 3 2 1
218: // 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
219: // +---------------------------------------------------------------+
220: // | |C|B| |W|S|G|C| |M|U|W|B|V|
221: // | reserved |E|E| res |T|P| |I|r| | |P|H| |
222: // +---------------------------------------------------------------+
223: static const uint32 SSR_CE = 0x00008000; // Copyback Error
224: static const uint32 SSR_BE = 0x00004000; // Bus Error
225: static const uint32 SSR_WT = 0x00000200; // WriteThrough
226: static const uint32 SSR_SP = 0x00000100; // Supervisor Privilege
227: static const uint32 SSR_G = 0x00000080; // Global
228: static const uint32 SSR_CI = 0x00000040; // Cache Inhibit
229: static const uint32 SSR_M = 0x00000010; // Modified
230: static const uint32 SSR_U = 0x00000008; // Used
231: static const uint32 SSR_WP = 0x00000004; // Write Protection
232: static const uint32 SSR_BH = 0x00000002; // BATC Hit
233: static const uint32 SSR_V = 0x00000001; // Valid
1.1.1.3 root 234: uint32 ssr {};
1.1 root 235: uint32 GetSSR() const { return ssr; }
236: void SetSSR(uint32 val) { ssr = val; }
237:
238: // SAR (System Address Register) +$00c
239: // 3 2 1
240: // 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
241: // +---------------------------------------------------------------+
242: // | Address |
243: // +---------------------------------------------------------------+
1.1.1.3 root 244: uint32 sar {};
1.1 root 245: uint32 GetSAR() const { return sar; }
246: void SetSAR(uint32 val) { sar = val; }
247:
248: // SCTR (System Control Register) +$104
249: // 3 2 1
250: // 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
251: // +-------------------------------+-+-+-+-------------------------+
252: // | |P|S|P| |
253: // | reserved |E|E|R| reserved |
254: // +-------------------------------+-+-+-+-------------------------+
255: static const uint32 SCTR_PE = 0x00008000; // Parity Enable
256: static const uint32 SCTR_SE = 0x00004000; // Snoop Enable
257: static const uint32 SCTR_PR = 0x00002000; // Priority Arbitration
1.1.1.3 root 258: uint32 sctr {};
1.1 root 259: uint32 GetSCTR() const { return sctr; }
260: void SetSCTR(uint32 val);
261:
262: // SAPR (Supervisor Area Pointer Register) +$200
263: // UAPR (User Area Pointer Register) +$204
264: // 3 2 1
265: // 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
266: // +---------------------------------------+---+-+-+-+-+---------+-+
267: // | Supervisor Segment Table Base Address | |W| |G|C| |T|
268: // | or User Segment Table Base Address |0 0|T|0| |I|0 0 0 0 0|E|
269: // +---------------------------------------+---+-+-+-+-+---------+-+
270: static const uint32 APR_ADDR_MASK = 0xfffff000; // Base Address
271: static const uint32 APR_WT = 0x00000200; // WriteThrough
272: static const uint32 APR_G = 0x00000080; // Global
273: static const uint32 APR_CI = 0x00000040; // Cache Inhibit
274: static const uint32 APR_TE = 0x00000001; // Translation Enable
275: m88200APR uapr {};
276: m88200APR sapr {};
277: private:
278: uint32 GetAPR(const m88200APR&) const;
279: void SetAPR(m88200APR&, uint32 data);
1.1.1.7 ! root 280: // 現在の xAPR
! 281: const m88200APR *acc_apr {};
1.1 root 282: public:
283: uint32 GetAPR(uint issuper) const;
284: uint32 GetUAPR() const { return GetAPR(uapr); }
285: uint32 GetSAPR() const { return GetAPR(sapr); }
286: void SetUAPR(uint32 data) { SetAPR(uapr, data); }
287: void SetSAPR(uint32 data) { SetAPR(sapr, data); }
288:
289: // PFSR (P Bus Fault Status Register) +$108
290: // 3 2 1
291: // 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
292: // +-------------------------+-----+-------------------------------+
293: // | |Fault| |
294: // | reserved | Code| reserved |
295: // +-------------------------+-----+-------------------------------+
296: static const uint32 FAULT_CODE_SUCCESS = 0; // Success (No fault)
297: static const uint32 FAULT_CODE_BUSERR = 3; // Bus Error
298: static const uint32 FAULT_CODE_SEGMENT = 4; // Segment Fault
299: static const uint32 FAULT_CODE_PAGE = 5; // Page Fault
300: static const uint32 FAULT_CODE_SUPERVISOR = 6; // Supervisor Violation
301: static const uint32 FAULT_CODE_WRITE = 7; // Write Violation
1.1.1.3 root 302: uint32 fault_code {};
1.1 root 303: uint32 GetPFSR() const {
304: return fault_code << 16;
305: }
306: void SetPFSR(uint32 data) {
307: fault_code = (data >> 16) & 7;
308: }
309:
310: // PFAR (P Bus Fault Address Register) +$10c
311: // 3 2 1
312: // 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
313: // +---------------------------------------------------------------+
314: // | Address |
315: // +---------------------------------------------------------------+
1.1.1.3 root 316: uint32 fault_addr {};
1.1 root 317: uint32 GetPFAR() const { return fault_addr; }
318: void SetPFAR(uint32 val) { fault_addr = val; }
319:
320: // BWP0-7 (BATC Write Ports 0..7) +$400..+$41c
321: // 3 2 1
322: // 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
323: // +---------------------------------------------------------------+
324: // | | |S|W|G|C|W|V|
325: // | Logical Block Address | Physical Block Address | |T| |I|P| |
326: // +---------------------------------------------------------------+
1.1.1.7 ! root 327: static const uint32 BWP_LBA_MASK = 0xfff80000;
! 328: static const uint32 BWP_PBA_MASK = 0x0007ffc0;
! 329: static const uint32 BWP_S = 0x00000020; // Address Space
! 330: static const uint32 BWP_WT = 0x00000010; // WriteThrough
! 331: static const uint32 BWP_G = 0x00000008; // Global
! 332: static const uint32 BWP_CI = 0x00000004; // Cache Inhibit
! 333: static const uint32 BWP_WP = 0x00000002; // Write Protect
! 334: static const uint32 BWP_V = 0x00000001; // Valid
! 335: void SetBWP(uint n, uint32 val);
1.1 root 336:
337: // CDP0-3 (Cache Data Ports 0..3) +$800..+$80c
338: // 3 2 1
339: // 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
340: // +---------------------------------------------------------------+
341: // | Data Word |
342: // +---------------------------------------------------------------+
343:
344: // CTP0-3 (Cache Tag Ports 0..3) +$840..+$84c
345: // 3 2 1
346: // 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
347: // +---------------------------------------+-----------------------+
348: // | Physical Address | reserved |
349: // +---------------------------------------+-----------------------+
350:
351: // CSSP (Cache Set Status Port) +$880
352: // 3 2 1
353: // 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
354: // +---------------------------------------------------------------+
355: // | |L|L|L|L|L|L|D|D|D|D|VV3|VV2|VV1|VV0| |
356: // |res|5|4|3|2|1|0|3|2|1|0| | | | | reserved |
357: // +---------------------------------------------------------------+
358: static const uint32 CSSP_L5 = 0x20000000; // Line5
359: static const uint32 CSSP_L4 = 0x10000000; // Line4
360: static const uint32 CSSP_L3 = 0x08000000; // Line3
361: static const uint32 CSSP_L2 = 0x04000000; // Line2
362: static const uint32 CSSP_L1 = 0x02000000; // Line1
363: static const uint32 CSSP_L0 = 0x01000000; // Line0
364: static const uint32 CSSP_D3 = 0x00800000; // Line Disable
365: static const uint32 CSSP_D2 = 0x00400000; // Line Disable
366: static const uint32 CSSP_D1 = 0x00200000; // Line Disable
367: static const uint32 CSSP_D0 = 0x00100000; // Line Disable
368: static const uint32 CSSP_VV3 = 0x000c0000; // Line Valid
369: static const uint32 CSSP_VV2 = 0x00030000; // Line Valid
370: static const uint32 CSSP_VV1 = 0x0000c000; // Line Valid
371: static const uint32 CSSP_VV0 = 0x00003000; // Line Valid
372: static const uint32 CSSP_VV3_OFFSET = 18;
373: static const uint32 CSSP_VV2_OFFSET = 16;
374: static const uint32 CSSP_VV1_OFFSET = 14;
375: static const uint32 CSSP_VV0_OFFSET = 12;
376: uint32 GetCSSP() const;
377: void SetCSSP(uint32 val);
378:
379: //
380: // 物理バスアクセス
381: //
382: // XXX size をどうするか
383: uint64 MBusRead(uint32 paddr, int size);
384: uint64 MBusWrite(uint32 paddr, uint32 data, int size);
385: uint64 MBusXmem(uint32 paddr, uint32 data, int size);
386:
387: //
388: // アクセス関数
389: //
390: private:
391: template <int bits> uint64 load(uint32 addr);
392: template <int bits> uint64 store(uint32 addr, uint32 data);
393: template <int bits> uint64 xmem(uint32 addr, uint32 data);
394: public:
395: uint64 load_8(uint32 addr);
396: uint64 load_16(uint32 addr);
397: uint64 load_32(uint32 addr);
398: uint64 store_8(uint32 addr, uint32 data);
399: uint64 store_16(uint32 addr, uint32 data);
400: uint64 store_32(uint32 addr, uint32 data);
401: uint64 xmem_8(uint32 addr, uint32 data);
402: uint64 xmem_16(uint32 addr, uint32 data);
403: uint64 xmem_32(uint32 addr, uint32 data);
404:
405: //
406: // 現在のアクセス中の状態。
407: //
408: // アドレス変換およびデータキャッシュルーチンではこれらの値を
409: // グローバルに状態変数として使う。
410:
411: // ディスクリプタの下位にあるフラグは全部ビット位置が同じ。
412: // Area descriptor (SAPR or UAPR)
413: // 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
414: // +---------------------------------------+---+-+-+-+-+---------+-+
415: // | Supervisor Segment Table Base Address | |W| |G|C| |T|
416: // | or User Segment Table Base Address |0 0|T|0| |I|0 0 0 0 0|E|
417: // +---------------------------------------+---+-+-+-+-+---------+-+
418: //
419: // Segment Descriptor
420: // 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
421: // +---------------------------------------+---+-+-+-+-+-----+-+-+-+
422: // | Page Table Base Address (PTBA) | |W|S|G|C| |W| |V|
423: // | |0 0|T|P| |I|0 0 0|P|0| |
424: // +---------------------------------------+---+-+-+-+-+-----+-+-+-+
425: //
426: // Page Descriptor
427: // 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
428: // +---------------------------------------+---+-+-+-+-+-+-+-+-+-+-+
429: // | Page Frame Address (PFA) | |W|S|G|C| |M|U|W| |V|
430: // | |0 0|T|P| |I|0| | |P|0| |
431: // +---------------------------------------+---+-+-+-+-+-+-+-+-+-+-+
432: //
433: // acc_stat も同じビット位置を使う。
434: // 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
435: // +---------------------------------------+---+-+-+-+-+-----+-+---+
436: // | | |W| |G|C| |W| |
437: // | |0 0|T|0| |I| 0 |P| 0 |
438: // +---------------------------------------+---+-+-+-+-+-----+-+---+
439: //
440: static const uint32 DESC_WT = 0x00000200; // Write Through
441: static const uint32 DESC_SP = 0x00000100; // Supervisor Protect
442: static const uint32 DESC_G = 0x00000080; // Global
443: static const uint32 DESC_CI = 0x00000040; // Cache Inhibit
444: static const uint32 DESC_M = 0x00000010; // Modified
445: static const uint32 DESC_U = 0x00000008; // Used
446: static const uint32 DESC_WP = 0x00000004; // Write Protect
447: static const uint32 DESC_V = 0x00000001; // Valid
448:
1.1.1.5 root 449: uint32 GetLaddr() const { return acc_laddr; }
450: uint32 GetPaddr() const { return acc_paddrH | acc_paddrL; }
451: private:
1.1 root 452: uint32 acc_laddr {}; // Logical Address
453: uint32 acc_paddrH {}; // Physical Address 上位30ビット。
454: // 下位2ビットは 0 固定。
455: uint32 acc_paddrL {}; // paddr の下位2ビット
456: // 上位30ビットは 0 固定。
457:
1.1.1.5 root 458: public:
1.1 root 459: // acc_stat は 4 ビットのみ使用。
460: // それ以外のビットは代入時にマスクすること。
461: static const uint32 ACC_STAT_MASK = DESC_WT | DESC_G | DESC_CI | DESC_WP;
462: uint32 acc_stat {};
463: // Table Address. とマニュアルには書いてあるけど、テーブル先頭と
464: // 紛らわしいし 88200 のアドレス変換ツリーは2段固定で、今何段目か
465: // しらんけど現在のテーブルアドレス…みたいなのを持つ必要はないので、
466: // ここでは
467: // sdaddr ... Segment Descriptor Address
468: // pdaddr ... Page Descriptor Address
469: // の2つに明確に分けて管理することにする。
470: uint32 acc_sdaddr {};
471: uint32 acc_pdaddr {};
1.1.1.3 root 472: bool acc_read {}; // True if read access
1.1 root 473: bool acc_IsWrite() const { return !acc_read; } // True if write access
474:
475: // S/U 信号線
476: // 実際には P Bus の Address フェーズで毎回送られてくるが
477: // そうそう変わらないので状態変化を通知してもらう方式。
478: // true なら super, false なら user。
1.1.1.3 root 479: bool acc_super {};
1.1.1.7 ! root 480: void SetSuper(bool super);
1.1 root 481:
482: m88200PATC *acc_patc {}; // ヒットした PATC エントリ
1.1.1.3 root 483: uint32 tmp_desc {}; // TEMP_DESCR
1.1 root 484:
485: //
486: // アドレス変換
487: //
488: bool Translate();
489: uint64 TranslatePeek(uint32 laddr, bool issuper, bool do_search) const;
490: private:
491: static std::string stat2str(uint32 stat);
492: bool SelectAreaDesc();
493: bool TableSearch();
494: bool FetchSegmentDesc();
495: bool FetchPageDesc();
496: bool UpdatePageDesc();
497:
1.1.1.7 ! root 498: // BATC
! 499: static const uint32 BATC_LBA_MASK = BWP_LBA_MASK;
! 500: static const uint32 BATC_S = m88200BATC::S;
! 501: static const uint32 BATC_INVALID = m88200BATC::INVALID;
! 502: void MakeBATCHash();
! 503: std::array<m88200BATC, 10> batc {};
! 504: // 検索用のハッシュ。値のビットN (0..9) が立っていれば batc[N] がこの
! 505: // ハッシュに当たることを示している (この後完全一致で比較する必要はある)。
! 506: // [0x00] => 0b00'0000'0000;
! 507: std::array<uint16, 16> batc_hash_s {};
! 508: std::array<uint16, 16> batc_hash_u {};
! 509: // 現在の特権状態によって batc_hash_{s,u} のいずれかを指す
! 510: uint16 *batc_hash {};
! 511: static int batc_hash_func(uint32 a) {
! 512: return (a >> 19) & 0x0f;
! 513: }
! 514:
1.1 root 515: // PATC
1.1.1.7 ! root 516: static const uint32 PATC_S = m88200PATC::S;
! 517: static const uint32 PATC_INVALID = m88200PATC::INVALID;
! 518: void CreatePATCEntry();
! 519: void InvalidatePATCHash(int);
1.1 root 520: std::array<m88200PATC, 56> patc {};
1.1.1.7 ! root 521: // 検索用のハッシュ。値のビット N (0..55) が立っていれば patc[N] がこの
! 522: // ハッシュに当たることを示している (この後完全一致で比較する必要はある)。
! 523: std::array<uint64, 256> patc_hash_s {};
! 524: std::array<uint64, 256> patc_hash_u {};
! 525: // 現在の特権状態によって patc_hash_{s,u} のいずれかを指す
! 526: uint64 *patc_hash {};
! 527: static int patc_hash_func(uint32 a) {
! 528: return (a >> 12) & 0xff;
! 529: }
! 530: // patc[] のうち空きエントリはビットを立てて示す
! 531: uint64 patc_free_map {};
! 532: // 次回追加する位置
! 533: int patc_next {};
! 534:
! 535: // 統計
! 536: uint64 translate_total {};
! 537: std::array<uint64, 10> batc_hit {};
! 538: uint64 patc_hit {};
! 539: uint64 atc_miss {};
! 540: #define M88200_STAT 1
! 541: #if defined(M88200_STAT)
! 542: // 開発用の統計
! 543: uint64 stat_patc_search {}; // ハッシュを引いた回数
! 544: uint64 stat_patc_hit {}; // ヒットした回数
! 545: uint64 stat_patc_miss1 {}; // ハッシュだけでミスした回数
! 546: uint64 stat_patc_miss2 {}; // ビットを調べてミスした回数
! 547: uint64 stat_patc_create {}; // エントリ作成回数
! 548: uint64 stat_patc_invcmd_all {}; // Invalidate ALL 発行回数
! 549: uint64 stat_patc_invcmd_seg {}; // Invalidate Segment 発行回数
! 550: uint64 stat_patc_invcmd_page {}; // Invalidate Page 発行回数
! 551: uint64 stat_patc_invalidate {}; // 無効にした PATC の総数
! 552: std::array<int, 8> stat_batc_hash_s {}; // BATC.S の衝突状況
! 553: std::array<int, 8> stat_batc_hash_u {}; // BATC.U の衝突状況
! 554: #endif
1.1 root 555:
556: //
557: // キャッシュ
558: //
1.1.1.3 root 559: private:
1.1 root 560: std::array<m88200CacheSet,256> setarray {};
1.1.1.3 root 561: // キャッシュラインにメモリから読み込む
562: uint64 ReadLine(m88200CacheSet& set, int line, uint32 tagaddr);
563: // キャッシュラインをメモリに書き出す
564: uint64 CopyBackLine(m88200CacheSet& set, int line);
1.1 root 565:
1.1.1.3 root 566: public:
1.1 root 567: // キャッシュに対して paddr の読み込みを行う
568: uint64 CacheRead(uint32 paddr);
569: // キャッシュに対して paddr への書き込みを行う
570: uint64 CacheWrite(uint32 paddr, uint32 data, int size);
571: uint64 CacheWriteHit(m88200CacheSet& set, int line,
572: uint32 paddr, uint32 data, int size);
573: uint64 CacheXmem(uint32 paddr, uint32 data, int size);
574:
575: // モニタスクリーン作成用
576: void MonitorCacheSet(TextScreen&, int y, int setidx);
577: void MonitorCacheOverview(TextScreen&, int y, int cursor, bool is_gui);
578: void MonitorCacheOverview(TextScreen& s, int y, bool is_gui) {
579: MonitorCacheOverview(s, y, -1, is_gui);
580: }
581:
1.1.1.3 root 582: //
583: // MBus
584: //
585: public:
1.1.1.7 ! root 586: // MBus を所有している CMMU を返す。誰も持っていなければ NULL。
1.1.1.3 root 587: // これは static 関数
588: static m88200 *GetBusMaster() { return mbus_master; }
589:
590: // この CMMU からのアクセスにウェイトを加算する (VM から使う)
1.1.1.4 root 591: void AddCycle(int32 cycle);
1.1.1.3 root 592:
1.1 root 593: private:
1.1.1.3 root 594: void MBusAcquire();
1.1 root 595: void MBusRelease() { }
1.1.1.7 ! root 596: // 他 CMMU にスヌープさせる (バスマスタ側)
! 597: void MBusMakeSnoop(uint32, int);
! 598: // バススヌープを行う (スレーブ側)
! 599: void Snoop(uint32, int);
1.1.1.3 root 600:
601: // MBus を所有してる CMMU を指す。NULL なら解放。
602: // これは static 変数で全 m88200 で共有している
603: static m88200 *mbus_master;
1.1.1.7 ! root 604:
! 605: // スヌープ相手の CMMU リスト
! 606: std::vector<m88200*> other_cmmu {};
1.1 root 607: };
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.