--- nono/vm/mpu.h 2026/04/29 17:04:28 1.1.1.1 +++ nono/vm/mpu.h 2026/04/29 17:05:41 1.1.1.16 @@ -1,90 +1,113 @@ // // nono -// Copyright (C) 2017 isaki@NetBSD.org +// Copyright (C) 2020 nono project +// Licensed under nono-license.txt +// + +// +// MPU 共通部 // #pragma once #include "device.h" -#include "m68030.h" +#include "event.h" +#include "message.h" +#include + +class Debugger; +class MainbusDevice; +class Syncer; +// 全 MPU の共通部 class MPUDevice : public Device { - typedef Device inherited; + using inherited = Device; public: - MPUDevice(uint32); - virtual ~MPUDevice(); + explicit MPUDevice(uint objid_); + ~MPUDevice() override; - virtual bool Init(); - virtual void ResetHard(); + bool Init() override; + void PowerOff() override; - virtual bool MonitorUpdate(); + // 現在実行中の命令の PC を取得 + virtual uint32 GetPPC() const = 0; - // MPU を request サイクル分実行する - uint32 Run(uint64 request); + protected: + // 1命令実行イベント + Event exec_event { this }; - // 現在の PPC を取得 - uint32 GetPPC() const { return RegPPC; } + Debugger *debugger {}; +}; - // 割り込み発生を MPU に通知 (オートベクタ) - void Interrupt(int level); +// メイン MPU (680x0/88xxx0) 共通部 +class MainMPUDevice : public MPUDevice +{ + using inherited = MPUDevice; + protected: + // CPU の実行状態 + static const uint32 CPU_STATE_NORMAL = 0; + static const uint32 CPU_STATE_STOP = 1; + static const uint32 CPU_STATE_HALT = 2; - // 割り込み発生を MPU に通知 (ベクタ) - void Interrupt(int level, int vector); + public: + MainMPUDevice(); + ~MainMPUDevice() override; - // MPU の処理をこの命令で中断させる。 - // スケジューラのイベントリストに追加が発生した時に VM 側から - // MPU へ処理の中断を指示する。 - void Release() { cpu->atomic_reqflag |= CPU_REQ_RELEASE; } + bool Init() override; - // 基準サイクル数を取得 - uint64 total_cycle() const { return cpu->total_cycle; } + // 現在の VBR を取得 + virtual uint32 GetVBR() const = 0; - // A-Line, F-Line 命令エミュレーションのコールバックを指定する。 - // (Human68k エミュレーションで使用) - void SetALineCallback(bool (*callback)(m68kcpu*, void*), void *arg); - void SetFLineCallback(bool (*callback)(m68kcpu*, void*), void *arg); + // 現在アクセス中の論理アドレス、物理アドレスを取得。 + // Laddr == Paddr が MMU オフなのか PA=VA で運用中なのかの区別は + // ここでは付かない。 + virtual uint32 GetLaddr() const = 0; + virtual uint32 GetPaddr() const = 0; - // FPU を持っているか - bool HaveFPU() const { - return cpu->has_fpu; - } + // CPU の実行状態 (uint32) を返す。 + uint32 GetState() const noexcept { return cpu_state; } - // CPU コアを取得 (主にデバッグ用途) - m68kcpu *GetCPU() const { - return cpu; - } + // MPU 名を取得する。("MC68030" みたいなやつ、ログ名とは別) + virtual const char *GetMPUName() const = 0; - private: - m68kcpu *cpu = NULL; -}; + // MPU クロック [kHz] を取得する。 + uint GetClockSpeed() const { return clock_khz; } -// ATC モニタ -class MPUATC : public Object -{ - public: - MPUATC(m68kcpu *cpu); - virtual ~MPUATC() { } + // MPU クロック [nsec] を取得する。 + uint64 GetClock_nsec() const { return clock_nsec; } - virtual bool MonitorUpdate(); + // 割り込み発生を MPU に通知 + virtual void Interrupt(int level) = 0; - private: - m68kcpu *cpu = NULL; -}; + // デバイスが CI (キャッシュ禁止) をセットする。 + virtual void SetCI() = 0; -// ブランチ履歴モニタ -class MPUBrHist : public Object -{ - public: - MPUBrHist(m68kcpu *cpu); - virtual ~MPUBrHist() { } + // 例外カウンタ + std::vector excep_counter {}; + + protected: + void TraceMessage(MessageID, uint32); + virtual void SetTrace(bool enable) = 0; + + // CPU の状態 + void ChangeState(uint32 new_state); + + // CPU の実行状態 + uint32 cpu_state {}; + + uint clock_khz {}; // MPU クロック [kHz] + uint64 clock_nsec {}; // MPU クロック [nsec] + + bool resetting {}; // リセット処理中フラグ - virtual bool MonitorUpdate(); + MainbusDevice *mainbus {}; + Syncer *syncer {}; - private: - m68kcpu *cpu = NULL; + // Round Mode (モニタ表示用) + static const char * const rmstr[4]; }; -extern MPUDevice *gMPU; -extern MPUATC *gMPUATC; -extern MPUBrHist *gMPUBrHist; +static inline MainMPUDevice *GetMPUDevice() { + return Object::GetObject(OBJ_MPU); +}