Refactor the core's handling of firmware and BIOS images to rely less on the file system (#1826)

* Introduce firmware-related structs

* Fix some indents

* Move the generated firmware identifier to a constant

* Document the WifiAccessPoint constructors

* Add some constants

* Remove a stray comment

* Implement Firmware::UserData

* Add Firmware::Mask

* Document Firmware::Buffer

* Add a Firmware constructor that uses a FileHandle

* Set the default username in UserData

* Update the UserData checksum

* Forgot to include Platform.h

* Remove some redundant assignments in the default Firmware constructor

* const-ify CRC16

* Replace the plain Firmware buffer with a Firmware object

- Remove some functions that were reimplemented in the Firmware constructors

* Fix some crashes due to undefined behavior

* Fix the user data initialization

- Initialize both user data objects to default
- Set both user data objects to the same touch screen calibration

* Follow the DS logic in determining which user data section is current

* Remove an unneeded include

* Remove another unneeded include

* Initialize FirmwareMask in Firmware::Firmware

* Use the DEFAULT_SSID constant

* Add SPI_Firmware::InstallFirmware and SPI_Firmware::RemoveFirmware

* Move a logging call to after the file is written

* Add a SaveManager for the firmware

* Touch up the SPI_Firmware::Firmware declaration

* Move all firmware loading and customization to the frontend

* Call Platform::WriteFirmware when it's time to write the firmware back to disk

* Fix some missing stuff

* Remove the Get* functions from SPI_Firmware in favor of GetFirmware()

* Implement SPI_Firmware::DeInit in terms of RemoveFirmware

* Add Firmware::UpdateChecksums

* Fix an incorrect length

* Update all checksums in the firmware after setting touch screen calibration data

* Use the Firmware object's Position methods

* Remove register fields from the Firmware object

* Install the firmware before seeing if direct boot is necessary

* Install the firmware before calling NDS::Reset in LoadROM

* Slight cleanup in ROMManager

* Fix the default access point name

* Shorten the various getters in Firmware

* Add qualifiers for certain uses of firmware types

- GCC can get picky if -fpermissive isn't defined

* Add an InstallFirmware overload that takes a unique_ptr

* Log when firmware is added or removed

* Don't clear the firmware in SPI_Firmware::Init

- The original code didn't, it just set the pointer to nullptr

* Fix a typo

* Write back the full firmware if it's not generated

* Move the FreeBIOS to an external file

* Load wfcsettings.bin into the correct part of the generated firmware blob

* Load BIOS files in the frontend, not in the core

* Fix logging the firmware ID

* Add some utility functions

* Mark Firmware's constructors as explicit

* Remove obsolete ConfigEntry values

* Include <locale> explicitly in ROMManager

* Fix up some includes

* Add Firmware::IsBootable()

* Add a newline to a log entry

- Whoops

* Log the number of bytes written out in SaveManager

* Mark FirmwareHeader's constructor as explicit

* Clean up GenerateDefaultFirmware and LoadFirmwareFromFile

- Now they return a pair instead of two by-ref values

* Refactor SaveManager a little bit

- Manage its buffers as unique_ptrs to mitigate leaks
- Reallocate the internal buffer if SetPath is asked to reload the file (and the new length is different)

* Remove some stray parens

* Fix some firmware-related bugs I introduced

- Firmware settings are now properly saved to disk (beforehand I misunderstood when the firmware blob was written)
- Firmware is no longer overwritten by contents of wfcsettings.bin

* Slight cleanup
This commit is contained in:
Jesse Talavera-Greenberg
2023-09-18 15:09:11 -04:00
committed by GitHub
parent db963aa002
commit 5bfe51e670
20 changed files with 3259 additions and 2250 deletions

View File

@ -375,7 +375,7 @@ bool NeedsDirectBoot()
return true;
// DSi/3DS firmwares aren't bootable
if (SPI_Firmware::GetFirmwareLength() == 0x20000)
if (!SPI_Firmware::GetFirmware()->IsBootable())
return true;
return false;
@ -524,50 +524,7 @@ void Reset()
RunningGame = false;
LastSysClockCycles = 0;
// DS BIOSes are always loaded, even in DSi mode
// we need them for DS-compatible mode
if (Platform::GetConfigBool(Platform::ExternalBIOSEnable))
{
f = Platform::OpenLocalFile(Platform::GetConfigString(Platform::BIOS9Path), FileMode::Read);
if (!f)
{
Log(LogLevel::Warn, "ARM9 BIOS not found\n");
for (i = 0; i < 16; i++)
((u32*)ARM9BIOS)[i] = 0xE7FFDEFF;
}
else
{
FileRewind(f);
FileRead(ARM9BIOS, 0x1000, 1, f);
Log(LogLevel::Info, "ARM9 BIOS loaded\n");
Platform::CloseFile(f);
}
f = Platform::OpenLocalFile(Platform::GetConfigString(Platform::BIOS7Path), FileMode::Read);
if (!f)
{
Log(LogLevel::Warn, "ARM7 BIOS not found\n");
for (i = 0; i < 16; i++)
((u32*)ARM7BIOS)[i] = 0xE7FFDEFF;
}
else
{
FileRewind(f);
FileRead(ARM7BIOS, 0x4000, 1, f);
Log(LogLevel::Info, "ARM7 BIOS loaded\n");
Platform::CloseFile(f);
}
}
else
{
memcpy(ARM9BIOS, bios_arm9_bin, sizeof(bios_arm9_bin));
memcpy(ARM7BIOS, bios_arm7_bin, sizeof(bios_arm7_bin));
}
// BIOS files are now loaded by the frontend
#ifdef JIT_ENABLED
ARMJIT::Reset();
@ -575,7 +532,7 @@ void Reset()
if (ConsoleType == 1)
{
DSi::LoadBIOS();
// BIOS files are now loaded by the frontend
ARM9ClockShift = 2;
MainRAMMask = 0xFFFFFF;
@ -1046,6 +1003,15 @@ void LoadBIOS()
Reset();
}
bool IsLoadedARM9BIOSBuiltIn()
{
return memcmp(NDS::ARM9BIOS, bios_arm9_bin, sizeof(NDS::ARM9BIOS)) == 0;
}
bool IsLoadedARM7BIOSBuiltIn()
{
return memcmp(NDS::ARM7BIOS, bios_arm7_bin, sizeof(NDS::ARM7BIOS)) == 0;
}
u64 NextTarget()
{