diff --git a/arm9/link.ld b/arm9/link.ld index 4f3cfce..e6df812 100644 --- a/arm9/link.ld +++ b/arm9/link.ld @@ -16,8 +16,5 @@ SECTIONS . = ALIGN(4); __end__ = ABSOLUTE(.); - - __stack_abt = 0x22800000; - __stack_top = __stack_abt - 0x80000; __code_size__ = __end__ - __start__; } diff --git a/arm9/source/fatfs/ramdrive.c b/arm9/source/fatfs/ramdrive.c index 6b7797e..c0c5135 100644 --- a/arm9/source/fatfs/ramdrive.c +++ b/arm9/source/fatfs/ramdrive.c @@ -1,5 +1,6 @@ #include "ramdrive.h" #include "unittype.h" +#include "memmap.h" static u8* ramdrv_buffer = NULL; static u32 ramdrv_size = 0; @@ -26,6 +27,6 @@ u64 GetRamDriveSize(void) { } void InitRamDrive(void) { - ramdrv_buffer = RAMDRV_BUFFER; - ramdrv_size = (IS_O3DS || IS_SIGHAX) ? RAMDRV_SIZE_O3DS : RAMDRV_SIZE_N3DS; + ramdrv_buffer = (u8*) __RAMDRV_ADDR; + ramdrv_size = ((IS_O3DS || IS_SIGHAX) ? __RAMDRV_END : __RAMDRV_END_N) - __RAMDRV_ADDR; } diff --git a/arm9/source/nand/nand.c b/arm9/source/nand/nand.c index adc5928..d3b46bd 100644 --- a/arm9/source/nand/nand.c +++ b/arm9/source/nand/nand.c @@ -6,6 +6,7 @@ #include "fatmbr.h" #include "sdmmc.h" #include "image.h" +#include "memmap.h" #define KEY95_SHA256 ((IS_DEVKIT) ? slot0x11Key95dev_sha256 : slot0x11Key95_sha256) @@ -87,7 +88,7 @@ bool InitNandCrypto(bool init_full) // on a9lh this MUST be run before accessing the SHA register in any other way if (IS_UNLOCKED) { // if OTP is unlocked // see: https://www.3dbrew.org/wiki/OTP_Registers - sha_quick(OtpSha256, (u8*) 0x10012000, 0x90, SHA256_MODE); + sha_quick(OtpSha256, (u8*) __OTP_ADDR, 0x90, SHA256_MODE); Crypto0x96 = true; // valid 100% in that case, others need checking } else if (IS_A9LH) { // for a9lh // store the current SHA256 from register @@ -116,7 +117,7 @@ bool InitNandCrypto(bool init_full) if (GetNandPartitionInfo(NULL, NP_TYPE_FAT, NP_SUBTYPE_TWL, 0, NAND_SYSNAND) != 0) { u64 TwlCustId = 0; // TWL customer ID (different for devkits) if (!IS_DEVKIT) TwlCustId = 0x80000000ULL | (*(vu64 *)0x01FFB808 ^ 0x8C267B7B358A6AFULL); - else if (IS_UNLOCKED) TwlCustId = (*(vu64*)0x10012000); + else if (IS_UNLOCKED) TwlCustId = (*(vu64*)__OTP_ADDR); if (!TwlCustId && IS_DEVKIT) { u64 __attribute__((aligned(32))) otp0x10[2]; if (GetOtp0x90(otp0x10, 0x10)) TwlCustId = *otp0x10; diff --git a/arm9/source/start.s b/arm9/source/start.s index 67e9643..bdd9be6 100644 --- a/arm9/source/start.s +++ b/arm9/source/start.s @@ -5,7 +5,7 @@ #include #include #include -#include +#include "memmap.h" .global _start _start: @@ -103,7 +103,7 @@ _start: @ Switch to system mode, disable interrupts, setup application stack msr cpsr_c, #(SR_SYS_MODE | SR_IRQ | SR_FIQ) - ldr sp, =__stack_top + ldr sp, =__STACK_TOP @ Check entrypoints diff --git a/arm9/source/system/itcm.h b/arm9/source/system/itcm.h index ba20245..518012e 100644 --- a/arm9/source/system/itcm.h +++ b/arm9/source/system/itcm.h @@ -3,6 +3,7 @@ // This file contains the structure of ITCM on the ARM9, as initialized by boot9. #include "common.h" +#include "memmap.h" // Structure of the decrypted version of the OTP. Part of this is in ITCM. @@ -168,4 +169,4 @@ STATIC_ASSERT(sizeof(Arm9Itcm) == 0x8000); // Macro for accessing ITCM. -#define ARM9_ITCM ((Arm9Itcm*) 0x01FF8000) +#define ARM9_ITCM ((Arm9Itcm*) __ITCM_ADDR) diff --git a/arm9/source/system/memmap.h b/arm9/source/system/memmap.h index 0a74823..a0239c5 100644 --- a/arm9/source/system/memmap.h +++ b/arm9/source/system/memmap.h @@ -3,20 +3,55 @@ // general memory areas +#define __ITCM_ADDR 0x01FF8000 +#define __ITCM_LEN 0x00008000 + +#define __DTCM_ADDR 0x30008000 +#define __DTCM_LEN 0x00004000 + +#define __A9RAM0_ADDR 0x08000000 +#define __A9RAM0_LEN 0x00100000 + +#define __A9RAM1_ADDR 0x08100000 +#define __A9RAM1_LEN 0x00080000 + +#define __VRAM_ADDR 0x18000000 +#define __VRAM_LEN 0x00600000 + +#define __DSP_ADDR 0x1FF00000 +#define __DSP_LEN 0x00080000 + +#define __AWRAM_ADDR 0x1FF80000 +#define __AWRAM_LEN 0x00080000 + +#define __OTP_ADDR 0x10012000 +#define __OTP_LEN 0x00000100 + #define __FCRAM0_ADDR 0x20000000 #define __FCRAM0_END 0x28000000 +#define __FCRAM0_LEN (__FCRAM0_END - __FCRAM0_ADDR) #define __FCRAM1_ADDR 0x28000000 #define __FCRAM1_END 0x30000000 +#define __FCRAM1_LEN (__FCRAM1_END - __FCRAM1_ADDR) +// offsets provided by SciresM, only available if booted on b9s + +#define __BOOT9_ADDR 0x08080000 +#define __BOOT9_LEN 0x00010000 + +#define __BOOT11_ADDR 0x08090000 +#define __BOOT11_LEN 0x00010000 + // stuff in FCRAM #define __FIRMTMP_ADDR (__FCRAM0_END - 0x0800000) #define __FIRMTMP_END (__FIRMTMP_ADDR + 0x0400000) #define __RAMDRV_ADDR (__FCRAM0_ADDR + 0x2800000) -#define __RAMDRV_END __FCRAM0_END // can be bigger on N3DS +#define __RAMDRV_END __FCRAM0_END +#define __RAMDRV_END_N __FCRAM1_END #define __STACK_ABT_TOP __RAMDRV_ADDR #define __STACK_ABT_LEN 0x10000 diff --git a/arm9/source/system/xrq.c b/arm9/source/system/xrq.c index c95d586..f66db41 100644 --- a/arm9/source/system/xrq.c +++ b/arm9/source/system/xrq.c @@ -11,6 +11,7 @@ #include "rtc.h" #include "hid.h" #include "ui.h" +#include "memmap.h" #include @@ -42,7 +43,6 @@ const char *XRQ_Name[] = { "Data Abort", "Reserved", "IRQ", "FIQ" }; -extern char __stack_top; void XRQ_DumpRegisters(u32 xrq, u32 *regs) { @@ -77,7 +77,7 @@ void XRQ_DumpRegisters(u32 xrq, u32 *regs) /* Dump STACK */ sp = regs[13] & ~0xF; - st = (u32)&__stack_top; + st = __STACK_TOP; wstr += sprintf(wstr, "Stack dump:\n"); wstr += XRQ_DumpData_u8(wstr, sp, min(sp+SP_DUMPLEN, st)); wstr += sprintf(wstr, "\n"); diff --git a/arm9/source/system/xrq_handler.s b/arm9/source/system/xrq_handler.s index 71a3a66..db20b4f 100644 --- a/arm9/source/system/xrq_handler.s +++ b/arm9/source/system/xrq_handler.s @@ -8,9 +8,10 @@ #include #include +#include "memmap.h" .macro XRQ_FATAL id=0 - ldr sp, =__stack_abt + ldr sp, =__STACK_ABT_TOP sub sp, sp, #(18*4) @ Reserve space for registers stmia sp, {r0-r12} mov r11, #\id diff --git a/arm9/source/utils/nandutil.c b/arm9/source/utils/nandutil.c index 385a0a9..a0e6270 100644 --- a/arm9/source/utils/nandutil.c +++ b/arm9/source/utils/nandutil.c @@ -12,6 +12,7 @@ #include "keydb.h" // for perfect keydb hash and length #include "essentials.h" // for essential backup struct #include "unittype.h" +#include "memmap.h" static const u8 twl_mbr_std[0x42] = { @@ -84,7 +85,7 @@ u32 BuildEssentialBackup(const char* path, EssentialBackup* essential) { // fill nand cid / otp hash sdmmc_get_cid(1, (u32*) (void*) &(essential->nand_cid)); if (!IS_UNLOCKED) memset(&(filelist[5]), 0, 3 * sizeof(ExeFsFileHeader)); - else memcpy(&(essential->otp), (u8*) 0x10012000, 0x100); + else memcpy(&(essential->otp), (u8*) __OTP_ADDR, 0x100); // calculate hashes for (u32 i = 0; i < 8 && *(filelist[i].name); i++) diff --git a/arm9/source/virtual/vmem.c b/arm9/source/virtual/vmem.c index eca8533..7fd223d 100644 --- a/arm9/source/virtual/vmem.c +++ b/arm9/source/virtual/vmem.c @@ -14,15 +14,9 @@ #define VFLAG_OTP (1UL<<30) #define VFLAG_N3DS_EXT (1UL<<31) -// offsets provided by SciresM -#define BOOT9_POS 0x08080000 -#define BOOT11_POS 0x08090000 -#define BOOT9_LEN 0x00010000 -#define BOOT11_LEN 0x00010000 - // checks for boot9 / boot11 -#define HAS_BOOT9 (sha_cmp(boot9_sha256, (u8*) BOOT9_POS, BOOT9_LEN, SHA256_MODE) == 0) -#define HAS_BOOT11 (sha_cmp(boot11_sha256, (u8*) BOOT11_POS, BOOT11_LEN, SHA256_MODE) == 0) +#define HAS_BOOT9 (sha_cmp(boot9_sha256, (u8*) __BOOT9_ADDR, __BOOT9_LEN, SHA256_MODE) == 0) +#define HAS_BOOT11 (sha_cmp(boot11_sha256, (u8*) __BOOT11_ADDR, __BOOT11_LEN, SHA256_MODE) == 0) // see: https://www.youtube.com/watch?v=wogNzUypLuI u8 boot9_sha256[0x20] = { @@ -35,10 +29,8 @@ u8 boot11_sha256[0x20] = { }; // see: https://github.com/SciresM/CTRAesEngine/blob/8312adc74b911a6b9cb9e03982ba3768b8e2e69c/CTRAesEngine/AesEngine.cs#L672-L688 -#define OTP_KEY ((u8*) BOOT9_POS + ((IS_DEVKIT) ? + 0xD700 : 0xD6E0)) +#define OTP_KEY ((u8*) __BOOT9_ADDR + ((IS_DEVKIT) ? + 0xD700 : 0xD6E0)) #define OTP_IV (OTP_KEY + 0x10) -#define OTP_POS 0x10012000 -#define OTP_LEN sizeof(Otp) // Custom read/write handlers. typedef int ReadVMemFileCallback(const VirtualFile* vfile, void* buffer, u64 offset, u64 count); @@ -66,24 +58,24 @@ STATIC_ASSERT(sizeof(vMemCallbacks) / sizeof(vMemCallbacks[0]) == VMEM_NUM_CALLB // see: http://3dbrew.org/wiki/Memory_layout#ARM9 static const VirtualFile vMemFileTemplates[] = { - { "itcm.mem" , 0x01FF8000, 0x00008000, 0xFF, 0 }, - { "arm9.mem" , 0x08000000, 0x00100000, 0xFF, 0 }, - { "arm9ext.mem" , 0x08100000, 0x00080000, 0xFF, VFLAG_N3DS_EXT }, - { "boot9.bin" , BOOT9_POS , BOOT9_LEN , 0xFF, VFLAG_READONLY | VFLAG_BOOT9 }, - { "boot11.bin" , BOOT11_POS, BOOT11_LEN, 0xFF, VFLAG_READONLY | VFLAG_BOOT11 }, - { "vram.mem" , 0x18000000, 0x00600000, 0xFF, 0 }, - { "dsp.mem" , 0x1FF00000, 0x00080000, 0xFF, 0 }, - { "axiwram.mem" , 0x1FF80000, 0x00080000, 0xFF, 0 }, - { "fcram.mem" , 0x20000000, 0x08000000, 0xFF, 0 }, - { "fcramext.mem" , 0x28000000, 0x08000000, 0xFF, VFLAG_N3DS_EXT }, - { "dtcm.mem" , 0x30008000, 0x00004000, 0xFF, 0 }, - { "otp.mem" , OTP_POS , OTP_LEN , 0xFF, VFLAG_READONLY | VFLAG_OTP }, + { "itcm.mem" , __ITCM_ADDR , __ITCM_LEN , 0xFF, 0 }, + { "arm9.mem" , __A9RAM0_ADDR, __A9RAM0_LEN, 0xFF, 0 }, + { "arm9ext.mem" , __A9RAM1_ADDR, __A9RAM1_LEN, 0xFF, VFLAG_N3DS_EXT }, + { "boot9.bin" , __BOOT9_ADDR , __BOOT9_LEN , 0xFF, VFLAG_READONLY | VFLAG_BOOT9 }, + { "boot11.bin" , __BOOT11_ADDR, __BOOT11_LEN, 0xFF, VFLAG_READONLY | VFLAG_BOOT11 }, + { "vram.mem" , __VRAM_ADDR , __VRAM_LEN , 0xFF, 0 }, + { "dsp.mem" , __DSP_ADDR , __DSP_LEN , 0xFF, 0 }, + { "axiwram.mem" , __AWRAM_ADDR , __AWRAM_LEN , 0xFF, 0 }, + { "fcram.mem" , __FCRAM0_ADDR, __FCRAM0_LEN, 0xFF, 0 }, + { "fcramext.mem" , __FCRAM1_ADDR, __FCRAM1_LEN, 0xFF, VFLAG_N3DS_EXT }, + { "dtcm.mem" , __DTCM_ADDR , __DTCM_LEN , 0xFF, 0 }, + { "otp.mem" , __OTP_ADDR , __OTP_LEN , 0xFF, VFLAG_READONLY | VFLAG_OTP }, // { "bootrom.mem" , 0xFFFF0000, 0x00010000, 0xFF, 0 }, // { "bootrom_unp.mem" , 0xFFFF0000, 0x00008000, 0xFF, 0 } // Custom callback implementations. // Keyslot field has arbitrary meaning, and may not actually be a keyslot. - { "otp_dec.mem" , VMEM_CALLBACK_OTP_DECRYPTED, OTP_LEN , 0x11, VFLAG_CALLBACK | VFLAG_READONLY | VFLAG_OTP }, + { "otp_dec.mem" , VMEM_CALLBACK_OTP_DECRYPTED, __OTP_LEN , 0x11, VFLAG_CALLBACK | VFLAG_READONLY | VFLAG_OTP }, { "mcu_3ds_regs.mem" , VMEM_CALLBACK_MCU_REGISTERS, 0x00000100, I2C_DEV_MCU, VFLAG_CALLBACK | VFLAG_READONLY }, { "mcu_dsi_regs.mem" , VMEM_CALLBACK_MCU_REGISTERS, 0x00000100, I2C_DEV_POWER, VFLAG_CALLBACK | VFLAG_READONLY }, { "sd_cid.mem" , VMEM_CALLBACK_FLASH_CID , 0x00000010, 0x00, VFLAG_CALLBACK | VFLAG_READONLY }, @@ -117,10 +109,10 @@ bool ReadVMemDir(VirtualFile* vfile, VirtualDir* vdir) { // uses a generic vdir int ReadVMemOTPDecrypted(const VirtualFile* vfile, void* buffer, u64 offset, u64 count) { (void) vfile; - alignas(32) u8 otp_local[OTP_LEN]; + alignas(32) u8 otp_local[__OTP_LEN]; alignas(32) u8 otp_iv[0x10]; alignas(32) u8 otp_key[0x10]; - u8* otp_mem = (u8*) OTP_POS; + u8* otp_mem = (u8*) __OTP_ADDR; if (HAS_BOOT9) { // easy setup when boot9 available memcpy(otp_iv, OTP_IV, 0x10); @@ -133,7 +125,7 @@ int ReadVMemOTPDecrypted(const VirtualFile* vfile, void* buffer, u64 offset, u64 setup_aeskey(0x11, otp_key); use_aeskey(0x11); - cbc_decrypt(otp_mem, otp_local, OTP_LEN / 0x10, AES_CNT_TITLEKEY_DECRYPT_MODE, otp_iv); + cbc_decrypt(otp_mem, otp_local, __OTP_LEN / 0x10, AES_CNT_TITLEKEY_DECRYPT_MODE, otp_iv); memcpy(buffer, otp_local + offset, count); return 0; }