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