Skip to content

Commit 46eaeea

Browse files
authored
Slot1launch: Fix DSi CPU clock setting and fix reading ARM9i secure area (#2596)
* slot1launch: Fix DSi CPU clock setting * slot1launch: Fix reading ARM9i secure area
1 parent 4cfdc51 commit 46eaeea

File tree

8 files changed

+135
-18
lines changed

8 files changed

+135
-18
lines changed

compile_docker.sh

100644100755
File mode changed.

slot1launch/bootloader/Makefile

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,8 @@ INCLUDES := build source $(UNIVERSAL)/include
2222
#INCLUDES := build source $(UNIVERSAL)/include $(DSIMODE_FULL_SOURCES)
2323
DATA := ../data
2424
SPECS := specs
25+
CARDENGINE_BIN := cardengine_arm7.bin
26+
#CARDENGINE_BIN :=
2527

2628
#---------------------------------------------------------------------------------
2729
# options for code generation
@@ -69,7 +71,7 @@ export OBJCOPY := $(PREFIX)objcopy
6971
CFILES := $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.c)))
7072
CPPFILES := $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.cpp)))
7173
SFILES := $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.s)))
72-
BINFILES := cardengine_arm7.bin
74+
BINFILES := $(CARDENGINE_BIN)
7375

7476
export OFILES := $(addsuffix .o,$(BINFILES)) $(CPPFILES:.cpp=.o) $(CFILES:.c=.o) $(SFILES:.s=.o)
7577

slot1launch/bootloader/source/common.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,10 @@
2222
#include <nds/dma.h>
2323
#include <stdlib.h>
2424

25+
// Enable compiling support for launching games in DSi mode.
26+
// For now, requires removing the cardengine...
27+
//#define FULL_DSI_MODE_ENABLED
28+
2529
#define resetCpu() \
2630
__asm volatile("swi 0x000000")
2731

@@ -59,6 +63,7 @@ extern tNDSHeader* ndsHeader;
5963
extern bool dsiModeConfirmed;
6064
extern bool arm9_boostVram;
6165
extern bool arm9_scfgUnlock;
66+
extern bool arm9_twlClock;
6267
extern bool arm9_extendedMemory;
6368
extern bool arm9_isSdk5;
6469
extern volatile int arm9_stateFlag;

slot1launch/bootloader/source/main.arm7.c

Lines changed: 14 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -52,24 +52,27 @@
5252

5353
#define REG_GPIO_WIFI *(vu16*)0x4004C04
5454

55-
//#define FULL_DSI_MODE_ENABLED
56-
5755
#include "common.h"
5856
#include "dmaTwl.h"
5957
#include "common/tonccpy.h"
6058
#include "read_card.h"
6159
#include "module_params.h"
62-
#include "cardengine_arm7_bin.h"
6360
#include "hook.h"
6461
#include "find.h"
6562

6663
#ifdef FULL_DSI_MODE_ENABLED
64+
// Needed due to size
65+
#define SKIP_CARDENGINE_ARM7
6766
#include "gm9i/crypto.h"
6867
#include "gm9i/f_xy.h"
6968
#include "twltool/dsi.h"
7069
#include "u128_math.h"
7170
#endif
7271

72+
#ifndef SKIP_CARDENGINE_ARM7
73+
#include "cardengine_arm7_bin.h"
74+
#endif
75+
7376
extern bool __dsimode;
7477
extern u32 dsiMode;
7578
extern u32 language;
@@ -1061,14 +1064,14 @@ void arm7_main (void) {
10611064

10621065
REG_GPIO_WIFI |= BIT(8); // Old NDS-Wifi mode
10631066

1064-
if (twlClock) {
1065-
REG_SCFG_CLK = 0x0181;
1066-
} else {
1067-
REG_SCFG_CLK = 0x0180;
1068-
}
10691067
if (!sdAccess) {
1068+
REG_SCFG_CLK = 0x0180;
10701069
REG_SCFG_EXT = 0x93FBFB06;
10711070
}
1071+
else {
1072+
REG_SCFG_CLK = 0x0181;
1073+
}
1074+
10721075
// Used by ARM7 binaries to determine DSi mode...
10731076
toncset((u8*)0x0380FFC0, 0, 0x10);
10741077
}
@@ -1096,6 +1099,7 @@ void arm7_main (void) {
10961099
runCardEngine = false;
10971100
}
10981101

1102+
#ifndef SKIP_CARDENGINE_ARM7
10991103
if (runCardEngine) {
11001104
// WRAM-A mapped to the 0x37C0000 - 0x37FFFFF area : 256k
11011105
REG_MBK6=0x080037C0;
@@ -1118,12 +1122,14 @@ void arm7_main (void) {
11181122
}
11191123
}
11201124
}
1125+
#endif
11211126
toncset ((void*)0x023F0000, 0, 0x8000); // Clear cheat data from main memory
11221127

11231128
//debugOutput (ERR_STS_START);
11241129

11251130
arm9_boostVram = boostVram;
11261131
arm9_scfgUnlock = scfgUnlock;
1132+
arm9_twlClock = twlClock;
11271133
arm9_isSdk5 = isSdk5(moduleParams);
11281134
arm9_runCardEngine = runCardEngine;
11291135

slot1launch/bootloader/source/main.arm9.c

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,7 @@ bool arm9_runCardEngine = false;
4949
bool dsiModeConfirmed = false;
5050
bool arm9_boostVram = false;
5151
bool arm9_scfgUnlock = false;
52+
bool arm9_twlClock = false;
5253
bool arm9_extendedMemory = false;
5354
bool arm9_isSdk5 = false;
5455

@@ -61,6 +62,7 @@ volatile u32 arm9_BLANK_RAM = 0;
6162
External functions
6263
--------------------------------------------------------------------------*/
6364
extern void arm9_clearCache (void);
65+
extern void arm9_write_to_scfg_clk(uint16_t);
6466

6567

6668
void initMBKARM9() {
@@ -300,13 +302,25 @@ void __attribute__((target("arm"))) arm9_main (void) {
300302
initMBKARM9_dsiMode();
301303
}
302304
REG_SCFG_EXT = 0x8307F100;
303-
REG_SCFG_CLK = 0x87;
305+
// bit 7 is read only in reality...
306+
if(arm9_twlClock)
307+
arm9_write_to_scfg_clk(0x87);
308+
else
309+
arm9_write_to_scfg_clk(0x86);
304310
REG_SCFG_RST = 1;
305311
} else {
306312
REG_SCFG_EXT = (arm9_extendedMemory ? 0x8300C000 : 0x83000000);
307313
if (arm9_boostVram) {
308314
REG_SCFG_EXT |= BIT(13); // Extended VRAM Access
309315
}
316+
// TODO: For now, not enabled to avoid breaking
317+
// certain DSi games...
318+
#ifdef FULL_DSI_MODE_ENABLED
319+
if(arm9_twlClock)
320+
arm9_write_to_scfg_clk(0x01);
321+
else
322+
arm9_write_to_scfg_clk(0x00);
323+
#endif
310324
if (!arm9_scfgUnlock) {
311325
// lock SCFG
312326
REG_SCFG_EXT &= ~(1UL << 31);

slot1launch/bootloader/source/ndsheaderbanner.h

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -85,7 +85,11 @@ typedef struct {
8585
u32 romSize; //!< total size of the ROM.
8686

8787
u32 headerSize; //!< ROM header size.
88-
u32 zeros88[14];
88+
u32 arm9_param_table_offset;
89+
u32 arm7_param_table_offset;
90+
u16 ntr_rom_region_end;
91+
u16 twl_rom_region_start;
92+
u32 zeros94[11];
8993
u8 gbaLogo[156]; //!< Nintendo logo needed for booting the game.
9094
u16 logoCRC16; //!< Nintendo Logo Checksum, CRC-16.
9195
u16 headerCRC16; //!< header checksum, CRC-16.

slot1launch/bootloader/source/read_card.c

Lines changed: 15 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,9 @@
2828
#include "encryption.h"
2929
#include "common.h"
3030

31+
#define TWL_BLOWFISH_TABLE_SIZE 0x3000
32+
#define SINGLE_ROM_REGION_SIZE 0x80000
33+
3134
typedef union
3235
{
3336
char title[4];
@@ -427,13 +430,18 @@ void cardRead (u32 src, u32* dest, size_t size)
427430
src += readSize;
428431
dest += readSize/sizeof(*dest);
429432
size -= readSize;
430-
} else if ((ndsHeader->unitCode != 0) && (src >= ndsHeader->arm9iromOffset) && (src < ndsHeader->arm9iromOffset+CARD_SECURE_AREA_SIZE)) {
431-
// Read data from secure area
432-
readSize = src + size < (ndsHeader->arm9iromOffset+CARD_SECURE_AREA_SIZE) ? size : (ndsHeader->arm9iromOffset+CARD_SECURE_AREA_SIZE) - src;
433-
tonccpy (dest, (u8*)secureArea + src - ndsHeader->arm9iromOffset, readSize);
434-
src += readSize;
435-
dest += readSize/sizeof(*dest);
436-
size -= readSize;
433+
} else if (ndsHeader->unitCode != 0) {
434+
size_t twl_rom_region_start = 0;
435+
if(ndsHeader->twl_rom_region_start != 0)
436+
twl_rom_region_start = (ndsHeader->twl_rom_region_start * SINGLE_ROM_REGION_SIZE) + TWL_BLOWFISH_TABLE_SIZE;
437+
if((twl_rom_region_start != 0) && (src >= twl_rom_region_start) && (src < twl_rom_region_start + CARD_SECURE_AREA_SIZE)) {
438+
// Read data from secure area
439+
readSize = src + size < (twl_rom_region_start+CARD_SECURE_AREA_SIZE) ? size : (twl_rom_region_start+CARD_SECURE_AREA_SIZE) - src;
440+
tonccpy (dest, (u8*)secureArea + src - twl_rom_region_start, readSize);
441+
src += readSize;
442+
dest += readSize/sizeof(*dest);
443+
size -= readSize;
444+
}
437445
}
438446

439447
while (size > 0) {
Lines changed: 78 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,78 @@
1+
#include <nds/asminc.h>
2+
3+
#define ITCM_foo_base 0x00000004
4+
5+
.align 4
6+
.arm
7+
8+
@ Writes a new value to the ARM9 SCFG_CLK.
9+
@ Must be called from ITCM.
10+
@ Must wait 8 clock cycles after changing the value before returning.
11+
@ https://problemkaputt.de/gbatek.htm#dsicontrolregistersscfg
12+
@ Not what I experimentally observed, but better safe than sorry...
13+
@ void _arm9_write_to_scfg_clk(uint16_t new_val);
14+
BEGIN_ASM_FUNC _arm9_write_to_scfg_clk
15+
mov r1, #0x04000000
16+
add r1, #0x4000
17+
strh r0,[r1, #4]
18+
@ Wait 8 clock cycles... Could be done in a better way.
19+
mov r0, #8
20+
wait_loop:
21+
subs r0, r0, #1
22+
bne wait_loop
23+
bx lr
24+
25+
_arm9_write_to_scfg_clk_end:
26+
27+
bx_r1_caller:
28+
bx r1
29+
30+
@ Writes a new value to the ARM9 SCFG_CLK.
31+
@ Copies the right function to ITCM and calls it.
32+
@ void arm9_write_to_scfg_clk(uint16_t new_val);
33+
BEGIN_ASM_FUNC arm9_write_to_scfg_clk
34+
push {r4, lr}
35+
36+
mrc p15, 0, r3, c1, c0, 0 @ Store current Control Register
37+
push {r3}
38+
ldr r2,=#0x00041000 @ Enable ITCM back
39+
orr r3, r3, r2
40+
mvn r2, #1 @ Disabe MMU/PU
41+
and r3, r3, r2
42+
mcr p15, 0, r3, c1, c0, 0 @ Update Control Register
43+
44+
mov r3, #3
45+
mcr p15, 0, r3, c5, c0, 3 @ Enable RW IAccess
46+
47+
mov r1, #ITCM_foo_base @ ITCM foo_base
48+
ldr r2,=_arm9_write_to_scfg_clk
49+
ldr r3,=_arm9_write_to_scfg_clk_end-_arm9_write_to_scfg_clk
50+
itcm_copy_loop:
51+
ldr r4,[r2, #0]
52+
str r4,[r1, #0]
53+
add r1, #4
54+
add r2, #4
55+
subs r3, r3, #4
56+
bne itcm_copy_loop
57+
mov r1, #ITCM_foo_base @ ITCM foo_base
58+
@ Call _arm9_write_to_scfg_clk
59+
bl bx_r1_caller
60+
61+
@ Clear back the ITCM
62+
mov r0, #0
63+
mov r1, #0x00000000 @ ITCM
64+
ldr r3,=#0x00008000 @ Wipe ITCM back
65+
itcm_clear_loop:
66+
str r0,[r1, #0]
67+
add r1, #4
68+
subs r3, r3, #4
69+
bne itcm_clear_loop
70+
71+
mov r3, #0
72+
mcr p15, 0, r3, c7, c5, 0 @ Flush ICache
73+
mcr p15, 0, r3, c5, c0, 3 @ Disable IAccess
74+
75+
pop {r3}
76+
mcr p15, 0, r3, c1, c0, 0 @ Restore old Control Register
77+
78+
pop {r4, pc}

0 commit comments

Comments
 (0)