Skip to content

Commit

Permalink
Refactor the core's handling of firmware and BIOS images to rely less…
Browse files Browse the repository at this point in the history
… 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
  • Loading branch information
JesseTG authored Sep 18, 2023
1 parent db963aa commit 5bfe51e
Show file tree
Hide file tree
Showing 20 changed files with 3,258 additions and 2,249 deletions.
2 changes: 2 additions & 0 deletions src/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -40,9 +40,11 @@ add_library(core STATIC
ROMList.h
ROMList.cpp
FreeBIOS.h
FreeBIOS.cpp
RTC.cpp
Savestate.cpp
SPI.cpp
SPI_Firmware.cpp
SPU.cpp
types.h
version.h
Expand Down
64 changes: 3 additions & 61 deletions src/DSi.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -548,12 +548,12 @@ void SetupDirectBoot()
DSi_NAND::DeInit();
}

u8 nwifiver = SPI_Firmware::GetNWifiVersion();
ARM9Write8(0x020005E0, nwifiver);
SPI_Firmware::WifiBoard nwifiver = SPI_Firmware::GetFirmware()->Header().WifiBoard;
ARM9Write8(0x020005E0, static_cast<u8>(nwifiver));

// TODO: these should be taken from the wifi firmware in NAND
// but, hey, this works too.
if (nwifiver == 1)
if (nwifiver == SPI_Firmware::WifiBoard::W015)
{
ARM9Write16(0x020005E2, 0xB57E);
ARM9Write32(0x020005E4, 0x00500400);
Expand Down Expand Up @@ -726,64 +726,6 @@ void SoftReset()
GPU::DispStat[1] |= (1<<6);
}

bool LoadBIOS()
{
Platform::FileHandle* f;
u32 i;

memset(ARM9iBIOS, 0, 0x10000);
memset(ARM7iBIOS, 0, 0x10000);

f = Platform::OpenLocalFile(Platform::GetConfigString(Platform::DSi_BIOS9Path), FileMode::Read);
if (!f)
{
Log(LogLevel::Warn, "ARM9i BIOS not found\n");

for (i = 0; i < 16; i++)
((u32*)ARM9iBIOS)[i] = 0xE7FFDEFF;
}
else
{
FileRewind(f);
FileRead(ARM9iBIOS, 0x10000, 1, f);

Log(LogLevel::Info, "ARM9i BIOS loaded\n");
Platform::CloseFile(f);
}

f = Platform::OpenLocalFile(Platform::GetConfigString(Platform::DSi_BIOS7Path), FileMode::Read);
if (!f)
{
Log(LogLevel::Warn, "ARM7i BIOS not found\n");

for (i = 0; i < 16; i++)
((u32*)ARM7iBIOS)[i] = 0xE7FFDEFF;
}
else
{
// TODO: check if the first 32 bytes are crapoed

FileRewind(f);
FileRead(ARM7iBIOS, 0x10000, 1, f);

Log(LogLevel::Info, "ARM7i BIOS loaded\n");
CloseFile(f);
}

if (!Platform::GetConfigBool(Platform::DSi_FullBIOSBoot))
{
// herp
*(u32*)&ARM9iBIOS[0] = 0xEAFFFFFE;
*(u32*)&ARM7iBIOS[0] = 0xEAFFFFFE;

// TODO!!!!
// hax the upper 32K out of the goddamn DSi
// done that :) -pcy
}

return true;
}

bool LoadNAND()
{
Log(LogLevel::Info, "Loading DSi NAND\n");
Expand Down
1 change: 0 additions & 1 deletion src/DSi.h
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,6 @@ void SetCartInserted(bool inserted);
void SetupDirectBoot();
void SoftReset();

bool LoadBIOS();
bool LoadNAND();

void RunNDMAs(u32 cpu);
Expand Down
18 changes: 10 additions & 8 deletions src/DSi_NWifi.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -147,6 +147,7 @@ DSi_NWifi::~DSi_NWifi()

void DSi_NWifi::Reset()
{
using namespace SPI_Firmware;
TransferCmd = 0xFFFFFFFF;
RemSize = 0;

Expand All @@ -163,34 +164,34 @@ void DSi_NWifi::Reset()
for (int i = 0; i < 9; i++)
Mailbox[i].Clear();

u8* mac = SPI_Firmware::GetWifiMAC();
MacAddress mac = GetFirmware()->Header().MacAddress;
Log(LogLevel::Info, "NWifi MAC: %02X:%02X:%02X:%02X:%02X:%02X\n",
mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]);

u8 type = SPI_Firmware::GetNWifiVersion();
WifiBoard type = GetFirmware()->Header().WifiBoard;
switch (type)
{
case 1: // AR6002
case WifiBoard::W015: // AR6002
ROMID = 0x20000188;
ChipID = 0x02000001;
HostIntAddr = 0x00500400;
break;

case 2: // AR6013
case WifiBoard::W024: // AR6013
ROMID = 0x23000024;
ChipID = 0x0D000000;
HostIntAddr = 0x00520000;
break;

case 3: // AR6014 (3DS)
case WifiBoard::W028: // AR6014 (3DS)
ROMID = 0x2300006F;
ChipID = 0x0D000001;
HostIntAddr = 0x00520000;
Log(LogLevel::Info, "NWifi: hardware is 3DS type, unchecked\n");
break;

default:
Log(LogLevel::Warn, "NWifi: unknown hardware type, assuming AR6002\n");
Log(LogLevel::Warn, "NWifi: unknown hardware type 0x%x, assuming AR6002\n", static_cast<u8>(type));
ROMID = 0x20000188;
ChipID = 0x02000001;
HostIntAddr = 0x00500400;
Expand All @@ -201,7 +202,7 @@ void DSi_NWifi::Reset()

*(u32*)&EEPROM[0x000] = 0x300;
*(u16*)&EEPROM[0x008] = 0x8348; // TODO: determine properly (country code)
memcpy(&EEPROM[0x00A], mac, 6);
memcpy(&EEPROM[0x00A], mac.data(), mac.size());
*(u32*)&EEPROM[0x010] = 0x60000000;

memset(&EEPROM[0x03C], 0xFF, 0x70);
Expand Down Expand Up @@ -894,8 +895,9 @@ void DSi_NWifi::HTC_Command()

case 0x0004: // setup complete
{
SPI_Firmware::MacAddress mac = SPI_Firmware::GetFirmware()->Header().MacAddress;
u8 ready_evt[12];
memcpy(&ready_evt[0], SPI_Firmware::GetWifiMAC(), 6);
memcpy(&ready_evt[0], &mac, mac.size());
ready_evt[6] = 0x02;
ready_evt[7] = 0;
*(u32*)&ready_evt[8] = 0x2300006C;
Expand Down
Loading

0 comments on commit 5bfe51e

Please sign in to comment.