/* * crt0_cygmon.S -- Minimal startup file for MIPS targets running Cygmon. * * Copyright (c) 1995, 1996, 1997, 2000 Red Hat, Inc. * * The authors hereby grant permission to use, copy, modify, distribute, * and license this software and its documentation for any purpose, provided * that existing copyright notices are retained in all copies and that this * notice is included verbatim in any distributions. No written agreement, * license, or royalty fee is required for any of the authorized uses. * Modifications to this software may be copyrighted by their authors * and need not follow the licensing terms described here, provided that * the new terms are clearly indicated on the first page of each file where * they apply. */ /* * This file contains the minimal startup code necessary. * This will not do any hardware initialization. It is assumed that we are talking to Cygmon * and therefore the hardware will be initialized properly. */ #ifdef __mips16 /* This file contains 32 bit assembly code. */ .set nomips16 #endif #include "regs.S" /* * Set up some room for a stack. We just grab a chunk of memory. */ #define STACK_SIZE 0x4000 #define GLOBAL_SIZE 0x2000 #define STARTUP_STACK_SIZE 0x0100 .comm __memsize, 12 .comm __lstack, STARTUP_STACK_SIZE .comm __stackbase,4 .text .align 4 /* * Without the following nop, GDB thinks _start is a data variable. * This is probably a bug in GDB in handling a symbol that is at the * start of the .text section. */ nop .globl _start .ent _start _start: .set noreorder la gp, _gp # set the global data pointer, defined in the linker script .end _start /* * zero out the bss section. */ .globl __memsize .globl get_mem_info .text .globl zerobss .ent zerobss zerobss: la v0, _fbss # These variables are defined in the linker script la v1, _end 3: sw zero, 0(v0) bltu v0, v1, 3b addiu v0, v0, 4 # executed in delay slot /* * Setup a small stack so we can run some C code, * and get the usable memory size. */ la t0, __lstack addiu sp, t0, STARTUP_STACK_SIZE la a0, __memsize jal get_mem_info nop /* * Setup the stack pointer -- * get_mem_info returns the top of memory, so just use that In * addition, we must subtract 24 bytes for the 3 8 byte * arguments to main, in case main wants to write them back to * the stack. The caller is supposed to allocate stack space * for parameters in registers in the old MIPS ABIs. We must * do this even though we aren't passing arguments, because * main might be declared to have them. * Some ports need a larger alignment for the stack, so we * subtract 32, which satisifes the stack for the arguments and * keeps the stack pointer better aligned. */ subu v0, v0, 32 move sp, v0 sw sp, __stackbase # keep this for future ref .end zerobss /* * initialize target specific stuff. Only execute these * functions it they exist. */ .globl hardware_init_hook .text .globl software_init_hook .text .globl __do_global_dtors .text .globl atexit .text .globl exit .text .globl init .ent init init: la t9, hardware_init_hook # init the hardware if needed beq t9, zero, 6f nop jal t9 nop 6: la t9, software_init_hook # init the software if needed beq t9, zero, 7f nop jal t9 nop 7: la a0, __do_global_dtors jal atexit nop #ifdef GCRT0 .globl _ftext .globl _extext la a0, _ftext la a1, _etext jal monstartup nop #endif move a0,zero # set argc to 0 jal main # call the program start function nop # fall through to the "exit" routine jal exit # call libc exit to run the G++ # destructors move a0, v0 # pass through the exit code .end init /* * _exit -- Exit from the application. Normally we cause a user trap * to return to the ROM monitor for another run. NOTE: This is * the only other routine we provide in the crt0.o object, since * it may be tied to the "_start" routine. It also allows * executables that contain a complete world to be linked with * just the crt0.o object. */ .globl _exit .ent _exit _exit: 7: #ifdef GCRT0 jal _mcleanup nop #endif # Cygmon expects a break 5 break 5 nop b 7b # loop back just in-case nop .end _exit /* EOF crt0.S */