Fix bootloader

This commit is contained in:
RocketRobz 2018-10-05 21:59:31 -06:00
parent c311120c0c
commit 2a0f5e7c38
8 changed files with 108 additions and 112 deletions

View File

@ -31,6 +31,7 @@
#ifndef _NO_BOOTSTUB_ #ifndef _NO_BOOTSTUB_
#include "bootstub_bin.h" #include "bootstub_bin.h"
#include "exceptionstub_bin.h"
#endif #endif
#include "nds_loader_arm9.h" #include "nds_loader_arm9.h"
@ -403,6 +404,9 @@ dldiOffset:
dsiSD: dsiSD:
.word 0 .word 0
*/ */
void(*exceptionstub)(void) = (void(*)(void))0x2ffa000;
bool installBootStub(bool havedsiSD) { bool installBootStub(bool havedsiSD) {
#ifndef _NO_BOOTSTUB_ #ifndef _NO_BOOTSTUB_
extern char *fake_heap_end; extern char *fake_heap_end;
@ -424,7 +428,11 @@ bool installBootStub(bool havedsiSD) {
bootstub->arm9reboot = (VoidFn)(((u32)bootstub->arm9reboot)+fake_heap_end); bootstub->arm9reboot = (VoidFn)(((u32)bootstub->arm9reboot)+fake_heap_end);
bootstub->arm7reboot = (VoidFn)(((u32)bootstub->arm7reboot)+fake_heap_end); bootstub->arm7reboot = (VoidFn)(((u32)bootstub->arm7reboot)+fake_heap_end);
bootstub->bootsize = load_bin_size; bootstub->bootsize = load_bin_size;
memcpy(exceptionstub,exceptionstub_bin,exceptionstub_bin_size);
exceptionstub();
DC_FlushAll(); DC_FlushAll();
return ret; return ret;

3
bootloader/.gitignore vendored Normal file
View File

@ -0,0 +1,3 @@
*build
load.bin
load.elf

View File

@ -33,7 +33,7 @@ CFLAGS += $(INCLUDE) $(EXTRA_CFLAGS) -DARM7
ASFLAGS := -g $(ARCH) $(EXTRA_CFLAGS) $(INCLUDE) ASFLAGS := -g $(ARCH) $(EXTRA_CFLAGS) $(INCLUDE)
LDFLAGS = -nostartfiles -T $(TOPDIR)/load.ld -g $(ARCH) -Wl,-Map,$(TARGET).map LDFLAGS = -nostartfiles -T $(TOPDIR)/load.ld -g $(ARCH) -Wl,-Map,$(TARGET).map
LIBS := -lnds7 LIBS :=
#--------------------------------------------------------------------------------- #---------------------------------------------------------------------------------
# list of directories containing libraries, this must be the top level containing # list of directories containing libraries, this must be the top level containing
@ -50,7 +50,7 @@ ifneq ($(BUILD),$(notdir $(CURDIR)))
#--------------------------------------------------------------------------------- #---------------------------------------------------------------------------------
export TOPDIR := $(CURDIR) export TOPDIR := $(CURDIR)
export LOADBIN := $(CURDIR)/../data/$(TARGET).bin export LOADBIN ?= $(CURDIR)/$(TARGET).bin
export LOADELF := $(CURDIR)/$(TARGET).elf export LOADELF := $(CURDIR)/$(TARGET).elf
export DEPSDIR := $(CURDIR)/$(BUILD) export DEPSDIR := $(CURDIR)/$(BUILD)

View File

@ -71,24 +71,6 @@ void __attribute__ ((long_call)) __attribute__((naked)) __attribute__((noreturn)
while(1); while(1);
} }
void __attribute__ ((long_call)) __attribute__((naked)) __attribute__((noreturn)) clearMasterBright_ARM9 (void)
{
u16 mode = 1 << 14;
*(u16*)(0x0400006C + (0x1000 * 0)) = 0 + mode;
*(u16*)(0x0400006C + (0x1000 * 1)) = 0 + mode;
// Return to passme loop
*((vu32*)0x02FFFE04) = (u32)0xE59FF018; // ldr pc, 0x02FFFE24
*((vu32*)0x02FFFE24) = (u32)0x02FFFE04; // Set ARM9 Loop address
asm volatile(
"\tbx %0\n"
: : "r" (0x02FFFE04)
);
while(1);
}
/*------------------------------------------------------------------------- /*-------------------------------------------------------------------------
startBinary_ARM9 startBinary_ARM9
Jumps to the ARM9 NDS binary in sync with the display and ARM7 Jumps to the ARM9 NDS binary in sync with the display and ARM7

View File

@ -1,10 +1,10 @@
/*----------------------------------------------------------------- /*-----------------------------------------------------------------
boot.c boot.c
BootLoader BootLoader
Loads a file into memory and runs it Loads a file into memory and runs it
All resetMemory and startBinary functions are based All resetMemory and startBinary functions are based
on the MultiNDS loader by Darkain. on the MultiNDS loader by Darkain.
Original source available at: Original source available at:
http://cvs.sourceforge.net/viewcvs.py/ndslib/ndslib/examples/loader/boot/main.cpp http://cvs.sourceforge.net/viewcvs.py/ndslib/ndslib/examples/loader/boot/main.cpp
@ -28,7 +28,7 @@ License:
If you use this code, please give due credit and email me about your If you use this code, please give due credit and email me about your
project at chishm@hotmail.com project at chishm@hotmail.com
Helpful information: Helpful information:
This code runs from VRAM bank C on ARM7 This code runs from VRAM bank C on ARM7
------------------------------------------------------------------*/ ------------------------------------------------------------------*/
@ -46,20 +46,18 @@ Helpful information:
#undef ARM9 #undef ARM9
#define ARM7 #define ARM7
#include <nds/arm7/audio.h> #include <nds/arm7/audio.h>
#include <nds/arm7/sdmmc.h>
#include "fat.h" #include "fat.h"
#include "dldi_patcher.h" #include "dldi_patcher.h"
#include "card.h" #include "card.h"
#include "boot.h" #include "boot.h"
void arm7clearRAM(); void arm7clearRAM();
int sdmmc_sdcard_readsectors(u32 sector_no, u32 numsectors, void *out);
int sdmmc_sdcard_init();
void sdmmc_controller_init();
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
// Important things // Important things
#define TEMP_MEM 0x02FFE000 #define TEMP_MEM 0x02FFD000
#define TWL_HEAD 0x02FFE000
#define NDS_HEAD 0x02FFFE00 #define NDS_HEAD 0x02FFFE00
#define TEMP_ARM9_START_ADDRESS (*(vu32*)0x02FFFFF4) #define TEMP_ARM9_START_ADDRESS (*(vu32*)0x02FFFFF4)
@ -73,6 +71,7 @@ extern unsigned long wantToPatchDLDI;
extern unsigned long argStart; extern unsigned long argStart;
extern unsigned long argSize; extern unsigned long argSize;
extern unsigned long dsiSD; extern unsigned long dsiSD;
extern unsigned long dsiMode;
//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
// Firmware stuff // Firmware stuff
@ -116,7 +115,7 @@ static inline void copyLoop (u32* dest, const u32* src, u32 size) {
/*------------------------------------------------------------------------- /*-------------------------------------------------------------------------
passArgs_ARM7 passArgs_ARM7
Copies the command line arguments to the end of the ARM9 binary, Copies the command line arguments to the end of the ARM9 binary,
then sets a flag in memory for the loaded NDS to use then sets a flag in memory for the loaded NDS to use
--------------------------------------------------------------------------*/ --------------------------------------------------------------------------*/
void passArgs_ARM7 (void) { void passArgs_ARM7 (void) {
@ -124,15 +123,32 @@ void passArgs_ARM7 (void) {
u32 ARM9_LEN = *((u32*)(NDS_HEAD + 0x02C)); u32 ARM9_LEN = *((u32*)(NDS_HEAD + 0x02C));
u32* argSrc; u32* argSrc;
u32* argDst; u32* argDst;
if (!argStart || !argSize) return; if (!argStart || !argSize) return;
if ( ARM9_DST == 0 && ARM9_LEN == 0) {
ARM9_DST = *((u32*)(NDS_HEAD + 0x038));
ARM9_LEN = *((u32*)(NDS_HEAD + 0x03C));
}
argSrc = (u32*)(argStart + (int)&_start); argSrc = (u32*)(argStart + (int)&_start);
argDst = (u32*)((ARM9_DST + ARM9_LEN + 3) & ~3); // Word aligned argDst = (u32*)((ARM9_DST + ARM9_LEN + 3) & ~3); // Word aligned
if (dsiMode && (*(u8*)(NDS_HEAD + 0x012) & BIT(1)))
{
u32 ARM9i_DST = *((u32*)(TWL_HEAD + 0x1C8));
u32 ARM9i_LEN = *((u32*)(TWL_HEAD + 0x1CC));
if (ARM9i_LEN)
{
u32* argDst2 = (u32*)((ARM9i_DST + ARM9i_LEN + 3) & ~3); // Word aligned
if (argDst2 > argDst)
argDst = argDst2;
}
}
copyLoop(argDst, argSrc, argSize); copyLoop(argDst, argSrc, argSize);
__system_argv->argvMagic = ARGV_MAGIC; __system_argv->argvMagic = ARGV_MAGIC;
__system_argv->commandLine = (char*)argDst; __system_argv->commandLine = (char*)argDst;
__system_argv->length = argSize; __system_argv->length = argSize;
@ -153,7 +169,7 @@ void resetMemory_ARM7 (void)
int i; int i;
u8 settings1, settings2; u8 settings1, settings2;
u32 settingsOffset = 0; u32 settingsOffset = 0;
REG_IME = 0; REG_IME = 0;
for (i=0; i<16; i++) { for (i=0; i<16; i++) {
@ -173,7 +189,7 @@ void resetMemory_ARM7 (void)
TIMER_CR(i) = 0; TIMER_CR(i) = 0;
TIMER_DATA(i) = 0; TIMER_DATA(i) = 0;
} }
arm7clearRAM(); arm7clearRAM();
REG_IE = 0; REG_IE = 0;
@ -181,20 +197,25 @@ void resetMemory_ARM7 (void)
(*(vu32*)(0x04000000-4)) = 0; //IRQ_HANDLER ARM7 version (*(vu32*)(0x04000000-4)) = 0; //IRQ_HANDLER ARM7 version
(*(vu32*)(0x04000000-8)) = ~0; //VBLANK_INTR_WAIT_FLAGS, ARM7 version (*(vu32*)(0x04000000-8)) = ~0; //VBLANK_INTR_WAIT_FLAGS, ARM7 version
REG_POWERCNT = 1; //turn off power to stuff REG_POWERCNT = 1; //turn off power to stuff
// Get settings location // Get settings location
boot_readFirmware((u32)0x00020, (u8*)&settingsOffset, 0x2); boot_readFirmware((u32)0x00020, (u8*)&settingsOffset, 0x2);
settingsOffset *= 8; settingsOffset *= 8;
// Reload DS Firmware settings // Reload DS Firmware settings
boot_readFirmware(settingsOffset + 0x070, &settings1, 0x1); boot_readFirmware(settingsOffset + 0x070, &settings1, 0x1);
boot_readFirmware(settingsOffset + 0x170, &settings2, 0x1); boot_readFirmware(settingsOffset + 0x170, &settings2, 0x1);
if ((settings1 & 0x7F) == ((settings2+1) & 0x7F)) { if ((settings1 & 0x7F) == ((settings2+1) & 0x7F)) {
boot_readFirmware(settingsOffset + 0x000, (u8*)0x02FFFC80, 0x70); boot_readFirmware(settingsOffset + 0x000, (u8*)0x02FFFC80, 0x70);
} else { } else {
boot_readFirmware(settingsOffset + 0x100, (u8*)0x02FFFC80, 0x70); boot_readFirmware(settingsOffset + 0x100, (u8*)0x02FFFC80, 0x70);
} }
((vu32*)0x040044f0)[2] = 0x202DDD1D;
((vu32*)0x040044f0)[3] = 0xE1A00005;
while((*(vu32*)0x04004400) & 0x2000000);
} }
@ -212,7 +233,7 @@ void loadBinary_ARM7 (u32 fileCluster)
u32 ARM7_SRC = ndsHeader[0x030>>2]; u32 ARM7_SRC = ndsHeader[0x030>>2];
char* ARM7_DST = (char*)ndsHeader[0x038>>2]; char* ARM7_DST = (char*)ndsHeader[0x038>>2];
u32 ARM7_LEN = ndsHeader[0x03C>>2]; u32 ARM7_LEN = ndsHeader[0x03C>>2];
// Load binaries into memory // Load binaries into memory
fileRead(ARM9_DST, fileCluster, ARM9_SRC, ARM9_LEN); fileRead(ARM9_DST, fileCluster, ARM9_SRC, ARM9_LEN);
fileRead(ARM7_DST, fileCluster, ARM7_SRC, ARM7_LEN); fileRead(ARM7_DST, fileCluster, ARM7_SRC, ARM7_LEN);
@ -222,6 +243,24 @@ void loadBinary_ARM7 (u32 fileCluster)
TEMP_ARM9_START_ADDRESS = ndsHeader[0x024>>2]; // Store for later TEMP_ARM9_START_ADDRESS = ndsHeader[0x024>>2]; // Store for later
ndsHeader[0x024>>2] = 0; ndsHeader[0x024>>2] = 0;
dmaCopyWords(3, (void*)ndsHeader, (void*)NDS_HEAD, 0x170); dmaCopyWords(3, (void*)ndsHeader, (void*)NDS_HEAD, 0x170);
if (dsiMode && (ndsHeader[0x10>>2]&BIT(16+1)))
{
// Read full TWL header
fileRead((char*)TWL_HEAD, fileCluster, 0, 0x1000);
u32 ARM9i_SRC = *(u32*)(TWL_HEAD+0x1C0);
char* ARM9i_DST = (char*)*(u32*)(TWL_HEAD+0x1C8);
u32 ARM9i_LEN = *(u32*)(TWL_HEAD+0x1CC);
u32 ARM7i_SRC = *(u32*)(TWL_HEAD+0x1D0);
char* ARM7i_DST = (char*)*(u32*)(TWL_HEAD+0x1D8);
u32 ARM7i_LEN = *(u32*)(TWL_HEAD+0x1DC);
if (ARM9i_LEN)
fileRead(ARM9i_DST, fileCluster, ARM9i_SRC, ARM9i_LEN);
if (ARM7i_LEN)
fileRead(ARM7i_DST, fileCluster, ARM7i_SRC, ARM7i_LEN);
}
} }
/*------------------------------------------------------------------------- /*-------------------------------------------------------------------------
@ -231,7 +270,7 @@ Written by Darkain.
Modified by Chishm: Modified by Chishm:
* Removed MultiNDS specific stuff * Removed MultiNDS specific stuff
--------------------------------------------------------------------------*/ --------------------------------------------------------------------------*/
void startBinary_ARM7 (void) { void startBinary_ARM7 (void) {
REG_IME=0; REG_IME=0;
while(REG_VCOUNT!=191); while(REG_VCOUNT!=191);
while(REG_VCOUNT==191); while(REG_VCOUNT==191);
@ -242,7 +281,7 @@ void startBinary_ARM7 (void) {
VoidFn arm7code = *(VoidFn*)(0x2FFFE34); VoidFn arm7code = *(VoidFn*)(0x2FFFE34);
arm7code(); arm7code();
} }
#ifndef NO_SDMMC
int sdmmc_sd_readsectors(u32 sector_no, u32 numsectors, void *out); int sdmmc_sd_readsectors(u32 sector_no, u32 numsectors, void *out);
//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
// Main function // Main function
@ -251,21 +290,29 @@ bool sdmmc_inserted() {
} }
bool sdmmc_startup() { bool sdmmc_startup() {
sdmmc_controller_init(); sdmmc_controller_init(true);
return sdmmc_sdcard_init() == 0; return sdmmc_sdcard_init() == 0;
} }
bool sdmmc_readsectors(u32 sector_no, u32 numsectors, void *out) { bool sdmmc_readsectors(u32 sector_no, u32 numsectors, void *out) {
return sdmmc_sdcard_readsectors(sector_no, numsectors, out) == 0; return sdmmc_sdcard_readsectors(sector_no, numsectors, out) == 0;
} }
#endif
void mpu_reset();
void mpu_reset_end();
int main (void) { int main (void) {
if (dsiSD) { #ifdef NO_DLDI
dsiSD = true;
dsiMode = true;
#endif
#ifndef NO_SDMMC
if (dsiSD && dsiMode) {
_io_dldi.fn_readSectors = sdmmc_readsectors; _io_dldi.fn_readSectors = sdmmc_readsectors;
_io_dldi.fn_isInserted = sdmmc_inserted; _io_dldi.fn_isInserted = sdmmc_inserted;
_io_dldi.fn_startup = sdmmc_startup; _io_dldi.fn_startup = sdmmc_startup;
} }
#endif
u32 fileCluster = storedFileCluster; u32 fileCluster = storedFileCluster;
// Init card // Init card
if(!FAT_InitFiles(initDisc)) if(!FAT_InitFiles(initDisc))
@ -280,7 +327,7 @@ int main (void) {
{ {
return -1; return -1;
} }
// ARM9 clears its memory part 2 // ARM9 clears its memory part 2
// copy ARM9 function to RAM, and make the ARM9 jump to it // copy ARM9 function to RAM, and make the ARM9 jump to it
copyLoop((void*)TEMP_MEM, (void*)resetMemory2_ARM9, resetMemory2_ARM9_size); copyLoop((void*)TEMP_MEM, (void*)resetMemory2_ARM9, resetMemory2_ARM9_size);
@ -288,9 +335,16 @@ int main (void) {
// Wait until the ARM9 has completed its task // Wait until the ARM9 has completed its task
while ((*(vu32*)0x02FFFE24) == (u32)TEMP_MEM); while ((*(vu32*)0x02FFFE24) == (u32)TEMP_MEM);
// ARM9 sets up mpu
// copy ARM9 function to RAM, and make the ARM9 jump to it
copyLoop((void*)TEMP_MEM, (void*)mpu_reset, mpu_reset_end - mpu_reset);
(*(vu32*)0x02FFFE24) = (u32)TEMP_MEM; // Make ARM9 jump to the function
// Wait until the ARM9 has completed its task
while ((*(vu32*)0x02FFFE24) == (u32)TEMP_MEM);
// Get ARM7 to clear RAM // Get ARM7 to clear RAM
resetMemory_ARM7(); resetMemory_ARM7();
// ARM9 enters a wait loop // ARM9 enters a wait loop
// copy ARM9 function to RAM, and make the ARM9 jump to it // copy ARM9 function to RAM, and make the ARM9 jump to it
copyLoop((void*)TEMP_MEM, (void*)startBinary_ARM9, startBinary_ARM9_size); copyLoop((void*)TEMP_MEM, (void*)startBinary_ARM9, startBinary_ARM9_size);
@ -298,12 +352,19 @@ int main (void) {
// Load the NDS file // Load the NDS file
loadBinary_ARM7(fileCluster); loadBinary_ARM7(fileCluster);
#ifndef NO_DLDI
// Patch with DLDI if desired // Patch with DLDI if desired
if (wantToPatchDLDI) { if (wantToPatchDLDI) {
dldiPatchBinary ((u8*)((u32*)NDS_HEAD)[0x0A], ((u32*)NDS_HEAD)[0x0B]); dldiPatchBinary ((u8*)((u32*)NDS_HEAD)[0x0A], ((u32*)NDS_HEAD)[0x0B]);
} }
#endif
#ifndef NO_SDMMC
if (dsiSD && dsiMode) {
sdmmc_controller_init(true);
}
#endif
// Pass command line arguments to loaded program // Pass command line arguments to loaded program
passArgs_ARM7(); passArgs_ARM7();

View File

@ -3,8 +3,6 @@
#define resetMemory2_ARM9_size 0x400 #define resetMemory2_ARM9_size 0x400
void __attribute__ ((long_call)) __attribute__((naked)) __attribute__((noreturn)) resetMemory2_ARM9(); void __attribute__ ((long_call)) __attribute__((naked)) __attribute__((noreturn)) resetMemory2_ARM9();
#define clearMasterBright_ARM9_size 0x200
void __attribute__ ((long_call)) __attribute__((naked)) __attribute__((noreturn)) clearMasterBright_ARM9();
#define startBinary_ARM9_size 0x100 #define startBinary_ARM9_size 0x100
void __attribute__ ((long_call)) __attribute__((noreturn)) __attribute__((naked)) startBinary_ARM9 (); void __attribute__ ((long_call)) __attribute__((noreturn)) __attribute__((naked)) startBinary_ARM9 ();
#define ARM9_START_FLAG (*(vu8*)0x02FFFDFB) #define ARM9_START_FLAG (*(vu8*)0x02FFFDFB)

View File

@ -29,6 +29,7 @@
.global argStart .global argStart
.global argSize .global argSize
.global dsiSD .global dsiSD
.global dsiMode
@--------------------------------------------------------------------------------- @---------------------------------------------------------------------------------
.align 4 .align 4
.arm .arm
@ -52,6 +53,8 @@ dldiOffset:
.word _dldi_start - _start .word _dldi_start - _start
dsiSD: dsiSD:
.word 0 .word 0
dsiMode:
.word 0
startUp: startUp:
mov r0, #0x04000000 mov r0, #0x04000000

View File

@ -48,13 +48,6 @@ void sdmmc_send_command(struct mmcdevice *ctx, uint32_t cmd, uint32_t args) {
sdmmc_write16(REG_SDIRMASK1,0); sdmmc_write16(REG_SDIRMASK1,0);
sdmmc_write16(REG_SDSTATUS0,0); sdmmc_write16(REG_SDSTATUS0,0);
sdmmc_write16(REG_SDSTATUS1,0); sdmmc_write16(REG_SDSTATUS1,0);
#ifdef DATA32_SUPPORT
// if(readdata)sdmmc_mask16(REG_DATACTL32, 0x1000, 0x800);
// if(writedata)sdmmc_mask16(REG_DATACTL32, 0x800, 0x1000);
// sdmmc_mask16(REG_DATACTL32,0x1800,2);
#else
sdmmc_mask16(REG_DATACTL32,0x1800,0);
#endif
sdmmc_write16(REG_SDCMDARG0,args &0xFFFF); sdmmc_write16(REG_SDCMDARG0,args &0xFFFF);
sdmmc_write16(REG_SDCMDARG1,args >> 16); sdmmc_write16(REG_SDCMDARG1,args >> 16);
sdmmc_write16(REG_SDCMD,cmd &0xFFFF); sdmmc_write16(REG_SDCMD,cmd &0xFFFF);
@ -70,30 +63,22 @@ void sdmmc_send_command(struct mmcdevice *ctx, uint32_t cmd, uint32_t args) {
while(1) { while(1) {
volatile uint16_t status1 = sdmmc_read16(REG_SDSTATUS1); volatile uint16_t status1 = sdmmc_read16(REG_SDSTATUS1);
#ifdef DATA32_SUPPORT
volatile uint16_t ctl32 = sdmmc_read16(REG_SDDATACTL32); volatile uint16_t ctl32 = sdmmc_read16(REG_SDDATACTL32);
if((ctl32 & 0x100)) if((ctl32 & 0x100))
#else
if((status1 & TMIO_STAT1_RXRDY))
#endif
{ {
if(readdata) { if(readdata) {
if(useBuf) { if(useBuf) {
sdmmc_mask16(REG_SDSTATUS1, TMIO_STAT1_RXRDY, 0); sdmmc_mask16(REG_SDSTATUS1, TMIO_STAT1_RXRDY, 0);
if(size > 0x1FF) { if(size > 0x1FF) {
#ifdef DATA32_SUPPORT
if(useBuf32) { if(useBuf32) {
for(i = 0; i<0x200; i+=4) { for(i = 0; i<0x200; i+=4) {
*dataPtr32++ = sdmmc_read32(REG_SDFIFO32); *dataPtr32++ = sdmmc_read32(REG_SDFIFO32);
} }
} else { } else {
#endif
for(i = 0; i<0x200; i+=2) { for(i = 0; i<0x200; i+=2) {
*dataPtr++ = sdmmc_read16(REG_SDFIFO); *dataPtr++ = sdmmc_read16(REG_SDFIFO);
} }
#ifdef DATA32_SUPPORT
} }
#endif
size -= 0x200; size -= 0x200;
} }
} }
@ -101,33 +86,7 @@ void sdmmc_send_command(struct mmcdevice *ctx, uint32_t cmd, uint32_t args) {
sdmmc_mask16(REG_SDDATACTL32, 0x800, 0); sdmmc_mask16(REG_SDDATACTL32, 0x800, 0);
} }
} }
#ifdef DATA32_SUPPORT
if(!(ctl32 & 0x200))
#else
if((status1 & TMIO_STAT1_TXRQ))
#endif
{
if(writedata) {
if(useBuf) {
sdmmc_mask16(REG_SDSTATUS1, TMIO_STAT1_TXRQ, 0);
//sdmmc_write16(REG_SDSTATUS1,~TMIO_STAT1_TXRQ);
if(size > 0x1FF) {
#ifdef DATA32_SUPPORT
for(i = 0; i<0x200; i+=4) {
sdmmc_write32(REG_SDFIFO32,*dataPtr32++);
}
#else
for(i = 0; i<0x200; i+=2) {
sdmmc_write16(REG_SDFIFO,*dataPtr++);
}
#endif
size -= 0x200;
}
}
sdmmc_mask16(REG_SDDATACTL32, 0x1000, 0);
}
}
if(status1 & TMIO_MASK_GW) { if(status1 & TMIO_MASK_GW) {
ctx->error |= 4; ctx->error |= 4;
break; break;
@ -178,21 +137,11 @@ void sdmmc_controller_init(bool force) {
*(vu16*)(SDMMC_BASE + REG_SDDATACTL32) &= 0xF7FFu; *(vu16*)(SDMMC_BASE + REG_SDDATACTL32) &= 0xF7FFu;
*(vu16*)(SDMMC_BASE + REG_SDDATACTL32) &= 0xEFFFu; *(vu16*)(SDMMC_BASE + REG_SDDATACTL32) &= 0xEFFFu;
#ifdef DATA32_SUPPORT
*(vu16*)(SDMMC_BASE + REG_SDDATACTL32) |= 0x402u; *(vu16*)(SDMMC_BASE + REG_SDDATACTL32) |= 0x402u;
#else
*(vu16*)(SDMMC_BASE + REG_SDDATACTL32) |= 0x402u;
#endif
*(vu16*)(SDMMC_BASE + REG_SDDATACTL) = (*(vu16*)(SDMMC_BASE + REG_SDDATACTL) & 0xFFDD) | 2; *(vu16*)(SDMMC_BASE + REG_SDDATACTL) = (*(vu16*)(SDMMC_BASE + REG_SDDATACTL) & 0xFFDD) | 2;
#ifdef DATA32_SUPPORT
*(vu16*)(SDMMC_BASE + REG_SDDATACTL32) &= 0xFFFFu; *(vu16*)(SDMMC_BASE + REG_SDDATACTL32) &= 0xFFFFu;
*(vu16*)(SDMMC_BASE + REG_SDDATACTL) &= 0xFFDFu; *(vu16*)(SDMMC_BASE + REG_SDDATACTL) &= 0xFFDFu;
*(vu16*)(SDMMC_BASE + REG_SDBLKLEN32) = 512; *(vu16*)(SDMMC_BASE + REG_SDBLKLEN32) = 512;
#else
*(vu16*)(SDMMC_BASE + REG_SDDATACTL32) &= 0xFFFDu;
*(vu16*)(SDMMC_BASE + REG_SDDATACTL) &= 0xFFDDu;
*(vu16*)(SDMMC_BASE + REG_SDBLKLEN32) = 0;
#endif
*(vu16*)(SDMMC_BASE + REG_SDBLKCOUNT32) = 1; *(vu16*)(SDMMC_BASE + REG_SDBLKCOUNT32) = 1;
*(vu16*)(SDMMC_BASE + REG_SDRESET) &= 0xFFFEu; *(vu16*)(SDMMC_BASE + REG_SDRESET) &= 0xFFFEu;
*(vu16*)(SDMMC_BASE + REG_SDRESET) |= 1u; *(vu16*)(SDMMC_BASE + REG_SDRESET) |= 1u;
@ -201,18 +150,12 @@ void sdmmc_controller_init(bool force) {
*(vu16*)(SDMMC_BASE + 0x0fc) |= 0xDBu; //SDCTL_RESERVED7 *(vu16*)(SDMMC_BASE + 0x0fc) |= 0xDBu; //SDCTL_RESERVED7
*(vu16*)(SDMMC_BASE + 0x0fe) |= 0xDBu; //SDCTL_RESERVED8 *(vu16*)(SDMMC_BASE + 0x0fe) |= 0xDBu; //SDCTL_RESERVED8
*(vu16*)(SDMMC_BASE + REG_SDPORTSEL) &= 0xFFFCu; *(vu16*)(SDMMC_BASE + REG_SDPORTSEL) &= 0xFFFCu;
#ifdef DATA32_SUPPORT
*(vu16*)(SDMMC_BASE + REG_SDCLKCTL) = 0x20; *(vu16*)(SDMMC_BASE + REG_SDCLKCTL) = 0x20;
*(vu16*)(SDMMC_BASE + REG_SDOPT) = 0x40EE; *(vu16*)(SDMMC_BASE + REG_SDOPT) = 0x40EE;
#else
*(vu16*)(SDMMC_BASE + REG_SDCLKCTL) = 0x40; //Nintendo sets this to 0x20
*(vu16*)(SDMMC_BASE + REG_SDOPT) = 0x40EB; //Nintendo sets this to 0x40EE
#endif
*(vu16*)(SDMMC_BASE + REG_SDPORTSEL) &= 0xFFFCu; *(vu16*)(SDMMC_BASE + REG_SDPORTSEL) &= 0xFFFCu;
*(vu16*)(SDMMC_BASE + REG_SDBLKLEN) = 512; *(vu16*)(SDMMC_BASE + REG_SDBLKLEN) = 512;
*(vu16*)(SDMMC_BASE + REG_SDSTOP) = 0; *(vu16*)(SDMMC_BASE + REG_SDSTOP) = 0;
setTarget(&deviceSD);
} }
//--------------------------------------------------------------------------------- //---------------------------------------------------------------------------------
@ -287,10 +230,8 @@ int sdmmc_sdcard_readsectors(u32 sector_no, u32 numsectors, void *out) {
setTarget(&deviceSD); setTarget(&deviceSD);
sdmmc_write16(REG_SDSTOP,0x100); sdmmc_write16(REG_SDSTOP,0x100);
#ifdef DATA32_SUPPORT
sdmmc_write16(REG_SDBLKCOUNT32,numsectors); sdmmc_write16(REG_SDBLKCOUNT32,numsectors);
sdmmc_write16(REG_SDBLKLEN32,0x200); sdmmc_write16(REG_SDBLKLEN32,0x200);
#endif
sdmmc_write16(REG_SDBLKCOUNT,numsectors); sdmmc_write16(REG_SDBLKCOUNT,numsectors);
deviceSD.data = out; deviceSD.data = out;