10 changed files with 5187 additions and 1 deletions
@ -0,0 +1,100 @@ |
|||
# Copyright (c) 1998 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.
|
|||
|
|||
DESTDIR = |
|||
VPATH = @srcdir@ |
|||
srcdir = @srcdir@ |
|||
objdir = . |
|||
srcroot = $(srcdir)/../.. |
|||
objroot = $(objdir)/../.. |
|||
|
|||
prefix = @prefix@ |
|||
exec_prefix = @exec_prefix@ |
|||
|
|||
host_alias = @host_alias@ |
|||
target_alias = @target_alias@ |
|||
program_transform_name = @program_transform_name@ |
|||
|
|||
bindir = @bindir@ |
|||
libdir = @libdir@ |
|||
includedir = @includedir@ |
|||
tooldir = $(exec_prefix)/$(target_alias) |
|||
|
|||
# Multilib support variables.
|
|||
# TOP is used instead of MULTI{BUILD,SRC}TOP.
|
|||
MULTIDIRS = |
|||
MULTISUBDIR = |
|||
MULTIDO = true |
|||
MULTICLEAN = true |
|||
|
|||
INSTALL = @INSTALL@ |
|||
INSTALL_PROGRAM = @INSTALL_PROGRAM@ |
|||
INSTALL_DATA = @INSTALL_DATA@ |
|||
|
|||
SHELL = /bin/sh |
|||
|
|||
CC = @CC@ |
|||
AS = @AS@ |
|||
AR = @AR@ |
|||
LD = @LD@ |
|||
RANLIB = @RANLIB@ |
|||
|
|||
OBJDUMP = `if [ -f ${objroot}/../binutils/objdump ] ; \
|
|||
then echo ${objroot}/../binutils/objdump ; \
|
|||
else t='$(program_transform_name)'; echo objdump | sed -e $$t ; fi` |
|||
OBJCOPY = `if [ -f ${objroot}/../binutils/objcopy ] ; \
|
|||
then echo ${objroot}/../binutils/objcopy ; \
|
|||
else t='$(program_transform_name)'; echo objcopy | sed -e $$t ; fi` |
|||
|
|||
GCC_LDFLAGS = `if [ -d ${objroot}/../gcc ] ; \
|
|||
then echo -L${objroot}/../gcc ; fi` |
|||
|
|||
OUTPUTS = crt0.o |
|||
|
|||
# Host specific makefile fragment comes in here.
|
|||
@host_makefile_frag@ |
|||
|
|||
|
|||
all: ${OUTPUTS} |
|||
|
|||
#
|
|||
# here's where we build the library for each target
|
|||
#
|
|||
|
|||
doc: |
|||
|
|||
clean mostlyclean: |
|||
rm -f $(OUTPUTS) $(BOARD_LIBS) *.i *~ *.o *-test *.srec *.dis *.map *.x |
|||
|
|||
distclean maintainer-clean realclean: clean |
|||
rm -f Makefile config.status $(OUTPUTS) |
|||
|
|||
.PHONY: install info install-info clean-info |
|||
install: |
|||
@for outputs in ${OUTPUTS}; do\
|
|||
mkdir -p $(DESTDIR)$(tooldir)/lib${MULTISUBDIR}; \
|
|||
$(INSTALL_DATA) $${outputs} $(DESTDIR)$(tooldir)/lib${MULTISUBDIR}; \
|
|||
done |
|||
$(INSTALL_DATA) ${srcdir}/include/or1k-support.h $(DESTDIR)$(tooldir)/include/ |
|||
$(INSTALL_DATA) ${srcdir}/include/or1k-sprs.h $(DESTDIR)$(tooldir)/include/ |
|||
$(INSTALL_DATA) ${srcdir}/include/or1k-asm.h $(DESTDIR)$(tooldir)/include/ |
|||
$(INSTALL_DATA) ${srcdir}/include/or1k-nop.h $(DESTDIR)$(tooldir)/include/ |
|||
|
|||
info: |
|||
install-info: |
|||
clean-info: |
|||
|
|||
Makefile: Makefile.in config.status @host_makefile_frag_path@ |
|||
$(SHELL) config.status |
|||
|
|||
config.status: configure |
|||
$(SHELL) config.status --recheck |
|||
@ -0,0 +1,409 @@ |
|||
# generated automatically by aclocal 1.11.6 -*- Autoconf -*- |
|||
|
|||
# Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, |
|||
# 2005, 2006, 2007, 2008, 2009, 2010, 2011 Free Software Foundation, |
|||
# Inc. |
|||
# This file is free software; the Free Software Foundation |
|||
# gives unlimited permission to copy and/or distribute it, |
|||
# with or without modifications, as long as this notice is preserved. |
|||
|
|||
# This program is distributed in the hope that it will be useful, |
|||
# but WITHOUT ANY WARRANTY, to the extent permitted by law; without |
|||
# even the implied warranty of MERCHANTABILITY or FITNESS FOR A |
|||
# PARTICULAR PURPOSE. |
|||
|
|||
# AM_CONDITIONAL -*- Autoconf -*- |
|||
|
|||
# Copyright (C) 1997, 2000, 2001, 2003, 2004, 2005, 2006, 2008 |
|||
# Free Software Foundation, Inc. |
|||
# |
|||
# This file is free software; the Free Software Foundation |
|||
# gives unlimited permission to copy and/or distribute it, |
|||
# with or without modifications, as long as this notice is preserved. |
|||
|
|||
# serial 9 |
|||
|
|||
# AM_CONDITIONAL(NAME, SHELL-CONDITION) |
|||
# ------------------------------------- |
|||
# Define a conditional. |
|||
AC_DEFUN([AM_CONDITIONAL], |
|||
[AC_PREREQ(2.52)dnl |
|||
ifelse([$1], [TRUE], [AC_FATAL([$0: invalid condition: $1])], |
|||
[$1], [FALSE], [AC_FATAL([$0: invalid condition: $1])])dnl |
|||
AC_SUBST([$1_TRUE])dnl |
|||
AC_SUBST([$1_FALSE])dnl |
|||
_AM_SUBST_NOTMAKE([$1_TRUE])dnl |
|||
_AM_SUBST_NOTMAKE([$1_FALSE])dnl |
|||
m4_define([_AM_COND_VALUE_$1], [$2])dnl |
|||
if $2; then |
|||
$1_TRUE= |
|||
$1_FALSE='#' |
|||
else |
|||
$1_TRUE='#' |
|||
$1_FALSE= |
|||
fi |
|||
AC_CONFIG_COMMANDS_PRE( |
|||
[if test -z "${$1_TRUE}" && test -z "${$1_FALSE}"; then |
|||
AC_MSG_ERROR([[conditional "$1" was never defined. |
|||
Usually this means the macro was only invoked conditionally.]]) |
|||
fi])]) |
|||
|
|||
# Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2009, |
|||
# 2010, 2011 Free Software Foundation, Inc. |
|||
# |
|||
# This file is free software; the Free Software Foundation |
|||
# gives unlimited permission to copy and/or distribute it, |
|||
# with or without modifications, as long as this notice is preserved. |
|||
|
|||
# serial 12 |
|||
|
|||
# There are a few dirty hacks below to avoid letting `AC_PROG_CC' be |
|||
# written in clear, in which case automake, when reading aclocal.m4, |
|||
# will think it sees a *use*, and therefore will trigger all it's |
|||
# C support machinery. Also note that it means that autoscan, seeing |
|||
# CC etc. in the Makefile, will ask for an AC_PROG_CC use... |
|||
|
|||
|
|||
# _AM_DEPENDENCIES(NAME) |
|||
# ---------------------- |
|||
# See how the compiler implements dependency checking. |
|||
# NAME is "CC", "CXX", "GCJ", or "OBJC". |
|||
# We try a few techniques and use that to set a single cache variable. |
|||
# |
|||
# We don't AC_REQUIRE the corresponding AC_PROG_CC since the latter was |
|||
# modified to invoke _AM_DEPENDENCIES(CC); we would have a circular |
|||
# dependency, and given that the user is not expected to run this macro, |
|||
# just rely on AC_PROG_CC. |
|||
AC_DEFUN([_AM_DEPENDENCIES], |
|||
[AC_REQUIRE([AM_SET_DEPDIR])dnl |
|||
AC_REQUIRE([AM_OUTPUT_DEPENDENCY_COMMANDS])dnl |
|||
AC_REQUIRE([AM_MAKE_INCLUDE])dnl |
|||
AC_REQUIRE([AM_DEP_TRACK])dnl |
|||
|
|||
ifelse([$1], CC, [depcc="$CC" am_compiler_list=], |
|||
[$1], CXX, [depcc="$CXX" am_compiler_list=], |
|||
[$1], OBJC, [depcc="$OBJC" am_compiler_list='gcc3 gcc'], |
|||
[$1], UPC, [depcc="$UPC" am_compiler_list=], |
|||
[$1], GCJ, [depcc="$GCJ" am_compiler_list='gcc3 gcc'], |
|||
[depcc="$$1" am_compiler_list=]) |
|||
|
|||
AC_CACHE_CHECK([dependency style of $depcc], |
|||
[am_cv_$1_dependencies_compiler_type], |
|||
[if test -z "$AMDEP_TRUE" && test -f "$am_depcomp"; then |
|||
# We make a subdir and do the tests there. Otherwise we can end up |
|||
# making bogus files that we don't know about and never remove. For |
|||
# instance it was reported that on HP-UX the gcc test will end up |
|||
# making a dummy file named `D' -- because `-MD' means `put the output |
|||
# in D'. |
|||
rm -rf conftest.dir |
|||
mkdir conftest.dir |
|||
# Copy depcomp to subdir because otherwise we won't find it if we're |
|||
# using a relative directory. |
|||
cp "$am_depcomp" conftest.dir |
|||
cd conftest.dir |
|||
# We will build objects and dependencies in a subdirectory because |
|||
# it helps to detect inapplicable dependency modes. For instance |
|||
# both Tru64's cc and ICC support -MD to output dependencies as a |
|||
# side effect of compilation, but ICC will put the dependencies in |
|||
# the current directory while Tru64 will put them in the object |
|||
# directory. |
|||
mkdir sub |
|||
|
|||
am_cv_$1_dependencies_compiler_type=none |
|||
if test "$am_compiler_list" = ""; then |
|||
am_compiler_list=`sed -n ['s/^#*\([a-zA-Z0-9]*\))$/\1/p'] < ./depcomp` |
|||
fi |
|||
am__universal=false |
|||
m4_case([$1], [CC], |
|||
[case " $depcc " in #( |
|||
*\ -arch\ *\ -arch\ *) am__universal=true ;; |
|||
esac], |
|||
[CXX], |
|||
[case " $depcc " in #( |
|||
*\ -arch\ *\ -arch\ *) am__universal=true ;; |
|||
esac]) |
|||
|
|||
for depmode in $am_compiler_list; do |
|||
# Setup a source with many dependencies, because some compilers |
|||
# like to wrap large dependency lists on column 80 (with \), and |
|||
# we should not choose a depcomp mode which is confused by this. |
|||
# |
|||
# We need to recreate these files for each test, as the compiler may |
|||
# overwrite some of them when testing with obscure command lines. |
|||
# This happens at least with the AIX C compiler. |
|||
: > sub/conftest.c |
|||
for i in 1 2 3 4 5 6; do |
|||
echo '#include "conftst'$i'.h"' >> sub/conftest.c |
|||
# Using `: > sub/conftst$i.h' creates only sub/conftst1.h with |
|||
# Solaris 8's {/usr,}/bin/sh. |
|||
touch sub/conftst$i.h |
|||
done |
|||
echo "${am__include} ${am__quote}sub/conftest.Po${am__quote}" > confmf |
|||
|
|||
# We check with `-c' and `-o' for the sake of the "dashmstdout" |
|||
# mode. It turns out that the SunPro C++ compiler does not properly |
|||
# handle `-M -o', and we need to detect this. Also, some Intel |
|||
# versions had trouble with output in subdirs |
|||
am__obj=sub/conftest.${OBJEXT-o} |
|||
am__minus_obj="-o $am__obj" |
|||
case $depmode in |
|||
gcc) |
|||
# This depmode causes a compiler race in universal mode. |
|||
test "$am__universal" = false || continue |
|||
;; |
|||
nosideeffect) |
|||
# after this tag, mechanisms are not by side-effect, so they'll |
|||
# only be used when explicitly requested |
|||
if test "x$enable_dependency_tracking" = xyes; then |
|||
continue |
|||
else |
|||
break |
|||
fi |
|||
;; |
|||
msvc7 | msvc7msys | msvisualcpp | msvcmsys) |
|||
# This compiler won't grok `-c -o', but also, the minuso test has |
|||
# not run yet. These depmodes are late enough in the game, and |
|||
# so weak that their functioning should not be impacted. |
|||
am__obj=conftest.${OBJEXT-o} |
|||
am__minus_obj= |
|||
;; |
|||
none) break ;; |
|||
esac |
|||
if depmode=$depmode \ |
|||
source=sub/conftest.c object=$am__obj \ |
|||
depfile=sub/conftest.Po tmpdepfile=sub/conftest.TPo \ |
|||
$SHELL ./depcomp $depcc -c $am__minus_obj sub/conftest.c \ |
|||
>/dev/null 2>conftest.err && |
|||
grep sub/conftst1.h sub/conftest.Po > /dev/null 2>&1 && |
|||
grep sub/conftst6.h sub/conftest.Po > /dev/null 2>&1 && |
|||
grep $am__obj sub/conftest.Po > /dev/null 2>&1 && |
|||
${MAKE-make} -s -f confmf > /dev/null 2>&1; then |
|||
# icc doesn't choke on unknown options, it will just issue warnings |
|||
# or remarks (even with -Werror). So we grep stderr for any message |
|||
# that says an option was ignored or not supported. |
|||
# When given -MP, icc 7.0 and 7.1 complain thusly: |
|||
# icc: Command line warning: ignoring option '-M'; no argument required |
|||
# The diagnosis changed in icc 8.0: |
|||
# icc: Command line remark: option '-MP' not supported |
|||
if (grep 'ignoring option' conftest.err || |
|||
grep 'not supported' conftest.err) >/dev/null 2>&1; then :; else |
|||
am_cv_$1_dependencies_compiler_type=$depmode |
|||
break |
|||
fi |
|||
fi |
|||
done |
|||
|
|||
cd .. |
|||
rm -rf conftest.dir |
|||
else |
|||
am_cv_$1_dependencies_compiler_type=none |
|||
fi |
|||
]) |
|||
AC_SUBST([$1DEPMODE], [depmode=$am_cv_$1_dependencies_compiler_type]) |
|||
AM_CONDITIONAL([am__fastdep$1], [ |
|||
test "x$enable_dependency_tracking" != xno \ |
|||
&& test "$am_cv_$1_dependencies_compiler_type" = gcc3]) |
|||
]) |
|||
|
|||
|
|||
# AM_SET_DEPDIR |
|||
# ------------- |
|||
# Choose a directory name for dependency files. |
|||
# This macro is AC_REQUIREd in _AM_DEPENDENCIES |
|||
AC_DEFUN([AM_SET_DEPDIR], |
|||
[AC_REQUIRE([AM_SET_LEADING_DOT])dnl |
|||
AC_SUBST([DEPDIR], ["${am__leading_dot}deps"])dnl |
|||
]) |
|||
|
|||
|
|||
# AM_DEP_TRACK |
|||
# ------------ |
|||
AC_DEFUN([AM_DEP_TRACK], |
|||
[AC_ARG_ENABLE(dependency-tracking, |
|||
[ --disable-dependency-tracking speeds up one-time build |
|||
--enable-dependency-tracking do not reject slow dependency extractors]) |
|||
if test "x$enable_dependency_tracking" != xno; then |
|||
am_depcomp="$ac_aux_dir/depcomp" |
|||
AMDEPBACKSLASH='\' |
|||
am__nodep='_no' |
|||
fi |
|||
AM_CONDITIONAL([AMDEP], [test "x$enable_dependency_tracking" != xno]) |
|||
AC_SUBST([AMDEPBACKSLASH])dnl |
|||
_AM_SUBST_NOTMAKE([AMDEPBACKSLASH])dnl |
|||
AC_SUBST([am__nodep])dnl |
|||
_AM_SUBST_NOTMAKE([am__nodep])dnl |
|||
]) |
|||
|
|||
# Generate code to set up dependency tracking. -*- Autoconf -*- |
|||
|
|||
# Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2008 |
|||
# Free Software Foundation, Inc. |
|||
# |
|||
# This file is free software; the Free Software Foundation |
|||
# gives unlimited permission to copy and/or distribute it, |
|||
# with or without modifications, as long as this notice is preserved. |
|||
|
|||
#serial 5 |
|||
|
|||
# _AM_OUTPUT_DEPENDENCY_COMMANDS |
|||
# ------------------------------ |
|||
AC_DEFUN([_AM_OUTPUT_DEPENDENCY_COMMANDS], |
|||
[{ |
|||
# Autoconf 2.62 quotes --file arguments for eval, but not when files |
|||
# are listed without --file. Let's play safe and only enable the eval |
|||
# if we detect the quoting. |
|||
case $CONFIG_FILES in |
|||
*\'*) eval set x "$CONFIG_FILES" ;; |
|||
*) set x $CONFIG_FILES ;; |
|||
esac |
|||
shift |
|||
for mf |
|||
do |
|||
# Strip MF so we end up with the name of the file. |
|||
mf=`echo "$mf" | sed -e 's/:.*$//'` |
|||
# Check whether this is an Automake generated Makefile or not. |
|||
# We used to match only the files named `Makefile.in', but |
|||
# some people rename them; so instead we look at the file content. |
|||
# Grep'ing the first line is not enough: some people post-process |
|||
# each Makefile.in and add a new line on top of each file to say so. |
|||
# Grep'ing the whole file is not good either: AIX grep has a line |
|||
# limit of 2048, but all sed's we know have understand at least 4000. |
|||
if sed -n 's,^#.*generated by automake.*,X,p' "$mf" | grep X >/dev/null 2>&1; then |
|||
dirpart=`AS_DIRNAME("$mf")` |
|||
else |
|||
continue |
|||
fi |
|||
# Extract the definition of DEPDIR, am__include, and am__quote |
|||
# from the Makefile without running `make'. |
|||
DEPDIR=`sed -n 's/^DEPDIR = //p' < "$mf"` |
|||
test -z "$DEPDIR" && continue |
|||
am__include=`sed -n 's/^am__include = //p' < "$mf"` |
|||
test -z "am__include" && continue |
|||
am__quote=`sed -n 's/^am__quote = //p' < "$mf"` |
|||
# When using ansi2knr, U may be empty or an underscore; expand it |
|||
U=`sed -n 's/^U = //p' < "$mf"` |
|||
# Find all dependency output files, they are included files with |
|||
# $(DEPDIR) in their names. We invoke sed twice because it is the |
|||
# simplest approach to changing $(DEPDIR) to its actual value in the |
|||
# expansion. |
|||
for file in `sed -n " |
|||
s/^$am__include $am__quote\(.*(DEPDIR).*\)$am__quote"'$/\1/p' <"$mf" | \ |
|||
sed -e 's/\$(DEPDIR)/'"$DEPDIR"'/g' -e 's/\$U/'"$U"'/g'`; do |
|||
# Make sure the directory exists. |
|||
test -f "$dirpart/$file" && continue |
|||
fdir=`AS_DIRNAME(["$file"])` |
|||
AS_MKDIR_P([$dirpart/$fdir]) |
|||
# echo "creating $dirpart/$file" |
|||
echo '# dummy' > "$dirpart/$file" |
|||
done |
|||
done |
|||
} |
|||
])# _AM_OUTPUT_DEPENDENCY_COMMANDS |
|||
|
|||
|
|||
# AM_OUTPUT_DEPENDENCY_COMMANDS |
|||
# ----------------------------- |
|||
# This macro should only be invoked once -- use via AC_REQUIRE. |
|||
# |
|||
# This code is only required when automatic dependency tracking |
|||
# is enabled. FIXME. This creates each `.P' file that we will |
|||
# need in order to bootstrap the dependency handling code. |
|||
AC_DEFUN([AM_OUTPUT_DEPENDENCY_COMMANDS], |
|||
[AC_CONFIG_COMMANDS([depfiles], |
|||
[test x"$AMDEP_TRUE" != x"" || _AM_OUTPUT_DEPENDENCY_COMMANDS], |
|||
[AMDEP_TRUE="$AMDEP_TRUE" ac_aux_dir="$ac_aux_dir"]) |
|||
]) |
|||
|
|||
# Copyright (C) 2003, 2005 Free Software Foundation, Inc. |
|||
# |
|||
# This file is free software; the Free Software Foundation |
|||
# gives unlimited permission to copy and/or distribute it, |
|||
# with or without modifications, as long as this notice is preserved. |
|||
|
|||
# serial 2 |
|||
|
|||
# Check whether the underlying file-system supports filenames |
|||
# with a leading dot. For instance MS-DOS doesn't. |
|||
AC_DEFUN([AM_SET_LEADING_DOT], |
|||
[rm -rf .tst 2>/dev/null |
|||
mkdir .tst 2>/dev/null |
|||
if test -d .tst; then |
|||
am__leading_dot=. |
|||
else |
|||
am__leading_dot=_ |
|||
fi |
|||
rmdir .tst 2>/dev/null |
|||
AC_SUBST([am__leading_dot])]) |
|||
|
|||
# Check to see how 'make' treats includes. -*- Autoconf -*- |
|||
|
|||
# Copyright (C) 2001, 2002, 2003, 2005, 2009 Free Software Foundation, Inc. |
|||
# |
|||
# This file is free software; the Free Software Foundation |
|||
# gives unlimited permission to copy and/or distribute it, |
|||
# with or without modifications, as long as this notice is preserved. |
|||
|
|||
# serial 4 |
|||
|
|||
# AM_MAKE_INCLUDE() |
|||
# ----------------- |
|||
# Check to see how make treats includes. |
|||
AC_DEFUN([AM_MAKE_INCLUDE], |
|||
[am_make=${MAKE-make} |
|||
cat > confinc << 'END' |
|||
am__doit: |
|||
@echo this is the am__doit target |
|||
.PHONY: am__doit |
|||
END |
|||
# If we don't find an include directive, just comment out the code. |
|||
AC_MSG_CHECKING([for style of include used by $am_make]) |
|||
am__include="#" |
|||
am__quote= |
|||
_am_result=none |
|||
# First try GNU make style include. |
|||
echo "include confinc" > confmf |
|||
# Ignore all kinds of additional output from `make'. |
|||
case `$am_make -s -f confmf 2> /dev/null` in #( |
|||
*the\ am__doit\ target*) |
|||
am__include=include |
|||
am__quote= |
|||
_am_result=GNU |
|||
;; |
|||
esac |
|||
# Now try BSD make style include. |
|||
if test "$am__include" = "#"; then |
|||
echo '.include "confinc"' > confmf |
|||
case `$am_make -s -f confmf 2> /dev/null` in #( |
|||
*the\ am__doit\ target*) |
|||
am__include=.include |
|||
am__quote="\"" |
|||
_am_result=BSD |
|||
;; |
|||
esac |
|||
fi |
|||
AC_SUBST([am__include]) |
|||
AC_SUBST([am__quote]) |
|||
AC_MSG_RESULT([$_am_result]) |
|||
rm -f confinc confmf |
|||
]) |
|||
|
|||
# Copyright (C) 2006, 2008, 2010 Free Software Foundation, Inc. |
|||
# |
|||
# This file is free software; the Free Software Foundation |
|||
# gives unlimited permission to copy and/or distribute it, |
|||
# with or without modifications, as long as this notice is preserved. |
|||
|
|||
# serial 3 |
|||
|
|||
# _AM_SUBST_NOTMAKE(VARIABLE) |
|||
# --------------------------- |
|||
# Prevent Automake from outputting VARIABLE = @VARIABLE@ in Makefile.in. |
|||
# This macro is traced by Automake. |
|||
AC_DEFUN([_AM_SUBST_NOTMAKE]) |
|||
|
|||
# AM_SUBST_NOTMAKE(VARIABLE) |
|||
# -------------------------- |
|||
# Public sister of _AM_SUBST_NOTMAKE. |
|||
AC_DEFUN([AM_SUBST_NOTMAKE], [_AM_SUBST_NOTMAKE($@)]) |
|||
|
|||
m4_include([../acinclude.m4]) |
|||
File diff suppressed because it is too large
@ -0,0 +1,81 @@ |
|||
# Makefile for libgloss/or1k |
|||
|
|||
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" |
|||
# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE |
|||
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE |
|||
# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE |
|||
# LIABLE FOR ANY 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) |
|||
# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE |
|||
# POSSIBILITY OF SUCH DAMAGE. */ |
|||
|
|||
# Process this file with autoconf to produce a configure script |
|||
|
|||
AC_PREREQ(2.59) |
|||
AC_INIT(libor1k,0.0.1) |
|||
|
|||
# No shared libraries allowed |
|||
if test "${enable_shared}" = "yes" ; then |
|||
echo "Shared libraries not supported for cross compiling, ignored" |
|||
fi |
|||
|
|||
# Where are the auxillary tools (confg.sub etc)? |
|||
if test "$srcdir" = "." ; then |
|||
if test "${with_target_subdir}" != "." ; then |
|||
libgloss_topdir="${srcdir}/${with_multisrctop}../../.." |
|||
else |
|||
libgloss_topdir="${srcdir}/${with_multisrctop}../.." |
|||
fi |
|||
else |
|||
libgloss_topdir="${srcdir}/../.." |
|||
fi |
|||
AC_CONFIG_AUX_DIR($libgloss_topdir) |
|||
|
|||
AC_CANONICAL_SYSTEM |
|||
AC_ARG_PROGRAM |
|||
|
|||
AC_PROG_INSTALL |
|||
|
|||
AC_DEFINE(HAVE_GNU_LD, 1, [Using GNU ld]) |
|||
|
|||
# We always use ELF, define various useful associated things. |
|||
AC_DEFINE(HAVE_ELF, 1, [Using ELF format]) |
|||
|
|||
# Standard stuff copied from libnosys. For this we'll need to an aclocal.m4 |
|||
LIB_AC_PROG_CC |
|||
AS=${AS-as} |
|||
AC_SUBST(AS) |
|||
AR=${AR-ar} |
|||
AC_SUBST(AR) |
|||
LD=${LD-ld} |
|||
AC_SUBST(LD) |
|||
AC_PROG_RANLIB |
|||
LIB_AM_PROG_AS |
|||
|
|||
host_makefile_frag=${srcdir}/../config/default.mh |
|||
target_makefile_frag=${srcdir}/../config/default.mt |
|||
|
|||
dnl We have to assign the same value to other variables because autoconf |
|||
dnl doesn't provide a mechanism to substitute a replacement keyword with |
|||
dnl arbitrary data or pathnames. |
|||
dnl |
|||
host_makefile_frag_path=$host_makefile_frag |
|||
AC_SUBST(host_makefile_frag_path) |
|||
AC_SUBST_FILE(host_makefile_frag) |
|||
target_makefile_frag_path=$target_makefile_frag |
|||
AC_SUBST(target_makefile_frag_path) |
|||
AC_SUBST_FILE(target_makefile_frag) |
|||
|
|||
AC_CONFIG_FILES(Makefile, |
|||
. ${libgloss_topdir}/config-ml.in, |
|||
srcdir=${srcdir} |
|||
target=${target} |
|||
with_multisubdir=${with_multisubdir} |
|||
ac_configure_args="${ac_configure_args} --enable-multilib" |
|||
CONFIG_SHELL=${CONFIG_SHELL-/bin/sh} |
|||
libgloss_topdir=${libgloss_topdir} |
|||
) |
|||
AC_OUTPUT |
|||
@ -0,0 +1,600 @@ |
|||
/* crt0.S -- startup file for OpenRISC 1000. |
|||
* |
|||
* Copyright (c) 2011, 2014 Authors |
|||
* |
|||
* Contributor Julius Baxter <juliusbaxter@gmail.com> |
|||
* Contributor Stefan Wallentowitz <stefan.wallentowitz@tum.de> |
|||
* |
|||
* 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. |
|||
*/ |
|||
|
|||
/* -------------------------------------------------------------------------- */ |
|||
/* Coding convention: |
|||
Assembly is hard to read per se, so please follow the following coding |
|||
conventions to keep it consistent and ease reading: |
|||
* internal jump labels start with L, no identation |
|||
* assemble lines have one tab identation |
|||
* attributes (.section, .global, ..) are indented with one tab |
|||
* code is structured using tabs, i.e., use 'l.sw\t0(r1),r1' with a single |
|||
tab. libgloss assumes 8 space tab width, so that might look unstructured |
|||
with tab widths below 6. Nevertheless don't use spaces or two tabs. |
|||
* no space after comma |
|||
* use the defined macros if possible as they reduce errors |
|||
* use OR1K_INST with OR1K_DELAYED(_NOP) |
|||
* OR1K_DELAYED is multiline for better readability, the inner parts are |
|||
indented with another tab. |
|||
* COMMENT! Try to accompy every line with a meaningful comment. If possible |
|||
use pseudo code to describe the code. Also mention intentions and not only |
|||
the obvious things.. */ |
|||
/* -------------------------------------------------------------------------- */ |
|||
|
|||
#include "include/or1k-asm.h" |
|||
#include "include/or1k-sprs.h" |
|||
|
|||
/* -------------------------------------------------------------------------- */ |
|||
// Stack definitions |
|||
/* -------------------------------------------------------------------------- */ |
|||
|
|||
// Stacks |
|||
// Memory layout: |
|||
// +--------------------+ <- board_mem_base+board_mem_size/exception_stack_top |
|||
// | exception stack(s) | |
|||
// +--------------------+ <- stack_top |
|||
// | stack(s) | |
|||
// +--------------------+ <- stack_bottom |
|||
// | heap | |
|||
// +--------------------+ |
|||
// | text, data, bss.. | |
|||
// +--------------------+ |
|||
|
|||
// Reserved stack size |
|||
#define STACK_SIZE 8192 |
|||
|
|||
// Reserved stack size for exceptions (can usually be smaller than normal stack) |
|||
#define EXCEPTION_STACK_SIZE 8192 |
|||
|
|||
// Size of redzone + size of space required to store state |
|||
// This value must match that in the support library or1k_exception_handler |
|||
// function |
|||
#define EXCEPTION_STACK_FRAME (128+128) |
|||
|
|||
.extern _or1k_stack_top /* points to the next address after the stack */ |
|||
.extern _or1k_stack_bottom /* points to the last address in the stack */ |
|||
.extern _or1k_exception_stack_top |
|||
.extern _or1k_exception_stack_bottom |
|||
|
|||
.section .data |
|||
.global _or1k_stack_size /* reserved stack size */ |
|||
.global _or1k_exception_stack_size |
|||
|
|||
_or1k_stack_size: .word STACK_SIZE |
|||
_or1k_exception_stack_size: .word EXCEPTION_STACK_SIZE |
|||
|
|||
#ifdef __OR1K_MULTICORE__ |
|||
.extern _or1k_stack_core |
|||
.extern _or1k_exception_stack_core |
|||
#endif |
|||
|
|||
#define SHADOW_REG(x) (OR1K_SPR_SYS_GPR_BASE + 32 + x) |
|||
|
|||
/* -------------------------------------------------------------------------- */ |
|||
/*!Macro to handle exceptions. |
|||
|
|||
Load NPC into r3, EPCR into r4 |
|||
*/ |
|||
/* -------------------------------------------------------------------------- */ |
|||
|
|||
#define GPR_BUF_OFFSET(x) (x << 2) |
|||
|
|||
#ifndef __OR1K_MULTICORE__ |
|||
#define CALL_EXCEPTION_HANDLER \ |
|||
/* store current stack pointer to address 4 */ \ |
|||
l.sw 0x4(r0),r1; \ |
|||
/* Load top of the exception stack */ \ |
|||
l.movhi r1,hi(_or1k_exception_stack_top); \ |
|||
l.ori r1,r1,lo(_or1k_exception_stack_top); \ |
|||
l.lwz r1,0(r1); \ |
|||
/* Reserve red zone and context space */ \ |
|||
l.addi r1,r1,-EXCEPTION_STACK_FRAME; \ |
|||
/* Store GPR3 in context */ \ |
|||
l.sw GPR_BUF_OFFSET(3)(r1),r3; \ |
|||
/* Load back software's stack pointer */ \ |
|||
l.lwz r3,0x4(r0); \ |
|||
/* Store this in the context */ \ |
|||
l.sw GPR_BUF_OFFSET(1)(r1),r3; \ |
|||
/* Store GPR4 in the context */ \ |
|||
l.sw GPR_BUF_OFFSET(4)(r1),r4; \ |
|||
/* Copy the current program counter as first */ \ |
|||
/* argument for the exception handler. This */ \ |
|||
/* is then used to determine the exception. */ \ |
|||
l.mfspr r3,r0,OR1K_SPR_SYS_NPC_ADDR; \ |
|||
OR1K_DELAYED( \ |
|||
/* Copy program counter of exception as */ \ |
|||
/* second argument to the exception handler */ \ |
|||
OR1K_INST(l.mfspr r4,r0,OR1K_SPR_SYS_EPCR_BASE),\ |
|||
/* Jump to exception handler. This will rfe */ \ |
|||
OR1K_INST(l.j _or1k_exception_handler) \ |
|||
) |
|||
#else |
|||
#define CALL_EXCEPTION_HANDLER \ |
|||
/* store current stack pointer to shadow reg */ \ |
|||
l.mtspr r0,r1,SHADOW_REG(1); \ |
|||
/* store current GPR3 as we need it */ \ |
|||
l.mtspr r0,r3,SHADOW_REG(2); \ |
|||
/* Load pointer to exception stack array */ \ |
|||
l.movhi r1,hi(_or1k_exception_stack_core); \ |
|||
l.ori r1,r1,lo(_or1k_exception_stack_core); \ |
|||
l.lwz r1,0(r1); \ |
|||
/* Get core id */ \ |
|||
l.mfspr r3,r0,OR1K_SPR_SYS_COREID_ADDR; \ |
|||
/* Calculate offset in array */ \ |
|||
l.slli r3,r3,2; \ |
|||
/* Load value from array to stack pointer */ \ |
|||
l.add r1,r1,r3; \ |
|||
l.lwz r1,0(r1); \ |
|||
/* Reserve red zone and context space */ \ |
|||
l.addi r1,r1,-EXCEPTION_STACK_FRAME; \ |
|||
/* Load back software's stack pointer */ \ |
|||
l.mfspr r3,r0,SHADOW_REG(1); \ |
|||
/* Store this in the context */ \ |
|||
l.sw GPR_BUF_OFFSET(1)(r1),r3; \ |
|||
/* Load back GPR3 */ \ |
|||
l.mfspr r3,r0,SHADOW_REG(2); \ |
|||
/* Store this in the context */ \ |
|||
l.sw GPR_BUF_OFFSET(3)(r1),r3; \ |
|||
/* Store GPR4 in the context */ \ |
|||
l.sw GPR_BUF_OFFSET(4)(r1),r4; \ |
|||
/* Copy the current program counter as first */ \ |
|||
/* argument for the exception handler. This */ \ |
|||
/* is then used to determine the exception. */ \ |
|||
l.mfspr r3,r0,OR1K_SPR_SYS_NPC_ADDR; \ |
|||
OR1K_DELAYED( \ |
|||
/* Copy program counter of exception as */ \ |
|||
/* second argument to the exception handler */ \ |
|||
OR1K_INST(l.mfspr r4,r0,OR1K_SPR_SYS_EPCR_BASE),\ |
|||
/* Jump to exception handler. This will rfe */ \ |
|||
OR1K_INST(l.j _or1k_exception_handler) \ |
|||
) |
|||
#endif |
|||
|
|||
/* -------------------------------------------------------------------------- */ |
|||
/*!Exception vectors */ |
|||
/* -------------------------------------------------------------------------- */ |
|||
.section .vectors,"ax" |
|||
|
|||
/* 0x100: RESET exception */ |
|||
.org 0x100 |
|||
_or1k_reset: |
|||
l.movhi r0,0 |
|||
#ifdef __OR1K_MULTICORE__ |
|||
// This is a hack that relies on the fact, that all cores start at the |
|||
// same time and they are similarily fast |
|||
l.sw 0x4(r0),r0 |
|||
// Similarly, we use address 8 to signal how many cores have exit'ed |
|||
l.sw 0x8(r0),r0 |
|||
#endif |
|||
l.movhi r1,0 |
|||
l.movhi r2,0 |
|||
l.movhi r3,0 |
|||
l.movhi r4,0 |
|||
l.movhi r5,0 |
|||
l.movhi r6,0 |
|||
l.movhi r7,0 |
|||
l.movhi r8,0 |
|||
l.movhi r9,0 |
|||
l.movhi r10,0 |
|||
l.movhi r11,0 |
|||
l.movhi r12,0 |
|||
l.movhi r13,0 |
|||
l.movhi r14,0 |
|||
l.movhi r15,0 |
|||
l.movhi r16,0 |
|||
l.movhi r17,0 |
|||
l.movhi r18,0 |
|||
l.movhi r19,0 |
|||
l.movhi r20,0 |
|||
l.movhi r21,0 |
|||
l.movhi r22,0 |
|||
l.movhi r23,0 |
|||
l.movhi r24,0 |
|||
l.movhi r25,0 |
|||
l.movhi r26,0 |
|||
l.movhi r27,0 |
|||
l.movhi r28,0 |
|||
l.movhi r29,0 |
|||
l.movhi r30,0 |
|||
l.movhi r31,0 |
|||
|
|||
/* Clear status register, set supervisor mode */ |
|||
l.ori r1,r0,OR1K_SPR_SYS_SR_SM_MASK |
|||
l.mtspr r0,r1,OR1K_SPR_SYS_SR_ADDR |
|||
/* Clear timer mode register*/ |
|||
l.mtspr r0,r0,OR1K_SPR_TICK_TTMR_ADDR |
|||
/* Jump to program initialisation code */ |
|||
LOAD_SYMBOL_2_GPR(r4, _or1k_start) |
|||
OR1K_DELAYED_NOP(OR1K_INST(l.jr r4)) |
|||
|
|||
.org 0x200 |
|||
CALL_EXCEPTION_HANDLER |
|||
|
|||
/* 0x300: Data Page Fault exception */ |
|||
.org 0x300 |
|||
CALL_EXCEPTION_HANDLER |
|||
|
|||
/* 0x400: Insn Page Fault exception */ |
|||
.org 0x400 |
|||
CALL_EXCEPTION_HANDLER |
|||
|
|||
/* 0x500: Timer exception */ |
|||
.org 0x500 |
|||
CALL_EXCEPTION_HANDLER |
|||
|
|||
/* 0x600: Aligment exception */ |
|||
.org 0x600 |
|||
CALL_EXCEPTION_HANDLER |
|||
|
|||
/* 0x700: Illegal insn exception */ |
|||
.org 0x700 |
|||
CALL_EXCEPTION_HANDLER |
|||
|
|||
/* 0x800: External interrupt exception */ |
|||
.org 0x800 |
|||
CALL_EXCEPTION_HANDLER |
|||
|
|||
/* 0x900: DTLB miss exception */ |
|||
.org 0x900 |
|||
CALL_EXCEPTION_HANDLER |
|||
|
|||
/* 0xa00: ITLB miss exception */ |
|||
.org 0xa00 |
|||
CALL_EXCEPTION_HANDLER |
|||
|
|||
/* 0xb00: Range exception */ |
|||
.org 0xb00 |
|||
CALL_EXCEPTION_HANDLER |
|||
|
|||
/* 0xc00: Syscall exception */ |
|||
.org 0xc00 |
|||
CALL_EXCEPTION_HANDLER |
|||
|
|||
/* 0xd00: Floating point exception */ |
|||
.org 0xd00 |
|||
CALL_EXCEPTION_HANDLER |
|||
|
|||
/* 0xe00: Trap exception */ |
|||
.org 0xe00 |
|||
CALL_EXCEPTION_HANDLER |
|||
|
|||
/* 0xf00: Reserved exceptions */ |
|||
.org 0xf00 |
|||
CALL_EXCEPTION_HANDLER |
|||
|
|||
.org 0x1000 |
|||
CALL_EXCEPTION_HANDLER |
|||
|
|||
.org 0x1100 |
|||
CALL_EXCEPTION_HANDLER |
|||
|
|||
.org 0x1200 |
|||
CALL_EXCEPTION_HANDLER |
|||
|
|||
.org 0x1300 |
|||
CALL_EXCEPTION_HANDLER |
|||
|
|||
.org 0x1400 |
|||
CALL_EXCEPTION_HANDLER |
|||
|
|||
.org 0x1500 |
|||
CALL_EXCEPTION_HANDLER |
|||
|
|||
.org 0x1600 |
|||
CALL_EXCEPTION_HANDLER |
|||
|
|||
.org 0x1700 |
|||
CALL_EXCEPTION_HANDLER |
|||
|
|||
.org 0x1800 |
|||
CALL_EXCEPTION_HANDLER |
|||
|
|||
.org 0x1900 |
|||
CALL_EXCEPTION_HANDLER |
|||
|
|||
.org 0x1a00 |
|||
CALL_EXCEPTION_HANDLER |
|||
|
|||
.org 0x1b00 |
|||
CALL_EXCEPTION_HANDLER |
|||
|
|||
.org 0x1c00 |
|||
CALL_EXCEPTION_HANDLER |
|||
|
|||
.org 0x1d00 |
|||
CALL_EXCEPTION_HANDLER |
|||
|
|||
.org 0x1e00 |
|||
CALL_EXCEPTION_HANDLER |
|||
|
|||
.org 0x1f00 |
|||
CALL_EXCEPTION_HANDLER |
|||
|
|||
/* Pad to the end */ |
|||
.org 0x1ffc |
|||
l.nop |
|||
|
|||
/* -------------------------------------------------------------------------- */ |
|||
/*!Main entry point |
|||
|
|||
This is the initialization code of the library. It performs these steps: |
|||
|
|||
* Call early board initialization: |
|||
Before anything happened, the board support may do some very early |
|||
initialization. This is at maximum some very basic stuff that would |
|||
otherwise prevent the following code from functioning. Other initialization |
|||
of peripherals etc. is done later (before calling main). |
|||
See the description below and README.board for details. |
|||
|
|||
* Initialize the stacks: |
|||
Two stacks are configured: The system stack is used by the software and |
|||
the exception stack is used when an exception occurs. We added this as |
|||
this should be flexible with respect to the usage of virtual memory. |
|||
|
|||
* Activate the caches: |
|||
If available the caches are initiliazed and activated. |
|||
|
|||
* Clear BSS: |
|||
The BSS are essentially the uninitialized C variables. They are set to 0 |
|||
by default. This is performed by this function. |
|||
|
|||
* Initialize the impure data structure: |
|||
Similarly, we need two library contexts, one for the normal software and |
|||
one that is used during exceptions. The impure data structure holds |
|||
the context information of the library. The called C function will setup |
|||
both data structures. There is furthermore a pointer to the currently |
|||
active impure data structure, which is initially set to the normal one. |
|||
|
|||
* Initialize or1k support library reentrant data structures |
|||
|
|||
* Initialize constructors: |
|||
Call the static and global constructors |
|||
|
|||
* Set up destructors to call from exit |
|||
The library will call the function set via atexit() during exit(). We set |
|||
it to call the _fini function which performs destruction. |
|||
|
|||
* Call board initialization: |
|||
The board initialization can perform board specific initializations such as |
|||
configuring peripherals etc. |
|||
|
|||
* Jump to main |
|||
Call main with argc = 0 and *argv[] = 0 |
|||
|
|||
* Call exit after main returns |
|||
Now we call exit() |
|||
|
|||
* Loop forever |
|||
We are dead. |
|||
*/ |
|||
|
|||
/* -------------------------------------------------------------------------- */ |
|||
.section .text |
|||
|
|||
/* Following externs from board-specific object passed at link time */ |
|||
.extern _or1k_board_mem_base |
|||
.extern _or1k_board_mem_size |
|||
.extern _or1k_board_uart_base |
|||
|
|||
/* The early board initialization may for example read the memory size and |
|||
set the mem_base and mem_size or do some preliminary board |
|||
initialization. As we do not have a stack at this time, the function may |
|||
not use the stack (and therefore be a or call a C function. But it can |
|||
safely use all registers. |
|||
|
|||
We define a default implementation, which allows board files in C. As |
|||
described above, this can only be used in assembly (board_*.S) as at |
|||
the early stage not stack is available. A board that needs early |
|||
initialization can overwrite the function with .global _board_init_early. |
|||
|
|||
Recommendation: Only use when you really need it! */ |
|||
.weak _or1k_board_init_early |
|||
_or1k_board_init_early: |
|||
OR1K_DELAYED_NOP(OR1K_INST(l.jr r9)) |
|||
|
|||
/* The board initialization is then called after the C library and UART |
|||
are initialized. It can then be used to configure UART or other |
|||
devices before the actual main function is called. */ |
|||
.extern _or1k_board_init |
|||
|
|||
.global _or1k_start |
|||
.type _or1k_start,@function |
|||
_or1k_start: |
|||
/* It is good to initialize and enable the caches before we do anything, |
|||
otherwise the cores will continuously access the bus during the wait |
|||
time for the boot barrier (0x4). |
|||
Fortunately or1k_cache_init does not need a stack */ |
|||
OR1K_DELAYED_NOP(OR1K_INST(l.jal _or1k_cache_init)) |
|||
|
|||
#ifdef __OR1K_MULTICORE__ |
|||
// All but core 0 have to wait |
|||
l.mfspr r1, r0, OR1K_SPR_SYS_COREID_ADDR |
|||
l.sfeq r1, r0 |
|||
OR1K_DELAYED_NOP(OR1K_INST(l.bf .Lcore0)) |
|||
.Lspin: |
|||
/* r1 will be used by the other cores to check for the boot variable |
|||
Check if r1 is still zero, core 0 will set it to 1 once it booted |
|||
As the cache is already turned on, this will not create traffic on |
|||
the bus, but the change is snooped by cache coherency then */ |
|||
l.lwz r1,0x4(r0) |
|||
l.sfeq r1, r0 |
|||
OR1K_DELAYED_NOP(OR1K_INST(l.bf .Lspin)) |
|||
|
|||
/* Initialize core i stack */ |
|||
// _or1k_stack_core is the array of stack pointers |
|||
LOAD_SYMBOL_2_GPR(r2,_or1k_stack_core) |
|||
// Load the base address |
|||
l.lwz r2,0(r2) |
|||
// Generate offset in array |
|||
l.mfspr r1,r0,OR1K_SPR_SYS_COREID_ADDR |
|||
l.slli r1,r1,2 |
|||
// Add to array base |
|||
l.add r2,r2,r1 |
|||
// Load pointer to the stack top and set frame pointer |
|||
l.lwz r1,0(r2) |
|||
l.or r2,r1,r1 |
|||
|
|||
// The slave cores are done, jump to main part |
|||
OR1K_DELAYED_NOP(OR1K_INST(l.j .Linit_done)); |
|||
|
|||
/* Only core 0 executes the initialization code */ |
|||
.Lcore0: |
|||
#endif |
|||
/* Call early board initialization */ |
|||
OR1K_DELAYED_NOP(OR1K_INST(l.jal _or1k_board_init_early)) |
|||
|
|||
/* Clear BSS */ |
|||
.Lclear_bss: |
|||
LOAD_SYMBOL_2_GPR(r3,__bss_start) |
|||
LOAD_SYMBOL_2_GPR(r4,end) |
|||
|
|||
.Lclear_bss_loop: |
|||
l.sw (0)(r3),r0 |
|||
l.sfltu r3,r4 |
|||
OR1K_DELAYED( |
|||
OR1K_INST(l.addi r3,r3,4), |
|||
OR1K_INST(l.bf .Lclear_bss_loop) |
|||
) |
|||
|
|||
/* Initialise stack and frame pointer (set to same value) */ |
|||
LOAD_SYMBOL_2_GPR(r1,_or1k_board_mem_base) |
|||
l.lwz r1,0(r1) |
|||
LOAD_SYMBOL_2_GPR(r2,_or1k_board_mem_size) |
|||
l.lwz r2,0(r2) |
|||
l.add r1,r1,r2 |
|||
|
|||
/* Store exception stack top address */ |
|||
LOAD_SYMBOL_2_GPR(r3,_or1k_exception_stack_top) |
|||
l.sw 0(r3),r1 |
|||
|
|||
/* Store exception stack bottom address */ |
|||
// calculate bottom address |
|||
// r3 = *exception stack size |
|||
LOAD_SYMBOL_2_GPR(r3,_or1k_exception_stack_size) |
|||
// r3 = exception stack size |
|||
l.lwz r3,0(r3) |
|||
#ifdef __OR1K_MULTICORE__ |
|||
l.mfspr r4,r0,OR1K_SPR_SYS_NUMCORES_ADDR |
|||
l.mul r3,r4,r3 |
|||
#endif |
|||
// r4 = exception stack top - exception stack size = exception stack bottom |
|||
l.sub r4,r1,r3 |
|||
// r5 = *exception stack bottom |
|||
LOAD_SYMBOL_2_GPR(r5,_or1k_exception_stack_bottom) |
|||
// store |
|||
l.sw 0(r5),r4 |
|||
|
|||
// Move stack pointer accordingly |
|||
l.or r1,r0,r4 |
|||
l.or r2,r1,r1 |
|||
|
|||
/* Store stack top address */ |
|||
LOAD_SYMBOL_2_GPR(r3,_or1k_stack_top) |
|||
l.sw 0(r3),r1 |
|||
|
|||
/* Store stack bottom address */ |
|||
// calculate bottom address |
|||
// r3 = stack size |
|||
LOAD_SYMBOL_2_GPR(r3,_or1k_stack_size) |
|||
l.lwz r3,0(r3) |
|||
#ifdef __OR1K_MULTICORE__ |
|||
l.mfspr r4, r0, OR1K_SPR_SYS_NUMCORES_ADDR |
|||
l.mul r3, r4, r3 |
|||
#endif |
|||
// r4 = stack top - stack size = stack bottom |
|||
// -> stack bottom |
|||
l.sub r4,r1,r3 |
|||
// r5 = *exception stack bottom |
|||
LOAD_SYMBOL_2_GPR(r5,_or1k_stack_bottom) |
|||
// store to variable |
|||
l.sw 0(r5),r4 |
|||
|
|||
/* Reinitialize the or1k support library */ |
|||
OR1K_DELAYED_NOP(OR1K_INST(l.jal _or1k_init)) |
|||
|
|||
/* Reinitialize the reentrancy structure */ |
|||
OR1K_DELAYED_NOP(OR1K_INST(l.jal _or1k_libc_impure_init)) |
|||
|
|||
/* Call global and static constructors */ |
|||
OR1K_DELAYED_NOP(OR1K_INST(l.jal _init)) |
|||
|
|||
/* Set up destructors to be called from exit if main ever returns */ |
|||
l.movhi r3,hi(_fini) |
|||
OR1K_DELAYED( |
|||
OR1K_INST(l.ori r3,r3,lo(_fini)), |
|||
OR1K_INST(l.jal atexit) |
|||
) |
|||
|
|||
/* Check if UART is to be initialised */ |
|||
LOAD_SYMBOL_2_GPR(r4,_or1k_board_uart_base) |
|||
l.lwz r4,0(r4) |
|||
/* Is base set? If not, no UART */ |
|||
l.sfne r4,r0 |
|||
l.bnf .Lskip_uart |
|||
l.or r3,r0,r0 |
|||
OR1K_DELAYED_NOP(OR1K_INST(l.jal _or1k_uart_init)) |
|||
|
|||
.Lskip_uart: |
|||
/* Board initialization */ |
|||
OR1K_DELAYED_NOP(OR1K_INST(l.jal _or1k_board_init)) |
|||
|
|||
#ifdef __OR1K_MULTICORE__ |
|||
// Start other cores |
|||
l.ori r3, r0, 1 |
|||
l.sw 0x4(r0), r3 |
|||
#endif |
|||
|
|||
.Linit_done: |
|||
/* Jump to main program entry point (argc = argv = envp = 0) */ |
|||
l.or r3,r0,r0 |
|||
l.or r4,r0,r0 |
|||
OR1K_DELAYED( |
|||
OR1K_INST(l.or r5,r0,r0), |
|||
OR1K_INST(l.jal main) |
|||
) |
|||
|
|||
#ifdef __OR1K_MULTICORE__ |
|||
.incrementexit: |
|||
/* Atomically increment number of finished cores */ |
|||
l.lwa r3,0x8(r0) |
|||
l.addi r3,r3,1 |
|||
l.swa 0x8(r0),r3 |
|||
OR1K_DELAYED_NOP(OR1K_INST(l.bnf .incrementexit)); |
|||
/* Compare to number of cores in this cluster */ |
|||
l.mfspr r4,r0, OR1K_SPR_SYS_NUMCORES_ADDR |
|||
/* Compare to number of finished tasks */ |
|||
l.sfeq r3,r4 |
|||
/* Last core needs to desctruct library etc. */ |
|||
OR1K_DELAYED_NOP(OR1K_INST(l.bf .exitcorelast)); |
|||
OR1K_DELAYED( |
|||
OR1K_INST(l.addi r3,r11,0), |
|||
OR1K_INST(l.jal _exit) |
|||
) |
|||
.exitcorelast: |
|||
#endif |
|||
/* If program exits, call exit routine */ |
|||
OR1K_DELAYED( |
|||
OR1K_INST(l.addi r3,r11,0), |
|||
OR1K_INST(l.jal exit) |
|||
) |
|||
|
|||
/* Loop forever */ |
|||
.Lloop_forever: |
|||
OR1K_DELAYED_NOP(OR1K_INST(l.j .Lloop_forever)) |
|||
|
|||
.size _or1k_start,.-_or1k_start |
|||
@ -0,0 +1,83 @@ |
|||
/* or1k-asm.h -- OR1K assembly helper macros
|
|||
|
|||
Copyright (c) 2014 OpenRISC Project Maintainers |
|||
Copyright (C) 2012-2014 Peter Gavin <pgavin@gmail.com> |
|||
All rights reserved. |
|||
|
|||
Redistribution and use in source and binary forms, with or without |
|||
modification, are permitted provided that the following condition |
|||
is met: |
|||
|
|||
1. Redistributions of source code must retain the above copyright |
|||
notice, this list of conditions and the following disclaimer. |
|||
|
|||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS |
|||
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT |
|||
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS |
|||
FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE |
|||
COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY 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) |
|||
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED |
|||
OF THE POSSIBILITY OF SUCH DAMAGE. |
|||
|
|||
*/ |
|||
|
|||
#ifndef OR1K_ASM_H |
|||
#define OR1K_ASM_H |
|||
|
|||
/* The purpose of the OR1K_INST macro is simply to protect the commas
|
|||
embedded within an instruction from the C preprocessor. An entire |
|||
instruction can be safely embedded within its arguments, including |
|||
an arbitrary number of commas, and it will be reproduced |
|||
exactly. */ |
|||
#define OR1K_INST(...) __VA_ARGS__ |
|||
|
|||
/* OR1K_DELAYED takes two arguments which must be instructions. They
|
|||
should be wrapped in OR1K_INST if the instructions require commas. |
|||
The second argument should be a jump or branch instruction. If we |
|||
are assembling the code in delay-slot mode (e.g., for the standard |
|||
OR1K) the first instruction will be emitted in the delay slot of |
|||
the second instruction. In no-delay-slot mode they will be emitted |
|||
in order. If we are using compat-delay mode, they will be emitted |
|||
in order, but an l.nop instruction will be emitted immediately |
|||
after. */ |
|||
|
|||
/* OR1K_DELAYED_NOP takes a single argument, which should be a
|
|||
branch/jump instruction. In delay-slot or compat-delay modes, the |
|||
instruction will be emitted with an l.nop in its delay slot. In |
|||
no-delay mode, the instruction will be emitted by itself. */ |
|||
|
|||
#if defined(__OR1K_NODELAY__) |
|||
|
|||
#define OR1K_DELAYED(a, b) a; b |
|||
#define OR1K_DELAYED_NOP(a) a |
|||
|
|||
/* Go ahead and emit the .nodelay directive when in no-delay mode, so
|
|||
that the flags are appropriately set in the binary. */ |
|||
.nodelay |
|||
|
|||
#elif defined(__OR1K_DELAY__) |
|||
|
|||
#define OR1K_DELAYED(a, b) b; a |
|||
#define OR1K_DELAYED_NOP(a) a; l.nop |
|||
|
|||
#elif defined(__OR1K_DELAY_COMPAT__) |
|||
|
|||
#define OR1K_DELAYED(a, b) a; b; l.nop |
|||
#define OR1K_DELAYED_NOP(a) a; l.nop |
|||
|
|||
#else |
|||
|
|||
#error One of __OR1K_NODELAY__, __OR1K_DELAY__, or __OR1K_DELAY_COMPAT__ must be defined |
|||
|
|||
#endif |
|||
|
|||
#define LOAD_SYMBOL_2_GPR(gpr,symbol) \ |
|||
.global symbol ; \ |
|||
l.movhi gpr, hi(symbol) ; \ |
|||
l.ori gpr, gpr, lo(symbol) |
|||
#endif |
|||
Loading…
Reference in new issue