From 0da167a7885a68e52a9e9cb8c941acb4c89ba48b Mon Sep 17 00:00:00 2001 From: Zack Buhman Date: Tue, 10 Sep 2024 11:56:15 -0500 Subject: [PATCH] arm7: copy to exclusive internal ram Before this commit, attempting to start the rom on real NDS/DSi hardware would result in the display of a solid white screen, with no apparent evidence of the arm9 program running. After much testing, I found that this issue was directly caused "main mmeory" bus contention. Because arm7 and arm9 are both attempting to read instructions from ewram at the same time, and arm9 bus access stalls completely. I also found that this could not be mitigated with giving arm9 priority in EXMEMCNT. The solution appears to be to relocate arm7 code execution from main/shared memory to an arm7-internal memory. --- Makefile | 1 + arm7/arm7.lds | 25 ++++++++++++++----------- arm7/start.s | 24 +++++++++++++++++++++++- arm9/arm9.lds | 2 ++ dump.py | 6 ++++-- header.s | 2 +- symbols.lds | 2 -- 7 files changed, 45 insertions(+), 17 deletions(-) diff --git a/Makefile b/Makefile index 19feb9e..ac98bdd 100644 --- a/Makefile +++ b/Makefile @@ -15,6 +15,7 @@ registers: DEFAULT = header.o arm7/arm7.bin.o +2d_engine.elf: $(DEFAULT) arm9/2d_engine.bin.o triangle.elf: $(DEFAULT) arm9/triangle.bin.o triangle_rotating.elf: $(DEFAULT) arm9/triangle_rotating.bin.o texture.elf: $(DEFAULT) arm9/texture.bin.o diff --git a/arm7/arm7.lds b/arm7/arm7.lds index 9fe7410..e123193 100644 --- a/arm7/arm7.lds +++ b/arm7/arm7.lds @@ -2,47 +2,50 @@ OUTPUT_FORMAT("elf32-littlearm", "elf32-littlearm", "elf32-littlearm") OUTPUT_ARCH(arm) MEMORY { - ram : ORIGIN = 0x02000000, LENGTH = 4M + main_memory : ORIGIN = 0x02390000, LENGTH = 256K + arm7_exclusive_internal_work_ram : ORIGIN = 0x03800000, LENGTH = 64K } SECTIONS { - . = ORIGIN(ram) + 0x390000; + . = ORIGIN(arm7_exclusive_internal_work_ram); .text ALIGN(4) : { KEEP(*(.text.start)) *(.text) *(.text.*) - *(.glue_7t) - *(.glue_7) - *(.vfp11_veneer) - *(.v4_bx) - } > ram + . = ALIGN(32); + } >arm7_exclusive_internal_work_ram AT>main_memory .data ALIGN(4) : { *(.data) *(.data.*) - } > ram + } >arm7_exclusive_internal_work_ram AT>main_memory .rodata ALIGN(4) : { *(.rodata) *(.rodata.*) - } > ram + } >arm7_exclusive_internal_work_ram AT>main_memory .ctors ALIGN(4) : { KEEP(*(.ctors)) KEEP(*(.ctors.*)) - } > ram + } >arm7_exclusive_internal_work_ram AT>main_memory .bss ALIGN(4) (NOLOAD) : { *(.bss) *(.bss.*) *(COMMON) - } > ram + } >arm7_exclusive_internal_work_ram + + /DISCARD/ : + { + *(.glue_7) *(.glue_7t) *(.vfp11_veneer) *(.v4_bx) + } INCLUDE "../debug.lds" } diff --git a/arm7/start.s b/arm7/start.s index 62a5724..285e951 100644 --- a/arm7/start.s +++ b/arm7/start.s @@ -1,4 +1,26 @@ + .macro COPY_32_BYTE_ALIGNED + cmp r1, r10 + beq _fill_break.\@ +_fill_loop.\@: + ldmia r0!, {r2 - r9} + stmia r1!, {r2 - r9} + cmp r1, r10 + bne _fill_loop.\@ +_fill_break.\@: + .endm + .section .text.start .global _start _start: - b _start + // copy .text to internal ram + ldr r0, =__text_load_start + ldr r1, =__text_link_start + ldr r10, =__text_link_end + COPY_32_BYTE_ALIGNED + + // jump to internal ram + ldr r3,=_loop_forever + bx r3 + +_loop_forever: + b _loop_forever diff --git a/arm9/arm9.lds b/arm9/arm9.lds index e0832c2..918de4f 100644 --- a/arm9/arm9.lds +++ b/arm9/arm9.lds @@ -49,3 +49,5 @@ SECTIONS INCLUDE "../symbols.lds" INCLUDE "addresses.lds" + +__stack_end = ORIGIN(ram) + LENGTH(ram) - 4; diff --git a/dump.py b/dump.py index 9ea65e1..04d87f7 100644 --- a/dump.py +++ b/dump.py @@ -58,10 +58,12 @@ for name, offset, size in fields: print(f'{b:02x}', end='') pad = ' ' * (17 * 2 - size * 2) - if size == 4: + if name in {'game title', 'game code'}: + print(pad, buf[offset:offset+size], end='') + elif size == 4: n, = struct.unpack('