mirror of
https://github.com/hrydgard/ppsspp.git
synced 2026-11-04 21:33:58 +01:00
The calls homebrew starts the ME with (1.50's NIDs, and 3.71's for the ME's reset and bus clock) set or clear a bit of the reset or bus clock register the way the firmware's driver does, returning whether it was set. Only those NIDs, so a later firmware's lowio.prx keeps its own exports under --vsh. Kernel modules copy their ME code to the boot page with SysclibForKernel's memcpy, which now goes through MMIO for hardware addresses like the replaced memcpy already did (MMIO::Copy, shared). pspsdk's mebasic, MElib's test, PSP Bunny, snes9xTYL and ProTrekkr's test now start their ME. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
74 lines
2.9 KiB
C++
74 lines
2.9 KiB
C++
// Copyright (c) 2012- PPSSPP Project.
|
|
|
|
// This program is free software: you can redistribute it and/or modify
|
|
// it under the terms of the GNU General Public License as published by
|
|
// the Free Software Foundation, version 2.0 or later versions.
|
|
|
|
// This program is distributed in the hope that it will be useful,
|
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
// GNU General Public License 2.0 for more details.
|
|
|
|
// A copy of the GPL 2.0 should have been included with the program.
|
|
// If not, see http://www.gnu.org/licenses/
|
|
|
|
// Official git repository and contact information can be found at
|
|
// https://github.com/hrydgard/ppsspp and http://www.ppsspp.org/.
|
|
|
|
// Memory-mapped hardware registers, for kernel code that pokes the hardware directly (the firmware
|
|
// modules the VSH boot runs). Each block of registers is a device covering an address range; the
|
|
// interpreter sends an access there (Memory::IsMMIOAccess) to the device, or logs it as unhandled.
|
|
|
|
#pragma once
|
|
|
|
#include "Common/CommonTypes.h"
|
|
|
|
class MIPSState;
|
|
class PointerWrap;
|
|
|
|
class MMIODevice {
|
|
public:
|
|
MMIODevice(const char *name, u32 base, u32 size) : name_(name), base_(base), size_(size) {}
|
|
virtual ~MMIODevice() {}
|
|
|
|
// offset is from the base. size is 1, 2 or 4. The CPU doing the access is passed for registers
|
|
// that answer each CPU differently. Returns false for an access the device doesn't handle.
|
|
virtual bool Read(MIPSState *mips, u32 offset, int size, u32 *value) = 0;
|
|
virtual bool Write(MIPSState *mips, u32 offset, int size, u32 value) = 0;
|
|
// To the power-on state.
|
|
virtual void Reset() = 0;
|
|
virtual void DoState(PointerWrap &p) = 0;
|
|
|
|
const char *Name() const { return name_; }
|
|
bool Contains(u32 address) const { return address - base_ < size_; }
|
|
u32 Base() const { return base_; }
|
|
|
|
private:
|
|
const char *name_;
|
|
u32 base_;
|
|
u32 size_;
|
|
};
|
|
|
|
namespace MMIO {
|
|
|
|
// What an unhandled read returns. Distinctive (not 0) so it's obvious in a live trace when some later
|
|
// computation's input traces back to an unimplemented register, rather than looking like an
|
|
// ordinary, legitimate zero.
|
|
constexpr u32 UNHANDLED_READ = 0x1337BEEF;
|
|
|
|
// Registers the devices, in their power-on state.
|
|
void Init();
|
|
void Shutdown();
|
|
void DoState(PointerWrap &p);
|
|
|
|
// For an address Memory::IsMMIOAccess() accepts, from kernel code (the caller checks). size is 1, 2
|
|
// or 4. An access no device handles is logged, and reads as UNHANDLED_READ.
|
|
u32 Read(MIPSState *mips, u32 address, int size);
|
|
void Write(MIPSState *mips, u32 address, int size, u32 value);
|
|
// A memory copy where either end may be hardware registers: kernel code copies Media Engine code
|
|
// to the boot page at 0xBFC00000, which the main CPU reaches through MMIO. Byte by byte, and
|
|
// backward where memmove would be. Returns false, having done nothing, if neither end is MMIO.
|
|
bool Copy(MIPSState *mips, u32 destPtr, u32 srcPtr, u32 bytes);
|
|
|
|
} // namespace MMIO
|