Fix slc payload loading

Align isfs buffers, remove the need for heap
This commit is contained in:
rw-r-r-0644 2021-06-01 12:36:01 +02:00
parent b16cca5a8c
commit 239a7607c8
8 changed files with 20 additions and 46 deletions

View File

@ -14,7 +14,6 @@
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <malloc.h>
#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;
}

View File

@ -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;

View File

@ -14,7 +14,6 @@
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <malloc.h>
#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;
}

View File

@ -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

View File

@ -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;

View File

@ -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;

View File

@ -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");
}

View File

@ -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