|
|
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: // MPU (m88xx0)
8:
9: #include "mpu88xx0.h"
10: #include "config.h"
1.1.1.2 root 11: #include "sysctlr.h"
12:
13: std::unique_ptr<MPU88200ATC> gMPU88200ATC[2];
1.1 root 14:
15: // コンストラクタ
1.1.1.7 ! root 16: MPU88xx0Device::MPU88xx0Device()
1.1 root 17: {
1.1.1.3 root 18: monitor_size = nnSize(79, 18);
1.1 root 19:
1.1.1.7 ! root 20: cpu.reset(new m88kcpu());
1.1.1.4 root 21:
1.1.1.2 root 22: // LUNA88K では CMMU の ID は次のように割り振ってあるようだ。
23: // OpenBSD の sys/arch/luna68k/include/board.h より。
24: //
25: // Inst Data
26: // CPU#0 ID=7 ID=6
27: // CPU#1 ID=5 ID=4
28: // CPU#2 ID=3 ID=2
29: // CPU#3 ID=1 ID=0
30: //
31: // 厳密にはこれは LUNA88K のハードウェアがどういうコンフィグレーションで
32: // m88200 を使うかなので、ここではなくて vm_luna あたりのほうがいいかも
33: // しれんけど、あまり遠いのも面倒なので、とりあえずこの辺に。
34: // あとマルチプロセッサになったらまたその時考える。
35: cpu->cmmu[0].SetID(7);
36: cpu->cmmu[1].SetID(6);
37:
38: // モニタ用の別オブジェクト
39: gMPU88200ATC[0].reset(new MPU88200ATC(&cpu->cmmu[0]));
40: gMPU88200ATC[1].reset(new MPU88200ATC(&cpu->cmmu[1]));
1.1 root 41: }
42:
43: // デストラクタ
44: MPU88xx0Device::~MPU88xx0Device()
45: {
46: }
47:
1.1.1.5 root 48: bool
49: MPU88xx0Device::Init()
50: {
51: // 親クラス
52: if (inherited::Init() == false) {
53: return false;
54: }
55: // MPU クロックは親 Init() で読み込んで、ここで cpu にセットする
56: cpu->SetClockSpeed(clock_khz);
57:
58: return true;
59: }
60:
1.1.1.7 ! root 61: bool
! 62: MPU88xx0Device::PowerOn()
! 63: {
! 64: cpu->PowerOn();
! 65: return true;
! 66: }
! 67:
1.1 root 68: void
1.1.1.7 ! root 69: MPU88xx0Device::ResetHard()
1.1 root 70: {
1.1.1.5 root 71: cpu->RequestReset();
1.1 root 72: }
73:
1.1.1.6 root 74: // アクセス中の論理アドレスを取得
75: uint32
76: MPU88xx0Device::GetLaddr() const
77: {
78: m88200 *cmmu = m88200::GetBusMaster();
79: assert(cmmu);
80: return cmmu->GetLaddr();
81: }
82:
83: // アクセス中の物理アドレスを取得
84: uint32
85: MPU88xx0Device::GetPaddr() const
86: {
87: m88200 *cmmu = m88200::GetBusMaster();
88: assert(cmmu);
89: return cmmu->GetPaddr();
90: }
91:
1.1.1.4 root 92: // アクセスウェイトを加算
93: void
1.1.1.5 root 94: MPU88xx0Device::AddCycle(int32 cycle)
1.1.1.4 root 95: {
96: // 今アクセスしてきている(= バスマスターの) CMMU に対して加算する
97: m88200 *cmmu = m88200::GetBusMaster();
98: assert(cmmu);
99: cmmu->AddCycle(cycle);
100: }
101:
1.1.1.2 root 102: // Interrupt
103: void
1.1.1.5 root 104: MPU88xx0Device::Interrupt(int level)
1.1.1.2 root 105: {
1.1.1.5 root 106: cpu->Interrupt(level);
1.1.1.2 root 107: }
108:
1.1 root 109: // モニター更新
1.1.1.3 root 110: void
111: MPU88xx0Device::MonitorUpdate(TextScreen& monitor)
1.1 root 112: {
113: m88100reg reg;
114: int x;
115: int y;
116:
117: monitor.Clear();
118:
119: // ローカルにコピー
120: reg = *cpu;
121:
122: //
123: for (int i = 0; i < countof(reg.r); i++) {
124: monitor.Print((i / 8) * 14, i % 8, "r%-2d:%08x", i, reg.r[i]);
125: }
126:
127: // 制御レジスタ
128: x = 0;
129: y = 9;
1.1.1.2 root 130: monitor.Print(x, y++, "pid (cr0):%08x(Arch=$%02x Ver=$%02x MC=%s)",
1.1 root 131: reg.pid,
132: (reg.pid >> 8) & 0xff,
1.1.1.2 root 133: (reg.pid >> 1) & 0x7f,
134: (reg.pid & 1) ? "Master" : "Checker");
135: monitor.Print(x, y, "psr (cr1):%08x(", reg.psr);
136: monitor.Puts(x + 19, y, TA::OnOff(reg.psr & m88100reg::PSR_SUPER), "S");
137: monitor.Puts(x + 21, y,
138: ((reg.psr & m88100reg::PSR_BO_LE) ? "BO=LE" : "BO=BE"));
139: monitor.Puts(x + 27, y, TA::OnOff(reg.psr & m88100reg::PSR_SER), "SER");
140: monitor.Puts(x + 31, y, TA::OnOff(reg.psr & m88100reg::PSR_C), "Cy");
141: monitor.Puts(x + 34, y, TA::OnOff(reg.psr & m88100reg::PSR_SFD1), "SFD1");
142: monitor.Puts(x + 39, y, TA::OnOff(reg.psr & m88100reg::PSR_MXM), "MXM");
143: monitor.Puts(x + 43, y, TA::OnOff(reg.psr & m88100reg::PSR_IND), "IND");
144: monitor.Puts(x + 47, y, TA::OnOff(reg.psr & m88100reg::PSR_SFRZ), "SFRZ");
145: monitor.Puts(x + 51, y, ")");
146: y++;
147: monitor.Print(x, y, "epsr(cr2):%08x(", reg.epsr);
148: monitor.Puts(x + 19, y, TA::OnOff(reg.epsr & m88100reg::PSR_SUPER), "S");
149: monitor.Puts(x + 21, y,
150: ((reg.epsr& m88100reg::PSR_BO_LE) ? "BO=LE" : "BO=BE"));
151: monitor.Puts(x + 27, y, TA::OnOff(reg.epsr & m88100reg::PSR_SER), "SER");
152: monitor.Puts(x + 31, y, TA::OnOff(reg.epsr & m88100reg::PSR_C), "Cy");
153: monitor.Puts(x + 34, y, TA::OnOff(reg.epsr & m88100reg::PSR_SFD1), "SFD1");
154: monitor.Puts(x + 39, y, TA::OnOff(reg.epsr & m88100reg::PSR_MXM), "MXM");
155: monitor.Puts(x + 43, y, TA::OnOff(reg.epsr & m88100reg::PSR_IND), "IND");
156: monitor.Puts(x + 47, y, TA::OnOff(reg.epsr & m88100reg::PSR_SFRZ), "SFRZ");
157: monitor.Puts(x + 51, y, ")");
1.1 root 158:
1.1.1.2 root 159: // 制御レジスタ(左中; *IP)
1.1 root 160: x = 0;
161: y = 12;
162: monitor.Print(x, y + 0, "xip:%08x opX:%08x(%c%c)",
163: reg.xip, (uint32)reg.opX,
164: cpu->OpIsBusErr(reg.opX) ? 'B' : '-',
165: cpu->OpIsDelay(reg.opX) ? 'D' : '-');
166: monitor.Print(x, y + 1, "nip:%08x opF:%08x(%c%c)",
167: reg.nip, (uint32)reg.opF,
168: cpu->OpIsBusErr(reg.opF) ? 'B' : '-',
169: cpu->OpIsDelay(reg.opF) ? 'D' : '-');
170: monitor.Print(x, y + 2, "fip:%08x", reg.fip);
171:
172: // 制御レジスタ (S*IP)
173: x = 32;
174: for (int i = 0; i < 3; i++) {
175: monitor.Print(x, y + i, "%s(cr%d):%08x:%c%c",
176: m88100reg::sipname[i], 4 + i,
177: (reg.cr[4 + i] & m88100reg::SIP_MASK),
178: (reg.cr[4 + i] & m88100reg::SIP_V) ? 'V' : '-',
179: (reg.cr[4 + i] & m88100reg::SIP_E) ? 'E' : '-');
180: }
181:
1.1.1.2 root 182: // 制御レジスタ(右中)
1.1 root 183: x = 55;
184: y = 9;
185: for (int i = 0; i < 4; i++) {
186: int rn = 17 + i;
1.1.1.4 root 187: monitor.Print(x, y++, "sr%d(cr%d):%08x", i, rn, reg.cr[rn]);
1.1 root 188: }
1.1.1.4 root 189: monitor.Print(x, y++, "ssbr(cr3):%08x", reg.ssbr);
190: monitor.Print(x, y++, "vbr (cr7):%08x", reg.vbr);
1.1 root 191:
1.1.1.2 root 192: // MMU レジスタ(下段)
193: y = 15;
194: for (int i = 0; i <= 2; i++) {
195: int dt = 8 + i * 3;
196: int dd = 9 + i * 3;
197: int da = 10 + i * 3;
198:
199: monitor.Print(0, y, "dmt%d(cr%-2d):%04x",
200: i, dt, (reg.cr[dt] & 0xffff));
201: monitor.Puts(15, y, "(b,s,d,l,rx, s,en ,w,v)");
202: monitor.Puts(16, y, (reg.cr[dt] & m88100reg::DM_BO) ? "B" : "-");
203: monitor.Puts(18, y, (reg.cr[dt] & m88100reg::DM_DAS) ? "S" : "U");
204: monitor.Puts(20, y, (reg.cr[dt] & m88100reg::DM_DOUB1) ? "D" : "-");
205: monitor.Puts(22, y, (reg.cr[dt] & m88100reg::DM_LOCK) ? "L" : "-");
206: // カンマが自然に見えるようにここだけカンマも含めて前詰めで出力
207: monitor.Print(25, y, "%d,",
208: (reg.cr[dt] & m88100reg::DM_DREG_MASK) >> 7);
209: monitor.Puts(28, y, (reg.cr[dt] & m88100reg::DM_SIGNED) ? "S" : "-");
210: uint32 en = (reg.cr[dt] & m88100reg::DM_EN_MASK) >> 2;
211: monitor.Puts(30, y, m88100reg::dmt_en_str[en]);
212: monitor.Puts(35, y, (reg.cr[dt] & m88100reg::DM_WRITE) ? "W" : "-");
213: monitor.Puts(37, y, (reg.cr[dt] & m88100reg::DM_VALID) ? "V" : "-");
214:
215: monitor.Print(40, y, "dmd%d(cr%-2d):%08x", i, dd, reg.cr[dd]);
216: monitor.Print(60, y, "dma%d(cr%2d):%08x", i, da, reg.cr[da]);
217: y++;
218: }
219: }
220:
221: //
222: // {B,P}ATC モニタ
223: //
224:
225: // コンストラクタ
226: MPU88200ATC::MPU88200ATC(m88200 *cmmu_)
227: {
228: cmmu = cmmu_;
229:
1.1.1.3 root 230: monitor_size = nnSize(65, 38);
1.1.1.2 root 231: }
232:
1.1.1.3 root 233: void
234: MPU88200ATC::MonitorUpdate(TextScreen& monitor)
1.1.1.2 root 235: {
236: int x;
237: int y;
238:
239: monitor.Clear();
240:
241: monitor.Print(0, 0, "SAPR %05x'000 TE=%d %c%c%c",
242: (cmmu->sapr.addr >> 12) & 0xfffff,
243: cmmu->sapr.enable ? 1 : 0,
244: (cmmu->sapr.stat & m88200::APR_WT) ? 'T' : '-',
245: (cmmu->sapr.stat & m88200::APR_G) ? 'G' : '-',
246: (cmmu->sapr.stat & m88200::APR_CI) ? 'C' : '-');
247:
248: monitor.Print(34, 0, "UAPR %05x'000 TE=%d %c%c%c",
249: (cmmu->uapr.addr >> 12) & 0xfffff,
250: cmmu->uapr.enable ? 1 : 0,
251: (cmmu->uapr.stat & m88200::APR_WT) ? 'T' : '-',
252: (cmmu->uapr.stat & m88200::APR_G) ? 'G' : '-',
253: (cmmu->uapr.stat & m88200::APR_CI) ? 'C' : '-');
254:
255: monitor.Puts(0, 1, "<BATC>");
256: monitor.Puts(0, 2, "No. LBA PBA Stat");
257: monitor.Puts(34, 2, "No. LBA PBA Stat");
258: x = 0;
259: y = 3;
260: for (int i = 0; i < 10; i++) {
261: m88200BATC& b = cmmu->batc[i];
262:
263: if (i == cmmu->batc.size() / 2) {
264: x = 34;
265: y = 3;
266: }
267: if (i < 8) {
268: monitor.Print(x, y, " %d:", i);
269: } else {
270: monitor.Print(x, y, "(%d)", i);
271: }
272: if ((b.lba & 1) == 0) {
273: monitor.Print(x + 4, y, "%c:%04x'0000 %04x'0000 %c%c%c%c",
274: (b.lba & m88200::BATC_S) ? 'S' : 'U',
275: b.lba >> 16, b.pba >> 16,
276: (b.stat & m88200::DESC_WT) ? 'T' : '-',
277: (b.stat & m88200::DESC_G) ? 'G' : '-',
278: (b.stat & m88200::DESC_CI) ? 'C' : '-',
279: (b.stat & m88200::DESC_WP) ? 'P' : '-');
280: }
281: y++;
282: }
283:
284: monitor.Puts(0, 8, "<PATC>");
285: monitor.Puts(0, 9, "No. LPA PFA Stat");
286: monitor.Puts(34, 9, "No. LPA PFA Stat");
287:
288: x = 0;
289: y = 10;
290: for (int i = 0; i < cmmu->patc.size(); i++) {
291: m88200PATC& p = cmmu->patc[i];
292:
293: if (i == cmmu->patc.size() / 2) {
294: x = 34;
295: y = 10;
296: }
297:
298: monitor.Print(x, y, "%2d:", i);
299: if ((p.lpa & 1) == 0) {
300: monitor.Print(x + 4, y, "%c:%05x'000 %05x'000 %c%c%c%c%c",
301: (p.lpa & m88200::PATC_S) ? 'S' : 'U',
302: p.lpa >> 12, p.pfa >> 12,
303: (p.stat & m88200::DESC_WT) ? 'T' : '-',
304: (p.stat & m88200::DESC_G) ? 'G' : '-',
305: (p.stat & m88200::DESC_CI) ? 'C' : '-',
306: (p.stat & m88200::DESC_WP) ? 'P' : '-',
307: p.m ? 'M' : '-');
308: }
309:
310: y++;
311: }
1.1 root 312: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.