From 49703eb3f53c12fb0ac3d12ca0beaddfe581cfd4 Mon Sep 17 00:00:00 2001 From: Jeff Johnston Date: Wed, 20 Aug 2003 19:32:52 +0000 Subject: [PATCH] 2003-08-20 Chris Demetriou * mips/crt0_cfe.S: New file. * mips/cfe_mem.c: New file. * mips/cfe_prestart.S: Remove. * mips/cfe.ld: Adjust to use crt0_cfe.o as the startup file, and and use _start as the entry point. Align BSS to 32-byte boundary. * mips/cfe.c: Reimplement to fit on top of a crt0_cfe.o file. * mips/cfe_api.h (__libcfe_stack_size, __libcfe_mem_limit) (__libcfe_meminit, __libcfe_stack_top): New prototypes. * mips/Makefile.in (CFEOBJS): Replace cfe_prestart.o with cfe_mem.o. (cfe.o, cfe_api.o, cfe_mem.o, crt0_cfe.o): New targets. * mips/configure.in: Build and install crt0_cfe.o when CFE support is built. * mips/configure: Regenerate. --- libgloss/ChangeLog | 16 +++ libgloss/mips/Makefile.in | 11 +- libgloss/mips/cfe.c | 88 ++++-------- libgloss/mips/cfe.ld | 5 +- libgloss/mips/cfe_api.h | 34 +++++ libgloss/mips/cfe_mem.c | 130 +++++++++++++++++ libgloss/mips/cfe_prestart.S | 86 ------------ libgloss/mips/configure | 46 +++--- libgloss/mips/configure.in | 3 +- libgloss/mips/crt0_cfe.S | 263 +++++++++++++++++++++++++++++++++++ 10 files changed, 502 insertions(+), 180 deletions(-) create mode 100644 libgloss/mips/cfe_mem.c delete mode 100644 libgloss/mips/cfe_prestart.S create mode 100644 libgloss/mips/crt0_cfe.S diff --git a/libgloss/ChangeLog b/libgloss/ChangeLog index d8ed896d5..49f37d5a2 100644 --- a/libgloss/ChangeLog +++ b/libgloss/ChangeLog @@ -1,3 +1,19 @@ +2003-08-20 Chris Demetriou + + * mips/crt0_cfe.S: New file. + * mips/cfe_mem.c: New file. + * mips/cfe_prestart.S: Remove. + * mips/cfe.ld: Adjust to use crt0_cfe.o as the startup file, and + and use _start as the entry point. Align BSS to 32-byte boundary. + * mips/cfe.c: Reimplement to fit on top of a crt0_cfe.o file. + * mips/cfe_api.h (__libcfe_stack_size, __libcfe_mem_limit) + (__libcfe_meminit, __libcfe_stack_top): New prototypes. + * mips/Makefile.in (CFEOBJS): Replace cfe_prestart.o with cfe_mem.o. + (cfe.o, cfe_api.o, cfe_mem.o, crt0_cfe.o): New targets. + * mips/configure.in: Build and install crt0_cfe.o when CFE support + is built. + * mips/configure: Regenerate. + 2003-08-12 Jeff Johnston * i386/cygmon-salib.c (unlink): New stub. diff --git a/libgloss/mips/Makefile.in b/libgloss/mips/Makefile.in index 78d6f4752..ada567eb3 100644 --- a/libgloss/mips/Makefile.in +++ b/libgloss/mips/Makefile.in @@ -73,8 +73,7 @@ PMONOBJS = pmon.o @part_specific_obj@ ${GENOBJS} LSIOBJS = lsipmon.o @part_specific_obj@ ${GENOBJS} DVEOBJS = dvemon.o @part_specific_obj@ ${GENOBJS} ${GENOBJS2} JMR3904OBJS = jmr3904-io.o @part_specific_obj@ ${GENOBJS} ${GENOBJS2} -CFEOBJS = cfe.o cfe_api.o cfe_prestart.o \ - @part_specific_obj@ ${GENOBJS} ${GENOBJS2} +CFEOBJS = cfe.o cfe_api.o cfe_mem.o @part_specific_obj@ ${GENOBJS} ${GENOBJS2} CYGMONOBJS = open.o close.o cygmon.o @part_specific_obj@ ${GENOBJS} # Nullmon cannot support read and write, but the test cases pull them in via libs @@ -136,7 +135,6 @@ libcygmon.a: $(CYGMONOBJS) ${AR} ${ARFLAGS} $@ $(CYGMONOBJS) ${RANLIB} $@ - libcfe.a: $(CFEOBJS) ${AR} ${ARFLAGS} $@ $(CFEOBJS) ${RANLIB} $@ @@ -219,6 +217,7 @@ test.o: ${srcdir}/test.c crt0.o: ${srcdir}/crt0.S pcrt0.o: ${srcdir}/crt0.S $(CC) -c $(CFLAGS_FOR_TARGET) $(CFLAGS) -DGCRT0 ${srcdir}/crt0.S -o ${PCRT0} +crt0_cfe.o: ${srcdir}/crt0_cfe.S crt0_cygmon.o: ${srcdir}/crt0_cygmon.S idtmon.o: ${srcdir}/idtmon.S pmon.o: ${srcdir}/pmon.S @@ -230,6 +229,12 @@ vr5xxx.o: ${srcdir}/vr5xxx.S lsipmon.o: $(srcdir)/lsipmon.S $(srcdir)/pmon.S jmr3904-io.o: ${srcdir}/jmr3904-io.c $(CC) -c $(CFLAGS_FOR_TARGET) $(CFLAGS) ${srcdir}/jmr3904-io.c -o $@ +cfe.o: ${srcdir}/cfe.c ${srcdir}/cfe_api.h + $(CC) -c $(CFLAGS_FOR_TARGET) $(CFLAGS) ${srcdir}/cfe.c -o $@ +cfe_api.o: ${srcdir}/cfe_api.c ${srcdir}/cfe_api.h ${srcdir}/cfe_api_int.h + $(CC) -c $(CFLAGS_FOR_TARGET) $(CFLAGS) ${srcdir}/cfe_api.c -o $@ +cfe_mem.o: ${srcdir}/cfe_mem.c ${srcdir}/cfe_api.h + $(CC) -c $(CFLAGS_FOR_TARGET) $(CFLAGS) ${srcdir}/cfe_mem.c -o $@ # cma101 can not be compiled mips16, if a mips16 version is needed then # it will have to be built, then this rule can be scrapped, allowing diff --git a/libgloss/mips/cfe.c b/libgloss/mips/cfe.c index 0b0865eae..c1d8af559 100644 --- a/libgloss/mips/cfe.c +++ b/libgloss/mips/cfe.c @@ -1,7 +1,7 @@ /* cfe.c -- I/O code for the MIPS boards running CFE. */ /* - * Copyright 2001, 2002 + * Copyright 2001, 2002, 2003 * Broadcom Corporation. All rights reserved. * * This software is furnished under license and may be used and copied only @@ -32,37 +32,40 @@ #include "cfe_api.h" +void *__libcfe_init (long handle, long a1, long cfe_entrypoint, long a3); +void __libcfe_exit (long status); + char inbyte (void); int outbyte (char c); -/* Make sure cfe_prestart is used. It doesn't look like setting the - entry symbol in the linker script to a symbol from that fiel will do - this! */ -extern int _prestart; -static void *force_prestart = &_prestart; - -/* The following variables are initialized to non-zero so that they'll be - in data, rather than BSS. Used to be that you could init variables to - any value to put them into initialized data sections rather than BSS, - but that decades-old idiom went out the window with gcc 3.2. Now, - either you compile specially (with -fno-zero-initialized-in-bss), or - you init to non-zero. In this case, initting to non-zero is OK (and - even beneficial; alignment fault via jump to odd if not properly - set up by _prestart()), so we do the latter. - - These variables are 'int's so they can be reliably stored w/ "sw". - (longs fall victim to -mlong64.) They are signed so that they remain - valid pointers when extended to cfe_xuint_t in the call to cfe_init(). - This assumes that they are compatibility-space pointers. */ -int __cfe_handle = 0xdeadbeef; -int __cfe_entrypt = 0xdeadbeef; - /* Echo input characters? */ -int __cfe_echo_input = 0; +int __libcfe_echo_input = 0; /* CFE handle used to access console device. */ static int cfe_conshandle; + +/* Initialize firmware callbacks. Called from crt0_cfe. Returns desired + stack pointer. */ +void * +__libcfe_init (long handle, long a1, long entrypoint, long a3) +{ + cfe_init (handle, entrypoint); + cfe_conshandle = cfe_getstdhandle (CFE_STDHANDLE_CONSOLE); + + __libcfe_meminit (); + return __libcfe_stack_top (); +} + +/* Exit back to monitor, with the given status code. */ +void +__libcfe_exit (long status) +{ + outbyte ('\r'); + outbyte ('\n'); + cfe_exit (CFE_FLG_WARMSTART, status); +} + char inbyte (void) { @@ -73,7 +76,7 @@ inbyte (void) ; if (c == '\r') c = '\n'; - if (__cfe_echo_input) + if (__libcfe_echo_input) outbyte (c); return c; } @@ -93,41 +96,6 @@ outbyte (char c) return 0; } -/* Initialize hardware. Called from crt0. */ -void -hardware_init_hook(void) -{ - cfe_init (__cfe_handle, __cfe_entrypt); - cfe_conshandle = cfe_getstdhandle(CFE_STDHANDLE_CONSOLE); -} - -/* Exit back to monitor, with the given status code. */ -void -hardware_exit_hook (int status) -{ - outbyte ('\r'); - outbyte ('\n'); - cfe_exit (CFE_FLG_WARMSTART, status); -} - -/* Structure filled in by get_mem_info. Only the size field is - actually used (by sbrk), so the others aren't even filled in. */ -struct s_mem -{ - unsigned int size; - unsigned int icsize; - unsigned int dcsize; -}; - -void -get_mem_info (mem) - struct s_mem *mem; -{ - /* XXX FIXME: Fake this for now. Should invoke cfe_enummem, but we - don't have enough stack to do that (yet). */ - mem->size = 0x4000000; /* Assume 64 MB of RAM */ -} - /* This is the MIPS cache flush function call. No defines are provided by libgloss for 'cache', and CFE doesn't let you flush ranges, so we just flush all I & D for every call. */ diff --git a/libgloss/mips/cfe.ld b/libgloss/mips/cfe.ld index 4abbf4468..d9fa414c0 100644 --- a/libgloss/mips/cfe.ld +++ b/libgloss/mips/cfe.ld @@ -1,8 +1,8 @@ /* The following TEXT start address leaves space for the monitor workspace. */ -ENTRY(_prestart) -STARTUP(crt0.o) +ENTRY(_start) +STARTUP(crt0_cfe.o) OUTPUT_FORMAT("elf32-bigmips", "elf32-bigmips", "elf32-littlemips") GROUP(-lc -lcfe -lgcc) SEARCH_DIR(.) @@ -127,6 +127,7 @@ SECTIONS *(COMMON) } + . = ALIGN(32); PROVIDE (end = .); _end = .; diff --git a/libgloss/mips/cfe_api.h b/libgloss/mips/cfe_api.h index 7b98a8fc8..afe46834e 100644 --- a/libgloss/mips/cfe_api.h +++ b/libgloss/mips/cfe_api.h @@ -71,6 +71,40 @@ typedef unsigned _POINTER_INT uintptr_t; #define CFE_API_ALL #define CFE_API_IMPL_NAMESPACE + +/* Return the stack size to be used for the program. Normally 32KB. The + normal memory allocator uses the bottom of the stack as its heap limit, + so if your application uses a lot of stack space define this function + appropriately to keep the heap from growing into the stack. */ +unsigned long __libcfe_stack_size(void) __attribute__((__weak__)); + +/* Return the (max address + 1) to be used by this program. (This address + minus '_end' is used as the heap size, so the address should be in the + same address space segments as _end. The normal memory allocator + queries CFE to determine the available memory. */ +void *__libcfe_mem_limit(void) __attribute__((__weak__)); + +/* If the configuration ability provided by __libcfe_mem_limit() and + __libcfe_stack_size() do not provide enough flexibility for your + application's memory allocation needs, you can replace the normal + low-level allocator by providing the functions listed below and + also the function: + + void *sbrk(ptrdiff_t incr); + + If you provide any of these functions, you should provide all three, + and be sure to link them into your application as a .o file (rather + than a .a). + + __libcfe_meminit() is responsible for initializing the low-level + memory allocator. + + __libcfe_stack_top() returns a pointer to the top (highest address; + the stack grows down from that address) of the stack to be used by + the program. */ +void __libcfe_meminit (void); +void *__libcfe_stack_top (void); + /* End customization. */ diff --git a/libgloss/mips/cfe_mem.c b/libgloss/mips/cfe_mem.c new file mode 100644 index 000000000..87caabf8c --- /dev/null +++ b/libgloss/mips/cfe_mem.c @@ -0,0 +1,130 @@ +/* cfe_mem.c -- Replaceable memory management hooks for MIPS boards + running CFE. */ + +/* + * Copyright 2003 + * Broadcom Corporation. All rights reserved. + * + * This software is furnished under license and may be used and copied only + * in accordance with the following terms and conditions. Subject to these + * conditions, you may download, copy, install, use, modify and distribute + * modified or unmodified copies of this software in source and/or binary + * form. No title or ownership is transferred hereby. + * + * 1) Any source code used, modified or distributed must reproduce and + * retain this copyright notice and list of conditions as they appear in + * the source file. + * + * 2) No right is granted to use any trade name, trademark, or logo of + * Broadcom Corporation. The "Broadcom Corporation" name may not be + * used to endorse or promote products derived from this software + * without the prior written permission of Broadcom Corporation. + * + * 3) THIS SOFTWARE IS PROVIDED "AS-IS" AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING BUT NOT LIMITED TO, ANY IMPLIED WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, OR + * NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL BROADCOM BE LIABLE + * FOR ANY DAMAGES WHATSOEVER, AND IN PARTICULAR, BROADCOM SHALL NOT BE + * LIABLE FOR DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR + * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + */ + +#include "cfe_api.h" + +/* Structure filled in by get_mem_info. Only the size field is + actually used (by sbrk), so the others aren't even filled in. + Note that 'size' is the __size__ of the heap starting at _end! */ +struct s_mem { + unsigned int size; + unsigned int icsize; + unsigned int dcsize; +}; + +void *get_mem_info (struct s_mem *); + +extern char _end[]; + +/* Address immediately after available memory. */ +static unsigned long memtop; + +/* Program stack size. */ +static unsigned long stack_size; + +void +__libcfe_meminit (void) +{ + /* If the user has provided a memory-limit function, use it to + determine the end of usable memory. */ + if (&__libcfe_mem_limit != NULL) + memtop = __libcfe_mem_limit (); + else + { + uint64_t start, length, type; + int i, rv; + long end_segbits, end_pa; + + /* Note that this only works if _end and the program live in kseg0 + or kseg1. Not a problem with the default linker script, but + if you're writing your own, keep it in mind. For more complex + memory allocation needs, you're encouraged to copy this file + and syscalls.c (for sbrk()), and reimplement as appropriate. */ + end_segbits = (long)_end & ~ 0x1fffffffL; + end_pa = (long)_end & 0x1fffffffL; + + for (i = 0; ; i++) + { + rv = cfe_enummem(i, 0, &start, &length, &type); + if (rv < 0) + { + /* Did not find an available entry containing _end. + Assume a minimal amount of memory (1MB). */ + memtop = _end + (1 * 1024 * 1024); + break; + } + + /* If not available, try the next. */ + if (type != CFE_MI_AVAILABLE) + continue; + + /* If end_pa is between start and (start + length) then we have + a winner. */ + if (end_pa >= start && end_pa < (start + length)) + { + memtop = (start + length) | end_segbits; + break; + } + } + } + + /* If the user has provided a memory-limit function, use it to + determine the end of usable memory. */ + if (&__libcfe_stack_size != NULL) + stack_size = __libcfe_stack_size (); + else + stack_size = (32 * 1024); /* Default = 32KB. */ + + /* Chop the top of memory to a 32-byte aligned location, and + round the stack size up to a 32-byte multiple. */ + memtop = memtop & ~(unsigned long)31; + stack_size = (stack_size + 31) & ~(unsigned long)31; +} + +void * +__libcfe_stack_top (void) +{ + /* Grow down from the top of available memory. Obviously, if + code writes above this limit, problems could result! */ + return (void *) memtop; +} + +/* For compatibility, get_mem_info returns the top of memory + (i.e., the stack address). Nothing actually uses that, + though. */ +void * +get_mem_info (struct s_mem *meminfo) +{ + meminfo->size = (char *)(memtop - stack_size) - _end; + return (void *) memtop; +} diff --git a/libgloss/mips/cfe_prestart.S b/libgloss/mips/cfe_prestart.S deleted file mode 100644 index 8548c1e47..000000000 --- a/libgloss/mips/cfe_prestart.S +++ /dev/null @@ -1,86 +0,0 @@ -/* - * cfe_prestart.S -- startup file for MIPS running CFE. - * Derived from crt0.S. - * - * Copyright (c) 1995, 1996, 1997 Cygnus Support - * - * 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. - */ - -#ifdef __mips16 -/* This file contains 32 bit assembly code. */ - .set nomips16 -#endif - -#include "regs.S" - -/* This is for referencing addresses that are not in the .sdata or - .sbss section under embedded-pic, or before we've set up gp. */ -#ifdef __mips_embedded_pic -# ifdef __mips64 -# define LA(t,x) la t,x-PICBASE ; daddu t,s0,t -# else -# define LA(t,x) la t,x-PICBASE ; addu t,s0,t -# endif -#else /* __mips_embedded_pic */ -# define LA(t,x) la t,x -#endif /* __mips_embedded_pic */ - - .globl __cfe_handle - .globl __cfe_entrypt - - .text - .align 2 - - .globl _prestart - .ent _prestart -_prestart: - .set noreorder -#ifdef __mips_embedded_pic - PICBASE = .+8 - bal PICBASE - nop - move s0,$31 -#endif - - /* These are actually pointers, but they're guaranteed to be - in compatibility space and it's just easier to store them - as words ("unsigned int") than worry about the actual - pointer size of the runtime we're building. */ - LA (v0, __cfe_handle) - sw a0, 0(v0) - LA (v0, __cfe_entrypt) - sw a2, 0(v0) - - LA (v0, _start) - jr v0 - nop - .end _prestart - - -/* Avoid worst-case execution hazards. This is targetted at the SB-1 - pipe, and is much worse than it needs to be (not even counting - the subroutine call and return). */ - .globl hardware_hazard_hook - .ent hardware_hazard_hook -hardware_hazard_hook: - .set push - .set mips32 - .set noreorder - ssnop - ssnop - ssnop - bnel $0, $0, .+4 - ssnop - j ra - nop - .set pop - .end hardware_hazard_hook diff --git a/libgloss/mips/configure b/libgloss/mips/configure index fb2e774ef..4089d6383 100755 --- a/libgloss/mips/configure +++ b/libgloss/mips/configure @@ -28,7 +28,6 @@ program_suffix=NONE program_transform_name=s,x,x, silent= site= -sitefile= srcdir= target=NONE verbose= @@ -143,7 +142,6 @@ Configuration: --help print this message --no-create do not create output files --quiet, --silent do not print \`checking...' messages - --site-file=FILE use FILE as the site file --version print the version of autoconf that created configure Directory and file names: --prefix=PREFIX install architecture-independent files in PREFIX @@ -314,11 +312,6 @@ EOF -site=* | --site=* | --sit=*) site="$ac_optarg" ;; - -site-file | --site-file | --site-fil | --site-fi | --site-f) - ac_prev=sitefile ;; - -site-file=* | --site-file=* | --site-fil=* | --site-fi=* | --site-f=*) - sitefile="$ac_optarg" ;; - -srcdir | --srcdir | --srcdi | --srcd | --src | --sr) ac_prev=srcdir ;; -srcdir=* | --srcdir=* | --srcdi=* | --srcd=* | --src=* | --sr=*) @@ -484,16 +477,12 @@ fi srcdir=`echo "${srcdir}" | sed 's%\([^/]\)/*$%\1%'` # Prefer explicitly selected file to automatically selected ones. -if test -z "$sitefile"; then - if test -z "$CONFIG_SITE"; then - if test "x$prefix" != xNONE; then - CONFIG_SITE="$prefix/share/config.site $prefix/etc/config.site" - else - CONFIG_SITE="$ac_default_prefix/share/config.site $ac_default_prefix/etc/config.site" - fi +if test -z "$CONFIG_SITE"; then + if test "x$prefix" != xNONE; then + CONFIG_SITE="$prefix/share/config.site $prefix/etc/config.site" + else + CONFIG_SITE="$ac_default_prefix/share/config.site $ac_default_prefix/etc/config.site" fi -else - CONFIG_SITE="$sitefile" fi for ac_site_file in $CONFIG_SITE; do if test -r "$ac_site_file"; then @@ -594,7 +583,7 @@ else { echo "configure: error: can not run $ac_config_sub" 1>&2; exit 1; } fi echo $ac_n "checking host system type""... $ac_c" 1>&6 -echo "configure:598: checking host system type" >&5 +echo "configure:587: checking host system type" >&5 host_alias=$host case "$host_alias" in @@ -615,7 +604,7 @@ host_os=`echo $host | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\3/'` echo "$ac_t""$host" 1>&6 echo $ac_n "checking target system type""... $ac_c" 1>&6 -echo "configure:619: checking target system type" >&5 +echo "configure:608: checking target system type" >&5 target_alias=$target case "$target_alias" in @@ -633,7 +622,7 @@ target_os=`echo $target | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\3/'` echo "$ac_t""$target" 1>&6 echo $ac_n "checking build system type""... $ac_c" 1>&6 -echo "configure:637: checking build system type" >&5 +echo "configure:626: checking build system type" >&5 build_alias=$build case "$build_alias" in @@ -687,7 +676,7 @@ test "$program_transform_name" = "" && program_transform_name="s,x,x," # SVR4 /usr/ucb/install, which tries to use the nonexistent group "staff" # ./install, which can be erroneously created by make from ./install.sh. echo $ac_n "checking for a BSD compatible install""... $ac_c" 1>&6 -echo "configure:691: checking for a BSD compatible install" >&5 +echo "configure:680: checking for a BSD compatible install" >&5 if test -z "$INSTALL"; then if eval "test \"`echo '$''{'ac_cv_path_install'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 @@ -751,7 +740,7 @@ test -z "$INSTALL_DATA" && INSTALL_DATA='${INSTALL} -m 644' # Extract the first word of "gcc", so it can be a program name with args. set dummy gcc; ac_word=$2 echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 -echo "configure:755: checking for $ac_word" >&5 +echo "configure:744: checking for $ac_word" >&5 if eval "test \"`echo '$''{'ac_cv_prog_CC'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else @@ -781,7 +770,7 @@ if test -z "$CC"; then # Extract the first word of "cc", so it can be a program name with args. set dummy cc; ac_word=$2 echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 -echo "configure:785: checking for $ac_word" >&5 +echo "configure:774: checking for $ac_word" >&5 if eval "test \"`echo '$''{'ac_cv_prog_CC'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else @@ -830,7 +819,7 @@ fi fi echo $ac_n "checking whether we are using GNU C""... $ac_c" 1>&6 -echo "configure:834: checking whether we are using GNU C" >&5 +echo "configure:823: checking whether we are using GNU C" >&5 if eval "test \"`echo '$''{'ac_cv_prog_gcc'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else @@ -839,7 +828,7 @@ else yes; #endif EOF -if { ac_try='${CC-cc} -E conftest.c'; { (eval echo configure:843: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }; } | egrep yes >/dev/null 2>&1; then +if { ac_try='${CC-cc} -E conftest.c'; { (eval echo configure:832: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }; } | egrep yes >/dev/null 2>&1; then ac_cv_prog_gcc=yes else ac_cv_prog_gcc=no @@ -854,7 +843,7 @@ if test $ac_cv_prog_gcc = yes; then ac_save_CFLAGS="$CFLAGS" CFLAGS= echo $ac_n "checking whether ${CC-cc} accepts -g""... $ac_c" 1>&6 -echo "configure:858: checking whether ${CC-cc} accepts -g" >&5 +echo "configure:847: checking whether ${CC-cc} accepts -g" >&5 if eval "test \"`echo '$''{'ac_cv_prog_cc_g'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else @@ -890,7 +879,7 @@ LD=${LD-ld} # Extract the first word of "ranlib", so it can be a program name with args. set dummy ranlib; ac_word=$2 echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 -echo "configure:894: checking for $ac_word" >&5 +echo "configure:883: checking for $ac_word" >&5 if eval "test \"`echo '$''{'ac_cv_prog_RANLIB'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else @@ -930,7 +919,7 @@ case "${target}" in ;; mipsisa32-*-* | mipsisa32el-*-* | \ mipsisa32r2-*-* | mipsisa32r2el-*-*) - crt0="crt0_cygmon.o crt0.o" + crt0="crt0_cfe.o crt0_cygmon.o crt0.o" pcrt0="pcrt0.o" part_specific_obj= part_specific_defines= @@ -955,6 +944,7 @@ case "${target}" in bsp_list="libpmon.a libnullmon.a" ;; *) + crt0="crt0_cfe.o crt0.o" part_specific_obj="vr4300.o cma101.o" part_specific_defines= script_list="idt pmon ddb ddb-kseg0 lsi cfe idtecoff nullmon" @@ -1166,7 +1156,7 @@ cat >> $CONFIG_STATUS <<\EOF # Split the substitutions into bite-sized pieces for seds with # small command number limits, like on Digital OSF/1 and HP-UX. -ac_max_sed_cmds=60 # Maximum number of lines to put in a sed script. +ac_max_sed_cmds=90 # Maximum number of lines to put in a sed script. ac_file=1 # Number of current file. ac_beg=1 # First line for current file. ac_end=$ac_max_sed_cmds # Line after last line for current file. diff --git a/libgloss/mips/configure.in b/libgloss/mips/configure.in index 8bc36bc32..b26734a38 100644 --- a/libgloss/mips/configure.in +++ b/libgloss/mips/configure.in @@ -94,7 +94,7 @@ case "${target}" in ;; mipsisa32-*-* | mipsisa32el-*-* | \ mipsisa32r2-*-* | mipsisa32r2el-*-*) - crt0="crt0_cygmon.o crt0.o" + crt0="crt0_cfe.o crt0_cygmon.o crt0.o" pcrt0="pcrt0.o" part_specific_obj= part_specific_defines= @@ -119,6 +119,7 @@ case "${target}" in bsp_list="libpmon.a libnullmon.a" ;; *) + crt0="crt0_cfe.o crt0.o" part_specific_obj="vr4300.o cma101.o" part_specific_defines= script_list="idt pmon ddb ddb-kseg0 lsi cfe idtecoff nullmon" diff --git a/libgloss/mips/crt0_cfe.S b/libgloss/mips/crt0_cfe.S new file mode 100644 index 000000000..9e920e2d5 --- /dev/null +++ b/libgloss/mips/crt0_cfe.S @@ -0,0 +1,263 @@ +/* + * crt0_cfe.S -- Runtime startup for MIPS targets running CFE. + * + * Copyright 2003 + * Broadcom Corporation. All rights reserved. + * + * This software is furnished under license and may be used and copied only + * in accordance with the following terms and conditions. Subject to these + * conditions, you may download, copy, install, use, modify and distribute + * modified or unmodified copies of this software in source and/or binary + * form. No title or ownership is transferred hereby. + * + * 1) Any source code used, modified or distributed must reproduce and + * retain this copyright notice and list of conditions as they appear in + * the source file. + * + * 2) No right is granted to use any trade name, trademark, or logo of + * Broadcom Corporation. The "Broadcom Corporation" name may not be + * used to endorse or promote products derived from this software + * without the prior written permission of Broadcom Corporation. + * + * 3) THIS SOFTWARE IS PROVIDED "AS-IS" AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING BUT NOT LIMITED TO, ANY IMPLIED WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, OR + * NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL BROADCOM BE LIABLE + * FOR ANY DAMAGES WHATSOEVER, AND IN PARTICULAR, BROADCOM SHALL NOT BE + * LIABLE FOR DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR + * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE + * OR OTHERWISE), EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +/* + * Derived from crt0_cygmon.S: + * + * 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 does minimal runtime startup for code running under + * CFE firmware. + * + * It does minimal hardware initialization. In particular + * it sets Status:FR to match the requested floating point + * mode. + * + * It is meant to be linked with the other files provided by libcfe.a, + * and calls routines in those files. + */ + +#ifdef __mips16 +/* This file contains 32 bit assembly code. */ + .set nomips16 +#endif +#ifdef __mips_embedded_pic +# error -membedded-pic is not supported. +#endif + +#include "regs.S" + +/* + * Set up some room for a stack. We just grab a chunk of memory. + */ +#define STARTUP_STACK_SIZE (1 * 1024) + + .comm _lstack, STARTUP_STACK_SIZE + + .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 + + + /* + * On entry, the following values have been passed in registers + * by the firmware: + * + * a0: firmware handle + * a1: zero (unused) + * a2: firmware callback entrypoint + * a3: CFE entrypoint seal (unused) + * + * They must be preserved until the CFE entrypoint and handle + * are passed to __libcfe_init(). + */ + + .globl _start + .ent _start +_start: + .set noreorder + /* Set the global data pointer, defined in the linker script. */ + la gp, _gp + +#ifndef __mips_soft_float + /* If compiled for hard float, set the FPU mode based on the + compilation flags. Note that this assumes that enough code + will run after the mtc0 to clear any hazards. */ + mfc0 t0, C0_SR + or t0, t0, (SR_CU1 | SR_FR) +#if (__mips_fpr == 32) + xor t0, t0, SR_FR /* If 32-bit FP mode, clear FR. */ +#endif + mtc0 t0, C0_SR +#endif + .end _start + + /* + * zero out the bss section. + */ + .globl _zerobss + .ent _zerobss +_zerobss: + /* These variables are defined in the linker script. */ + la v0, _fbss + la v1, _end + +3: + sw zero, 0(v0) + bltu v0, v1, 3b + addiu v0, v0, 4 /* Delay slot. */ + .end _zerobss + + /* + * Setup a small stack so we can run some C code, and do + * the library initialization. (32 bytes are saved for + * the argument registers' stack slots.) + */ + .globl _stackinit + .ent _stackinit +_stackinit: + la t0, _lstack + addiu sp, t0, (STARTUP_STACK_SIZE - 32) + jal __libcfe_init + nop + + /* + * Setup the stack pointer -- + * __libcfe_init() returns the value to be used as the top of + * the program's stack. + * + * We subtract 32 bytes for the 4 argument registers, in case + * main() wants to write them back to the stack. The caller + * allocates stack space for parameters in the old MIPS ABIs. + * We must do this even though we aren't passing arguments, + * because main might be declared to have them.) + * + * We subtract 32 more bytes for the argv/envp setup for the + * call to main(). + */ + subu v0, v0, 64 + move sp, v0 + + .end _stackinit + + /* + * initialize target specific stuff. Only execute these + * functions it they exist. + */ + .globl hardware_init_hook .text + .globl software_init_hook .text + .type _fini,@function + .type _init,@function + .globl atexit .text + .globl exit .text + .globl _crt0init + .ent _crt0init +_crt0init: + 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, _fini + jal atexit + nop + +#ifdef GCRT0 + .globl _ftext + .globl _extext + la a0, _ftext + la a1, _etext + jal monstartup + nop +#endif + + jal _init # run global constructors + nop + + addiu a1,sp,32 # argv = sp + 32 + addiu a2,sp,40 # envp = sp + 40 +#if __mips64 + sd zero,(a1) # argv[argc] = 0 + sd zero,(a2) # envp[0] = 0 +#else + sw zero,(a1) + sw zero,(a2) +#endif + + jal main # call the program start function + move a0,zero # set argc to 0; delay slot. + + # 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 _crt0init + +/* + * _exit -- Exit from the application. This is provided in this file because + * program exit should shut down profiling (if GCRT0 is defined), + * and only this file is compiled with GCRT0 defined. + */ + .globl _exit + .ent _exit +_exit: +7: + move s0, a0 /* Save in case we loop. */ + +#ifdef GCRT0 + jal _mcleanup + nop +#endif + + la t0, hardware_exit_hook + beq t0,zero,1f + nop + jal t0 + nop + +1: + /* Call into the library to do the heavy lifting. */ + jal __libcfe_exit + move a0, s0 /* Delay slot. */ + + b 7b /* Loop back just in case. */ + nop + .end _exit + +/* EOF crt0_cfe.S */