diff --git a/.gitignore b/.gitignore index e8ab513..8997ce7 100644 --- a/.gitignore +++ b/.gitignore @@ -1,10 +1,10 @@ build9/ build11/ +eclipse_project/ boot3r.sublime-project boot3r.sublime-workspace code9.bin -code9.elf code11.bin +code9.elf code11.elf -firm_builder.exe -test_firm.bin +firm.bin diff --git a/build.bat b/build.bat index 8182ff5..963119e 100644 --- a/build.bat +++ b/build.bat @@ -1,2 +1,2 @@ -make -pause \ No newline at end of file +make +pause diff --git a/build_redo.bat b/build_redo.bat index 3260f43..ac09e8c 100644 --- a/build_redo.bat +++ b/build_redo.bat @@ -1,3 +1,3 @@ -make clean -make -pause +make clean +make +pause diff --git a/clean.bat b/clean.bat index efcd16e..666cf40 100644 --- a/clean.bat +++ b/clean.bat @@ -1 +1 @@ -make clean +make clean diff --git a/eclipse_project/.cproject b/eclipse_project/.cproject deleted file mode 100644 index 8905299..0000000 --- a/eclipse_project/.cproject +++ /dev/null @@ -1,110 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/eclipse_project/.project b/eclipse_project/.project deleted file mode 100644 index 9589629..0000000 --- a/eclipse_project/.project +++ /dev/null @@ -1,353 +0,0 @@ - - - 3ds_bootloader - - - - - - org.eclipse.cdt.managedbuilder.core.genmakebuilder - clean,full,incremental, - - - - - org.eclipse.cdt.managedbuilder.core.ScannerConfigBuilder - full,incremental, - - - - - - org.eclipse.cdt.core.cnature - org.eclipse.cdt.managedbuilder.core.managedBuildNature - org.eclipse.cdt.managedbuilder.core.ScannerConfigNature - - - - arm11 - 2 - virtual:/virtual - - - arm9 - 2 - virtual:/virtual - - - cache.h - 1 - PARENT-1-PROJECT_LOC/include/cache.h - - - gfx.h - 1 - PARENT-1-PROJECT_LOC/include/gfx.h - - - hid.c - 1 - PARENT-1-PROJECT_LOC/source/hid.c - - - hid.h - 1 - PARENT-1-PROJECT_LOC/include/hid.h - - - io.h - 1 - PARENT-1-PROJECT_LOC/include/io.h - - - mem_map.h - 1 - PARENT-1-PROJECT_LOC/include/mem_map.h - - - pxi.h - 1 - PARENT-1-PROJECT_LOC/include/pxi.h - - - types.h - 1 - PARENT-1-PROJECT_LOC/include/types.h - - - util.c - 1 - PARENT-1-PROJECT_LOC/source/util.c - - - util.h - 1 - PARENT-1-PROJECT_LOC/include/util.h - - - version.h - 1 - PARENT-1-PROJECT_LOC/include/version.h - - - arm11/cache.s - 1 - PARENT-1-PROJECT_LOC/source/arm11/cache.s - - - arm11/gfx.c - 1 - PARENT-1-PROJECT_LOC/source/arm11/gfx.c - - - arm11/gpio.s - 1 - PARENT-1-PROJECT_LOC/source/arm11/gpio.s - - - arm11/i2c.c - 1 - PARENT-1-PROJECT_LOC/source/arm11/i2c.c - - - arm11/main.c - 1 - PARENT-1-PROJECT_LOC/source/arm11/main.c - - - arm11/pxi.c - 1 - PARENT-1-PROJECT_LOC/source/arm11/pxi.c - - - arm11/start.s - 1 - PARENT-1-PROJECT_LOC/source/arm11/start.s - - - arm9/cache.s - 1 - PARENT-1-PROJECT_LOC/source/arm9/cache.s - - - arm9/config.h - 1 - PARENT-1-PROJECT_LOC/include/arm9/config.h - - - arm9/config_parser.c - 1 - PARENT-1-PROJECT_LOC/source/arm9/config_parser.c - - - arm9/console.c - 1 - PARENT-1-PROJECT_LOC/source/arm9/console.c - - - arm9/console.h - 1 - PARENT-1-PROJECT_LOC/include/arm9/console.h - - - arm9/crypto.c - 1 - PARENT-1-PROJECT_LOC/source/arm9/crypto.c - - - arm9/crypto.h - 1 - PARENT-1-PROJECT_LOC/include/arm9/crypto.h - - - arm9/debug.c - 1 - PARENT-1-PROJECT_LOC/source/arm9/debug.c - - - arm9/dev.c - 1 - PARENT-1-PROJECT_LOC/source/arm9/dev.c - - - arm9/dev.h - 1 - PARENT-1-PROJECT_LOC/include/arm9/dev.h - - - arm9/exception.s - 1 - PARENT-1-PROJECT_LOC/source/arm9/exception.s - - - arm9/fatfs - 2 - virtual:/virtual - - - arm9/filebrowse.c - 1 - PARENT-1-PROJECT_LOC/source/arm9/filebrowse.c - - - arm9/firm.c - 1 - PARENT-1-PROJECT_LOC/source/arm9/firm.c - - - arm9/firm.h - 1 - PARENT-1-PROJECT_LOC/include/arm9/firm.h - - - arm9/gamecard.c - 1 - PARENT-1-PROJECT_LOC/source/arm9/gamecard.c - - - arm9/gamecard.h - 1 - PARENT-1-PROJECT_LOC/include/arm9/gamecard.h - - - arm9/interrupt.h - 1 - PARENT-1-PROJECT_LOC/include/arm9/interrupt.h - - - arm9/main.c - 1 - PARENT-1-PROJECT_LOC/source/arm9/main.c - - - arm9/main.h - 1 - PARENT-1-PROJECT_LOC/include/arm9/main.h - - - arm9/menu.c - 1 - PARENT-1-PROJECT_LOC/source/arm9/menu.c - - - arm9/menu.h - 1 - PARENT-1-PROJECT_LOC/include/arm9/menu.h - - - arm9/ncch.h - 1 - PARENT-1-PROJECT_LOC/include/arm9/ncch.h - - - arm9/ncsd.h - 1 - PARENT-1-PROJECT_LOC/include/arm9/ncsd.h - - - arm9/ndma.c - 1 - PARENT-1-PROJECT_LOC/source/arm9/ndma.c - - - arm9/ndma.h - 1 - PARENT-1-PROJECT_LOC/include/arm9/ndma.h - - - arm9/pxi.c - 1 - PARENT-1-PROJECT_LOC/source/arm9/pxi.c - - - arm9/sdmmc.c - 1 - PARENT-1-PROJECT_LOC/source/arm9/sdmmc.c - - - arm9/sdmmc.h - 1 - PARENT-1-PROJECT_LOC/include/arm9/sdmmc.h - - - arm9/spiflash.c - 1 - PARENT-1-PROJECT_LOC/source/arm9/spiflash.c - - - arm9/spiflash.h - 1 - PARENT-1-PROJECT_LOC/include/arm9/spiflash.h - - - arm9/start.s - 1 - PARENT-1-PROJECT_LOC/source/arm9/start.s - - - arm9/system.s - 1 - PARENT-1-PROJECT_LOC/source/arm9/system.s - - - arm9/systemInit.c - 1 - PARENT-1-PROJECT_LOC/source/arm9/systemInit.c - - - arm9/timer.c - 1 - PARENT-1-PROJECT_LOC/source/arm9/timer.c - - - arm9/timer.h - 1 - PARENT-1-PROJECT_LOC/include/arm9/timer.h - - - arm9/util_nand.c - 1 - PARENT-1-PROJECT_LOC/source/arm9/util_nand.c - - - arm9/util_nand.h - 1 - PARENT-1-PROJECT_LOC/include/arm9/util_nand.h - - - arm9/fatfs/ccsbcs.c - 1 - PARENT-1-PROJECT_LOC/source/arm9/fatfs/ccsbcs.c - - - arm9/fatfs/diskio.c - 1 - PARENT-1-PROJECT_LOC/source/arm9/fatfs/diskio.c - - - arm9/fatfs/diskio.h - 1 - PARENT-1-PROJECT_LOC/include/arm9/fatfs/diskio.h - - - arm9/fatfs/ff.c - 1 - PARENT-1-PROJECT_LOC/source/arm9/fatfs/ff.c - - - arm9/fatfs/ff.h - 1 - PARENT-1-PROJECT_LOC/include/arm9/fatfs/ff.h - - - arm9/fatfs/ffconf.h - 1 - PARENT-1-PROJECT_LOC/include/arm9/fatfs/ffconf.h - - - arm9/fatfs/integer.h - 1 - PARENT-1-PROJECT_LOC/include/arm9/fatfs/integer.h - - - diff --git a/source/arm11/cache.s b/source/arm11/cache.s index fb44102..b3769a8 100644 --- a/source/arm11/cache.s +++ b/source/arm11/cache.s @@ -33,18 +33,18 @@ invalidateICacheRange: - add r1, r1, r0 - bic r0, r0, #(CACHE_LINE_SIZE - 1) + add r1, r1, r0 + bic r0, r0, #(CACHE_LINE_SIZE - 1) mov r2, #0 -invalidateICacheRange_lp: - mcr p15, 0, r0, c7, c5, 1 @ Invalidate Instruction Cache Line (using MVA) - add r0, r0, #CACHE_LINE_SIZE - cmp r0, r1 - blt invalidateICacheRange_lp + invalidateICacheRange_lp: + mcr p15, 0, r0, c7, c5, 1 @ Invalidate Instruction Cache Line (using MVA) + add r0, r0, #CACHE_LINE_SIZE + cmp r0, r1 + blt invalidateICacheRange_lp mcr p15, 0, r2, c7, c5, 6 @ Flush Entire Branch Target Cache mcr p15, 0, r2, c7, c10, 4 @ Data Synchronization Barrier mcr p15, 0, r2, c7, c5, 4 @ Flush Prefetch Buffer - bx lr + bx lr flushDCache: @@ -55,37 +55,37 @@ flushDCacheRange: - add r1, r1, r0 - bic r0, r0, #(CACHE_LINE_SIZE - 1) + add r1, r1, r0 + bic r0, r0, #(CACHE_LINE_SIZE - 1) mov r2, #0 -flushDCacheRange_lp: - mcr p15, 0, r0, c7, c10, 1 @ "Clean Data Cache Line (using MVA)" - add r0, r0, #CACHE_LINE_SIZE - cmp r0, r1 - blt flushDCacheRange_lp + flushDCacheRange_lp: + mcr p15, 0, r0, c7, c10, 1 @ "Clean Data Cache Line (using MVA)" + add r0, r0, #CACHE_LINE_SIZE + cmp r0, r1 + blt flushDCacheRange_lp mcr p15, 0, r2, c7, c10, 4 @ Data Synchronization Barrier bx lr invalidateDCache: - mov r0, #0 + mov r0, #0 mcr p15, 0, r0, c7, c6, 0 @ Invalidate Entire Data Cache mcr p15, 0, r0, c7, c10, 4 @ Data Synchronization Barrier - bx lr + bx lr invalidateDCacheRange: - add r1, r1, r0 - tst r0, #(CACHE_LINE_SIZE - 1) - mcrne p15, 0, r0, c7, c10, 1 @ "Clean Data Cache Line (using MVA)" - tst r1, #(CACHE_LINE_SIZE - 1) - mcrne p15, 0, r1, c7, c10, 1 @ "Clean Data Cache Line (using MVA)" - bic r0, r0, #(CACHE_LINE_SIZE - 1) + add r1, r1, r0 + tst r0, #(CACHE_LINE_SIZE - 1) + mcrne p15, 0, r0, c7, c10, 1 @ "Clean Data Cache Line (using MVA)" + tst r1, #(CACHE_LINE_SIZE - 1) + mcrne p15, 0, r1, c7, c10, 1 @ "Clean Data Cache Line (using MVA)" + bic r0, r0, #(CACHE_LINE_SIZE - 1) mov r2, #0 -invalidateDCacheRange_lp: - mcr p15, 0, r0, c7, c6, 1 @ Invalidate Data Cache Line (using MVA) - add r0, r0, #CACHE_LINE_SIZE - cmp r0, r1 - blt invalidateDCacheRange_lp + invalidateDCacheRange_lp: + mcr p15, 0, r0, c7, c6, 1 @ Invalidate Data Cache Line (using MVA) + add r0, r0, #CACHE_LINE_SIZE + cmp r0, r1 + blt invalidateDCacheRange_lp mcr p15, 0, r2, c7, c10, 4 @ Data Synchronization Barrier - bx lr + bx lr diff --git a/source/arm11/cpu.s b/source/arm11/cpu.s deleted file mode 100644 index 7a1dd02..0000000 --- a/source/arm11/cpu.s +++ /dev/null @@ -1,113 +0,0 @@ -#include "mem_map.h" - -.arm -.cpu mpcore -.fpu vfpv2 - -.global initCpu -.global deinitCpu - -.type initCpu STT_FUNC -.type stubExceptionVectors STT_FUNC -.type setupVfp STT_FUNC -.type deinitCpu STT_FUNC - -.extern setupMmu -.extern flushDCache - -.section ".init" - - - -initCpu: - mov r10, lr - - @ Control register: - @ [29] Force AP functionality : disabled - @ [28] TEX remap : disabled - @ [27] NMFI bit : normal FIQ behavior - @ [25] CPSR E bit on taking an exception : 0 - @ [23] Extended page table configuration : subpage AP bits enabled - @ [22] Unaligned data access : disabled - @ [15] Disable loading TBIT : disabled - @ [13] Vector select : 0x00000000 - @ [12] Level one instruction cache : disabled - @ [11] Program flow prediction : disabled - @ [7] Endianess : little - @ [2] Level one data cache : disabled - @ [1] Strict data address alignment fault: disabled - @ [0] MMU : disabled - ldr r0, =0x54078 - mcr p15, 0, r0, c1, c0, 0 @ Write control register - mov r0, #0 - mcr p15, 0, r0, c1, c0, 1 @ Write Auxiliary Control Register - - mcr p15, 0, r0, c7, c5, 4 @ Flush Prefetch Buffer - mcr p15, 0, r0, c7, c7, 0 @ Invalidate Both Caches. Also flushes the branch target cache - mcr p15, 0, r0, c7, c10, 4 @ Data Synchronization Barrier - clrex - - bl stubExceptionVectors @ Stub the vectors in AXIWRAM bootrom vectors jump to - ldr sp, =A11_STACK_END - blx setupMmu - bl setupVfp - cpsie a - bx r10 -.pool - - -#define MAKE_BRANCH(src, dst) (0xEA000000 | (((((dst) - (src)) >> 2) - 2) & 0xFFFFFF)) - -stubExceptionVectors: - ldr r0, =A11_VECTORS_START - mov r1, #6 - ldr r2, =MAKE_BRANCH(0, 0) @ Endless loop - stubExceptionVectors_lp: - str r2, [r0], #8 - subs r1, r1, #1 - bne stubExceptionVectors_lp - bx lr - - -setupVfp: - mov r0, #0 - mov r1, #0xF00000 @ Give full access to cp10/11 in user and privileged mode - mcr p15, 0, r1, c1, c0, 2 @ Write Coprocessor Access Control Register - mcr p15, 0, r0, c7, c5, 4 @ Flush Prefetch Buffer - mov r1, #0x40000000 @ Clear exception bits and enable VFP11 - mov r2, #0x3C00000 @ Round towards zero (RZ) mode, flush-to-zero mode, default NaN mode - fmxr fpexc, r1 @ Write Floating-point exception register - fmxr fpscr, r2 @ Write Floating-Point Status and Control Register - bx lr -.pool - - -deinitCpu: - cpsid aif, #0x1F - mov r3, lr - - bl stubExceptionVectors - bl flushDCache - mov r2, #0 - mrc p15, 0, r0, c1, c0, 0 @ Read control register - ldr r1, =0x803807 @ Enable MMU, Strict data address alignment fault, D-Cache, - @ Program flow prediction, I-Cache, high exception vectors, - @ subpage AP bits disabled - bic r0, r0, r1 - mcr p15, 0, r0, c1, c0, 0 @ Write control register - mrc p15, 0, r0, c1, c0, 1 @ Read Auxiliary Control Register - bic r0, r0, #0x6F @ Return stack, Dynamic branch prediction, Static branch prediction, - @ Instruction folding, SMP mode: the CPU is taking part in coherency - @ and L1 parity checking - mcr p15, 0, r0, c1, c0, 1 @ Write Auxiliary Control Register - - mcr p15, 0, r2, c7, c5, 4 @ Flush Prefetch Buffer - mcr p15, 0, r2, c7, c7, 0 @ Invalidate Both Caches. Also flushes the branch target cache - mcr p15, 0, r2, c7, c10, 4 @ Data Synchronization Barrier - clrex - - @ Disable VFP11 - fmxr fpscr, r2 @ Write Floating-Point Status and Control Register - fmxr fpexc, r2 @ Write Floating-point exception register - bx r3 -.pool diff --git a/source/arm11/gfx.c b/source/arm11/gfx.c index dd13c15..2e67efa 100644 --- a/source/arm11/gfx.c +++ b/source/arm11/gfx.c @@ -165,9 +165,9 @@ u32 gfx_i2c_lcd_init() { if(!i2c_write_regdata_dev5_dev6(true, true, 0x11, 0x10) || - !i2c_write_regdata_dev5_dev6(true, false, 0x50, 0x1) || - !i2c_write_regdata_dev5_dev6(true, true, 0x60, 0) || - !i2c_write_regdata_dev5_dev6(true, true, 1, 0x10)) + !i2c_write_regdata_dev5_dev6(true, false, 0x50, 0x1) || + !i2c_write_regdata_dev5_dev6(true, true, 0x60, 0) || + !i2c_write_regdata_dev5_dev6(true, true, 1, 0x10)) return 0; return 1; } diff --git a/source/arm11/mmu.c b/source/arm11/mmu.c index 33e0213..ec5ea9c 100644 --- a/source/arm11/mmu.c +++ b/source/arm11/mmu.c @@ -48,13 +48,12 @@ * @param[in] xn If this memory should be marked as execute never. * @param[in] attr Other attribute bits like caching. */ -static void mmuMapSections(const u32 va, const u32 pa, const u32 num, const bool shared, - const u32 access, const u8 domain, const bool xn, const u32 attr) +static void mmuMapSections(u32 va, u32 pa, u32 num, bool shared, u32 access, u8 domain, bool xn, u32 attr) { for(u32 i = 0; i < 0x100000u * num; i += 0x100000u) { ((u32*)A11_MMU_TABLES_BASE)[(va + i)>>20] = (((pa + i) & 0xFFF00000u) | (u32)shared<<16 | access<<10 | - (u32)domain<<5 | (u32)xn<<4 | attr<<2 | 0b10u); + (u32)domain<<5 | (u32)xn<<4 | attr<<2 | 0b10u); } } @@ -72,28 +71,27 @@ * @param[in] xn If this memory should be marked as execute never. * @param[in] attr Other attribute bits like caching. */ -static void mmuMapPages(const u32 va, const u32 pa, const u32 num, u32 *l2Table, const bool shared, - const u32 access, const u8 domain, const bool xn, const u32 attr) +static void mmuMapPages(u32 va, u32 pa, u32 num, u32 *l2Table, bool shared, u32 access, u8 domain, bool xn, u32 attr) { ((u32*)A11_MMU_TABLES_BASE)[va>>20] = (((u32)l2Table & 0xFFFFFC00u) | (u32)domain<<5 | 0b01u); for(u32 i = 0; i < 0x1000u * num; i += 0x1000u) { l2Table[(va + i)>>12 & 0xFFu] = (((pa + i) & 0xFFFFF000u) | (u32)shared<<10 | - access<<4 | attr<<2 | 0b10u | (u32)xn); + access<<4 | attr<<2 | 0b10u | (u32)xn); } } void setupMmu(void) { // TTBR0 address shared page table walk and outer cachable write-through, no allocate on write - __asm__ __volatile__("mcr p15, 0, %0, c2, c0, 0\n\t" : : "r" (A11_MMU_TABLES_BASE | 0x12u)); + __asm__ __volatile__("mcr p15, 0, %0, c2, c0, 0" : : "r" (A11_MMU_TABLES_BASE | 0x12u)); // Use the 16 KB L1 table only - __asm__ __volatile__("mcr p15, 0, %0, c2, c0, 2\n\t" : : "r" (0u)); + __asm__ __volatile__("mcr p15, 0, %0, c2, c0, 2" : : "r" (0u)); // Domain 1 = client, remaining domains all = no access - __asm__ __volatile__("mcr p15, 0, %0, c3, c0, 0\n\t" : : "r" (4u)); + __asm__ __volatile__("mcr p15, 0, %0, c3, c0, 0" : : "r" (4u)); // Context ID Register (ASID = 0, PROCID = 0) - __asm__ __volatile__("mcr p15, 0, %0, c13, c0, 1\n\t" : : "r" (0u)); + __asm__ __volatile__("mcr p15, 0, %0, c13, c0, 1" : : "r" (0u)); // Clear L1 and L2 tables @@ -101,34 +99,34 @@ // IO mem mapping mmuMapSections(IO_MEM_ARM9_ARM11, IO_MEM_ARM9_ARM11, 4, true, - PERM_PRIV_RW_USR_NO_ACC, 1, true, ATTR_SHARED_DEVICE); + PERM_PRIV_RW_USR_NO_ACC, 1, true, ATTR_SHARED_DEVICE); // MPCore private region mapping mmuMapPages(MPCORE_PRIV_REG_BASE, MPCORE_PRIV_REG_BASE, 2, - (u32*)(A11_MMU_TABLES_BASE + 0x4000u), false, PERM_PRIV_RW_USR_NO_ACC, - 1, true, L1_TO_L2(ATTR_NONSHARED_DEVICE)); + (u32*)(A11_MMU_TABLES_BASE + 0x4000u), false, PERM_PRIV_RW_USR_NO_ACC, + 1, true, L1_TO_L2(ATTR_NONSHARED_DEVICE)); // VRAM mapping mmuMapSections(VRAM_BASE, VRAM_BASE, 6, true, PERM_PRIV_RW_USR_NO_ACC, 1, true, ATTR_NORM_WRITE_TROUGH_NO_ALLOC); // AXIWRAM MMU table mapping mmuMapPages(A11_MMU_TABLES_BASE, A11_MMU_TABLES_BASE, 5, (u32*)(A11_MMU_TABLES_BASE + 0x4400u), true, - PERM_PRIV_RO_USR_NO_ACC, 1, true, L1_TO_L2(ATTR_NORM_NONCACHABLE)); + PERM_PRIV_RO_USR_NO_ACC, 1, true, L1_TO_L2(ATTR_NORM_NONCACHABLE)); // Remaining AXIWRAM pages mmuMapPages(AXIWRAM_BASE + 0x5000u, AXIWRAM_BASE + 0x5000u, 123, - (u32*)(A11_MMU_TABLES_BASE + 0x4400u), true, PERM_PRIV_RW_USR_NO_ACC, 1, false, - L1_TO_L2(MAKE_CUSTOM_NORM_ATTR(POLICY_WRITE_BACK_ALLOC_BUFFERED, POLICY_WRITE_BACK_ALLOC_BUFFERED))); + (u32*)(A11_MMU_TABLES_BASE + 0x4400u), true, PERM_PRIV_RW_USR_NO_ACC, 1, false, + L1_TO_L2(MAKE_CUSTOM_NORM_ATTR(POLICY_WRITE_BACK_ALLOC_BUFFERED, POLICY_WRITE_BACK_ALLOC_BUFFERED))); // Map boot11 mirror to loader executable start (exception vectors) mmuMapPages(BOOT11_MIRROR2, (u32)&__start__, 1, (u32*)(A11_MMU_TABLES_BASE + 0x4800u), true, - PERM_PRIV_RO_USR_NO_ACC, 1, false, - L1_TO_L2(MAKE_CUSTOM_NORM_ATTR(POLICY_WRITE_BACK_ALLOC_BUFFERED, POLICY_WRITE_BACK_ALLOC_BUFFERED))); + PERM_PRIV_RO_USR_NO_ACC, 1, false, + L1_TO_L2(MAKE_CUSTOM_NORM_ATTR(POLICY_WRITE_BACK_ALLOC_BUFFERED, POLICY_WRITE_BACK_ALLOC_BUFFERED))); // Invalidate TLB (Unified TLB operation) + Data Synchronization Barrier __asm__ __volatile__("mcr p15, 0, %0, c8, c7, 0\n\t" - "mcr p15, 0, %0, c7, c10, 4\n\t" : : "r" (0u)); + "mcr p15, 0, %0, c7, c10, 4" : : "r" (0u)); // Invalidate tag RAMs before enabling SMP like recommended by the MPCore docs @@ -140,16 +138,16 @@ u32 tmp; // Modify Auxiliary Control Register - __asm__ __volatile__("mrc p15, 0, %0, c1, c0, 1\n\t" : "=r" (tmp) : ); + __asm__ __volatile__("mrc p15, 0, %0, c1, c0, 1" : "=r" (tmp) : ); tmp |= 0x6Fu; // Enable Return stack, Dynamic branch prediction, Static branch prediction, // Instruction folding, SMP mode: the CPU is taking part in coherency // and L1 parity checking - __asm__ __volatile__("mcr p15, 0, %0, c1, c0, 1\n\t" : : "r" (tmp)); + __asm__ __volatile__("mcr p15, 0, %0, c1, c0, 1" : : "r" (tmp)); // Modify Control Register - __asm__ __volatile__("mrc p15, 0, %0, c1, c0, 0\n\t" : "=r" (tmp) : ); - tmp |= 0x803807u; // Enable MMU, Strict data address alignment fault, D-Cache, - // Program flow prediction, I-Cache, high exception vectors, + __asm__ __volatile__("mrc p15, 0, %0, c1, c0, 0" : "=r" (tmp) : ); + tmp |= 0xC03805u; // Enable MMU, D-Cache, Program flow prediction, + // I-Cache, high exception vectors, Unaligned data access, // subpage AP bits disabled - __asm__ __volatile__("mcr p15, 0, %0, c1, c0, 0\n\t" : : "r" (tmp)); + __asm__ __volatile__("mcr p15, 0, %0, c1, c0, 0" : : "r" (tmp)); } diff --git a/source/arm11/start.s b/source/arm11/start.s index be43740..d2d9611 100644 --- a/source/arm11/start.s +++ b/source/arm11/start.s @@ -1,3 +1,5 @@ +#include "mem_map.h" + .arm .cpu mpcore .fpu vfpv2 @@ -5,40 +7,75 @@ .global _start .global clearMem .global _init +.global deinitCpu .type vectors STT_FUNC .type _start STT_FUNC +.type stubExceptionVectors STT_FUNC .type clearMem STT_FUNC +.type setupVfp STT_FUNC .type _init STT_FUNC +.type deinitCpu STT_FUNC -.extern initCpu .extern __bss_start__ .extern __bss_end__ +.extern setupMmu .extern __libc_init_array .extern main -.extern deinitCpu .extern firm_launch .section ".crt0" -_vectors: +vectors: ldr pc, =_start @ Reset vector - ldr pc, =(_vectors + 0x04) @ Undefined instruction vector - ldr pc, =(_vectors + 0x08) @ Software interrupt (SVC) vector - ldr pc, =(_vectors + 0x0C) @ Prefetch abort vector - ldr pc, =(_vectors + 0x10) @ Data abort vector - ldr pc, =(_vectors + 0x14) @ Reserved (unused) vector - ldr pc, =(_vectors + 0x18) @ Interrupt (IRQ) vector - ldr pc, =(_vectors + 0x1C) @ Fast interrupt (FIQ) vector + ldr pc, =(vectors + 0x04) @ Undefined instruction vector + ldr pc, =(vectors + 0x08) @ Software interrupt (SVC) vector + ldr pc, =(vectors + 0x0C) @ Prefetch abort vector + ldr pc, =(vectors + 0x10) @ Data abort vector + ldr pc, =(vectors + 0x14) @ Reserved (unused) vector + ldr pc, =(vectors + 0x18) @ Interrupt (IRQ) vector + ldr pc, =(vectors + 0x1C) @ Fast interrupt (FIQ) vector .pool _start: - cpsid aif, #0x1F @ Disable all interrupts, system mode + cpsid aif, #0x13 @ Disable all interrupts, SVC mode - bl initCpu + @ Control register: + @ [29] Force AP functionality : disabled + @ [28] TEX remap : disabled + @ [27] NMFI bit : normal FIQ behavior + @ [25] CPSR E bit on taking an exception : 0 + @ [23] Extended page table configuration : subpage AP bits enabled + @ [22] Unaligned data access : disabled + @ [15] Disable loading TBIT : disabled + @ [13] Vector select : 0x00000000 + @ [12] Level one instruction cache : disabled + @ [11] Program flow prediction : disabled + @ [7] Endianess : little + @ [2] Level one data cache : disabled + @ [1] Strict data address alignment fault: disabled + @ [0] MMU : disabled + ldr r0, =0x54078 + mcr p15, 0, r0, c1, c0, 0 @ Write control register + mov r0, #0 + mcr p15, 0, r0, c1, c0, 1 @ Write Auxiliary Control Register + + mcr p15, 0, r0, c7, c5, 4 @ Flush Prefetch Buffer + mcr p15, 0, r0, c7, c7, 0 @ Invalidate Both Caches. Also flushes the branch target cache + mcr p15, 0, r0, c7, c10, 4 @ Data Synchronization Barrier + + bl stubExceptionVectors @ Stub the vectors in AXIWRAM bootrom vectors jump to + + mov sp, #0 @ SVC mode sp (Unused, aborts) + cpsid aif, #0x11 @ FIQ mode + mov sp, #0 @ Not yet + cpsid aif, #0x12 @ IRQ mode + mov sp, #0 @ Not yet + cpsid aif, #0x1F @ System mode + ldr sp, =A11_STACK_END @ Clear bss section ldr r0, =__bss_start__ @@ -46,18 +83,39 @@ sub r1, r1, r0 bl clearMem + blx setupMmu + bl setupVfp + clrex + cpsie a + blx __libc_init_array @ Initialize ctors and dtors mov r0, #0 @ argc mov r1, #0 @ argv blx main cmp r0, #0 - bne . + bne fail_loop bl deinitCpu b firm_launch + fail_loop: + wfi + b fail_loop .pool +#define MAKE_BRANCH(src, dst) (0xEA000000 | (((((dst) - (src)) >> 2) - 2) & 0xFFFFFF)) + +stubExceptionVectors: + ldr r0, =A11_VECTORS_START + mov r1, #6 + ldr r2, =MAKE_BRANCH(0, 0) @ Endless loop + stubExceptionVectors_lp: + str r2, [r0], #8 + subs r1, r1, #1 + bne stubExceptionVectors_lp + bx lr + + @ void clearMem(u32 *adr, u32 size) clearMem: mov r2, #0 @@ -88,5 +146,50 @@ .pool +setupVfp: + mov r0, #0 + mov r1, #0xF00000 @ Give full access to cp10/11 in user and privileged mode + mcr p15, 0, r1, c1, c0, 2 @ Write Coprocessor Access Control Register + mcr p15, 0, r0, c7, c5, 4 @ Flush Prefetch Buffer + mov r1, #0x40000000 @ Clear exception bits and enable VFP11 + mov r2, #0x3C00000 @ Round towards zero (RZ) mode, flush-to-zero mode, default NaN mode + fmxr fpexc, r1 @ Write Floating-point exception register + fmxr fpscr, r2 @ Write Floating-Point Status and Control Register + bx lr +.pool + + _init: bx lr +.pool + + +deinitCpu: + cpsid aif, #0x1F @ System mode + mov r3, lr + + bl stubExceptionVectors + bl flushDCache + mov r2, #0 + mrc p15, 0, r0, c1, c0, 0 @ Read control register + ldr r1, =0xC03805 @ Disable MMU, D-Cache, Program flow prediction, I-Cache, + @ high exception vectors, Unaligned data access, + @ subpage AP bits disabled + bic r0, r0, r1 + mcr p15, 0, r0, c1, c0, 0 @ Write control register + mrc p15, 0, r0, c1, c0, 1 @ Read Auxiliary Control Register + bic r0, r0, #0x6F @ Return stack, Dynamic branch prediction, Static branch prediction, + @ Instruction folding, SMP mode: the CPU is taking part in coherency + @ and L1 parity checking + mcr p15, 0, r0, c1, c0, 1 @ Write Auxiliary Control Register + + mcr p15, 0, r2, c7, c5, 4 @ Flush Prefetch Buffer + mcr p15, 0, r2, c7, c7, 0 @ Invalidate Both Caches. Also flushes the branch target cache + mcr p15, 0, r2, c7, c10, 4 @ Data Synchronization Barrier + + @ Disable VFP11 + fmxr fpscr, r2 @ Write Floating-Point Status and Control Register + fmxr fpexc, r2 @ Write Floating-point exception register + clrex + bx r3 +.pool diff --git a/source/arm9/cache.s b/source/arm9/cache.s index ed29f93..02b3c80 100644 --- a/source/arm9/cache.s +++ b/source/arm9/cache.s @@ -26,69 +26,69 @@ invalidateICache: - mov r0, #0 - mcr p15, 0, r0, c7, c5, 0 @ "Flush instruction cache" - bx lr + mov r0, #0 + mcr p15, 0, r0, c7, c5, 0 @ "Flush instruction cache" + bx lr invalidateICacheRange: - add r1, r1, r0 - bic r0, r0, #(CACHE_LINE_SIZE - 1) -invalidateICacheRange_lp: - mcr p15, 0, r0, c7, c5, 1 @ "Flush instruction cache single entry Address" - add r0, r0, #CACHE_LINE_SIZE - cmp r0, r1 - blt invalidateICacheRange_lp - bx lr + add r1, r1, r0 + bic r0, r0, #(CACHE_LINE_SIZE - 1) + invalidateICacheRange_lp: + mcr p15, 0, r0, c7, c5, 1 @ "Flush instruction cache single entry Address" + add r0, r0, #CACHE_LINE_SIZE + cmp r0, r1 + blt invalidateICacheRange_lp + bx lr flushDCache: - mov r1, #0 -flushDCache_outer_lp: - mov r0, #0 -flushDCache_inner_lp: - orr r2, r1, r0 @ Generate segment and line address - mcr p15, 0, r2, c7, c10, 2 @ "Clean data cache entry Index and segment" - add r0, r0, #CACHE_LINE_SIZE - cmp r0, #(DCACHE_SIZE / 4) - bne flushDCache_inner_lp - add r1, r1, #0x40000000 - cmp r1, #0 - bne flushDCache_outer_lp - b drainWriteBuffer + mov r1, #0 + flushDCache_outer_lp: + mov r0, #0 + flushDCache_inner_lp: + orr r2, r1, r0 @ Generate segment and line address + mcr p15, 0, r2, c7, c10, 2 @ "Clean data cache entry Index and segment" + add r0, r0, #CACHE_LINE_SIZE + cmp r0, #(DCACHE_SIZE / 4) + bne flushDCache_inner_lp + add r1, r1, #0x40000000 + cmp r1, #0 + bne flushDCache_outer_lp + b drainWriteBuffer flushDCacheRange: - add r1, r1, r0 - bic r0, r0, #(CACHE_LINE_SIZE - 1) -flushDCacheRange_lp: - mcr p15, 0, r0, c7, c10, 1 @ "Clean data cache entry Address" - add r0, r0, #CACHE_LINE_SIZE - cmp r0, r1 - blt flushDCacheRange_lp + add r1, r1, r0 + bic r0, r0, #(CACHE_LINE_SIZE - 1) + flushDCacheRange_lp: + mcr p15, 0, r0, c7, c10, 1 @ "Clean data cache entry Address" + add r0, r0, #CACHE_LINE_SIZE + cmp r0, r1 + blt flushDCacheRange_lp drainWriteBuffer: mov r0, #0 mcr p15, 0, r0, c7, c10, 4 @ Drain write buffer - bx lr + bx lr invalidateDCache: - mov r0, #0 - mcr p15, 0, r0, c7, c6, 0 @ "Flush data cache" - bx lr + mov r0, #0 + mcr p15, 0, r0, c7, c6, 0 @ "Flush data cache" + bx lr invalidateDCacheRange: - add r1, r1, r0 - tst r0, #(CACHE_LINE_SIZE - 1) - mcrne p15, 0, r0, c7, c10, 1 @ "Clean data cache entry Address" - tst r1, #(CACHE_LINE_SIZE - 1) - mcrne p15, 0, r1, c7, c10, 1 @ "Clean data cache entry Address" - bic r0, r0, #(CACHE_LINE_SIZE - 1) -invalidateDCacheRange_lp: - mcr p15, 0, r0, c7, c6, 1 @ "Flush data cache single entry Address" - add r0, r0, #CACHE_LINE_SIZE - cmp r0, r1 - blt invalidateDCacheRange_lp - bx lr + add r1, r1, r0 + tst r0, #(CACHE_LINE_SIZE - 1) + mcrne p15, 0, r0, c7, c10, 1 @ "Clean data cache entry Address" + tst r1, #(CACHE_LINE_SIZE - 1) + mcrne p15, 0, r1, c7, c10, 1 @ "Clean data cache entry Address" + bic r0, r0, #(CACHE_LINE_SIZE - 1) + invalidateDCacheRange_lp: + mcr p15, 0, r0, c7, c6, 1 @ "Flush data cache single entry Address" + add r0, r0, #CACHE_LINE_SIZE + cmp r0, r1 + blt invalidateDCacheRange_lp + bx lr diff --git a/source/arm9/console.c b/source/arm9/console.c index 2bf00de..07852e8 100644 --- a/source/arm9/console.c +++ b/source/arm9/console.c @@ -177,21 +177,8 @@ } } -// strchr() function with length check from WinterMute //--------------------------------------------------------------------------------- -static const char *strnchr(const char *p, char c, size_t n) { -//--------------------------------------------------------------------------------- - if (!p) return 0; - - while (n-- > 0) { - if (*p == c) return p; - p++; - } - return 0; -} - -//--------------------------------------------------------------------------------- -ssize_t con_write(UNUSED struct _reent *r,UNUSED int fd,const char *ptr, size_t len) { +ssize_t con_write(UNUSED struct _reent *r,UNUSED void *fd,const char *ptr, size_t len) { //--------------------------------------------------------------------------------- char chr; @@ -349,7 +336,7 @@ parameter = 0; if (escapelen == 1) { consumed = 1; - } else if (strnchr(escapeseq,';',escapelen)) { + } else if (memchr(escapeseq,';',escapelen)) { sscanf(escapeseq,"%d;%n", ¶meter, &consumed); } else { sscanf(escapeseq,"%dm%n", ¶meter, &consumed); diff --git a/source/arm9/cpu.s b/source/arm9/cpu.s deleted file mode 100644 index daa28c5..0000000 --- a/source/arm9/cpu.s +++ /dev/null @@ -1,256 +0,0 @@ -#include "mem_map.h" - -.arm -.cpu arm946e-s -.fpu softvfp - -.global initCpu -.global deinitCpu - -.type initCpu STT_FUNC -.type setupExceptionVectors STT_FUNC -.type setupTcms STT_FUNC -.type setupMpu STT_FUNC -.type deinitCpu STT_FUNC - -.extern undefInstrHandler -.extern prefetchAbortHandler -.extern dataAbortHandler -.extern irqHandler -.extern flushDCache - -.section ".init" - - - -initCpu: - mov r10, lr - - @ Control register: - @ [19] ITCM load mode : disabled - @ [18] ITCM : disabled - @ [17] DTCM load mode : disabled - @ [16] DTCM : disabled - @ [15] Disable loading TBIT : disabled - @ [14] Round-robin replacement: disabled - @ [13] Vector select : 0xFFFF0000 - @ [12] I-Cache : disabled - @ [7] Endianess : little - @ [2] D-Cache : disabled - @ [0] MPU : disabled - ldr r0, =0x2078 - mcr p15, 0, r0, c1, c0, 0 @ Write control register - - mov r0, #0 - mcr p15, 0, r0, c7, c5, 0 @ Invalidate I-Cache - mcr p15, 0, r0, c7, c6, 0 @ Invalidate D-Cache - mcr p15, 0, r0, c7, c10, 4 @ Drain write buffer - - bl setupExceptionVectors @ Setup the vectors in ARM9 mem bootrom vectors jump to - bl setupMpu - bl setupTcms @ Setup and enable DTCM and ITCM - - msr cpsr_cxsf, #0xD2 @ IRQ mode - ldr sp, =(A9_STACK_END - 0x3000) - msr cpsr_cxsf, #0xDF - ldr sp, =A9_STACK_END - - bx r10 -.pool - - -#define MAKE_BRANCH(src, dst) (0xEA000000 | (((((dst) - (src)) >> 2) - 2) & 0xFFFFFF)) - -setupExceptionVectors: - adr r0, __vectorStubs - mov r1, #A9_VECTORS_START - ldmia r0!, {r2-r9} - stmia r1!, {r2-r9} - ldmia r0, {r2-r5} - stmia r1, {r2-r5} - bx lr -__vectorStubs: - ldr pc, irqHandlerPtr - irqHandlerPtr: .word irqHandler - ldr pc, fiqHandlerPtr - fiqHandlerPtr: .word (A9_VECTORS_START + 0x08) - ldr pc, svcHandlerPtr - svcHandlerPtr: .word (A9_VECTORS_START + 0x10) - ldr pc, undefInstrHandlerPtr - undefInstrHandlerPtr: .word undefInstrHandler - ldr pc, prefetchAbortHandlerPtr - prefetchAbortHandlerPtr: .word prefetchAbortHandler - ldr pc, dataAbortHandlerPtr - dataAbortHandlerPtr: .word dataAbortHandler -.pool - - -setupTcms: - ldr r0, =(DTCM_BASE | 0x0A) @ Base = 0xFFF00000, size = 16 KB - mcr p15, 0, r0, c9, c1, 0 @ Write DTCM region reg - mov r0, #(ITCM_BASE | 0x24) @ Base = 0x00000000, size = 512 KB (32 KB mirrored) - mcr p15, 0, r0, c9, c1, 1 @ Write ITCM region reg - - mrc p15, 0, r0, c1, c0, 0 @ Read control register - orr r0, r0, #0x50000 @ Enable DTCM and ITCM - mcr p15, 0, r0, c1, c0, 0 @ Write control register - bx lr -.pool - - -#define REGION_4KB (0b01011) -#define REGION_8KB (0b01100) -#define REGION_16KB (0b01101) -#define REGION_32KB (0b01110) -#define REGION_64KB (0b01111) -#define REGION_128KB (0b10000) -#define REGION_256KB (0b10001) -#define REGION_512KB (0b10010) -#define REGION_1MB (0b10011) -#define REGION_2MB (0b10100) -#define REGION_4MB (0b10101) -#define REGION_8MB (0b10110) -#define REGION_16MB (0b10111) -#define REGION_32MB (0b11000) -#define REGION_64MB (0b11001) -#define REGION_128MB (0b11010) -#define REGION_256MB (0b11011) -#define REGION_512MB (0b11100) -#define REGION_1GB (0b11101) -#define REGION_2GB (0b11110) -#define REGION_4GB (0b11111) -#define MAKE_REGION(adr, size) ((adr) | ((size)<<1) | 1) - -#define PER_NO_ACC (0) -#define PER_PRIV_RW_USR_NO_ACC (0b0001) -#define PER_PRIV_RW_USR_RO (0b0010) -#define PER_PRIV_RW_USR_RW (0b0011) -#define PER_PRIV_RO_USR_NO_ACC (0b0101) -#define PER_PRIV_RO_USR_RO (0b0110) -#define MAKE_PERMISSIONS(r0, r1, r2, r3, r4, r5, r6, r7) \ - ((r0) | (r1<<4) | (r2<<8) | (r3<<12) | (r4<<16) | (r5<<20) | (r6<<24) | (r7<<28)) - -setupMpu: - @ Region 0: ITCM kernel mirror 32 KB - @ Region 1: ARM9 internal mem 1 MB - @ Region 2: IO region 2 MB covers only ARM9 accessible regs - @ Region 3: VRAM 8MB - @ Region 4: DTCM 16 KB - @ Region 5: - (reserved) - @ Region 6: - (reserved) - @ Region 7: Exception vectors + ARM9 bootrom 32 KB - ldr r0, =MAKE_REGION(ITCM_KERNEL_MIRROR, REGION_32KB) - mcr p15, 0, r0, c6, c0, 0 - ldr r0, =MAKE_REGION(A9_RAM_BASE, REGION_1MB) - mcr p15, 0, r0, c6, c1, 0 - ldr r0, =MAKE_REGION(IO_MEM_ARM9_ONLY, REGION_2MB) - mcr p15, 0, r0, c6, c2, 0 - ldr r0, =MAKE_REGION(VRAM_BASE, REGION_8MB) - mcr p15, 0, r0, c6, c3, 0 - ldr r0, =MAKE_REGION(DTCM_BASE, REGION_16KB) - mcr p15, 0, r0, c6, c4, 0 - mov r0, #0 - mcr p15, 0, r0, c6, c5, 0 - //mov r0, #0 - mcr p15, 0, r0, c6, c6, 0 - ldr r0, =MAKE_REGION(BOOT9_BASE, REGION_32KB) - mcr p15, 0, r0, c6, c7, 0 - - @ Data access permissions: - @ Region 0: User = --, Privileged = RW - @ Region 1: User = --, Privileged = RW - @ Region 2: User = --, Privileged = RW - @ Region 3: User = --, Privileged = RW - @ Region 4: User = --, Privileged = RW - @ Region 5: User = --, Privileged = -- - @ Region 6: User = --, Privileged = -- - @ Region 7: User = --, Privileged = RO - ldr r0, =MAKE_PERMISSIONS(PER_PRIV_RW_USR_NO_ACC, PER_PRIV_RW_USR_NO_ACC, - PER_PRIV_RW_USR_NO_ACC, PER_PRIV_RW_USR_NO_ACC, - PER_PRIV_RW_USR_NO_ACC, PER_NO_ACC, - PER_NO_ACC , PER_PRIV_RO_USR_NO_ACC) - mcr p15, 0, r0, c5, c0, 2 @ Data access permissions - - @ Instruction access permissions: - @ Region 0: User = --, Privileged = RO - @ Region 1: User = --, Privileged = RO - @ Region 2: User = --, Privileged = -- - @ Region 3: User = --, Privileged = -- - @ Region 4: User = --, Privileged = -- - @ Region 5: User = --, Privileged = -- - @ Region 6: User = --, Privileged = -- - @ Region 7: User = --, Privileged = RO - ldr r0, =MAKE_PERMISSIONS(PER_PRIV_RO_USR_NO_ACC, PER_PRIV_RO_USR_NO_ACC, - PER_NO_ACC, PER_NO_ACC, - PER_NO_ACC, PER_NO_ACC, - PER_NO_ACC, PER_PRIV_RO_USR_NO_ACC) - mcr p15, 0, r0, c5, c0, 3 @ Instruction access permissions - - @ Data cachable bits: - @ Region 0 = no - @ Region 1 = yes - @ Region 2 = no <-- Never cache IO regs - @ Region 3 = yes - @ Region 4 = no - @ Region 5 = no - @ Region 6 = no - @ Region 7 = yes - mov r0, #0b10001010 - mcr p15, 0, r0, c2, c0, 0 @ Data cachable bits - - @ Instruction cachable bits: - @ Region 0 = no - @ Region 1 = yes - @ Region 2 = no - @ Region 3 = no - @ Region 4 = no - @ Region 5 = no - @ Region 6 = no - @ Region 7 = yes - mov r0, #0b10000010 - mcr p15, 0, r0, c2, c0, 1 @ Instruction cachable bits - - @ Write bufferable bits: - @ Region 0 = no - @ Region 1 = yes - @ Region 2 = no <-- Never buffer IO regs - @ Region 3 = yes - @ Region 4 = no - @ Region 5 = no - @ Region 6 = no - @ Region 7 = yes - mov r0, #0b10001010 - mcr p15, 0, r0, c3, c0, 0 @ Write bufferable bits - - mrc p15, 0, r0, c1, c0, 0 @ Read control register - ldr r1, =0x1005 @ MPU, D-Cache and I-Cache bitmask - orr r0, r0, r1 @ Enable MPU, D-Cache and I-Cache - mcr p15, 0, r0, c1, c0, 0 @ Write control register - bx lr -.pool - - -deinitCpu: - msr cpsr_cxsf, #0xDF - mov r3, lr - - @ Stub vectors to endless loops - mov r0, #A9_RAM_BASE - mov r1, #6 - ldr r2, =MAKE_BRANCH(0, 0) @ Endless loop - deinitCpu_lp: - str r2, [r0], #8 - subs r1, r1, #1 - bne deinitCpu_lp - - bl flushDCache - mov r2, #0 - mrc p15, 0, r0, c1, c0, 0 @ Read control register - ldr r1, =0x1005 @ MPU, D-Cache and I-Cache bitmask - bic r0, r0, r1 @ Disable MPU, D-Cache and I-Cache - mcr p15, 0, r0, c1, c0, 0 @ Write control register - - mcr p15, 0, r2, c7, c5, 0 @ Invalidate I-Cache - mcr p15, 0, r2, c7, c6, 0 @ Invalidate D-Cache - bx r3 -.pool diff --git a/source/arm9/crypto.c b/source/arm9/crypto.c index e319ae2..435e96f 100644 --- a/source/arm9/crypto.c +++ b/source/arm9/crypto.c @@ -122,7 +122,7 @@ REG_NDMA0_WRITE_CNT = wordCount; REG_NDMA0_BLOCK_CNT = NDMA_BLOCK_SYS_FREQ; REG_NDMA0_CNT = NDMA_ENABLE | NDMA_REPEATING_MODE | burstSize | NDMA_STARTUP_AES_IN | - NDMA_SRC_UPDATE_INC | NDMA_DST_UPDATE_FIXED; + NDMA_SRC_UPDATE_INC | NDMA_DST_UPDATE_FIXED; REG_NDMA1_CNT = 0; REG_NDMA1_SRC_ADDR = (u32)REG_AESRDFIFO; @@ -130,7 +130,7 @@ REG_NDMA1_WRITE_CNT = wordCount; REG_NDMA1_BLOCK_CNT = NDMA_BLOCK_SYS_FREQ; REG_NDMA1_CNT = NDMA_ENABLE | NDMA_REPEATING_MODE | burstSize | NDMA_STARTUP_AES_OUT | - NDMA_SRC_UPDATE_FIXED | NDMA_DST_UPDATE_INC; + NDMA_SRC_UPDATE_FIXED | NDMA_DST_UPDATE_INC; } void AES_crypt(AES_ctx *restrict ctx, const u32 *restrict in, u32 *restrict out, u32 size) diff --git a/source/arm9/debug.c b/source/arm9/debug.c index 8c51a31..a237440 100644 --- a/source/arm9/debug.c +++ b/source/arm9/debug.c @@ -82,33 +82,33 @@ printf("\x1b[41m\x1b[0J\x1b[9CGuru Meditation Error!\n\n%s:\n", typeStr[type]); printf("CPSR: 0x%08" PRIX32 "\n" - "r0 = 0x%08" PRIX32 " r8 = 0x%08" PRIX32 "\n" - "r1 = 0x%08" PRIX32 " r9 = 0x%08" PRIX32 "\n" - "r2 = 0x%08" PRIX32 " r10 = 0x%08" PRIX32 "\n" - "r3 = 0x%08" PRIX32 " r11 = 0x%08" PRIX32 "\n" - "r4 = 0x%08" PRIX32 " r12 = 0x%08" PRIX32 "\n" - "r5 = 0x%08" PRIX32 " sp = 0x%08" PRIX32 "\n" - "r6 = 0x%08" PRIX32 " lr = 0x%08" PRIX32 "\n" - "r7 = 0x%08" PRIX32 " pc = 0x%08" PRIX32 "\n\n", - excStack[0], - excStack[2], excStack[10], - excStack[3], excStack[11], - excStack[4], excStack[12], - excStack[5], excStack[13], - excStack[6], excStack[14], - excStack[7], excStack[15], - excStack[8], excStack[16], - excStack[9], realPc); + "r0 = 0x%08" PRIX32 " r8 = 0x%08" PRIX32 "\n" + "r1 = 0x%08" PRIX32 " r9 = 0x%08" PRIX32 "\n" + "r2 = 0x%08" PRIX32 " r10 = 0x%08" PRIX32 "\n" + "r3 = 0x%08" PRIX32 " r11 = 0x%08" PRIX32 "\n" + "r4 = 0x%08" PRIX32 " r12 = 0x%08" PRIX32 "\n" + "r5 = 0x%08" PRIX32 " sp = 0x%08" PRIX32 "\n" + "r6 = 0x%08" PRIX32 " lr = 0x%08" PRIX32 "\n" + "r7 = 0x%08" PRIX32 " pc = 0x%08" PRIX32 "\n\n", + excStack[0], + excStack[2], excStack[10], + excStack[3], excStack[11], + excStack[4], excStack[12], + excStack[5], excStack[13], + excStack[6], excStack[14], + excStack[7], excStack[15], + excStack[8], excStack[16], + excStack[9], realPc); // make sure we can actually dump the stack without triggering another fault. if((excStack[15] >= (u32)A9_STACK_START) && (excStack[15] < (u32)A9_STACK_END) && - (excStack[15] + maxStackWords * 4 < (u32)A9_STACK_END)) + (excStack[15] + maxStackWords * 4 < (u32)A9_STACK_END)) { puts("Stack dump:"); for(u32 i = 0; i < maxStackWords / 2; i++) { printf("0x%08" PRIX32 ": %08" PRIX32 " %08" PRIX32 "\n", excStack[15], - ((u32*)excStack[15])[0], ((u32*)excStack[15])[1]); + ((u32*)excStack[15])[0], ((u32*)excStack[15])[1]); excStack[15] += 8; } } diff --git a/source/arm9/dev.c b/source/arm9/dev.c index 75dcd2b..850cbae 100644 --- a/source/arm9/dev.c +++ b/source/arm9/dev.c @@ -158,7 +158,7 @@ bool sdmmc_sd_write_sector(u32 sector, u32 count, const void *buf) { if(!dev_sd.initialized) - return false; + return false; return !sdmmc_sdcard_writesectors(sector, count, buf); } @@ -299,9 +299,9 @@ // Crypt settings AES_setCryptParams(&dev_dnand.twlAesCtx, AES_OUTPUT_LITTLE | AES_INPUT_LITTLE | AES_OUTPUT_REVERSED | - AES_INPUT_REVERSED | AES_MODE_CTR); + AES_INPUT_REVERSED | AES_MODE_CTR); AES_setCryptParams(&dev_dnand.ctrAesCtx, AES_OUTPUT_BIG | AES_INPUT_BIG | AES_OUTPUT_NORMAL | - AES_INPUT_NORMAL | AES_MODE_CTR); + AES_INPUT_NORMAL | AES_MODE_CTR); dev_dnand.dev.initialized = true; } @@ -315,7 +315,7 @@ { nand_partition_struct *partition = &dev_dnand.partitions[i]; if((partition->sector <= sector) && (partition->count >= count) - && (partition->sector + partition->count >= sector + count)) + && (partition->sector + partition->count >= sector + count)) return partition; } diff --git a/source/arm9/exception.s b/source/arm9/exception.s index e5970ca..78d007d 100644 --- a/source/arm9/exception.s +++ b/source/arm9/exception.s @@ -54,10 +54,10 @@ ldmia r12, {r1, r2} and r1, r1, r2 mov r3, #0x80000000 -irqHandler_find_first_lp: - clz r0, r1 - bics r1, r1, r3, lsr r0 - bne irqHandler_find_first_lp + irqHandler_find_first_lp: + clz r0, r1 + bics r1, r1, r3, lsr r0 + bne irqHandler_find_first_lp mov r1, r3, lsr r0 str r1, [r12, #4] @ REG_IRQ_IF rsb r2, r0, #31 @ r2 = 31 - r0 diff --git a/source/arm9/firm.c b/source/arm9/firm.c index 1b23e20..6e2bfb2 100644 --- a/source/arm9/firm.c +++ b/source/arm9/firm.c @@ -72,8 +72,8 @@ REG_NDMA_DST_ADDR(i) = section->address; REG_NDMA_WRITE_CNT(i) = section->size / 4; REG_NDMA_BLOCK_CNT(i) = NDMA_BLOCK_SYS_FREQ; - REG_NDMA_CNT(i) = NDMA_DST_UPDATE_INC | NDMA_SRC_UPDATE_INC - | NDMA_STARTUP_IMMEDIATE | NDMA_ENABLE; + REG_NDMA_CNT(i) = NDMA_DST_UPDATE_INC | NDMA_SRC_UPDATE_INC | + NDMA_STARTUP_IMMEDIATE | NDMA_ENABLE; } else { @@ -90,8 +90,8 @@ } } - while(REG_NDMA0_CNT & NDMA_ENABLE || REG_NDMA1_CNT & NDMA_ENABLE - || REG_NDMA2_CNT & NDMA_ENABLE || REG_NDMA3_CNT & NDMA_ENABLE); + while(REG_NDMA0_CNT & NDMA_ENABLE || REG_NDMA1_CNT & NDMA_ENABLE || + REG_NDMA2_CNT & NDMA_ENABLE || REG_NDMA3_CNT & NDMA_ENABLE); // Tell ARM11 its entrypoint REG_PXI_SYNC9 = 0; // Disable all IRQs @@ -143,8 +143,8 @@ continue; if(printInfo) - printf("Section %i:\noffset: 0x%"PRIX32", addr: 0x%"PRIX32", size: 0x%"PRIX32"\n", - (int) i, section->offset, section->address, section->size); + printf("Section %i:\noffset: 0x%"PRIX32", addr: 0x%"PRIX32", size: 0x%"PRIX32"\n", (int)i, + section->offset, section->address, section->size); if(section->offset >= fwSize) { @@ -162,6 +162,7 @@ // check for bad sections const u32 numEntries = arrayEntries(firmProtectedArea); + for(u32 j=0; j> 2) - 2) & 0xFFFFFF)) + +setupExceptionVectors: + adr r0, vectorStubs + mov r1, #A9_VECTORS_START + ldmia r0!, {r2-r9} + stmia r1!, {r2-r9} + ldmia r0, {r2-r5} + stmia r1, {r2-r5} + bx lr +vectorStubs: + ldr pc, irqHandlerPtr + irqHandlerPtr: .word irqHandler + ldr pc, fiqHandlerPtr + fiqHandlerPtr: .word (A9_VECTORS_START + 0x08) + ldr pc, svcHandlerPtr + svcHandlerPtr: .word (A9_VECTORS_START + 0x10) + ldr pc, undefInstrHandlerPtr + undefInstrHandlerPtr: .word undefInstrHandler + ldr pc, prefetchAbortHandlerPtr + prefetchAbortHandlerPtr: .word prefetchAbortHandler + ldr pc, dataAbortHandlerPtr + dataAbortHandlerPtr: .word dataAbortHandler +.pool + + +setupTcms: + ldr r0, =(DTCM_BASE | 0x0A) @ Base = 0xFFF00000, size = 16 KB + mcr p15, 0, r0, c9, c1, 0 @ Write DTCM region reg + mov r0, #(ITCM_BASE | 0x24) @ Base = 0x00000000, size = 512 KB (32 KB mirrored) + mcr p15, 0, r0, c9, c1, 1 @ Write ITCM region reg + + mrc p15, 0, r0, c1, c0, 0 @ Read control register + orr r0, r0, #0x50000 @ Enable DTCM and ITCM + mcr p15, 0, r0, c1, c0, 0 @ Write control register + bx lr .pool @@ -95,6 +172,165 @@ .pool +#define REGION_4KB (0b01011) +#define REGION_8KB (0b01100) +#define REGION_16KB (0b01101) +#define REGION_32KB (0b01110) +#define REGION_64KB (0b01111) +#define REGION_128KB (0b10000) +#define REGION_256KB (0b10001) +#define REGION_512KB (0b10010) +#define REGION_1MB (0b10011) +#define REGION_2MB (0b10100) +#define REGION_4MB (0b10101) +#define REGION_8MB (0b10110) +#define REGION_16MB (0b10111) +#define REGION_32MB (0b11000) +#define REGION_64MB (0b11001) +#define REGION_128MB (0b11010) +#define REGION_256MB (0b11011) +#define REGION_512MB (0b11100) +#define REGION_1GB (0b11101) +#define REGION_2GB (0b11110) +#define REGION_4GB (0b11111) +#define MAKE_REGION(adr, size) ((adr) | ((size)<<1) | 1) + +#define PER_NO_ACC (0) +#define PER_PRIV_RW_USR_NO_ACC (0b0001) +#define PER_PRIV_RW_USR_RO (0b0010) +#define PER_PRIV_RW_USR_RW (0b0011) +#define PER_PRIV_RO_USR_NO_ACC (0b0101) +#define PER_PRIV_RO_USR_RO (0b0110) +#define MAKE_PERMISSIONS(r0, r1, r2, r3, r4, r5, r6, r7) \ + ((r0) | (r1<<4) | (r2<<8) | (r3<<12) | (r4<<16) | (r5<<20) | (r6<<24) | (r7<<28)) + +setupMpu: + @ Region 0: ITCM kernel mirror 32 KB + @ Region 1: ARM9 internal mem 1 MB + @ Region 2: IO region 2 MB covers only ARM9 accessible regs + @ Region 3: VRAM 8MB + @ Region 4: DTCM 16 KB + @ Region 5: - (reserved) + @ Region 6: - (reserved) + @ Region 7: Exception vectors + ARM9 bootrom 32 KB + ldr r0, =MAKE_REGION(ITCM_KERNEL_MIRROR, REGION_32KB) + mcr p15, 0, r0, c6, c0, 0 + ldr r0, =MAKE_REGION(A9_RAM_BASE, REGION_1MB) + mcr p15, 0, r0, c6, c1, 0 + ldr r0, =MAKE_REGION(IO_MEM_ARM9_ONLY, REGION_2MB) + mcr p15, 0, r0, c6, c2, 0 + ldr r0, =MAKE_REGION(VRAM_BASE, REGION_8MB) + mcr p15, 0, r0, c6, c3, 0 + ldr r0, =MAKE_REGION(DTCM_BASE, REGION_16KB) + mcr p15, 0, r0, c6, c4, 0 + mov r0, #0 + mcr p15, 0, r0, c6, c5, 0 + //mov r0, #0 + mcr p15, 0, r0, c6, c6, 0 + ldr r0, =MAKE_REGION(BOOT9_BASE, REGION_32KB) + mcr p15, 0, r0, c6, c7, 0 + + @ Data access permissions: + @ Region 0: User = --, Privileged = RW + @ Region 1: User = --, Privileged = RW + @ Region 2: User = --, Privileged = RW + @ Region 3: User = --, Privileged = RW + @ Region 4: User = --, Privileged = RW + @ Region 5: User = --, Privileged = -- + @ Region 6: User = --, Privileged = -- + @ Region 7: User = --, Privileged = RO + ldr r0, =MAKE_PERMISSIONS(PER_PRIV_RW_USR_NO_ACC, PER_PRIV_RW_USR_NO_ACC, + PER_PRIV_RW_USR_NO_ACC, PER_PRIV_RW_USR_NO_ACC, + PER_PRIV_RW_USR_NO_ACC, PER_NO_ACC, + PER_NO_ACC , PER_PRIV_RO_USR_NO_ACC) + mcr p15, 0, r0, c5, c0, 2 @ Data access permissions + + @ Instruction access permissions: + @ Region 0: User = --, Privileged = RO + @ Region 1: User = --, Privileged = RO + @ Region 2: User = --, Privileged = -- + @ Region 3: User = --, Privileged = -- + @ Region 4: User = --, Privileged = -- + @ Region 5: User = --, Privileged = -- + @ Region 6: User = --, Privileged = -- + @ Region 7: User = --, Privileged = RO + ldr r0, =MAKE_PERMISSIONS(PER_PRIV_RO_USR_NO_ACC, PER_PRIV_RO_USR_NO_ACC, + PER_NO_ACC, PER_NO_ACC, + PER_NO_ACC, PER_NO_ACC, + PER_NO_ACC, PER_PRIV_RO_USR_NO_ACC) + mcr p15, 0, r0, c5, c0, 3 @ Instruction access permissions + + @ Data cachable bits: + @ Region 0 = no + @ Region 1 = yes + @ Region 2 = no <-- Never cache IO regs + @ Region 3 = yes + @ Region 4 = no + @ Region 5 = no + @ Region 6 = no + @ Region 7 = yes + mov r0, #0b10001010 + mcr p15, 0, r0, c2, c0, 0 @ Data cachable bits + + @ Instruction cachable bits: + @ Region 0 = no + @ Region 1 = yes + @ Region 2 = no + @ Region 3 = no + @ Region 4 = no + @ Region 5 = no + @ Region 6 = no + @ Region 7 = yes + mov r0, #0b10000010 + mcr p15, 0, r0, c2, c0, 1 @ Instruction cachable bits + + @ Write bufferable bits: + @ Region 0 = no + @ Region 1 = yes + @ Region 2 = no <-- Never buffer IO regs + @ Region 3 = yes + @ Region 4 = no + @ Region 5 = no + @ Region 6 = no + @ Region 7 = yes + mov r0, #0b10001010 + mcr p15, 0, r0, c3, c0, 0 @ Write bufferable bits + + mrc p15, 0, r0, c1, c0, 0 @ Read control register + ldr r1, =0x1005 @ MPU, D-Cache and I-Cache bitmask + orr r0, r0, r1 @ Enable MPU, D-Cache and I-Cache + mcr p15, 0, r0, c1, c0, 0 @ Write control register + bx lr +.pool + + @ Needed by libc _init: bx lr +.pool + + +deinitCpu: + msr cpsr_cxsf, #0xDF @ System mode + mov r3, lr + + @ Stub vectors to endless loops + mov r0, #A9_RAM_BASE + mov r1, #6 + ldr r2, =MAKE_BRANCH(0, 0) @ Endless loop + deinitCpu_lp: + str r2, [r0], #8 + subs r1, r1, #1 + bne deinitCpu_lp + + bl flushDCache + mov r2, #0 + mrc p15, 0, r0, c1, c0, 0 @ Read control register + ldr r1, =0x1005 @ MPU, D-Cache and I-Cache bitmask + bic r0, r0, r1 @ Disable MPU, D-Cache and I-Cache + mcr p15, 0, r0, c1, c0, 0 @ Write control register + + mcr p15, 0, r2, c7, c5, 0 @ Invalidate I-Cache + mcr p15, 0, r2, c7, c6, 0 @ Invalidate D-Cache + bx r3 +.pool diff --git a/source/arm9/timer.c b/source/arm9/timer.c index edc3e17..ead2ece 100644 --- a/source/arm9/timer.c +++ b/source/arm9/timer.c @@ -59,4 +59,3 @@ waitForIrq(); } } - diff --git a/source/util.c b/source/util.c index a10741c..c4cc818 100644 --- a/source/util.c +++ b/source/util.c @@ -99,8 +99,8 @@ u32 swap32(u32 val) { - return ((val>>24)| - (val>>8 & 0x0000FF00)| - (val<<8 & 0x00FF0000)| - (val<<24)); + return ((val>>24) | + (val>>8 & 0x0000FF00) | + (val<<8 & 0x00FF0000) | + (val<<24)); }