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