System: Store BIOS image info/hash after loading

This commit is contained in:
Stenzek 2023-03-16 19:22:54 +10:00
parent 70695d3a4d
commit 1fcf16fc81
7 changed files with 66 additions and 24 deletions

View File

@ -96,7 +96,7 @@ static constexpr const BIOS::ImageInfo s_openbios_info = {"OpenBIOS", ConsoleReg
static constexpr const char s_openbios_signature[] = {'O', 'p', 'e', 'n', 'B', 'I', 'O', 'S'}; static constexpr const char s_openbios_signature[] = {'O', 'p', 'e', 'n', 'B', 'I', 'O', 'S'};
static constexpr u32 s_openbios_signature_offset = 0x78; static constexpr u32 s_openbios_signature_offset = 0x78;
static BIOS::Hash GetHash(const BIOS::Image& image) BIOS::Hash BIOS::GetImageHash(const BIOS::Image& image)
{ {
BIOS::Hash hash; BIOS::Hash hash;
MD5Digest digest; MD5Digest digest;
@ -132,17 +132,21 @@ std::optional<BIOS::Image> BIOS::LoadImageFromFile(const char* filename)
return std::nullopt; return std::nullopt;
} }
Log_DevPrint(fmt::format("Hash for BIOS '{}': {}", FileSystem::GetDisplayNameFromPath(filename), GetHash(ret).ToString()).c_str()); Log_DevPrint(fmt::format("Hash for BIOS '{}': {}", FileSystem::GetDisplayNameFromPath(filename), GetImageHash(ret).ToString()).c_str());
return ret; return ret;
} }
const BIOS::ImageInfo* BIOS::GetInfoForImage(const Image& image) const BIOS::ImageInfo* BIOS::GetInfoForImage(const Image& image)
{ {
const Hash hash(GetHash(image)); const Hash hash(GetImageHash(image));
return GetInfoForImage(image, hash);
}
const BIOS::ImageInfo* BIOS::GetInfoForImage(const Image& image, const Hash& hash)
{
// check for openbios // check for openbios
if (image.size() >= (s_openbios_signature_offset + std::size(s_openbios_signature)) && if (image.size() >= (s_openbios_signature_offset + std::size(s_openbios_signature)) &&
std::memcmp(&image[s_openbios_signature_offset], s_openbios_signature, std::size(s_openbios_signature)) == 0) std::memcmp(&image[s_openbios_signature_offset], s_openbios_signature, std::size(s_openbios_signature)) == 0)
{ {
return &s_openbios_info; return &s_openbios_info;
} }

View File

@ -59,8 +59,10 @@ static_assert(sizeof(PSEXEHeader) == 0x800);
#pragma pack(pop) #pragma pack(pop)
std::optional<Image> LoadImageFromFile(const char* filename); std::optional<Image> LoadImageFromFile(const char* filename);
Hash GetImageHash(const Image& image);
const ImageInfo* GetInfoForImage(const Image& image); const ImageInfo* GetInfoForImage(const Image& image);
const ImageInfo* GetInfoForImage(const Image& image, const Hash& hash);
bool IsValidBIOSForRegion(ConsoleRegion console_region, ConsoleRegion bios_region); bool IsValidBIOSForRegion(ConsoleRegion console_region, ConsoleRegion bios_region);
void PatchBIOS(u8* image, u32 image_size, u32 address, u32 value, u32 mask = UINT32_C(0xFFFFFFFF)); void PatchBIOS(u8* image, u32 image_size, u32 address, u32 value, u32 mask = UINT32_C(0xFFFFFFFF));

View File

@ -223,17 +223,6 @@ void SetExpansionROM(std::vector<u8> data)
m_exp1_rom = std::move(data); m_exp1_rom = std::move(data);
} }
void SetBIOS(const std::vector<u8>& image)
{
if (image.size() != static_cast<u32>(BIOS_SIZE))
{
Panic("Incorrect BIOS image size");
return;
}
std::memcpy(g_bios, image.data(), BIOS_SIZE);
}
std::tuple<TickCount, TickCount, TickCount> CalculateMemoryTiming(MEMDELAY mem_delay, COMDELAY common_delay) std::tuple<TickCount, TickCount, TickCount> CalculateMemoryTiming(MEMDELAY mem_delay, COMDELAY common_delay)
{ {
// from nocash spec // from nocash spec

View File

@ -114,7 +114,6 @@ void UpdateFastmemViews(CPUFastmemMode mode);
bool CanUseFastmemForAddress(VirtualMemoryAddress address); bool CanUseFastmemForAddress(VirtualMemoryAddress address);
void SetExpansionROM(std::vector<u8> data); void SetExpansionROM(std::vector<u8> data);
void SetBIOS(const std::vector<u8>& image);
extern std::bitset<RAM_8MB_CODE_PAGE_COUNT> m_ram_code_bits; extern std::bitset<RAM_8MB_CODE_PAGE_COUNT> m_ram_code_bits;
extern u8* g_ram; // 2MB-8MB RAM extern u8* g_ram; // 2MB-8MB RAM

View File

@ -2081,6 +2081,7 @@ void CodeGenerator::EmitStoreGuestMemoryFastmem(const CodeBlockInstruction& cbi,
bpi.address_host_reg = HostReg_Invalid; bpi.address_host_reg = HostReg_Invalid;
bpi.value_host_reg = value.host_reg; bpi.value_host_reg = value.host_reg;
bpi.guest_pc = m_current_instruction->pc; bpi.guest_pc = m_current_instruction->pc;
bpi.fault_count = 0;
if (g_settings.cpu_fastmem_mode == CPUFastmemMode::MMap) if (g_settings.cpu_fastmem_mode == CPUFastmemMode::MMap)
{ {

View File

@ -96,6 +96,7 @@ static bool ReadExecutableFromImage(ISOReader& iso, std::string* out_executable_
static void StallCPU(TickCount ticks); static void StallCPU(TickCount ticks);
static bool LoadBIOS();
static void InternalReset(); static void InternalReset();
static void ClearRunningGame(); static void ClearRunningGame();
static void DestroySystem(); static void DestroySystem();
@ -139,6 +140,8 @@ TickCount System::g_ticks_per_second = System::MASTER_CLOCK;
static TickCount s_max_slice_ticks = System::MASTER_CLOCK / 10; static TickCount s_max_slice_ticks = System::MASTER_CLOCK / 10;
static u32 s_frame_number = 1; static u32 s_frame_number = 1;
static u32 s_internal_frame_number = 1; static u32 s_internal_frame_number = 1;
static const BIOS::ImageInfo* s_bios_image_info = nullptr;
static BIOS::Hash s_bios_hash = {};
static std::string s_running_game_path; static std::string s_running_game_path;
static std::string s_running_game_serial; static std::string s_running_game_serial;
@ -330,6 +333,16 @@ bool System::IsRunningBIOS()
return s_running_bios; return s_running_bios;
} }
const BIOS::ImageInfo* System::GetBIOSImageInfo()
{
return s_bios_image_info;
}
const BIOS::Hash& System::GetBIOSHash()
{
return s_bios_hash;
}
float System::GetFPS() float System::GetFPS()
{ {
return s_fps; return s_fps;
@ -1217,11 +1230,8 @@ bool System::BootSystem(SystemBootParameters parameters)
#endif #endif
// Load BIOS image. // Load BIOS image.
std::optional<BIOS::Image> bios_image(BIOS::GetBIOSImage(s_region)); if (!LoadBIOS())
if (!bios_image)
{ {
Host::ReportFormattedErrorAsync("Error", Host::TranslateString("System", "Failed to load %s BIOS."),
Settings::GetConsoleRegionName(s_region));
s_state = State::Shutdown; s_state = State::Shutdown;
ClearRunningGame(); ClearRunningGame();
Host::OnSystemDestroyed(); Host::OnSystemDestroyed();
@ -1240,17 +1250,15 @@ bool System::BootSystem(SystemBootParameters parameters)
// Allow controller analog mode for EXEs and PSFs. // Allow controller analog mode for EXEs and PSFs.
s_running_bios = s_running_game_path.empty() && exe_boot.empty() && psf_boot.empty(); s_running_bios = s_running_game_path.empty() && exe_boot.empty() && psf_boot.empty();
Bus::SetBIOS(bios_image.value());
UpdateControllers(); UpdateControllers();
UpdateMemoryCardTypes(); UpdateMemoryCardTypes();
UpdateMultitaps(); UpdateMultitaps();
InternalReset(); InternalReset();
// Enable tty by patching bios. // Enable tty by patching bios.
const BIOS::ImageInfo* bios_info = BIOS::GetInfoForImage(bios_image.value());
if (g_settings.bios_patch_tty_enable) if (g_settings.bios_patch_tty_enable)
{ {
if (bios_info && bios_info->patch_compatible) if (s_bios_image_info && s_bios_image_info->patch_compatible)
BIOS::PatchBIOSEnableTTY(Bus::g_bios, Bus::BIOS_SIZE); BIOS::PatchBIOSEnableTTY(Bus::g_bios, Bus::BIOS_SIZE);
else else
Log_ErrorPrintf("Not patching TTY enable, as BIOS is not patch compatible."); Log_ErrorPrintf("Not patching TTY enable, as BIOS is not patch compatible.");
@ -1276,7 +1284,7 @@ bool System::BootSystem(SystemBootParameters parameters)
if (CDROM::HasMedia() && (parameters.override_fast_boot.has_value() ? parameters.override_fast_boot.value() : if (CDROM::HasMedia() && (parameters.override_fast_boot.has_value() ? parameters.override_fast_boot.value() :
g_settings.bios_patch_fast_boot)) g_settings.bios_patch_fast_boot))
{ {
if (bios_info && bios_info->patch_compatible) if (s_bios_image_info && s_bios_image_info->patch_compatible)
BIOS::PatchBIOSFastBoot(Bus::g_bios, Bus::BIOS_SIZE); BIOS::PatchBIOSFastBoot(Bus::g_bios, Bus::BIOS_SIZE);
else else
Log_ErrorPrintf("Not patching fast boot, as BIOS is not patch compatible."); Log_ErrorPrintf("Not patching fast boot, as BIOS is not patch compatible.");
@ -1497,6 +1505,9 @@ void System::DestroySystem()
Host::ReleaseHostDisplay(); Host::ReleaseHostDisplay();
} }
s_bios_hash = {};
s_bios_image_info = nullptr;
Host::OnSystemDestroyed(); Host::OnSystemDestroyed();
} }
@ -1755,6 +1766,33 @@ bool System::DoState(StateWrapper& sw, GPUTexture** host_texture, bool update_di
return !sw.HasError(); return !sw.HasError();
} }
bool System::LoadBIOS()
{
std::optional<BIOS::Image> bios_image(BIOS::GetBIOSImage(s_region));
if (!bios_image.has_value())
{
Host::ReportFormattedErrorAsync("Error", Host::TranslateString("System", "Failed to load %s BIOS."),
Settings::GetConsoleRegionName(s_region));
return false;
}
if (bios_image->size() != static_cast<u32>(Bus::BIOS_SIZE))
{
Host::ReportFormattedErrorAsync("Error", Host::TranslateString("System", "Incorrect BIOS image size"));
return false;
}
s_bios_hash = BIOS::GetImageHash(bios_image.value());
s_bios_image_info = BIOS::GetInfoForImage(bios_image.value(), s_bios_hash);
if (s_bios_image_info)
Log_InfoPrintf("Using BIOS: %s", s_bios_image_info->description);
else
Log_WarningPrintf("Using an unknown BIOS: %s", s_bios_image_info->hash.ToString().c_str());
std::memcpy(Bus::g_bios, bios_image->data(), Bus::BIOS_SIZE);
return true;
}
void System::InternalReset() void System::InternalReset()
{ {
if (IsShutdown()) if (IsShutdown())

View File

@ -19,6 +19,12 @@ class Controller;
struct CheatCode; struct CheatCode;
class CheatList; class CheatList;
namespace BIOS
{
struct ImageInfo;
struct Hash;
}
struct SystemBootParameters struct SystemBootParameters
{ {
SystemBootParameters(); SystemBootParameters();
@ -174,7 +180,10 @@ void IncrementInternalFrameNumber();
const std::string& GetRunningPath(); const std::string& GetRunningPath();
const std::string& GetRunningSerial(); const std::string& GetRunningSerial();
const std::string& GetRunningTitle(); const std::string& GetRunningTitle();
bool IsRunningBIOS(); bool IsRunningBIOS();
const BIOS::ImageInfo* GetBIOSImageInfo();
const BIOS::Hash& GetBIOSHash();
// TODO: Move to PerformanceMetrics // TODO: Move to PerformanceMetrics
static constexpr u32 NUM_FRAME_TIME_SAMPLES = 150; static constexpr u32 NUM_FRAME_TIME_SAMPLES = 150;