diff options
Diffstat (limited to 'libgloss/mips/crt0_cygmon.S')
-rw-r--r-- | libgloss/mips/crt0_cygmon.S | 173 |
1 files changed, 173 insertions, 0 deletions
diff --git a/libgloss/mips/crt0_cygmon.S b/libgloss/mips/crt0_cygmon.S new file mode 100644 index 000000000..ae0a9e373 --- /dev/null +++ b/libgloss/mips/crt0_cygmon.S @@ -0,0 +1,173 @@ +/* + * 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 */ |