--- nono/vm/mpu88xx0.cpp 2026/04/29 17:04:42 1.1.1.4 +++ nono/vm/mpu88xx0.cpp 2026/04/29 17:04:55 1.1.1.8 @@ -10,21 +10,12 @@ #include "config.h" #include "sysctlr.h" -std::unique_ptr gMPU88200ATC[2]; - // コンストラクタ -MPU88xx0Device::MPU88xx0Device(uint32 addr) +MPU88xx0Device::MPU88xx0Device() + : inherited("MPU(88xx0)") { - monitor_size = nnSize(79, 18); - - // リセットベクタアドレスは Reset() で指定するので保持しておく - reset_vector = addr; - cpu.reset(new m88kcpu()); - // リセット例外イベントコールバック設定 - reset_event.func = (DeviceCallback_t)&MPU88xx0Device::ResetCallback; - // LUNA88K では CMMU の ID は次のように割り振ってあるようだ。 // OpenBSD の sys/arch/luna68k/include/board.h より。 // @@ -41,9 +32,10 @@ MPU88xx0Device::MPU88xx0Device(uint32 ad cpu->cmmu[0].SetID(7); cpu->cmmu[1].SetID(6); - // モニタ用の別オブジェクト - gMPU88200ATC[0].reset(new MPU88200ATC(&cpu->cmmu[0])); - gMPU88200ATC[1].reset(new MPU88200ATC(&cpu->cmmu[1])); + // レジスタモニター + monitor.func = (MonitorCallback_t)&MPU88xx0Device::MonitorUpdate; + monitor.SetSize(79, 18); + monitor.Regist(ID_MONITOR_MPUREG); } // デストラクタ @@ -51,16 +43,56 @@ MPU88xx0Device::~MPU88xx0Device() { } -// リセット例外イベントコールバック +bool +MPU88xx0Device::Init() +{ + // 親クラス + if (inherited::Init() == false) { + return false; + } + // MPU クロックは親 Init() で読み込んで、ここで cpu にセットする + cpu->SetClockSpeed(clock_khz); + + const ConfigItem& item = gConfig->Find("mpu-pseudo-stop"); + cpu->pseudo_stop_enable = (bool)item.AsInt(); + + return true; +} + +bool +MPU88xx0Device::PowerOn() +{ + cpu->PowerOn(); + return true; +} + void -MPU88xx0Device::ResetCallback(Event& ev) +MPU88xx0Device::ResetHard() +{ + cpu->RequestReset(); +} + +// アクセス中の論理アドレスを取得 +uint32 +MPU88xx0Device::GetLaddr() const +{ + m88200 *cmmu = m88200::GetBusMaster(); + assert(cmmu); + return cmmu->GetLaddr(); +} + +// アクセス中の物理アドレスを取得 +uint32 +MPU88xx0Device::GetPaddr() const { - cpu->Reset(reset_vector); + m88200 *cmmu = m88200::GetBusMaster(); + assert(cmmu); + return cmmu->GetPaddr(); } // アクセスウェイトを加算 void -MPU88xx0Device::AddCycle(uint64 cycle) +MPU88xx0Device::AddCycle(int32 cycle) { // 今アクセスしてきている(= バスマスターの) CMMU に対して加算する m88200 *cmmu = m88200::GetBusMaster(); @@ -70,84 +102,78 @@ MPU88xx0Device::AddCycle(uint64 cycle) // Interrupt void -MPU88xx0Device::Interrupt(Object *src, int level) +MPU88xx0Device::Interrupt(int level) { - // XXX: なぜか 1 レベルずれている? - level++; - if (gSysCtlr->GetIntMask(0) & (1 << level)) { - putlog(1, "Interrupt from %s", src->devname.c_str()); - gSysCtlr->TellIntLevel(0, 1 << level); - cpu->Interrupt(); - } + cpu->Interrupt(level); } // モニター更新 void -MPU88xx0Device::MonitorUpdate(TextScreen& monitor) +MPU88xx0Device::MonitorUpdate(Monitor *, TextScreen& screen) { m88100reg reg; int x; int y; - monitor.Clear(); + screen.Clear(); // ローカルにコピー reg = *cpu; // for (int i = 0; i < countof(reg.r); i++) { - monitor.Print((i / 8) * 14, i % 8, "r%-2d:%08x", i, reg.r[i]); + screen.Print((i / 8) * 14, i % 8, "r%-2d:%08x", i, reg.r[i]); } // 制御レジスタ x = 0; y = 9; - monitor.Print(x, y++, "pid (cr0):%08x(Arch=$%02x Ver=$%02x MC=%s)", + screen.Print(x, y++, "pid (cr0):%08x(Arch=$%02x Ver=$%02x MC=%s)", reg.pid, (reg.pid >> 8) & 0xff, (reg.pid >> 1) & 0x7f, (reg.pid & 1) ? "Master" : "Checker"); - monitor.Print(x, y, "psr (cr1):%08x(", reg.psr); - monitor.Puts(x + 19, y, TA::OnOff(reg.psr & m88100reg::PSR_SUPER), "S"); - monitor.Puts(x + 21, y, + screen.Print(x, y, "psr (cr1):%08x(", reg.psr); + screen.Puts(x + 19, y, TA::OnOff(reg.psr & m88100reg::PSR_SUPER), "S"); + screen.Puts(x + 21, y, ((reg.psr & m88100reg::PSR_BO_LE) ? "BO=LE" : "BO=BE")); - monitor.Puts(x + 27, y, TA::OnOff(reg.psr & m88100reg::PSR_SER), "SER"); - monitor.Puts(x + 31, y, TA::OnOff(reg.psr & m88100reg::PSR_C), "Cy"); - monitor.Puts(x + 34, y, TA::OnOff(reg.psr & m88100reg::PSR_SFD1), "SFD1"); - monitor.Puts(x + 39, y, TA::OnOff(reg.psr & m88100reg::PSR_MXM), "MXM"); - monitor.Puts(x + 43, y, TA::OnOff(reg.psr & m88100reg::PSR_IND), "IND"); - monitor.Puts(x + 47, y, TA::OnOff(reg.psr & m88100reg::PSR_SFRZ), "SFRZ"); - monitor.Puts(x + 51, y, ")"); + screen.Puts(x + 27, y, TA::OnOff(reg.psr & m88100reg::PSR_SER), "SER"); + screen.Puts(x + 31, y, TA::OnOff(reg.psr & m88100reg::PSR_C), "Cy"); + screen.Puts(x + 34, y, TA::OnOff(reg.psr & m88100reg::PSR_SFD1), "SFD1"); + screen.Puts(x + 39, y, TA::OnOff(reg.psr & m88100reg::PSR_MXM), "MXM"); + screen.Puts(x + 43, y, TA::OnOff(reg.psr & m88100reg::PSR_IND), "IND"); + screen.Puts(x + 47, y, TA::OnOff(reg.psr & m88100reg::PSR_SFRZ), "SFRZ"); + screen.Puts(x + 51, y, ")"); y++; - monitor.Print(x, y, "epsr(cr2):%08x(", reg.epsr); - monitor.Puts(x + 19, y, TA::OnOff(reg.epsr & m88100reg::PSR_SUPER), "S"); - monitor.Puts(x + 21, y, + screen.Print(x, y, "epsr(cr2):%08x(", reg.epsr); + screen.Puts(x + 19, y, TA::OnOff(reg.epsr & m88100reg::PSR_SUPER), "S"); + screen.Puts(x + 21, y, ((reg.epsr& m88100reg::PSR_BO_LE) ? "BO=LE" : "BO=BE")); - monitor.Puts(x + 27, y, TA::OnOff(reg.epsr & m88100reg::PSR_SER), "SER"); - monitor.Puts(x + 31, y, TA::OnOff(reg.epsr & m88100reg::PSR_C), "Cy"); - monitor.Puts(x + 34, y, TA::OnOff(reg.epsr & m88100reg::PSR_SFD1), "SFD1"); - monitor.Puts(x + 39, y, TA::OnOff(reg.epsr & m88100reg::PSR_MXM), "MXM"); - monitor.Puts(x + 43, y, TA::OnOff(reg.epsr & m88100reg::PSR_IND), "IND"); - monitor.Puts(x + 47, y, TA::OnOff(reg.epsr & m88100reg::PSR_SFRZ), "SFRZ"); - monitor.Puts(x + 51, y, ")"); + screen.Puts(x + 27, y, TA::OnOff(reg.epsr & m88100reg::PSR_SER), "SER"); + screen.Puts(x + 31, y, TA::OnOff(reg.epsr & m88100reg::PSR_C), "Cy"); + screen.Puts(x + 34, y, TA::OnOff(reg.epsr & m88100reg::PSR_SFD1), "SFD1"); + screen.Puts(x + 39, y, TA::OnOff(reg.epsr & m88100reg::PSR_MXM), "MXM"); + screen.Puts(x + 43, y, TA::OnOff(reg.epsr & m88100reg::PSR_IND), "IND"); + screen.Puts(x + 47, y, TA::OnOff(reg.epsr & m88100reg::PSR_SFRZ), "SFRZ"); + screen.Puts(x + 51, y, ")"); // 制御レジスタ(左中; *IP) x = 0; y = 12; - monitor.Print(x, y + 0, "xip:%08x opX:%08x(%c%c)", + screen.Print(x, y + 0, "xip:%08x opX:%08x(%c%c)", reg.xip, (uint32)reg.opX, cpu->OpIsBusErr(reg.opX) ? 'B' : '-', cpu->OpIsDelay(reg.opX) ? 'D' : '-'); - monitor.Print(x, y + 1, "nip:%08x opF:%08x(%c%c)", + screen.Print(x, y + 1, "nip:%08x opF:%08x(%c%c)", reg.nip, (uint32)reg.opF, cpu->OpIsBusErr(reg.opF) ? 'B' : '-', cpu->OpIsDelay(reg.opF) ? 'D' : '-'); - monitor.Print(x, y + 2, "fip:%08x", reg.fip); + screen.Print(x, y + 2, "fip:%08x", reg.fip); // 制御レジスタ (S*IP) x = 32; for (int i = 0; i < 3; i++) { - monitor.Print(x, y + i, "%s(cr%d):%08x:%c%c", + screen.Print(x, y + i, "%s(cr%d):%08x:%c%c", m88100reg::sipname[i], 4 + i, (reg.cr[4 + i] & m88100reg::SIP_MASK), (reg.cr[4 + i] & m88100reg::SIP_V) ? 'V' : '-', @@ -159,130 +185,36 @@ MPU88xx0Device::MonitorUpdate(TextScreen y = 9; for (int i = 0; i < 4; i++) { int rn = 17 + i; - monitor.Print(x, y++, "sr%d(cr%d):%08x", i, rn, reg.cr[rn]); + screen.Print(x, y++, "sr%d(cr%d):%08x", i, rn, reg.cr[rn]); } - monitor.Print(x, y++, "ssbr(cr3):%08x", reg.ssbr); - monitor.Print(x, y++, "vbr (cr7):%08x", reg.vbr); + screen.Print(x, y++, "ssbr(cr3):%08x", reg.ssbr); + screen.Print(x, y++, "vbr (cr7):%08x", reg.vbr); // MMU レジスタ(下段) - x = 0; y = 15; for (int i = 0; i <= 2; i++) { int dt = 8 + i * 3; int dd = 9 + i * 3; int da = 10 + i * 3; - monitor.Print(0, y, "dmt%d(cr%-2d):%04x", + screen.Print(0, y, "dmt%d(cr%-2d):%04x", i, dt, (reg.cr[dt] & 0xffff)); - monitor.Puts(15, y, "(b,s,d,l,rx, s,en ,w,v)"); - monitor.Puts(16, y, (reg.cr[dt] & m88100reg::DM_BO) ? "B" : "-"); - monitor.Puts(18, y, (reg.cr[dt] & m88100reg::DM_DAS) ? "S" : "U"); - monitor.Puts(20, y, (reg.cr[dt] & m88100reg::DM_DOUB1) ? "D" : "-"); - monitor.Puts(22, y, (reg.cr[dt] & m88100reg::DM_LOCK) ? "L" : "-"); + screen.Puts(15, y, "(b,s,d,l,rx, s,en ,w,v)"); + screen.Puts(16, y, (reg.cr[dt] & m88100reg::DM_BO) ? "B" : "-"); + screen.Puts(18, y, (reg.cr[dt] & m88100reg::DM_DAS) ? "S" : "U"); + screen.Puts(20, y, (reg.cr[dt] & m88100reg::DM_DOUB1) ? "D" : "-"); + screen.Puts(22, y, (reg.cr[dt] & m88100reg::DM_LOCK) ? "L" : "-"); // カンマが自然に見えるようにここだけカンマも含めて前詰めで出力 - monitor.Print(25, y, "%d,", + screen.Print(25, y, "%d,", (reg.cr[dt] & m88100reg::DM_DREG_MASK) >> 7); - monitor.Puts(28, y, (reg.cr[dt] & m88100reg::DM_SIGNED) ? "S" : "-"); + screen.Puts(28, y, (reg.cr[dt] & m88100reg::DM_SIGNED) ? "S" : "-"); uint32 en = (reg.cr[dt] & m88100reg::DM_EN_MASK) >> 2; - monitor.Puts(30, y, m88100reg::dmt_en_str[en]); - monitor.Puts(35, y, (reg.cr[dt] & m88100reg::DM_WRITE) ? "W" : "-"); - monitor.Puts(37, y, (reg.cr[dt] & m88100reg::DM_VALID) ? "V" : "-"); - - monitor.Print(40, y, "dmd%d(cr%-2d):%08x", i, dd, reg.cr[dd]); - monitor.Print(60, y, "dma%d(cr%2d):%08x", i, da, reg.cr[da]); - y++; - } -} - -// -// {B,P}ATC モニタ -// - -// コンストラクタ -MPU88200ATC::MPU88200ATC(m88200 *cmmu_) -{ - cmmu = cmmu_; - - monitor_size = nnSize(65, 38); -} - -void -MPU88200ATC::MonitorUpdate(TextScreen& monitor) -{ - int x; - int y; - - monitor.Clear(); - - monitor.Print(0, 0, "SAPR %05x'000 TE=%d %c%c%c", - (cmmu->sapr.addr >> 12) & 0xfffff, - cmmu->sapr.enable ? 1 : 0, - (cmmu->sapr.stat & m88200::APR_WT) ? 'T' : '-', - (cmmu->sapr.stat & m88200::APR_G) ? 'G' : '-', - (cmmu->sapr.stat & m88200::APR_CI) ? 'C' : '-'); - - monitor.Print(34, 0, "UAPR %05x'000 TE=%d %c%c%c", - (cmmu->uapr.addr >> 12) & 0xfffff, - cmmu->uapr.enable ? 1 : 0, - (cmmu->uapr.stat & m88200::APR_WT) ? 'T' : '-', - (cmmu->uapr.stat & m88200::APR_G) ? 'G' : '-', - (cmmu->uapr.stat & m88200::APR_CI) ? 'C' : '-'); - - monitor.Puts(0, 1, ""); - monitor.Puts(0, 2, "No. LBA PBA Stat"); - monitor.Puts(34, 2, "No. LBA PBA Stat"); - x = 0; - y = 3; - for (int i = 0; i < 10; i++) { - m88200BATC& b = cmmu->batc[i]; - - if (i == cmmu->batc.size() / 2) { - x = 34; - y = 3; - } - if (i < 8) { - monitor.Print(x, y, " %d:", i); - } else { - monitor.Print(x, y, "(%d)", i); - } - if ((b.lba & 1) == 0) { - monitor.Print(x + 4, y, "%c:%04x'0000 %04x'0000 %c%c%c%c", - (b.lba & m88200::BATC_S) ? 'S' : 'U', - b.lba >> 16, b.pba >> 16, - (b.stat & m88200::DESC_WT) ? 'T' : '-', - (b.stat & m88200::DESC_G) ? 'G' : '-', - (b.stat & m88200::DESC_CI) ? 'C' : '-', - (b.stat & m88200::DESC_WP) ? 'P' : '-'); - } - y++; - } - - monitor.Puts(0, 8, ""); - monitor.Puts(0, 9, "No. LPA PFA Stat"); - monitor.Puts(34, 9, "No. LPA PFA Stat"); - - x = 0; - y = 10; - for (int i = 0; i < cmmu->patc.size(); i++) { - m88200PATC& p = cmmu->patc[i]; - - if (i == cmmu->patc.size() / 2) { - x = 34; - y = 10; - } - - monitor.Print(x, y, "%2d:", i); - if ((p.lpa & 1) == 0) { - monitor.Print(x + 4, y, "%c:%05x'000 %05x'000 %c%c%c%c%c", - (p.lpa & m88200::PATC_S) ? 'S' : 'U', - p.lpa >> 12, p.pfa >> 12, - (p.stat & m88200::DESC_WT) ? 'T' : '-', - (p.stat & m88200::DESC_G) ? 'G' : '-', - (p.stat & m88200::DESC_CI) ? 'C' : '-', - (p.stat & m88200::DESC_WP) ? 'P' : '-', - p.m ? 'M' : '-'); - } + screen.Puts(30, y, m88100reg::dmt_en_str[en]); + screen.Puts(35, y, (reg.cr[dt] & m88100reg::DM_WRITE) ? "W" : "-"); + screen.Puts(37, y, (reg.cr[dt] & m88100reg::DM_VALID) ? "V" : "-"); + screen.Print(40, y, "dmd%d(cr%-2d):%08x", i, dd, reg.cr[dd]); + screen.Print(60, y, "dma%d(cr%2d):%08x", i, da, reg.cr[da]); y++; } }