No longer saves more than the ROM size, cleanup
Using some header information from rom_tool, it was possible to implement something that will accurately determine the real ROM size. With that information, uncart no longer dumps in 2GB chunks, but to the actual size of ROM (all 8 partitions). Warnings were cleaned up as much as possible for now (2 remain). i2c support was added in order to be able to shut down uncart when it is over (it isn't clear that the ASM in start.s is right for returning control to brahma, if that's even possible). More warnings were enabled in the Makefile, and lto was enabled. Currently, the Makefile and the draw.h are configured for a9lh support.
This commit is contained in:
parent
13a9ad8ec5
commit
913bc867b7
11
Makefile
11
Makefile
@ -31,17 +31,18 @@ INCLUDES := source
|
||||
#---------------------------------------------------------------------------------
|
||||
ARCH := -march=armv5te -mtune=arm946e-s -mthumb -mthumb-interwork
|
||||
|
||||
CFLAGS := -g -Wall -O2\
|
||||
CFLAGS := -g -Wall -Wextra -Wpedantic -O2 -flto\
|
||||
-fomit-frame-pointer\
|
||||
-ffast-math -std=c99\
|
||||
-ffast-math -std=c11\
|
||||
$(ARCH)
|
||||
|
||||
CFLAGS += $(INCLUDE) -DARM9 -Werror-implicit-function-declaration
|
||||
CFLAGS += $(INCLUDE) -DARM9 -Werror-implicit-function-declaration -Wcast-align -Wcast-qual -Wdisabled-optimization -Wformat=2 -Winit-self -Wlogical-op -Wmissing-declarations -Wmissing-include-dirs -Wredundant-decls -Wshadow -Wsign-conversion -Wstrict-overflow=5 -Wswitch-default -Wundef -Wno-unused
|
||||
|
||||
CXXFLAGS := $(CFLAGS) -fno-rtti -fno-exceptions
|
||||
|
||||
ASFLAGS := -g $(ARCH)
|
||||
LDFLAGS = -nostartfiles -g --specs=../stub.specs $(ARCH) -Wl,-Map,$(TARGET).map
|
||||
OCFLAGS=--set-section-flags .bss=alloc,load,contents
|
||||
|
||||
LIBS :=
|
||||
|
||||
@ -101,7 +102,7 @@ all: $(BUILD)
|
||||
$(BUILD):
|
||||
@[ -d $@ ] || mkdir -p $@
|
||||
@make --no-print-directory -C $(BUILD) -f $(CURDIR)/Makefile
|
||||
cp $(OUTPUT).bin arm9payload.bin
|
||||
cp $(OUTPUT).bin arm9loaderhax.bin
|
||||
|
||||
#---------------------------------------------------------------------------------
|
||||
clean:
|
||||
@ -123,7 +124,7 @@ $(OUTPUT).elf : $(OFILES)
|
||||
|
||||
#---------------------------------------------------------------------------------
|
||||
%.bin: %.elf
|
||||
@$(OBJCOPY) -O binary $< $@
|
||||
@$(OBJCOPY) $(OCFLAGS) -O binary $< $@
|
||||
@echo built ... $(notdir $@)
|
||||
|
||||
|
||||
|
48
source/aes.h
48
source/aes.h
@ -26,29 +26,29 @@
|
||||
|
||||
#define AES_WRITE_FIFO_COUNT ((REG_AESCNT>>0) & 0x1F)
|
||||
#define AES_READ_FIFO_COUNT ((REG_AESCNT>>5) & 0x1F)
|
||||
#define AES_BUSY (1<<31)
|
||||
#define AES_BUSY (1u<<31)
|
||||
|
||||
#define AES_FLUSH_READ_FIFO (1<<10)
|
||||
#define AES_FLUSH_WRITE_FIFO (1<<11)
|
||||
#define AES_BIT12 (1<<12)
|
||||
#define AES_BIT13 (1<<13)
|
||||
#define AES_MAC_SIZE(n) ((n&7)<<16)
|
||||
#define AES_MAC_REGISTER_SOURCE (1<<20)
|
||||
#define AES_UNKNOWN_21 (1<<21)
|
||||
#define AES_OUTPUT_BIG_ENDIAN (1<<22)
|
||||
#define AES_INPUT_BIG_ENDIAN (1<<23)
|
||||
#define AES_OUTPUT_NORMAL_ORDER (1<<24)
|
||||
#define AES_INPUT_NORMAL_ORDER (1<<25)
|
||||
#define AES_UNKNOWN_26 (1<<26)
|
||||
#define AES_MODE(n) ((n&7)<<27)
|
||||
#define AES_INTERRUPT_ENABLE (1<<30)
|
||||
#define AES_ENABLE (1<<31)
|
||||
#define AES_FLUSH_READ_FIFO (1u<<10)
|
||||
#define AES_FLUSH_WRITE_FIFO (1u<<11)
|
||||
#define AES_BIT12 (1u<<12)
|
||||
#define AES_BIT13 (1u<<13)
|
||||
#define AES_MAC_SIZE(n) ((n&7u)<<16)
|
||||
#define AES_MAC_REGISTER_SOURCE (1u<<20)
|
||||
#define AES_UNKNOWN_21 (1u<<21)
|
||||
#define AES_OUTPUT_BIG_ENDIAN (1u<<22)
|
||||
#define AES_INPUT_BIG_ENDIAN (1u<<23)
|
||||
#define AES_OUTPUT_NORMAL_ORDER (1u<<24)
|
||||
#define AES_INPUT_NORMAL_ORDER (1u<<25)
|
||||
#define AES_UNKNOWN_26 (1u<<26)
|
||||
#define AES_MODE(n) ((n&7u)<<27)
|
||||
#define AES_INTERRUPT_ENABLE (1u<<30)
|
||||
#define AES_ENABLE (1u<<31)
|
||||
|
||||
#define AES_MODE_CCM_DECRYPT 0
|
||||
#define AES_MODE_CCM_ENCRYPT 1
|
||||
#define AES_MODE_CTR 2
|
||||
#define AES_MODE_UNK3 3
|
||||
#define AES_MODE_CBC_DECRYPT 4
|
||||
#define AES_MODE_CBC_ENCRYPT 5
|
||||
#define AES_MODE_UNK6 6
|
||||
#define AES_MODE_UNK7 7
|
||||
#define AES_MODE_CCM_DECRYPT 0u
|
||||
#define AES_MODE_CCM_ENCRYPT 1u
|
||||
#define AES_MODE_CTR 2u
|
||||
#define AES_MODE_UNK3 3u
|
||||
#define AES_MODE_CBC_DECRYPT 4u
|
||||
#define AES_MODE_CBC_ENCRYPT 5u
|
||||
#define AES_MODE_UNK6 6u
|
||||
#define AES_MODE_UNK7 7u
|
||||
|
@ -10,7 +10,7 @@
|
||||
#include "font.h"
|
||||
#include "draw.h"
|
||||
|
||||
int current_y = 0;
|
||||
size_t current_y = 0;
|
||||
|
||||
void ClearScreen(unsigned char *screen, int color)
|
||||
{
|
||||
@ -23,16 +23,15 @@ void ClearScreen(unsigned char *screen, int color)
|
||||
}
|
||||
}
|
||||
|
||||
void DrawCharacter(unsigned char *screen, int character, int x, int y, int color, int bgcolor)
|
||||
void DrawCharacter(unsigned char *screen, int character, size_t x, size_t y, int color, int bgcolor)
|
||||
{
|
||||
int yy, xx;
|
||||
for (yy = 0; yy < 8; yy++) {
|
||||
int xDisplacement = (x * BYTES_PER_PIXEL * SCREEN_WIDTH);
|
||||
int yDisplacement = ((SCREEN_WIDTH - (y + yy) - 1) * BYTES_PER_PIXEL);
|
||||
unsigned char *screenPos = screen + xDisplacement + yDisplacement;
|
||||
for (size_t yy = 0; yy < 8; yy++) {
|
||||
size_t xDisplacement = (x * BYTES_PER_PIXEL * SCREEN_WIDTH);
|
||||
size_t yDisplacement = ((SCREEN_WIDTH - (y + yy) - 1) * BYTES_PER_PIXEL);
|
||||
|
||||
unsigned char charPos = font[character * 8 + yy];
|
||||
for (xx = 7; xx >= 0; xx--) {
|
||||
unsigned char *screenPos = screen + xDisplacement + yDisplacement;
|
||||
unsigned char charPos = font[(size_t)character * 8 + yy];
|
||||
for (int xx = 7; xx >= 0; xx--) {
|
||||
if ((charPos >> xx) & 1) {
|
||||
*(screenPos + 0) = color >> 16; // B
|
||||
*(screenPos + 1) = color >> 8; // G
|
||||
@ -47,7 +46,7 @@ void DrawCharacter(unsigned char *screen, int character, int x, int y, int color
|
||||
}
|
||||
}
|
||||
|
||||
void DrawString(unsigned char *screen, const char *str, int x, int y, int color, int bgcolor)
|
||||
void DrawString(unsigned char *screen, const char *str, size_t x, size_t y, int color, int bgcolor)
|
||||
{
|
||||
const size_t string_len = strlen(str);
|
||||
|
||||
@ -55,7 +54,7 @@ void DrawString(unsigned char *screen, const char *str, int x, int y, int color,
|
||||
DrawCharacter(screen, str[i], x + i * 8, y, color, bgcolor);
|
||||
}
|
||||
|
||||
void DrawStringF(int x, int y, const char *format, ...)
|
||||
void DrawStringF(size_t x, size_t y, const char *format, ...)
|
||||
{
|
||||
char str[256];
|
||||
va_list va;
|
||||
@ -70,7 +69,7 @@ void DrawStringF(int x, int y, const char *format, ...)
|
||||
|
||||
void Debug(const char *format, ...)
|
||||
{
|
||||
char str[50];
|
||||
char str[51];
|
||||
const char* spaces = " X";
|
||||
va_list va;
|
||||
|
||||
@ -79,10 +78,10 @@ void Debug(const char *format, ...)
|
||||
va_end(va);
|
||||
snprintf(str, sizeof(str), "%s%s", str, spaces);
|
||||
|
||||
DrawString(TOP_SCREEN0, str, 10, current_y, RGB(255, 0, 0), RGB(255, 255, 255));
|
||||
DrawString(TOP_SCREEN0, spaces, 10, current_y + 10, RGB(255, 0, 0), RGB(255, 255, 255));
|
||||
DrawString(TOP_SCREEN1, str, 10, current_y, RGB(255, 0, 0), RGB(255, 255, 255));
|
||||
DrawString(TOP_SCREEN1, spaces, 10, current_y + 10, RGB(255, 0, 0), RGB(255, 255, 255));
|
||||
DrawString(TOP_SCREEN0, str, 0u, current_y, RGB(255, 0, 0), RGB(255, 255, 255));
|
||||
DrawString(TOP_SCREEN0, spaces, 0u, current_y + 10, RGB(255, 0, 0), RGB(255, 255, 255));
|
||||
DrawString(TOP_SCREEN1, str, 0u, current_y, RGB(255, 0, 0), RGB(255, 255, 255));
|
||||
DrawString(TOP_SCREEN1, spaces, 0u, current_y + 10, RGB(255, 0, 0), RGB(255, 255, 255));
|
||||
|
||||
current_y += 10;
|
||||
if (current_y >= 240) {
|
||||
|
@ -14,17 +14,22 @@
|
||||
|
||||
#define RGB(r,g,b) (r<<24|b<<16|g<<8|r)
|
||||
|
||||
#define TOP_SCREEN0 (u8*)(0x20000000)
|
||||
#define TOP_SCREEN1 (u8*)(0x20046500)
|
||||
#define BOT_SCREEN0 (u8*)(0x2008CA00)
|
||||
#define BOT_SCREEN1 (u8*)(0x200C4E00)
|
||||
extern int current_y;
|
||||
//#define TOP_SCREEN0 (u8*)(0x20000000)
|
||||
//#define TOP_SCREEN1 (u8*)(0x20046500)
|
||||
//#define BOT_SCREEN0 (u8*)(0x2008CA00)
|
||||
//#define BOT_SCREEN1 (u8*)(0x200C4E00)
|
||||
|
||||
#define TOP_SCREEN0 (u8*)(0x18300000)
|
||||
#define TOP_SCREEN1 (u8*)(0x18300000)
|
||||
#define BOT_SCREEN0 (u8*)(0x18346500)
|
||||
#define BOT_SCREEN1 (u8*)(0x18346500)
|
||||
extern size_t current_y;
|
||||
|
||||
void ClearScreen(unsigned char *screen, int color);
|
||||
void DrawCharacter(unsigned char *screen, int character, int x, int y, int color, int bgcolor);
|
||||
void DrawHex(unsigned char *screen, unsigned int hex, int x, int y, int color, int bgcolor);
|
||||
void DrawString(unsigned char *screen, const char *str, int x, int y, int color, int bgcolor);
|
||||
void DrawStringF(int x, int y, const char *format, ...);
|
||||
void DrawHexWithName(unsigned char *screen, const char *str, unsigned int hex, int x, int y, int color, int bgcolor);
|
||||
void DrawCharacter(unsigned char *screen, int character, size_t x, size_t y, int color, int bgcolor);
|
||||
void DrawHex(unsigned char *screen, unsigned int hex, size_t x, size_t y, int color, int bgcolor);
|
||||
void DrawString(unsigned char *screen, const char *str, size_t x, size_t y, int color, int bgcolor);
|
||||
void DrawStringF(size_t x, size_t y, const char *format, ...);
|
||||
void DrawHexWithName(unsigned char *screen, const char *str, unsigned int hex, size_t x, size_t y, int color, int bgcolor);
|
||||
|
||||
void Debug(const char *format, ...);
|
||||
|
@ -139,8 +139,8 @@ const unsigned short Tbl[] = { /* CP437(0x80-0xFF) to Unicode conversion table
|
||||
};
|
||||
|
||||
DWORD get_fattime (void) {
|
||||
//NO
|
||||
return 0;
|
||||
// fixed valid time of 1980-01-01 00:00:00
|
||||
return 0x210000;
|
||||
}
|
||||
|
||||
WCHAR ff_convert ( /* Converted character, Returns zero on error */
|
||||
@ -908,7 +908,7 @@ FRESULT sync_fs ( /* FR_OK: successful, FR_DISK_ERR: failed */
|
||||
/*-----------------------------------------------------------------------*/
|
||||
|
||||
|
||||
DWORD clust2sect ( /* !=0: Sector number, 0: Failed - invalid cluster# */
|
||||
static DWORD clust2sect ( /* !=0: Sector number, 0: Failed - invalid cluster# */
|
||||
FATFS* fs, /* File system object */
|
||||
DWORD clst /* Cluster# to be converted */
|
||||
)
|
||||
@ -926,7 +926,7 @@ DWORD clust2sect ( /* !=0: Sector number, 0: Failed - invalid cluster# */
|
||||
/*-----------------------------------------------------------------------*/
|
||||
|
||||
|
||||
DWORD get_fat ( /* 0xFFFFFFFF:Disk error, 1:Internal error, Else:Cluster status */
|
||||
static DWORD get_fat ( /* 0xFFFFFFFF:Disk error, 1:Internal error, Else:Cluster status */
|
||||
FATFS* fs, /* File system object */
|
||||
DWORD clst /* Cluster# to get the link information */
|
||||
)
|
||||
@ -946,7 +946,7 @@ DWORD get_fat ( /* 0xFFFFFFFF:Disk error, 1:Internal error, Else:Cluster status
|
||||
wc = fs->win[bc % SS(fs)];
|
||||
bc++;
|
||||
if (move_window(fs, fs->fatbase + (bc / SS(fs)))) break;
|
||||
wc |= fs->win[bc % SS(fs)] << 8;
|
||||
wc |= (UINT)fs->win[bc % SS(fs)] << 8;
|
||||
return clst & 1 ? wc >> 4 : (wc & 0xFFF);
|
||||
|
||||
case FS_FAT16 :
|
||||
@ -974,7 +974,7 @@ DWORD get_fat ( /* 0xFFFFFFFF:Disk error, 1:Internal error, Else:Cluster status
|
||||
/*-----------------------------------------------------------------------*/
|
||||
#if !_FS_READONLY
|
||||
|
||||
FRESULT put_fat (
|
||||
static FRESULT put_fat (
|
||||
FATFS* fs, /* File system object */
|
||||
DWORD clst, /* Cluster# to be changed in range of 2 to fs->n_fatent - 1 */
|
||||
DWORD val /* New value to mark the cluster */
|
||||
@ -1245,7 +1245,7 @@ FRESULT dir_next ( /* FR_OK:Succeeded, FR_NO_FILE:End of table, FR_DENIED:Could
|
||||
UINT i;
|
||||
|
||||
|
||||
i = dp->index + 1;
|
||||
i = dp->index + 1u;
|
||||
if (!(i & 0xFFFF) || !dp->sect) /* Report EOT when index has reached 65535 */
|
||||
return FR_NO_FILE;
|
||||
|
||||
@ -1257,7 +1257,7 @@ FRESULT dir_next ( /* FR_OK:Succeeded, FR_NO_FILE:End of table, FR_DENIED:Could
|
||||
return FR_NO_FILE;
|
||||
}
|
||||
else { /* Dynamic table */
|
||||
if (((i / (SS(dp->fs) / SZ_DIR)) & (dp->fs->csize - 1)) == 0) { /* Cluster changed? */
|
||||
if (((i / (SS(dp->fs) / SZ_DIR)) & (dp->fs->csize - 1u)) == 0) { /* Cluster changed? */
|
||||
clst = get_fat(dp->fs, dp->clust); /* Get next cluster */
|
||||
if (clst <= 1) return FR_INT_ERR;
|
||||
if (clst == 0xFFFFFFFF) return FR_DISK_ERR;
|
||||
@ -1389,7 +1389,7 @@ int cmp_lfn ( /* 1:Matched, 0:Not matched */
|
||||
WCHAR wc, uc;
|
||||
|
||||
|
||||
i = ((dir[LDIR_Ord] & ~LLE) - 1) * 13; /* Get offset in the LFN buffer */
|
||||
i = ((UINT)(dir[LDIR_Ord] & ~LLE) - 1u) * 13u; /* Get offset in the LFN buffer */
|
||||
s = 0;
|
||||
wc = 1;
|
||||
do {
|
||||
@ -1421,7 +1421,7 @@ int pick_lfn ( /* 1:Succeeded, 0:Buffer overflow */
|
||||
WCHAR wc, uc;
|
||||
|
||||
|
||||
i = ((dir[LDIR_Ord] & 0x3F) - 1) * 13; /* Offset in the LFN buffer */
|
||||
i = ((dir[LDIR_Ord] & 0x3F) - 1u) * 13u; /* Offset in the LFN buffer */
|
||||
|
||||
s = 0;
|
||||
wc = 1;
|
||||
@ -1462,7 +1462,7 @@ void fit_lfn (
|
||||
dir[LDIR_Type] = 0;
|
||||
ST_WORD(dir+LDIR_FstClusLO, 0);
|
||||
|
||||
i = (ord - 1) * 13; /* Get offset in the LFN buffer */
|
||||
i = (ord - 1u) * 13u; /* Get offset in the LFN buffer */
|
||||
s = wc = 0;
|
||||
do {
|
||||
if (wc != 0xFFFF) wc = lfnbuf[i++]; /* Get an effective character */
|
||||
@ -2200,7 +2200,7 @@ int get_ldnumber ( /* Returns logical drive number (-1:invalid drive) */
|
||||
for (tt = *path; (UINT)*tt >= (_USE_LFN ? ' ' : '!') && *tt != ':'; tt++) ; /* Find ':' in the path */
|
||||
if (*tt == ':') { /* If a ':' is exist in the path name */
|
||||
tp = *path;
|
||||
i = *tp++ - '0';
|
||||
i = (UINT)(*tp++ - '0');
|
||||
if (i < 10 && tp == tt) { /* Is there a numeric drive id? */
|
||||
if (i < _VOLUMES) { /* If a drive id is found, get the value and strip it */
|
||||
vol = (int)i;
|
||||
@ -2696,7 +2696,7 @@ FRESULT f_read (
|
||||
for ( ; btr; /* Repeat until all data read */
|
||||
rbuff += rcnt, fp->fptr += rcnt, *br += rcnt, btr -= rcnt) {
|
||||
if ((fp->fptr % SS(fp->fs)) == 0) { /* On the sector boundary? */
|
||||
csect = (BYTE)(fp->fptr / SS(fp->fs) & (fp->fs->csize - 1)); /* Sector offset in the cluster */
|
||||
csect = (BYTE)(fp->fptr / SS(fp->fs) & (fp->fs->csize - 1u)); /* Sector offset in the cluster */
|
||||
if (!csect) { /* On the cluster boundary? */
|
||||
if (fp->fptr == 0) { /* On the top of the file? */
|
||||
clst = fp->sclust; /* Follow from the origin */
|
||||
@ -2718,7 +2718,7 @@ FRESULT f_read (
|
||||
cc = btr / SS(fp->fs); /* When remaining bytes >= sector size, */
|
||||
if (cc) { /* Read maximum contiguous sectors directly */
|
||||
if (csect + cc > fp->fs->csize) /* Clip at cluster boundary */
|
||||
cc = fp->fs->csize - csect;
|
||||
cc = (UINT)fp->fs->csize - csect;
|
||||
if (disk_read(fp->fs->drv, rbuff, sect, cc))
|
||||
ABORT(fp->fs, FR_DISK_ERR);
|
||||
#if !_FS_READONLY && _FS_MINIMIZE <= 2 /* Replace one of the read sectors with cached data if it contains a dirty sector */
|
||||
@ -2797,7 +2797,7 @@ FRESULT f_write (
|
||||
for ( ; btw; /* Repeat until all data written */
|
||||
wbuff += wcnt, fp->fptr += wcnt, *bw += wcnt, btw -= wcnt) {
|
||||
if ((fp->fptr % SS(fp->fs)) == 0) { /* On the sector boundary? */
|
||||
csect = (BYTE)(fp->fptr / SS(fp->fs) & (fp->fs->csize - 1)); /* Sector offset in the cluster */
|
||||
csect = (BYTE)(fp->fptr / SS(fp->fs) & (fp->fs->csize - 1u)); /* Sector offset in the cluster */
|
||||
if (!csect) { /* On the cluster boundary? */
|
||||
if (fp->fptr == 0) { /* On the top of the file? */
|
||||
clst = fp->sclust; /* Follow from the origin */
|
||||
@ -2832,7 +2832,7 @@ FRESULT f_write (
|
||||
cc = btw / SS(fp->fs); /* When remaining bytes >= sector size, */
|
||||
if (cc) { /* Write maximum contiguous sectors directly */
|
||||
if (csect + cc > fp->fs->csize) /* Clip at cluster boundary */
|
||||
cc = fp->fs->csize - csect;
|
||||
cc = (UINT)fp->fs->csize - csect;
|
||||
if (disk_write(fp->fs->drv, wbuff, sect, cc))
|
||||
ABORT(fp->fs, FR_DISK_ERR);
|
||||
#if _FS_MINIMIZE <= 2
|
||||
|
@ -330,7 +330,7 @@ int ff_del_syncobj (_SYNC_t sobj); /* Delete a sync object */
|
||||
#define ST_DWORD(ptr,val) *(DWORD*)(BYTE*)(ptr)=(DWORD)(val)
|
||||
#else /* Use byte-by-byte access to the FAT structure */
|
||||
#define LD_WORD(ptr) (WORD)(((WORD)*((BYTE*)(ptr)+1)<<8)|(WORD)*(BYTE*)(ptr))
|
||||
#define LD_DWORD(ptr) (DWORD)(((DWORD)*((BYTE*)(ptr)+3)<<24)|((DWORD)*((BYTE*)(ptr)+2)<<16)|((WORD)*((BYTE*)(ptr)+1)<<8)|*(BYTE*)(ptr))
|
||||
#define LD_DWORD(ptr) (DWORD)(((DWORD)*((BYTE*)(ptr)+3)<<24)|((DWORD)*((BYTE*)(ptr)+2)<<16)|(DWORD)((WORD)*((BYTE*)(ptr)+1)<<8)|*(BYTE*)(ptr))
|
||||
#define ST_WORD(ptr,val) *(BYTE*)(ptr)=(BYTE)(val); *((BYTE*)(ptr)+1)=(BYTE)((WORD)(val)>>8)
|
||||
#define ST_DWORD(ptr,val) *(BYTE*)(ptr)=(BYTE)(val); *((BYTE*)(ptr)+1)=(BYTE)((WORD)(val)>>8); *((BYTE*)(ptr)+2)=(BYTE)((DWORD)(val)>>16); *((BYTE*)(ptr)+3)=(BYTE)((DWORD)(val)>>24)
|
||||
#endif
|
||||
|
@ -20,15 +20,15 @@ mmcdevice *getMMCDevice(int drive)
|
||||
return &handleSD;
|
||||
}
|
||||
|
||||
int __attribute__((noinline)) geterror(struct mmcdevice *ctx)
|
||||
static int __attribute__((noinline)) geterror(struct mmcdevice *ctx)
|
||||
{
|
||||
//if(ctx->error == 0x4) return -1;
|
||||
//else return 0;
|
||||
return (ctx->error << 29) >> 31;
|
||||
return (int)((ctx->error << 29) >> 31);
|
||||
}
|
||||
|
||||
|
||||
void __attribute__((noinline)) inittarget(struct mmcdevice *ctx)
|
||||
static void __attribute__((noinline)) inittarget(struct mmcdevice *ctx)
|
||||
{
|
||||
sdmmc_mask16(REG_SDPORTSEL,0x3,(u16)ctx->devicenumber);
|
||||
setckl(ctx->clk);
|
||||
@ -41,7 +41,7 @@ void __attribute__((noinline)) inittarget(struct mmcdevice *ctx)
|
||||
}
|
||||
|
||||
|
||||
void __attribute__((noinline)) sdmmc_send_command(struct mmcdevice *ctx, u32 cmd, u32 args)
|
||||
static void __attribute__((noinline)) sdmmc_send_command(struct mmcdevice *ctx, u32 cmd, u32 args)
|
||||
{
|
||||
bool getSDRESP = (cmd << 15) >> 31;
|
||||
u16 flags = (cmd << 15) >> 31;
|
||||
@ -72,8 +72,7 @@ void __attribute__((noinline)) sdmmc_send_command(struct mmcdevice *ctx, u32 cmd
|
||||
sdmmc_write16(REG_SDCMD,cmd &0xFFFF);
|
||||
|
||||
u32 size = ctx->size;
|
||||
u16 *dataPtr = (u16*)ctx->data;
|
||||
u32 *dataPtr32 = (u32*)ctx->data;
|
||||
u8 *dataPtr = ctx->data;
|
||||
|
||||
bool useBuf = ( NULL != dataPtr );
|
||||
bool useBuf32 = (useBuf && (0 == (3 & ((u32)dataPtr))));
|
||||
@ -88,12 +87,20 @@ void __attribute__((noinline)) sdmmc_send_command(struct mmcdevice *ctx, u32 cmd
|
||||
if (size > 0x1FF) {
|
||||
#ifdef DATA32_SUPPORT
|
||||
if (useBuf32) {
|
||||
for(int i = 0; i<0x200; i+=4)
|
||||
*dataPtr32++ = sdmmc_read32(REG_SDFIFO32);
|
||||
for(int i = 0; i<0x200; i+=4) {
|
||||
u32 data = sdmmc_read32(REG_SDFIFO32);
|
||||
*dataPtr++ = data;
|
||||
*dataPtr++ = data >> 8;
|
||||
*dataPtr++ = data >> 16;
|
||||
*dataPtr++ = data >> 24;
|
||||
}
|
||||
} else {
|
||||
#endif
|
||||
for(int i = 0; i<0x200; i+=2)
|
||||
*dataPtr++ = sdmmc_read16(REG_SDFIFO);
|
||||
for(int i = 0; i<0x200; i+=2) {
|
||||
u16 data = sdmmc_read16(REG_SDFIFO);
|
||||
*dataPtr++ = data;
|
||||
*dataPtr++ = data >> 8;
|
||||
}
|
||||
#ifdef DATA32_SUPPORT
|
||||
}
|
||||
#endif
|
||||
@ -108,11 +115,20 @@ void __attribute__((noinline)) sdmmc_send_command(struct mmcdevice *ctx, u32 cmd
|
||||
//sdmmc_write16(REG_SDSTATUS1,~TMIO_STAT1_TXRQ);
|
||||
if (size > 0x1FF) {
|
||||
#ifdef DATA32_SUPPORT
|
||||
for (int i = 0; i<0x200; i+=4)
|
||||
sdmmc_write32(REG_SDFIFO32,*dataPtr32++);
|
||||
for (int i = 0; i<0x200; i+=4) {
|
||||
u32 data = *dataPtr++;
|
||||
data |= *dataPtr++ << 8;
|
||||
data |= *dataPtr++ << 16;
|
||||
data |= *dataPtr++ << 24;
|
||||
sdmmc_write32(REG_SDFIFO32,data);
|
||||
}
|
||||
#else
|
||||
for (int i = 0; i<0x200; i+=2)
|
||||
sdmmc_write16(REG_SDFIFO,*dataPtr++);
|
||||
for (int i = 0; i<0x200; i+=2) {
|
||||
u16 data = *dataPtr++;
|
||||
data |= *dataPtr++ << 8;
|
||||
sdmmc_write16(REG_SDFIFO,data);
|
||||
|
||||
}
|
||||
#endif
|
||||
size -= 0x200;
|
||||
}
|
||||
@ -140,14 +156,14 @@ void __attribute__((noinline)) sdmmc_send_command(struct mmcdevice *ctx, u32 cmd
|
||||
sdmmc_write16(REG_SDSTATUS1,0);
|
||||
|
||||
if (getSDRESP != 0) {
|
||||
ctx->ret[0] = sdmmc_read16(REG_SDRESP0) | (sdmmc_read16(REG_SDRESP1) << 16);
|
||||
ctx->ret[1] = sdmmc_read16(REG_SDRESP2) | (sdmmc_read16(REG_SDRESP3) << 16);
|
||||
ctx->ret[2] = sdmmc_read16(REG_SDRESP4) | (sdmmc_read16(REG_SDRESP5) << 16);
|
||||
ctx->ret[3] = sdmmc_read16(REG_SDRESP6) | (sdmmc_read16(REG_SDRESP7) << 16);
|
||||
ctx->ret[0] = (u32)sdmmc_read16(REG_SDRESP0) | ((u32)sdmmc_read16(REG_SDRESP1) << 16);
|
||||
ctx->ret[1] = (u32)sdmmc_read16(REG_SDRESP2) | ((u32)sdmmc_read16(REG_SDRESP3) << 16);
|
||||
ctx->ret[2] = (u32)sdmmc_read16(REG_SDRESP4) | ((u32)sdmmc_read16(REG_SDRESP5) << 16);
|
||||
ctx->ret[3] = (u32)sdmmc_read16(REG_SDRESP6) | ((u32)sdmmc_read16(REG_SDRESP7) << 16);
|
||||
}
|
||||
}
|
||||
|
||||
int __attribute__((noinline)) sdmmc_sdcard_writesectors(u32 sector_no, u32 numsectors, u8 *in)
|
||||
int __attribute__((noinline)) sdmmc_sdcard_writesectors(u32 sector_no, u32 numsectors, const u8 *in)
|
||||
{
|
||||
if (handleSD.isSDHC == 0)
|
||||
sector_no <<= 9;
|
||||
@ -206,7 +222,7 @@ int __attribute__((noinline)) sdmmc_nand_readsectors(u32 sector_no, u32 numsecto
|
||||
return geterror(&handleNAND);
|
||||
}
|
||||
|
||||
int __attribute__((noinline)) sdmmc_nand_writesectors(u32 sector_no, u32 numsectors, u8 *in) //experimental
|
||||
int __attribute__((noinline)) sdmmc_nand_writesectors(u32 sector_no, u32 numsectors, const u8 *in) //experimental
|
||||
{
|
||||
if (handleNAND.isSDHC == 0)
|
||||
sector_no <<= 9;
|
||||
@ -226,7 +242,7 @@ int __attribute__((noinline)) sdmmc_nand_writesectors(u32 sector_no, u32 numsect
|
||||
return geterror(&handleNAND);
|
||||
}
|
||||
|
||||
u32 calcSDSize(u8* csd, int type)
|
||||
static u32 calcSDSize(u8* csd, int type)
|
||||
{
|
||||
u32 result = 0;
|
||||
u8 temp = csd[0xE];
|
||||
@ -238,14 +254,14 @@ u32 calcSDSize(u8* csd, int type)
|
||||
break;
|
||||
case 0:
|
||||
{
|
||||
u32 temp = (csd[0x7] << 0x2 | csd[0x8] << 0xA | csd[0x6] >> 0x6 | (csd[0x9] & 0xF) << 0x10) & 0xFFF;
|
||||
u32 temp2 = temp * (1 << (csd[0x9] & 0xF));
|
||||
u32 retval = temp2 * (1 << (((csd[0x4] >> 7 | csd[0x5] << 1) & 7) + 2));
|
||||
u32 temp2 = (csd[0x7] << 0x2 | csd[0x8] << 0xA | csd[0x6] >> 0x6 | (csd[0x9] & 0xF) << 0x10) & 0xFFF;
|
||||
u32 temp3 = temp2 * (1u << (csd[0x9] & 0xF));
|
||||
u32 retval = temp3 * (1u << (((csd[0x4] >> 7 | csd[0x5] << 1) & 7) + 2));
|
||||
result = retval >> 9;
|
||||
break;
|
||||
}
|
||||
case 1:
|
||||
result = (((csd[0x7] & 0x3F) << 0x10 | csd[0x6] << 8 | csd[0x5]) + 1) << 0xA;
|
||||
result = (u32)(((csd[0x7] & 0x3F) << 0x10 | csd[0x6] << 8 | csd[0x5]) + 1) << 0xA;
|
||||
break;
|
||||
default:
|
||||
result = 0;
|
||||
@ -255,7 +271,7 @@ u32 calcSDSize(u8* csd, int type)
|
||||
return result;
|
||||
}
|
||||
|
||||
void InitSD()
|
||||
static void InitSD()
|
||||
{
|
||||
//NAND
|
||||
handleNAND.isSDHC = 0;
|
||||
@ -453,9 +469,10 @@ int SD_Init()
|
||||
return 0;
|
||||
}
|
||||
|
||||
void sdmmc_sdcard_init()
|
||||
int sdmmc_sdcard_init()
|
||||
{
|
||||
InitSD();
|
||||
u32 nand_res = Nand_Init();
|
||||
u32 sd_res = SD_Init();
|
||||
int nand_res = Nand_Init();
|
||||
int sd_res = SD_Init();
|
||||
return nand_res | sd_res;
|
||||
}
|
||||
|
@ -125,14 +125,14 @@ void sdmmc_sdcard_writesector(uint32_t sector_no, void *in);
|
||||
void sdmmc_sdcard_writesectors(uint32_t sector_no, uint32_t numsectors, void *in);
|
||||
void sdmmc_blktransferinit();*/
|
||||
|
||||
void sdmmc_sdcard_init();
|
||||
int sdmmc_sdcard_init();
|
||||
int sdmmc_sdcard_readsector(u32 sector_no, u8 *out);
|
||||
int sdmmc_sdcard_readsectors(u32 sector_no, u32 numsectors, u8 *out);
|
||||
int sdmmc_sdcard_writesector(u32 sector_no, u8 *in);
|
||||
int sdmmc_sdcard_writesectors(u32 sector_no, u32 numsectors, u8 *in);
|
||||
int sdmmc_sdcard_writesector(u32 sector_no, const u8 *in);
|
||||
int sdmmc_sdcard_writesectors(u32 sector_no, u32 numsectors, const u8 *in);
|
||||
|
||||
int sdmmc_nand_readsectors(u32 sector_no, u32 numsectors, u8 *out);
|
||||
int sdmmc_nand_writesectors(u32 sector_no, u32 numsectors, u8 *in);
|
||||
int sdmmc_nand_writesectors(u32 sector_no, u32 numsectors, const u8 *in);
|
||||
|
||||
mmcdevice *getMMCDevice(int drive);
|
||||
|
||||
|
@ -9,7 +9,7 @@
|
||||
|
||||
static int read_count = 0;
|
||||
|
||||
void CTR_CmdC5()
|
||||
static inline void CTR_CmdC5()
|
||||
{
|
||||
static const u32 c5_cmd[4] = { 0xC5000000, 0x00000000, 0x00000000, 0x00000000 };
|
||||
CTR_SendCommand(c5_cmd, 0, 1, 0x100002C, NULL);
|
||||
|
@ -12,7 +12,7 @@ void NTR_CmdReset(void)
|
||||
NTR_SendCommand(reset_cmd, 0x2000, NTRCARD_CLK_SLOW | NTRCARD_DELAY1(0x1FFF) | NTRCARD_DELAY2(0x18), NULL);
|
||||
}
|
||||
|
||||
int NTR_CmdGetCartId(void)
|
||||
u32 NTR_CmdGetCartId(void)
|
||||
{
|
||||
u32 id;
|
||||
static const u32 getid_cmd[2] = { 0x90000000, 0x00000000 };
|
||||
|
@ -7,5 +7,5 @@
|
||||
#include "common.h"
|
||||
|
||||
void NTR_CmdReset(void);
|
||||
int NTR_CmdGetCartId(void);
|
||||
u32 NTR_CmdGetCartId(void);
|
||||
void NTR_CmdEnter16ByteMode(void);
|
||||
|
@ -19,10 +19,10 @@
|
||||
|
||||
extern u8* bottomScreen;
|
||||
|
||||
u32 CartID = -1;
|
||||
u32 CartID = 0xFFFFFFFFu;
|
||||
u32 CartType = 0;
|
||||
|
||||
static int A0_Response = -1;
|
||||
static u32 A0_Response = 0xFFFFFFFFu;
|
||||
static u32 rand1 = 0;
|
||||
static u32 rand2 = 0;
|
||||
|
||||
|
@ -9,12 +9,12 @@
|
||||
#define REG_CARDCONF2 (*(vu8*)0x10000010)
|
||||
|
||||
//REG_AUXSPICNT
|
||||
#define CARD_ENABLE (1<<15)
|
||||
#define CARD_SPI_ENABLE (1<<13)
|
||||
#define CARD_SPI_BUSY (1<<7)
|
||||
#define CARD_SPI_HOLD (1<<6)
|
||||
#define CARD_ENABLE (1u<<15)
|
||||
#define CARD_SPI_ENABLE (1u<<13)
|
||||
#define CARD_SPI_BUSY (1u<<7)
|
||||
#define CARD_SPI_HOLD (1u<<6)
|
||||
|
||||
#define LATENCY 0x822C
|
||||
#define LATENCY 0x822Cu
|
||||
|
||||
u32 BSWAP32(u32 val);
|
||||
|
||||
|
@ -74,6 +74,8 @@ void CTR_SendCommand(const u32 command[4], u32 pageSize, u32 blocks, u32 latency
|
||||
transferLength = 4096;
|
||||
pageParam = CTRCARD_PAGESIZE_4K;
|
||||
break;
|
||||
default:
|
||||
break; //Defaults already set
|
||||
}
|
||||
|
||||
REG_CTRCARDBLKCNT = blocks - 1;
|
||||
|
@ -14,27 +14,27 @@
|
||||
#define REG_CTRCARDFIFO (*(vu32*)0x10004030)
|
||||
|
||||
#define CTRCARD_PAGESIZE_0 (0<<16)
|
||||
#define CTRCARD_PAGESIZE_4 (1<<16)
|
||||
#define CTRCARD_PAGESIZE_16 (2<<16)
|
||||
#define CTRCARD_PAGESIZE_64 (3<<16)
|
||||
#define CTRCARD_PAGESIZE_512 (4<<16)
|
||||
#define CTRCARD_PAGESIZE_1K (5<<16)
|
||||
#define CTRCARD_PAGESIZE_2K (6<<16)
|
||||
#define CTRCARD_PAGESIZE_4K (7<<16)
|
||||
#define CTRCARD_PAGESIZE_16K (8<<16)
|
||||
#define CTRCARD_PAGESIZE_64K (9<<16)
|
||||
#define CTRCARD_PAGESIZE_4 (1u<<16)
|
||||
#define CTRCARD_PAGESIZE_16 (2u<<16)
|
||||
#define CTRCARD_PAGESIZE_64 (3u<<16)
|
||||
#define CTRCARD_PAGESIZE_512 (4u<<16)
|
||||
#define CTRCARD_PAGESIZE_1K (5u<<16)
|
||||
#define CTRCARD_PAGESIZE_2K (6u<<16)
|
||||
#define CTRCARD_PAGESIZE_4K (7u<<16)
|
||||
#define CTRCARD_PAGESIZE_16K (8u<<16)
|
||||
#define CTRCARD_PAGESIZE_64K (9u<<16)
|
||||
|
||||
#define CTRCARD_CRC_ERROR (1<<4)
|
||||
#define CTRCARD_ACTIVATE (1<<31) // when writing, get the ball rolling
|
||||
#define CTRCARD_IE (1<<30) // Interrupt enable
|
||||
#define CTRCARD_WR (1<<29) // Card write enable
|
||||
#define CTRCARD_nRESET (1<<28) // value on the /reset pin (1 = high out, not a reset state, 0 = low out = in reset)
|
||||
#define CTRCARD_BLK_SIZE(n) (((n)&0xF)<<16) // Transfer block size
|
||||
#define CTRCARD_CRC_ERROR (1u<<4)
|
||||
#define CTRCARD_ACTIVATE (1u<<31) // when writing, get the ball rolling
|
||||
#define CTRCARD_IE (1u<<30) // Interrupt enable
|
||||
#define CTRCARD_WR (1u<<29) // Card write enable
|
||||
#define CTRCARD_nRESET (1u<<28) // value on the /reset pin (1 = high out, not a reset state, 0 = low out = in reset)
|
||||
#define CTRCARD_BLK_SIZE(n) (((n)&0xFu)<<16) // Transfer block size
|
||||
|
||||
#define CTRCARD_BUSY (1<<31) // when reading, still expecting incomming data?
|
||||
#define CTRCARD_DATA_READY (1<<27) // when reading, REG_CTRCARDFIFO has another word of data and is good to go
|
||||
#define CTRCARD_BUSY (1u<<31) // when reading, still expecting incomming data?
|
||||
#define CTRCARD_DATA_READY (1u<<27) // when reading, REG_CTRCARDFIFO has another word of data and is good to go
|
||||
|
||||
#define CTRKEY_PARAM 0x1000000
|
||||
#define CTRKEY_PARAM 0x1000000u
|
||||
|
||||
void CTR_SetSecKey(u32 value);
|
||||
void CTR_SetSecSeed(const u32* seed, bool flag);
|
||||
|
@ -44,6 +44,8 @@ void NTR_SendCommand(const u32 command[2], u32 pageSize, u32 latency, void* buff
|
||||
transferLength = 8192;
|
||||
pageParam = NTRCARD_PAGESIZE_8K;
|
||||
break;
|
||||
default:
|
||||
break; //Using 4K pagesize and transfer length by default
|
||||
}
|
||||
|
||||
// go
|
||||
|
@ -17,48 +17,48 @@
|
||||
#define REG_NTRCARDFIFO (*(vu32*)0x1016401C)
|
||||
|
||||
#define NTRCARD_PAGESIZE_0 (0<<24)
|
||||
#define NTRCARD_PAGESIZE_4 (7<<24)
|
||||
#define NTRCARD_PAGESIZE_512 (1<<24)
|
||||
#define NTRCARD_PAGESIZE_1K (2<<24)
|
||||
#define NTRCARD_PAGESIZE_2K (3<<24)
|
||||
#define NTRCARD_PAGESIZE_4K (4<<24)
|
||||
#define NTRCARD_PAGESIZE_8K (5<<24)
|
||||
#define NTRCARD_PAGESIZE_16K (6<<24)
|
||||
#define NTRCARD_PAGESIZE_4 (7u<<24)
|
||||
#define NTRCARD_PAGESIZE_512 (1u<<24)
|
||||
#define NTRCARD_PAGESIZE_1K (2u<<24)
|
||||
#define NTRCARD_PAGESIZE_2K (3u<<24)
|
||||
#define NTRCARD_PAGESIZE_4K (4u<<24)
|
||||
#define NTRCARD_PAGESIZE_8K (5u<<24)
|
||||
#define NTRCARD_PAGESIZE_16K (6u<<24)
|
||||
|
||||
#define NTRCARD_ACTIVATE (1<<31) // when writing, get the ball rolling
|
||||
#define NTRCARD_WR (1<<30) // Card write enable
|
||||
#define NTRCARD_nRESET (1<<29) // value on the /reset pin (1 = high out, not a reset state, 0 = low out = in reset)
|
||||
#define NTRCARD_SEC_LARGE (1<<28) // Use "other" secure area mode, which tranfers blocks of 0x1000 bytes at a time
|
||||
#define NTRCARD_CLK_SLOW (1<<27) // Transfer clock rate (0 = 6.7MHz, 1 = 4.2MHz)
|
||||
#define NTRCARD_BLK_SIZE(n) (((n)&0x7)<<24) // Transfer block size, (0 = None, 1..6 = (0x100 << n) bytes, 7 = 4 bytes)
|
||||
#define NTRCARD_SEC_CMD (1<<22) // The command transfer will be hardware encrypted (KEY2)
|
||||
#define NTRCARD_DELAY2(n) (((n)&0x3F)<<16) // Transfer delay length part 2
|
||||
#define NTRCARD_SEC_SEED (1<<15) // Apply encryption (KEY2) seed to hardware registers
|
||||
#define NTRCARD_SEC_EN (1<<14) // Security enable
|
||||
#define NTRCARD_SEC_DAT (1<<13) // The data transfer will be hardware encrypted (KEY2)
|
||||
#define NTRCARD_DELAY1(n) ((n)&0x1FFF) // Transfer delay length part 1
|
||||
#define NTRCARD_ACTIVATE (1u<<31) // when writing, get the ball rolling
|
||||
#define NTRCARD_WR (1u<<30) // Card write enable
|
||||
#define NTRCARD_nRESET (1u<<29) // value on the /reset pin (1 = high out, not a reset state, 0 = low out = in reset)
|
||||
#define NTRCARD_SEC_LARGE (1u<<28) // Use "other" secure area mode, which tranfers blocks of 0x1000 bytes at a time
|
||||
#define NTRCARD_CLK_SLOW (1u<<27) // Transfer clock rate (0 = 6.7MHz, 1 = 4.2MHz)
|
||||
#define NTRCARD_BLK_SIZE(n) (((n)&0x7u)<<24) // Transfer block size, (0 = None, 1..6 = (0x100 << n) bytes, 7 = 4 bytes)
|
||||
#define NTRCARD_SEC_CMD (1u<<22) // The command transfer will be hardware encrypted (KEY2)
|
||||
#define NTRCARD_DELAY2(n) (((n)&0x3Fu)<<16) // Transfer delay length part 2
|
||||
#define NTRCARD_SEC_SEED (1u<<15) // Apply encryption (KEY2) seed to hardware registers
|
||||
#define NTRCARD_SEC_EN (1u<<14) // Security enable
|
||||
#define NTRCARD_SEC_DAT (1u<<13) // The data transfer will be hardware encrypted (KEY2)
|
||||
#define NTRCARD_DELAY1(n) ((n)&0x1FFFu) // Transfer delay length part 1
|
||||
|
||||
// 3 bits in b10..b8 indicate something
|
||||
// read bits
|
||||
#define NTRCARD_BUSY (1<<31) // when reading, still expecting incomming data?
|
||||
#define NTRCARD_DATA_READY (1<<23) // when reading, REG_NTRCARDFIFO has another word of data and is good to go
|
||||
#define NTRCARD_BUSY (1u<<31) // when reading, still expecting incomming data?
|
||||
#define NTRCARD_DATA_READY (1u<<23) // when reading, REG_NTRCARDFIFO has another word of data and is good to go
|
||||
|
||||
// Card commands
|
||||
#define NTRCARD_CMD_DUMMY 0x9F
|
||||
#define NTRCARD_CMD_HEADER_READ 0x00
|
||||
#define NTRCARD_CMD_HEADER_CHIPID 0x90
|
||||
#define NTRCARD_CMD_ACTIVATE_BF 0x3C // Go into blowfish (KEY1) encryption mode
|
||||
#define NTRCARD_CMD_ACTIVATE_SEC 0x40 // Go into hardware (KEY2) encryption mode
|
||||
#define NTRCARD_CMD_SECURE_CHIPID 0x10
|
||||
#define NTRCARD_CMD_SECURE_READ 0x20
|
||||
#define NTRCARD_CMD_DISABLE_SEC 0x60 // Leave hardware (KEY2) encryption mode
|
||||
#define NTRCARD_CMD_DATA_MODE 0xA0
|
||||
#define NTRCARD_CMD_DATA_READ 0xB7
|
||||
#define NTRCARD_CMD_DATA_CHIPID 0xB8
|
||||
#define NTRCARD_CMD_DUMMY 0x9Fu
|
||||
#define NTRCARD_CMD_HEADER_READ 0x00u
|
||||
#define NTRCARD_CMD_HEADER_CHIPID 0x90u
|
||||
#define NTRCARD_CMD_ACTIVATE_BF 0x3Cu // Go into blowfish (KEY1) encryption mode
|
||||
#define NTRCARD_CMD_ACTIVATE_SEC 0x40u // Go into hardware (KEY2) encryption mode
|
||||
#define NTRCARD_CMD_SECURE_CHIPID 0x10u
|
||||
#define NTRCARD_CMD_SECURE_READ 0x20u
|
||||
#define NTRCARD_CMD_DISABLE_SEC 0x60u // Leave hardware (KEY2) encryption mode
|
||||
#define NTRCARD_CMD_DATA_MODE 0xA0u
|
||||
#define NTRCARD_CMD_DATA_READ 0xB7u
|
||||
#define NTRCARD_CMD_DATA_CHIPID 0xB8u
|
||||
|
||||
#define NTRCARD_CR1_ENABLE 0x8000
|
||||
#define NTRCARD_CR1_IRQ 0x4000
|
||||
#define NTRCARD_CR1_ENABLE 0x8000u
|
||||
#define NTRCARD_CR1_IRQ 0x4000u
|
||||
|
||||
#define NTRKEY_PARAM 0x3F1FFF
|
||||
#define NTRKEY_PARAM 0x3F1FFFu
|
||||
|
||||
void NTR_SendCommand(const u32 command[2], u32 pageSize, u32 latency, void* buffer);
|
||||
|
75
source/headers.h
Normal file
75
source/headers.h
Normal file
@ -0,0 +1,75 @@
|
||||
#ifndef UNCART_HEADERS_H_
|
||||
#define UNCART_HEADERS_H_
|
||||
|
||||
#include "common.h"
|
||||
|
||||
typedef enum
|
||||
{
|
||||
MEDIA_6X_SAVE_CRYPTO = 1,
|
||||
MEDIA_CARD_DEVICE = 3,
|
||||
MEDIA_PLATFORM_INDEX = 4,
|
||||
MEDIA_TYPE_INDEX = 5,
|
||||
MEDIA_UNIT_SIZE = 6,
|
||||
MEDIA_CARD_DEVICE_OLD = 7
|
||||
} NcsdFlagIndex;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
u32 offset;
|
||||
u32 size;
|
||||
} partition_offsetsize;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
u8 sha256[0x100];
|
||||
u8 magic[4];
|
||||
u32 media_size;
|
||||
u8 title_id[8];
|
||||
u8 partitions_fs_type[8];
|
||||
u8 partitions_crypto_type[8];
|
||||
partition_offsetsize offsetsize_table[8];
|
||||
u8 exheader_hash[0x20];
|
||||
u8 additional_header_size[0x4];
|
||||
u8 sector_zero_offset[0x4];
|
||||
u8 partition_flags[8];
|
||||
u8 partition_id_table[8][8];
|
||||
u8 reserved[0x30];
|
||||
} NCSD_HEADER;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
u8 sha256[0x100];
|
||||
u8 magic[4];
|
||||
u32 content_size;
|
||||
u8 title_id[8];
|
||||
u8 maker_code[2];
|
||||
u8 version[2];
|
||||
u8 reserved_0[4];
|
||||
u8 program_id[8];
|
||||
u8 temp_flag;
|
||||
u8 reserved_1[0xF];
|
||||
u8 logo_sha_256_hash[0x20];
|
||||
u8 product_code[0x10];
|
||||
u8 extended_header_sha_256_hash[0x20];
|
||||
u8 extended_header_size[4];
|
||||
u8 reserved_2[4];
|
||||
u8 flags[8];
|
||||
u8 plain_region_offset[4];
|
||||
u8 plain_region_size[4];
|
||||
u8 logo_region_offset[4];
|
||||
u8 logo_region_size[4];
|
||||
u8 exefs_offset[4];
|
||||
u8 exefs_size[4];
|
||||
u8 exefs_hash_size[4];
|
||||
u8 reserved_4[4];
|
||||
u8 romfs_offset[4];
|
||||
u8 romfs_size[4];
|
||||
u8 romfs_hash_size[4];
|
||||
u8 reserved_5[4];
|
||||
u8 exefs_sha_256_hash[0x20];
|
||||
u8 romfs_sha_256_hash[0x20];
|
||||
} __attribute__((__packed__))
|
||||
NCCH_HEADER;
|
||||
|
||||
#endif//UNCART_HEADERS_H_
|
||||
|
16
source/i2c.c
16
source/i2c.c
@ -3,7 +3,7 @@
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
static const struct { u8 bus_id, reg_addr } dev_data[] = {
|
||||
static const struct { u8 bus_id, reg_addr; } dev_data[] = {
|
||||
{0, 0x4A}, {0, 0x7A}, {0, 0x78},
|
||||
{1, 0x4A}, {1, 0x78}, {1, 0x2C},
|
||||
{1, 0x2E}, {1, 0x40}, {1, 0x44},
|
||||
@ -11,35 +11,35 @@ static const struct { u8 bus_id, reg_addr } dev_data[] = {
|
||||
{2, 0xA4}, {2, 0x9A}, {2, 0xA0},
|
||||
};
|
||||
|
||||
const inline u8 i2cGetDeviceBusId(u8 device_id) {
|
||||
inline u8 i2cGetDeviceBusId(u8 device_id) {
|
||||
return dev_data[device_id].bus_id;
|
||||
}
|
||||
|
||||
const inline u8 i2cGetDeviceRegAddr(u8 device_id) {
|
||||
inline u8 i2cGetDeviceRegAddr(u8 device_id) {
|
||||
return dev_data[device_id].reg_addr;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
static vu8* const reg_data_addrs[] = {
|
||||
static vu8* reg_data_addrs[] = {
|
||||
(vu8*)(I2C1_REG_OFF + I2C_REG_DATA),
|
||||
(vu8*)(I2C2_REG_OFF + I2C_REG_DATA),
|
||||
(vu8*)(I2C3_REG_OFF + I2C_REG_DATA),
|
||||
};
|
||||
|
||||
inline vu8* const i2cGetDataReg(u8 bus_id) {
|
||||
inline vu8* i2cGetDataReg(u8 bus_id) {
|
||||
return reg_data_addrs[bus_id];
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
static vu8* const reg_cnt_addrs[] = {
|
||||
static vu8* reg_cnt_addrs[] = {
|
||||
(vu8*)(I2C1_REG_OFF + I2C_REG_CNT),
|
||||
(vu8*)(I2C2_REG_OFF + I2C_REG_CNT),
|
||||
(vu8*)(I2C3_REG_OFF + I2C_REG_CNT),
|
||||
};
|
||||
|
||||
inline vu8* const i2cGetCntReg(u8 bus_id) {
|
||||
inline vu8* i2cGetCntReg(u8 bus_id) {
|
||||
return reg_cnt_addrs[bus_id];
|
||||
}
|
||||
|
||||
@ -114,7 +114,7 @@ bool i2cReadRegisterBuffer(unsigned int dev_id, int reg, u8* buffer, size_t buf_
|
||||
}
|
||||
|
||||
if (buf_size != 1) {
|
||||
for (int i = 0; i < buf_size - 1; i++) {
|
||||
for (size_t i = 0; i < buf_size - 1; i++) {
|
||||
i2cWaitBusy(bus_id);
|
||||
*i2cGetCntReg(bus_id) = 0xF0;
|
||||
i2cWaitBusy(bus_id);
|
||||
|
@ -15,11 +15,11 @@
|
||||
#define I2C_DEV_GYRO 10
|
||||
#define I2C_DEV_IR 13
|
||||
|
||||
const u8 i2cGetDeviceBusId(u8 device_id);
|
||||
const u8 i2cGetDeviceRegAddr(u8 device_id);
|
||||
u8 i2cGetDeviceBusId(u8 device_id);
|
||||
u8 i2cGetDeviceRegAddr(u8 device_id);
|
||||
|
||||
vu8* const i2cGetDataReg(u8 bus_id);
|
||||
vu8* const i2cGetCntReg(u8 bus_id);
|
||||
vu8* i2cGetDataReg(u8 bus_id);
|
||||
vu8* i2cGetCntReg(u8 bus_id);
|
||||
|
||||
void i2cWaitBusy(u8 bus_id);
|
||||
bool i2cGetResult(u8 bus_id);
|
||||
@ -33,3 +33,4 @@ u8 i2cReadRegister(u8 dev_id, u8 reg);
|
||||
bool i2cWriteRegister(u8 dev_id, u8 reg, u8 data);
|
||||
|
||||
bool i2cReadRegisterBuffer(unsigned int dev_id, int reg, u8* buffer, size_t buf_size);
|
||||
|
||||
|
@ -1,13 +1,14 @@
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#include "draw.h"
|
||||
#include "hid.h"
|
||||
#include "i2c.h"
|
||||
#include "fatfs/ff.h"
|
||||
#include "gamecart/protocol.h"
|
||||
#include "gamecart/command_ctr.h"
|
||||
#include "headers.h"
|
||||
#include "i2c.h"
|
||||
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
|
||||
extern s32 CartID;
|
||||
extern s32 CartID2;
|
||||
@ -17,7 +18,6 @@ static FATFS fs;
|
||||
static FIL file;
|
||||
|
||||
static void ClearTop(void) {
|
||||
ClearScreen(TOP_SCREEN0, RGB(255, 255, 255));
|
||||
ClearScreen(TOP_SCREEN1, RGB(255, 255, 255));
|
||||
current_y = 0;
|
||||
}
|
||||
@ -27,7 +27,7 @@ static void wait_key(void) {
|
||||
InputWait();
|
||||
}
|
||||
|
||||
void Reboot()
|
||||
static void Reboot()
|
||||
{
|
||||
i2cWriteRegister(I2C_DEV_MCU, 0x20, 1 << 2);
|
||||
while(true);
|
||||
@ -41,8 +41,8 @@ struct Context {
|
||||
u32 media_unit;
|
||||
};
|
||||
|
||||
int dump_cart_region(u32 start_sector, u32 end_sector, FIL* output_file, struct Context* ctx) {
|
||||
const u32 read_size = 1 * 1024 * 1024 / ctx->media_unit; // 1MB
|
||||
static int dump_cart_region(u32 start_sector, u32 end_sector, FIL* output_file, struct Context* ctx) {
|
||||
u32 read_size = 1u * 1024 * 1024 / ctx->media_unit; // 1MiB default
|
||||
|
||||
// Dump remaining data
|
||||
u32 current_sector = start_sector;
|
||||
@ -54,6 +54,12 @@ int dump_cart_region(u32 start_sector, u32 end_sector, FIL* output_file, struct
|
||||
while (read_ptr < ctx->buffer + ctx->buffer_size && current_sector < end_sector) {
|
||||
Cart_Dummy();
|
||||
Cart_Dummy();
|
||||
|
||||
//If there is less data to read than the curren read_size, fix it
|
||||
if (end_sector - current_sector < read_size)
|
||||
{
|
||||
read_size = end_sector - current_sector;
|
||||
}
|
||||
CTR_CmdReadData(current_sector, ctx->media_unit, read_size, read_ptr);
|
||||
read_ptr += ctx->media_unit * read_size;
|
||||
current_sector += read_size;
|
||||
@ -62,8 +68,8 @@ int dump_cart_region(u32 start_sector, u32 end_sector, FIL* output_file, struct
|
||||
u8* write_ptr = ctx->buffer;
|
||||
while (write_ptr < read_ptr) {
|
||||
unsigned int bytes_written = 0;
|
||||
f_write(output_file, write_ptr, read_ptr - write_ptr, &bytes_written);
|
||||
Debug("Wrote 0x%x bytes, e.g. %08x", bytes_written, *(u32*)write_ptr);
|
||||
f_write(output_file, write_ptr, (size_t)(read_ptr - write_ptr), &bytes_written);
|
||||
Debug("Wrote 0x%x bytes...", bytes_written);
|
||||
|
||||
if (bytes_written == 0) {
|
||||
Debug("Writing failed! :( SD full?");
|
||||
@ -82,17 +88,21 @@ int main() {
|
||||
restart_program:
|
||||
// Setup boring stuff - clear the screen, initialize SD output, etc...
|
||||
ClearTop();
|
||||
Debug("ROM dump tool v0.2");
|
||||
|
||||
Debug("Uncart: ROM dump tool v0.2");
|
||||
Debug("Insert your game cart now.");
|
||||
wait_key();
|
||||
|
||||
// Arbitrary target buffer
|
||||
// TODO: This should be done in a nicer way ;)
|
||||
u8* target = (u8*)0x22000000;
|
||||
u32* target = (u32*)0x22000000;
|
||||
NCSD_HEADER *ncsdHeader = (NCSD_HEADER*)target;
|
||||
u32 target_buf_size = 16u * 1024u * 1024u; // 16MB
|
||||
u8* header = (u8*)0x23000000;
|
||||
memset(target, 0, target_buf_size); // Clear our buffer
|
||||
|
||||
u32* ncchHeaderData = (u32*)0x23000000;
|
||||
NCCH_HEADER *ncchHeader = (NCCH_HEADER*)ncchHeaderData;
|
||||
|
||||
*(vu32*)0x10000020 = 0; // InitFS stuff
|
||||
*(vu32*)0x10000020 = 0x340; // InitFS stuff
|
||||
|
||||
@ -100,45 +110,62 @@ restart_program:
|
||||
|
||||
Cart_Init();
|
||||
Debug("Cart id is %08x", Cart_GetID());
|
||||
CTR_CmdReadHeader(header);
|
||||
Debug("Done reading header: %08X :)...", *(u32*)&header[0x100]);
|
||||
Debug("Reading NCCH header...");
|
||||
CTR_CmdReadHeader(ncchHeader);
|
||||
Debug("Done reading NCCH header.");
|
||||
|
||||
if (strncmp((const char*)(ncchHeader->magic), "NCCH", 4))
|
||||
{
|
||||
Debug("NCCH magic not found in header!!!");
|
||||
Debug("Press A to continue anyway.");
|
||||
if (!(InputWait() & BUTTON_A))
|
||||
goto restart_prompt;
|
||||
}
|
||||
|
||||
// TODO: Check first header bytes for "NCCH" or other magic words
|
||||
u32 sec_keys[4];
|
||||
Cart_Secure_Init((u32*)header,sec_keys);
|
||||
|
||||
const u32 mediaUnit = 0x200; // TODO: Read from cart
|
||||
Cart_Secure_Init(ncchHeaderData, sec_keys);
|
||||
|
||||
// Guess 0x200 first for the media size. this will be set correctly once the cart header is read
|
||||
// Read out the header 0x0000-0x1000
|
||||
Cart_Dummy();
|
||||
CTR_CmdReadData(0, mediaUnit, 0x1000 / mediaUnit, target);
|
||||
Debug("Reading NCSD header...");
|
||||
CTR_CmdReadData(0, 0x200, 0x1000 / 0x200, target);
|
||||
Debug("Done reading NCSD header.");
|
||||
|
||||
u32 NCSD_magic = *(u32*)(&target[0x100]);
|
||||
u32 cartSize = *(u32*)(&target[0x104]);
|
||||
Debug("Cart size: %llu MB", (u64)cartSize * (u64)mediaUnit / 1024ull / 1024ull);
|
||||
if (NCSD_magic != 0x4453434E) {
|
||||
if (strncmp((const char*)(ncsdHeader->magic), "NCSD", 4)) {
|
||||
Debug("NCSD magic not found in header!!!");
|
||||
Debug("Press A to continue anyway.");
|
||||
if (!(InputWait() & BUTTON_A))
|
||||
goto restart_prompt;
|
||||
}
|
||||
|
||||
const u32 mediaUnit = 0x200 * (1u << ncsdHeader->partition_flags[MEDIA_UNIT_SIZE]); //Correctly set the media unit size
|
||||
|
||||
//Calculate the actual size by counting the adding the size of each partition, plus the initial offset
|
||||
//size is in media units
|
||||
u32 cartSize = ncsdHeader->offsetsize_table[0].offset;
|
||||
for(int i = 0; i < 8; i++){
|
||||
cartSize += ncsdHeader->offsetsize_table[i].size;
|
||||
}
|
||||
|
||||
Debug("Cart data size: %llu MB", (u64)cartSize * (u64)mediaUnit / 1024ull / 1024ull);
|
||||
|
||||
struct Context context = {
|
||||
.buffer = target,
|
||||
.buffer = (u8*)target,
|
||||
.buffer_size = target_buf_size,
|
||||
.cart_size = cartSize,
|
||||
.media_unit = mediaUnit,
|
||||
};
|
||||
|
||||
// Maximum number of blocks in a single file
|
||||
u32 file_max_blocks = 2u * 1024u * 1024u * 1024u / mediaUnit; // 2GB
|
||||
u32 file_max_blocks = 0xFFFFFFFFu / mediaUnit; // 4GiB - 1
|
||||
u32 current_part = 0;
|
||||
|
||||
while (current_part * file_max_blocks < cartSize) {
|
||||
// Create output file
|
||||
char filename_buf[32];
|
||||
char extension_digit = cartSize <= file_max_blocks ? 's' : '0' + current_part;
|
||||
snprintf(filename_buf, sizeof(filename_buf), "/%.16s.3d%c", &header[0x150], extension_digit);
|
||||
snprintf(filename_buf, sizeof(filename_buf), "/%.16s.3d%c", ncchHeader->product_code, extension_digit);
|
||||
Debug("Writing to file: \"%s\"", filename_buf);
|
||||
Debug("Change the SD card now and/or press a key.");
|
||||
Debug("(Or SELECT to cancel)");
|
||||
@ -172,8 +199,8 @@ restart_program:
|
||||
f_lseek(&file, 0x1000);
|
||||
unsigned int written = 0;
|
||||
// Fill the 0x1200-0x4000 unused area with 0xFF instead of random garbage.
|
||||
memset(header + 0x200, 0xFF, 0x3000 - 0x200);
|
||||
f_write(&file, header, 0x3000, &written);
|
||||
memset((u8*)ncchHeaderData + 0x200, 0xFF, 0x3000 - 0x200);
|
||||
f_write(&file, ncchHeader, 0x3000, &written);
|
||||
}
|
||||
|
||||
Debug("Done!");
|
||||
|
@ -90,6 +90,20 @@ _init:
|
||||
push {r0-r12, lr}
|
||||
|
||||
bl _enable_caches
|
||||
|
||||
@@ Initialize .bss
|
||||
@ ldr r0, =__bss_start__
|
||||
@ ldr r1, =__bss_end__
|
||||
@ ldr r2, =__bss_end__
|
||||
@ sbc r2, r0
|
||||
@ eor r4, r4
|
||||
|
||||
|
||||
@zero_bss:
|
||||
@ strb r4, [r0], #1
|
||||
@ subs r2, r2, #1
|
||||
@ bne zero_bss
|
||||
|
||||
bl main
|
||||
|
||||
mrc p15, 0, r4, c1, c0, 0
|
||||
|
Loading…
x
Reference in New Issue
Block a user