mirror of
https://github.com/LNH-team/pico-loader.git
synced 2026-01-10 08:29:29 +01:00
98 lines
2.8 KiB
C++
98 lines
2.8 KiB
C++
#include "common.h"
|
|
#include <string.h>
|
|
#include "ipc.h"
|
|
#include "ipcCommands.h"
|
|
#include "loader/DldiDriver.h"
|
|
|
|
static u8 sDldiBuffer[16 * 1024] alignas(32);
|
|
static DldiDriver sDldiDriver = DldiDriver((dldi_header_t*)sDldiBuffer);
|
|
|
|
[[gnu::target("thumb")]]
|
|
static bool readSectorsWithPatchCode(u32 sector, u32 count, void* buffer)
|
|
{
|
|
typedef void (*patch_code_read_sd_sectors_t)(u32 srcSector, void* dst, u32 sectorCount);
|
|
(*(patch_code_read_sd_sectors_t*)0x037F8000)(sector, buffer, count);
|
|
return true;
|
|
}
|
|
|
|
[[gnu::target("thumb")]]
|
|
static bool writeSectorsWithPatchCode(u32 sector, u32 count, const void* buffer)
|
|
{
|
|
typedef void (*patch_code_write_sd_sectors_t)(u32 dstSector, const void* src, u32 sectorCount);
|
|
(*(patch_code_write_sd_sectors_t*)0x037F8004)(sector, buffer, count);
|
|
return true;
|
|
}
|
|
|
|
bool dldi_init()
|
|
{
|
|
auto driver = (const dldi_header_t*)gLoaderHeader.dldiDriver;
|
|
if (!driver || driver->dldiMagic != DLDI_MAGIC || driver->driverMagic == DLDI_DRIVER_MAGIC_NONE)
|
|
{
|
|
LOG_DEBUG("No dldi driver found\n");
|
|
|
|
// Need to initialize before getting the patch code
|
|
sendToArm9(IPC_COMMAND_ARM9_INITIALIZE_SD_CARD);
|
|
if (!receiveFromArm9())
|
|
{
|
|
LOG_ERROR("Sd card initialization failed\n");
|
|
return false;
|
|
}
|
|
|
|
// Try to get the patch code
|
|
sendToArm9(IPC_COMMAND_ARM9_GET_SD_FUNCTIONS);
|
|
if (!receiveFromArm9())
|
|
{
|
|
LOG_ERROR("Getting patch code failed\n");
|
|
return false;
|
|
}
|
|
|
|
LOG_DEBUG("Using patch code sd read/write\n");
|
|
((dldi_header_t*)sDldiBuffer)->readSectorsFuncAddress = (u32)readSectorsWithPatchCode;
|
|
((dldi_header_t*)sDldiBuffer)->writeSectorsFuncAddress = (u32)writeSectorsWithPatchCode;
|
|
}
|
|
else
|
|
{
|
|
u32 driverSize = 1 << driver->driverSize;
|
|
if (driverSize > sizeof(sDldiBuffer))
|
|
{
|
|
LOG_ERROR("Not enough space for dldi driver of size %d\n", driverSize);
|
|
return false;
|
|
}
|
|
|
|
memcpy(sDldiBuffer, driver, driverSize);
|
|
|
|
sDldiDriver.Relocate();
|
|
sDldiDriver.PrepareForUse();
|
|
|
|
if (!sDldiDriver.Startup())
|
|
{
|
|
LOG_ERROR("DLDI startup failed\n");
|
|
return false;
|
|
}
|
|
|
|
sendToArm9(IPC_COMMAND_ARM9_INITIALIZE_SD_CARD);
|
|
if (!receiveFromArm9())
|
|
{
|
|
LOG_ERROR("Sd card initialization failed\n");
|
|
return false;
|
|
}
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
extern "C" bool dldi_readSectors(void* buffer, u32 sector, u32 count)
|
|
{
|
|
return sDldiDriver.ReadSectors(sector, count, buffer);
|
|
}
|
|
|
|
extern "C" bool dldi_writeSectors(const void* buffer, u32 sector, u32 count)
|
|
{
|
|
return sDldiDriver.WriteSectors(sector, count, buffer);
|
|
}
|
|
|
|
bool dldi_patchTo(dldi_header_t* stub)
|
|
{
|
|
return sDldiDriver.PatchTo(stub);
|
|
}
|