diff --git a/source/keys/keys.c b/source/keys/keys.c index 153c1ca..9f56e79 100644 --- a/source/keys/keys.c +++ b/source/keys/keys.c @@ -44,6 +44,7 @@ #include "key_sources.inl" #include "ccrypto.h" +#include "../libs/fatfs/diskio.h" #include extern bool sd_mount(); @@ -364,6 +365,36 @@ get_tsec: ; gfx_hexdump(0, tmp, NX_EMMC_BLOCKSIZE); + + DRESULT read_res; + read_res = disk_read_mod (tmp, 0, 1, &storage, pkg2_part, 9); + + switch (read_res) + { + case RES_OK: + WPRINTF("Successful!"); + break; /* 0: Successful */ + case RES_ERROR: + WPRINTF("R/W Error!"); + break; /* 1: R/W Error */ + case RES_WRPRT: + WPRINTF("Write Protected!"); + break; /* 2: Write Protected */ + case RES_NOTRDY: + WPRINTF("Not Ready!"); + break; /* 3: Not Ready */ + case RES_PARERR: + WPRINTF("Invalid Parameter!"); + break; /* 4: Invalid Parameter */ + + default: + WPRINTF("No Idea!"); + break; + } + + gfx_hexdump(0, tmp, NX_EMMC_BLOCKSIZE); + + free(tmp); goto pkg2_done; diff --git a/source/libs/fatfs/diskio.c b/source/libs/fatfs/diskio.c index 97f8336..d7528d9 100644 --- a/source/libs/fatfs/diskio.c +++ b/source/libs/fatfs/diskio.c @@ -27,8 +27,7 @@ #include "diskio.h" /* FatFs lower layer API */ #include "../../mem/heap.h" #include "../../sec/se.h" -#include "../../storage/nx_emmc.h" -#include "../../storage/sdmmc.h" + #define SDMMC_UPPER_BUFFER 0xB8000000 #define DRAM_START 0x80000000 @@ -125,6 +124,73 @@ out:; return res; } + + + +DRESULT disk_read_mod ( + + BYTE *buff, /* Data buffer to store read data */ + DWORD sector, /* Start sector in LBA */ + UINT count, /* Number of sectors to read */ + sdmmc_storage_t *storage, + emmc_part_t *partition, + u32 hiKey +) +{ + + + __attribute__ ((aligned (16))) static u8 tweak[0x10]; + __attribute__ ((aligned (16))) static u64 prev_cluster = -1; + __attribute__ ((aligned (16))) static u32 prev_sector = 0; + u32 tweak_exp = 0; + bool regen_tweak = true, cache_sector = false; + + u32 s = 0; + if (count == 1) { + for ( ; s < secindex; s++) { + if (sector_cache[s].sector == sector) { + sector_cache[s].visit_count++; + memcpy(buff, sector_cache[s].cached_sector, 0x200); + memcpy(tweak, sector_cache[s].tweak, 0x10); + prev_sector = sector; + prev_cluster = sector / 0x20; + return RES_OK; + } + } + // add to cache + if (s == secindex && s < MAX_SEC_CACHE_ENTRIES) { + sector_cache[s].sector = sector; + sector_cache[s].visit_count++; + cache_sector = true; + secindex++; + } + } + + if (nx_emmc_part_read(storage, partition, sector, count, buff)) { + if (prev_cluster != sector / 0x20) { // sector in different cluster than last read + prev_cluster = sector / 0x20; + tweak_exp = sector % 0x20; + } else if (sector > prev_sector) { // sector in same cluster and past last sector + tweak_exp = sector - prev_sector - 1; + regen_tweak = false; + } else { // sector in same cluster and before or same as last sector + tweak_exp = sector % 0x20; + } + + // fatfs will never pull more than a cluster + _emmc_xts(hiKey, hiKey - 1, 0, tweak, regen_tweak, tweak_exp, prev_cluster, buff, buff, count * 0x200); + if (cache_sector) { + memcpy(sector_cache[s].cached_sector, buff, 0x200); + memcpy(sector_cache[s].tweak, tweak, 0x10); + } + prev_sector = sector + count - 1; + return RES_OK; + } + + return RES_ERROR; +} + + DRESULT disk_read ( BYTE pdrv, /* Physical drive number to identify the drive */ BYTE *buff, /* Data buffer to store read data */ diff --git a/source/libs/fatfs/diskio.h b/source/libs/fatfs/diskio.h index d6ae8f8..39b2d20 100644 --- a/source/libs/fatfs/diskio.h +++ b/source/libs/fatfs/diskio.h @@ -10,6 +10,8 @@ extern "C" { #endif #include "../../utils/types.h" +#include "../../storage/sdmmc.h" +#include "../../storage/nx_emmc.h" /* Status of Disk Functions */ typedef BYTE DSTATUS; @@ -31,6 +33,7 @@ typedef enum { DSTATUS disk_initialize (BYTE pdrv); DSTATUS disk_status (BYTE pdrv); DRESULT disk_read (BYTE pdrv, BYTE* buff, DWORD sector, UINT count); +DRESULT disk_read_mod (BYTE *buff, DWORD sector, UINT count, sdmmc_storage_t *storage, emmc_part_t *partition, u32 hiKey); DRESULT disk_write (BYTE pdrv, const BYTE* buff, DWORD sector, UINT count); DRESULT disk_ioctl (BYTE pdrv, BYTE cmd, void* buff);