|
|
nono 1.7.0
//
// nono
// Copyright (C) 2024 nono project
// Licensed under nono-license.txt
//
//
// QEMU Virtual System Controller
//
// https://www.qemu.org/docs/master/specs/virt-ctlr.html
#include "qemusysctlr.h"
#include "mainbus.h"
#include "power.h"
#include "syncer.h"
// コンストラクタ
QemuSysCtlrDevice::QemuSysCtlrDevice()
: inherited(OBJ_QEMUSYSCTLR)
{
}
// デストラクタ
QemuSysCtlrDevice::~QemuSysCtlrDevice()
{
}
busdata
QemuSysCtlrDevice::ReadPort(uint32 offset)
{
busdata data;
if (offset == 0) {
// Features (Read Only)
data = FEATURES;
putlog(2, "FEATURES -> $%08x", data.Data());
} else {
// 他のポートがどうなるのかは仕様に書いてない。
data.SetBusErr();
putlog(1, "Read $%08x (BusErr)", GetMainbusDevice()->GetPaddr());
}
data |= BusData::Size4;
return data;
}
busdata
QemuSysCtlrDevice::WritePort(uint32 offset, uint32 data)
{
busdata r;
if (offset == 1) {
// Command (Write Only)
static const char *cmdname[] = {
"no-op",
"reset",
"halt",
"panic",
};
putlog(1, "Command <- $%08x (%s)", data,
(data < countof(cmdname) ? cmdname[data] : cmdname[0]));
switch (data) {
default:
case 0: // no-op
break;
case 1: // reset
GetPowerDevice()->MakeResetHard();
break;
case 2: // halt
GetPowerDevice()->PushPowerButton();
break;
case 3: // panic
DoPanic();
break;
}
} else {
// 他のポートがどうなるのかは仕様に書いてない。
putlog(1, "Write $%08x <- $%08x (BusErr)",
GetMainbusDevice()->GetPaddr(), data);
r.SetBusErr();
}
r |= BusData::Size4;
return r;
}
busdata
QemuSysCtlrDevice::PeekPort(uint32 offset)
{
switch (offset) {
case 0: return FEATURES;
default:
return BusData::BusErr;
}
}
// ゲストがパニックしたので、状態を保全して停止。
// 本当はデバッガで止まるとかすればいいんだろうけど。
void
QemuSysCtlrDevice::DoPanic()
{
// 速度だけは落としておく。
auto syncer = GetSyncer();
syncer->NotifyFullSpeed(false);
}
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.