--- nono/vm/qemusysctlr.cpp 2026/04/29 17:05:24 1.1 +++ nono/vm/qemusysctlr.cpp 2026/04/29 17:06:00 1.1.1.3 @@ -11,7 +11,9 @@ // https://www.qemu.org/docs/master/specs/virt-ctlr.html #include "qemusysctlr.h" +#include "mainbus.h" #include "power.h" +#include "syncer.h" // コンストラクタ QemuSysCtlrDevice::QemuSysCtlrDevice() @@ -25,28 +27,30 @@ QemuSysCtlrDevice::~QemuSysCtlrDevice() } busdata -QemuSysCtlrDevice::Read32(uint32 addr) +QemuSysCtlrDevice::ReadPort(uint32 offset) { - uint32 offset = addr & 0xff; + busdata data; if (offset == 0) { // Features (Read Only) - uint32 data = FEATURES; - putlog(2, "FEATURES -> $%08x", data); - return data; + data = FEATURES; + putlog(2, "FEATURES -> $%08x", data.Data()); } else { // 他のポートがどうなるのかは仕様に書いてない。 - putlog(1, "Read32 $%08x (BusErr)", addr); - return busdata::BusErr; + data.SetBusErr(); + putlog(1, "Read $%08x (BusErr)", GetMainbusDevice()->GetPaddr()); } + + data |= BusData::Size4; + return data; } busdata -QemuSysCtlrDevice::Write32(uint32 addr, uint32 data) +QemuSysCtlrDevice::WritePort(uint32 offset, uint32 data) { - uint32 offset = addr & 0xff; + busdata r; - if (offset == 4) { + if (offset == 1) { // Command (Write Only) static const char *cmdname[] = { "no-op", @@ -66,30 +70,40 @@ QemuSysCtlrDevice::Write32(uint32 addr, break; case 2: // halt - case 3: // panic GetPowerDevice()->PushPowerButton(); break; + + case 3: // panic + DoPanic(); + break; } - return 0; } else { // 他のポートがどうなるのかは仕様に書いてない。 - putlog(1, "Write32 $%08x <- $%08x (BusErr)", addr, data); - return busdata::BusErr; + putlog(1, "Write $%08x <- $%08x (BusErr)", + GetMainbusDevice()->GetPaddr(), data); + r.SetBusErr(); } + + r |= BusData::Size4; + return r; } busdata -QemuSysCtlrDevice::Peek8(uint32 addr) +QemuSysCtlrDevice::PeekPort(uint32 offset) { - uint32 offset = addr & 0xff; - switch (offset) { - case 0: return (FEATURES >> 24); - case 1: return (FEATURES >> 16) & 0xff; - case 2: return (FEATURES >> 8) & 0xff; - case 3: return (FEATURES ) & 0xff; - + case 0: return FEATURES; default: - return busdata::BusErr; + return BusData::BusErr; } } + +// ゲストがパニックしたので、状態を保全して停止。 +// 本当はデバッガで止まるとかすればいいんだろうけど。 +void +QemuSysCtlrDevice::DoPanic() +{ + // 速度だけは落としておく。 + auto syncer = GetSyncer(); + syncer->NotifyFullSpeed(false); +}