; crt0_2.s - Startup code for the mrisc1. This code initializes the C ; run-time model. ; ; 12Nov01 (DJK) - The return code from main was not being passed to exit(). ; Now it is passed as a parameter in R1. ; ; 10Sep01 (DJK) - The function exit() does not return. However, in the ; the case of device error (if the halt bit does not ; function properly, for instance), then a catch loop ; has been added. ; ; ; Copyright 2001, 2002, 2003, 2004 Morpho Technologies, Inc. ; ; Create a label for the start of the eh_frame section. .section .eh_frame __eh_frame_begin: .equ HALT_REG, 0x300 .section .text .global _start _start: ;; Initialize the stack pointer ldui sp, #%hi16(__stack) addui sp, sp, #%lo16(__stack) or fp, sp, sp ;; Copy data from ROM to Frame Buffer (on-chip memory) ldui r9, #%hi16(_fbdata_start) ori r9, r9, #%lo16(_fbdata_start) ldui r10, #%hi16(_fbdata_end) ori r10, r10, #%lo16(_fbdata_end) ldui r11, #%hi16(__FRAME_BUFFER_START) brle r10, r9, .Lnext1 ori r11, r11, #%lo16(__FRAME_BUFFER_START) .Lcpy0: ldw r5, r9, #$0 addi r9, r9, #$4 stw r5, r11, #$0 brlt r9, r10, .Lcpy0 addi r11, r11, #$4 .Lnext1: ;; Copy data from ROM to External Memory (off-chip memory) ldui r9, #%hi16(_extdata_start) ori r9, r9, #%lo16(_extdata_start) ldui r10, #%hi16(_extdata_end) ori r10, r10, #%lo16(_extdata_end) ldui r11, #%hi16(__EXTERNAL_MEMORY_START) brle r10, r9, .Lnext2 ori r11, r11, #%lo16(__EXTERNAL_MEMORY_START) .Lcpy1: ldw r5, r9, #$0 addi r9, r9, #$4 stw r5, r11, #$0 brlt r9, r10, .Lcpy1 addi r11, r11, #$4 .Lnext2: ;; Zero the bss space ldui r9, #%hi16(__bss_start) addui r9, r9, #%lo16(__bss_start) ldui r10, #%hi16(__bss_end) addui r10, r10, #%lo16(__bss_end) or r0, r0, r0 brle r10, r9, .Lnext3 or r0, r0, r0 .Lcpy2: stw r0, r9, #0 addi r9, r9, #4 or r0, r0, r0 ; nop brle r9, r10, .Lcpy2 or r0, r0, r0 ; nop .Lnext3: ;; Zero the external memory bss section ldui r9, #%hi16(_extbss_start) ori r9, r9, #%lo16(_extbss_start) ldui r10, #%hi16(_extbss_end) ori r10, r10, #%lo16(_extbss_end) or r0, r0, r0 brle r10, r9, .Lnext4 or r0, r0, r0 .Lcpy3: stw r0, r9, #$0 addi r9, r9, #$4 or r0, r0, r0 brle r9, r10, .Lcpy3 or r0, r0, r0 .Lnext4: ;; Call global and static constructors ldui r10, #%hi16(_init) ori r10, r10, #%lo16(_init) or r0, r0, r0 ; nop jal r14, r10 or r0, r0, r0 ; nop ;; Setup destructors to be called from exit. ;; (Just in case main never returns....) ldui r10, #%hi16(atexit) ori r10, r10, #%lo16(atexit) ldui r1, #%hi16(_fini) ori r1, r1, #%lo16(_fini) or r0, r0, r0 ; nop jal r14, r10 or r0, r0, r0 ; nop ;; Initialise argc, argv and envp to empty addi r1, r0, #0 addi r2, r0, #0 addi r3, r0, #0 ;; Call main ldui r10, #%hi16(main) ori r10, r10, #%lo16(main) or r0, r0, r0 ; nop jal r14, r10 or r0, r0, r0 ; nop ;; DJK - Added 12Nov01. Pass main's return value to exit. or r1, r11, r0 ;; Jump to exit ldui r10, #%hi16(exit) ori r10, r10, #%lo16(exit) or r0, r0, r0 ; nop jal r14, r10 or r0, r0, r0 ; nop ;; Exit does not return, however, this code is to catch an ;; error if it does. Set the processor into sleep mode. ori r1, r0, #$1 stw r1, r0, #HALT_REG or r0, r0, r0 or r0, r0, r0 or r0, r0, r0 or r0, r0, r0 or r0, r0, r0 .Lend: jmp .Lend or r0, r0, r0