diff --git a/dkarm-eabi/crtls/ds_arm7.ld b/dkarm-eabi/crtls/ds_arm7.ld index f057bc0..feb4843 100644 --- a/dkarm-eabi/crtls/ds_arm7.ld +++ b/dkarm-eabi/crtls/ds_arm7.ld @@ -37,26 +37,26 @@ SECTIONS { __arm7i_start__ = .; *(.twl) - *.twl.*(.text .stub .text.* .gnu.linkonce.t.*) - *.twl.*(.rodata) - *.twl.*(.roda) - *.twl.*(.rodata.*) - *.twl.*(.data) - *.twl.*(.data.*) - *.twl.*(.gnu.linkonce.d*) + *.twl*(.text .stub .text.* .gnu.linkonce.t.*) + *.twl*(.rodata) + *.twl*(.roda) + *.twl*(.rodata.*) + *.twl*(.data) + *.twl*(.data.*) + *.twl*(.gnu.linkonce.d*) __arm7i_end__ = .; } >twl_iwram AT>twl_ewram :arm7i .twl_bss ALIGN(4) (NOLOAD) : { __twl_bss_start__ = .; - *.(.twl_bss) + *(.twl_bss) *.twl.*(.dynbss) *.twl.*(.gnu.linkonce.b*) *.twl.*(.bss*) *.twl.*(COMMON) __twl_bss_end__ = .; - } + } >twl_iwram :NONE .crt0 : { @@ -66,7 +66,7 @@ SECTIONS __arm7_lma__ = .; - .text : /* ALIGN (4): */ + .text : { __arm7_start__ = .; KEEP (*(SORT_NONE(.init))) @@ -222,4 +222,4 @@ SECTIONS .debug_typenames 0 : { *(.debug_typenames) } .debug_varnames 0 : { *(.debug_varnames) } /* These must appear regardless of . */ -} +} \ No newline at end of file diff --git a/dkarm-eabi/crtls/ds_arm7_crt0.s b/dkarm-eabi/crtls/ds_arm7_crt0.s index b7c57bf..763e31b 100644 --- a/dkarm-eabi/crtls/ds_arm7_crt0.s +++ b/dkarm-eabi/crtls/ds_arm7_crt0.s @@ -23,13 +23,20 @@ _start: msr cpsr, r0 ldr sp, =__sp_usr @ Set user stack + adr r1, __sync_start @ Perform ARM7<->ARM9 sync code + ldr r2, =__arm7_start__ + mov r3, #(__sync_end-__sync_start) + mov r8, r2 + bl CopyMem + mov r3, r8 + bl _blx_r3_stub + @--------------------------------------------------------------------------------- @ Copy initialized data (data section) from LMA to VMA (EWRAM to IWRAM) @--------------------------------------------------------------------------------- - adr r0, arm7lma + adr r0, arm7lma @ Calculate ARM7 LMA ldr r1, [r0] - add r1, r0 - + add r1, r1, r0 ldr r2, =__arm7_start__ ldr r4, =__arm7_end__ bl CopyMemCheck @@ -39,6 +46,22 @@ _start: sub r1, r1, r0 bl ClearMem + cmp r10, #1 + bne NotTWL + ldr r1, =__dsimode @ set DSi mode flag + strb r10, [r1] + + ldr r1, =__arm7i_lma + ldr r2, =__arm7i_start__ + ldr r4, =__arm7i_end__ + bl CopyMemCheck + + ldr r0, =__twl_bss_start__ @ Clear TWL BSS section to 0x00 + ldr r1, =__twl_bss_end__ + sub r1, r1, r0 + bl ClearMem + +NotTWL: ldr r3, =__libc_init_array @ global constructors bl _blx_r3_stub @@ -46,17 +69,49 @@ _start: mov r1, #0 @ char *argv[] ldr r3, =main ldr lr,=__libnds_exit - -@--------------------------------------------------------------------------------- + mov r12, #0x4000000 @ tell arm9 we are ready + mov r9, #0 + str r9, [r12, #0x180] _blx_r3_stub: -@--------------------------------------------------------------------------------- bx r3 - arm7lma: - .word __arm7_lma__ - . + .word __arm7_lma__ - . .pool +@--------------------------------------------------------------------------------- +@ ARM7<->ARM9 synchronization code +@--------------------------------------------------------------------------------- + +__sync_start: + push {lr} + mov r12, #0x4000000 + mov r9, #0x0 + bl IPCSync + mov r9, #(0x9<<8) + str r9, [r12, #0x180] + mov r9, #0xA + bl IPCSync + mov r9, #(0xB<<8) + str r9, [r12, #0x180] + mov r9, #0xC + bl IPCSync + mov r9, #(0xD<<8) + str r9, [r12, #0x180] +IPCRecvFlag: + ldr r10, [r12, #0x180] + and r10, r10, #0xF + cmp r10, #0xC + beq IPCRecvFlag + pop {pc} +IPCSync: + ldr r10, [r12, #0x180] + and r10, r10, #0xF + cmp r10, r9 + bne IPCSync + bx lr +__sync_end: + @--------------------------------------------------------------------------------- @ Clear memory to 0x00 if length != 0 @ r0 = Start Address diff --git a/dkarm-eabi/crtls/ds_arm9.ld b/dkarm-eabi/crtls/ds_arm9.ld index 84c639d..82aaa6b 100644 --- a/dkarm-eabi/crtls/ds_arm9.ld +++ b/dkarm-eabi/crtls/ds_arm9.ld @@ -2,11 +2,9 @@ OUTPUT_FORMAT("elf32-littlearm", "elf32-bigarm", "elf32-littlearm") OUTPUT_ARCH(arm) ENTRY(_start) -__vectors_start = ORIGIN(vectors); -__itcm_start = ORIGIN(itcm); __ewram_end = ORIGIN(ewram) + LENGTH(ewram); __eheap_end = ORIGIN(ewram) + LENGTH(ewram); -__dtcm_start = ORIGIN(dtcm); + __dtcm_top = ORIGIN(dtcm) + LENGTH(dtcm); __irq_flags = __dtcm_top - 0x08; __irq_vector = __dtcm_top - 0x04; @@ -15,60 +13,67 @@ __sp_svc = __dtcm_top - 0x100; __sp_irq = __sp_svc - 0x100; __sp_usr = __sp_irq - 0x100; +PHDRS { + main PT_LOAD FLAGS(7); + dtcm PT_LOAD FLAGS(7); + itcm PT_LOAD FLAGS(7); + vectors PT_LOAD FLAGS(7); + twl PT_LOAD FLAGS(0x100007); +} + SECTIONS { /* Secure area crap */ - .secure : { *(.secure) } >ewram = 0 + .secure : { *(.secure) } >ewram :main = 0 .crt0 : { __text_start = . ; KEEP (*(.crt0)) . = ALIGN(4); /* REQUIRED. LD is flaky without it. */ - } >ewram = 0xff + } >ewram :main = 0x00 - .plt : { *(.plt) } >ewram = 0xff + .plt : { *(.plt) } >ewram :main = 0xff .init : { KEEP (*(SORT_NONE(.init))) - } >ewram + } >ewram :main .text : /* ALIGN (4): */ { - *(EXCLUDE_FILE (*.itcm*) .text) - - *(.text.*) - *(.stub) + *(EXCLUDE_FILE(*.itcm* *.vectors* *.twl*) .text) + *(EXCLUDE_FILE(*.itcm* *.vectors* *.twl*) .stub) + *(EXCLUDE_FILE(*.itcm* *.vectors* *.twl*) .text.*) /* .gnu.warning sections are handled specially by elf32.em. */ - *(.gnu.warning) - *(.gnu.linkonce.t*) + *(EXCLUDE_FILE(*.twl*) .gnu.warning) + *(EXCLUDE_FILE(*.twl*) .gnu.linkonce.t*) *(.glue_7) *(.glue_7t) . = ALIGN(4); /* REQUIRED. LD is flaky without it. */ - } >ewram = 0xff + } >ewram :main = 0xff .fini : { KEEP (*(.fini)) - } >ewram =0xff + } >ewram :main =0xff __text_end = . ; .rodata : { - *(.rodata) + *(EXCLUDE_FILE(*.twl*) .rodata) *all.rodata*(*) - *(.roda) - *(.rodata.*) - *(.gnu.linkonce.r*) + *(EXCLUDE_FILE(*.twl*) .roda) + *(EXCLUDE_FILE(*.twl*) .rodata.*) + *(EXCLUDE_FILE(*.twl*) .gnu.linkonce.r*) SORT(CONSTRUCTORS) . = ALIGN(4); /* REQUIRED. LD is flaky without it. */ - } >ewram = 0xff + } >ewram :main = 0xff - .ARM.extab : { *(.ARM.extab* .gnu.linkonce.armextab.*) } >ewram + .ARM.extab : { *(.ARM.extab* .gnu.linkonce.armextab.*) } >ewram :main __exidx_start = .; - ARM.exidx : { *(.ARM.exidx* .gnu.linkonce.armexidx.*) } >ewram + ARM.exidx : { *(.ARM.exidx* .gnu.linkonce.armexidx.*) } >ewram :main __exidx_end = .; /* Ensure the __preinit_array_start label is properly aligned. We @@ -79,21 +84,21 @@ SECTIONS . = ALIGN(32 / 8); PROVIDE (__preinit_array_start = .); - .preinit_array : { KEEP (*(.preinit_array)) } >ewram = 0xff + .preinit_array : { KEEP (*(.preinit_array)) } >ewram :main = 0xff PROVIDE (__preinit_array_end = .); PROVIDE (__init_array_start = .); .init_array : { KEEP (*(SORT(.init_array.*))) KEEP (*(.init_array)) - } >ewram = 0xff + } >ewram :main = 0xff PROVIDE (__init_array_end = .); PROVIDE (__fini_array_start = .); .fini_array : { KEEP (*(.fini_array)) KEEP (*(SORT(.fini_array.*))) - } >ewram = 0xff + } >ewram :main = 0xff PROVIDE (__fini_array_end = .); @@ -110,7 +115,7 @@ SECTIONS KEEP (*(SORT(.ctors.*))) KEEP (*(.ctors)) . = ALIGN(4); /* REQUIRED. LD is flaky without it. */ - } >ewram = 0xff + } >ewram :main = 0xff .dtors : { @@ -119,21 +124,21 @@ SECTIONS KEEP (*(SORT(.dtors.*))) KEEP (*(.dtors)) . = ALIGN(4); /* REQUIRED. LD is flaky without it. */ - } >ewram = 0xff + } >ewram :main = 0xff .eh_frame : { KEEP (*(.eh_frame)) . = ALIGN(4); /* REQUIRED. LD is flaky without it. */ - } >ewram = 0xff + } >ewram :main = 0xff .gcc_except_table : { *(.gcc_except_table) . = ALIGN(4); /* REQUIRED. LD is flaky without it. */ - } >ewram = 0xff - .jcr : { KEEP (*(.jcr)) } >ewram = 0 - .got : { *(.got.plt) *(.got) *(.rel.got) } >ewram = 0 + } >ewram :main = 0xff + .jcr : { KEEP (*(.jcr)) } >ewram :main = 0 + .got : { *(.got.plt) *(.got) *(.rel.got) } >ewram :main = 0 .ewram ALIGN(4) : { @@ -141,52 +146,51 @@ SECTIONS *(.ewram) *ewram.*(.text) . = ALIGN(4); /* REQUIRED. LD is flaky without it. */ - } >ewram = 0xff + } >ewram :main = 0xff .data ALIGN(4) : { __data_start = ABSOLUTE(.); - *(.data) - *(.data.*) - *(.gnu.linkonce.d*) + *(EXCLUDE_FILE(*.twl*) .data) + *(EXCLUDE_FILE(*.twl*) .data.*) + *(EXCLUDE_FILE(*.twl*) .gnu.linkonce.d*) CONSTRUCTORS . = ALIGN(4); __data_end = ABSOLUTE(.) ; - } >ewram = 0xff + } >ewram :main = 0xff - - __dtcm_lma = . ; __bss_vma = . ; - .dtcm __dtcm_start : AT (__dtcm_lma) + .dtcm : { + __dtcm_lma = LOADADDR(.dtcm); + __dtcm_start = ABSOLUTE(.); *(.dtcm) *(.dtcm.*) . = ALIGN(4); __dtcm_end = ABSOLUTE(.); - } >dtcm = 0xff + } >dtcm AT>ewram :dtcm = 0xff - - __itcm_lma = __dtcm_lma + SIZEOF(.dtcm); - - .itcm __itcm_start : AT (__itcm_lma) + .itcm : { + __itcm_lma = LOADADDR(.itcm); + __itcm_start = ABSOLUTE(.); *(.itcm) - *itcm.*(.text) + *.itcm*(.text .stub .text.*) . = ALIGN(4); __itcm_end = ABSOLUTE(.); - } >itcm = 0xff - - __vectors_lma = __itcm_lma + SIZEOF(.itcm); + } >itcm AT>ewram :itcm = 0xff - .vectors __vectors_start : AT (__vectors_lma) + .vectors : { + __vectors_lma = LOADADDR(.vectors); + __vectors_start = ABSOLUTE(.); *(.vectors) - *vectors.*(.text) + *.vectors*(.text .stub .text.*) . = ALIGN(4); __vectors_end = ABSOLUTE(.); - } >vectors = 0xff + } >vectors AT>ewram :vectors = 0xff .sbss __dtcm_end (NOLOAD): { @@ -195,22 +199,48 @@ SECTIONS *(.sbss) . = ALIGN(4); /* REQUIRED. LD is flaky without it. */ __sbss_end = ABSOLUTE(.); - } >dtcm + } >dtcm :NONE .bss __bss_vma (NOLOAD): { __bss_start = ABSOLUTE(.); __bss_start__ = ABSOLUTE(.); - *(.dynbss) - *(.gnu.linkonce.b*) - *(.bss*) - *(COMMON) + *(EXCLUDE_FILE(*.twl*) .dynbss) + *(EXCLUDE_FILE(*.twl*) .gnu.linkonce.b*) + *(EXCLUDE_FILE(*.twl*) .bss*) + *(EXCLUDE_FILE(*.twl*) COMMON) . = ALIGN(4); /* REQUIRED. LD is flaky without it. */ __bss_end__ = ABSOLUTE(.) ; __end__ = ABSOLUTE(.) ; - } AT>ewram + } >ewram :NONE + .twl __end__ : AT(MAX(0x2400000,MAX(__end__,LOADADDR(.vectors)+SIZEOF(.vectors)))) + { + __arm9i_lma = LOADADDR(.twl); + __arm9i_start__ = ABSOLUTE(.); + *(.twl) + *.twl*(.text .stub .text.* .gnu.linkonce.t.*) + *.twl*(.rodata) + *.twl*(.roda) + *.twl*(.rodata.*) + *.twl*(.data) + *.twl*(.data.*) + *.twl*(.gnu.linkonce.d*) + __arm9i_end__ = ABSOLUTE(.); + } :twl + .twl_bss __arm9i_end__ (NOLOAD): + { + __twl_bss_start__ = ABSOLUTE(.); + *(.twl_bss) + *.twl*(.dynbss) + *.twl*(.gnu.linkonce.b*) + *.twl*(.bss*) + *.twl*(COMMON) + . = ALIGN(4); /* REQUIRED. LD is flaky without it. */ + __twl_bss_end__ = ABSOLUTE(.); + __twl_end__ = ABSOLUTE(.); + } :NONE /* Stabs debugging sections. */ .stab 0 : { *(.stab) } diff --git a/dkarm-eabi/crtls/ds_arm9.mem b/dkarm-eabi/crtls/ds_arm9.mem index d97bb7b..1b3f0b4 100644 --- a/dkarm-eabi/crtls/ds_arm9.mem +++ b/dkarm-eabi/crtls/ds_arm9.mem @@ -1,7 +1,5 @@ MEMORY { - - rom : ORIGIN = 0x08000000, LENGTH = 32M - ewram : ORIGIN = 0x02000000, LENGTH = 4M - 48k + ewram : ORIGIN = 0x02000000, LENGTH = 4M - 512k dtcm : ORIGIN = 0x0b000000, LENGTH = 16K vectors : ORIGIN = 0x01000000, LENGTH = 256 itcm : ORIGIN = 0x01000100, LENGTH = 32K - 256 diff --git a/dkarm-eabi/crtls/ds_arm9_crt0.s b/dkarm-eabi/crtls/ds_arm9_crt0.s index 47591c5..0649c10 100644 --- a/dkarm-eabi/crtls/ds_arm9_crt0.s +++ b/dkarm-eabi/crtls/ds_arm9_crt0.s @@ -16,7 +16,7 @@ @--------------------------------------------------------------------------------- _start: @--------------------------------------------------------------------------------- - mov r0, #0x04000000 @ IME = 0; + mov r0, #0x04000000 @ IME = 0; str r0, [r0, #0x208] @ set sensible stacks to allow bios call @@ -46,6 +46,28 @@ _start: msr cpsr, r0 ldr sp, =__sp_usr @ Set user stack + mov r12, #0x4000000 @ Read system ROM status (NTR/TWL) + ldrb r11, [r12,r12,lsr #12] + and r11, r11, #0x3 + + mov r9, #(0x0<<8) @ Synchronize with ARM7 + str r9, [r12, #0x180] + mov r9, #0x9 + bl IPCSync + mov r9, #(0xA<<8) + str r9, [r12, #0x180] + mov r9, #0xB + bl IPCSync + mov r9, #(0xC<<8) + str r9, [r12, #0x180] + mov r9, #0xD + bl IPCSync + mov r9, r11, lsl #8 + str r9, [r12, #0x180] + mov r9, #0 + bl IPCSync + str r9, [r12, #0x180] + ldr r1, =__itcm_lma @ Copy instruction tightly coupled memory (itcm section) from LMA to VMA ldr r2, =__itcm_start ldr r4, =__itcm_end @@ -61,6 +83,9 @@ _start: ldr r4, =__dtcm_end bl CopyMemCheck + cmp r11, #1 + ldrne r10, =__end__ @ (DS mode) heap start + ldreq r10, =__twl_end__ @ (DSi mode) heap start bl checkARGV @ check and process argv trickery ldr r0, =__bss_start__ @ Clear BSS section @@ -72,14 +97,32 @@ _start: ldr r1, =__sbss_end sub r1, r1, r0 bl ClearMem - + cmp r11, #1 + bne NotTWL + ldr r9, =__dsimode @ set DSi mode flag + strb r11, [r9] + + ldr r1, =__arm9i_lma @ Copy TWL area (arm9i section) from LMA to VMA + ldr r2, =__arm9i_start__ + cmp r1, r2 @ skip copy if LMA=VMA + ldrne r4, =__arm9i_end__ + blne CopyMemCheck + + ldr r0, =__twl_bss_start__ @ Clear TWL BSS section + ldr r1, =__twl_bss_end__ + sub r1, r1, r0 + bl ClearMem + +NotTWL: ldr r0, =_libnds_argv @ reset heap base ldr r2, [r0,#20] @ newheap base - ldr r1,=fake_heap_start - str r2,[r1] + cmp r2, #0 + moveq r2, r10 + ldr r1, =fake_heap_start @ set heap start + str r2, [r1] ldr r1, =fake_heap_end @ set heap end sub r8, r8,#0xc000 @@ -122,7 +165,7 @@ checkARGV: ldr r2, [r0, #8] @ length of command line @ copy to heap - ldr r3, =__end__ @ initial heap base + mov r3, r10 @ initial heap base str r3, [r0, #4] @ set command line address cmp r2, #0 @@ -162,7 +205,7 @@ ClearMem: @--------------------------------------------------------------------------------- mov r2, #3 @ Round down to nearest word boundary add r1, r1, r2 @ Shouldn't be needed - bics r1, r1, r2 @ Clear 2 LSB (and set Z) + bics r1, r1, r2 @ Clear 2 LSB (and set Z) bxeq lr @ Quit if copy size is 0 mov r2, #0 @@ -192,7 +235,7 @@ CopyMem: @--------------------------------------------------------------------------------- mov r0, #3 @ These commands are used in cases where add r3, r3, r0 @ the length is not a multiple of 4, - bics r3, r3, r0 @ even though it should be. + bics r3, r3, r0 @ even though it should be. bxeq lr @ Length is zero, so exit CIDLoop: ldmia r1!, {r0} @@ -202,6 +245,17 @@ CIDLoop: bx lr +@--------------------------------------------------------------------------------- +@ Synchronize with ARM7 +@--------------------------------------------------------------------------------- +IPCSync: +@--------------------------------------------------------------------------------- + ldr r10, [r12, #0x180] + and r10, r10, #0xF + cmp r10, r9 + bne IPCSync + bx lr + @--------------------------------------------------------------------------------- .align .pool diff --git a/dkarm-eabi/crtls/dsi_arm9.mem b/dkarm-eabi/crtls/dsi_arm9.mem index e0027d2..a1d6aa8 100644 --- a/dkarm-eabi/crtls/dsi_arm9.mem +++ b/dkarm-eabi/crtls/dsi_arm9.mem @@ -1,5 +1,5 @@ MEMORY { - ewram : ORIGIN = 0x02000000, LENGTH = 16M - 48k + ewram : ORIGIN = 0x02000000, LENGTH = 15M - 512k dtcm : ORIGIN = 0x0b000000, LENGTH = 16K vectors : ORIGIN = 0x01000000, LENGTH = 256 itcm : ORIGIN = 0x01000100, LENGTH = 32K - 256