From 239a7607c8e3334b19fea107508c065489c35e2b Mon Sep 17 00:00:00 2001 From: rw-r-r-0644 Date: Tue, 1 Jun 2021 12:36:01 +0200 Subject: [PATCH] Fix slc payload loading Align isfs buffers, remove the need for heap --- stage2/isfs/isfs.c | 16 ++-------------- stage2/isfs/isfs.h | 1 + stage2/isfs/super.c | 13 +++---------- stage2/isfs/super.h | 2 +- stage2/isfs/volume.c | 22 ++++++---------------- stage2/main.c | 2 +- stage2/nand.c | 8 ++++---- stage2/nand.h | 2 ++ 8 files changed, 20 insertions(+), 46 deletions(-) diff --git a/stage2/isfs/isfs.c b/stage2/isfs/isfs.c index 0430d4b..5af9d58 100644 --- a/stage2/isfs/isfs.c +++ b/stage2/isfs/isfs.c @@ -14,7 +14,6 @@ #include #include #include -#include #include "nand.h" #include "isfs/isfs.h" @@ -34,9 +33,6 @@ int isfs_init(void) ctx = isfs_get_volume(ISFSVOL_SLC); ctx->mounted = !isfs_load_super(ctx, 0, ISFSHAX_GENERATION_FIRST); - /*ctx = isfs_get_volume(ISFSVOL_SLCCMPT); - ctx->mounted = !isfs_load_super(ctx, 0, 0xffffffff);*/ - initialized = true; return 0; } @@ -146,20 +142,14 @@ int isfs_read(isfs_file* file, void* buffer, size_t size, size_t* bytes_read) size_t total = size; - void* cluster_buf = memalign(64, CLUSTER_SIZE); - if(!cluster_buf) return -3; - while(size) { size_t pos = file->offset % CLUSTER_SIZE; size_t copy = CLUSTER_SIZE - pos; if(copy > size) copy = size; - if (isfs_read_volume(ctx, file->cluster, 1, ISFSVOL_FLAG_ENCRYPTED, NULL, cluster_buf) < 0) - { - free(cluster_buf); + if (isfs_read_volume(ctx, file->cluster, 1, ISFSVOL_FLAG_ENCRYPTED, NULL, ctx->clbuf) < 0) return -4; - } - memcpy(buffer, cluster_buf + pos, copy); + memcpy(buffer, ctx->clbuf + pos, copy); file->offset += copy; buffer += copy; @@ -169,8 +159,6 @@ int isfs_read(isfs_file* file, void* buffer, size_t size, size_t* bytes_read) file->cluster = isfs_get_fat(ctx)[file->cluster]; } - free(cluster_buf); - *bytes_read = total; return 0; } diff --git a/stage2/isfs/isfs.h b/stage2/isfs/isfs.h index 6c5d241..7b27117 100644 --- a/stage2/isfs/isfs.h +++ b/stage2/isfs/isfs.h @@ -23,6 +23,7 @@ typedef struct isfs_ctx { const u32 super_count; int index; u8* const super; + u8* const clbuf; u32 generation; u32 version; bool mounted; diff --git a/stage2/isfs/super.c b/stage2/isfs/super.c index 33ef01e..ec5e783 100644 --- a/stage2/isfs/super.c +++ b/stage2/isfs/super.c @@ -14,7 +14,6 @@ #include #include #include -#include #include "debug.h" #include "isfs/isfs.h" @@ -171,9 +170,6 @@ int isfs_write_super(isfs_ctx *ctx, void *super, int index) int isfs_find_super(isfs_ctx* ctx, u32 min_generation, u32 max_generation, u32 *generation, u32 *version) { - void* super = memalign(64, CLUSTER_SIZE); - if(!super) return -1; - struct { int index; u32 generation; @@ -184,13 +180,13 @@ int isfs_find_super(isfs_ctx* ctx, u32 min_generation, u32 max_generation, u32 * { u32 cluster = CLUSTER_COUNT - (ctx->super_count - i) * ISFSSUPER_CLUSTERS; - if(isfs_read_volume(ctx, cluster, 1, 0, NULL, super)) + if(isfs_read_volume(ctx, cluster, 1, 0, NULL, ctx->clbuf)) continue; - int cur_version = isfs_get_super_version(super); + int cur_version = isfs_get_super_version(ctx->clbuf); if(cur_version < 0) continue; - u32 cur_generation = isfs_get_super_generation(super); + u32 cur_generation = isfs_get_super_generation(ctx->clbuf); if((cur_generation < newest.generation) || (cur_generation < min_generation) || (cur_generation >= max_generation)) @@ -201,8 +197,6 @@ int isfs_find_super(isfs_ctx* ctx, u32 min_generation, u32 max_generation, u32 * newest.version = cur_version; } - free(super); - if(newest.index == -1) { ISFS_debug("Failed to find super block.\n"); @@ -248,4 +242,3 @@ int isfs_commit_super(isfs_ctx* ctx) return -1; } - diff --git a/stage2/isfs/super.h b/stage2/isfs/super.h index e321e2d..5575281 100644 --- a/stage2/isfs/super.h +++ b/stage2/isfs/super.h @@ -31,7 +31,7 @@ typedef struct isfs_super { u16 fat[CLUSTER_COUNT]; isfs_fst fst[6143]; u8 pad[20]; -} PACKED ALIGNED(64) isfs_super; +} PACKED ALIGNED(NAND_DATA_ALIGN) isfs_super; _Static_assert(sizeof(isfs_super) == ISFSSUPER_SIZE, "isfs_super must be 0x40000"); #define FAT_CLUSTER_LAST 0xFFFB // last cluster within a chain diff --git a/stage2/isfs/volume.c b/stage2/isfs/volume.c index 686991a..455e6a1 100644 --- a/stage2/isfs/volume.c +++ b/stage2/isfs/volume.c @@ -8,10 +8,9 @@ #include "hmac.h" #include "string.h" -static u8 slc_super_buf[ISFSSUPER_SIZE]; -/*static u8 slccmpt_super_buf[ISFSSUPER_SIZE];*/ +static u8 slc_super_buf[ISFSSUPER_SIZE] ALIGNED(NAND_DATA_ALIGN), slc_cluster_buf[CLUSTER_SIZE] ALIGNED(NAND_DATA_ALIGN); -isfs_ctx isfs[4] = { +isfs_ctx isfs[] = { [ISFSVOL_SLC] { .volume = ISFSVOL_SLC, @@ -21,22 +20,13 @@ isfs_ctx isfs[4] = { .hmac = &otp.nand_hmac, .super_count = 64, .super = slc_super_buf, + .clbuf = slc_cluster_buf, }, - /*[ISFSVOL_SLCCMPT] - { - .volume = ISFSVOL_SLCCMPT, - .name = "slccmpt", - .bank = BANK_SLCCMPT, - .key = &otp.wii_nand_key, - .hmac = &otp.wii_nand_hmac, - .super_count = 16, - .super = slccmpt_super_buf, - },*/ }; int isfs_num_volumes(void) { - return sizeof(isfs) / sizeof(isfs_ctx); + return sizeof(isfs) / sizeof(*isfs); } isfs_ctx* isfs_get_volume(int volume) @@ -155,8 +145,8 @@ int isfs_read_volume(const isfs_ctx* ctx, u32 start_cluster, u32 cluster_count, int isfs_write_volume(const isfs_ctx* ctx, u32 start_cluster, u32 cluster_count, u32 flags, void *hmac_seed, void *data) { - static u8 blockpg[64][PAGE_SIZE] ALIGNED(64), blocksp[64][SPARE_SIZE]; - static u8 pgbuf[PAGE_SIZE] ALIGNED(64), spbuf[SPARE_SIZE]; + static u8 blockpg[64][PAGE_SIZE] ALIGNED(NAND_DATA_ALIGN), blocksp[64][SPARE_SIZE]; + static u8 pgbuf[PAGE_SIZE] ALIGNED(NAND_DATA_ALIGN), spbuf[SPARE_SIZE]; u8 hmac[20] = {0}; int rc = ISFSVOL_OK; u32 b, p; diff --git a/stage2/main.c b/stage2/main.c index 9679753..7cc9241 100644 --- a/stage2/main.c +++ b/stage2/main.c @@ -84,7 +84,7 @@ u32 load_payload_nand(void) if (res) return vector; - res = isfs_open(&file, "slc:/isfshax.bin"); + res = isfs_open(&file, "slc:/sys/isfshax.bin"); if (res) goto error_open; diff --git a/stage2/nand.c b/stage2/nand.c index 0a7312a..8544717 100644 --- a/stage2/nand.c +++ b/stage2/nand.c @@ -66,9 +66,9 @@ #define BANK_FL_4 (0x00000004) /* set by bsp:fla for revisions after latte A2X */ #if NAND_WRITE_ENABLED -static u8 nand_status_buf[STATUS_BUF_SIZE] ALIGNED(256); +static u8 nand_status_buf[STATUS_BUF_SIZE] ALIGNED(NAND_DATA_ALIGN); #endif -static u8 nand_spare_buf[SPARE_BUF_SIZE] ALIGNED(256); +static u8 nand_spare_buf[SPARE_BUF_SIZE] ALIGNED(NAND_DATA_ALIGN); static u32 nand_enabled_banks = BANK_SLC; @@ -193,7 +193,7 @@ int nand_write_page(u32 pageno, void *data, void *spare) if (pageno > PAGE_COUNT) { return nand_error("invalid page number"); } - if ((u32)data & 0x1f) { + if ((u32)data & (NAND_DATA_ALIGN - 1)) { return nand_error("unaligned page buffer"); } @@ -342,7 +342,7 @@ int nand_read_page(u32 pageno, void *data, void *spare) if (pageno > PAGE_COUNT) { return nand_error("invalid page number"); } - if ((u32)data & 0x1f) { + if ((u32)data & (NAND_DATA_ALIGN - 1)) { return nand_error("unaligned page buffer"); } diff --git a/stage2/nand.h b/stage2/nand.h index df542b4..ef919c2 100644 --- a/stage2/nand.h +++ b/stage2/nand.h @@ -19,6 +19,8 @@ #define NAND_WRITE_ENABLED 1 +#define NAND_DATA_ALIGN 128 + /* nand structure definitions */ #define PAGE_SIZE 0x800 #define PAGE_COUNT 0x40000