2011-12-15 Konrad Eisele <konrad@gaisler.com>

* configure.in: Add SPARC LEON support.
        * configure: Regenerated.
        * sparc_leon/asm-leon/amba.h, sparc_leon/asm-leon/asmmacro.h,
        sparc_leon/asm-leon/clock.h, sparc_leon/asm-leon/contextswitch.h,
        sparc_leon/asm-leon/elfmacro.h, sparc_leon/asm-leon/head.h,
        sparc_leon/asm-leon/irq.h, sparc_leon/asm-leon/jiffies.h,
        sparc_leon/asm-leon/lambapp.h, sparc_leon/asm-leon/lambapp_devs.h,
        sparc_leon/asm-leon/leon.h, sparc_leon/asm-leon/leon3.h,
        sparc_leon/asm-leon/leonbare_debug.h, sparc_leon/asm-leon/leonbare_kernel.h,
        sparc_leon/asm-leon/leonbare_kernel_queue.h, sparc_leon/asm-leon/leoncompat.h,
        sparc_leon/asm-leon/leondbg.h, sparc_leon/asm-leon/leonstack.h,
        sparc_leon/asm-leon/liblocks.h, sparc_leon/asm-leon/linkage.h,
        sparc_leon/asm-leon/param.h, sparc_leon/asm-leon/queue.h,
        sparc_leon/asm-leon/spinlock.h, sparc_leon/asm-leon/stack.h,
        sparc_leon/asm-leon/time.h, sparc_leon/asm-leon/timer.h,
        sparc_leon/asm-leon/types.h, sparc_leon/asm-leon/winmacros.h:
        New file.
        * sparc_leon/Makefile.in, sparc_leon/_exit.c,
        sparc_leon/amba.c, sparc_leon/amba_dbg.c,
        sparc_leon/amba_driver.c, sparc_leon/amba_scan.c,
        sparc_leon/asm-leon, sparc_leon/bdinit.S,
        sparc_leon/busscan.S, sparc_leon/cacheA.S,
        sparc_leon/catch_interrupt.c, sparc_leon/catch_interrupt_mvt.c,
        sparc_leon/catch_interrupt_pending.c, sparc_leon/catch_interrupt_svt.c,
        sparc_leon/configure.in,
        sparc_leon/console.c, sparc_leon/console_dbg.c,
        sparc_leon/console_init.c, sparc_leon/contextswitch.c,
        sparc_leon/contextswitch_asm.S, sparc_leon/crt0.S,
        sparc_leon/crti.S, sparc_leon/crtn.S,
        sparc_leon/etrap.S, sparc_leon/etrap_fast.S,
        sparc_leon/fpu.S, sparc_leon/gettimeofday.c,
        sparc_leon/initcalls.c, sparc_leon/io.c,
        sparc_leon/irqinstall.S, sparc_leon/irqtrap.S,
        sparc_leon/irqtrap_fast.S, sparc_leon/jiffies.c,
        sparc_leon/kernel.c, sparc_leon/kernel_context.S,
        sparc_leon/kernel_debug.c, sparc_leon/kernel_debug_var.c,
        sparc_leon/kernel_mm.c, sparc_leon/kernel_mutex.c,
        sparc_leon/kernel_queue.c, sparc_leon/kernel_sched.c,
        sparc_leon/kernel_thread.c, sparc_leon/lcpuinit.S,
        sparc_leon/locore.S, sparc_leon/locore_atexit.c,
        sparc_leon/locore_clean.S, sparc_leon/locore_mvt.S,
        sparc_leon/locore_mvt_reset.S, sparc_leon/locore_svt.S,
        sparc_leon/locore_svt_reset.S, sparc_leon/locore_svtdisp.S,
        sparc_leon/locore_var.S, sparc_leon/locore_var_svt.S,
        sparc_leon/mmu_asm.S, sparc_leon/mutex.c,
        sparc_leon/nocache.S, sparc_leon/pnpinit.c,
        sparc_leon/pnpinit_malloc.c, sparc_leon/pnpinit_simple.c,
        sparc_leon/regwin.S, sparc_leon/regwin_patch.c,
        sparc_leon/regwin_slow.S, sparc_leon/regwinflush.S,
        sparc_leon/rtc.c, sparc_leon/rtrap.S,
        sparc_leon/rtrap_fast.S, sparc_leon/stop.S,
        sparc_leon/timer.c, sparc_leon/times.c:
        New file
        * sparc_leon/configure: Regenerate
This commit is contained in:
Jeff Johnston 2011-12-15 22:58:40 +00:00
parent e74758408e
commit 8e0346d137
101 changed files with 17261 additions and 1046 deletions

View File

@ -1,3 +1,60 @@
2011-12-15 Konrad Eisele <konrad@gaisler.com>
* configure.in: Add SPARC LEON support.
* configure: Regenerated.
* sparc_leon/asm-leon/amba.h, sparc_leon/asm-leon/asmmacro.h,
sparc_leon/asm-leon/clock.h, sparc_leon/asm-leon/contextswitch.h,
sparc_leon/asm-leon/elfmacro.h, sparc_leon/asm-leon/head.h,
sparc_leon/asm-leon/irq.h, sparc_leon/asm-leon/jiffies.h,
sparc_leon/asm-leon/lambapp.h, sparc_leon/asm-leon/lambapp_devs.h,
sparc_leon/asm-leon/leon.h, sparc_leon/asm-leon/leon3.h,
sparc_leon/asm-leon/leonbare_debug.h, sparc_leon/asm-leon/leonbare_kernel.h,
sparc_leon/asm-leon/leonbare_kernel_queue.h, sparc_leon/asm-leon/leoncompat.h,
sparc_leon/asm-leon/leondbg.h, sparc_leon/asm-leon/leonstack.h,
sparc_leon/asm-leon/liblocks.h, sparc_leon/asm-leon/linkage.h,
sparc_leon/asm-leon/param.h, sparc_leon/asm-leon/queue.h,
sparc_leon/asm-leon/spinlock.h, sparc_leon/asm-leon/stack.h,
sparc_leon/asm-leon/time.h, sparc_leon/asm-leon/timer.h,
sparc_leon/asm-leon/types.h, sparc_leon/asm-leon/winmacros.h:
New file.
* sparc_leon/Makefile.in, sparc_leon/_exit.c,
sparc_leon/amba.c, sparc_leon/amba_dbg.c,
sparc_leon/amba_driver.c, sparc_leon/amba_scan.c,
sparc_leon/asm-leon, sparc_leon/bdinit.S,
sparc_leon/busscan.S, sparc_leon/cacheA.S,
sparc_leon/catch_interrupt.c, sparc_leon/catch_interrupt_mvt.c,
sparc_leon/catch_interrupt_pending.c, sparc_leon/catch_interrupt_svt.c,
sparc_leon/configure.in,
sparc_leon/console.c, sparc_leon/console_dbg.c,
sparc_leon/console_init.c, sparc_leon/contextswitch.c,
sparc_leon/contextswitch_asm.S, sparc_leon/crt0.S,
sparc_leon/crti.S, sparc_leon/crtn.S,
sparc_leon/etrap.S, sparc_leon/etrap_fast.S,
sparc_leon/fpu.S, sparc_leon/gettimeofday.c,
sparc_leon/initcalls.c, sparc_leon/io.c,
sparc_leon/irqinstall.S, sparc_leon/irqtrap.S,
sparc_leon/irqtrap_fast.S, sparc_leon/jiffies.c,
sparc_leon/kernel.c, sparc_leon/kernel_context.S,
sparc_leon/kernel_debug.c, sparc_leon/kernel_debug_var.c,
sparc_leon/kernel_mm.c, sparc_leon/kernel_mutex.c,
sparc_leon/kernel_queue.c, sparc_leon/kernel_sched.c,
sparc_leon/kernel_thread.c, sparc_leon/lcpuinit.S,
sparc_leon/locore.S, sparc_leon/locore_atexit.c,
sparc_leon/locore_clean.S, sparc_leon/locore_mvt.S,
sparc_leon/locore_mvt_reset.S, sparc_leon/locore_svt.S,
sparc_leon/locore_svt_reset.S, sparc_leon/locore_svtdisp.S,
sparc_leon/locore_var.S, sparc_leon/locore_var_svt.S,
sparc_leon/mmu_asm.S, sparc_leon/mutex.c,
sparc_leon/nocache.S, sparc_leon/pnpinit.c,
sparc_leon/pnpinit_malloc.c, sparc_leon/pnpinit_simple.c,
sparc_leon/regwin.S, sparc_leon/regwin_patch.c,
sparc_leon/regwin_slow.S, sparc_leon/regwinflush.S,
sparc_leon/rtc.c, sparc_leon/rtrap.S,
sparc_leon/rtrap_fast.S, sparc_leon/stop.S,
sparc_leon/timer.c, sparc_leon/times.c:
New file
* sparc_leon/configure: Regenerate
2011-12-13 Richard Earnshaw <rearnsha@arm.com>
Thomas Klein <th.r.klein@web.de>

1936
libgloss/configure vendored

File diff suppressed because it is too large Load Diff

View File

@ -52,6 +52,9 @@ case "${target}" in
i960-*-coff)
AC_CONFIG_SUBDIRS([i960])
;;
sparc-*leon*-elf* | sparc-*leon*-none*)
AC_CONFIG_SUBDIRS([sparc_leon])
;;
sparclet-*-aout* | sparc-*-elf* | sparc64-*-elf* | sparc86x-*-* | sparclite-*-*)
AC_CONFIG_SUBDIRS([sparc])
;;

View File

@ -0,0 +1,161 @@
# Makefile for libgloss/sparc_leon. This is the board support
# code for the various sparc leon targets.
DESTDIR =
VPATH = @srcdir@
srcdir = @srcdir@
objdir = .
srcroot = $(srcdir)/../..
objroot = $(objdir)/../..
prefix = @prefix@
exec_prefix = @exec_prefix@
host_alias = @host_alias@
target_alias = @target_alias@
bindir = @bindir@
libdir = @libdir@
tooldir = $(exec_prefix)/$(target_alias)
mkinstalldirs = $(SHELL) $(srcroot)/mkinstalldirs
# 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@
AR_FLAGS = qrv
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`
LEON_BSP = libleonbare.a
LEON_OBJS = etrap.o rtrap.o etrap_fast.o rtrap_fast.o irqinstall.o regwin.o \
regwinflush.o fpu.o bdinit.o contextswitch.o \
busscan.o irqtrap_fast.o catch_interrupt.o catch_interrupt_svt.o \
catch_interrupt_mvt.o catch_interrupt_pending.o gettimeofday.o \
times.o rtc.o lcpuinit.o console_init.o console.o console_dbg.o \
contextswitch.o contextswitch_asm.o _exit.o amba.o amba_dbg.o \
amba_scan.o amba_driver.o timer.o mutex.o locore.o locore_clean.o \
locore_var.o locore_var_svt.o jiffies.o \
mmu_asm.o locore_svtdisp.o locore_mvt_reset.o locore_svt_reset.o stop.o initcalls.o \
regwin_patch.o cacheA.o nocache.o
LEONBARE_THREADS = liblbthread.a
LEONBARE_THREADS_OBJS = kernel.o kernel_debug.o kernel_debug_var.o kernel_context.o \
kernel_mutex.o kernel_thread.o kernel_sched.o kernel_queue.o \
kernel_mm.o
LOCOREATEXIT = locore_atexit.o
LEON_SMALLC = libsmall.a
PNP=pnpinit.o
PNP_S=pnpinit_simple.o
LEON_ALL = $(LEON_BSP) $(LEON_SMALLC) $(LEONBARE_THREADS) $(PNP) $(PNP_S) crti.o crtn.o
LOCORESVT = locore_svt.o
LOCOREMVT = locore_mvt.o
CRT0 = crt0.o
OBJS = close.o fstat.o getpid.o isatty.o kill.o \
lseek.o open.o print.o putnum.o read.o sbrk.o stat.o \
unlink.o write.o io.o kernel.o kernel_debug.o kernel_debug_var.o kernel_context.o
#link.o
#### Host specific Makefile fragment comes in here.
@host_makefile_frag@
all: stmp-targ-include $(CRT0) $(LOCOREMVT) $(LOCORESVT) $(LEON_ALL)
$(CRT0): $(srcdir)/crt0.S
$(CC) $(CFLAGS_FOR_TARGET) $(CFLAGS) $(INCLUDES) -o $@ -c $(srcdir)/crt0.S
$(LEON_BSP): $(OBJS) $(LEON_OBJS)
@rm -f $@
${AR} ${AR_FLAGS} $@ $(OBJS) $(LEON_OBJS)
${RANLIB} $@
$(LEON_SMALLC): $(LOCOREATEXIT)
@rm -f $@
${AR} ${AR_FLAGS} $@ $(LOCOREATEXIT)
${RANLIB} $@
$(LEONBARE_THREADS): $(LEONBARE_THREADS_OBJS)
@rm -f $@
${AR} ${AR_FLAGS} $@ $(LEONBARE_THREADS_OBJS)
${RANLIB} $@
install:
$(INSTALL_DATA) $(CRT0) $(DESTDIR)$(tooldir)/lib${MULTISUBDIR}/$(CRT0)
$(INSTALL_DATA) $(LOCORESVT) $(DESTDIR)$(tooldir)/lib${MULTISUBDIR}/$(LOCORESVT)
$(INSTALL_DATA) $(LOCOREMVT) $(DESTDIR)$(tooldir)/lib${MULTISUBDIR}/$(LOCOREMVT)
$(INSTALL_DATA) $(PNP) $(DESTDIR)$(tooldir)/lib${MULTISUBDIR}/$(PNP)
$(INSTALL_DATA) $(PNP_S) $(DESTDIR)$(tooldir)/lib${MULTISUBDIR}/$(PNP_S)
$(INSTALL_DATA) $(LEON_BSP) $(DESTDIR)$(tooldir)/lib${MULTISUBDIR}/$(LEON_BSP)
$(INSTALL_DATA) $(LEON_SMALLC) $(DESTDIR)$(tooldir)/lib${MULTISUBDIR}/$(LEON_SMALLC)
$(INSTALL_DATA) $(LEONBARE_THREADS) $(DESTDIR)$(tooldir)/lib${MULTISUBDIR}/$(LEONBARE_THREADS)
if [ -z "$(MULTISUBDIR)" ]; then \
$(mkinstalldirs) $(DESTDIR)$(tooldir)/include/asm-leon; \
for i in $(srcdir)/asm-leon/*.h; do \
if [ -f $$i ]; then \
$(INSTALL_DATA) $$i $(DESTDIR)$(tooldir)/include/asm-leon/`basename $$i` || exit $$?; \
else true; fi ; \
done; \
else true; fi
stmp-targ-include: $(srcdir)/asm-leon/*
if [ -d ${objroot}/newlib/targ-include/asm-leon ]; then \
rm -rf ${objroot}/newlib/targ-include/asm-leon; \
else true; fi ; \
if [ -d ${objroot}/newlib/targ-include ]; then \
cp -r $(srcdir)/asm-leon ${objroot}/newlib/targ-include/asm-leon; \
else true; fi ; \
touch $@
all-recursive: stmp-targ-include
# Make a simple test case to test the linker script, startup code, and
# I/O code
#
test:
@echo Done...
# target specific makefile fragment comes in here.
# @target_makefile_frag@
clean mostlyclean:
rm -f *.o *.a *.map *.x
distclean maintainer-clean realclean: clean
rm -f Makefile config.cache config.log config.status
.PHONY: info dvi doc install-info clean-info
info doc dvi:
install-info:
clean-info:
# target specific makefile fragment comes in here.
@target_makefile_frag@
Makefile: Makefile.in config.status @host_makefile_frag_path@ @target_makefile_frag_path@
$(SHELL) config.status
config.status: configure
$(SHELL) config.status --recheck

View File

@ -0,0 +1,30 @@
/*
* Copyright (c) 2011 Aeroflex Gaisler
*
* BSD license:
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
void
_exit (int status)
{
asm ("mov 1, %g1; ta 0;\n");
}

404
libgloss/sparc_leon/aclocal.m4 vendored Normal file
View File

@ -0,0 +1,404 @@
# generated automatically by aclocal 1.11.1 -*- Autoconf -*-
# Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004,
# 2005, 2006, 2007, 2008, 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.
# 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
# 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 10
# 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'.
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
;;
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='\'
fi
AM_CONDITIONAL([AMDEP], [test "x$enable_dependency_tracking" != xno])
AC_SUBST([AMDEPBACKSLASH])dnl
_AM_SUBST_NOTMAKE([AMDEPBACKSLASH])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 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
# _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])

152
libgloss/sparc_leon/amba.c Normal file
View File

@ -0,0 +1,152 @@
/*
* Copyright (c) 2011 Aeroflex Gaisler
*
* BSD license:
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
#include <asm-leon/leon.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
/*#define DEBUG_CONFIG*/
/* Structure containing address to devices found on the Amba Plug&Play bus */
amba_confarea_type amba_conf;
/* Pointers to Interrupt Controller configuration registers */
volatile LEON3_IrqCtrl_Regs_Map *LEON3_IrqCtrl_Regs = 0;
volatile LEON3_GpTimer_Regs_Map *LEON3_GpTimer_Regs = 0;
unsigned long LEON3_GpTimer_Irq = 0;
unsigned long
amba_find_apbslv_addr (unsigned long vendor, unsigned long device,
unsigned long *irq)
{
unsigned int i, conf, iobar;
for (i = 0; i < amba_conf.apbslv.devnr; i++)
{
conf = amba_get_confword (amba_conf.apbslv, i, 0);
if ((amba_vendor (conf) == vendor) && (amba_device (conf) == device))
{
if (irq)
{
*irq = amba_irq (conf);
}
iobar = amba_apb_get_membar (amba_conf.apbslv, i);
return amba_iobar_start (amba_conf.apbslv.apbmst[i], iobar);
}
}
return 0;
}
#define amba_insert_device(tab, address) do { \
if (LEON3_BYPASS_LOAD_PA(address)) { \
(tab)->addr[(tab)->devnr] = (address); \
(tab)->devnr ++; \
} \
} while(0)
#define amba_insert_apb_device(tab, address, apbmst, idx) do { \
if (*(address)) { \
(tab)->addr[(tab)->devnr] = (address); \
(tab)->apbmst[(tab)->devnr] = (apbmst); \
(tab)->apbmstidx[(tab)->devnr] = (idx); \
(tab)->devnr ++; \
} \
} while(0)
/*
* Used to scan system bus. Probes for AHB masters, AHB slaves and
* APB slaves. Addresses to configuration areas of the AHB masters,
* AHB slaves, APB slaves and APB master are storeds in
* amba_ahb_masters, amba_ahb_slaves and amba.
*/
int amba_init_done = 0;
void
amba_init (void)
{
unsigned int *cfg_area; /* address to configuration area */
unsigned int mbar, conf, apbmst;
int i, j, idx = 0;
if (amba_init_done)
{
return;
}
amba_init_done = 1;
memset (&amba_conf, 0, sizeof (amba_conf));
/*amba_conf.ahbmst.devnr = 0; amba_conf.ahbslv.devnr = 0; amba_conf.apbslv.devnr = 0; */
cfg_area = (unsigned int *) (LEON3_IO_AREA | LEON3_CONF_AREA);
for (i = 0; i < LEON3_AHB_MASTERS; i++)
{
amba_insert_device (&amba_conf.ahbmst, cfg_area);
cfg_area += LEON3_AHB_CONF_WORDS;
}
cfg_area =
(unsigned int *) (LEON3_IO_AREA | LEON3_CONF_AREA |
LEON3_AHB_SLAVE_CONF_AREA);
for (i = 0; i < LEON3_AHB_SLAVES; i++)
{
amba_insert_device (&amba_conf.ahbslv, cfg_area);
cfg_area += LEON3_AHB_CONF_WORDS;
}
for (i = 0; i < amba_conf.ahbslv.devnr; i++)
{
conf = amba_get_confword (amba_conf.ahbslv, i, 0);
mbar = amba_ahb_get_membar (amba_conf.ahbslv, i, 0);
if ((amba_vendor (conf) == VENDOR_GAISLER)
&& (amba_device (conf) == GAISLER_APBMST))
{
int k;
/*amba_conf.apbmst = */ apbmst = amba_membar_start (mbar);
cfg_area = (unsigned int *) (apbmst | LEON3_CONF_AREA);
for (j = amba_conf.apbslv.devnr, k = 0;
j < AMBA_MAXAPB_DEVS && k < AMBA_MAXAPB_DEVS_PERBUS; j++, k++)
{
amba_insert_apb_device (&amba_conf.apbslv, cfg_area, apbmst,
idx);
cfg_area += LEON3_APB_CONF_WORDS;
}
idx++;
}
}
/* Find LEON3 Interrupt controler */
LEON3_IrqCtrl_Regs = (volatile LEON3_IrqCtrl_Regs_Map *)
amba_find_apbslv_addr (VENDOR_GAISLER, GAISLER_IRQMP, 0);
LEON3_GpTimer_Regs = (volatile LEON3_GpTimer_Regs_Map *)
amba_find_apbslv_addr (VENDOR_GAISLER, GAISLER_GPTIMER,
&LEON3_GpTimer_Irq);
if (LEON3_IrqCtrl_Regs)
{
LEON3_BYPASS_STORE_PA (&(LEON3_IrqCtrl_Regs->mask[0]), 0);
}
}

View File

@ -0,0 +1,147 @@
/*
* Copyright (c) 2011 Aeroflex Gaisler
*
* BSD license:
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
#include <asm-leon/leon.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
/*#define DEBUG_CONFIG*/
/* Structure containing address to devices found on the Amba Plug&Play bus */
extern amba_confarea_type amba_conf;
#ifdef DEBUG_CONFIG
#define printk(fmt,arg...) \
{ char c[1024]; \
sprintf(c,fmt,##arg); \
DEBUG_puts(c); \
}
#else
#define printk(fmt,arg...)
#endif
static void
vendor_dev_string (unsigned long conf, char *vendorbuf, char *devbuf)
{
int vendor = amba_vendor (conf);
int dev = amba_device (conf);
char *devstr;
char *vendorstr;
#ifdef DEBUG_CONFIG
sprintf (vendorbuf, "Unknown vendor %2x", vendor);
sprintf (devbuf, "Unknown device %2x", dev);
vendorstr = vendor_id2str (vendor);
if (vendorstr)
{
sprintf (vendorbuf, "%s", vendorstr);
}
devstr = device_id2str (vendor, dev);
if (devstr)
{
sprintf (devbuf, "%s", devstr);
}
#else
vendorbuf[0] = 0;
devbuf[0] = 0;
#endif
}
void
amba_prinf_config (void)
{
char devbuf[128];
char vendorbuf[128];
unsigned int conf;
int i = 0;
int j = 0;
unsigned int addr;
unsigned int m;
printk (" Vendors Slaves\n");
printk ("Ahb masters:\n");
i = 0;
while (i < amba_conf.ahbmst.devnr)
{
conf = amba_get_confword (amba_conf.ahbmst, i, 0);
vendor_dev_string (conf, vendorbuf, devbuf);
printk ("%2i(%2x:%3x|%2i): %16s %16s \n", i, amba_vendor (conf),
amba_device (conf), amba_irq (conf), vendorbuf, devbuf);
for (j = 0; j < 4; j++)
{
m = amba_ahb_get_membar (amba_conf.ahbmst, i, j);
if (m)
{
addr = amba_membar_start (m);
printk (" +%i: 0x%x \n", j, addr);
}
}
i++;
}
printk ("Ahb slaves:\n");
i = 0;
while (i < amba_conf.ahbslv.devnr)
{
conf = amba_get_confword (amba_conf.ahbslv, i, 0);
vendor_dev_string (conf, vendorbuf, devbuf);
printk ("%2i(%2x:%3x|%2i): %16s %16s \n", i, amba_vendor (conf),
amba_device (conf), amba_irq (conf), vendorbuf, devbuf);
for (j = 0; j < 4; j++)
{
m = amba_ahb_get_membar (amba_conf.ahbslv, i, j);
if (m)
{
addr = amba_membar_start (m);
if (amba_membar_type (m) == AMBA_TYPE_AHBIO)
{
addr = AMBA_TYPE_AHBIO_ADDR (addr);
}
else if (amba_membar_type (m) == AMBA_TYPE_APBIO)
{
printk ("Warning: apbio membar\n");
}
printk (" +%i: 0x%x (raw:0x%x)\n", j, addr, m);
}
}
i++;
}
printk ("Apb slaves:\n");
i = 0;
while (i < amba_conf.apbslv.devnr)
{
conf = amba_get_confword (amba_conf.apbslv, i, 0);
vendor_dev_string (conf, vendorbuf, devbuf);
printk ("%2i(%2x:%3x|%2i): %16s %16s \n", i, amba_vendor (conf),
amba_device (conf), amba_irq (conf), vendorbuf, devbuf);
m = amba_apb_get_membar (amba_conf.apbslv, i);
addr = amba_iobar_start (amba_conf.apbslv.apbmst[i], m);
printk (" +%2i: 0x%x (raw:0x%x) \n", 0, addr, m);
i++;
}
}

View File

@ -0,0 +1,119 @@
/*
* Copyright (c) 2011 Aeroflex Gaisler
*
* BSD license:
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
#include <asm-leon/leon.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
/*#define DEBUG_CONFIG*/
/* Structure containing address to devices found on the Amba Plug&Play bus */
extern amba_confarea_type amba_conf;
/*collect apb slaves*/
int
amba_get_free_apbslv_devices (int vendor, int device, amba_apb_device * dev,
int nr)
{
unsigned int i, conf, iobar, j = 0;
#ifdef DEBUG_CONFIG
printf ("Apbslv: search for apdslv devices\n");
#endif
for (i = 0; i < amba_conf.apbslv.devnr && j < nr; i++)
{
conf = amba_get_confword (amba_conf.apbslv, i, 0);
#ifdef DEBUG_CONFIG
printf ("Apbslv: check(%x:%x)==(%x:%x)\n", vendor, device,
amba_vendor (conf), amba_device (conf));
#endif
if ((amba_vendor (conf) == vendor) && (amba_device (conf) == device))
{
if (!(amba_conf.apbslv.allocbits[i / 32] & (1 << (i & (32 - 1)))))
{
#ifdef DEBUG_CONFIG
printf ("Apbslv: alloc device idx %i (%x:%x)\n",
j, vendor, device);
#endif
amba_conf.apbslv.allocbits[i / 32] |= (1 << (i & (32 - 1)));
dev[j].irq = amba_irq (conf);
iobar = amba_apb_get_membar (amba_conf.apbslv, i);
dev[j].start =
amba_iobar_start (amba_conf.apbslv.apbmst[i], iobar);
#ifdef DEBUG_CONFIG
printf (" +bar: 0x%x \n", k, dev[j].start);
#endif
j++;
}
}
}
return j;
}
/*collect ahb slaves*/
int
amba_get_free_ahbslv_devices (int vendor, int device, amba_ahb_device * dev,
int nr)
{
unsigned int addr, i, conf, iobar, j = 0, k;
#ifdef DEBUG_CONFIG
printf ("Ahbslv: search for ahdslv devices\n");
#endif
for (i = 0; i < amba_conf.ahbslv.devnr && j < nr; i++)
{
conf = amba_get_confword (amba_conf.ahbslv, i, 0);
#ifdef DEBUG_CONFIG
printf ("Ahbslv: check(%x:%x)==(%x:%x)\n", vendor, device,
amba_vendor (conf), amba_device (conf));
#endif
if ((amba_vendor (conf) == vendor) && (amba_device (conf) == device))
{
if (!(amba_conf.ahbslv.allocbits[i / 32] & (1 << (i & (32 - 1)))))
{
#ifdef DEBUG_CONFIG
printf ("Ahbslv: alloc device idx %i (%x:%x)\n",
j, vendor, device);
#endif
amba_conf.ahbslv.allocbits[i / 32] |= (1 << (i & (32 - 1)));
dev[j].irq = amba_irq (conf);
for (k = 0; k < 4; k++)
{
iobar = amba_ahb_get_membar (amba_conf.ahbslv, i, k);
addr = amba_membar_start (iobar);
if (amba_membar_type (iobar) == AMBA_TYPE_AHBIO)
{
addr = AMBA_TYPE_AHBIO_ADDR (addr);
}
dev[j].start[k] = addr;
#ifdef DEBUG_CONFIG
printf (" +%i: 0x%x \n", k, dev[j].start[k]);
#endif
}
j++;
}
}
}
return j;
}

View File

@ -0,0 +1,96 @@
/*
* Copyright (c) 2011 Aeroflex Gaisler
*
* BSD license:
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
#include <asm-leon/leon.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
unsigned int
leon3_ahbslv_scan (register unsigned int vendor, register unsigned int driver)
{
register unsigned int conf, i, *confp;
register unsigned int cfg_area =
(unsigned int) (LEON3_IO_AREA | LEON3_CONF_AREA |
LEON3_AHB_SLAVE_CONF_AREA);
for (i = 0; i < LEON3_AHB_SLAVES; i++)
{
confp = (unsigned int *) (cfg_area + (i * LEON3_AHB_CONF_WORDS * 4));
conf = *confp;
if ((amba_vendor (conf) == vendor) && (amba_device (conf) == driver))
{
return (unsigned int) confp;
}
}
return 0;
}
unsigned int
leon3_getbase (register unsigned int *mbar, register unsigned int iobase,
int *irq)
{
register unsigned int conf = mbar[1];
return (unsigned int) (((iobase & 0xfff00000) |
((conf & 0xfff00000) >> 12)) & (((conf & 0x0000fff0)
<< 4) |
0xfff00000));
}
unsigned int
leon3_apbslv_scan (register unsigned int base,
register unsigned int vendor,
register unsigned int driver,
amba_apb_device * apbdevs, int c)
{
register unsigned int conf, i, *confp;
int j = 0;
for (i = 0; i < LEON3_APB_SLAVES; i++)
{
confp = (unsigned int *) (base + (i * LEON3_APB_CONF_WORDS * 4));
conf = *confp;
if ((amba_vendor (conf) == vendor) && (amba_device (conf) == driver))
{
if (j < c)
{
apbdevs[j].start = leon3_getbase (confp, base, 0);
apbdevs[j].irq = amba_irq (conf);
j++;
}
}
}
return j;
}
unsigned int
leon3_getapbbase (register unsigned int vendor,
register unsigned int driver,
amba_apb_device * apbdevs, int c)
{
unsigned int apb = leon3_ahbslv_scan (VENDOR_GAISLER, GAISLER_APBMST);
apb = (*(unsigned int *) (apb + 16)) & LEON3_IO_AREA;
apb |= LEON3_CONF_AREA;
return leon3_apbslv_scan (apb, vendor, driver, apbdevs, c);
}

View File

@ -0,0 +1,429 @@
/*
* Copyright (c) 2011 Aeroflex Gaisler
*
* BSD license:
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
#ifndef _LEON3_AMBA_H__
#define _LEON3_AMBA_H__
#define LEON3_IO_AREA 0xfff00000
#define LEON3_CONF_AREA 0xff000
#define LEON3_AHB_SLAVE_CONF_AREA (1 << 11)
#define LEON3_AHB_CONF_WORDS 8
#define LEON3_APB_CONF_WORDS 2
#define LEON3_AHB_MASTERS 8
#define LEON3_AHB_SLAVES 8
#define LEON3_APB_SLAVES 16
#define LEON3_APBUARTS 8
/* Vendor codes */
#define VENDOR_GAISLER 1
#define VENDOR_PENDER 2
#define VENDOR_ESA 4
#define VENDOR_OPENCORES 8
/* Gaisler Research device id's */
#define GAISLER_LEON3 0x003
#define GAISLER_LEON3DSU 0x004
#define GAISLER_ETHAHB 0x005
#define GAISLER_APBMST 0x006
#define GAISLER_AHBUART 0x007
#define GAISLER_SRCTRL 0x008
#define GAISLER_SDCTRL 0x009
#define GAISLER_APBUART 0x00c
#define GAISLER_IRQMP 0x00d
#define GAISLER_AHBRAM 0x00e
#define GAISLER_GPTIMER 0x011
#define GAISLER_PCITRG 0x012
#define GAISLER_PCISBRG 0x013
#define GAISLER_PCIFBRG 0x014
#define GAISLER_PCITRACE 0x015
#define GAISLER_PCIDMA 0x016
#define GAISLER_AHBTRACE 0x017
#define GAISLER_ETHDSU 0x018
#define GAISLER_PIOPORT 0x01A
#define GAISLER_SPACEWIRE 0x01f
#define GAISLER_ETHMAC 0x01d
#define GAISLER_EHCI 0x026
#define GAISLER_UHCI 0x027
#define GAISLER_L2TIME 0xffd /* internal device: leon2 timer */
#define GAISLER_L2C 0xffe /* internal device: leon2compat */
#define GAISLER_PLUGPLAY 0xfff /* internal device: plug & play configarea */
#ifndef __ASSEMBLER__
extern inline char *
gaisler_device_str (int id)
{
switch (id)
{
case GAISLER_LEON3:
return "GAISLER_LEON3";
case GAISLER_LEON3DSU:
return "GAISLER_LEON3DSU";
case GAISLER_ETHAHB:
return "GAISLER_ETHAHB";
case GAISLER_APBMST:
return "GAISLER_APBMST";
case GAISLER_AHBUART:
return "GAISLER_AHBUART";
case GAISLER_SRCTRL:
return "GAISLER_SRCTRL";
case GAISLER_SDCTRL:
return "GAISLER_SDCTRL";
case GAISLER_APBUART:
return "GAISLER_APBUART";
case GAISLER_IRQMP:
return "GAISLER_IRQMP";
case GAISLER_AHBRAM:
return "GAISLER_AHBRAM";
case GAISLER_GPTIMER:
return "GAISLER_GPTIMER";
case GAISLER_PCITRG:
return "GAISLER_PCITRG";
case GAISLER_PCISBRG:
return "GAISLER_PCISBRG";
case GAISLER_PCIFBRG:
return "GAISLER_PCIFBRG";
case GAISLER_PCITRACE:
return "GAISLER_PCITRACE";
case GAISLER_AHBTRACE:
return "GAISLER_AHBTRACE";
case GAISLER_ETHDSU:
return "GAISLER_ETHDSU";
case GAISLER_PIOPORT:
return "GAISLER_PIOPORT";
case GAISLER_SPACEWIRE:
return "GAISLER_SPACEWIRE";
case GAISLER_L2TIME:
return "GAISLER_L2TIME";
case GAISLER_L2C:
return "GAISLER_L2C";
case GAISLER_PLUGPLAY:
return "GAISLER_PLUGPLAY";
default:
break;
}
return 0;
}
#endif
/* European Space Agency device id's */
#define ESA_LEON2 0x002
#define ESA_MCTRL 0x00f
#ifndef __ASSEMBLER__
extern inline char *
esa_device_str (int id)
{
switch (id)
{
case ESA_LEON2:
return "ESA_LEON2";
case ESA_MCTRL:
return "ESA_MCTRL";
default:
break;
}
return 0;
}
#endif
/* Opencores device id's */
#define OPENCORES_PCIBR 0x4
#define OPENCORES_ETHMAC 0x5
#ifndef __ASSEMBLER__
extern inline char *
opencores_device_str (int id)
{
switch (id)
{
case OPENCORES_PCIBR:
return "OPENCORES_PCIBR";
case OPENCORES_ETHMAC:
return "OPENCORES_ETHMAC";
default:
break;
}
return 0;
}
extern inline char *
device_id2str (int vendor, int id)
{
switch (vendor)
{
case VENDOR_GAISLER:
return gaisler_device_str (id);
case VENDOR_ESA:
return esa_device_str (id);
case VENDOR_OPENCORES:
return opencores_device_str (id);
case VENDOR_PENDER:
default:
break;
}
return 0;
}
extern inline char *
vendor_id2str (int vendor)
{
switch (vendor)
{
case VENDOR_GAISLER:
return "VENDOR_GAISLER";
case VENDOR_ESA:
return "VENDOR_ESA";
case VENDOR_OPENCORES:
return "VENDOR_OPENCORES";
case VENDOR_PENDER:
return "VENDOR_PENDER";
default:
break;
}
return 0;
}
#endif
/* Vendor codes */
/*
*
* Macros for manipulating Configuration registers
*
*/
#define LEON3_BYPASS_LOAD_PA(x) (*((unsigned long*)x))
#define LEON3_BYPASS_STORE_PA(x,v) (*((unsigned long*)x) = (v))
#define amba_get_confword(tab, index, word) (*((tab).addr[(index)]+(word)))
#define amba_vendor(x) (((x) >> 24) & 0xff)
#define amba_device(x) (((x) >> 12) & 0xfff)
#define amba_ahb_get_membar(tab, index, nr) (*((tab).addr[(index)]+4+(nr)))
#define amba_apb_get_membar(tab, index) (*((tab).addr[(index)]+1))
#define amba_membar_start(mbar) (((mbar) & 0xfff00000) & (((mbar) & 0xfff0) << 16))
#define amba_iobar_start(base, iobar) ((base) | ((((iobar) & 0xfff00000)>>12) & (((iobar) & 0xfff0)<<4)) )
#define amba_irq(conf) ((conf) & 0xf)
#define amba_membar_type(mbar) ((mbar) & 0xf)
#define AMBA_TYPE_APBIO 0x1
#define AMBA_TYPE_MEM 0x2
#define AMBA_TYPE_AHBIO 0x3
#define AMBA_TYPE_AHBIO_ADDR(addr) (LEON3_IO_AREA | ((addr) >> 12))
#ifndef __ASSEMBLER__
/*
* The following defines the bits in the LEON UART Status Registers.
*/
#define LEON_REG_UART_STATUS_DR 0x00000001 /* Data Ready */
#define LEON_REG_UART_STATUS_TSE 0x00000002 /* TX Send Register Empty */
#define LEON_REG_UART_STATUS_THE 0x00000004 /* TX Hold Register Empty */
#define LEON_REG_UART_STATUS_BR 0x00000008 /* Break Error */
#define LEON_REG_UART_STATUS_OE 0x00000010 /* RX Overrun Error */
#define LEON_REG_UART_STATUS_PE 0x00000020 /* RX Parity Error */
#define LEON_REG_UART_STATUS_FE 0x00000040 /* RX Framing Error */
#define LEON_REG_UART_STATUS_ERR 0x00000078 /* Error Mask */
/*
* The following defines the bits in the LEON UART Ctrl Registers.
*/
#define LEON_REG_UART_CTRL_RE 0x00000001 /* Receiver enable */
#define LEON_REG_UART_CTRL_TE 0x00000002 /* Transmitter enable */
#define LEON_REG_UART_CTRL_RI 0x00000004 /* Receiver interrupt enable */
#define LEON_REG_UART_CTRL_TI 0x00000008 /* Transmitter interrupt enable */
#define LEON_REG_UART_CTRL_PS 0x00000010 /* Parity select */
#define LEON_REG_UART_CTRL_PE 0x00000020 /* Parity enable */
#define LEON_REG_UART_CTRL_FL 0x00000040 /* Flow control enable */
#define LEON_REG_UART_CTRL_LB 0x00000080 /* Loop Back enable */
#define LEON3_GPTIMER_EN 1
#define LEON3_GPTIMER_RL 2
#define LEON3_GPTIMER_LD 4
#define LEON3_GPTIMER_IRQEN 8
#define LEON3_GPTIMER_IP 0x10
#define LEON3_GPTIMER_CONFIG_TIMERMASK 0x7
#define LEON3_GPTIMER_CONFIG_SEPERATE (1<<8)
typedef struct
{
volatile unsigned int ilevel;
volatile unsigned int ipend;
volatile unsigned int iforce;
volatile unsigned int iclear;
volatile unsigned int notused00;
volatile unsigned int notused01;
volatile unsigned int notused02;
volatile unsigned int notused03;
volatile unsigned int notused10;
volatile unsigned int notused11;
volatile unsigned int notused12;
volatile unsigned int notused13;
volatile unsigned int notused20;
volatile unsigned int notused21;
volatile unsigned int notused22;
volatile unsigned int notused23;
volatile unsigned int mask[16];
} LEON3_IrqCtrl_Regs_Map;
extern volatile LEON3_IrqCtrl_Regs_Map *LEON3_IrqCtrl_Regs; /* in amba.c */
typedef struct
{
volatile unsigned int data;
volatile unsigned int status;
volatile unsigned int ctrl;
volatile unsigned int scaler;
} LEON23_APBUART_Regs_Map;
extern volatile LEON23_APBUART_Regs_Map *leon23_uarts[2]; /* in console.c */
extern unsigned int leon23_irqs[2]; /* in console.c */
typedef struct
{
volatile unsigned int val;
volatile unsigned int rld;
volatile unsigned int ctrl;
volatile unsigned int unused;
} LEON3_GpTimerElem_Regs_Map;
typedef struct
{
volatile unsigned int scalar;
volatile unsigned int scalar_reload;
volatile unsigned int config;
volatile unsigned int unused;
volatile LEON3_GpTimerElem_Regs_Map e[8];
} LEON3_GpTimer_Regs_Map;
#define LEON3_GPTIMER_CONFIG_NRTIMERS(c) ((c)->config & 0x7)
int Timer_getTimer1 (unsigned int **count, unsigned int **reload, unsigned int **ctrl); /* in timer.c */
int Timer_getTimer2 (unsigned int **count, unsigned int **reload, unsigned int **ctrl); /* in timer.c */
extern volatile LEON3_GpTimer_Regs_Map *LEON3_GpTimer_Regs;
extern unsigned long LEON3_GpTimer_Irq;
typedef struct
{
volatile unsigned int iodata;
volatile unsigned int ioout;
volatile unsigned int iodir;
volatile unsigned int irqmask;
volatile unsigned int irqpol;
volatile unsigned int irqedge;
} LEON3_IOPORT_Regs_Map;
/*
* Types and structure used for AMBA Plug & Play bus scanning
*/
extern int amba_init_done;
#define AMBA_MAXAPB_DEVS 64
#define AMBA_MAXAPB_DEVS_PERBUS 16
typedef struct amba_device_table
{
int devnr; /* numbrer of devices on AHB or APB bus */
unsigned int *addr[16]; /* addresses to the devices configuration tables */
unsigned int allocbits[1]; /* 0=unallocated, 1=allocated driver */
} amba_device_table;
typedef struct amba_apbslv_device_table
{
int devnr; /* number of devices on AHB or APB bus */
unsigned int *addr[AMBA_MAXAPB_DEVS]; /* addresses to the devices configuration tables */
unsigned int apbmst[AMBA_MAXAPB_DEVS]; /* apb master if a entry is a apb slave */
unsigned int apbmstidx[AMBA_MAXAPB_DEVS]; /* apb master idx if a entry is a apb slave */
unsigned int allocbits[4]; /* 0=unallocated, 1=allocated driver */
} amba_apbslv_device_table;
typedef struct amba_confarea_type
{
amba_device_table ahbmst;
amba_device_table ahbslv;
amba_apbslv_device_table apbslv;
/*unsigned int apbmst; */
} amba_confarea_type;
extern unsigned long amba_find_apbslv_addr (unsigned long vendor,
unsigned long device,
unsigned long *irq);
// collect apb slaves
typedef struct amba_apb_device
{
unsigned int start, irq;
} amba_apb_device;
extern int amba_get_free_apbslv_devices (int vendor, int device,
amba_apb_device * dev, int nr);
// collect ahb slaves
typedef struct amba_ahb_device
{
unsigned int start[4], irq;
} amba_ahb_device;
extern int amba_get_free_ahbslv_devices (int vendor, int device,
amba_ahb_device * dev, int nr);
/*amba_scan.c*/
unsigned int leon3_getapbbase (register unsigned int vendor,
register unsigned int driver,
amba_apb_device * apbdevs, int c);
#endif //!__ASSEMBLER__
#endif

View File

@ -0,0 +1,54 @@
/*
* Copyright (c) 2011 Aeroflex Gaisler
*
* BSD license:
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
#ifndef _INCLUDE_LEON_ASMMACRO_h
#define _INCLUDE_LEON_ASMMACRO_h
#include <asm-leon/leonstack.h>
/* All trap entry points _must_ begin with this macro or else you
* lose. It makes sure the kernel has a proper window so that
* c-code can be called.
*/
#define SAVE_ALL_HEAD \
sethi %hi(leonbare_trapsetup), %l4; \
jmpl %l4 + %lo(leonbare_trapsetup), %l6;
#define SAVE_ALL \
SAVE_ALL_HEAD \
nop;
#define SAVE_ALL_FAST(l) \
set l-8, %l6; \
sethi %hi(leonbare_trapsetup_fast), %l4; \
jmpl %l4 + %lo(leonbare_trapsetup_fast), %g0; \
nop;
/* All traps low-level code here must end with this macro. */
#define RESTORE_ALL b leonbare_trapreturn; clr %l6;
#define RESTORE_ALL_FAST b leonbare_trapreturn_fast; clr %l6;
#define WRITE_PAUSE nop; nop; nop;
#endif /* !_INCLUDE_LEON_STACK_h */

View File

@ -0,0 +1,45 @@
/*
* Copyright (c) 2011 Aeroflex Gaisler
*
* BSD license:
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
#ifndef _ASMSPARC_CLOCK_PARAM_H
#define _ASMSPARC_CLOCK_PARAM_H
#include <_ansi.h>
#include <asm-leon/param.h>
#ifndef __ASSEMBLER__
int _EXFUN (gettimeofday, (struct timeval * __p, void *__tz));
int _EXFUN (settimeofday, (const struct timeval *, const struct timezone *));
void do_gettimeofday (struct timeval *tv);
#endif
#define USEC_PER_SEC (1000000L)
#define NSEC_PER_SEC (1000000000L)
#define NSEC_PER_USEC (1000L)
extern unsigned long tick_nsec;
extern unsigned long tick_usec;
#endif

View File

@ -0,0 +1,58 @@
/*
* Copyright (c) 2011 Aeroflex Gaisler
*
* BSD license:
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
#ifndef H_LEONBARE_CONTEXTSWITCH_H
#define H_LEONBARE_CONTEXTSWITCH_H
/*
* for this version, the index of THREAD_JB_SP must be even !!!
* This way, we can speed up the context switch (using std).
*/
#define THREAD_JB_SP 0 /* aligned */
#define THREAD_JB_PC 1
#define THREAD_JB_SVMASK 3
#define THREAD_JB_MASK 4
#define THREAD_JB_FP 5
#define THREAD_JB_I7 6
#define THREAD_JB_PSR 8 /* aligned */
#define THREAD_JB_WIM 9
#define THREAD_JB_FPUCTX 10
#ifndef __ASSEMBLER__
extern unsigned long fpustate_current;
typedef int threadctx_t[14 + 2] __attribute__ ((aligned (8)));
int thread_setjmp (threadctx_t env, int val);
void thread_longjmp (threadctx_t env, int val);
void _switch_to (threadctx_t env, int val);
#endif /* __ASSEMBLER__ */
#endif

View File

@ -0,0 +1,79 @@
/*
* Copyright (c) 2011 Aeroflex Gaisler
*
* BSD license:
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
#ifndef _INCLUDE_LEON_ELFMACRO_h
#define _INCLUDE_LEON_ELFMACRO_h
#ifdef __ASSEMBLER__
#define _TEXT_SEG_ALIGN 4
#define _LIBLEONBARE_TEXT_SEG_START \
.text ; .balign _TEXT_SEG_ALIGN
#define FUNC_BEGIN(func) func:
#define FUNC_END(func) .size func, . - func
#define GTEXT(sym) sym ; .type sym,@function
#define GDATA(sym) sym ; .type sym,@object
#define FUNC_EXPORT(func) .globl GTEXT(func)
#define DATA_EXPORT(var) .globl GDATA(var)
#define FUNC_IMPORT(func) .extern FUNC(func)
#define DATA_IMPORT(var) .extern var
#endif
#ifndef weak_alias
/* Define ALIASNAME as a weak alias for NAME. */
# define weak_alias(name, aliasname) _weak_alias (name, aliasname)
# define _weak_alias(name, aliasname) \
extern __typeof (name) aliasname __attribute__ ((weak, alias (#name)));
#endif
#ifndef strong_alias
/* Define ALIASNAME as a strong alias for NAME. */
# define strong_alias(name, aliasname) _strong_alias(name, aliasname)
# define _strong_alias(name, aliasname) \
extern __typeof (name) aliasname __attribute__ ((alias (#name)));
#endif
#ifndef __ASSEMBLER__
typedef int (*initcall_t) (void);
extern initcall_t __leonbare_initcall_start;
extern initcall_t __leonbare_initcall_end;
#endif
#if __GNUC_MINOR__ >= 3
# define __attribute_used__ __attribute__((__used__))
#else
# define __attribute_used__ __attribute__((__unused__))
#endif
#define __define_initcall(level,fn) \
static initcall_t __initcall_##fn __attribute_used__ \
__attribute__((__section__(".initcall" level ".init"))) = fn
#define libc_initcall(fn) __define_initcall("1",fn)
#endif /* !_INCLUDE_LEON_STACK_h */

View File

@ -0,0 +1,39 @@
/*
* Copyright (c) 2011 Aeroflex Gaisler
*
* BSD license:
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
#ifndef __LEONBARE_HEAD_H
#define __LEONBARE_HEAD_H
/* This is for hard interrupts from level 1-14, 15 is non-maskable (nmi) and
* gets handled with another macro.
*/
#define TRAP_ENTRY_INTERRUPT(int_level) \
mov int_level, %l7; rd %psr, %l0; b leonbare_irq_entry; rd %wim, %l3;
#define TRAP_ENTRY(H) \
rd %psr, %l0; b H; rd %wim, %l3; nop;
#endif /* __SPARC_HEAD_H */

View File

@ -0,0 +1,101 @@
/*
* Copyright (c) 2011 Aeroflex Gaisler
*
* BSD license:
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
#ifndef _LEON_CATCHIRQ_HANDLER_H_
#define _LEON_CATCHIRQ_HANDLER_H_
#include <asm-leon/leon.h>
#include <asm-leon/queue.h>
/*#include <sys/fsu_pthread_queue.h>*/
#include <asm-leon/leoncompat.h>
#include <asm-leon/leonstack.h>
#ifndef __ASSEMBLER__
struct pt_regs;
typedef int (*irqhandler) (int, void *, struct leonbare_pt_regs *);
struct irqaction
{
irqhandler handler;
unsigned long flags;
void *dev_id;
struct irqaction *next;
};
#define INIT_IRQACTION { 0,0,0,0 }
struct irqmp_type
{
int *addr;
int eirq;
};
extern void chained_catch_interrupt (int irq, struct irqaction *a);
extern int catch_interrupt (int func, int irq);
typedef int (*schedulehandler) (struct leonbare_pt_regs *);
extern schedulehandler schedule_callback;
typedef int (*tickerhandler) (struct leonbare_pt_regs *);
extern tickerhandler ticker_callback;
extern int leonbare_hz;
extern int nestcount;
extern int no_inirq_check;
extern unsigned long force_noalarm;
extern void (*handler_irq_pre) (void);
extern void (*handler_irq_post) (void);
extern void leonbare_enable_traps (unsigned long old_flags);
extern unsigned long leonbare_disable_traps ();
extern void leonbare_flush_windows ();
static inline void
leonbare_enable_irq (int irq)
{
unsigned int old, irqmask = 1 << irq;
old = leonbare_disable_traps ();
//---------------------
switch (LEONCOMPAT_VERSION)
{
case 3:
default:
LEON3_IrqCtrl_Regs->mask[0] = LEON3_IrqCtrl_Regs->mask[0] | irqmask;
break;
}
//---------------------
leonbare_enable_traps (old);
}
typedef int (*pendinghandler) (void *);
struct pendingaction
{
TAILQ_ENTRY (pendingaction) next;
pendinghandler handler;
void *arg;
};
#endif
#endif

View File

@ -0,0 +1,104 @@
/*
* Copyright (c) 2011 Aeroflex Gaisler
*
* BSD license:
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
#ifndef _LINUX_JIFFIES_H
#define _LINUX_JIFFIES_H
#include <asm-leon/types.h>
#include <asm-leon/clock.h>
#include <asm-leon/linkage.h>
/* Suppose we want to devide two numbers NOM and DEN: NOM/DEN, the we can
* improve accuracy by shifting LSH bits, hence calculating:
* (NOM << LSH) / DEN
* This however means trouble for large NOM, because (NOM << LSH) may no
* longer fit in 32 bits. The following way of calculating this gives us
* some slack, under the following conditions:
* - (NOM / DEN) fits in (32 - LSH) bits.
* - (NOM % DEN) fits in (32 - LSH) bits.
*/
#define SH_DIV(NOM,DEN,LSH) ( ((NOM / DEN) << LSH) \
+ (((NOM % DEN) << LSH) + DEN / 2) / DEN)
/* TICK_NSEC is the time between ticks in nsec assuming real ACTHZ */
#define TICK_NSEC (SH_DIV (1000000UL * 1000, (HZ<<8), 8))
/*
* The 64-bit value is not volatile - you MUST NOT read it
* without sampling the sequence number in xtime_lock.
*/
extern u64 jiffies_64;
extern struct timespec xtime __attribute__ ((aligned (16)));
#define jiffies (*((unsigned long *)(((unsigned long)(&jiffies_64))+4)))
/*
* These inlines deal with timer wrapping correctly. You are
* strongly encouraged to use them
* 1. Because people otherwise forget
* 2. Because if the timer wrap changes in future you won't have to
* alter your driver code.
*
* time_after(a,b) returns true if the time a is after time b.
*
* Do this with "<0" and ">=0" to only test the sign of the result. A
* good compiler would generate better code (and a really good compiler
* wouldn't care). Gcc is currently neither.
*/
#define time_after(a,b) \
(typecheck(unsigned long, a) && \
typecheck(unsigned long, b) && \
((long)(b) - (long)(a) < 0))
#define time_before(a,b) time_after(b,a)
#define time_after_eq(a,b) \
(typecheck(unsigned long, a) && \
typecheck(unsigned long, b) && \
((long)(a) - (long)(b) >= 0))
#define time_before_eq(a,b) time_after_eq(b,a)
/*
* Have the 32 bit jiffies value wrap 5 minutes after boot
* so jiffies wrap bugs show up earlier.
*/
#define INITIAL_JIFFIES ((unsigned long)(unsigned int) (-300*HZ))
static inline void
set_normalized_timespec (struct timespec *ts, time_t sec, long nsec)
{
while (nsec > NSEC_PER_SEC)
{
nsec -= NSEC_PER_SEC;
++sec;
}
while (nsec < 0)
{
nsec += NSEC_PER_SEC;
--sec;
}
ts->tv_sec = sec;
ts->tv_nsec = nsec;
}
#endif

View File

@ -0,0 +1,177 @@
/*
* Copyright (c) 2011 Aeroflex Gaisler
*
* BSD license:
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
#ifndef _LAMBAPP_H
#define _LAMBAPP_H
/* Include VENDOR and DEVICE definitions */
#include "lambapp_devs.h"
#ifdef __cplusplus
extern "C"
{
#endif
struct ambapp_dev_hdr;
struct ambapp_apb_info;
struct ambapp_ahb_info;
struct ambapp_dev_hdr
{
struct ambapp_dev_hdr *next; /* Next */
struct ambapp_dev_hdr *prev; /* Previous Device. If (this == prev->child) prev is bus bridge */
struct ambapp_dev_hdr *children; /* Points to first device on sub-bus */
void *owner; /* Owner of this AMBA device */
unsigned char dev_type; /* AHB MST, AHB SLV or APB SLV */
unsigned char vendor; /* Vendor ID */
unsigned short device; /* Device ID */
void *devinfo; /* Device info (APB or AHB depending on type) */
};
#define AMBAPP_FLAG_FFACT_DIR 0x100 /* Frequency factor direction, 0=down, 1=up */
#define AMBAPP_FLAG_FFACT 0x0f0 /* Frequency factor against top bus */
#define AMBAPP_FLAG_MBUS 0x00c
#define AMBAPP_FLAG_SBUS 0x003
struct ambapp_apb_info
{
/* COMMON */
unsigned char irq;
unsigned char ver;
/* APB SPECIFIC */
unsigned int start;
unsigned int mask;
};
struct ambapp_ahb_info
{
/* COMMON */
unsigned char irq;
unsigned char ver;
/* AHB SPECIFIC */
unsigned int start[4];
unsigned int mask[4];
char type[4]; /* type[N] Determine type of start[N]-mask[N], 2=AHB Memory Space, 3=AHB I/O Space */
unsigned int custom[3];
};
/* Describes a complete AMBA Core. Each device may consist of 3 interfaces */
struct ambapp_dev_info
{
char irq; /* irq=-1 indicate no IRQ */
unsigned char vendor;
unsigned short device;
int index; /* Core index if multiple "subcores" in one */
struct ambapp_ahb_info *ahb_mst;
struct ambapp_ahb_info *ahb_slv;
struct ambapp_apb_info *apb_slv;
};
struct ambapp_mmap
{
unsigned int size;
unsigned int local_adr;
unsigned int remote_adr;
};
/* Complete AMBA PnP information */
struct ambapp_bus
{
struct ambapp_mmap *mmaps;
struct ambapp_dev_hdr *root;
};
/*
* Return values
* 0 - continue
* 1 - stop scanning
*/
typedef int (*ambapp_func_t) (struct ambapp_dev_hdr * dev, int index,
int maxdepth, void *arg);
#define DEV_IS_FREE(dev) (dev->owner == NULL)
#define DEV_IS_ALLOCATED(dev) (dev->owner != NULL)
/* Options to ambapp_for_each */
#define OPTIONS_AHB_MSTS 0x00000001
#define OPTIONS_AHB_SLVS 0x00000002
#define OPTIONS_APB_SLVS 0x00000004
#define OPTIONS_ALL_DEVS (OPTIONS_AHB_MSTS|OPTIONS_AHB_SLVS|OPTIONS_APB_SLVS)
#define OPTIONS_FREE 0x00000010
#define OPTIONS_ALLOCATED 0x00000020
#define OPTIONS_ALL (OPTIONS_FREE|OPTIONS_ALLOCATED)
/* Depth first search, Defualt is breth first search. */
#define OPTIONS_DEPTH_FIRST 0x00000100
#define DEV_AHB_NONE 0
#define DEV_AHB_MST 1
#define DEV_AHB_SLV 2
#define DEV_APB_SLV 3
/* Structures used to access Plug&Play information directly */
struct ambapp_pnp_ahb
{
const unsigned int id; /* VENDOR, DEVICE, VER, IRQ, */
const unsigned int custom[3];
const unsigned int mbar[4]; /* MASK, ADDRESS, TYPE, CACHABLE/PREFETCHABLE */
};
struct ambapp_pnp_apb
{
const unsigned int id; /* VENDOR, DEVICE, VER, IRQ, */
const unsigned int iobar; /* MASK, ADDRESS, TYPE, CACHABLE/PREFETCHABLE */
};
#define ambapp_pnp_vendor(id) (((id) >> 24) & 0xff)
#define ambapp_pnp_device(id) (((id) >> 12) & 0xfff)
#define ambapp_pnp_ver(id) (((id)>>5) & 0x1f)
#define ambapp_pnp_irq(id) ((id) & 0x1f)
#define ambapp_pnp_start(mbar) (((mbar) & 0xfff00000) & (((mbar) & 0xfff0) << 16))
#define ambapp_pnp_mbar_mask(mbar) (((mbar)>>4) & 0xfff)
#define ambapp_pnp_mbar_type(mbar) ((mbar) & 0xf)
#define ambapp_pnp_apb_start(iobar, base) ((base) | ((((iobar) & 0xfff00000)>>12) & (((iobar) & 0xfff0)<<4)) )
#define ambapp_pnp_apb_mask(iobar) ((~(ambapp_pnp_mbar_mask(iobar)<<8) & 0x000fffff) + 1)
#define AMBA_TYPE_AHBIO_ADDR(addr,base_ioarea) ((unsigned int)(base_ioarea) | ((addr) >> 12))
#define AMBA_TYPE_APBIO 0x1
#define AMBA_TYPE_MEM 0x2
#define AMBA_TYPE_AHBIO 0x3
extern int find_apbslv (int vendor, int device,
struct ambapp_apb_info *dev);
#ifdef __cplusplus
}
#endif
#endif

View File

@ -0,0 +1,242 @@
/*
* Copyright (c) 2011 Aeroflex Gaisler
*
* BSD license:
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
#ifndef __AMBAPP_DEVS_H__
#define __AMBAPP_DEVS_H__
/* Vendor codes */
#define VENDOR_GAISLER 1
#define VENDOR_PENDER 2
#define VENDOR_ESA 4
#define VENDOR_ASTRIUM 6
#define VENDOR_OPENCHIP 7
#define VENDOR_OPENCORES 8
#define VENDOR_CONTRIB 9
#define VENDOR_EONIC 11
#define VENDOR_RADIONOR 15
#define VENDOR_GLEICHMANN 16
#define VENDOR_MENTA 17
#define VENDOR_SUN 19
#define VENDOR_MOVIDIA 20
#define VENDOR_ORBITA 23
#define VENDOR_SYNOPSYS 33
#define VENDOR_NASA 34
#define VENDOR_ACTEL 172
#define VENDOR_CAL 202
#define VENDOR_EMBEDDIT 234
#define VENDOR_CETON 203
/* Gaisler Research device id's */
#define GAISLER_LEON2DSU 0x002
#define GAISLER_LEON3 0x003
#define GAISLER_LEON3DSU 0x004
#define GAISLER_ETHAHB 0x005
#define GAISLER_APBMST 0x006
#define GAISLER_AHBUART 0x007
#define GAISLER_SRCTRL 0x008
#define GAISLER_SDCTRL 0x009
#define GAISLER_SSRCTRL 0x00a
#define GAISLER_APBUART 0x00c
#define GAISLER_IRQMP 0x00d
#define GAISLER_AHBRAM 0x00e
#define GAISLER_AHBDPRAM 0x00f
#define GAISLER_GPTIMER 0x011
#define GAISLER_PCITRG 0x012
#define GAISLER_PCISBRG 0x013
#define GAISLER_PCIFBRG 0x014
#define GAISLER_PCITRACE 0x015
#define GAISLER_DMACTRL 0x016
#define GAISLER_AHBTRACE 0x017
#define GAISLER_DSUCTRL 0x018
#define GAISLER_CANAHB 0x019
#define GAISLER_GPIO 0x01a
#define GAISLER_AHBROM 0x01b
#define GAISLER_AHBJTAG 0x01c
#define GAISLER_ETHMAC 0x01d
#define GAISLER_SWNODE 0x01e
#define GAISLER_SPW 0x01f
#define GAISLER_AHB2AHB 0x020
#define GAISLER_USBDC 0x021
#define GAISLER_USB_DCL 0x022
#define GAISLER_DDRMP 0x023
#define GAISLER_ATACTRL 0x024
#define GAISLER_DDRSP 0x025
#define GAISLER_EHCI 0x026
#define GAISLER_UHCI 0x027
#define GAISLER_I2CMST 0x028
#define GAISLER_SPW2 0x029
#define GAISLER_AHBDMA 0x02a
#define GAISLER_NUHOSP3 0x02b
#define GAISLER_CLKGATE 0x02c
#define GAISLER_SPICTRL 0x02d
#define GAISLER_DDR2SP 0x02e
#define GAISLER_SLINK 0x02f
#define GAISLER_GRTM 0x030
#define GAISLER_GRTC 0x031
#define GAISLER_GRPW 0x032
#define GAISLER_GRCTM 0x033
#define GAISLER_GRHCAN 0x034
#define GAISLER_GRFIFO 0x035
#define GAISLER_GRADCDAC 0x036
#define GAISLER_GRPULSE 0x037
#define GAISLER_GRTIMER 0x038
#define GAISLER_AHB2PP 0x039
#define GAISLER_GRVERSION 0x03a
#define GAISLER_APB2PW 0x03b
#define GAISLER_PW2APB 0x03c
#define GAISLER_GRCAN 0x03d
#define GAISLER_I2CSLV 0x03e
#define GAISLER_U16550 0x03f
#define GAISLER_AHBMST_EM 0x040
#define GAISLER_AHBSLV_EM 0x041
#define GAISLER_GRTESTMOD 0x042
#define GAISLER_ASCS 0x043
#define GAISLER_IPMVBCTRL 0x044
#define GAISLER_SPIMCTRL 0x045
#define GAISLER_LEON4 0x048
#define GAISLER_LEON4DSU 0x049
#define GAISLER_GRPWM 0x04A
#define GAISLER_FTAHBRAM 0x050
#define GAISLER_FTSRCTRL 0x051
#define GAISLER_AHBSTAT 0x052
#define GAISLER_LEON3FT 0x053
#define GAISLER_FTMCTRL 0x054
#define GAISLER_FTSDCTRL 0x055
#define GAISLER_FTSRCTRL8 0x056
#define GAISLER_APBPS2 0x060
#define GAISLER_VGACTRL 0x061
#define GAISLER_LOGAN 0x062
#define GAISLER_SVGACTRL 0x063
#define GAISLER_T1AHB 0x064
#define GAISLER_MP7WRAP 0x065
#define GAISLER_GRSYSMON 0x066
#define GAISLER_GRACECTRL 0x067
#define GAISLER_B1553BC 0x070
#define GAISLER_B1553RT 0x071
#define GAISLER_B1553BRM 0x072
#define GAISLER_SATCAN 0x080
#define GAISLER_CANMUX 0x081
#define GAISLER_GRTMRX 0x082
#define GAISLER_GRTCTX 0x083
#define GAISLER_GRTMDESC 0x084
#define GAISLER_GRTMVC 0x085
#define GAISLER_GEFFE 0x086
#define GAISLER_AES 0x073
#define GAISLER_ECC 0x074
#define GAISLER_PCIF 0x075
#define GAISLER_CLKMOD 0x076
#define GAISLER_HAPSTRAK 0x077
#define GAISLER_TEST_1X2 0x078
#define GAISLER_WILD2AHB 0x079
#define GAISLER_BIO1 0x07a
#define GAISLER_PIPEWRAPPER 0xffa
#define GAISLER_L2TIME 0xffd /* internal device: leon2 timer */
#define GAISLER_L2C 0xffe /* internal device: leon2compat */
#define GAISLER_PLUGPLAY 0xfff /* internal device: plug & play configarea */
/* European Space Agency device id's */
#define ESA_LEON2 0x002
#define ESA_LEON2APB 0x003
#define ESA_IRQ 0x005
#define ESA_TIMER 0x006
#define ESA_UART 0x007
#define ESA_CFG 0x008
#define ESA_IO 0x009
#define ESA_MCTRL 0x00f
#define ESA_PCIARB 0x010
#define ESA_HURRICANE 0x011
#define ESA_SPW_RMAP 0x012
#define ESA_SPW2 0x012
#define ESA_AHBUART 0x013
#define ESA_SPWA 0x014
#define ESA_BOSCHCAN 0x015
#define ESA_IRQ2 0x016
#define ESA_AHBSTAT 0x017
#define ESA_WPROT 0x018
#define ESA_WPROT2 0x019
#define ESA_PDEC3AMBA 0x020
#define ESA_PTME3AMBA 0x021
#define OPENCHIP_APBGPIO 0x001
#define OPENCHIP_APBI2C 0x002
#define OPENCHIP_APBSPI 0x003
#define OPENCHIP_APBCHARLCD 0x004
#define OPENCHIP_APBPWM 0x005
#define OPENCHIP_APBPS2 0x006
#define OPENCHIP_APBMMCSD 0x007
#define OPENCHIP_APBNAND 0x008
#define OPENCHIP_APBLPC 0x009
#define OPENCHIP_APBCF 0x00a
#define OPENCHIP_APBSYSACE 0x00b
#define OPENCHIP_APB1WIRE 0x00c
#define OPENCHIP_APBJTAG 0x00d
#define OPENCHIP_APBSUI 0x00e
#define CONTRIB_CORE1 0x001
#define CONTRIB_CORE2 0x002
#define GLEICHMANN_CUSTOM 0x001
#define GLEICHMANN_GEOLCD01 0x002
#define GLEICHMANN_DAC 0x003
#define GLEICHMANN_HPI 0x004
#define GLEICHMANN_SPI 0x005
#define GLEICHMANN_HIFC 0x006
#define GLEICHMANN_ADCDAC 0x007
#define GLEICHMANN_SPIOC 0x008
#define GLEICHMANN_AC97 0x009
#define SUN_T1 0x001
#define SUN_S1 0x011
#define ORBITA_1553B 0x001
#define ORBITA_429 0x002
#define ORBITA_SPI 0x003
#define ORBITA_I2C 0x004
#define ORBITA_SMARTCARD 0x064
#define ORBITA_SDCARD 0x065
#define ORBITA_UART16550 0x066
#define ORBITA_CRYPTO 0x067
#define ORBITA_SYSIF 0x068
#define ORBITA_PIO 0x069
#define ORBITA_RTC 0x0c8
#define ORBITA_COLORLCD 0x12c
#define ORBITA_PCI 0x190
#define ORBITA_DSP 0x1f4
#define ORBITA_USBHOST 0x258
#define ORBITA_USBDEV 0x2bc
#define NASA_EP32 0x001
#define CAL_DDRCTRL 0x188
#define ACTEL_COREMP7 0x001
/* Opencores device id's */
#define OPENCORES_PCIBR 0x4
#define OPENCORES_ETHMAC 0x5
#endif

View File

@ -0,0 +1,370 @@
/*
* Copyright (c) 2011 Aeroflex Gaisler
*
* BSD license:
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
#ifndef _INCLUDE_LEON_h
#define _INCLUDE_LEON_h
#include <asm-leon/leon3.h>
#include <asm-leon/amba.h>
#ifdef __cplusplus
extern "C"
{
#endif
/* psr defines */
#define SPARC_PSR_WIN_MASK 0x0000001f /* bit 0-4 */
#define SPARC_PSR_ET_MASK 0x00000020 /* bit 5 */
#define SPARC_PSR_PS_MASK 0x00000040 /* bit 6 */
#define SPARC_PSR_S_MASK 0x00000080 /* bit 7 */
#define SPARC_PSR_PIL_MASK 0x00000F00 /* bits 8 - 11 */
#define SPARC_PSR_EF_MASK 0x00001000 /* bit 12 */
#define SPARC_PSR_EC_MASK 0x00002000 /* bit 13 */
#define SPARC_PSR_ICC_MASK 0x00F00000 /* bits 20 - 23 */
#define SPARC_PSR_VER_MASK 0x0F000000 /* bits 24 - 27 */
#define SPARC_PSR_IMPL_MASK 0xF0000000 /* bits 28 - 31 */
#define SPARC_PSR_PIL_SHIFT 8
#define SPARC_NUM_REGWIN _nwindows
#ifndef __ASSEMBLER__
extern int _nwindows;
extern int _leon_version;
#endif
#define LEON_VERSION _leon_version
/*
* Interrupt Sources
*
* The interrupt source numbers directly map to the trap type and to
* the bits used in the Interrupt Clear, Interrupt Force, Interrupt Mask,
* and the Interrupt Pending Registers.
*/
#define LEON_INTERRUPT_CORRECTABLE_MEMORY_ERROR 1
#define LEON2_INTERRUPT_UART_2_RX_TX 2
#define LEON2_INTERRUPT_UART_1_RX_TX 3
#define LEON23_INTERRUPT_UART_2_RX_TX leon23_irqs[1] /*console.c */
#define LEON23_INTERRUPT_UART_1_RX_TX leon23_irqs[0] /*console.c */
#define LEON_INTERRUPT_EXTERNAL_0 4
#define LEON_INTERRUPT_EXTERNAL_1 5
#define LEON_INTERRUPT_EXTERNAL_2 6
#define LEON_INTERRUPT_EXTERNAL_3 7
#define LEON2_INTERRUPT_TIMER1 8
#define LEON2_INTERRUPT_TIMER2 9
#define LEON23_INTERRUPT_TIMER1 leon23_timerirqs[0] /* timer.c */
#define LEON23_INTERRUPT_TIMER2 leon23_timerirqs[1] /* timer.c */
#define LEON_INTERRUPT_EMPTY1 10
#define LEON_INTERRUPT_EMPTY2 11
#define LEON_INTERRUPT_EMPTY3 12
#define LEON_INTERRUPT_EMPTY4 13
#define LEON_INTERRUPT_EMPTY5 14
#define LEON_INTERRUPT_EMPTY6 15
#ifndef __ASSEMBLER__
/*
* Trap Types for on-chip peripherals
*
* Source: Table 8 - Interrupt Trap Type and Default Priority Assignments
*
* NOTE: The priority level for each source corresponds to the least
* significant nibble of the trap type.
*/
#define LEON_TRAP_TYPE( _source ) SPARC_ASYNCHRONOUS_TRAP((_source) + 0x10)
#define LEON_TRAP_SOURCE( _trap ) ((_trap) - 0x10)
#define LEON_INT_TRAP( _trap ) \
( (_trap) >= LEON_TRAP_TYPE( LEON_INTERRUPT_CORRECTABLE_MEMORY_ERROR ) && \
(_trap) <= LEON_TRAP_TYPE( LEON_INTERRUPT_EMPTY6 ) )
#endif
/*
* The following defines the bits in Memory Configuration Register 1.
*/
#define LEON_MEMORY_CONFIGURATION_PROM_SIZE_MASK 0x0003C000
/*
* The following defines the bits in Memory Configuration Register 1.
*/
#define LEON_MEMORY_CONFIGURATION_RAM_SIZE_MASK 0x00001E00
/*
* The following defines the bits in the Timer Control Register.
*/
#define LEON_REG_TIMER_CONTROL_EN 0x00000001 /* 1 = enable counting */
/* 0 = hold scalar and counter */
#define LEON_REG_TIMER_CONTROL_RL 0x00000002 /* 1 = reload at 0 */
/* 0 = stop at 0 */
#define LEON_REG_TIMER_CONTROL_LD 0x00000004 /* 1 = load counter */
/* 0 = no function */
/*
* The following defines the bits in the UART Control Registers.
*
*/
#define LEON_REG_UART_CONTROL_RTD 0x000000FF /* RX/TX data */
/*
* The following defines the bits in the LEON UART Status Registers.
*/
#define LEON_REG_UART_STATUS_DR 0x00000001 /* Data Ready */
#define LEON_REG_UART_STATUS_TSE 0x00000002 /* TX Send Register Empty */
#define LEON_REG_UART_STATUS_THE 0x00000004 /* TX Hold Register Empty */
#define LEON_REG_UART_STATUS_BR 0x00000008 /* Break Error */
#define LEON_REG_UART_STATUS_OE 0x00000010 /* RX Overrun Error */
#define LEON_REG_UART_STATUS_PE 0x00000020 /* RX Parity Error */
#define LEON_REG_UART_STATUS_FE 0x00000040 /* RX Framing Error */
#define LEON_REG_UART_STATUS_ERR 0x00000078 /* Error Mask */
/*
* The following defines the bits in the LEON UART Status Registers.
*/
#define LEON_REG_UART_CTRL_RE 0x00000001 /* Receiver enable */
#define LEON_REG_UART_CTRL_TE 0x00000002 /* Transmitter enable */
#define LEON_REG_UART_CTRL_RI 0x00000004 /* Receiver interrupt enable */
#define LEON_REG_UART_CTRL_TI 0x00000008 /* Transmitter interrupt enable */
#define LEON_REG_UART_CTRL_PS 0x00000010 /* Parity select */
#define LEON_REG_UART_CTRL_PE 0x00000020 /* Parity enable */
#define LEON_REG_UART_CTRL_FL 0x00000040 /* Flow control enable */
#define LEON_REG_UART_CTRL_LB 0x00000080 /* Loop Back enable */
/* leon2 asis */
#define ASI_LEON2_IFLUSH 0x05
#define ASI_LEON2_DFLUSH 0x06
#define ASI_LEON2_CACHEMISS 1
/* leon3 asis */
#define ASI_LEON3_IFLUSH 0x10
#define ASI_LEON3_DFLUSH 0x11
#define ASI_LEON3_CACHEMISS 1
#define ASI_LEON3_SYSCTRL 0x02
#define ASI_LEON23_ITAG 0x0c
#define ASI_LEON23_DTAG 0x0e
#ifndef __ASSEMBLER__
unsigned int leonbare_leon23_loadnocache (unsigned int addr);
unsigned int leonbare_leon23_loadnocache16 (unsigned int addr);
unsigned int leonbare_leon23_loadnocache8 (unsigned int addr);
unsigned int leonbare_leon23_storenocache (unsigned int addr,
unsigned int value);
unsigned int leonbare_leon23_storenocache16 (unsigned int addr,
unsigned int value);
unsigned int leonbare_leon23_storenocache8 (unsigned int addr,
unsigned int value);
unsigned int leonbare_leon3_loadnocache (unsigned int addr);
unsigned int leonbare_leon3_loadnocache16 (unsigned int addr);
unsigned int leonbare_leon3_loadnocache8 (unsigned int addr);
/*
* This is used to manipulate the on-chip registers.
*
* The following symbol must be defined in the linkcmds file and point
* to the correct location.
*/
extern unsigned long *LEON23_IRQ_mask_addr; /* in peripherals.h */
extern unsigned long *LEON23_IRQ_force_addr; /* in peripherals.h */
extern unsigned long *LEON23_IRQ_pending_addr; /* in peripherals.h */
extern unsigned long *LEON23_IRQ_clear_addr; /* in peripherals.h */
/*
* Macros to manipulate the Interrupt Clear, Interrupt Force, Interrupt Mask,
* and the Interrupt Pending Registers.
*
* NOTE: For operations which are not atomic, this code disables interrupts
* to guarantee there are no intervening accesses to the same register.
* The operations which read the register, modify the value and then
* store the result back are vulnerable.
*/
#define LEON_Clear_interrupt( _source ) \
do { \
(*LEON23_IRQ_clear_addr) = (1 << (_source)); \
} while (0)
#define LEON_Force_interrupt( _source ) \
do { \
(*LEON23_IRQ_force_addr) = (1 << (_source)); \
} while (0)
#define LEON_Is_interrupt_masked( _source ) \
((*LEON23_IRQ_mask_addr) & (1 << (_source)))
#define LEON_Mask_interrupt( _source ) \
do { \
unsigned32 _level; \
\
_level = sparc_disable_interrupts(); \
(*LEON23_IRQ_mask_addr) &= ~(1 << (_source)); \
sparc_enable_interrupts( _level ); \
} while (0)
#define LEON_Unmask_interrupt( _source ) \
do { \
unsigned32 _level; \
\
_level = sparc_disable_interrupts(); \
(*LEON23_IRQ_mask_addr) |= (1 << (_source)); \
sparc_enable_interrupts( _level ); \
} while (0)
#define LEON_Disable_interrupt( _source, _previous ) \
do { \
unsigned32 _level; \
unsigned32 _mask = 1 << (_source); \
\
_level = sparc_disable_interrupts(); \
(_previous) = (*LEON23_IRQ_mask_addr); \
(*LEON23_IRQ_mask_addr) = _previous & ~_mask; \
sparc_enable_interrupts( _level ); \
(_previous) &= _mask; \
} while (0)
#define LEON_Restore_interrupt( _source, _previous ) \
do { \
unsigned32 _level; \
unsigned32 _mask = 1 << (_source); \
\
_level = sparc_disable_interrupts(); \
(*LEON23_IRQ_mask_addr) = \
((*LEON23_IRQ_mask_addr) & ~_mask) | (_previous); \
sparc_enable_interrupts( _level ); \
} while (0)
/*
* Each timer control register is organized as follows:
*
* D0 - Enable
* 1 = enable counting
* 0 = hold scaler and counter
*
* D1 - Counter Reload
* 1 = reload counter at zero and restart
* 0 = stop counter at zero
*
* D2 - Counter Load
* 1 = load counter with preset value
* 0 = no function
*
*/
#define LEON_REG_TIMER_COUNTER_IRQEN 0x00000008
#define LEON_REG_TIMER_COUNTER_RELOAD_AT_ZERO 0x00000002
#define LEON_REG_TIMER_COUNTER_STOP_AT_ZERO 0x00000000
#define LEON_REG_TIMER_COUNTER_LOAD_COUNTER 0x00000004
#define LEON_REG_TIMER_COUNTER_ENABLE_COUNTING 0x00000001
#define LEON_REG_TIMER_COUNTER_DISABLE_COUNTING 0x00000000
#define LEON_REG_TIMER_COUNTER_RELOAD_MASK 0x00000002
#define LEON_REG_TIMER_COUNTER_ENABLE_MASK 0x00000001
#define LEON_REG_TIMER_COUNTER_DEFINED_MASK 0x00000003
#define LEON_REG_TIMER_COUNTER_CURRENT_MODE_MASK 0x00000003
/* console.c */
int lo_sprintf (char *buf, const char *fmt, ...);
/* do a virtual address read without cache */
static __inline__ unsigned long leon23_getpsr ()
{
unsigned long retval;
__asm__ __volatile__ ("mov %%psr, %0\n\t":"=r" (retval):);
return retval;
}
extern __inline__ void sparc_leon2_dcache_flush (void)
{
__asm__
__volatile__ ("sta %%g0, [%%g0] %0\n\t"::"i"
(ASI_LEON2_IFLUSH):"memory");
__asm__
__volatile__ ("sta %%g0, [%%g0] %0\n\t"::"i"
(ASI_LEON2_DFLUSH):"memory");
};
extern __inline__ void sparc_leon_dcache_flush (void)
{
switch (sparc_leon23_get_psr_version ())
{
case 0:
case 2:
sparc_leon2_dcache_flush ();
break;
default:
sparc_leon3_dcache_flush ();
break;
}
}
extern int lolevelirqinstall (int irqnr, void (*handler) ());
extern unsigned long locore_readtbr ();
extern void _leonbase_Stop ();
extern void uninstall_winoverflow_hook ();
extern int install_winoverflow_hook (void (*func) (void));
extern void sparc_leon23_icache_flush ();
extern void sparc_leon23_dcache_flush ();
#endif /* ! __ASSEMBLER__ */
#ifdef __cplusplus
}
#endif
#define TACODE_IRQCALL 2
#define TACODE_IRQCALL_FLUSH 6
#define TACODE_FLUSH 3
#define TACODE_IRQCALLDIS 5
#endif /* !_INCLUDE_LEON_h */
/* end of include file */

View File

@ -0,0 +1,107 @@
/*
* Copyright (c) 2011 Aeroflex Gaisler
*
* BSD license:
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
#ifndef _INCLUDE_LEON3_h
#define _INCLUDE_LEON3_h
#ifndef __ASSEMBLER__
#ifdef __cplusplus
extern "C"
{
#endif
#define ASI_LEON3_CACHEMISS 1
#define ASI_LEON3_SYSCTRL 0x02
#define ASI_LEON3_DFLUSH 0x11
#define ASI_LEON3_SYSCTRL_ICFG 0x08
#define ASI_LEON3_SYSCTRL_DCFG 0x0c
#define ASI_LEON3_SYSCTRL_CFG_SNOOPING (1<<27)
#define ASI_LEON3_SYSCTRL_CFG_SSIZE(c) (1<<((c>>20)&0xf))
extern __inline__ unsigned long sparc_leon23_get_psr (void)
{
unsigned int retval;
__asm__ __volatile__ ("rd %%psr, %0\n\t":"=r" (retval):);
return (retval);
}
extern __inline__ unsigned long sparc_leon23_get_psr_version (void)
{
unsigned int psr = sparc_leon23_get_psr ();
return (psr >> 24) & 0xf;
}
#define LEON_ISLEON2 (sparc_leon23_get_psr_version() == 2 || sparc_leon23_get_psr_version() == 0)
#define LEON_ISLEON3 (sparc_leon23_get_psr_version() == 3)
extern __inline__ unsigned long sparc_leon3_get_dcachecfg (void)
{
unsigned int retval;
__asm__
__volatile__ ("lda [%1] %2, %0\n\t":"=r" (retval):"r"
(ASI_LEON3_SYSCTRL_DCFG), "i" (ASI_LEON3_SYSCTRL));
return (retval);
}
extern __inline__ void sparc_leon3_enable_snooping (void)
{
/*enable snooping */
__asm__ volatile ("lda [%%g0] 2, %%l1\n\t"
"set 0x800000, %%l2\n\t"
"or %%l2, %%l1, %%l2\n\t"
"sta %%l2, [%%g0] 2\n\t":::"l1", "l2");
};
extern __inline__ void sparc_leon3_disable_cache (void)
{
/*asi 2 */
__asm__ volatile ("lda [%%g0] 2, %%l1\n\t"
"set 0x00000f, %%l2\n\t"
"andn %%l2, %%l1, %%l2\n\t"
"sta %%l2, [%%g0] 2\n\t":::"l1", "l2");
};
extern __inline__ void sparc_leon3_dcache_flush (void)
{
__asm__ __volatile__ (" flush "); //iflush
__asm__
__volatile__ ("sta %%g0, [%%g0] %0\n\t"::"i"
(ASI_LEON3_DFLUSH):"memory");
};
#ifdef __cplusplus
}
#endif
#endif /* !ASM */
#endif /* !_INCLUDE_LEON3_h */
/* end of include file */

View File

@ -0,0 +1,125 @@
/*
* Copyright (c) 2011 Aeroflex Gaisler
*
* BSD license:
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
#ifndef __LEONBARE_KERNEL_DEBUG_H__
#define __LEONBARE_KERNEL_DEBUG_H__
#include <asm-leon/leondbg.h>
/*
#define LBDEBUG_DO_DEBUG
#define LBDEBUG_DO_ASSERT
*/
#define LBDEBUG_ALWAYS_NR (1<<0)
#define LBDEBUG_ASSERT_NR (1<<1)
#define LBDEBUG_FNCALL_NR (1<<2)
#define LBDEBUG_FNEXIT_NR (1<<3)
#define LBDEBUG_SCHED_NR (1<<4)
#define LBDEBUG_QUEUE_NR (1<<5)
#define LBDEBUG_THREAD_NR (1<<6)
#define LBDEBUG_PRINTF dbgleon_printf /*leonbare_debug_printf */
#ifdef LBDEBUG_DO_DEBUG
#ifndef __ASSEMBLER__
extern int leonbare_debug;
#endif
# define PDEBUG_FLAGS_CHECK(c) ((c)&leonbare_debug)
# define PDEBUG_FLAGS_SET(c) leonbare_debug |= c
#else
# define PDEBUG_FLAGS_CHECK(c) 0
# define PDEBUG_FLAGS_SET(c)
#endif
#ifdef LBDEBUG_DO_DEBUG
# define LBDEBUG(x, fmt, args...) do { if (PDEBUG_FLAGS_CHECK(x)) { LBDEBUG_PRINTF(fmt,args); } } while(0)
#else
# define LBDEBUG(x, fmt, args...)
#endif
#ifdef LBDEBUG_DO_ASSERT
# define LBPASSERT(x, fmt, args...) if (!(x)) { LBDEBUG_PRINTF(fmt,args); while(1); }
#else
# define LBPASSERT(x, fmt, args...)
#endif
#ifndef LBDEBUG___FUNCTION__
#define LBDEBUG___FUNCTION__ __FUNCTION__
#endif
#ifndef LBDEBUG___FUNCTION_WIDTH__
#define LBDEBUG___FUNCTION_WIDTH__ "28"
#endif
#ifdef LBDEBUG_DO_FILE
#ifndef LBDEBUG___FILE__
#define LBDEBUG___FILE__ __FILE__
#endif
#ifndef LBDEBUG___FILE_WIDTH__
#define LBDEBUG___FILE_WIDTH__ "28"
#endif
#define LBDEBUG___FILE_APPEND ,__FILE__
#define LBDEBUG___FILE_FMT_APPEND ":%" LBDEBUG___FILE_WIDTH__ "s"
#else
#define LBDEBUG___FILE_APPEND
#define LBDEBUG___FILE_FMT_APPEND
#endif
#ifdef LBDEBUG_DO_DEBUG
# define LBDEBUG_HEADER(code) \
if (PDEBUG_FLAGS_CHECK(code)) { \
register unsigned int _GETSP asm("sp"); \
LBDEBUG_PRINTF("[sp:%08x self(%08x):", _GETSP, LEONBARE_KR_CURRENT); \
LBDEBUG_PRINTF("%10s",LEONBARE_TH_NAME_DBG(LEONBARE_KR_CURRENT)); \
LBDEBUG_PRINTF(" %03d @ %" LBDEBUG___FUNCTION_WIDTH__ "s()" LBDEBUG___FILE_FMT_APPEND "]:" , __LINE__,LBDEBUG___FUNCTION__ LBDEBUG___FILE_APPEND); \
}
# define LBDEBUG_HEADER_PRINTF(code,fmt,args...) \
if (PDEBUG_FLAGS_CHECK(code)) { \
LBDEBUG_HEADER(code); \
LBDEBUG_PRINTF(fmt,args); \
}
# define LBDEBUG_CODE_PRINTF(code,fmt,args...) \
if (PDEBUG_FLAGS_CHECK(code)) { \
LBDEBUG_PRINTF(fmt,args); \
}
#else
# define LBDEBUG_HEADER(code)
# define LBDEBUG_HEADER_PRINTF(code,fmt,args...)
# define LBDEBUG_CODE_PRINTF(code,fmt,args...)
#endif
#define LBDEBUG_FNCALL LBDEBUG_HEADER_PRINTF(LBDEBUG_FNCALL_NR,"enter\n",0)
#define LBDEBUG_FNEXIT LBDEBUG_HEADER_PRINTF(LBDEBUG_FNEXIT_NR,"exit\n",0)
#ifndef __ASSEMBLER__
int leonbare_debug_printf (const char *fmt, ...);
#endif
#endif

View File

@ -0,0 +1,438 @@
/*
* Copyright (c) 2011 Aeroflex Gaisler
*
* BSD license:
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
#ifndef __LEONBARE_KERNEL_H__
#define __LEONBARE_KERNEL_H__
#include <asm-leon/contextswitch.h>
#include <asm-leon/leonbare_debug.h>
#include <asm-leon/leon.h>
#ifndef __ASSEMBLER__
#include <asm-leon/leonbare_kernel_queue.h>
#include <reent.h>
#endif
#include "irq.h"
#define LEONBARE_RUNQ_READY_NR (2) /* queue 0-1 for ready */
#define LEONBARE_RUNQ_SUSPENDED_IDX (2) /* queue 2 for suspended */
#define LEONBARE_RUNQ_PREPARE_IDX (3) /* LEONBARE_RUNQ_READY_NR times queues */
#define LEONBARE_RUNQ_KILLED_IDX (LEONBARE_RUNQ_PREPARE_IDX+LEONBARE_RUNQ_READY_NR) /* queue 2 for killed threads */
#define LEONBARE_RUNQ_NR (LEONBARE_RUNQ_KILLED_IDX+1)
#define LEONBARE_RUNQ_ISREADY(idx) ((idx) >= 0 && (idx) < LEONBARE_RUNQ_READY_NR)
#define LEONBARE_RUNQ_ISPREPARE(idx) ((idx) >= LEONBARE_RUNQ_PREPARE_IDX && (idx) < LEONBARE_RUNQ_PREPARE_IDX+LEONBARE_RUNQ_READY_NR)
#define LEONBARE_RUNQ_ISSUSPEND(idx) ((idx) == LEONBARE_RUNQ_SUSPENDED_IDX)
#define LEONBARE_RUNQ_ISKILLED(idx) ((idx) == LEONBARE_RUNQ_KILLED_IDX)
#ifndef __ASSEMBLER__
#ifndef NULL
#define NULL ((void *)0)
#endif
#define MACRO_BEGIN do {
#define MACRO_END } while (0)
#define optbarrier() __asm__ __volatile__("": : :"memory")
typedef struct leonbare_thread_ctx
{
unsigned long sf_locals[8];
unsigned long sf_ins[8];
unsigned long outs[8];
unsigned long globals[8];
unsigned long psr;
unsigned long wim;
unsigned long magic;
unsigned long fpu;
/* size aligned to 8 */
} leonbare_thread_ctx_t;
#define LEONBARE_THREAD_CTX_SZ sizeof(struct leonbare_thread_ctx)
typedef
LBTAILQ_HEAD (leonbare_mutex_queue, leonbare_mutex) *
leonbare_mutex_queue_t;
#endif
#define LEONBARE_THREAD_OFFSET_CTX 0
#ifndef __ASSEMBLER__
struct leonbare_thread_protect
{
unsigned int runq;
unsigned int krp_runq_depth;
unsigned int krp_k_depth;
struct leonbare_mutex *krp_m;
unsigned int krp_m_depth;
unsigned int krp_flags;;
unsigned int krp_flags_depth;
};
#define LEONBARE_INT_DISABLE_DECL unsigned long _irq_flags = leonbare_disable_traps();
#define LEONBARE_INT_ENABLE_DECL leonbare_enable_traps(_irq_flags);
#define leonbare_setu32p(a,v) leonbare_leon23_storenocache(a,v)
#define leonbare_setu32(a,v) leonbare_leon23_storenocache(a,v)
#define leonbare_getu32(a) leonbare_leon23_loadnocache(a)
#define LEONBARE_KERNEL_UNCACHED
#ifndef LEONBARE_KERNEL_UNCACHED
#define LEONBARE_KERNEL_SETU32P(a,v) (a=v)
#define LEONBARE_KERNEL_SETU32(a,v) (a=v) /* uncached version should return v */
#define LEONBARE_KERNEL_GETU32(a) (a)
#define LEONBARE_KERNEL_GETU32P(a) (a)
#define LEONBARE_KERNEL_GETI32(a) (a)
#define LEONBARE_KERNEL_GETU32P_CAST(a,typ) ((typ)(a))
#define LEONBARE_KERNEL_GETU32P_BARE(a) (*(a)) /* uncached: no & */
#define LEONBARE_KERNEL_SETU32P_BARE(a,v) (*(a) = v) /* uncached: no & */
#else
#define LEONBARE_KERNEL_SETU32P(a,v) (leonbare_setu32p(&a,v))
#define LEONBARE_KERNEL_SETU32(a,v) (leonbare_setu32p(&a,v)) /* uncached version should return v */
#define LEONBARE_KERNEL_GETU32(a) (leonbare_getu32(&a))
#define LEONBARE_KERNEL_GETU32P(a) ((void *)leonbare_getu32(&a))
#define LEONBARE_KERNEL_GETI32(a) (leonbare_getu32(&a))
#define LEONBARE_KERNEL_GETU32P_CAST(a,typ) ((typ)(LEONBARE_KERNEL_GETU32P(a)))
#define LEONBARE_KERNEL_GETU32P_BARE(a) ((void *)leonbare_getu32(a)) /* uncached: no & */
#define LEONBARE_KERNEL_SETU32P_BARE(a,v) (leonbare_setu32p(a,v)) /* uncached: no & */
#endif
#define LEONBARE_SMP_SPINLOCK_AQUIRE(l)
#define LEONBARE_SMP_SPINLOCK_RELEASE(l)
#define LEONBARE_ISQ_ISDISABLED ((leon23_getpsr() & SPARC_PSR_PIL_MASK) == SPARC_PSR_PIL_MASK)
#define _LEONBARE_PROTECT_IRQ_START \
if (LEONBARE_KR_CURRENT->th_prot.krp_flags_depth++) { \
LBPASSERT((LEONBARE_ISQ_ISDISABLED),"Internal error: Recursiv IRQ protection with irq's enabled",0); \
} else { \
LEONBARE_KR_CURRENT->th_prot.krp_flags = leonbare_disable_traps(); \
}
#define _LEONBARE_PROTECT_IRQ_END \
if (--LEONBARE_KR_CURRENT->th_prot.krp_flags_depth) { \
LBPASSERT((LEONBARE_ISQ_ISDISABLED),"Internal error: Recursiv IRQ protection with irq's enabled",0); \
} else { \
leonbare_enable_traps(LEONBARE_KR_CURRENT->th_prot.krp_flags); \
}
#define _LEONBARE_PROTECT_MUTEXSTRUCT_START(m) \
if (LEONBARE_KR_CURRENT->th_prot.krp_m_depth++) { \
LBPASSERT((LEONBARE_KR_CURRENT->th_prot.krp_m == m),"Mutex protection only allowed for one mutex at a time",0); \
} else { \
LEONBARE_SMP_SPINLOCK_AQUIRE(m->smp_lock); \
LEONBARE_KR_CURRENT->th_prot.krp_m = m; \
}
#define _LEONBARE_PROTECT_MUTEXSTRUCT_END(m) \
LBPASSERT((LEONBARE_KR_CURRENT->th_prot.krp_m == m),"Mutex protection only allowed for one mutex at a time",0); \
if ((--LEONBARE_KR_CURRENT->th_prot.krp_m_depth) == 0) { \
LEONBARE_SMP_SPINLOCK_RELEASE(m->smp_lock); \
}
#define _LEONBARE_PROTECT_KERNEL_START \
if (LEONBARE_KR_CURRENT->th_prot.krp_k_depth++ == 0) { \
LEONBARE_SMP_SPINLOCK_AQUIRE(LEONBARE_KR_LOCK); \
}
#define _LEONBARE_PROTECT_KERNEL_END \
if ((--LEONBARE_KR_CURRENT->th_prot.krp_k_depth) == 0) { \
LEONBARE_SMP_SPINLOCK_RELEASE(LEONBARE_KR_LOCK); \
}
#define LEONBARE_PROTECT_MUTEXSTRUCT_START(m) \
_LEONBARE_PROTECT_IRQ_START; \
_LEONBARE_PROTECT_MUTEXSTRUCT_START(m)
#define LEONBARE_PROTECT_MUTEXSTRUCT_END(m) \
_LEONBARE_PROTECT_MUTEXSTRUCT_END(m) \
_LEONBARE_PROTECT_IRQ_END;
#define LEONBARE_PROTECT_KERNEL_START() \
_LEONBARE_PROTECT_IRQ_START; \
_LEONBARE_PROTECT_KERNEL_START;
#define LEONBARE_PROTECT_KERNEL_END() \
_LEONBARE_PROTECT_KERNEL_END; \
_LEONBARE_PROTECT_IRQ_END;
typedef struct leonbare_thread
{
struct leonbare_thread_ctx th_ctx;
unsigned int th_flags;
int th_account; /* how many ticks the thread stays in the readyqueue for one round */
int th_caccount; /* current value of th_account, updated on reinsertion */
unsigned int th_pri_idx; /* ready queue index */
unsigned int th_runq_idx; /* ready queue index index */
unsigned int th_runq_which; /* 0: ready queue, 1: ready prepare queue */
char *th_name;
int th_result;
int (*th_func) (void *);
void *th_arg;
char *th_stack_base;
unsigned int th_stack_size;
struct _reent th_reent; /* reentrant structure for newlib */
struct _reent *th_reentp; /* pointer to eather pt_reent or global reent */
struct leonbare_thread_protect th_prot;
LBTAILQ_ENTRY (leonbare_thread) th_runq;
LBTAILQ_ENTRY (leonbare_thread) th_allq;
LBTAILQ_ENTRY (leonbare_thread) th_mutex;
struct leonbare_mutex_queue th_mutex_locked;
} *leonbare_thread_t __attribute__ ((aligned (8)));
#define LEONBARE_TH_FLAGS_get(c) LEONBARE_KERNEL_GETU32((c)->th_flags)
#define LEONBARE_TH_ACCOUNT_get(c) LEONBARE_KERNEL_GETI32((c)->th_account)
#define LEONBARE_TH_CACCOUNT_get(c) LEONBARE_KERNEL_GETI32((c)->th_caccount)
#define LEONBARE_TH_PRI_IDX_get(c) LEONBARE_KERNEL_GETU32((c)->th_pri_idx)
#define LEONBARE_TH_RUNQ_IDX_get(c) LEONBARE_KERNEL_GETU32((c)->th_runq_idx)
#define LEONBARE_TH_RUNQ_WHICH_get(c) LEONBARE_KERNEL_GETU32((c)->th_runq_which)
#define LEONBARE_TH_NAME_get(c) LEONBARE_KERNEL_GETU32P((c)->th_name)
#define LEONBARE_TH_RESULT_get(c) LEONBARE_KERNEL_GETI32((c)->th_result)
#define LEONBARE_TH_FUNC_get(c) LEONBARE_KERNEL_GETU32((c)->th_func)
#define LEONBARE_TH_ARG_get(c) LEONBARE_KERNEL_GETU32((c)->th_arg)
#define LEONBARE_TH_STACK_BASE_get(c) LEONBARE_KERNEL_GETU32P((c)->th_stack_base)
#define LEONBARE_TH_STACK_SIZE_get(c) LEONBARE_KERNEL_GETU32((c)->th_stack_size)
#define LEONBARE_TH_REENTP_get(c) LEONBARE_KERNEL_GETU32P((c)->th_reentp)
#define LEONBARE_TH_NAME(c) (c->th_name)
#define LEONBARE_TH_NAME_DBG(c) (LEONBARE_TH_NAME(c) ? LEONBARE_TH_NAME(c) : "<unknown>")
#define LEONBARE_REENT_SET(p) ((_impure_ptr=(p)->th_reentp)==_impure_ptr)
#define LEONBARE_TH_READY (1<<0)
#define LEONBARE_TH_SUSPENDED (1<<1)
#define LEONBARE_TH_TERMINATED (1<<2)
#define LEONBARE_TH_FINISHED (1<<3)
#define LEONBARE_TH_SATEMASK (LEONBARE_TH_READY | \
LEONBARE_TH_SUSPENDED | \
LEONBARE_TH_TERMINATED | \
LEONBARE_TH_FINISHED)
#define LEONBARE_TH_SETSTATE(c,f) c->th_flags = ((c->th_flags & ~LEONBARE_TH_SATEMASK) | (f & LEONBARE_TH_SATEMASK))
#define LEONBARE_TH_ORSTATE(c,f) c->th_flags |= (f & LEONBARE_TH_SATEMASK)
typedef LBTAILQ_HEAD (leonbare_thread_queue,
leonbare_thread) * leonbare_thread_queue_t;
extern struct leonbare_kernel leonbare_kernel;
#define KERNEL_GLOBAL leonbare_kernel
typedef struct leonbare_kernel
{
leonbare_thread_t kr_cur, kr_next;
struct leonbare_thread_queue kr_runq[LEONBARE_RUNQ_NR];
struct leonbare_thread_queue kr_allq;
struct leonbare_mutex_queue kr_allm;
int kr_is_inkernel, kr_need_schedule, kr_is_preemption, kr_runq_which;
int kr_protect_flags;
} leonbare_kernel_t __attribute__ ((aligned (8)));
#define LEONBARE_KR_CURRENT (KERNEL_GLOBAL.kr_cur)
#define LEONBARE_KR_NEXT (KERNEL_GLOBAL.kr_next)
#define LEONBARE_KR_RUNQ(i) (&(KERNEL_GLOBAL.kr_runq[i]))
#define LEONBARE_KR_RUNQ_WHICH (KERNEL_GLOBAL.kr_runq_which)
#define LEONBARE_KR_ALLQ (&(KERNEL_GLOBAL.kr_allq))
#define LEONBARE_KR_ALLM (&(KERNEL_GLOBAL.kr_allm))
#define LEONBARE_KR_IS_IN_KERNEL (KERNEL_GLOBAL.kr_is_inkernel)
#define LEONBARE_KR_IS_PREEMPTION (KERNEL_GLOBAL.kr_is_preemption)
#define LEONBARE_KR_NEED_SCHEDULE (LEONBARE_KR_CURRENT != LEONBARE_KR_NEXT)
#define LEONBARE_STACKALIGN(sp) ((((unsigned int)sp) + 7) & ~7)
/* context switching macros, implemented via setjmp/longjmp plus saving errno */
#define SAVE_CONTEXT(t) ( _leonbare_kernel_savecontext((t), 0) )
#define RESTORE_CONTEXT(t) _leonbare_kernel_switchto((t), 1)
#define KERNEL_SCHEDULE(f,retval) \
MACRO_BEGIN \
LEONBARE_KR_IS_IN_KERNEL--; \
if (LEONBARE_KR_IS_IN_KERNEL == 0 && LEONBARE_KR_NEED_SCHEDULE) { \
LEONBARE_KR_IS_IN_KERNEL++; \
if ((f) && (SAVE_CONTEXT(LEONBARE_KR_CURRENT) == 0)) { \
leonbare_sched(); \
} \
optbarrier(); \
LEONBARE_KR_IS_IN_KERNEL--; \
} \
MACRO_END
#define KERNEL_ENTER LEONBARE_KR_IS_IN_KERNEL++;
#define KERNEL_EXIT(f,ret) KERNEL_SCHEDULE(f,ret)
int leonbare_thread_init ();
int leonbare_thread_create (struct leonbare_thread *thread, char *stack,
int stacksize);
int leonbare_sched_update ();
leonbare_thread_t leonbare_sched_paytime ();
void leonbare_sched_insert (struct leonbare_thread *thread, int head,
int prepare);
unsigned int leonbare_sched ();
unsigned int reschedule ();
unsigned int _leonbare_kernel_switchto (struct leonbare_thread *old,
struct leonbare_thread *new);
#define LEONBARE_STACK_DEFINE(n,size) unsigned char n[size] __attribute__((aligned(8)));
#define LEONBARE_STACK_SIZE_DEFAULT 1024*20
typedef struct leonbare_mutex
{
unsigned int mx_owner_cnt;
leonbare_thread_t mx_owner;
struct leonbare_thread_queue mx_threads;
LBTAILQ_ENTRY (leonbare_mutex) mx_allm;
LBTAILQ_ENTRY (leonbare_mutex) mx_locked;
} *leonbare_mutex_t;
#define LEONBARE_MUTEX_OWNER_GET(m) LEONBARE_KERNEL_GETU32(m->mx_owner)
#define LEONBARE_MUTEX_OWNER_SET(m,o) LEONBARE_KERNEL_SETU32(m->mx_owner,o)
#define LEONBARE_MUTEX_OWNER_CNT_GET(m) LEONBARE_KERNEL_GETU32(m->mx_owner_cnt)
#define LEONBARE_MUTEX_OWNER_CNT_SET(m,o) LEONBARE_KERNEL_SETU32(m->mx_owner_cnt,o)
#define LEONBARE_MUTEX_LOCK_TIMEOUT -1
#define LEONBARE_MUTEX_LOCK_OK 0
#define LEONBARE_MUTEX_LOCK_ERROR 1
#define LEONBARE_MUTEX_UNLOCK_OK 0
#define LEONBARE_MUTEX_UNLOCK_ERROR 1
#define LEONBARE_PROTECT_DECL(flags) unsigned long flags;
#define LEONBARE_PROTECT_KERNEL(flags) flags = leonbare_disable_traps();
#define LEONBARE_UNPROTECT_KERNEL(flags) leonbare_enable_traps(flags);
#define LEONBARE_PROTECT_MUTEX(flags,m) flags = leonbare_disable_traps();
#define LEONBARE_UNPROTECT_MUTEX(flags,m) leonbare_enable_traps(flags);
#else
#define LEONBARE_THREAD_CTX_STORE_LOCALS(base_reg) \
std %l0, [%base_reg + LEONBARE_THREAD_CTX_STACK_L0]; \
std %l2, [%base_reg + LEONBARE_THREAD_CTX_STACK_L2]; \
std %l4, [%base_reg + LEONBARE_THREAD_CTX_STACK_L4]; \
std %l6, [%base_reg + LEONBARE_THREAD_CTX_STACK_L6];
#define LEONBARE_THREAD_CTX_STORE_INS(base_reg) \
std %i0, [%base_reg + LEONBARE_THREAD_CTX_STACK_I0]; \
std %i2, [%base_reg + LEONBARE_THREAD_CTX_STACK_I2]; \
std %i4, [%base_reg + LEONBARE_THREAD_CTX_STACK_I4]; \
std %i6, [%base_reg + LEONBARE_THREAD_CTX_STACK_I6];
#define LEONBARE_THREAD_CTX_STORE_OUTS(base_reg) \
std %o0, [%base_reg + LEONBARE_THREAD_CTX_STACK_O0]; \
std %o2, [%base_reg + LEONBARE_THREAD_CTX_STACK_O2]; \
std %o4, [%base_reg + LEONBARE_THREAD_CTX_STACK_O4]; \
std %o6, [%base_reg + LEONBARE_THREAD_CTX_STACK_O6];
#define LEONBARE_THREAD_CTX_STORE_GLOBALS(base_reg) \
st %g1, [%base_reg + LEONBARE_THREAD_CTX_STACK_G1]; \
std %g2, [%base_reg + LEONBARE_THREAD_CTX_STACK_G2]; \
std %g4, [%base_reg + LEONBARE_THREAD_CTX_STACK_G4]; \
std %g6, [%base_reg + LEONBARE_THREAD_CTX_STACK_G6];
#define LEONBARE_THREAD_CTX_LOAD_LOCALS(base_reg) \
ldd [%base_reg + LEONBARE_THREAD_CTX_STACK_L0], %l0; \
ldd [%base_reg + LEONBARE_THREAD_CTX_STACK_L2], %l2; \
ldd [%base_reg + LEONBARE_THREAD_CTX_STACK_L4], %l4; \
ldd [%base_reg + LEONBARE_THREAD_CTX_STACK_L6], %l6;
#define LEONBARE_THREAD_CTX_LOAD_INS(base_reg) \
ldd [%base_reg + LEONBARE_THREAD_CTX_STACK_I0], %i0; \
ldd [%base_reg + LEONBARE_THREAD_CTX_STACK_I2], %i2; \
ldd [%base_reg + LEONBARE_THREAD_CTX_STACK_I4], %i4; \
ldd [%base_reg + LEONBARE_THREAD_CTX_STACK_I6], %i6;
#define LEONBARE_THREAD_CTX_LOAD_OUTS(base_reg) \
ldd [%base_reg + LEONBARE_THREAD_CTX_STACK_O0], %o0; \
ldd [%base_reg + LEONBARE_THREAD_CTX_STACK_O2], %o2; \
ldd [%base_reg + LEONBARE_THREAD_CTX_STACK_O4], %o4; \
ldd [%base_reg + LEONBARE_THREAD_CTX_STACK_O6], %o6;
#define LEONBARE_THREAD_CTX_LOAD_GLOBALS(base_reg) \
ld [%base_reg + LEONBARE_THREAD_CTX_STACK_G1], %g1; \
ldd [%base_reg + LEONBARE_THREAD_CTX_STACK_G2], %g2; \
ldd [%base_reg + LEONBARE_THREAD_CTX_STACK_G4], %g4; \
ldd [%base_reg + LEONBARE_THREAD_CTX_STACK_G6], %g6;
#define LEONBARE_THREAD_CTX_STACK_L0 (0*8*4)
#define LEONBARE_THREAD_CTX_STACK_L2 (LEONBARE_THREAD_CTX_STACK_L0+(2*4))
#define LEONBARE_THREAD_CTX_STACK_L4 (LEONBARE_THREAD_CTX_STACK_L0+(4*4))
#define LEONBARE_THREAD_CTX_STACK_L6 (LEONBARE_THREAD_CTX_STACK_L0+(6*4))
#define LEONBARE_THREAD_CTX_STACK_I0 (1*8*4)
#define LEONBARE_THREAD_CTX_STACK_I2 (LEONBARE_THREAD_CTX_STACK_I0+(2*4))
#define LEONBARE_THREAD_CTX_STACK_I4 (LEONBARE_THREAD_CTX_STACK_I0+(4*4))
#define LEONBARE_THREAD_CTX_STACK_I6 (LEONBARE_THREAD_CTX_STACK_I0+(6*4))
#define LEONBARE_THREAD_CTX_STACK_O0 (2*8*4)
#define LEONBARE_THREAD_CTX_STACK_O2 (LEONBARE_THREAD_CTX_STACK_O0+(2*4))
#define LEONBARE_THREAD_CTX_STACK_O4 (LEONBARE_THREAD_CTX_STACK_O0+(4*4))
#define LEONBARE_THREAD_CTX_STACK_O6 (LEONBARE_THREAD_CTX_STACK_O0+(6*4))
#define LEONBARE_THREAD_CTX_STACK_G0 (3*8*4)
#define LEONBARE_THREAD_CTX_STACK_G1 (LEONBARE_THREAD_CTX_STACK_G0+(1*4))
#define LEONBARE_THREAD_CTX_STACK_G2 (LEONBARE_THREAD_CTX_STACK_G0+(2*4))
#define LEONBARE_THREAD_CTX_STACK_G4 (LEONBARE_THREAD_CTX_STACK_G0+(4*4))
#define LEONBARE_THREAD_CTX_STACK_G6 (LEONBARE_THREAD_CTX_STACK_G0+(6*4))
#define LEONBARE_THREAD_CTX_STACK_PSR (4*8*4)
#define LEONBARE_THREAD_CTX_STACK_WIM (LEONBARE_THREAD_CTX_STACK_PSR+4)
#define LEONBARE_THREAD_CTX_STACK_MAGIC (LEONBARE_THREAD_CTX_STACK_PSR+8)
#define LEONBARE_THREAD_CTX_STACK_FPU (LEONBARE_THREAD_CTX_STACK_PSR+12)
#define LEONBARE_THREAD_CTX_SZ (LEONBARE_THREAD_CTX_STACK_PSR+16)
#endif /* __ASSEMBLER__ */
# define LEONBARE_STOPALL \
LBDEBUG_HEADER_PRINTF(LBDEBUG_ALWAYS_NR,"Stopped at %s(%d), possibly not implemented yet\n",__FUNCTION__,__LINE__); \
_leonbare_Stop();
#define LEONBARE_THREAD_CTX_MAGIC 0x1234
#ifdef LBDEBUG_DO_ASSERT
#define LEONBARE_VERIFYIRQDISABLED() LBPASSERT(((leon23_getpsr() & SPARC_PSR_PIL_MASK) == SPARC_PSR_PIL_MASK),"Irq must be disabled (pil==0xf)\n",0)
#define LEONBARE_VERIFYSCHED() leonbare_sched_verify()
#else
#define LEONBARE_VERIFYIRQDISABLED()
#define LEONBARE_VERIFYSCHED()
#endif
#define LEONBARE_PRINTQUEUES() if (PDEBUG_FLAGS_CHECK(LBDEBUG_QUEUE_NR)) { leonbare_sched_printqueue(); }
#endif

View File

@ -0,0 +1,148 @@
//####BSDCOPYRIGHTBEGIN####
//
// -------------------------------------------
//
// Portions of this software may have been derived from OpenBSD,
// FreeBSD or other sources, and are covered by the appropriate
// copyright disclaimers included herein.
//
// Portions created by Red Hat are
// Copyright (C) 2002 Red Hat, Inc. All Rights Reserved.
//
// -------------------------------------------
//
//####BSDCOPYRIGHTEND####
//==========================================================================
/*
* Copyright (c) 1991, 1993
* The Regents of the University of California. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by the University of
* California, Berkeley and its contributors.
* 4. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE REGENTS 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 REGENTS 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.
*
* @(#)queue.h 8.5 (Berkeley) 8/20/94
* $FreeBSD: src/sys/sys/queue.h,v 1.32.2.4 2001/03/31 03:33:39 hsu Exp $
*/
#ifndef _SYS_LEONBARE_QUEUE_H_
#define _SYS_LEONBARE_QUEUE_H_
/*
* Tail queue definitions.
*/
#define LBTAILQ_HEAD(name, type) \
struct name { \
struct type *tqh_first; /* first element */ \
struct type **tqh_last; /* addr of last next element */ \
char *tqh_name; \
}
#define LBTAILQ_HEAD_INITIALIZER(head) \
{ NULL, &(head).tqh_first, 0 }
#define LBTAILQ_ENTRY(type) \
struct { \
struct type *tqe_next; /* next element */ \
struct type **tqe_prev; /* address of previous next element */ \
}
/*
* Tail queue functions.
*/
#define LBTAILQ_EMPTY(head) (LEONBARE_KERNEL_GETU32P((head)->tqh_first) == NULL)
#define LBTAILQ_HASTWO(head, field) ((!LBTAILQ_EMPTY(head)) && LBTAILQ_NEXT(LBTAILQ_FIRST(head),field))
#define LBTAILQ_FOREACH(var, head, field) \
for (var = LBTAILQ_FIRST(head); var; var = LBTAILQ_NEXT(var, field))
#define LBTAILQ_FIRST(head) LEONBARE_KERNEL_GETU32P_CAST((head)->tqh_first,__typeof((head)->tqh_first))
#define LBTAILQ_LAST(head, headname) \
LEONBARE_KERNEL_GETU32P_BARE(LEONBARE_KERNEL_GETU32P(((struct headname *)(LEONBARE_KERNEL_GETU32P((head)->tqh_last)))->tqh_last))
#define LBTAILQ_NEXT(elm, field) LEONBARE_KERNEL_GETU32P_CAST((elm)->field.tqe_next,__typeof((elm)->field.tqe_next))
#define LBTAILQ_PREV(elm, headname, field) \
LEONBARE_KERNEL_GETU32P_BARE(LEONBARE_KERNEL_GETU32P(((struct headname *)(LEONBARE_KERNEL_GETU32P((elm)->field.tqe_prev)))->tqh_last))
/* #define LBTAILQ_INIT(head) do { \ */
/* (head)->tqh_first = NULL; \ */
/* (head)->tqh_last = &(head)->tqh_first; \ */
/* (head)->tqh_name = 0; \ */
/* } while (0) */
#define LBTAILQ_INIT(head) do { \
LEONBARE_KERNEL_SETU32P((head)->tqh_first,NULL); \
LEONBARE_KERNEL_SETU32P((head)->tqh_last,&(head)->tqh_first); \
LEONBARE_KERNEL_SETU32P((head)->tqh_name,0); \
} while (0)
/* #define LBTAILQ_INSERT_HEAD(head, elm, field) do { \ */
/* if (((elm)->field.tqe_next = (head)->tqh_first) != NULL) \ */
/* (head)->tqh_first->field.tqe_prev = \ */
/* &(elm)->field.tqe_next; \ */
/* else \ */
/* (head)->tqh_last = &(elm)->field.tqe_next; \ */
/* (head)->tqh_first = (elm); \ */
/* (elm)->field.tqe_prev = &(head)->tqh_first; \ */
/* } while (0) */
#define LBTAILQ_INSERT_HEAD(head, elm, field) do { \
if ((LEONBARE_KERNEL_SETU32P((elm)->field.tqe_next,LEONBARE_KERNEL_GETU32P((head)->tqh_first))) != NULL) \
LEONBARE_KERNEL_SETU32P(LEONBARE_KERNEL_GETU32P_CAST((head)->tqh_first,__typeof ((head)->tqh_first))->field.tqe_prev,&(elm)->field.tqe_next); \
else \
LEONBARE_KERNEL_SETU32P((head)->tqh_last,&(elm)->field.tqe_next); \
LEONBARE_KERNEL_SETU32P((head)->tqh_first,(elm)); \
LEONBARE_KERNEL_SETU32P((elm)->field.tqe_prev,&(head)->tqh_first); \
} while (0)
#define LBTAILQ_INSERT_TAIL(head, elm, field) do { \
LEONBARE_KERNEL_SETU32P((elm)->field.tqe_next,NULL); \
LEONBARE_KERNEL_SETU32P((elm)->field.tqe_prev,LEONBARE_KERNEL_GETU32P((head)->tqh_last)); \
LEONBARE_KERNEL_SETU32P_BARE(LEONBARE_KERNEL_GETU32P((head)->tqh_last),(elm)); \
LEONBARE_KERNEL_SETU32P((head)->tqh_last,&(elm)->field.tqe_next); \
} while (0)
#define LBTAILQ_REMOVE(head, elm, field) do { \
if (LEONBARE_KERNEL_GETU32P((elm)->field.tqe_next) != NULL) \
LEONBARE_KERNEL_SETU32P(LEONBARE_KERNEL_GETU32P_CAST((elm)->field.tqe_next, __typeof((elm)->field.tqe_next))->field.tqe_prev, LEONBARE_KERNEL_GETU32P((elm)->field.tqe_prev)); \
else \
LEONBARE_KERNEL_SETU32P((head)->tqh_last, LEONBARE_KERNEL_GETU32P((elm)->field.tqe_prev)); \
LEONBARE_KERNEL_SETU32P_BARE(LEONBARE_KERNEL_GETU32P((elm)->field.tqe_prev),LEONBARE_KERNEL_GETU32P((elm)->field.tqe_next)); \
LEONBARE_KERNEL_SETU32P((elm)->field.tqe_next, 0); \
LEONBARE_KERNEL_SETU32P((elm)->field.tqe_prev, 0); /* mark removed */ \
} while (0)
#define LBTAILQ_REMOVED(elm, field) (LEONBARE_KERNEL_GETU32P((elm)->field.tqe_next) == NULL && LEONBARE_KERNEL_GETU32P((elm)->field.tqe_prev) == NULL)
#endif /* !_SYS_QUEUE_H_ */

View File

@ -0,0 +1,39 @@
/*
* Copyright (c) 2011 Aeroflex Gaisler
*
* BSD license:
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
#ifndef _INCLUDE_LEONCOMPAT_h
#define _INCLUDE_LEONCOMPAT_h
#include <asm-leon/leon.h>
#ifndef __ASSEMBLER__
#define LEONCOMPAT_VERSION _leon_version
#define LEONCOMPAT_VERSION_ISLEON3 (LEONCOMPAT_VERSION == 3)
extern int _leon_version;
#endif /* __ASSEMBLER__ */
#endif /* !_INCLUDE_LEONCOMPAT_h */

View File

@ -0,0 +1,33 @@
/*
* Copyright (c) 2011 Aeroflex Gaisler
*
* BSD license:
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
#ifndef _ASMSPARC_LEONDBG_H
#define _ASMSPARC_LEONDBG_H
#ifndef __ASSEMBLER__
extern int dbgleon_printf (const char *fmt, ...);
#endif
#endif

View File

@ -0,0 +1,177 @@
/*
* Copyright (c) 2011 Aeroflex Gaisler
*
* BSD license:
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
#ifndef _INCLUDE_LEON_STACK_h
#define _INCLUDE_LEON_STACK_h
#ifndef __ASSEMBLER__
#ifdef __cplusplus
extern "C"
{
#endif
/* process trap regs */
struct leonbare_pt_regs
{
unsigned long psr;
unsigned long pc;
unsigned long npc;
unsigned long y;
unsigned long u_regs[16]; /* globals and ins */
};
#define PT_REGS_SZ sizeof(struct leonbare_pt_regs)
/* A Sparc stack frame */
struct sparc_stackframe_regs
{
unsigned long sf_locals[8];
unsigned long sf_ins[6];
struct sparc_stackframe_regs *sf_fp;
unsigned long sf_callers_pc;
char *sf_structptr;
unsigned long sf_xargs[6];
unsigned long sf_xxargs[1];
};
#define SF_REGS_SZ sizeof(struct sparc_stackframe_regs)
/* A register window */
struct sparc_regwindow_regs
{
unsigned long locals[8];
unsigned long ins[8];
};
#define RW_REGS_SZ sizeof(struct sparc_regwindow_regs)
/* A fpu window */
struct sparc_fpuwindow_regs
{
unsigned long locals[32];
unsigned long fsr;
unsigned long dummy;
unsigned long irqpsr;
unsigned long lastctx;
};
#define FW_REGS_SZ sizeof(struct sparc_fpuwindow_regs)
#ifdef __cplusplus
}
#endif
#else
#define PT_REGS_SZ 0x50 /* 20*4 */
#define SF_REGS_SZ 0x60 /* 24*4 */
#define RW_REGS_SZ 0x20 /* 16*4 */
#define FW_REGS_SZ 0x90 /* 36*4 */
#endif /* !ASM */
/* These are for pt_regs. */
#define PT_PSR 0x0
#define PT_PC 0x4
#define PT_NPC 0x8
#define PT_Y 0xc
#define PT_G0 0x10
#define PT_WIM PT_G0
#define PT_G1 0x14
#define PT_G2 0x18
#define PT_G3 0x1c
#define PT_G4 0x20
#define PT_G5 0x24
#define PT_G6 0x28
#define PT_G7 0x2c
#define PT_I0 0x30
#define PT_I1 0x34
#define PT_I2 0x38
#define PT_I3 0x3c
#define PT_I4 0x40
#define PT_I5 0x44
#define PT_I6 0x48
#define PT_FP PT_I6
#define PT_I7 0x4c
/* Stack_frame offsets */
#define SF_L0 0x00
#define SF_L1 0x04
#define SF_L2 0x08
#define SF_L3 0x0c
#define SF_L4 0x10
#define SF_L5 0x14
#define SF_L6 0x18
#define SF_L7 0x1c
#define SF_I0 0x20
#define SF_I1 0x24
#define SF_I2 0x28
#define SF_I3 0x2c
#define SF_I4 0x30
#define SF_I5 0x34
#define SF_FP 0x38
#define SF_PC 0x3c
#define SF_RETP 0x40
#define SF_XARG0 0x44
#define SF_XARG1 0x48
#define SF_XARG2 0x4c
#define SF_XARG3 0x50
#define SF_XARG4 0x54
#define SF_XARG5 0x58
#define SF_XXARG 0x5c
/* Reg_window offsets */
#define RW_L0 0x00
#define RW_L1 0x04
#define RW_L2 0x08
#define RW_L3 0x0c
#define RW_L4 0x10
#define RW_L5 0x14
#define RW_L6 0x18
#define RW_L7 0x1c
#define RW_I0 0x20
#define RW_I1 0x24
#define RW_I2 0x28
#define RW_I3 0x2c
#define RW_I4 0x30
#define RW_I5 0x34
#define RW_I6 0x38
#define RW_I7 0x3c
/* Fpu_window offsets */
#define FW_F0 0x00
#define FW_F2 0x08
#define FW_F4 0x10
#define FW_F6 0x18
#define FW_F8 0x20
#define FW_F10 0x28
#define FW_F12 0x30
#define FW_F14 0x38
#define FW_F16 0x40
#define FW_F18 0x48
#define FW_F20 0x50
#define FW_F22 0x58
#define FW_F24 0x60
#define FW_F26 0x68
#define FW_F28 0x70
#define FW_F30 0x78
#define FW_FSR 0x80
#endif /* !_INCLUDE_LEON_STACK_h */

View File

@ -0,0 +1,40 @@
/*
* Copyright (c) 2011 Aeroflex Gaisler
*
* BSD license:
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
#ifndef __LEONBARE_LIBLOCKS_H
#define __LEONBARE_LIBLOCKS_H
extern int (*__lbst_pthread_mutex_init) (pthread_mutex_t * __mutex,
pthread_mutexattr_t * __mutex_attr);
extern int (*__lbst_pthread_mutex_destroy) (pthread_mutex_t * __mutex);
extern int (*__lbst_pthread_mutex_trylock) (pthread_mutex_t * __mutex);
extern int (*__lbst_pthread_mutex_lock) (pthread_mutex_t * __mutex);
extern int (*__lbst_pthread_mutex_unlock) (pthread_mutex_t * __mutex);
extern int (*__lbst_pthread_mutexattr_init) (pthread_mutexattr_t * __attr);
extern int (*__lbst_pthread_mutexattr_destroy) (pthread_mutexattr_t * __attr);
extern int (*__lbst_pthread_mutexattr_settype) (pthread_mutexattr_t * __attr,
int __kind);
#endif /* __LEONBARE_LIBLOCKS_H */

View File

@ -0,0 +1,59 @@
/*
* Copyright (c) 2011 Aeroflex Gaisler
*
* BSD license:
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
#ifndef H_LEONBARE_LINKAGE_H
#define H_LEONBARE_LINKAGE_H
#ifndef _ASM
# define __inline__ __inline__ __attribute__((always_inline))
#define likely(x) __builtin_expect(!!(x), 1)
#define unlikely(x) __builtin_expect(!!(x), 0)
#define barrier() __memory_barrier()
#define gccalign8 __attribute__((aligned(8)))
#else /* !_ASM */
#define MCOUNT_SIZE 0 /* no instructions inserted */
#define MCOUNT(x)
/*
* ENTRY provides the standard procedure entry code and an easy way to
* insert the calls to mcount for profiling. ENTRY_NP is identical, but
* never calls mcount.
*/
#define ENTRY(x) \
.section ".text"; \
.align 4; \
.global x; \
.type x, #function; \
x: MCOUNT(x)
#define ENTRY_SIZE MCOUNT_SIZE
#endif /* _ASM */
#endif

View File

@ -0,0 +1,33 @@
/*
* Copyright (c) 2011 Aeroflex Gaisler
*
* BSD license:
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
#ifndef _LEON_ASMSPARC_PARAM_H
#define _LEON_ASMSPARC_PARAM_H
/* note: this is also defined in machine/param.h */
#define HZ 100UL /* Internal kernel timer frequency */
#define CLOCK_TICK_RATE 1000000UL /* Underlying HZ */
#endif

View File

@ -0,0 +1,570 @@
//####BSDCOPYRIGHTBEGIN####
//
// -------------------------------------------
//
// Portions of this software may have been derived from OpenBSD,
// FreeBSD or other sources, and are covered by the appropriate
// copyright disclaimers included herein.
//
// Portions created by Red Hat are
// Copyright (C) 2002 Red Hat, Inc. All Rights Reserved.
//
// -------------------------------------------
//
//####BSDCOPYRIGHTEND####
//==========================================================================
/*
* Copyright (c) 1991, 1993
* The Regents of the University of California. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by the University of
* California, Berkeley and its contributors.
* 4. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE REGENTS 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 REGENTS 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.
*
* @(#)queue.h 8.5 (Berkeley) 8/20/94
* $FreeBSD: src/sys/sys/queue.h,v 1.32.2.4 2001/03/31 03:33:39 hsu Exp $
*/
#ifndef _SYS_QUEUE_H_
#define _SYS_QUEUE_H_
#ifndef __ASSEMBLER__
/*
* This file defines five types of data structures: singly-linked lists,
* singly-linked tail queues, lists, tail queues, and circular queues.
*
* A singly-linked list is headed by a single forward pointer. The elements
* are singly linked for minimum space and pointer manipulation overhead at
* the expense of O(n) removal for arbitrary elements. New elements can be
* added to the list after an existing element or at the head of the list.
* Elements being removed from the head of the list should use the explicit
* macro for this purpose for optimum efficiency. A singly-linked list may
* only be traversed in the forward direction. Singly-linked lists are ideal
* for applications with large datasets and few or no removals or for
* implementing a LIFO queue.
*
* A singly-linked tail queue is headed by a pair of pointers, one to the
* head of the list and the other to the tail of the list. The elements are
* singly linked for minimum space and pointer manipulation overhead at the
* expense of O(n) removal for arbitrary elements. New elements can be added
* to the list after an existing element, at the head of the list, or at the
* end of the list. Elements being removed from the head of the tail queue
* should use the explicit macro for this purpose for optimum efficiency.
* A singly-linked tail queue may only be traversed in the forward direction.
* Singly-linked tail queues are ideal for applications with large datasets
* and few or no removals or for implementing a FIFO queue.
*
* A list is headed by a single forward pointer (or an array of forward
* pointers for a hash table header). The elements are doubly linked
* so that an arbitrary element can be removed without a need to
* traverse the list. New elements can be added to the list before
* or after an existing element or at the head of the list. A list
* may only be traversed in the forward direction.
*
* A tail queue is headed by a pair of pointers, one to the head of the
* list and the other to the tail of the list. The elements are doubly
* linked so that an arbitrary element can be removed without a need to
* traverse the list. New elements can be added to the list before or
* after an existing element, at the head of the list, or at the end of
* the list. A tail queue may be traversed in either direction.
*
* A circle queue is headed by a pair of pointers, one to the head of the
* list and the other to the tail of the list. The elements are doubly
* linked so that an arbitrary element can be removed without a need to
* traverse the list. New elements can be added to the list before or after
* an existing element, at the head of the list, or at the end of the list.
* A circle queue may be traversed in either direction, but has a more
* complex end of list detection.
*
* For details on the use of these macros, see the queue(3) manual page.
*
*
* SLIST LIST STAILQ TAILQ CIRCLEQ
* _HEAD + + + + +
* _ENTRY + + + + +
* _INIT + + + + +
* _EMPTY + + + + +
* _FIRST + + + + +
* _NEXT + + + + +
* _PREV - - - + +
* _LAST - - + + +
* _FOREACH + + + + +
* _FOREACH_REVERSE - - - + +
* _INSERT_HEAD + + + + +
* _INSERT_BEFORE - + - + +
* _INSERT_AFTER + + + + +
* _INSERT_TAIL - - + + +
* _REMOVE_HEAD + - + - -
* _REMOVE + + + + +
*
*/
/*
* Singly-linked List definitions.
*/
#define SLIST_HEAD(name, type) \
struct name { \
struct type *slh_first; /* first element */ \
}
#define SLIST_HEAD_INITIALIZER(head) \
{ NULL }
#define SLIST_ENTRY(type) \
struct { \
struct type *sle_next; /* next element */ \
}
/*
* Singly-linked List functions.
*/
#define SLIST_EMPTY(head) ((head)->slh_first == NULL)
#define SLIST_FIRST(head) ((head)->slh_first)
#define SLIST_FOREACH(var, head, field) \
for((var) = (head)->slh_first; (var); (var) = (var)->field.sle_next)
#define SLIST_INIT(head) { \
(head)->slh_first = NULL; \
}
#define SLIST_INSERT_AFTER(slistelm, elm, field) do { \
(elm)->field.sle_next = (slistelm)->field.sle_next; \
(slistelm)->field.sle_next = (elm); \
} while (0)
#define SLIST_INSERT_HEAD(head, elm, field) do { \
(elm)->field.sle_next = (head)->slh_first; \
(head)->slh_first = (elm); \
} while (0)
#define SLIST_NEXT(elm, field) ((elm)->field.sle_next)
#define SLIST_REMOVE_HEAD(head, field) do { \
(head)->slh_first = (head)->slh_first->field.sle_next; \
} while (0)
#define SLIST_REMOVE(head, elm, type, field) do { \
if ((head)->slh_first == (elm)) { \
SLIST_REMOVE_HEAD((head), field); \
} \
else { \
struct type *curelm = (head)->slh_first; \
while( curelm->field.sle_next != (elm) ) \
curelm = curelm->field.sle_next; \
curelm->field.sle_next = \
curelm->field.sle_next->field.sle_next; \
} \
} while (0)
/*
* Singly-linked Tail queue definitions.
*/
#define STAILQ_HEAD(name, type) \
struct name { \
struct type *stqh_first;/* first element */ \
struct type **stqh_last;/* addr of last next element */ \
}
#define STAILQ_HEAD_INITIALIZER(head) \
{ NULL, &(head).stqh_first }
#define STAILQ_ENTRY(type) \
struct { \
struct type *stqe_next; /* next element */ \
}
/*
* Singly-linked Tail queue functions.
*/
#define STAILQ_EMPTY(head) ((head)->stqh_first == NULL)
#define STAILQ_INIT(head) do { \
(head)->stqh_first = NULL; \
(head)->stqh_last = &(head)->stqh_first; \
} while (0)
#define STAILQ_FIRST(head) ((head)->stqh_first)
#define STAILQ_LAST(head, type, field) \
(STAILQ_EMPTY(head) ? \
NULL : \
((struct type *) \
((char *)((head)->stqh_last) - __offsetof(struct type, field))))
#define STAILQ_FOREACH(var, head, field) \
for((var) = (head)->stqh_first; (var); (var) = (var)->field.stqe_next)
#define STAILQ_INSERT_HEAD(head, elm, field) do { \
if (((elm)->field.stqe_next = (head)->stqh_first) == NULL) \
(head)->stqh_last = &(elm)->field.stqe_next; \
(head)->stqh_first = (elm); \
} while (0)
#define STAILQ_INSERT_TAIL(head, elm, field) do { \
(elm)->field.stqe_next = NULL; \
*(head)->stqh_last = (elm); \
(head)->stqh_last = &(elm)->field.stqe_next; \
} while (0)
#define STAILQ_INSERT_AFTER(head, tqelm, elm, field) do { \
if (((elm)->field.stqe_next = (tqelm)->field.stqe_next) == NULL)\
(head)->stqh_last = &(elm)->field.stqe_next; \
(tqelm)->field.stqe_next = (elm); \
} while (0)
#define STAILQ_NEXT(elm, field) ((elm)->field.stqe_next)
#define STAILQ_REMOVE_HEAD(head, field) do { \
if (((head)->stqh_first = \
(head)->stqh_first->field.stqe_next) == NULL) \
(head)->stqh_last = &(head)->stqh_first; \
} while (0)
#define STAILQ_REMOVE_HEAD_UNTIL(head, elm, field) do { \
if (((head)->stqh_first = (elm)->field.stqe_next) == NULL) \
(head)->stqh_last = &(head)->stqh_first; \
} while (0)
#define STAILQ_REMOVE(head, elm, type, field) do { \
if ((head)->stqh_first == (elm)) { \
STAILQ_REMOVE_HEAD(head, field); \
} \
else { \
struct type *curelm = (head)->stqh_first; \
while( curelm->field.stqe_next != (elm) ) \
curelm = curelm->field.stqe_next; \
if((curelm->field.stqe_next = \
curelm->field.stqe_next->field.stqe_next) == NULL) \
(head)->stqh_last = &(curelm)->field.stqe_next; \
} \
} while (0)
/*
* List definitions.
*/
#define LIST_HEAD(name, type) \
struct name { \
struct type *lh_first; /* first element */ \
}
#define LIST_HEAD_INITIALIZER(head) \
{ NULL }
#define LIST_ENTRY(type) \
struct { \
struct type *le_next; /* next element */ \
struct type **le_prev; /* address of previous next element */ \
}
/*
* List functions.
*/
#define LIST_EMPTY(head) ((head)->lh_first == NULL)
#define LIST_FIRST(head) ((head)->lh_first)
#define LIST_FOREACH(var, head, field) \
for((var) = (head)->lh_first; (var); (var) = (var)->field.le_next)
#define LIST_INIT(head) do { \
(head)->lh_first = NULL; \
} while (0)
#define LIST_INSERT_AFTER(listelm, elm, field) do { \
if (((elm)->field.le_next = (listelm)->field.le_next) != NULL) \
(listelm)->field.le_next->field.le_prev = \
&(elm)->field.le_next; \
(listelm)->field.le_next = (elm); \
(elm)->field.le_prev = &(listelm)->field.le_next; \
} while (0)
#define LIST_INSERT_BEFORE(listelm, elm, field) do { \
(elm)->field.le_prev = (listelm)->field.le_prev; \
(elm)->field.le_next = (listelm); \
*(listelm)->field.le_prev = (elm); \
(listelm)->field.le_prev = &(elm)->field.le_next; \
} while (0)
#define LIST_INSERT_HEAD(head, elm, field) do { \
if (((elm)->field.le_next = (head)->lh_first) != NULL) \
(head)->lh_first->field.le_prev = &(elm)->field.le_next;\
(head)->lh_first = (elm); \
(elm)->field.le_prev = &(head)->lh_first; \
} while (0)
#define LIST_NEXT(elm, field) ((elm)->field.le_next)
#define LIST_REMOVE(elm, field) do { \
if ((elm)->field.le_next != NULL) \
(elm)->field.le_next->field.le_prev = \
(elm)->field.le_prev; \
*(elm)->field.le_prev = (elm)->field.le_next; \
} while (0)
/*
* Tail queue definitions.
*/
#define TAILQ_HEAD(name, type) \
struct name { \
struct type *tqh_first; /* first element */ \
struct type **tqh_last; /* addr of last next element */ \
char *tqh_name; \
}
#define TAILQ_HEAD_INITIALIZER(head) \
{ NULL, &(head).tqh_first, 0 }
#define TAILQ_ENTRY(type) \
struct { \
struct type *tqe_next; /* next element */ \
struct type **tqe_prev; /* address of previous next element */ \
}
/*
* Tail queue functions.
*/
#define TAILQ_EMPTY(head) ((head)->tqh_first == NULL)
#define TAILQ_HASTWO(head, field) ((!TAILQ_EMPTY(head)) && TAILQ_NEXT(TAILQ_FIRST(head),field))
#define TAILQ_FOREACH(var, head, field) \
for (var = TAILQ_FIRST(head); var; var = TAILQ_NEXT(var, field))
#define TAILQ_FOREACH_REVERSE(var, head, headname, field) \
for ((var) = TAILQ_LAST((head), headname); \
(var); \
(var) = TAILQ_PREV((var), headname, field))
#define TAILQ_FIRST(head) ((head)->tqh_first)
#define TAILQ_LAST(head, headname) \
(*(((struct headname *)((head)->tqh_last))->tqh_last))
#define TAILQ_NEXT(elm, field) ((elm)->field.tqe_next)
#define TAILQ_PREV(elm, headname, field) \
(*(((struct headname *)((elm)->field.tqe_prev))->tqh_last))
#define TAILQ_INIT(head) do { \
(head)->tqh_first = NULL; \
(head)->tqh_last = &(head)->tqh_first; \
(head)->tqh_name = 0; \
} while (0)
#define TAILQ_INSERT_HEAD(head, elm, field) do { \
if (((elm)->field.tqe_next = (head)->tqh_first) != NULL) \
(head)->tqh_first->field.tqe_prev = \
&(elm)->field.tqe_next; \
else \
(head)->tqh_last = &(elm)->field.tqe_next; \
(head)->tqh_first = (elm); \
(elm)->field.tqe_prev = &(head)->tqh_first; \
} while (0)
#define TAILQ_INSERT_TAIL(head, elm, field) do { \
(elm)->field.tqe_next = NULL; \
(elm)->field.tqe_prev = (head)->tqh_last; \
*(head)->tqh_last = (elm); \
(head)->tqh_last = &(elm)->field.tqe_next; \
} while (0)
#define TAILQ_INSERT_AFTER(head, listelm, elm, field) do { \
if (((elm)->field.tqe_next = (listelm)->field.tqe_next) != NULL)\
(elm)->field.tqe_next->field.tqe_prev = \
&(elm)->field.tqe_next; \
else \
(head)->tqh_last = &(elm)->field.tqe_next; \
(listelm)->field.tqe_next = (elm); \
(elm)->field.tqe_prev = &(listelm)->field.tqe_next; \
} while (0)
#define TAILQ_INSERT_BEFORE(listelm, elm, field) do { \
(elm)->field.tqe_prev = (listelm)->field.tqe_prev; \
(elm)->field.tqe_next = (listelm); \
*(listelm)->field.tqe_prev = (elm); \
(listelm)->field.tqe_prev = &(elm)->field.tqe_next; \
} while (0)
#define TAILQ_REMOVE(head, elm, field) do { \
if (((elm)->field.tqe_next) != NULL) \
(elm)->field.tqe_next->field.tqe_prev = \
(elm)->field.tqe_prev; \
else \
(head)->tqh_last = (elm)->field.tqe_prev; \
*(elm)->field.tqe_prev = (elm)->field.tqe_next; \
(elm)->field.tqe_next = 0; \
(elm)->field.tqe_prev = 0; /* mark removed */ \
} while (0)
#define TAILQ_REMOVED(elm, field) ((elm)->field.tqe_next == NULL && (elm)->field.tqe_prev == NULL)
/*
* Circular queue definitions.
*/
#define CIRCLEQ_HEAD(name, type) \
struct name { \
struct type *cqh_first; /* first element */ \
struct type *cqh_last; /* last element */ \
}
#define CIRCLEQ_ENTRY(type) \
struct { \
struct type *cqe_next; /* next element */ \
struct type *cqe_prev; /* previous element */ \
}
/*
* Circular queue functions.
*/
#define CIRCLEQ_EMPTY(head) ((head)->cqh_first == (void *)(head))
#define CIRCLEQ_FIRST(head) ((head)->cqh_first)
#define CIRCLEQ_FOREACH(var, head, field) \
for((var) = (head)->cqh_first; \
(var) != (void *)(head); \
(var) = (var)->field.cqe_next)
#define CIRCLEQ_FOREACH_REVERSE(var, head, field) \
for((var) = (head)->cqh_last; \
(var) != (void *)(head); \
(var) = (var)->field.cqe_prev)
#define CIRCLEQ_INIT(head) do { \
(head)->cqh_first = (void *)(head); \
(head)->cqh_last = (void *)(head); \
} while (0)
#define CIRCLEQ_INSERT_AFTER(head, listelm, elm, field) do { \
(elm)->field.cqe_next = (listelm)->field.cqe_next; \
(elm)->field.cqe_prev = (listelm); \
if ((listelm)->field.cqe_next == (void *)(head)) \
(head)->cqh_last = (elm); \
else \
(listelm)->field.cqe_next->field.cqe_prev = (elm); \
(listelm)->field.cqe_next = (elm); \
} while (0)
#define CIRCLEQ_INSERT_BEFORE(head, listelm, elm, field) do { \
(elm)->field.cqe_next = (listelm); \
(elm)->field.cqe_prev = (listelm)->field.cqe_prev; \
if ((listelm)->field.cqe_prev == (void *)(head)) \
(head)->cqh_first = (elm); \
else \
(listelm)->field.cqe_prev->field.cqe_next = (elm); \
(listelm)->field.cqe_prev = (elm); \
} while (0)
#define CIRCLEQ_INSERT_HEAD(head, elm, field) do { \
(elm)->field.cqe_next = (head)->cqh_first; \
(elm)->field.cqe_prev = (void *)(head); \
if ((head)->cqh_last == (void *)(head)) \
(head)->cqh_last = (elm); \
else \
(head)->cqh_first->field.cqe_prev = (elm); \
(head)->cqh_first = (elm); \
} while (0)
#define CIRCLEQ_INSERT_TAIL(head, elm, field) do { \
(elm)->field.cqe_next = (void *)(head); \
(elm)->field.cqe_prev = (head)->cqh_last; \
if ((head)->cqh_first == (void *)(head)) \
(head)->cqh_first = (elm); \
else \
(head)->cqh_last->field.cqe_next = (elm); \
(head)->cqh_last = (elm); \
} while (0)
#define CIRCLEQ_LAST(head) ((head)->cqh_last)
#define CIRCLEQ_NEXT(elm,field) ((elm)->field.cqe_next)
#define CIRCLEQ_PREV(elm,field) ((elm)->field.cqe_prev)
#define CIRCLEQ_REMOVE(head, elm, field) do { \
if ((elm)->field.cqe_next == (void *)(head)) \
(head)->cqh_last = (elm)->field.cqe_prev; \
else \
(elm)->field.cqe_next->field.cqe_prev = \
(elm)->field.cqe_prev; \
if ((elm)->field.cqe_prev == (void *)(head)) \
(head)->cqh_first = (elm)->field.cqe_next; \
else \
(elm)->field.cqe_prev->field.cqe_next = \
(elm)->field.cqe_next; \
} while (0)
/*
* XXX insque() and remque() are an old way of handling certain queues.
* They bogusly assumes that all queue heads look alike.
*/
struct quehead
{
struct quehead *qh_link;
struct quehead *qh_rlink;
};
#ifdef __GNUC__
static __inline void
insque (void *a, void *b)
{
struct quehead *element = a, *head = b;
element->qh_link = head->qh_link;
element->qh_rlink = head;
head->qh_link = element;
element->qh_link->qh_rlink = element;
}
static __inline void
remque (void *a)
{
struct quehead *element = a;
element->qh_link->qh_rlink = element->qh_rlink;
element->qh_rlink->qh_link = element->qh_link;
element->qh_rlink = 0;
}
#else /* !__GNUC__ */
void insque __P ((void *a, void *b));
void remque __P ((void *a));
#endif /* __GNUC__ */
#endif /* __ASSEMBLER__ */
#endif /* !_SYS_QUEUE_H_ */

View File

@ -0,0 +1,69 @@
/*
* Copyright (c) 2011 Aeroflex Gaisler
*
* BSD license:
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
#ifndef _INCLUDE_LEONSPINLOCK_h
#define _INCLUDE_LEONSPINLOCK_h
typedef struct
{
unsigned char lock;
} raw_spinlock_t;
#define __RAW_SPIN_LOCK_UNLOCKED { 0 }
typedef struct
{
volatile unsigned int lock;
} raw_rwlock_t;
#define __RAW_RW_LOCK_UNLOCKED { 0 }
static inline void
__raw_spin_lock (raw_spinlock_t * lock)
{
__asm__ __volatile__ ("\n1:\n\t" "ldstuba [%0]1, %%g2\n\t" /* ASI_LEON23_DCACHE_MISS */
"orcc %%g2, 0x0, %%g0\n\t" "bne,a 2f\n\t" " ldub [%0], %%g2\n\t" ".subsection 2\n" "2:\n\t" "orcc %%g2, 0x0, %%g0\n\t" "bne,a 2b\n\t" " ldub [%0], %%g2\n\t" "b,a 1b\n\t" ".previous\n": /* no outputs */
:"r" (lock):"g2", "memory", "cc");
}
static inline int
__raw_spin_trylock (raw_spinlock_t * lock)
{
unsigned int result;
__asm__ __volatile__ ("ldstuba [%1]1, %0" /* ASI_LEON23_DCACHE_MISS */
:"=r" (result):"r" (lock):"memory");
return (result == 0);
}
static inline void
__raw_spin_unlock (raw_spinlock_t * lock)
{
__asm__ __volatile__ ("stb %%g0, [%0]"::"r" (lock):"memory");
}
#endif /* _INCLUDE_LEONSPINLOCK_h */
/* end of include file */

View File

@ -0,0 +1,77 @@
/*
* Copyright (c) 2011 Aeroflex Gaisler
*
* BSD license:
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
#ifndef _SYS_STACK_H_
#define _SYS_STACK_H_
#if !defined(_ASM)
#include <sys/types.h>
#endif
#ifdef __cplusplus
extern "C"
{
#endif
/*
* A stack frame looks like:
*
* %fp->| |
* |-------------------------------|
* | Locals, temps, saved floats |
* |-------------------------------|
* | outgoing parameters past 6 |
* |-------------------------------|-\
* | 6 words for callee to dump | |
* | register arguments | |
* |-------------------------------| > minimum stack frame
* | One word struct-ret address | |
* |-------------------------------| |
* | 16 words to save IN and | |
* %sp->| LOCAL register on overflow | |
* |-------------------------------|-/
*/
/*
* Constants defining a 32-bit stack frame.
*/
#define WINDOWSIZE (16*4) /* size of window save area */
#define ARGPUSHSIZE (6*4) /* size of arg dump area */
#define ARGPUSH (WINDOWSIZE + 4) /* arg dump area offset */
#define MINFRAME (WINDOWSIZE + ARGPUSHSIZE + 4) /* min frame */
#define STACK_GROWTH_DOWN /* stacks grow from high to low addresses */
/*
* Stack alignment macros.
*/
#define STACK_ALIGN 8
#define SA(X) (((X)+(STACK_ALIGN-1)) & ~(STACK_ALIGN-1))
#ifdef __cplusplus
}
#endif
#endif /* _SYS_STACK_H */

View File

@ -0,0 +1,33 @@
/*
* Copyright (c) 2011 Aeroflex Gaisler
*
* BSD license:
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
#ifndef _ASMSPARC_TIME_H
#define _ASMSPARC_TIME_H
extern struct timespec xtime;
extern unsigned long tick_nsec; /* nsec per tick (resolution) */
extern unsigned long nodotimer;
#endif

View File

@ -0,0 +1,75 @@
/*
* Copyright (c) 2011 Aeroflex Gaisler
*
* BSD license:
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
#ifndef _ASMSPARC_TIMER_H
#define _ASMSPARC_TIMER_H
#include <asm-leon/queue.h>
/*#include <sys/fsu_pthread_queue.h>*/
#include <sys/time.h>
#include <asm-leon/clock.h>
#ifndef __ASSEMBLER__
typedef int (*timerevent_handler) (void *);
struct timerevent
{
TAILQ_ENTRY (timerevent) n;
struct timespec expire;
timerevent_handler handler;
void *arg;
};
#endif
#define GT_TIMESPEC(t1, t2) \
(t1.tv_sec > t2.tv_sec || \
(t1.tv_sec == t2.tv_sec && \
t1.tv_nsec > t2.tv_nsec))
#define GT_TIMEVAL(t1, t2) \
(t1.tv_sec > t2.tv_sec || \
(t1.tv_sec == t2.tv_sec && \
t1.tv_usec > t2.tv_usec))
/*
* MINUS_TIME only works if src1 > src2
*/
#define MINUS_TIMEVAL(dst, src1, src2) \
if ((src2).tv_usec > (src1).tv_usec) { \
(dst).tv_sec = (src1).tv_sec - (src2).tv_sec - 1; \
(dst).tv_usec = ((src1).tv_usec - (src2).tv_usec) + USEC_PER_SEC; \
} \
else { \
(dst).tv_sec = (src1).tv_sec - (src2).tv_sec; \
(dst).tv_usec = (src1).tv_usec - (src2).tv_usec; \
}
/* Protypes */
#ifndef __ASSEMBLER__
void leonbare_init_ticks ();
int addtimer (struct timerevent *e);
#endif
#endif

View File

@ -0,0 +1,31 @@
/*
* Copyright (c) 2011 Aeroflex Gaisler
*
* BSD license:
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
#ifndef H_LEONBARE_TYPES_H
#define H_LEONBARE_TYPES_H
typedef unsigned long long u64;
#endif

View File

@ -0,0 +1,185 @@
/*
* Copyright (c) 2011 Aeroflex Gaisler
*
* BSD license:
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
#include <asm-leon/leon.h>
#include <asm-leon/leonstack.h>
#include <asm-leon/asmmacro.h>
/* Store the register window onto the 8-byte aligned area starting
* at %reg. It might be %sp, it might not, we don't care.
*/
#define RW_STORE(reg) \
std %l0, [%reg + RW_L0]; \
std %l2, [%reg + RW_L2]; \
std %l4, [%reg + RW_L4]; \
std %l6, [%reg + RW_L6]; \
std %i0, [%reg + RW_I0]; \
std %i2, [%reg + RW_I2]; \
std %i4, [%reg + RW_I4]; \
std %i6, [%reg + RW_I6];
/* Load a register window from the area beginning at %reg. */
#define RW_LOAD(reg) \
ldd [%reg + RW_L0], %l0; \
ldd [%reg + RW_L2], %l2; \
ldd [%reg + RW_L4], %l4; \
ldd [%reg + RW_L6], %l6; \
ldd [%reg + RW_I0], %i0; \
ldd [%reg + RW_I2], %i2; \
ldd [%reg + RW_I4], %i4; \
ldd [%reg + RW_I6], %i6;
/* Loading and storing struct pt_reg trap frames. */
#define PT_LOAD_INS(base_reg) \
ldd [%base_reg + SF_REGS_SZ + PT_I0], %i0; \
ldd [%base_reg + SF_REGS_SZ + PT_I2], %i2; \
ldd [%base_reg + SF_REGS_SZ + PT_I4], %i4; \
ldd [%base_reg + SF_REGS_SZ + PT_I6], %i6;
#define PT_LOAD_GLOBALS(base_reg) \
ld [%base_reg + SF_REGS_SZ + PT_G1], %g1; \
ldd [%base_reg + SF_REGS_SZ + PT_G2], %g2; \
ldd [%base_reg + SF_REGS_SZ + PT_G4], %g4; \
ldd [%base_reg + SF_REGS_SZ + PT_G6], %g6;
#define PT_LOAD_GLOBALS_23(base_reg) \
ldd [%base_reg + SF_REGS_SZ + PT_G2], %g2;
#define PT_LOAD_YREG(base_reg, scratch) \
ld [%base_reg + SF_REGS_SZ + PT_Y], %scratch; \
wr %scratch, 0x0, %y;
#define PT_LOAD_PRIV(base_reg, pt_psr, pt_pc, pt_npc) \
ld [%base_reg + SF_REGS_SZ + PT_PSR], %pt_psr; \
ld [%base_reg + SF_REGS_SZ + PT_PC], %pt_pc; \
ld [%base_reg + SF_REGS_SZ + PT_NPC], %pt_npc;
#define PT_LOAD_ALL(base_reg, pt_psr, pt_pc, pt_npc, scratch) \
PT_LOAD_YREG(base_reg, scratch) \
PT_LOAD_INS(base_reg) \
PT_LOAD_GLOBALS(base_reg) \
PT_LOAD_PRIV(base_reg, pt_psr, pt_pc, pt_npc)
#define PT_LOAD_ALL_FAST(base_reg, pt_psr, pt_pc, pt_npc, scratch) \
PT_LOAD_YREG(base_reg, scratch) \
PT_LOAD_GLOBALS(base_reg)
#define PT_STORE_INS(base_reg) \
std %i0, [%base_reg + SF_REGS_SZ + PT_I0]; \
std %i2, [%base_reg + SF_REGS_SZ + PT_I2]; \
std %i4, [%base_reg + SF_REGS_SZ + PT_I4]; \
std %i6, [%base_reg + SF_REGS_SZ + PT_I6];
#define PT_STORE_GLOBALS(base_reg) \
st %g1, [%base_reg + SF_REGS_SZ + PT_G1]; \
std %g2, [%base_reg + SF_REGS_SZ + PT_G2]; \
std %g4, [%base_reg + SF_REGS_SZ + PT_G4]; \
std %g6, [%base_reg + SF_REGS_SZ + PT_G6];
#define PT_STORE_GLOBALS_23(base_reg) \
std %g2, [%base_reg + SF_REGS_SZ + PT_G2];
#define PT_STORE_YREG(base_reg, scratch) \
rd %y, %scratch; \
st %scratch, [%base_reg + SF_REGS_SZ + PT_Y];
#define PT_STORE_PRIV(base_reg, pt_psr, pt_pc, pt_npc) \
st %pt_psr, [%base_reg + SF_REGS_SZ + PT_PSR]; \
st %pt_pc, [%base_reg + SF_REGS_SZ + PT_PC]; \
st %pt_npc, [%base_reg + SF_REGS_SZ + PT_NPC];
#define PT_STORE_ALL(base_reg, reg_psr, reg_pc, reg_npc, g_scratch) \
PT_STORE_PRIV(base_reg, reg_psr, reg_pc, reg_npc) \
PT_STORE_GLOBALS(base_reg) \
PT_STORE_YREG(base_reg, g_scratch) \
PT_STORE_INS(base_reg)
#define PT_STORE_ALL_FAST(base_reg, reg_psr, reg_pc, reg_npc, g_scratch) \
PT_STORE_GLOBALS(base_reg) \
PT_STORE_YREG(base_reg, g_scratch)
/* Store the fpu register window*/
#define FW_STORE(reg) \
std %f0, [reg + FW_F0]; \
std %f2, [reg + FW_F2]; \
std %f4, [reg + FW_F4]; \
std %f6, [reg + FW_F6]; \
std %f8, [reg + FW_F8]; \
std %f10, [reg + FW_F10]; \
std %f12, [reg + FW_F12]; \
std %f14, [reg + FW_F14]; \
std %f16, [reg + FW_F16]; \
std %f18, [reg + FW_F18]; \
std %f20, [reg + FW_F20]; \
std %f22, [reg + FW_F22]; \
std %f24, [reg + FW_F24]; \
std %f26, [reg + FW_F26]; \
std %f28, [reg + FW_F28]; \
std %f30, [reg + FW_F30]; \
st %fsr, [reg + FW_FSR];
/* Load a fpu register window from the area beginning at reg. */
#define FW_LOAD(reg) \
ldd [reg + FW_F0], %f0; \
ldd [reg + FW_F2], %f2; \
ldd [reg + FW_F4], %f4; \
ldd [reg + FW_F6], %f6; \
ldd [reg + FW_F8], %f8; \
ldd [reg + FW_F10], %f10; \
ldd [reg + FW_F12], %f12; \
ldd [reg + FW_F14], %f14; \
ldd [reg + FW_F16], %f16; \
ldd [reg + FW_F18], %f18; \
ldd [reg + FW_F20], %f20; \
ldd [reg + FW_F22], %f22; \
ldd [reg + FW_F24], %f24; \
ldd [reg + FW_F26], %f26; \
ldd [reg + FW_F28], %f28; \
ldd [reg + FW_F30], %f30; \
ld [reg + FW_FSR], %fsr;
#define SET_WIM_CWPMIN2(psr_reg,tmp1,tmp2,tmp3,tmp4) \
sethi %hi(_nwindows_min2), %##tmp1; \
and %##psr_reg, SPARC_PSR_WIN_MASK, %##tmp3; \
mov 1, %##tmp2; \
ld [ %##tmp1 + %lo(_nwindows_min2)], %##tmp1; \
sll %##tmp2, %##tmp3, %##tmp3; \
sll %##tmp3, 2, %##tmp4; \
srl %##tmp3, %##tmp1, %##tmp1; \
or %##tmp4, %##tmp1, %##tmp3; \
wr %##tmp3, 0x0, %wim; \
nop; nop; nop;
#define SET_WIM_CWPMIN1(psr_reg,tmp1,tmp2,tmp3,tmp4) \
sethi %hi(_nwindows_min1), %##tmp1; \
and %##psr_reg, SPARC_PSR_WIN_MASK, %##tmp3; \
mov 1, %##tmp2; \
ld [ %##tmp1 + %lo(_nwindows_min1)], %##tmp1; \
sll %##tmp2, %##tmp3, %##tmp3; \
sll %##tmp3, 1, %##tmp4; \
srl %##tmp3, %##tmp1, %##tmp1; \
or %##tmp4, %##tmp1, %##tmp3; \
wr %##tmp3, 0x0, %wim; \
nop; nop; nop;

View File

@ -0,0 +1,53 @@
/*
* Copyright (c) 2011 Aeroflex Gaisler
*
* BSD license:
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
.section .text
/* ------- */
.weak bdinit1
.set bdinit1,__bdinit1
/* ------- */
__bdinit1:
retl
nop
.section .text
/* ------- */
.weak bdinit2
.set bdinit2,__bdinit2
/* ------- */
__bdinit2:
retl
nop
.section .text
/* ------- */
.weak prelibchook
.set prelibchook,__prelibchook
/* ------- */
__prelibchook:
retl
nop

View File

@ -0,0 +1,148 @@
/*
* Copyright (c) 2011 Aeroflex Gaisler
*
* BSD license:
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
!unsigned int ahbslv_scan(register unsigned int vendor,register unsigned int driver) {
! register unsigned int conf, mbar,i, *confp;
! register unsigned int cfg_area = (unsigned int ) (LEON3_IO_AREA | LEON3_CONF_AREA | LEON3_AHB_SLAVE_CONF_AREA);
! for (i = 0; i < LEON3_AHB_SLAVES; i++)
! {
! confp = (unsigned int*)(cfg_area + (i * LEON3_AHB_CONF_WORDS * 4));
! conf = *confp;
! //mbar = *(unsigned int*)(i * LEON3_AHB_CONF_WORDS+ (4 * 4));
! if ((amba_vendor(conf) == vendor) && (amba_device(conf) == driver)) {
! return (unsigned int)confp;
! }
! }
! return 0;
!}
.section ".text"
.global ahbslv_scan
.align 4
ahbslv_scan:
mov %o0, %g1
mov -2048, %o5
mov 0, %o3
sll %o3, 5, %o0
.LL11:
add %o5, %o0, %o4
ld [%o5+%o0], %o2
srl %o2, 24, %o0
cmp %o0, %g1
bne,a .LL10
add %o3, 1, %o3
srl %o2, 12, %o0
and %o0, 4095, %o0
cmp %o0, %o1
be .LL1
mov %o4, %o2
add %o3, 1, %o3
.LL10:
cmp %o3, 7
bleu,a .LL11
sll %o3, 5, %o0
mov 0, %o2
.LL1:
retl
mov %o2, %o0
!unsigned int apbslv_scan(register unsigned int base,register unsigned int vendor, register unsigned int driver) {
! register unsigned int conf, mbar,i, *confp;
! for (i = 0; i < LEON3_APB_SLAVES; i++)
! {
! confp = (unsigned int*)(base + (i * LEON3_APB_CONF_WORDS * 4));
! conf = *confp;
! //mbar = *(unsigned int*)(i * LEON3_AHB_CONF_WORDS+ (4 * 4));
! if ((amba_vendor(conf) == vendor) && (amba_device(conf) == driver)) {
! return (unsigned int)confp;
! }
! }
! return 0;
!}
.section ".text"
.align 4
.global apbslv_scan
apbslv_scan:
mov %o0, %g1
mov 0, %o4
sll %o4, 3, %o0
.LL22:
add %g1, %o0, %o5
ld [%g1+%o0], %o3
srl %o3, 24, %o0
cmp %o0, %o1
bne,a .LL21
add %o4, 1, %o4
srl %o3, 12, %o0
and %o0, 4095, %o0
cmp %o0, %o2
be .LL12
mov %o5, %o3
add %o4, 1, %o4
.LL21:
cmp %o4, 15
bleu,a .LL22
sll %o4, 3, %o0
mov 0, %o3
.LL12:
retl
mov %o3, %o0
!unsigned int getbase(register unsigned int *mbar,register unsigned int iobase) {
! register unsigned int conf = mbar[1];
! return ((iobase & 0xfff00000) |
! ((conf & 0xfff00000)>> 12)) & (((conf & 0x0000fff0) <<4) | 0xfff00000);
!
!}
.section ".text"
.align 4
.global iobar_getbase
iobar_getbase:
ld [%o0+4], %o2
sethi %hi(-1048576), %o3
and %o1, %o3, %o1
and %o2, %o3, %o0
srl %o0, 12, %o0
or %o1, %o0, %o1
sethi %hi(64512), %o0
or %o0, 1008, %o0
and %o2, %o0, %o2
sll %o2, 4, %o2
or %o2, %o3, %o2
and %o1, %o2, %o1
retl
mov %o1, %o0

View File

@ -0,0 +1,51 @@
/*
* Copyright (c) 2011 Aeroflex Gaisler
*
* BSD license:
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
#include <asm-leon/leon.h>
#include <asm-leon/leonstack.h>
.seg "data"
.global sparc_leon23_cache_flush, sparc_leon23_icache_flush, sparc_leon23_dcache_flush
.global _leon_version
.seg "text"
/* =============================================== */
/* use only %o7 */
sparc_leon23_icache_flush:
sparc_leon3_icache_flush:
retl
sparc_leon23_cache_flush:
sparc_leon3_cache_flush:
sta %g0, [%g0] ASI_LEON3_IFLUSH
sparc_leon23_dcache_flush:
sparc_leon3_dcache_flush:
retl
sta %g0, [%g0] ASI_LEON3_DFLUSH

View File

@ -0,0 +1,117 @@
/*
* Copyright (c) 2011 Aeroflex Gaisler
*
* BSD license:
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
#include <asm-leon/leonstack.h>
#include <asm-leon/irq.h>
#define NULL 0
struct irqaction *_irqtbl[32] =
{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0 };
struct irqaction _oirqtbl[32] =
{ INIT_IRQACTION, INIT_IRQACTION, INIT_IRQACTION, INIT_IRQACTION,
INIT_IRQACTION, INIT_IRQACTION, INIT_IRQACTION, INIT_IRQACTION,
INIT_IRQACTION, INIT_IRQACTION, INIT_IRQACTION, INIT_IRQACTION,
INIT_IRQACTION, INIT_IRQACTION, INIT_IRQACTION, INIT_IRQACTION,
INIT_IRQACTION, INIT_IRQACTION, INIT_IRQACTION, INIT_IRQACTION,
INIT_IRQACTION, INIT_IRQACTION, INIT_IRQACTION, INIT_IRQACTION,
INIT_IRQACTION, INIT_IRQACTION, INIT_IRQACTION, INIT_IRQACTION,
INIT_IRQACTION, INIT_IRQACTION, INIT_IRQACTION, INIT_IRQACTION
};
int
catch_interrupt (int func, int irq)
{
struct irqaction *a = _irqtbl[irq];
struct irqaction *n = &_oirqtbl[irq];
if (irq >= 32)
return 0;
while (a)
{
if (a == n)
{
int tmp = (int) a->handler;
a->handler = (irqhandler) func;
return tmp;
}
a = a->next;
}
n->handler = (irqhandler) func;
chained_catch_interrupt (irq, n);
return 0;
}
void
chained_catch_interrupt (int irq, struct irqaction *a)
{
a->next = _irqtbl[irq];
_irqtbl[irq] = a;
}
int no_inirq_check = 0;
int inirq[32] = { 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0
};
extern struct irqmp_type irqmp;
void (*handler_irq_pre) (void) = 0;
void (*handler_irq_post) (void) = 0;
handler_irq (int irq, struct leonbare_pt_regs *pt_regs)
{
struct irqaction *a;
if (irq == irqmp.eirq)
irq = irqmp.addr[48] & 0x1f;
if (!irq)
irq = irqmp.eirq;
a = _irqtbl[irq];
while (a)
{
if (a->handler)
{
#ifndef CONFIG_LEONBARE_NONESTEDIRQ
if (no_inirq_check || !(inirq[irq]))
{
#endif
inirq[irq]++;
if (handler_irq_pre)
handler_irq_pre ();
a->handler (irq, a->dev_id, pt_regs);
if (handler_irq_post)
handler_irq_post ();
inirq[irq]--;
#ifndef CONFIG_LEONBARE_NONESTEDIRQ
}
#endif
}
a = a->next;
}
}
schedulehandler schedule_callback = 0;

View File

@ -0,0 +1,55 @@
/*
* Copyright (c) 2011 Aeroflex Gaisler
*
* BSD license:
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
#include <asm-leon/leonstack.h>
#include <asm-leon/irq.h>
#define NULL 0
/* multi vector trapping version of trap handler installs */
int
mvtlolevelirqinstall (int irqnr, void (*handler) ())
{
unsigned long h = (unsigned long) handler;
unsigned long *addr =
(unsigned long *) ((locore_readtbr () & ~0xFFF) + 0x100 + (16 * irqnr));
if (irqnr == 0 || irqnr >= 15)
{
return 0;
}
addr[0] = ((h >> 10) & 0x3fffff) | 0x29000000; /* 29000000: sethi %hi(handler), %l4 */
addr[1] = ((h) & 0x3ff) | 0x81c52000; /* 81c52000: jmpl %l4 + %lo(handler), %g0 */
addr[2] = 0x01000000; /* 01000000: nop */
addr[3] = 0x01000000; /* 01000000: nop */
return 1;
}
int
lolevelirqinstall (int irqnr, void (*handler) ())
{
return mvtlolevelirqinstall (irqnr, handler);
}

View File

@ -0,0 +1,64 @@
/*
* Copyright (c) 2011 Aeroflex Gaisler
*
* BSD license:
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
#include <asm-leon/leonstack.h>
#include <asm-leon/irq.h>
#define NULL 0
TAILQ_HEAD (pending_queue, pendingaction) pending =
TAILQ_HEAD_INITIALIZER (pending);
void add_pending (struct pendingaction *a)
{
unsigned long old = leonbare_disable_traps ();
TAILQ_INSERT_TAIL (&pending, a, next);
leonbare_enable_traps (old);
}
struct pendingaction *
get_pending ()
{
struct pendingaction *a = 0;
unsigned long old = leonbare_disable_traps ();
if (a = TAILQ_FIRST (&pending))
{
TAILQ_REMOVE (&pending, a, next);
}
leonbare_enable_traps (old);
return a;
}
void
process_pending ()
{
struct pendingaction *a;
while (a = get_pending ())
{
if (a->handler)
{
a->handler (a->arg);
}
}
}

View File

@ -0,0 +1,76 @@
/*
* Copyright (c) 2011 Aeroflex Gaisler
*
* BSD license:
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
#include <asm-leon/leonstack.h>
#include <asm-leon/irq.h>
#define NULL 0
/* single vector trapping version of trap handler installs */
struct svt_trap_entry
{
int start, end, func;
};
extern struct svt_trap_entry trap_table[28];
extern struct svt_trap_entry svt_trap_table_ext[17];
extern struct svt_trap_entry svt_trap_table_ext_end;
static struct svt_trap_entry *
gettrap_pos (int nr)
{
struct svt_trap_entry *p = trap_table;
while ((p->start) || (p->end) || (p->func))
{
if (p->start <= nr && p->end >= nr)
{
break;
}
p++;
}
return p;
}
int
svtloleveltrapinstall (int trap, void (*handler) ())
{
struct svt_trap_entry *p = gettrap_pos (trap);
if (p >= &svt_trap_table_ext_end)
{
return 0;
}
p->start = trap;
p->end = trap;
p->func = handler;
return 1;
}
int
svtlolevelirqinstall (int irqnr, void (*handler) ())
{
if (irqnr == 0 || irqnr >= 15)
{
return 0;
}
return svtloleveltrapinstall (irqnr + 0x10, handler);
}

3877
libgloss/sparc_leon/configure vendored Executable file

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,58 @@
dnl Process this file with autoconf to produce a configure script.
AC_PREREQ(2.59)
AC_INIT(crt0.S)
if test "${enable_shared}" = "yes" ; then
echo "Shared libraries not supported for cross compiling, ignored"
fi
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
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

View File

@ -0,0 +1,29 @@
/*
* Copyright (c) 2011 Aeroflex Gaisler
*
* BSD license:
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
#include <stdlib.h>
#include <ctype.h>
int *console = (int *) 0x80000100;

View File

@ -0,0 +1,354 @@
/*
* Copyright (c) 2011 Aeroflex Gaisler
*
* BSD license:
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
#include <stdlib.h>
#include <ctype.h>
#ifdef _HAVE_STDC
#include <stdarg.h>
#else
#include <varargs.h>
#endif
#include <asm-leon/leoncompat.h>
#include <asm-leon/leon.h>
static size_t
lo_strnlen (const char *s, size_t count)
{
const char *sc;
for (sc = s; count-- && *sc != '\0'; ++sc)
/* nothing */ ;
return sc - s;
}
static int
lo_vsnprintf (char *buf, size_t size, const char *fmt, va_list args)
{
int len;
unsigned long long num;
int i, j, n;
char *str, *end, c;
const char *s;
int flags;
int field_width;
int precision;
int qualifier;
int filler;
str = buf;
end = buf + size - 1;
if (end < buf - 1)
{
end = ((void *) -1);
size = end - buf + 1;
}
for (; *fmt; ++fmt)
{
if (*fmt != '%')
{
if (*fmt == '\n')
{
if (str <= end)
{
*str = '\r';
}
str++;
}
if (str <= end)
*str = *fmt;
++str;
continue;
}
/* process flags */
flags = 0;
/* get field width */
field_width = 0;
/* get the precision */
precision = -1;
/* get the conversion qualifier */
qualifier = 'l';
filler = ' ';
++fmt;
if (*fmt == '0')
{
filler = '0';
++fmt;
}
while (isdigit (*fmt))
{
field_width = field_width * 10 + ((*fmt) - '0');
++fmt;
}
/* default base */
switch (*fmt)
{
case 'c':
c = (unsigned char) va_arg (args, int);
if (str <= end)
*str = c;
++str;
while (--field_width > 0)
{
if (str <= end)
*str = ' ';
++str;
}
continue;
case 's':
s = va_arg (args, char *);
if (!s)
s = "<NULL>";
len = lo_strnlen (s, precision);
for (i = 0; i < len; ++i)
{
if (str <= end)
*str = *s;
++str;
++s;
}
while (len < field_width--)
{
if (str <= end)
*str = ' ';
++str;
}
continue;
case '%':
if (str <= end)
*str = '%';
++str;
continue;
case 'x':
break;
case 'd':
break;
default:
if (str <= end)
*str = '%';
++str;
if (*fmt)
{
if (str <= end)
*str = *fmt;
++str;
}
else
{
--fmt;
}
continue;
}
num = va_arg (args, unsigned long);
if (*fmt == 'd')
{
j = 0;
while (num && str <= end)
{
*str = (num % 10) + '0';
num = num / 10;
++str;
j++;
}
/* flip */
for (i = 0; i < (j / 2); i++)
{
n = str[(-j) + i];
str[(-j) + i] = str[-(i + 1)];
str[-(i + 1)] = n;
}
/* shift */
if (field_width > j)
{
i = field_width - j;
for (n = 1; n <= j; n++)
{
if (str + i - n <= end)
{
str[i - n] = str[-n];
}
}
for (i--; i >= 0; i--)
{
str[i - j] = filler;
}
str += field_width - j;
j = 1;
}
}
else
{
for (j = 0, i = 0; i < 8 && str <= end; i++)
{
if ((n =
((unsigned long) (num & (0xf0000000ul >> (i * 4)))) >>
((7 - i) * 4)) || j != 0)
{
if (n >= 10)
n += 'a' - 10;
else
n += '0';
*str = n;
++str;
j++;
}
}
/* shift */
if (field_width > j)
{
i = field_width - j;
for (n = 1; n <= j; n++)
{
if (str + i - n <= end)
{
str[i - n] = str[-n];
}
}
for (i--; i >= 0; i--)
{
str[i - j] = filler;
}
str += field_width - j;
j = 1;
}
}
if (j == 0 && str <= end)
{
*str = '0';
++str;
}
}
if (str <= end)
*str = '\0';
else if (size > 0)
/* don't write out a null byte if the buf size is zero */
*end = '\0';
/* the trailing null byte doesn't count towards the total
* ++str;
*/
return str - buf;
}
/**
* lo_vsprintf - Format a string and place it in a buffer
* @buf: The buffer to place the result into
* @fmt: The format string to use
* @args: Arguments for the format string
*
* Call this function if you are already dealing with a va_list.
* You probably want lo_sprintf instead.
*/
static int
lo_vsprintf (char *buf, const char *fmt, va_list args)
{
return lo_vsnprintf (buf, 0xFFFFFFFFUL, fmt, args);
}
int
dbgleon_sprintf (char *buf, size_t size, const char *fmt, ...)
{
va_list args;
int printed_len;
va_start (args, fmt);
printed_len = lo_vsnprintf (buf, size, fmt, args);
va_end (args);
return printed_len;
}
#define UART_TIMEOUT 100000
static LEON23_APBUART_Regs_Map *uart_regs = 0;
int
dbgleon_printf (const char *fmt, ...)
{
unsigned int i, loops, ch;
amba_apb_device apbdevs[1];
va_list args;
int printed_len;
char printk_buf[1024];
char *p = printk_buf;
/* Emit the output into the temporary buffer */
va_start (args, fmt);
printed_len = lo_vsnprintf (printk_buf, sizeof (printk_buf), fmt, args);
va_end (args);
//---------------------
switch (LEONCOMPAT_VERSION)
{
case 3:
default:
{
if (!uart_regs)
{
if (i =
leon3_getapbbase (VENDOR_GAISLER, GAISLER_APBUART, apbdevs,
1))
{
uart_regs = (LEON23_APBUART_Regs_Map *) apbdevs[0].start;
}
}
if (uart_regs)
{
while (printed_len-- != 0)
{
ch = *p++;
if (uart_regs)
{
loops = 0;
while (!(uart_regs->status & LEON_REG_UART_STATUS_THE)
&& (loops < UART_TIMEOUT))
loops++;
uart_regs->data = ch;
loops = 0;
while (!(uart_regs->status & LEON_REG_UART_STATUS_TSE)
&& (loops < UART_TIMEOUT))
loops++;
}
}
}
}
break;
}
//---------------------
}

View File

@ -0,0 +1,34 @@
/*
* Copyright (c) 2011 Aeroflex Gaisler
*
* BSD license:
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
extern int *console;
console_init (unsigned int *addr, int freq, int baud)
{
console = addr;
addr[1] = 0;
addr[2] = 3;
addr[3] = (freq / baud + 8) / 16 - 1;
}

View File

@ -0,0 +1,121 @@
/*
* Copyright (c) 2011 Aeroflex Gaisler
*
* BSD license:
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
#include <asm-leon/leon.h>
#include <asm-leon/leonstack.h>
#include <asm-leon/irq.h>
#include <asm-leon/irq.h>
#include <asm-leon/time.h>
#include <asm-leon/contextswitch.h>
/* This asm code relies on the following offsets (setjmp.h):
#define THREAD_JB_SP 0
#define THREAD_JB_PC 1
#define THREAD_JB_PSR 8
#define THREAD_JB_WIM 9 */
int
_do_thread_setjmp (threadctx_t env, unsigned int savesigs)
{
#ifndef _FLAT
/* first restore should trap */
env[THREAD_JB_WIM] = 1 << ((env[THREAD_JB_PSR] & SPARC_PSR_WIN_MASK) + 1);
env[THREAD_JB_WIM] |= env[THREAD_JB_WIM] >> SPARC_NUM_REGWIN;
#else
env[THREAD_JB_WIM] = 0;
#endif
#ifndef _SOFT_FLOAT
env[THREAD_JB_FPUCTX] = fpustate_current;
#endif
return 0;
}
void
thread_longjmp (threadctx_t env, int val)
{
if (!val)
val = 1;
#ifndef _SOFT_FLOAT
fpustate_current = env[THREAD_JB_FPUCTX];
#endif
_switch_to (env, val);
/* __asm__ __volatile__( \ */
/* " mov %8,%%i0 /\* propagate on restore *\/ \n\t"\ */
/* " mov %0,%%i1 /\* propagate on restore *\/ \n\t"\ */
/* " restore \n\t"\ */
/* " mov %%o0,%%g6 \n\t"\ */
/* " mov %%o1,%%g3 /\* former %%i1 (val) *\/ \n\t"\ */
/* " \n\t"\ */
/* " !ta 0x03 /\* flush registers *\/ \n\t"\ */
/* " save %%sp, %7, %%sp \n\t"\ */
/* " save %%sp, %7, %%sp \n\t"\ */
/* " save %%sp, %7, %%sp \n\t"\ */
/* " save %%sp, %7, %%sp \n\t"\ */
/* " save %%sp, %7, %%sp \n\t"\ */
/* " save %%sp, %7, %%sp \n\t"\ */
/* " save %%sp, %7, %%sp \n\t"\ */
/* " \n\t"\ */
/* " ldd [%%g6+%5], %%g4 /\* load psr,wim *\/ \n\t"\ */
/* " wr %%g4, 0x20, %%psr \n\t"\ */
/* " nop \n\t"\ */
/* " nop \n\t"\ */
/* " nop \n\t"\ */
/* " ldd [%%g6 +%1], %%sp /\* load sp, pc to jump to *\/ \n\t"\ */
/* " wr %%g5, 0x0, %%wim \n\t"\ */
/* " \n\t"\ */
/* " ldd [%%sp], %%l0 /\* restore window *\/ \n\t"\ */
/* " ldd [%%sp+8], %%l2 \n\t"\ */
/* " ldd [%%sp+16], %%l4 \n\t"\ */
/* " ldd [%%sp+24], %%l6 \n\t"\ */
/* " \n\t"\ */
/* " ldd [%%sp+32], %%i0 \n\t"\ */
/* " ldd [%%sp+40], %%i2 \n\t"\ */
/* " ldd [%%sp+48], %%i4 \n\t"\ */
/* " ldd [%%sp+56], %%i6 \n\t"\ */
/* " wr %%g4, 0x00, %%psr \n\t"\ */
/* " nop \n\t"\ */
/* " nop \n\t"\ */
/* " nop \n\t"\ */
/* " \n\t"\ */
/* " jmp %%o7 + 8 /\* success *\/ \n\t"\ */
/* " mov %%g3, %%o0 /\* return %%g3 *\/ \n\t"\ */
/* : : /\* %0 *\/ "r" (val), \ */
/* /\* %1 *\/ "i" (sizeof(int) * THREAD_JB_SP), \ */
/* /\* %2 *\/ "i" (sizeof(int) * THREAD_JB_I7), \ */
/* /\* %3 *\/ "i" (sizeof(int) * THREAD_JB_FP), \ */
/* /\* %4 *\/ "i" (sizeof(int) * THREAD_JB_PC), \ */
/* /\* %5 *\/ "i" (sizeof(int) * THREAD_JB_PSR), \ */
/* /\* %6 *\/ "i" (sizeof(int) * THREAD_JB_WIM), \ */
/* /\* %7 *\/ "i" (-SF_REGS_SZ), \ */
/* /\* %8 *\/ "r" (env) ); */
/* never come here */
}

View File

@ -0,0 +1,101 @@
/*
* Copyright (c) 2011 Aeroflex Gaisler
*
* BSD license:
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
#include <asm-leon/leon.h>
#include <asm-leon/leonstack.h>
#include <asm-leon/contextswitch.h>
#include <asm-leon/winmacros.h>
/* This asm code relies on the following offsets (setjmp.h):
#define THREAD_JB_SP 0
#define THREAD_JB_PC 1
#define THREAD_JB_PSR 8
#define THREAD_JB_WIM 9 */
/* Number of register windows */
.global _nwindows_min1, _nwindows
.text
.global _switch_to
_switch_to:
#ifndef _FLAT
!mov %o0,%i0 /* propagate env on restore */
!mov %o1,%i1 /* propagate val on restore */
!restore
mov %o0,%g7
mov %o1,%g3 /* former %%i1 (val) */
sethi %hi(_nwindows_min1), %g4 /* flush registers */
ld [%g4+%lo(_nwindows_min1)], %g4
1: save %sp, -SF_REGS_SZ, %sp !NWINDOWS-1 times
sub %g4,1,%g4
cmp %g0,%g4
bne 1b
nop
#else
mov %o0,%g7
mov %o1,%g3 /* former %%i1 (val) */
RW_STORE(sp)
#endif
ldd [%g7+THREAD_JB_PSR*4], %g4 /* load psr,wim */
wr %g4, 0x20, %psr
nop
nop
nop
ldd [%g7 +THREAD_JB_SP*4], %sp /* load sp, pc to jump to */
wr %g5, 0x0, %wim
RW_LOAD(sp) /* restore window */
wr %g4, 0x00, %psr
nop
nop
nop
jmp %o7 + 8 /* success */
mov %g3, %o0 /* return %%g3 */
.text
.global thread_setjmp, _do_thread_setjmp
thread_setjmp:
#ifdef _FLAT
RW_STORE(sp) /* store window */
#endif
! RW_STORE(sp) /* store window for _FLAT and normal, SWITCH_TO_STACK in pthread need this*/
mov %psr,%o2
#ifndef _SOFT_FLOAT
set 0x1000,%o3
andn %o2,%o3,%o2 !disable fpu
#endif
std %sp,[%o0] !THREAD_JB_SP
st %o2,[%o0+(8*4)] !THREAD_JB_PSR
ba _do_thread_setjmp
nop

View File

@ -0,0 +1,91 @@
/*
* Copyright (c) 2011 Aeroflex Gaisler
*
* BSD license:
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
.text
.global _start, main, _end
_start:
#ifndef _FLAT
save %sp, -64, %sp
#else
add %sp, -72, %sp
st %o7, [%sp+64]
#endif
/* clear the bss */
sethi %hi(__bss_start),%g2
or %g2,%lo(__bss_start),%g2 ! g2 = start of bss
sethi %hi(_end),%g3
or %g3,%lo(_end),%g3 ! g3 = end of bss
mov %g0,%g1 ! so std has two zeros
sub %g3, %g2, %g3
zerobss:
subcc %g3, 8, %g3
bge,a zerobss
std %g0,[%g2+%g3]
set _end, %o0
st %g0,[%o0]
call bdinit2
nop
call prelibchook
nop
call _call_initcalls /* atexit uses __atexit lock */
nop
set _fini, %o0
call atexit, 1
nop
call _init
nop
call main
nop
call _exit
nop
#ifndef _FLAT
ret
restore
#else
ld [%sp+64], %o7
retl
add %sp, 72, %sp
#endif
.seg "data"
.global .bdata
.bdata:
.align 8
.global _environ
_environ:
.word 1

View File

@ -0,0 +1,69 @@
! Copyright (C) 1992 Free Software Foundation, Inc.
! Written By David Vinayak Henkel-Wallace, June 1992
!
! This file is free software; you can redistribute it and/or modify it
! under the terms of the GNU General Public License as published by the
! Free Software Foundation; either version 2, or (at your option) any
! later version.
!
! In addition to the permissions in the GNU General Public License, the
! Free Software Foundation gives you unlimited permission to link the
! compiled version of this file with other programs, and to distribute
! those programs without any restriction coming from the use of this
! file. (The General Public License restrictions do apply in other
! respects; for example, they cover modification of the file, and
! distribution when not linked into another program.)
!
! This file is distributed in the hope that it will be useful, but
! WITHOUT ANY WARRANTY; without even the implied warranty of
! MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
! General Public License for more details.
!
! You should have received a copy of the GNU General Public License
! along with this program; see the file COPYING. If not, write to
! the Free Software Foundation, 59 Temple Place - Suite 330,
! Boston, MA 02111-1307, USA.
!
! As a special exception, if you link this library with files
! compiled with GCC to produce an executable, this does not cause
! the resulting executable to be covered by the GNU General Public License.
! This exception does not however invalidate any other reasons why
! the executable file might be covered by the GNU General Public License.
!
! This file just make a stack frame for the contents of the .fini and
! .init sections. Users may put any desired instructions in those
! sections.
! This file is linked in before the Values-Xx.o files and also before
! crtbegin, with which perhaps it should be merged.
.section ".init"
.global _init
.type _init,#function
.align 4
_init:
#ifndef _FLAT
save %sp, -96, %sp
#else
add %sp, -96, %sp
st %o7, [%sp + 64]
#endif
.section ".fini"
.global _fini
.type _fini,#function
.align 4
_fini:
#ifndef _FLAT
save %sp, -96, %sp
#else
add %sp, -96, %sp
st %o7, [%sp + 64]
#endif

View File

@ -0,0 +1,63 @@
! Copyright (C) 1992 Free Software Foundation, Inc.
! Written By David Vinayak Henkel-Wallace, June 1992
!
! This file is free software; you can redistribute it and/or modify it
! under the terms of the GNU General Public License as published by the
! Free Software Foundation; either version 2, or (at your option) any
! later version.
!
! In addition to the permissions in the GNU General Public License, the
! Free Software Foundation gives you unlimited permission to link the
! compiled version of this file with other programs, and to distribute
! those programs without any restriction coming from the use of this
! file. (The General Public License restrictions do apply in other
! respects; for example, they cover modification of the file, and
! distribution when not linked into another program.)
!
! This file is distributed in the hope that it will be useful, but
! WITHOUT ANY WARRANTY; without even the implied warranty of
! MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
! General Public License for more details.
!
! You should have received a copy of the GNU General Public License
! along with this program; see the file COPYING. If not, write to
! the Free Software Foundation, 59 Temple Place - Suite 330,
! Boston, MA 02111-1307, USA.
!
! As a special exception, if you link this library with files
! compiled with GCC to produce an executable, this does not cause
! the resulting executable to be covered by the GNU General Public License.
! This exception does not however invalidate any other reasons why
! the executable file might be covered by the GNU General Public License.
!
! This file just makes sure that the .fini and .init sections do in
! fact return. Users may put any desired instructions in those sections.
! This file is the last thing linked into any executable.
.file "crtn.s"
.section ".init"
.align 4
#ifndef _FLAT
ret
restore
#else
ld [%sp+64], %o7
retl
add %sp, 96, %sp
#endif
.section ".fini"
.align 4
#ifndef _FLAT
ret
restore
#else
ld [%sp+64], %o7
retl
add %sp, 96, %sp
#endif

113
libgloss/sparc_leon/etrap.S Normal file
View File

@ -0,0 +1,113 @@
/*
* Copyright (c) 2011 Aeroflex Gaisler
*
* BSD license:
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
#include <asm-leon/leonstack.h>
#include <asm-leon/winmacros.h>
/* Registers to not touch at all. */
#define t_psr l0 /* Set by caller */
#define t_pc l1 /* Set by caller */
#define t_npc l2 /* Set by caller */
#define t_wim l3 /* Set by caller */
#define t_twinmask l4 /* Set at beginning of this entry routine. */
#define t_kstack l5 /* Set right before pt_regs frame is built */
#define t_retpc l6 /* If you change this, change winmacro.h header file */
#define t_systable l7 /* Never touch this, could be the syscall table ptr. */
#define curptr g6 /* Set after pt_regs frame is built */
/* Number of register windows */
.global _nwindows_min1, _nwindows
.text
.align 4
.globl leonbare_trapsetup
leonbare_trapsetup:
#ifdef _FLAT
restore
RW_STORE(sp)
save
#endif
#ifndef _SOFT_FLOAT
/* build a pt_regs trap frame. */
sub %fp, (SF_REGS_SZ + PT_REGS_SZ + FW_REGS_SZ), %t_kstack
PT_STORE_ALL(t_kstack, t_psr, t_pc, t_npc, g2)
/* build a fp_regs trap frame. */
sethi %hi(fpustate_current), %g2
ld [%g2+%lo(fpustate_current)], %g3
st %g3,[%t_kstack + (SF_REGS_SZ + PT_REGS_SZ + FW_REGS_SZ - 4)]
add %t_kstack,SF_REGS_SZ + PT_REGS_SZ,%g3
st %g3, [%g2+%lo(fpustate_current)]
#else
/* build a pt_regs trap frame.
*/
sub %fp, (SF_REGS_SZ + PT_REGS_SZ), %t_kstack
PT_STORE_ALL(t_kstack, t_psr, t_pc, t_npc, g2)
#endif
#ifndef _FLAT
/* See if we are in the trap window. */
mov 1, %t_twinmask
sll %t_twinmask, %t_psr, %t_twinmask ! t_twinmask = (1 << psr)
andcc %t_twinmask, %t_wim, %g0
beq 1f ! in trap window, clean up
nop
/*-------------------------------------------------*/
/* Spill , adjust %wim and go. */
srl %t_wim, 0x1, %g2 ! begin computation of new %wim
sethi %hi(_nwindows_min1), %g3
ld [%g3+%lo(_nwindows_min1)], %g3
sll %t_wim, %g3, %t_wim ! NWINDOWS-1
or %t_wim, %g2, %g2
and %g2, 0xff, %g2
save %g0, %g0, %g0 ! get in window to be saved
/* Set new %wim value */
wr %g2, 0x0, %wim
/* Save the kernel window onto the corresponding stack. */
RW_STORE(sp)
restore %g0, %g0, %g0
/*-------------------------------------------------*/
1:
#endif
/* Trap from kernel with a window available.
* Just do it...
*/
jmpl %t_retpc + 0x8, %g0 ! return to caller
mov %t_kstack, %sp ! jump onto new stack

View File

@ -0,0 +1,121 @@
/*
* Copyright (c) 2011 Aeroflex Gaisler
*
* BSD license:
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
#include <asm-leon/leonstack.h>
#include <asm-leon/winmacros.h>
/* Registers to not touch at all. */
#define t_psr l0 /* Set by caller */
#define t_pc l1 /* Set by caller */
#define t_npc l2 /* Set by caller */
#define t_wim l3 /* Set by caller */
#define t_twinmask l4 /* Set at beginning of this entry routine. */
#define t_kstack l5 /* Set right before pt_regs frame is built */
#define t_retpc l6 /* If you change this, change winmacro.h header file */
#define t_systable l7 /* Never touch this, could be the syscall table ptr. */
#define curptr g6 /* Set after pt_regs frame is built */
/* Number of register windows */
.global _nwindows_min1, _nwindows
.text
.align 4
.globl leonbare_trapsetup_fast
/* etap entry special for irqtrap.S */
leonbare_trapsetup_fast:
#ifdef _FLAT
restore
RW_STORE(sp)
save
#endif
#ifndef _SOFT_FLOAT
/* build a pt_regs trap frame. */
sub %fp, (SF_REGS_SZ + PT_REGS_SZ + FW_REGS_SZ), %t_kstack
st %t_psr, [%t_kstack + (SF_REGS_SZ + PT_REGS_SZ + FW_REGS_SZ - 8)] /* sparc_fpuwindow_regs.irqpsr */
set SPARC_PSR_EF_MASK, %t_twinmask
andn %t_psr, %t_twinmask, %t_psr ! fpu off
PT_STORE_ALL_FAST(t_kstack, t_psr, t_pc, t_npc, g2)
/*PT_STORE_GLOBALS(t_kstack)*/
/* build a fp_regs trap frame. */
sethi %hi(fpustate_current), %g2
ld [%g2+%lo(fpustate_current)], %g3
st %g3,[%t_kstack + (SF_REGS_SZ + PT_REGS_SZ + FW_REGS_SZ - 4)] /* sparc_fpuwindow_regs.lastctx */
add %t_kstack,SF_REGS_SZ + PT_REGS_SZ,%g3
st %g3, [%g2+%lo(fpustate_current)]
st %g0, [%g3 + FW_FSR]
#else
/* build a pt_regs trap frame.
*/
sub %fp, (SF_REGS_SZ + PT_REGS_SZ), %t_kstack
PT_STORE_ALL_FAST(t_kstack, t_psr, t_pc, t_npc, g2)
/*PT_STORE_GLOBALS(t_kstack)*/
#endif
#ifndef _FLAT
/* See if we are in the trap window . */
mov 1, %t_twinmask
sll %t_twinmask, %t_psr, %t_twinmask ! t_twinmask = (1 << psr)
andcc %t_twinmask, %t_wim, %g0
beq 1f ! in trap window, clean up
nop
/*-------------------------------------------------*/
/* Spill , adjust %wim and go. */
srl %t_wim, 0x1, %g2 ! begin computation of new %wim
sethi %hi(_nwindows_min1), %g3
ld [%g3+%lo(_nwindows_min1)], %g3
sll %t_wim, %g3, %t_wim ! NWINDOWS-1
or %t_wim, %g2, %g2
and %g2, 0xff, %g2
save %g0, %g0, %g0 ! get in window to be saved
/* Set new %wim value */
wr %g2, 0x0, %wim
/* Save the kernel window onto the corresponding stack. */
RW_STORE(sp)
restore %g0, %g0, %g0
/*-------------------------------------------------*/
1:
#endif
/* Trap from kernel with a window available.
* Just do it...
*/
jmpl %t_retpc + 0x8, %g0 ! return to caller
mov %t_kstack, %sp ! jump onto new stack

111
libgloss/sparc_leon/fpu.S Normal file
View File

@ -0,0 +1,111 @@
/*
* Copyright (c) 2011 Aeroflex Gaisler
*
* BSD license:
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
#include <asm-leon/asmmacro.h>
#include <asm-leon/leonstack.h>
#include <asm-leon/winmacros.h>
#include <asm-leon/leon.h>
#ifndef _SOFT_FLOAT
.seg "text"
/* ------- */
.weak _fpdis_enable_svt
.set _fpdis_enable_svt,__fpdis_enable_svt
.weak _fpdis_enable
.set _fpdis_enable,__fpdis_enable
/* ------- */
!.global _fpdis_enable,_fpdis_enable_svt
__fpdis_enable_svt:
__fpdis_enable:
set SPARC_PSR_EF_MASK,%l3
or %l0,%l3,%l0
or %l0,0xf00, %l3 ! PIL up to 15, enable fpu
wr %l3,0, %psr ! restore the condition flags, enable fpu
nop
nop
nop
mov %psr, %l3 ! check if fpu is present
set SPARC_PSR_EF_MASK,%l4
andcc %l3, %l4, %l3
bne 4f
nop
ta 0 ! no fpu present, halt
4:
set fpustate_current,%l4
ld [%l4],%l4
set fpustate_owner,%l5
ld [%l5],%l5
cmp %l4,%l5
beq mpfnostore
nop
cmp %g0,%l5
beq mpfstore
nop
FW_STORE(%l5)
mpfstore:
set fpustate_owner,%l6
st %l4,[%l6]
cmp %g0,%l4
beq mpfnostore
nop
FW_LOAD(%l4)
mpfnostore:
wr %l0,0, %psr ! restore the condition flags, enable fpu
nop
nop
nop
jmpl %l1, %g0
rett %l2
.seg "data"
.global fpustate_default
.align 8
fpustate_default:
.long 0; .long 0; .long 0; .long 0; .long 0; .long 0; .long 0; .long 0;
.long 0; .long 0; .long 0; .long 0; .long 0; .long 0; .long 0; .long 0;
.long 0; .long 0; .long 0; .long 0; .long 0; .long 0; .long 0; .long 0;
.long 0; .long 0; .long 0; .long 0; .long 0; .long 0; .long 0; .long 0;
.long 0; .long 0; .long 0; .long 0; .long 0; .long 0; .long 0; .long 0;
.global fpustate_owner
fpustate_owner:
.word fpustate_default ! pointer to FPU owning context
.global fpustate_current
fpustate_current:
.word fpustate_default ! pointer to current threads FPU context
#endif

View File

@ -0,0 +1,272 @@
/*
* Copyright (c) 2011 Aeroflex Gaisler
*
* BSD license:
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
#include <sys/types.h>
#include <sys/time.h>
#include <sys/errno.h>
#include <asm-leon/elfmacro.h>
#include <asm-leon/leon.h>
#include <asm-leon/irq.h>
#include <asm-leon/jiffies.h>
#include <asm-leon/param.h>
#include <asm-leon/leoncompat.h>
static __inline__ unsigned long do_gettimeoffset ();
extern int *rtc;
unsigned long wall_jiffies = INITIAL_JIFFIES;
unsigned long tick_nsec = TICK_NSEC;
unsigned long tick_usec = TICK_NSEC / 1000;
unsigned long seperateirq = 1;
unsigned long noalarm = 1;
unsigned long force_noalarm = 0;
unsigned long nodotimer = 0;
int leonbare_hz = HZ;
void settimer ();
inline void
do_timer (struct leonbare_pt_regs *regs)
{
unsigned long ticks;
jiffies_64++;
ticks = jiffies - wall_jiffies;
if (ticks)
{
wall_jiffies += ticks;
do
{
ticks--;
xtime.tv_nsec += tick_nsec;
if (xtime.tv_nsec >= 1000000000)
{
xtime.tv_nsec -= 1000000000;
xtime.tv_sec++;
}
}
while (ticks);
}
settimer ();
}
int
leonbare_alarm (int irq, void *arg, struct leonbare_pt_regs *regs)
{
settimer ();
}
extern clock_t (*clock_custom) (void);
clock_t
leonbare_clock_custom ()
{
int hz = leonbare_hz ? leonbare_hz : HZ;
return (clock_t) ((jiffies * (CLOCK_TICK_RATE / hz)) + do_gettimeoffset ());
}
tickerhandler ticker_callback = 0;
int
leonbare_tick (int irq, void *arg, struct leonbare_pt_regs *regs)
{
unsigned int ctrl;
if (!seperateirq)
{
/* only leon3 comes here */
if (!noalarm)
{
ctrl = LEON3_GpTimer_Regs->e[1].ctrl;
if (ctrl & LEON3_GPTIMER_IP)
{
leonbare_alarm (irq, arg, regs);
LEON3_GpTimer_Regs->e[1].ctrl = ctrl & ~LEON3_GPTIMER_IP;
}
}
ctrl = LEON3_GpTimer_Regs->e[0].ctrl;
if (!(ctrl & LEON3_GPTIMER_IP))
{
return 0;
}
LEON3_GpTimer_Regs->e[0].ctrl = ctrl & ~LEON3_GPTIMER_IP;
}
if (!nodotimer)
{
do_timer (regs);
}
if (ticker_callback)
{
ticker_callback (regs);
}
return 0;
}
static struct irqaction irqact1 = { (irqhandler) leonbare_tick, 0, 0, 0 };
static struct irqaction irqact2 = { (irqhandler) leonbare_alarm, 0, 0, 0 };
void
leonbare_init_ticks ()
{
int i, irq1 = 0, irq2 = 0;
int hz = leonbare_hz ? leonbare_hz : HZ;
amba_apb_device dev[1];
//---------------------
switch (LEONCOMPAT_VERSION)
{
case 3:
default:
amba_init ();
if (LEON3_GpTimer_Regs && LEON3_IrqCtrl_Regs)
{
if ((LEON3_GpTimer_Regs->config & LEON3_GPTIMER_CONFIG_TIMERMASK) >=
2 && force_noalarm == 0)
noalarm = 0;
if (!(LEON3_GpTimer_Regs->config & LEON3_GPTIMER_CONFIG_SEPERATE))
seperateirq = 0;
LEON3_GpTimer_Regs->e[0].val = 0;
LEON3_GpTimer_Regs->e[0].rld = (((CLOCK_TICK_RATE / hz) - 1));
LEON3_GpTimer_Regs->e[0].ctrl = 0;
LEON3_GpTimer_Regs->e[0].ctrl =
LEON3_GPTIMER_EN |
LEON3_GPTIMER_RL | LEON3_GPTIMER_LD | LEON3_GPTIMER_IRQEN;
irq1 = LEON3_GpTimer_Irq;
irq2 = LEON3_GpTimer_Irq + 1;
}
break;
}
//---------------------
if (irq1)
{
clock_custom = leonbare_clock_custom;
chained_catch_interrupt (irq1, &irqact1);
leonbare_enable_irq (irq1);
}
if (irq2 && (!noalarm) && seperateirq)
{
chained_catch_interrupt (irq2, &irqact2);
leonbare_enable_irq (irq2);
}
}
//'''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
static __inline__ unsigned long
do_gettimeoffset ()
{
unsigned long usec = 0;
//---------------------
switch (LEONCOMPAT_VERSION)
{
case 3:
default:
usec = ((LEON3_GpTimer_Regs->e[0].rld & 0x7fffff) -
(LEON3_GpTimer_Regs->e[0].val & 0x7fffff));
break;
}
//---------------------
return usec;
}
/* get usec (timeval) resolution,
* could use nsec (timespec) because pthread use it (todo) */
void
do_gettimeofday (struct timeval *tv)
{
unsigned long flags;
unsigned long seq;
unsigned long usec, sec;
do
{
unsigned long lost;
seq = jiffies;
usec = do_gettimeoffset ();
lost = jiffies - wall_jiffies;
if (unlikely (lost))
{
usec += lost * tick_usec;
}
sec = xtime.tv_sec;
usec += (xtime.tv_nsec / 1000);
}
while (seq != jiffies);
while (usec >= 1000000)
{
usec -= 1000000;
sec++;
}
tv->tv_sec = sec;
tv->tv_usec = usec;
}
int
gettimeofday (struct timeval *__p, void *__tz)
{
do_gettimeofday (__p);
return 0;
}
//'''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
static int
do_settimeofday (struct timespec *tv)
{
time_t sec = tv->tv_sec;
long nsec = tv->tv_nsec;
if ((unsigned long) nsec >= NSEC_PER_SEC)
return EINVAL;
/*
* This is revolting. We need to set "xtime" correctly. However, the
* value in this location is the value at the most recent update of
* wall time. Discover what correction gettimeofday() would have
* made, and then undo it!
*/
nsec -= 1000 * (do_gettimeoffset () +
(jiffies - wall_jiffies) * (USEC_PER_SEC / HZ));
set_normalized_timespec (&xtime, sec, nsec);
return 0;
}
int
settimeofday (const struct timeval *tv, const struct timezone *tz)
{
struct timespec ts;
ts.tv_sec = tv->tv_sec;
ts.tv_nsec = tv->tv_usec * NSEC_PER_USEC;
return do_settimeofday (&ts);
}

View File

@ -0,0 +1,45 @@
/*
* Copyright (c) 2011 Aeroflex Gaisler
*
* BSD license:
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
#include <asm-leon/leon.h>
#include <asm-leon/elfmacro.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
void
_call_initcalls ()
{
initcall_t *p = &__leonbare_initcall_start;
while (p < &__leonbare_initcall_end)
{
if (*p)
{
(*p) ();
}
p++;
}
}

53
libgloss/sparc_leon/io.c Normal file
View File

@ -0,0 +1,53 @@
/*
* Copyright (c) 2011 Aeroflex Gaisler
*
* BSD license:
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
#define DREADY 1
#define TREADY 4
extern volatile int *console;
void
outbyte (int c)
{
volatile int *rxstat;
volatile int *rxadata;
int rxmask;
while ((console[1] & TREADY) == 0);
console[0] = (0x0ff & c);
if (c == '\n')
{
while ((console[1] & TREADY) == 0);
console[0] = (int) '\r';
}
}
int
inbyte (void)
{
if (!console)
return (0);
while (!(console[1] & DREADY));
return console[0];
}

View File

@ -0,0 +1,41 @@
/*
* Copyright (c) 2011 Aeroflex Gaisler
*
* BSD license:
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
#include <asm-leon/leon.h>
/* l0: psr
l1: pc
l2: npc
l3: wim
l7: irqnr */
.seg "text"
.global locore_readtbr
locore_readtbr:
retl
rd %tbr,%o0

View File

@ -0,0 +1,108 @@
/*
* Copyright (c) 2011 Aeroflex Gaisler
*
* BSD license:
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
#include <asm-leon/leonstack.h>
#include <asm-leon/asmmacro.h>
#include <asm-leon/winmacros.h>
#include <asm-leon/leon.h>
/* l0: psr
l1: pc
l2: npc
l3: wim
l7: irqnr */
.seg "text"
/* ------- */
.weak _leonbare_irq_entry_svt
.set _leonbare_irq_entry_svt,__leonbare_irq_entry_svt
.weak leonbare_irq_entry
.set leonbare_irq_entry,_leonbare_irq_entry
/* ------- */
!.global leonbare_irq_entry,_leonbare_irq_entry_svt
.global _irqtbl, _irqtrap, handler_irq, fpustate_current
__leonbare_irq_entry_svt: /* irq from svt trap dispatcher */
sub %l6,0x10, %l7
rd %wim, %l3
_leonbare_irq_entry:
set SPARC_PSR_EF_MASK,%l6
andn %l0, %l6, %l0 ! fpu off
SAVE_ALL
set nestcount,%o0
ld [%o0],%o1
add %o1,1,%o1
st %o1,[%o0]
#ifdef CONFIG_LEONBARE_NONESTEDIRQ
or %l0, SPARC_PSR_PIL_MASK, %o0 ! no nested irqs
wr %o0, SPARC_PSR_ET_MASK, %psr
WRITE_PAUSE
#else
sll %l7,SPARC_PSR_PIL_SHIFT,%o1
andn %l0,SPARC_PSR_PIL_MASK,%o0
or %l0, %o1, %o1
set nestedirq,%o0
ld [%o0],%o0
cmp %g0,%o0 ! no nested irqs?
beq,a .L1
or %o1, SPARC_PSR_PIL_MASK, %o1
.L1:
wr %o1, SPARC_PSR_ET_MASK, %psr
WRITE_PAUSE
#endif
mov %l7, %o0 ! irq level
call handler_irq ! void handler_irq (int irq, struct leonbare_pt_regs *pt_regs)
#ifndef _SOFT_FLOAT
add %sp, FW_REGS_SZ + 8 + SF_REGS_SZ , %o1 ! pt_regs ptr
#else
add %sp, SF_REGS_SZ , %o1 ! pt_regs ptr
#endif
or %l0, SPARC_PSR_PIL_MASK, %o1
wr %o1, SPARC_PSR_ET_MASK, %psr ! enable nesting again, keep ET up
WRITE_PAUSE
set nestcount,%o0
ld [%o0],%o1
sub %o1,1,%o1
st %o1,[%o0]
RESTORE_ALL
.seg "data"
.global nestedirq
.align 4
nestedirq:
.long 0
.global nestcount
.align 4
nestcount:
.long 0

View File

@ -0,0 +1,128 @@
/*
* Copyright (c) 2011 Aeroflex Gaisler
*
* BSD license:
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
#include <asm-leon/leonstack.h>
#include <asm-leon/asmmacro.h>
#include <asm-leon/winmacros.h>
#include <asm-leon/leon.h>
/* l0: psr
l1: pc
l2: npc
l3: wim
l7: irqnr */
.seg "text"
/* ------- */
.weak _leonbare_irq_entry_svt
.set _leonbare_irq_entry_svt,__leonbare_irq_entry_svt
.weak leonbare_irq_entry
.set leonbare_irq_entry,_leonbare_irq_entry
/* ------- */
!.global leonbare_irq_entry,_leonbare_irq_entry_svt
.global _irqtbl, _irqtrap, handler_irq, fpustate_current
#define FASTIRQ_ENABLE
/*#define FASTIRQ_DYNAMIC*/ /* depend on FASTIRQ_ENABLE */
__leonbare_irq_entry_svt: /* irq from svt trap dispatcher */
sub %l6,0x10, %l7
rd %wim, %l3
_leonbare_irq_entry:
SAVE_ALL_FAST(.L3) ! fast irq processing, volatile %g6, use frame
.L3:
#ifdef __threadx__
set _tx_thread_system_state, %o0
ld [%o0],%o1
add %o1,1,%o1
st %o1,[%o0]
#endif
set nestcount,%o0
ld [%o0],%o1
add %o1,1,%o1
st %o1,[%o0]
#ifdef CONFIG_LEONBARE_NONESTEDIRQ
or %l0, SPARC_PSR_PIL_MASK, %o0 ! no nested irqs
wr %o0, SPARC_PSR_ET_MASK, %psr
WRITE_PAUSE
#else
sll %l7,SPARC_PSR_PIL_SHIFT,%o1
andn %l0,SPARC_PSR_PIL_MASK,%o0
or %o0, %o1, %o1
set nestedirq,%o0
ld [%o0],%o0
cmp %g0,%o0 ! no nested irqs?
beq,a .L1
or %o1, SPARC_PSR_PIL_MASK, %o1
.L1:
wr %o1, SPARC_PSR_ET_MASK, %psr
WRITE_PAUSE
#endif
mov %l7, %o0 ! irq level
call handler_irq ! void handler_irq (int irq, struct leonbare_pt_regs *pt_regs)
#ifndef _SOFT_FLOAT
add %sp, FW_REGS_SZ + 8 + SF_REGS_SZ , %o1 ! pt_regs ptr
#else
add %sp, SF_REGS_SZ , %o1 ! pt_regs ptr
#endif
or %l0, SPARC_PSR_PIL_MASK, %o1
wr %o1, SPARC_PSR_ET_MASK, %psr ! enable nesting again, keep ET up
WRITE_PAUSE
set nestcount,%o0
ld [%o0],%o1
sub %o1,1,%o1
st %o1,[%o0]
#ifdef __threadx__
set _tx_thread_system_state, %o0
ld [%o0],%o1
sub %o1,1,%o1
st %o1,[%o0]
#endif
RESTORE_ALL_FAST
.seg "data"
.global nestedirq
.align 4
nestedirq:
.long 0
.global fastirq
.align 4
fastirq:
.long 0
.global nestcount
.align 4
nestcount:
.long 0

View File

@ -0,0 +1,38 @@
/*
* Copyright (c) 2011 Aeroflex Gaisler
*
* BSD license:
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
#include <sys/types.h>
#include <sys/time.h>
#include <sys/errno.h>
#include <asm-leon/elfmacro.h>
#include <asm-leon/leon.h>
#include <asm-leon/irq.h>
#include <asm-leon/irq.h>
#include <asm-leon/jiffies.h>
#include <asm-leon/param.h>
#include <asm-leon/leoncompat.h>
struct timespec xtime __attribute__ ((aligned (16)));
u64 jiffies_64 = INITIAL_JIFFIES;

View File

@ -0,0 +1,217 @@
/*
* Copyright (c) 2011 Aeroflex Gaisler
*
* BSD license:
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
#include <asm-leon/contextswitch.h>
#include <asm-leon/leonbare_kernel.h>
#include <asm-leon/leonbare_debug.h>
#include <asm-leon/stack.h>
#include <asm-leon/leonstack.h>
#include <asm-leon/irq.h>
struct leonbare_kernel leonbare_kernel;
/*
* queue 0: [ <acc=2>],
* queue 1: [ <acc=10>, <acc=8>,<acc=8>,<acc=1> ],
* queue 2: [ ... ],
* ...
* queue n: [ ... ]
*
* Seach through ready queue [0 - LEONBARE_RUNQ_READY_NR-1] for the
* first thread in a queue'ss head to discover
* leonbare_thread_tick_callback() will put threads that have their th_caccount
* consumed into the prepare-run queues. th_caccount is already initialized
* to the value for the next schedule round. So all there is to do is to
* move the to prepare-run queues to run queues [0 - LEONBARE_RUNQ_READY_NR-1].
* return the first thread in any queue, similary to leonbare_sched_next().
* Using LEONBARE_KR_RUNQ_WHICH and leonbare_thread.th_runq_which one can
* determine weather the thread is in a runqueue or a prepare-runqueue:
* LEONBARE_KR_RUNQ_WHICH == leonbare_thread.th_runq_which : thread in runqueue
* LEONBARE_KR_RUNQ_WHICH != leonbare_thread.th_runq_which : thread in prepare-runqueue
* after a leonbare_thread_tick_callback() or a run queue change, call
* leonbare_sched_update() to update LEONBARE_KR_NEXT and
* LEONBARE_KR_NEED_SCHEDULE
*/
int
leonbare_sched_update ()
{
int idx;
leonbare_thread_t n = 0;
int i = 0;
LEONBARE_VERIFYIRQDISABLED ();
LEONBARE_VERIFYSCHED ();
for (i = 0; i < LEONBARE_RUNQ_READY_NR; i++)
{
leonbare_thread_t c;
if (!LBTAILQ_EMPTY (LEONBARE_KR_RUNQ (i)))
{
n = LBTAILQ_FIRST (LEONBARE_KR_RUNQ (i));
break;
}
}
if (!n)
{
for (idx = 0; idx < LEONBARE_RUNQ_READY_NR; idx++)
{
struct leonbare_thread_queue *h0 =
(struct leonbare_thread_queue *) LEONBARE_KR_RUNQ (idx);
struct leonbare_thread_queue *h1 = (struct leonbare_thread_queue *)
LEONBARE_KR_RUNQ (idx + LEONBARE_RUNQ_PREPARE_IDX);
if (LBTAILQ_EMPTY (h1))
{
LBTAILQ_INIT (h0);
}
else
{
*h0 = *h1;
if (LBTAILQ_FIRST (h0))
{
LBTAILQ_FIRST (h0)->th_runq.tqe_prev = &(h0)->tqh_first;
}
if (!n)
{
n = LBTAILQ_FIRST (h0);
}
}
}
for (idx = 0; idx < LEONBARE_RUNQ_READY_NR; idx++)
{
LBTAILQ_INIT (LEONBARE_KR_RUNQ (idx + LEONBARE_RUNQ_PREPARE_IDX));
}
LEONBARE_KR_RUNQ_WHICH++;
LEONBARE_VERIFYSCHED ();
LEONBARE_PRINTQUEUES ();
}
LEONBARE_KR_NEXT = n;
return (LEONBARE_KR_NEED_SCHEDULE);
}
/* called in the timer irq handling. Decrements the
* th_caccount field. On consumption of th_caccount the
* thread will be removed from the ready queue nad placed into the
* prepare-runqueue for later readdition by leonbare_sched_readyprepare()
* called from gettimeofday.c's installed ticker_callback callback
* leonbare_thread_tick_callback() might change the kernel state in which case
* state on return from leonbare_thread_tick_callback() leonbare_thread_schedule_callback()
* will be called from rtrap_fast.S .
*/
int
leonbare_thread_tick_callback ()
{
LEONBARE_PROTECT_DECL (flags);
unsigned int r;
volatile leonbare_thread_t c = LEONBARE_KR_CURRENT;
leonbare_thread_t i;
LBDEBUG_FNCALL;
if (c && LEONBARE_KR_IS_PREEMPTION)
{
LEONBARE_PROTECT_KERNEL_START ();
{
LEONBARE_VERIFYIRQDISABLED ();
LEONBARE_VERIFYSCHED ();
if ((--c->th_caccount) < 0)
{
LBDEBUG_HEADER_PRINTF (LBDEBUG_QUEUE_NR, "remove %s(%x)\n",
LEONBARE_TH_NAME_DBG (c), c);
LBTAILQ_REMOVE (LEONBARE_KR_RUNQ (c->th_runq_idx), c, th_runq);
LBTAILQ_INSERT_TAIL (LEONBARE_KR_RUNQ
(c->th_runq_idx + LEONBARE_RUNQ_PREPARE_IDX),
c, th_runq);
c->th_caccount = c->th_account;
c->th_runq_which++;
}
else
{
/* todo: round robbin scheme */
}
}
LEONBARE_PROTECT_KERNEL_END ();
}
r = leonbare_sched_update ();
return r;
}
/* called from rtrap_fast.S's installed schedule_callback callback */
int
leonbare_thread_schedule_callback (struct leonbare_pt_regs *ptregs)
{
unsigned int retval;
LBDEBUG_FNCALL;
if (LEONBARE_KR_IS_IN_KERNEL == 0 && LEONBARE_KR_NEED_SCHEDULE)
{
leonbare_sched ();
//KERNEL_ENTER;
//KERNEL_EXIT(LEONBARE_KR_NEED_SCHEDULE, retval);
}
LBDEBUG_FNEXIT;
}
struct leonbare_thread _thread_main;
int
leonbare_thread_init ()
{
int i;
LBDEBUG_FNCALL;
memset ((void *) &_thread_main, 0, sizeof (_thread_main));
_thread_main.th_reentp = _impure_ptr;
_thread_main.th_name = "<main>";
_thread_main.th_runq_idx = 0;
_thread_main.th_pri_idx = 0;
_thread_main.th_account = 0;
LBTAILQ_INIT (LEONBARE_KR_ALLQ);
for (i = 0; i < LEONBARE_RUNQ_NR; i++)
{
LBTAILQ_INIT (LEONBARE_KR_RUNQ (i));
}
LBTAILQ_INIT (LEONBARE_KR_ALLM);
/* queues */
LBTAILQ_INSERT_TAIL (LEONBARE_KR_ALLQ, &_thread_main, th_allq);
/* inseart into ready queue 0 at head */
LBTAILQ_INSERT_HEAD (LEONBARE_KR_RUNQ (_thread_main.th_runq_idx),
&_thread_main, th_runq);
LEONBARE_KR_CURRENT = &_thread_main;
LEONBARE_KR_IS_IN_KERNEL = 0;
leonbare_init_ticks ();
schedule_callback = (schedulehandler) leonbare_thread_schedule_callback;
ticker_callback = (tickerhandler) leonbare_thread_tick_callback;
/* disable later */
LEONBARE_KR_IS_PREEMPTION = 1;
LBDEBUG_FNEXIT;
}

View File

@ -0,0 +1,112 @@
/*
* Copyright (c) 2011 Aeroflex Gaisler
*
* BSD license:
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
#include <asm-leon/elfmacro.h>
#include <asm-leon/leon.h>
#include <asm-leon/leonstack.h>
#include <asm-leon/contextswitch.h>
#include <asm-leon/winmacros.h>
#include <asm-leon/leonbare_kernel.h>
FUNC_EXPORT(_leonbare_kernel_switchto)
FUNC_EXPORT(_leonbare_Stop)
FUNC_IMPORT(leonbare_disable_traps)
.text
/* unsigned int _leonbare_kernel_switchto(struct leonbare_thread_ctx *thread,struct leonbare_thread_ctx *thread) */
FUNC_BEGIN(_leonbare_kernel_switchto)
/* =================================*/
/* save context */
/* =================================*/
mov %o0, %g1
mov %o1, %g2
mov %o7, %g3
rd %psr, %g4 /* psr.cwp should stay same because irq path rely on it. */
call leonbare_disable_traps /* psr in %o0, modify %o0, %o1, %o7 */
nop
set TACODE_IRQCALL_FLUSH,%o1
ta TACODE_IRQCALL
st %g4, [%g1 + LEONBARE_THREAD_CTX_STACK_PSR] /* psr */
set LEONBARE_THREAD_CTX_MAGIC,%g4
st %g4, [%g1 + LEONBARE_THREAD_CTX_STACK_MAGIC]
mov %g3, %o7 ! restore %o7
LEONBARE_THREAD_CTX_STORE_INS(g1)
LEONBARE_THREAD_CTX_STORE_LOCALS(g1)
LEONBARE_THREAD_CTX_STORE_OUTS(g1)
/* =================================*/
/* restore context */
/* =================================*/
/* check valid context stack area */
ld [%g2 + LEONBARE_THREAD_CTX_STACK_MAGIC], %o1
set LEONBARE_THREAD_CTX_MAGIC,%o2
cmp %o1, %o2
beq 1f
nop
/* stop all */
ta 0x0
1:
/* get psr */
ld [%g2 + LEONBARE_THREAD_CTX_STACK_PSR],%g1 /* psr.cwp should stay same because irq path rely on it. */
set SPARC_PSR_EF_MASK,%g3 ! clear ef bit
andn %g1, %g3, %g1
wr %g0,%wim
nop; nop; nop;
andn %g1, SPARC_PSR_ET_MASK, %g3 ! disable traps, up to PSR_EF imm andn ok
wr %g3, %psr
nop; nop; nop;
LEONBARE_THREAD_CTX_LOAD_INS(g2)
LEONBARE_THREAD_CTX_LOAD_LOCALS(g2)
LEONBARE_THREAD_CTX_LOAD_OUTS(g2)
SET_WIM_CWPMIN1(g1,o1,o2,o3,o4) ! calc wim from psr_cwp so that next restore traps
wr %g1,%psr
nop; nop; nop;
retl
nop
FUNC_END(_leonbare_kernel_switchto)
FUNC_BEGIN(_leonbare_Stop)
ta 0x0
FUNC_END(_leonbare_Stop)

View File

@ -0,0 +1,162 @@
/*
* Copyright (c) 2011 Aeroflex Gaisler
*
* BSD license:
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
#include <asm-leon/queue.h>
/*#include <sys/fsu_pthread_queue.h>*/
#include <asm-leon/contextswitch.h>
#include <asm-leon/leonbare_kernel.h>
#include <asm-leon/leonbare_debug.h>
#include <asm-leon/stack.h>
#include <asm-leon/leonstack.h>
#include <stdarg.h>
/*indent:
indent -kr -i4 -ts4 -sob -l80 -ss -ncs -nut newlib-1.13.0/libgloss/sparc_leon/kernel*.c
indent -kr -i4 -ts4 -sob -l80 -ss -ncs -nut *.h
indent -kr -i4 -ts4 -sob -l80 -ss -ncs -nut *.c
*/
void leonbare_sched_printqueue ();
int
leonbare_sched_verify ()
{
#ifdef LBDEBUG_DO_ASSERT
int i, j;
leonbare_thread_t c, d;
for (i = 0; i < LEONBARE_RUNQ_NR; i++)
{
LBTAILQ_FOREACH (c, LEONBARE_KR_RUNQ (i), th_runq)
{
if (i < LEONBARE_RUNQ_READY_NR)
{
LBPASSERT (c->th_runq_idx == i,
"thread %s has wrong runq[%d] index (%d) ",
LEONBARE_TH_NAME_DBG (c), i, c->th_runq_idx);
LBPASSERT (c->th_runq_which == LEONBARE_KR_RUNQ_WHICH,
"thread %s in runqueue[%d] has wrong th_runq_which(%d) (!=LEONBARE_KR_RUNQ_WHICH(%d))",
LEONBARE_TH_NAME_DBG (c), i, c->th_runq_which,
LEONBARE_KR_RUNQ_WHICH);
}
else if (i == LEONBARE_RUNQ_SUSPENDED_IDX)
{
LBPASSERT (c->th_flags & LEONBARE_TH_SUSPENDED,
"thread %s in suspension queue has LEONBARE_TH_SUSPENDED not set ",
LEONBARE_TH_NAME_DBG (c));
}
else if (i == LEONBARE_RUNQ_KILLED_IDX)
{
LBPASSERT (c->
th_flags & (LEONBARE_TH_TERMINATED |
LEONBARE_TH_FINISHED),
"thread %s in killed queue has (LEONBARE_TH_TERMINATED | LEONBARE_TH_FINISHED) not set ",
LEONBARE_TH_NAME_DBG (c));
}
else if (i >= LEONBARE_RUNQ_PREPARE_IDX &&
i < (LEONBARE_RUNQ_PREPARE_IDX + LEONBARE_RUNQ_READY_NR))
{
LBPASSERT (c->th_runq_idx == (i - LEONBARE_RUNQ_PREPARE_IDX),
"thread %s has wrong prepare-runq[%d] index (%d) ",
LEONBARE_TH_NAME_DBG (c),
i - LEONBARE_RUNQ_PREPARE_IDX, c->th_runq_idx);
LBPASSERT (c->th_runq_which != LEONBARE_KR_RUNQ_WHICH,
"thread %s in prepare-runqueue[%d] has wrong th_runq_which(%d) (==LEONBARE_KR_RUNQ_WHICH(%d))",
LEONBARE_TH_NAME_DBG (c), i, c->th_runq_which,
LEONBARE_KR_RUNQ_WHICH);
}
if (i != LEONBARE_RUNQ_KILLED_IDX)
{
LBPASSERT (!
(c->
th_flags & (LEONBARE_TH_TERMINATED |
LEONBARE_TH_FINISHED)),
"thread %s not in killed queue has (LEONBARE_TH_TERMINATED | LEONBARE_TH_FINISHED) set ",
LEONBARE_TH_NAME_DBG (c));
}
if (i != LEONBARE_RUNQ_SUSPENDED_IDX)
{
LBPASSERT (!(c->th_flags & (LEONBARE_TH_SUSPENDED)),
"thread %s not in suspend queue has LEONBARE_TH_SUSPENDED set ",
LEONBARE_TH_NAME_DBG (c));
}
if (LBTAILQ_NEXT (c, th_runq))
{
LBPASSERT (c->th_account <=
LBTAILQ_NEXT (c, th_runq)->th_account,
"thread %s account is not sorted (%d<=%d)",
LEONBARE_TH_NAME_DBG (c), c->th_account,
LBTAILQ_NEXT (c, th_runq)->th_account);
}
}
}
LBTAILQ_FOREACH (c, LEONBARE_KR_ALLQ, th_allq)
{
if ((j = c->th_runq_idx) != -1)
{
LBPASSERT (j >= 0
&& j < LEONBARE_RUNQ_NR,
"thread %s has wrong runq index (%d) ",
LEONBARE_TH_NAME_DBG (c), c->th_runq_idx);
LBTAILQ_FOREACH (d, LEONBARE_KR_RUNQ (j), th_runq)
{
if (d == c)
{
break;
}
}
/*LBPASSERT(d,"thread %s is not in runq[%d] ",LEONBARE_TH_NAME_DBG(c),j); */
}
}
#endif
}
int
leonbare_debug_printf (const char *fmt, ...)
{
va_list ap;
va_start (ap, fmt);
vprintf (fmt, ap);
va_end (ap);
return 0;
}
void
leonbare_sched_printqueue ()
{
int i, j;
leonbare_thread_t c;
for (i = 0; i < LEONBARE_RUNQ_NR; i++)
{
LBDEBUG_HEADER_PRINTF (LBDEBUG_QUEUE_NR, "runq[%d]:[", i);
LBTAILQ_FOREACH (c, LEONBARE_KR_RUNQ (i), th_runq)
{
LBDEBUG (LBDEBUG_QUEUE_NR, "%s[0x%x](%d),", LEONBARE_TH_NAME_DBG (c),
c, c->th_account);
}
LBDEBUG (LBDEBUG_QUEUE_NR, "]\n", 0);
}
}

View File

@ -0,0 +1,35 @@
/*
* Copyright (c) 2011 Aeroflex Gaisler
*
* BSD license:
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
#include <asm-leon/queue.h>
/*#include <sys/fsu_pthread_queue.h>*/
#include <asm-leon/contextswitch.h>
#include <asm-leon/leonbare_kernel.h>
#include <asm-leon/leonbare_debug.h>
#include <asm-leon/stack.h>
#include <asm-leon/leonstack.h>
#include <stdarg.h>
int leonbare_debug = -1;

View File

@ -0,0 +1,31 @@
/*
* Copyright (c) 2011 Aeroflex Gaisler
*
* BSD license:
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
#include <asm-leon/contextswitch.h>
#include <asm-leon/leonbare_kernel.h>
#include <asm-leon/leonbare_debug.h>
#include <asm-leon/stack.h>
#include <asm-leon/leonstack.h>
#include <asm-leon/irq.h>

View File

@ -0,0 +1,107 @@
/*
* Copyright (c) 2011 Aeroflex Gaisler
*
* BSD license:
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
#include <asm-leon/queue.h>
/*#include <sys/fsu_pthread_queue.h>*/
#include <asm-leon/contextswitch.h>
#include <asm-leon/leonbare_kernel.h>
#include <asm-leon/leonbare_debug.h>
#include <asm-leon/stack.h>
#include <asm-leon/leonstack.h>
#include <asm-leon/irq.h>
leonbare_mutex_t
leonbare_mutex_init (leonbare_mutex_t m)
{
m->mx_owner_cnt = 0;
m->mx_owner = 0;
LBTAILQ_INIT (&(m->mx_threads));
LEONBARE_PROTECT_KERNEL_START ();
{
LBTAILQ_INSERT_TAIL (LEONBARE_KR_ALLM, m, mx_allm);
}
LEONBARE_PROTECT_KERNEL_END ();
}
int
_self__leonbare_mutex_lock (leonbare_mutex_t m, int wait)
{
int ret = LEONBARE_MUTEX_LOCK_OK;
leonbare_thread_t c;
LEONBARE_PROTECT_MUTEXSTRUCT_START (m);
while (1)
{
if (LEONBARE_MUTEX_OWNER_GET (m) == 0)
{
LEONBARE_MUTEX_OWNER_SET (m, LEONBARE_KR_CURRENT);
LEONBARE_MUTEX_OWNER_CNT_SET (m, 0);
LBTAILQ_INSERT_TAIL (&c->th_mutex_locked, m, mx_locked);
ret = LEONBARE_MUTEX_LOCK_OK;
break;
}
else if (m->mx_owner == LEONBARE_KR_CURRENT)
{
m->mx_owner_cnt++;
ret = LEONBARE_MUTEX_LOCK_OK;
break;
}
LBTAILQ_INSERT_TAIL (&m->mx_threads, c, th_mutex);
current_suspend ();
}
LEONBARE_PROTECT_MUTEXSTRUCT_END (m);
return ret;
}
int
leonbare_mutex_unlock (leonbare_mutex_t m)
{
int ret = LEONBARE_MUTEX_UNLOCK_ERROR;
leonbare_thread_t c, h;
LEONBARE_PROTECT_MUTEXSTRUCT_START (m);
{
c = LEONBARE_KR_CURRENT;
if (m->mx_owner != c)
{
ret = LEONBARE_MUTEX_UNLOCK_OK;
}
else if (m->mx_owner == c && m->mx_owner_cnt)
{
m->mx_owner_cnt--;
ret = LEONBARE_MUTEX_UNLOCK_OK;
}
else if ((h = LBTAILQ_FIRST (&m->mx_threads)))
{
LBTAILQ_REMOVE (&m->mx_threads, h, th_mutex);
leonbare_thread_resume (h);
ret = LEONBARE_MUTEX_UNLOCK_OK;
}
}
LEONBARE_PROTECT_MUTEXSTRUCT_END (m);
return ret;
}

View File

@ -0,0 +1,59 @@
/*
* Copyright (c) 2011 Aeroflex Gaisler
*
* BSD license:
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
#include <asm-leon/queue.h>
/*#include <sys/fsu_pthread_queue.h>*/
#include <asm-leon/contextswitch.h>
#include <asm-leon/leonbare_kernel.h>
#include <asm-leon/leonbare_debug.h>
#include <asm-leon/stack.h>
#include <asm-leon/leonstack.h>
#include <asm-leon/irq.h>
int
leonbare_thread_getqueueidx (leonbare_thread_t thread)
{
LEONBARE_VERIFYSCHED ();
if (thread->th_flags & (LEONBARE_TH_TERMINATED | LEONBARE_TH_FINISHED))
{
return LEONBARE_RUNQ_KILLED_IDX;
}
else if ((thread->th_flags & LEONBARE_TH_SUSPENDED))
{
return LEONBARE_RUNQ_SUSPENDED_IDX;
}
else if (LEONBARE_RUNQ_ISREADY (thread->th_runq_idx))
{
if (LEONBARE_KR_RUNQ_WHICH == thread->th_runq_which)
{
return thread->th_runq_idx;
}
else
{
return thread->th_runq_idx + LEONBARE_RUNQ_PREPARE_IDX;
}
}
return -1;
}

View File

@ -0,0 +1,84 @@
/*
* Copyright (c) 2011 Aeroflex Gaisler
*
* BSD license:
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
#include <asm-leon/contextswitch.h>
#include <asm-leon/leonbare_kernel.h>
#include <asm-leon/leonbare_debug.h>
#include <asm-leon/stack.h>
#include <asm-leon/leonstack.h>
#include <asm-leon/irq.h>
unsigned int
reschedule ()
{
leonbare_sched_update ();
return leonbare_sched ();
}
unsigned int
leonbare_sched ()
{
unsigned int ret = 0;
volatile leonbare_thread_t old = LEONBARE_KR_CURRENT, new =
LEONBARE_KR_NEXT;
LBDEBUG_FNCALL;
LBDEBUG_HEADER_PRINTF (LBDEBUG_SCHED_NR, "switch %s[%x]->%s[%x]\n",
LEONBARE_TH_NAME_DBG (old), old,
LEONBARE_TH_NAME_DBG (new), new);
LBPASSERT ((old != new),
"leonbare_sched should only be called with reschedule work to do",
0);
LEONBARE_KR_CURRENT = new;
/* to be able to programm symetrically on kernel level each thread
saves it's spinlock on mutexes and kernel and irq flags in its
own save region. On a kernel switch they are released until the
thread is reawakened. Then the locks will be reaquired (and finally
released when the codeblock exits). The locking can be recursive. */
if (old->th_prot.krp_k_depth)
{
LEONBARE_SMP_SPINLOCK_RELEASE (LEONBARE_KR_LOCK);
}
if (old->th_prot.krp_m_depth)
{
LEONBARE_SMP_SPINLOCK_RELEASE (old->th_prot.krp_m);
}
ret = _leonbare_kernel_switchto (old, new);
optbarrier ();
if (new->th_prot.krp_m_depth)
{
LEONBARE_SMP_SPINLOCK_AQUIRE (new->th_prot.krp_m);
}
if (old->th_prot.krp_k_depth)
{
LEONBARE_SMP_SPINLOCK_AQUIRE (LEONBARE_KR_LOCK);
}
return ret;
}

View File

@ -0,0 +1,214 @@
/*
* Copyright (c) 2011 Aeroflex Gaisler
*
* BSD license:
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
#include <asm-leon/queue.h>
/*#include <sys/fsu_pthread_queue.h>*/
#include <asm-leon/contextswitch.h>
#include <asm-leon/leonbare_kernel.h>
#include <asm-leon/leonbare_debug.h>
#include <asm-leon/stack.h>
#include <asm-leon/leonstack.h>
#include <asm-leon/irq.h>
int
leonbare_thread_resume (leonbare_thread_t thread)
{
leonbare_thread_t i = 0;
if ((thread->th_flags & LEONBARE_TH_SUSPENDED) &&
!(thread->th_flags & (LEONBARE_TH_TERMINATED | LEONBARE_TH_FINISHED)))
{
LEONBARE_PROTECT_KERNEL_START ();
{
unsigned int idx = leonbare_thread_getqueueidx (thread);
if (idx != -1)
{
LBTAILQ_REMOVE (LEONBARE_KR_RUNQ (idx), thread, th_runq);
}
if (thread->th_pri_idx != -1)
{
thread->th_runq_idx = thread->th_pri_idx;
thread->th_runq_which = LEONBARE_KR_RUNQ_WHICH;
LBTAILQ_INSERT_HEAD (LEONBARE_KR_RUNQ (thread->th_runq_idx),
thread, th_runq);
LEONBARE_TH_SETSTATE (thread, LEONBARE_TH_READY);
}
}
LEONBARE_PROTECT_KERNEL_END ();
}
}
int
leonbare_thread_terminate (leonbare_thread_t thread)
{
unsigned int ret = 0;
leonbare_thread_t c = LEONBARE_KR_CURRENT;
LEONBARE_PROTECT_KERNEL_START ();
{
unsigned int idx = leonbare_thread_getqueueidx (thread);
if (LEONBARE_RUNQ_ISREADY (idx) || LEONBARE_RUNQ_ISPREPARE (idx) ||
LEONBARE_RUNQ_ISSUSPEND (idx))
{
LBTAILQ_REMOVE (LEONBARE_KR_RUNQ (idx), thread, th_runq);
}
else
{
LBPASSERT (LEONBARE_RUNQ_ISKILLED (idx),
"thread %s is in no queue ",
LEONBARE_TH_NAME_DBG (thread));
}
LEONBARE_TH_SETSTATE (thread, LEONBARE_TH_TERMINATED);
LBTAILQ_INSERT_HEAD (LEONBARE_KR_RUNQ (LEONBARE_RUNQ_KILLED_IDX), thread,
th_runq);
LEONBARE_PRINTQUEUES ();
LEONBARE_VERIFYSCHED ();
}
if (thread == LEONBARE_KR_CURRENT)
{
ret = reschedule ();
/* never come here */
LEONBARE_STOPALL;
}
LEONBARE_PROTECT_KERNEL_END ();
return ret;
}
int
current_suspend ()
{
unsigned int ret = 0;
leonbare_thread_t c = LEONBARE_KR_CURRENT;
LEONBARE_PROTECT_KERNEL_START ();
{
LBPASSERT ((c->th_runq_which == LEONBARE_KR_RUNQ_WHICH),
"Current thread cannot be on the prepare queue", 0);
LBTAILQ_REMOVE (LEONBARE_KR_RUNQ (c->th_runq_idx), c, th_runq);
LBTAILQ_INSERT_TAIL (LEONBARE_KR_RUNQ (LEONBARE_RUNQ_SUSPENDED_IDX),
c, th_runq);
c->th_runq_idx = LEONBARE_RUNQ_SUSPENDED_IDX;
LEONBARE_TH_SETSTATE (c, LEONBARE_TH_SUSPENDED);
LEONBARE_VERIFYSCHED ();
}
ret = reschedule ();
LEONBARE_PROTECT_KERNEL_END ();
return ret;
}
void
_leonbare_thread_body ()
{
LBDEBUG_FNCALL;
leonbare_thread_t thread = LEONBARE_KR_CURRENT;
LEONBARE_KR_IS_IN_KERNEL = 0;
thread->th_result = thread->th_func (thread->th_arg);
leonbare_thread_terminate (thread);
LBDEBUG_FNEXIT;
}
#define LEONBARE_BODY_OFFSET 200
int
leonbare_thread_create (struct leonbare_thread *thread, char *stack,
int stacksize)
{
LEONBARE_PROTECT_DECL (flags);
struct sparc_stackframe_regs *sp;
unsigned int v;
unsigned int fpspill, bodysp, bodyfp;
struct leonbare_thread_ctx *threadctx;
LBDEBUG_FNCALL;
thread->th_stack_base = (char *) LEONBARE_STACKALIGN (stack);
stacksize -= thread->th_stack_base - stack;
thread->th_stack_size = stacksize;
thread->th_runq_idx = 0;
thread->th_pri_idx = 0;
thread->th_account = 0;
thread->th_caccount = 0;
/* stack:
* 0:+--------------------------------+ <- thread.th_stack_base
* | .... |
* +--------------------------------+ <- thread.th_ctx->out[6] (%sp)
* | _leonbare_thread_body() frame |
* +--------------------------------+ <- thread.th_ctx->sf_ins[6] (%fp)
* | WINDOWSPILL |
* +--------------------------------+ <- thread.th_ctx->fpu
* | struct sparc_fpuwindow_regs |
* +--------------------------------+ <- thread.th_stack_base + thread->th_stack_size
*
*/
v = (unsigned int) (thread->th_stack_base +
LEONBARE_STACKALIGN (thread->th_stack_size -
(LEONBARE_BODY_OFFSET +
WINDOWSIZE + FW_REGS_SZ)));
bodysp = ((unsigned int) v);
bodyfp = ((unsigned int) bodysp) + LEONBARE_BODY_OFFSET;
fpspill = ((unsigned int) bodyfp) + WINDOWSIZE;
thread->th_ctx.outs[6] = (unsigned int) bodysp;
thread->th_ctx.outs[7] = (int) _leonbare_thread_body;
thread->th_ctx.outs[7] -= 8;
thread->th_ctx.sf_ins[6] = (unsigned int) bodyfp;
thread->th_ctx.fpu = (unsigned int) fpspill;
thread->th_ctx.magic = LEONBARE_THREAD_CTX_MAGIC;
thread->th_ctx.psr = 0x0e0;
thread->th_ctx.wim = 0x2;
LBDEBUG_HEADER_PRINTF (LBDEBUG_THREAD_NR,
"Thread %s (0x%x): stack [0x%x-0x%x] \n",
LEONBARE_TH_NAME_DBG (thread), thread,
thread->th_stack_base,
thread->th_stack_base + thread->th_stack_size);
/* newlibc reent */
thread->th_reentp = &(thread->th_reent);
_REENT_INIT_PTR (thread->th_reentp);
LEONBARE_PROTECT_KERNEL_START ();
/* queues */
LBTAILQ_INSERT_TAIL (LEONBARE_KR_ALLQ, thread, th_allq);
LBTAILQ_INSERT_TAIL (LEONBARE_KR_RUNQ (thread->th_runq_idx), thread,
th_runq);
LEONBARE_PRINTQUEUES ();
LEONBARE_PROTECT_KERNEL_END ();
LBDEBUG_FNEXIT;
}

View File

@ -0,0 +1,143 @@
/*
* Copyright (c) 2011 Aeroflex Gaisler
*
* BSD license:
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
#define LEON3_IO_AREA 0xfff00000
#define LEON3_CONF_AREA 0xff000
#define VENDOR_GAISLER 0x01
#define GAISLER_APBMST 0x006
#define GAISLER_APBUART 0x00C
#define GAISLER_GPTIMER 0x011
.text
/* ------- */
.weak cpuinit
.set cpuinit,_cpuinit
/* ------- */
!.global cpuinit
_cpuinit:
mov %o7,%g6
mov %psr, %l3
srl %l3, 24, %g5
and %g5, 0xf, %g5
subcc %g5, 3, %0
be 1f
/* other versions */
ba 2f
! ####### leon3 #########
1: set 0x01, %o0 !VENDOR_GAISLER
set 0x006, %o1 !GAISLER_APBMST
call ahbslv_scan
nop
cmp %g0,%o0
be 2f
nop
ld [%o0+16],%g1
set 0xfff00000,%o0 !LEON3_IO_AREA
and %g1,%o0,%g1 !g1: apb base
set 0xff000,%o0 !LEON3_CONF_AREA
or %g1,%o0,%g2 !g2: apb conf base
! ####### uart #########
mov %g2,%o0
set 0x01 , %o1 ! VENDOR_GAISLER
set 0x00C,%o2 ! GAISLER_APBUART
call apbslv_scan
nop
cmp %g0,%o0
be 2f
nop
call iobar_getbase
mov %g1,%o1
set console, %g5
st %o1,[%g5] !uart base address
! ####### timer #########
mov %g2,%o0
set 0x01 , %o1 !VENDOR_GAISLER
set 0x011,%o2 !GAISLER_GPTIMER
call apbslv_scan
nop
cmp %g0,%o0
be 2f
nop
call iobar_getbase
mov %g1,%o1
add %o1,0x10,%o1
set rtc, %g5
st %o1,[%g5]
! ################
mov %g2,%o0
set 0x01 , %o1 !VENDOR_GAISLER
set 0x00D,%o2 !GAISLER_IRQMP
call apbslv_scan
nop
cmp %g0,%o0
be 2f
nop
call iobar_getbase
mov %g1,%o1
set irqmp, %g5
st %o1,[%g5]
ld [%o1+0x10], %o2
srl %o2, 16, %o2
and %o2, 15, %o2
st %o2,[%g5+4]
! ################
2: mov %g6,%o7
retl
nop
! force link of jiffies_64
.global jiffies_64
3: set jiffies_64,%g1
.data
.global irqmp
irqmp: .word 0 ! IRQMP base address
.word 0 ! extended irq number
.text

View File

@ -0,0 +1,170 @@
/*
* Copyright (c) 2011 Aeroflex Gaisler
*
* BSD license:
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
/* The traptable has to be the first code in a boot PROM. */
#include <asm-leon/head.h>
#define TRAP(H) mov %psr, %l0; sethi %hi(H), %l4; jmp %l4+%lo(H); nop;
#define TRAPL(H) nop; sethi %hi(H), %g1; jmp %g1+%lo(H); nop;
#define TRAP_ENTRY(H) rd %psr, %l0; b H; rd %wim, %l3; nop;
#define WIM_INIT 2
#ifdef _SOFT_FLOAT
#define PSR_INIT 0x0e0
#else
#define PSR_INIT 0x10e0
#endif
#define NUMREGWINDOWS 8
/* Unexcpected trap will halt the processor by forcing it to error state */
#define BAD_TRAP ta 0; nop; nop; nop;
/* Software trap. Treat as BAD_TRAP */
#define SOFT_TRAP BAD_TRAP
.seg "text"
.global _trap_table, start, _start, cpuinit, leonbare_irq_entry, _hardreset
.global _window_overflow, _window_underflow, _flush_windows, _fpdis_enable
/*.global _nwindows, _leon_version, _nwindows_min1*/
!
! Startup code for standalone system. Wash IU and FPU (if present) registers.
! The registers have to be written to initiate the parity bits.
!
.section .text
/* ------- */
.weak _hardreset
.set _hardreset,_hardreset_libgloss
/* ------- */
.global _hardreset_custom_weak, _hardreset_real, _cleanregs_custom_weak, _hardreset_custom_svt_weak
_hardreset_real:
nop
_hardreset_libgloss:
set _hardreset_custom_weak, %g1 ! possible mkprom init code here, default links to dummy _hardreset_custom_dummy
call %g1
nop
set _trap_table, %g1 ! Initialize TBR
mov %g1, %tbr
set _hardreset_custom_svt_weak, %g1 ! give mkprom svt chance to reset tbr
call %g1
nop
set _cleanregs_custom_weak, %g1
call %g1
nop
#ifdef _FLAT
mov %g0, %wim
#else
/* ! assume that %sp is correct use cwp of psr to set the next window as invalid
mov %psr, %g2 ! extract cwp
and 0x1f, %g2,%g2
set 0x1, %g3
sll %g3,%g2,%g3 ! the bit mask for cwp
sll %g3, 1, %g4 ! rotate one to left
sethi %hi(_nwindows_min1), %g5 ! NWINDOWS-1
ld [%g5+%lo(_nwindows_min1)], %g5
srl %g3, %g5, %g5
or %g5, %g4, %g5
mov %g5, %wim
nop; nop; nop */
#endif
/*
mov %psr, %g2
set 0x202, %g3
sll %g3, %g2, %g2
mov %g2, %wim
nop; nop; nop
1:
*/
! -------------------------------
! only cpu 0 initializes
/* mov %psr, %g5
srl %g5, 24, %g5
and %g5, 3, %g5
subcc %g5, 3, %g0 ! leon2: 0 or 2, leon3: 3
bne callcpuinit
nop
*/
rd %asr17,%g5
srl %g5,28,%g5
cmp %g5,%g0
bne slavego
nop
callcpuinit:
call cpuinit
nop
call pnpinit
nop
slavego:
! -------------------------------
sub %sp, 0x40, %sp ! room for main to save args
call _start
nop
mov 1, %g1
ta 0 ! Halt if _main would return ...
nop
.global _fpdis,_fpdis_svt
_fpdis_svt:
_fpdis:
set 0x1000, %l4
andcc %l0, %l4, %l3
bne,a 4f
andn %l0, %l4, %l0
ta 0
4:
mov %l0, %psr ! restore %psr
nop; nop; nop
jmp %l2 ! Jump to nPC
rett %l2 + 4
/*
!''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
.section .bss
.global _nwindows, _leon_version, _nwindows_min1
_nwindows:
.word 8
_nwindows_min1:
.word 7
_leon_version:
.word 3
*/

View File

@ -0,0 +1,50 @@
/*
* Copyright (c) 2011 Aeroflex Gaisler
*
* BSD license:
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
#include <stddef.h>
#include <stdlib.h>
#include <reent.h>
#include <sys/lock.h>
/*
* Register a function to be performed at exit or on shared library unload.
*/
int
atexit (void (*fn) (void))
{
register struct _atexit *p;
p = _GLOBAL_REENT->_atexit;
if (p == NULL)
_GLOBAL_REENT->_atexit = p = &_GLOBAL_REENT->_atexit0;
if (p->_ind >= _ATEXIT_SIZE)
{
return -1;
}
p->_fns[p->_ind++] = fn;
return 0;
}

View File

@ -0,0 +1,114 @@
/*
* Copyright (c) 2011 Aeroflex Gaisler
*
* BSD license:
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
#include <asm-leon/head.h>
.section .text
/* ------- */
.weak _cleanregs_custom_weak
.set _cleanregs_custom_weak,_cleanregs_donothing
/* ------- */
.global _cleanregs_libgloss
_cleanregs_donothing:
_cleanregs_libgloss:
retl
nop
#define NUMREGWINDOWS 8
//_cleanregs_libgloss:
!''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
! initialize regs with values
//#define REGINIT
#ifdef REGINIT
mov %psr, %g3
mov %wim, %g4
mov %sp, %g5
mov %fp, %g6
mov %o7, %g7
mov %g0, %wim
set 0, %g1
andn %g3,0x1f,%l0
mov %l0,%psr
nop; nop; nop
3: set 0x0001,%i0
set 0x0101,%i1
set 0x0201,%i2
set 0x0301,%i3
set 0x0401,%i4
set 0x0501,%i5
set 0x0601,%i6
set 0x0701,%i7
set 0x0801,%l0
set 0x0901,%l1
set 0x1001,%l2
set 0x1101,%l3
set 0x1201,%l4
set 0x1301,%l5
set 0x1401,%l6
set 0x1501,%l7
or %g1,%i0,%i0
or %g1,%i1,%i1
or %g1,%i2,%i2
or %g1,%i3,%i3
or %g1,%i4,%i4
or %g1,%i5,%i5
or %g1,%i6,%i6
or %g1,%i7,%i7
or %g1,%l0,%l0
or %g1,%l1,%l1
or %g1,%l2,%l2
or %g1,%l3,%l3
or %g1,%l4,%l4
or %g1,%l5,%l5
or %g1,%l6,%l6
or %g1,%l7,%l7
restore
set 0x10000,%g2
add %g1,%g2,%g1
set NUMREGWINDOWS*0x10000,%g2
cmp %g1,%g2
bne 3b
nop
mov %g4,%wim
nop; nop; nop;
mov %g3,%psr
nop; nop; nop;
mov %g5, %sp
mov %g6, %fp
#endif
!''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
jmpl %g7+8,%g0
nop

View File

@ -0,0 +1,170 @@
/*
* Copyright (c) 2011 Aeroflex Gaisler
*
* BSD license:
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
/* The traptable has to be the first code in a boot PROM. */
#include <asm-leon/head.h>
#define TRAP(H) mov %psr, %l0; sethi %hi(H), %l4; jmp %l4+%lo(H); nop;
#define TRAPL(H) mov %g0, %g4; sethi %hi(H), %g4; jmp %g4+%lo(H); nop;
#define TRAP_ENTRY(H) rd %psr, %l0; b H; rd %wim, %l3; nop;
/* srmmu trap */
#define SRMMU_TFAULT rd %psr, %l0; rd %wim, %l3; b _srmmu_fault; mov 1, %l6;
#define SRMMU_DFAULT rd %psr, %l0; rd %wim, %l3; b _srmmu_fault; mov 9, %l6;
#define WIM_INIT 2
#ifdef _SOFT_FLOAT
#define PSR_INIT 0x0e0
#else
#define PSR_INIT 0x10e0
#endif
#define NUMREGWINDOWS 8
/* Unexcpected trap will halt the processor by forcing it to error state */
#define BAD_TRAP ta 0; nop; nop; nop;
/* Software trap. Treat as BAD_TRAP */
#define SOFT_TRAP BAD_TRAP
.seg "text"
.global _trap_table, cpuinit, leonbare_irq_entry, _hardreset, _hardreset_mvt
.global _window_overflow, _window_underflow, _flush_windows, _fpdis_enable
.global start
start:
_trap_table:
TRAPL(_hardreset_mvt); ! 00 reset trap
SRMMU_TFAULT ! 01 instruction_access_exception (in mmu_asm.S)
BAD_TRAP; ! 02 illegal_instruction
BAD_TRAP; ! 03 priveleged_instruction
#ifndef _SOFT_FLOAT
TRAP(_fpdis_enable); ! 04 fp_disabled
#else
TRAP(_fpdis); ! 04 fp_disabled
#endif
#ifndef _FLAT
TRAP(_window_overflow); ! 05 window_overflow
TRAP(_window_underflow); ! 06 window_underflow
#else
BAD_TRAP; BAD_TRAP;
#endif
BAD_TRAP; ! 07 memory_address_not_aligned
BAD_TRAP; ! 08 fp_exception
SRMMU_DFAULT ! 09 data_access_exception (in mmu_asm.S)
BAD_TRAP; ! 0A tag_overflow
BAD_TRAP; ! 0B undefined
BAD_TRAP; ! 0C undefined
BAD_TRAP; ! 0D undefined
BAD_TRAP; ! 0E undefined
BAD_TRAP; ! 0F undefined
BAD_TRAP; ! 10 undefined
/* Interrupt entries */
TRAP_ENTRY_INTERRUPT(1); ! 11 interrupt level 1
TRAP_ENTRY_INTERRUPT(2); ! 12 interrupt level 2
TRAP_ENTRY_INTERRUPT(3); ! 13 interrupt level 3
TRAP_ENTRY_INTERRUPT(4); ! 14 interrupt level 4
TRAP_ENTRY_INTERRUPT(5); ! 15 interrupt level 5
TRAP_ENTRY_INTERRUPT(6); ! 16 interrupt level 6
TRAP_ENTRY_INTERRUPT(7); ! 17 interrupt level 7
TRAP_ENTRY_INTERRUPT(8); ! 18 interrupt level 8
TRAP_ENTRY_INTERRUPT(9); ! 19 interrupt level 9
TRAP_ENTRY_INTERRUPT(10); ! 1A interrupt level 1
TRAP_ENTRY_INTERRUPT(11); ! 1B interrupt level 11
TRAP_ENTRY_INTERRUPT(12); ! 1C interrupt level 12
TRAP_ENTRY_INTERRUPT(13); ! 1D interrupt level 13
TRAP_ENTRY_INTERRUPT(14); ! 1E interrupt level 14
TRAP_ENTRY_INTERRUPT(15); ! 1F interrupt level 15
BAD_TRAP; BAD_TRAP; BAD_TRAP; BAD_TRAP; ! 20 - 23 undefined
BAD_TRAP; ! 24 cp_disabled
BAD_TRAP; BAD_TRAP; BAD_TRAP; ! 25 - 27 undefined
BAD_TRAP; ! 28 cp_exception
BAD_TRAP; BAD_TRAP; BAD_TRAP; ! 29 - 2B undefined
BAD_TRAP; BAD_TRAP; BAD_TRAP; BAD_TRAP; ! 2C - 2F undefined
BAD_TRAP; BAD_TRAP; BAD_TRAP; BAD_TRAP; ! 30 - 33 undefined
BAD_TRAP; BAD_TRAP; BAD_TRAP; BAD_TRAP; ! 34 - 37 undefined
BAD_TRAP; BAD_TRAP; BAD_TRAP; BAD_TRAP; ! 38 - 3B undefined
BAD_TRAP; BAD_TRAP; BAD_TRAP; BAD_TRAP; ! 3C - 3F undefined
BAD_TRAP; BAD_TRAP; BAD_TRAP; BAD_TRAP; ! 40 - 43 undefined
BAD_TRAP; BAD_TRAP; BAD_TRAP; BAD_TRAP; ! 44 - 47 undefined
BAD_TRAP; BAD_TRAP; BAD_TRAP; BAD_TRAP; ! 48 - 4B undefined
BAD_TRAP; BAD_TRAP; BAD_TRAP; BAD_TRAP; ! 4C - 4F undefined
BAD_TRAP; BAD_TRAP; BAD_TRAP; BAD_TRAP; ! 50 - 53 undefined
BAD_TRAP; BAD_TRAP; BAD_TRAP; BAD_TRAP; ! 54 - 57 undefined
BAD_TRAP; BAD_TRAP; BAD_TRAP; BAD_TRAP; ! 58 - 5B undefined
BAD_TRAP; BAD_TRAP; BAD_TRAP; BAD_TRAP; ! 5C - 5F undefined
BAD_TRAP; BAD_TRAP; BAD_TRAP; BAD_TRAP; ! 60 - 63 undefined
BAD_TRAP; BAD_TRAP; BAD_TRAP; BAD_TRAP; ! 64 - 67 undefined
BAD_TRAP; BAD_TRAP; BAD_TRAP; BAD_TRAP; ! 68 - 6B undefined
BAD_TRAP; BAD_TRAP; BAD_TRAP; BAD_TRAP; ! 6C - 6F undefined
BAD_TRAP; BAD_TRAP; BAD_TRAP; BAD_TRAP; ! 70 - 73 undefined
BAD_TRAP; BAD_TRAP; BAD_TRAP; BAD_TRAP; ! 74 - 77 undefined
BAD_TRAP; BAD_TRAP; BAD_TRAP; BAD_TRAP; ! 78 - 7B undefined
BAD_TRAP; BAD_TRAP; BAD_TRAP; BAD_TRAP; ! 7C - 7F undefined
/* Software traps */
SOFT_TRAP; SOFT_TRAP; TRAP(_irqcall); ! 80 - 82
#ifndef _FLAT
TRAP_ENTRY(_flush_windows) ! 83
#else
SOFT_TRAP
#endif
SOFT_TRAP; ! 84
TRAP(_irqcall_disableirq); ! 85
SOFT_TRAP; SOFT_TRAP; ! 86 - 87
SOFT_TRAP; SOFT_TRAP; SOFT_TRAP; SOFT_TRAP; ! 88 - 8B
SOFT_TRAP; SOFT_TRAP; SOFT_TRAP; SOFT_TRAP; ! 8C - 8F
SOFT_TRAP; SOFT_TRAP; SOFT_TRAP; SOFT_TRAP; ! 90 - 93
SOFT_TRAP; SOFT_TRAP; SOFT_TRAP; SOFT_TRAP; ! 94 - 97
SOFT_TRAP; SOFT_TRAP; SOFT_TRAP; SOFT_TRAP; ! 98 - 9B
SOFT_TRAP; SOFT_TRAP; SOFT_TRAP; SOFT_TRAP; ! 9C - 9F
SOFT_TRAP; SOFT_TRAP; SOFT_TRAP; SOFT_TRAP; ! A0 - A3
SOFT_TRAP; SOFT_TRAP; SOFT_TRAP; SOFT_TRAP; ! A4 - A7
SOFT_TRAP; SOFT_TRAP; SOFT_TRAP; SOFT_TRAP; ! A8 - AB
SOFT_TRAP; SOFT_TRAP; SOFT_TRAP; SOFT_TRAP; ! AC - AF
SOFT_TRAP; SOFT_TRAP; SOFT_TRAP; SOFT_TRAP; ! B0 - B3
SOFT_TRAP; SOFT_TRAP; SOFT_TRAP; SOFT_TRAP; ! B4 - B7
SOFT_TRAP; SOFT_TRAP; SOFT_TRAP; SOFT_TRAP; ! B8 - BB
SOFT_TRAP; SOFT_TRAP; SOFT_TRAP; SOFT_TRAP; ! BC - BF
SOFT_TRAP; SOFT_TRAP; SOFT_TRAP; SOFT_TRAP; ! C0 - C3
SOFT_TRAP; SOFT_TRAP; SOFT_TRAP; SOFT_TRAP; ! C4 - C7
SOFT_TRAP; SOFT_TRAP; SOFT_TRAP; SOFT_TRAP; ! C8 - CB
SOFT_TRAP; SOFT_TRAP; SOFT_TRAP; SOFT_TRAP; ! CC - CF
SOFT_TRAP; SOFT_TRAP; SOFT_TRAP; SOFT_TRAP; ! D0 - D3
SOFT_TRAP; SOFT_TRAP; SOFT_TRAP; SOFT_TRAP; ! D4 - D7
SOFT_TRAP; SOFT_TRAP; SOFT_TRAP; SOFT_TRAP; ! D8 - DB
SOFT_TRAP; SOFT_TRAP; SOFT_TRAP; SOFT_TRAP; ! DC - DF
SOFT_TRAP; SOFT_TRAP; SOFT_TRAP; SOFT_TRAP; ! E0 - E3
SOFT_TRAP; SOFT_TRAP; SOFT_TRAP; SOFT_TRAP; ! E4 - E7
SOFT_TRAP; SOFT_TRAP; SOFT_TRAP; SOFT_TRAP; ! E8 - EB
SOFT_TRAP; SOFT_TRAP; SOFT_TRAP; SOFT_TRAP; ! EC - EF
SOFT_TRAP; SOFT_TRAP; SOFT_TRAP; SOFT_TRAP; ! F0 - F3
SOFT_TRAP; SOFT_TRAP; SOFT_TRAP; SOFT_TRAP; ! F4 - F7
SOFT_TRAP; SOFT_TRAP; SOFT_TRAP; SOFT_TRAP; ! F8 - FB
SOFT_TRAP; SOFT_TRAP; SOFT_TRAP; SOFT_TRAP; ! FC - FF

View File

@ -0,0 +1,52 @@
/*
* Copyright (c) 2011 Aeroflex Gaisler
*
* BSD license:
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
#include <asm-leon/head.h>
.section .text
/* ------- */
.weak _hardreset_mvt
.set _hardreset_mvt,_hardreset_mvt_ram
/* ------- */
.global _hardreset
_hardreset_mvt_ram:
mov %psr, %g1
srl %g1, 24, %g1
and %g1, 3, %g1
subcc %g1, 3, %g0 ! leon2: 0 or 2, leon3: 3
bne .L2
nop
mov %asr17, %g1 ! set svt
set 1<<13,%g2
andn %g1,%g2,%g1
mov %g1, %asr17
.L2: mov %g0, %g4
sethi %hi(_hardreset), %g4
jmp %g4+%lo(_hardreset);
nop

View File

@ -0,0 +1,44 @@
/*
* Copyright (c) 2011 Aeroflex Gaisler
*
* BSD license:
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
/* The traptable has to be the first code in a boot PROM. */
#include <asm-leon/head.h>
.seg "text"
.global _trap_table, _start_svt_weak
.global start
/* Hardware traps */
/* svt code asumes that %g6 is never used in the code */
start:
_trap_table:
sethi %hi(_start_svt_weak), %g6
jmp %g6+%lo(_start_svt_weak)
nop

View File

@ -0,0 +1,62 @@
/*
* Copyright (c) 2011 Aeroflex Gaisler
*
* BSD license:
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
#include <asm-leon/head.h>
.section .text
/* ------- */
.weak _hardreset_svt
.set _hardreset_svt, __hardreset_svt
/* ------- */
.global _hardreset, _hardreset_svt_real
! reset entry point for single vector trapping. Try enable svt
_hardreset_svt_real:
nop
__hardreset_svt:
mov %psr, %l3
srl %l3, 24, %g5
and %g5, 3, %g5
subcc %g5, 3, %g0 ! leon2: 0 or 2, leon3: 3
bne .L2
nop
mov %asr17, %g5 ! set svt
set 1<<13,%g1
or %g5,%g1,%g5
mov %g5, %asr17
nop; nop; nop
mov %asr17,%g5 ! check svt
andcc %g5, %g1, %g0
beq .L2
nop
set _hardreset,%l3
jmp %l3
nop
.L2: ta 0x0 ! no svt implemented (ether leon2 or svt != 1)
nop

View File

@ -0,0 +1,186 @@
/*
* Copyright (c) 2011 Aeroflex Gaisler
*
* BSD license:
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
/* The traptable has to be the first code in a boot PROM. */
#include <asm-leon/head.h>
#define TRAP(H) mov %psr, %l0; sethi %hi(H), %l4; jmp %l4+%lo(H); nop;
#define TRAPL(H) mov %g0, %l0; sethi %hi(H), %l4; jmp %l4+%lo(H); nop;
#define TRAP_ENTRY(H) rd %psr, %l0; b H; rd %wim, %l3; nop;
#define WIM_INIT 2
#ifdef _SOFT_FLOAT
#define PSR_INIT 0x0e0
#else
#define PSR_INIT 0x10e0
#endif
#define NUMREGWINDOWS 8
/* Unexcpected trap will halt the processor by forcing it to error state */
#define BAD_TRAP ta 0; nop; nop; nop;
/* Software trap. Treat as BAD_TRAP */
#define SOFT_TRAP BAD_TRAP
#define TT_MASK 0xff0 // trap type mask from tbr
#define TT_SHL 4 // shift to get a tbr value
.seg "text"
/* ------- */
.weak _start_svt_weak
.set _start_svt_weak,_start_svt_disp
/* ------- */
.global _trap_table, cpuinit, _hardreset, _hardreset_svt
.global _fpdis_enable_svt,_fpdis_svt,_window_overflow_svt,_window_underflow_svt
.global _leonbare_irq_entry_svt,_irqcall_svt,_flush_windows_svt,_srmmu_fault_svt,_irqcall_disableirq_svt
.global start, _start_svt_real
_start_svt_real:
nop
_start_svt_disp:
rd %tbr, %l3
rd %psr, %l0
! here,locals have been set up as follows:
! %l0 = psr
! %l1 = pc
! %l2 = npc
! %l3 = tbr
and %l3,TT_MASK,%l3
srl %l3,TT_SHL,%l3
/*
struct get {
int start,end,func;
};
struct get table[3] = {
{0,1,..},
{0,0,0},
};
int gettrap(int nr){
struct get *p = table;
while((p->start) || (p->end) || (p->func)) {
if (p->start <= nr && p->end >= nr) {
return p->func;
}
p++;
}
return 0;
}
$sparc-elf-gcc -S gettrap.c -o test.S -O2
*/
#define loc_o0 l3
#define loc_o1 l4
#define loc_o2 l5
#define loc_o3 l6
sethi %hi(trap_table), %loc_o2
or %loc_o2, %lo(trap_table), %loc_o2
mov %loc_o0, %loc_o3
ld [%loc_o2], %loc_o1
.LL13:
cmp %loc_o1, %loc_o3
.LL12:
bg,a .LL11
add %loc_o2, 12, %loc_o2
ld [%loc_o2+4], %loc_o0
cmp %loc_o0, %loc_o3
bge,a .LL1
ld [%loc_o2+8], %loc_o0
add %loc_o2, 12, %loc_o2
.LL11:
ld [%loc_o2], %loc_o0
orcc %loc_o0, 0, %loc_o1
bne .LL12
cmp %loc_o1, %loc_o3
ld [%loc_o2+4], %loc_o0
cmp %loc_o0, 0
bne .LL12
cmp %loc_o1, %loc_o3
ld [%loc_o2+8], %loc_o0
cmp %loc_o0, 0
bne .LL12
cmp %loc_o1, %loc_o3
!not in table
BAD_TRAP
.LL1:
jmp %loc_o0
nop
.global trap_table,svt_trap_table_ext,svt_trap_table_ext_end
.section ".rodata"
.align 4
trap_table:
.long 0,0, _hardreset_svt
.long 1,1, _srmmu_fault_svt ! 01 instruction_access_exception (in mmu_asm.S)
.long 4,4
#ifndef _SOFT_FLOAT
.long _fpdis_enable_svt ! 04 fp_disabled
#else
.long _fpdis_svt ! 04 fp_disabled
#endif
#ifndef _FLAT
.long 5, 5, _window_overflow_svt ! 05 window_overflow
.long 6, 6, _window_underflow_svt ! 06 window_underflow
#endif
.long 9,9, _srmmu_fault_svt ! 09 data_access_exception (in mmu_asm.S)
.long 0x11,0x1f, _leonbare_irq_entry_svt ! 11-1f interrupt level
.long 0x82,0x82, _irqcall_svt ! 82
#ifndef _FLAT
.long 0x83,0x83, _flush_windows_svt ! 83
#endif
.long 0x85,0x85, _irqcall_disableirq_svt ! 85
svt_trap_table_ext:
.long 0,0,0
.long 0,0,0
.long 0,0,0
.long 0,0,0
.long 0,0,0
.long 0,0,0
.long 0,0,0
.long 0,0,0
.long 0,0,0
.long 0,0,0
.long 0,0,0
.long 0,0,0
.long 0,0,0
.long 0,0,0
.long 0,0,0
.long 0,0,0
.long 0,0,0
svt_trap_table_ext_end:
.long 0,0,0

View File

@ -0,0 +1,77 @@
/*
* Copyright (c) 2011 Aeroflex Gaisler
*
* BSD license:
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
.section .text
/* ------- */
.weak _hardreset_custom_weak
.set _hardreset_custom_weak,_hardreset_custom_weak_dummy
/* ------- */
.global _nwindows, _leon_version, _nwindows_min1
_hardreset_custom_weak_dummy:
!''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
! get nwindows and leon version
mov %psr, %l3
srl %l3, 24, %g5
and %g5, 3, %g5
subcc %g5, 3, %g0 ! leon3: 3
bne 1f
nop
set _leon_version,%l0
set 3,%l1
st %l1,[%l0]
mov %asr17, %g5 ! leon3 has nwindows in %asr17
ba 2f
1:
/* other version */
2:
and %g5, 0x1f, %g5
set _nwindows_min1, %l3
st %g5, [%l3]
add %g5,1,%g5
set _nwindows, %l3
st %g5, [%l3]
set _nwindows_min2, %l3
sub %g5,2,%g5
st %g5, [%l3]
!''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
retl
nop
!''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
.section .data
.global _nwindows, _leon_version, _nwindows_min1, _nwindows_min2
_nwindows:
.word 8
_nwindows_min1:
.word 7
_nwindows_min2:
.word 6
_leon_version:
.word 3

View File

@ -0,0 +1,37 @@
/*
* Copyright (c) 2011 Aeroflex Gaisler
*
* BSD license:
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
.section .text
/* ------- */
.weak _hardreset_custom_svt_weak
.set _hardreset_custom_svt_weak,_hardreset_custom_svt_weak_dummy
/* ------- */
_hardreset_custom_svt_weak_dummy:
retl
nop

View File

@ -0,0 +1,45 @@
/*
* Copyright (c) 2011 Aeroflex Gaisler
*
* BSD license:
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
#include <asm-leon/leon.h>
#include <asm-leon/leonstack.h>
#include <asm-leon/asmmacro.h>
.seg "text"
! srmmu trap or data access trap
/* ------- */
.weak _srmmu_fault_svt
.set _srmmu_fault_svt,__srmmu_fault_svt
.weak _srmmu_fault
.set _srmmu_fault,__srmmu_fault
/* ------- */
/* 1 (inst) or 9 (data) in %l6 */
__srmmu_fault_svt:
__srmmu_fault:
ta 0; nop; nop; nop;
jmp %l1 ! Re-execute save.
rett %l2

256
libgloss/sparc_leon/mutex.c Normal file
View File

@ -0,0 +1,256 @@
/*
* Copyright (c) 2011 Aeroflex Gaisler
*
* BSD license:
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
#include <sys/types.h>
#include <sys/lock.h>
#include <asm-leon/queue.h>
/*#include <sys/fsu_pthread_mutex.h>*/
typedef int pthread_protocol_t;
typedef
TAILQ_HEAD (pthread_queue, pthread) *
pthread_queue_t;
#define pthread_mutex_t_defined
typedef struct pthread_mutex
{
struct pthread_queue queue;
char lock;
struct pthread *owner;
int flags;
int count;
int prioceiling;
pthread_protocol_t protocol;
int prev_max_ceiling_prio;
TAILQ_ENTRY (pthread_mutex) dbglist;
char *dbgname;
int _fitothers[16];
} pthread_mutex_t;
typedef struct
{
int flags;
int prioceiling;
pthread_protocol_t protocol;
} pthread_mutexattr_t;
int (*__lbst_pthread_mutex_init) (pthread_mutex_t * __mutex,
pthread_mutexattr_t * __mutex_attr) =
0;
int (*__lbst_pthread_mutex_destroy) (pthread_mutex_t * __mutex) = 0;
int (*__lbst_pthread_mutex_trylock) (pthread_mutex_t * __mutex) = 0;
int (*__lbst_pthread_mutex_lock) (pthread_mutex_t * __mutex) = 0;
int (*__lbst_pthread_mutex_unlock) (pthread_mutex_t * __mutex) = 0;
int (*__lbst_pthread_mutexattr_init) (pthread_mutexattr_t * __attr) = 0;
int (*__lbst_pthread_mutexattr_destroy) (pthread_mutexattr_t * __attr) =
0;
int (*__lbst_pthread_mutexattr_settype) (pthread_mutexattr_t * __attr,
int __kind) = 0;
int ___st_pthread_mutex_init (mutex, attr)
pthread_mutex_t *mutex;
pthread_mutexattr_t *attr;
{
if (__lbst_pthread_mutex_init)
{
return __lbst_pthread_mutex_init (mutex, attr);
}
return 0;
}
int
___st_pthread_mutex_destroy (mutex)
pthread_mutex_t *mutex;
{
if (__lbst_pthread_mutex_destroy)
{
return __lbst_pthread_mutex_destroy (mutex);
}
return 0;
}
int
___st_pthread_mutex_lock (mutex)
pthread_mutex_t *mutex;
{
if (__lbst_pthread_mutex_lock)
{
return __lbst_pthread_mutex_lock (mutex);
}
return 0;
}
int
___st_pthread_mutex_trylock (mutex)
pthread_mutex_t *mutex;
{
if (__lbst_pthread_mutex_trylock)
{
return __lbst_pthread_mutex_trylock (mutex);
}
return 0;
}
int
___st_pthread_mutex_unlock (mutex)
pthread_mutex_t *mutex;
{
if (__lbst_pthread_mutex_unlock)
{
return __lbst_pthread_mutex_unlock (mutex);
}
return 0;
}
int
___st_pthread_mutexattr_init (attr)
pthread_mutexattr_t *attr;
{
if (__lbst_pthread_mutexattr_init)
{
return __lbst_pthread_mutexattr_init (attr);
}
return (0);
}
int
___st_pthread_mutexattr_destroy (attr)
pthread_mutexattr_t *attr;
{
if (__lbst_pthread_mutexattr_destroy)
{
return __lbst_pthread_mutexattr_destroy (attr);
}
return 0;
}
int
___st_pthread_mutexattr_settype (attr, kind)
pthread_mutexattr_t *attr;
int kind;
{
if (__lbst_pthread_mutexattr_settype)
{
return __lbst_pthread_mutexattr_settype (attr, kind);
}
return 0;
}
#include <asm-leon/elfmacro.h>
weak_alias (___st_pthread_mutex_init, __st_pthread_mutex_init)
weak_alias (___st_pthread_mutex_destroy, __st_pthread_mutex_destroy)
weak_alias (___st_pthread_mutex_trylock, __st_pthread_mutex_trylock)
weak_alias (___st_pthread_mutex_lock, __st_pthread_mutex_lock)
weak_alias (___st_pthread_mutex_unlock, __st_pthread_mutex_unlock)
weak_alias (___st_pthread_mutexattr_init, __st_pthread_mutexattr_init)
weak_alias (___st_pthread_mutexattr_destroy, __st_pthread_mutexattr_destroy)
weak_alias (___st_pthread_mutexattr_settype, __st_pthread_mutexattr_settype)
/* /\* #ifndef weak_extern *\/ */
/* /\* #define weak_extern(symbol) _weak_extern (symbol) *\/ */
/* /\* #define _weak_extern(symbol) asm (".weak " #symbol); *\/ */
/* /\* #endif *\/ */
/* /\* weak_extern (__pthread_mutex_init) *\/ */
/* /\* weak_extern (__pthread_mutex_destroy) *\/ */
/* /\* weak_extern (__pthread_mutex_lock) *\/ */
/* /\* weak_extern (__pthread_mutex_trylock) *\/ */
/* /\* weak_extern (__pthread_mutex_unlock) *\/ */
/* /\* weak_extern (__pthread_mutexattr_init) *\/ */
/* /\* weak_extern (__pthread_mutexattr_destroy) *\/ */
/* /\* weak_extern (__pthread_mutexattr_settype) *\/ */
/* /\* weak_extern (__pthread_once) *\/ */
/* /\* weak_extern (__pthread_initialize) *\/ */
/* /\* Initialize the named lock variable, leaving it in a consistent, unlocked */
/* state. *\/ */
/* #define __libc_lock_init(NAME) \ */
/* (__pthread_mutex_init != NULL ? __pthread_mutex_init (&(NAME), NULL) : 0); */
/* /\* Same as last but this time we initialize a recursive mutex. *\/ */
/* #define __libc_lock_init_recursive(NAME) \ */
/* do { \ */
/* if (__pthread_mutex_init != NULL) \ */
/* { \ */
/* pthread_mutexattr_t __attr; \ */
/* __pthread_mutexattr_init (&__attr); \ */
/* __pthread_mutexattr_settype (&__attr, PTHREAD_MUTEX_RECURSIVE_NP); \ */
/* __pthread_mutex_init (&(NAME), &__attr); \ */
/* __pthread_mutexattr_destroy (&__attr); \ */
/* } \ */
/* } while (0); */
/* /\* Finalize the named lock variable, which must be locked. It cannot be */
/* used again until __libc_lock_init is called again on it. This must be */
/* called on a lock variable before the containing storage is reused. *\/ */
/* //#define __libc_lock_fini(NAME) (__pthread_mutex_destroy != NULL ? __pthread_mutex_destroy (&(NAME)) : 0) */
/* #define __libc_lock_fini(NAME) (__st_pthread_mutex_destroy (&(NAME))) */
/* /\* Finalize recursive named lock. *\/ */
/* #define __libc_lock_fini_recursive(NAME) __libc_lock_fini (NAME) */
/* /\* Lock the named lock variable. *\/ */
/* //#define __libc_lock_lock(NAME) (__pthread_mutex_lock != NULL ? __pthread_mutex_lock (&(NAME)) : 0) */
/* #define __libc_lock_lock(NAME) (__st_pthread_mutex_lock (&(NAME))) */
/* /\* Lock the recursive named lock variable. *\/ */
/* #define __libc_lock_lock_recursive(NAME) __libc_lock_lock (NAME) */
/* /\* Try to lock the named lock variable. *\/ */
/* //#define __libc_lock_trylock(NAME) (__pthread_mutex_trylock != NULL ? __pthread_mutex_trylock (&(NAME)) : 0) */
/* #define __libc_lock_trylock(NAME) (__st_pthread_mutex_trylock (&(NAME))) */
/* /\* Try to lock the recursive named lock variable. *\/ */
/* #define __libc_lock_trylock_recursive(NAME) __libc_lock_trylock (NAME) */
/* /\* Unlock the named lock variable. *\/ */
/* //#define __libc_lock_unlock(NAME) (__pthread_mutex_unlock != NULL ? __pthread_mutex_unlock (&(NAME)) : 0) */
/* #define __libc_lock_unlock(NAME) (__st_pthread_mutex_unlock (&(NAME))) */
/* /\* Unlock the recursive named lock variable. *\/ */
/* #define __libc_lock_unlock_recursive(NAME) __libc_lock_unlock (NAME) */
/* extern int __st_pthread_mutex_init (pthread_mutex_t *__mutex, pthread_mutexattr_t *__mutex_attr); */
/* extern int __st_pthread_mutex_destroy (pthread_mutex_t *__mutex); */
/* extern int __st_pthread_mutex_trylock (pthread_mutex_t *__mutex); */
/* extern int __st_pthread_mutex_lock (pthread_mutex_t *__mutex); */
/* extern int __st_pthread_mutex_unlock (pthread_mutex_t *__mutex); */
/* extern int __st_pthread_mutexattr_init (pthread_mutexattr_t *__attr); */
/* extern int __st_pthread_mutexattr_destroy (pthread_mutexattr_t *__attr); */
/* extern int __st_pthread_mutexattr_settype (pthread_mutexattr_t *__attr, int __kind); */
/* /\* /\\* Functions that are used by this file and are internal to the GNU C library. *\\/ *\/ */
/* /\* extern int __pthread_mutex_init (pthread_mutex_t *__mutex, pthread_mutexattr_t *__mutex_attr); *\/ */
/* /\* extern int __pthread_mutex_destroy (pthread_mutex_t *__mutex); *\/ */
/* /\* extern int __pthread_mutex_trylock (pthread_mutex_t *__mutex); *\/ */
/* /\* extern int __pthread_mutex_lock (pthread_mutex_t *__mutex); *\/ */
/* /\* extern int __pthread_mutex_unlock (pthread_mutex_t *__mutex); *\/ */
/* /\* extern int __pthread_mutexattr_init (pthread_mutexattr_t *__attr); *\/ */
/* /\* extern int __pthread_mutexattr_destroy (pthread_mutexattr_t *__attr); *\/ */
/* /\* extern int __pthread_mutexattr_settype (pthread_mutexattr_t *__attr, int __kind); *\/ */
/* /\* /\\* Make the pthread functions weak so that we can elide them from *\/ */
/* /\* single-threaded processes. *\\/ *\/ */
/* /\* #ifndef weak_extern *\/ */
/* /\* #define weak_extern(symbol) _weak_extern (symbol) *\/ */
/* /\* #define _weak_extern(symbol) asm (".weak " #symbol); *\/ */
/* /\* #endif *\/ */
/* /\* weak_extern (__pthread_mutex_init) *\/ */
/* /\* weak_extern (__pthread_mutex_destroy) *\/ */
/* /\* weak_extern (__pthread_mutex_lock) *\/ */
/* /\* weak_extern (__pthread_mutex_trylock) *\/ */
/* /\* weak_extern (__pthread_mutex_unlock) *\/ */
/* /\* weak_extern (__pthread_mutexattr_init) *\/ */
/* /\* weak_extern (__pthread_mutexattr_destroy) *\/ */
/* /\* weak_extern (__pthread_mutexattr_settype) *\/ */
/* /\* weak_extern (__pthread_once) *\/ */
/* /\* weak_extern (__pthread_initialize) *\/ */

View File

@ -0,0 +1,117 @@
/*
* Copyright (c) 2011 Aeroflex Gaisler
*
* BSD license:
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
#include <asm-leon/elfmacro.h>
#include <asm-leon/leon.h>
#include <asm-leon/leonstack.h>
#include <asm-leon/contextswitch.h>
#include <asm-leon/winmacros.h>
#include <asm-leon/leonbare_kernel.h>
FUNC_EXPORT(leonbare_leon23_loadnocache)
FUNC_EXPORT(leonbare_leon23_loadnocache16)
FUNC_EXPORT(leonbare_leon23_loadnocache8)
FUNC_EXPORT(leonbare_leon3_loadnocache)
FUNC_EXPORT(leonbare_leon3_loadnocache16)
FUNC_EXPORT(leonbare_leon3_loadnocache8)
FUNC_EXPORT(leonbare_leon23_storenocache)
FUNC_EXPORT(leonbare_leon23_storenocache16)
FUNC_EXPORT(leonbare_leon23_storenocache8)
FUNC_IMPORT(_leon_version)
.text
/* =================================== */
/* LEON2 / 3 */
/* load with forceing cache miss */
FUNC_BEGIN(leonbare_leon23_loadnocache) /* use only %o0,%o1,%o7 */
lda [%o0] ASI_LEON3_CACHEMISS, %o0
retl
nop
FUNC_END(leonbare_leon23_loadnocache)
/* load with forceing cache miss */
FUNC_BEGIN(leonbare_leon23_loadnocache16)
lduha [%o0] ASI_LEON3_CACHEMISS, %o0
retl
nop
FUNC_END(leonbare_leon23_loadnocache16)
/* load with forceing cache miss */
FUNC_BEGIN(leonbare_leon23_loadnocache8)
lduba [%o0] ASI_LEON3_CACHEMISS, %o0
retl
nop
FUNC_END(leonbare_leon23_loadnocache8)
/* write through cache */
FUNC_BEGIN(leonbare_leon23_storenocache) /* use only %o0,%o1,%o7 */
st %o1, [%o0]
retl
mov %o1,%o0
FUNC_END(leonbare_leon23_storenocache)
/* write through cache */
FUNC_BEGIN(leonbare_leon23_storenocache16)
sth %o1, [%o0]
retl
mov %o1,%o0
FUNC_END(leonbare_leon23_storenocache16)
/* write through cache */
FUNC_BEGIN(leonbare_leon23_storenocache8)
stb %o1, [%o0]
retl
mov %o1,%o0
FUNC_END(leonbare_leon23_storenocache8)
/* =================================== */
/* LEON3 only */
/* load with forceing cache miss */
FUNC_BEGIN(leonbare_leon3_loadnocache) /* use only %o0,%o1,%o7 */
retl
lda [%o0] ASI_LEON3_CACHEMISS, %o0
FUNC_END(leonbare_leon3_loadnocache)
/* load with forceing cache miss */
FUNC_BEGIN(leonbare_leon3_loadnocache16)
retl
lduha [%o0] ASI_LEON3_CACHEMISS, %o0
FUNC_END(leonbare_leon3_loadnocache16)
/* load with forceing cache miss */
FUNC_BEGIN(leonbare_leon3_loadnocache8)
retl
lduba [%o0] ASI_LEON3_CACHEMISS, %o0
FUNC_END(leonbare_leon3_loadnocache8)

View File

@ -0,0 +1,430 @@
/*
* Copyright (c) 2011 Aeroflex Gaisler
*
* BSD license:
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
#include <asm-leon/amba.h>
#undef AMBA_TYPE_AHBIO_ADDR
#include <asm-leon/lambapp.h>
#include <string.h>
#define AMBA_CONF_AREA 0xff000
#define AMBA_AHB_SLAVE_CONF_AREA (1 << 11)
#define AMBA_APB_SLAVES 16
#ifdef PDEBUG
#define DPRINTF(p) printf p
#else
#define DPRINTF(p)
#endif
unsigned int
ambapp_addr_from (struct ambapp_mmap *mmaps, unsigned int address)
{
/* no translation? */
if (!mmaps)
return address;
while (mmaps->size)
{
if ((address >= mmaps->remote_adr)
&& (address <= (mmaps->remote_adr + (mmaps->size - 1))))
{
return (address - mmaps->remote_adr) + mmaps->local_adr;
}
mmaps++;
}
return 1;
}
static void
ambapp_ahb_dev_init (unsigned int ioarea,
struct ambapp_mmap *mmaps,
struct ambapp_pnp_ahb *ahb, struct ambapp_dev_hdr *dev)
{
int bar;
struct ambapp_ahb_info *ahb_info;
unsigned int addr, mask, mbar;
/* Setup device struct */
dev->vendor = ambapp_pnp_vendor (ahb->id);
dev->device = ambapp_pnp_device (ahb->id);
ahb_info = dev->devinfo;
ahb_info->ver = ambapp_pnp_ver (ahb->id);
ahb_info->irq = ambapp_pnp_irq (ahb->id);
ahb_info->custom[0] = (unsigned int) ahb->custom[0];
ahb_info->custom[1] = (unsigned int) ahb->custom[1];
ahb_info->custom[2] = (unsigned int) ahb->custom[2];
DPRINTF (("+AHB device %d:%d\n", dev->device, dev->vendor));
/* Memory BARs */
for (bar = 0; bar < 4; bar++)
{
mbar = ahb->mbar[bar];
if (mbar == 0)
{
addr = 0;
mask = 0;
}
else
{
addr = ambapp_pnp_start (mbar);
if (ambapp_pnp_mbar_type (mbar) == AMBA_TYPE_AHBIO)
{
/* AHB I/O area is releative IO_AREA */
addr = AMBA_TYPE_AHBIO_ADDR (addr, ioarea);
mask =
(((unsigned int) (ambapp_pnp_mbar_mask ((~mbar)) << 8) |
0xff)) + 1;
}
else
{
/* AHB memory area, absolute address */
addr = ambapp_addr_from (mmaps, addr);
mask =
(~((unsigned int) (ambapp_pnp_mbar_mask (mbar) << 20))) + 1;
}
}
ahb_info->start[bar] = addr;
ahb_info->mask[bar] = mask;
}
}
static void
ambapp_apb_dev_init (unsigned int base,
struct ambapp_mmap *mmaps,
struct ambapp_pnp_apb *apb, struct ambapp_dev_hdr *dev)
{
struct ambapp_apb_info *apb_info;
/* Setup device struct */
dev->vendor = ambapp_pnp_vendor (apb->id);
dev->device = ambapp_pnp_device (apb->id);
apb_info = dev->devinfo;
apb_info->ver = ambapp_pnp_ver (apb->id);
apb_info->irq = ambapp_pnp_irq (apb->id);
apb_info->start = ambapp_pnp_apb_start (apb->iobar, base);
apb_info->mask = ambapp_pnp_apb_mask (apb->iobar);
DPRINTF (("+APB device %d:%d\n", dev->device, dev->vendor));
}
#define MAX_NUM_BUSES 16
static void
ambapp_add_scanned_bus (unsigned int *ioareas, unsigned int ioarea)
{
int i;
for (i = 0; i < MAX_NUM_BUSES; i++)
{
if (ioareas[i] == 0)
{
ioareas[i] = ioarea;
return;
}
}
}
static int
ambapp_has_been_scanned (unsigned int *ioareas, unsigned int ioarea)
{
int i;
if (!ioareas)
return 0;
for (i = 0; i < MAX_NUM_BUSES; i++)
{
if (ioareas[i] == 0)
{
break;
}
else if (ioareas[i] == ioarea)
{
return 1;
}
}
return 0;
}
static int
ambapp_find (unsigned int ioarea,
struct ambapp_dev_hdr *parent,
struct ambapp_mmap *mmaps,
void *internal,
int (*find_match) (struct ambapp_dev_hdr * dev, void *arg),
void *arg, int vendor, int device)
{
struct ambapp_pnp_ahb *ahb, ahb_buf;
struct ambapp_pnp_apb *apb, apb_buf;
struct ambapp_dev_hdr *dev, *prev, *prevapb, *apbdev;
struct ambapp_ahb_info *ahb_info;
int maxloops = 64;
unsigned int apbbase, bridge_address;
int i, j;
DPRINTF (("Scan at 0x%08x\n", ioarea));
if (parent)
{
/* scan first bus for 64 devices, rest for 16 devices */
maxloops = 16;
}
else
{
if (internal)
{
ambapp_add_scanned_bus (internal, ioarea);
}
}
prev = parent;
/* AHB MASTERS */
ahb = (struct ambapp_pnp_ahb *) (ioarea | AMBA_CONF_AREA);
for (i = 0; i < maxloops; i++)
{
memcpy (&ahb_buf, ahb, sizeof (struct ambapp_pnp_ahb));
if (ahb_buf.id != 0)
{
struct ambapp_dev_hdr _dev;
struct ambapp_ahb_info _ahb;
memset (&_dev, 0, sizeof (_dev));
memset (&_ahb, 0, sizeof (_ahb));
_dev.devinfo = &_ahb;
_dev.dev_type = DEV_AHB_MST;
dev = &_dev;
ambapp_ahb_dev_init (ioarea, mmaps, &ahb_buf, dev);
DPRINTF ((" = test %d:%d == %d:%d\n", vendor, device, dev->vendor,
dev->device));
if (vendor == dev->vendor &&
device == dev->device && find_match (dev, arg))
{
return 1;
}
}
ahb++;
}
/* AHB SLAVES */
ahb =
(struct ambapp_pnp_ahb *) (ioarea | AMBA_CONF_AREA |
AMBA_AHB_SLAVE_CONF_AREA);
for (i = 0; i < maxloops; i++)
{
memcpy (&ahb_buf, ahb, sizeof (struct ambapp_pnp_ahb));
if (ahb_buf.id != 0)
{
struct ambapp_dev_hdr _dev;
struct ambapp_ahb_info _ahb;
memset (&_dev, 0, sizeof (_dev));
memset (&_ahb, 0, sizeof (_ahb));
_dev.devinfo = &_ahb;
_dev.dev_type = DEV_AHB_MST;
dev = &_dev;
ambapp_ahb_dev_init (ioarea, mmaps, &ahb_buf, dev);
DPRINTF ((" = test %d:%d == %d:%d\n", vendor, device, dev->vendor,
dev->device));
if (vendor == dev->vendor &&
device == dev->device && find_match (dev, arg))
{
return 1;
}
/* Is it a AHB/AHB Bridge ? */
if ((dev->device == GAISLER_AHB2AHB)
&& (dev->vendor == VENDOR_GAISLER))
{
/* AHB/AHB Bridge Found, recurse down the Bridge */
ahb_info = dev->devinfo;
if (ahb_info->ver)
{
bridge_address =
ambapp_addr_from (mmaps, ahb_info->custom[1]);
DPRINTF (("+(AHBAHB:0x%x)\n", bridge_address));
/* Makes sure bus only scanned once */
if (internal == 0
|| ambapp_has_been_scanned (internal,
bridge_address) == NULL)
{
if (internal)
ambapp_add_scanned_bus (internal, bridge_address);
if (ambapp_find (bridge_address, dev, mmaps, internal,
find_match, arg, vendor, device))
return 1;
}
}
}
else if ((dev->device == GAISLER_APBMST)
&& (dev->vendor == VENDOR_GAISLER))
{
/* AHB/APB Bridge Found, add the APB devices to this AHB Slave's children */
prevapb = dev;
ahb_info = dev->devinfo;
apbbase = ahb_info->start[0];
apb = (struct ambapp_pnp_apb *) (apbbase | AMBA_CONF_AREA);
for (j = 0; j < AMBA_APB_SLAVES; j++)
{
memcpy (&apb_buf, apb, sizeof (struct ambapp_pnp_apb));
if (apb_buf.id)
{
struct ambapp_dev_hdr _apbdev;
struct ambapp_apb_info _apb;
memset (&_apbdev, 0, sizeof (_apbdev));
memset (&_apb, 0, sizeof (_apb));
_apbdev.devinfo = &_apb;
_apbdev.dev_type = DEV_APB_SLV;
apbdev = &_apbdev;
ambapp_apb_dev_init (apbbase, mmaps, &apb_buf, apbdev);
DPRINTF ((" = test %d:%d == %d:%d\n", vendor, device,
apbdev->vendor, apbdev->device));
if (vendor == apbdev->vendor &&
device == apbdev->device &&
find_match (apbdev, arg))
{
return 1;
}
}
apb++;
}
}
}
ahb++;
}
if (parent == NULL)
{
/*free(internal); */
}
return 0;
}
struct ambapp_dev_find_match_arg
{
int index;
int count;
int type;
void *dev;
};
/* AMBA PP find routines */
static int
ambapp_dev_find_match (struct ambapp_dev_hdr *dev, void *arg)
{
struct ambapp_dev_find_match_arg *p = arg;
if (p->index == 0)
{
/* Found controller, stop */
if (p->type == DEV_APB_SLV)
{
*(struct ambapp_apb_info *) p->dev =
*(struct ambapp_apb_info *) dev->devinfo;
p->dev = ((struct ambapp_apb_info *) p->dev) + 1;
}
else
{
*(struct ambapp_ahb_info *) p->dev =
*(struct ambapp_ahb_info *) dev->devinfo;
p->dev = ((struct ambapp_ahb_info *) p->dev) + 1;
}
p->count--;
if (p->count < 1)
return 1;
}
else
{
p->index--;
}
return 0;
}
static int
find_apbslvs_next (int vendor, int device, struct ambapp_apb_info *dev,
int index, int maxno)
{
struct ambapp_dev_find_match_arg arg;
unsigned int busses[MAX_NUM_BUSES];
memset (busses, 0, sizeof (busses));
arg.index = index;
arg.count = maxno;
arg.type = DEV_APB_SLV; /* APB */
arg.dev = dev;
ambapp_find (LEON3_IO_AREA, NULL, NULL, &busses,
ambapp_dev_find_match, &arg, vendor, device);
return maxno - arg.count;
}
int
find_apbslv (int vendor, int device, struct ambapp_apb_info *dev)
{
return find_apbslvs_next (vendor, device, dev, 0, 1);
}
struct ambapp_dev_hdr *ambapp_root = NULL;
unsigned int busses[MAX_NUM_BUSES];
extern unsigned int console;
extern unsigned int rtc;
extern unsigned int irqmp;
void
pnpinit (void)
{
struct ambapp_apb_info dev;
int n;
if ((n = find_apbslv (VENDOR_GAISLER, GAISLER_APBUART, &dev)) == 1)
{
console = dev.start;
DPRINTF (("Found abuart at 0x%x\n", console));
}
if ((n = find_apbslv (VENDOR_GAISLER, GAISLER_GPTIMER, &dev)) == 1)
{
rtc = dev.start + 0x10;
DPRINTF (("Found rtc at 0x%x\n", rtc));
}
if ((n = find_apbslv (VENDOR_GAISLER, GAISLER_IRQMP, &dev)) == 1)
{
irqmp = dev.start;
DPRINTF (("Found irqmp at 0x%x\n", rtc));
}
}

View File

@ -0,0 +1,679 @@
/*
* Copyright (c) 2011 Aeroflex Gaisler
*
* BSD license:
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
#include <asm-leon/amba.h>
#undef AMBA_TYPE_AHBIO_ADDR
#include <asm-leon/lambapp.h>
#include <string.h>
#define AMBA_CONF_AREA 0xff000
#define AMBA_AHB_SLAVE_CONF_AREA (1 << 11)
#define AMBA_APB_SLAVES 16
#define DPRINTF(p) printf p
/* Allocate */
struct ambapp_dev_hdr *
ambapp_alloc_dev_struct (int dev_type)
{
int size = sizeof (struct ambapp_dev_hdr);
struct ambapp_dev_hdr *dev;
if (dev_type == DEV_APB_SLV)
{
size += sizeof (struct ambapp_apb_info);
}
else
{
/* AHB */
size += sizeof (struct ambapp_ahb_info);
}
dev = malloc (size);
if (dev == NULL)
return NULL;
memset (dev, 0, size);
dev->devinfo = (void *) (dev + 1);
dev->dev_type = dev_type;
return dev;
}
unsigned int
ambapp_addr_from (struct ambapp_mmap *mmaps, unsigned int address)
{
/* no translation? */
if (!mmaps)
return address;
while (mmaps->size)
{
if ((address >= mmaps->remote_adr)
&& (address <= (mmaps->remote_adr + (mmaps->size - 1))))
{
return (address - mmaps->remote_adr) + mmaps->local_adr;
}
mmaps++;
}
return 1;
}
void
ambapp_ahb_dev_init (unsigned int ioarea,
struct ambapp_mmap *mmaps,
struct ambapp_pnp_ahb *ahb, struct ambapp_dev_hdr *dev)
{
int bar;
struct ambapp_ahb_info *ahb_info;
unsigned int addr, mask, mbar;
/* Setup device struct */
dev->vendor = ambapp_pnp_vendor (ahb->id);
dev->device = ambapp_pnp_device (ahb->id);
ahb_info = dev->devinfo;
ahb_info->ver = ambapp_pnp_ver (ahb->id);
ahb_info->irq = ambapp_pnp_irq (ahb->id);
ahb_info->custom[0] = (unsigned int) ahb->custom[0];
ahb_info->custom[1] = (unsigned int) ahb->custom[1];
ahb_info->custom[2] = (unsigned int) ahb->custom[2];
DPRINTF (("+AHB device %d:%d\n", dev->device, dev->vendor));
/* Memory BARs */
for (bar = 0; bar < 4; bar++)
{
mbar = ahb->mbar[bar];
if (mbar == 0)
{
addr = 0;
mask = 0;
}
else
{
addr = ambapp_pnp_start (mbar);
if (ambapp_pnp_mbar_type (mbar) == AMBA_TYPE_AHBIO)
{
/* AHB I/O area is releative IO_AREA */
addr = AMBA_TYPE_AHBIO_ADDR (addr, ioarea);
mask =
(((unsigned int) (ambapp_pnp_mbar_mask ((~mbar)) << 8) |
0xff)) + 1;
}
else
{
/* AHB memory area, absolute address */
addr = ambapp_addr_from (mmaps, addr);
mask =
(~((unsigned int) (ambapp_pnp_mbar_mask (mbar) << 20))) + 1;
}
}
ahb_info->start[bar] = addr;
ahb_info->mask[bar] = mask;
}
}
void
ambapp_apb_dev_init (unsigned int base,
struct ambapp_mmap *mmaps,
struct ambapp_pnp_apb *apb, struct ambapp_dev_hdr *dev)
{
struct ambapp_apb_info *apb_info;
/* Setup device struct */
dev->vendor = ambapp_pnp_vendor (apb->id);
dev->device = ambapp_pnp_device (apb->id);
apb_info = dev->devinfo;
apb_info->ver = ambapp_pnp_ver (apb->id);
apb_info->irq = ambapp_pnp_irq (apb->id);
apb_info->start = ambapp_pnp_apb_start (apb->iobar, base);
apb_info->mask = ambapp_pnp_apb_mask (apb->iobar);
DPRINTF (("+APB device %d:%d\n", dev->device, dev->vendor));
}
#define MAX_NUM_BUSES 16
void
ambapp_add_scanned_bus (unsigned int *ioareas, unsigned int ioarea)
{
int i;
for (i = 0; i < MAX_NUM_BUSES; i++)
{
if (ioareas[i] == 0)
{
ioareas[i] = ioarea;
return;
}
}
}
int
ambapp_has_been_scanned (unsigned int *ioareas, unsigned int ioarea)
{
int i;
if (!ioareas)
return 0;
for (i = 0; i < MAX_NUM_BUSES; i++)
{
if (ioareas[i] == 0)
{
break;
}
else if (ioareas[i] == ioarea)
{
return 1;
}
}
return 0;
}
int
ambapp_scan (unsigned int ioarea,
struct ambapp_dev_hdr *parent,
struct ambapp_mmap *mmaps,
void *(*memfunc) (void *dest, const void *src, int n),
struct ambapp_dev_hdr **root, void *internal)
{
struct ambapp_pnp_ahb *ahb, ahb_buf;
struct ambapp_pnp_apb *apb, apb_buf;
struct ambapp_dev_hdr *dev, *prev, *prevapb, *apbdev;
struct ambapp_ahb_info *ahb_info;
int maxloops = 64;
unsigned int apbbase, bridge_address;
int i, j;
DPRINTF (("Scan at 0x%08x\n", ioarea));
/* Default to memcpy() */
if (!memfunc)
memfunc = (void *(*)(void *dest, const void *src, int n)) memcpy;
*root = NULL;
if (parent)
{
/* scan first bus for 64 devices, rest for 16 devices */
maxloops = 16;
}
else
{
DPRINTF (("+(malloc:"));
internal = malloc (sizeof (unsigned int) * MAX_NUM_BUSES);
DPRINTF (("0x%x)\n", internal));
if (!internal)
return -1;
memset (internal, 0, sizeof (unsigned int) * MAX_NUM_BUSES);
ambapp_add_scanned_bus (internal, ioarea);
}
prev = parent;
/* AHB MASTERS */
ahb = (struct ambapp_pnp_ahb *) (ioarea | AMBA_CONF_AREA);
for (i = 0; i < maxloops; i++)
{
memfunc (&ahb_buf, ahb, sizeof (struct ambapp_pnp_ahb));
if (ahb_buf.id != 0)
{
/* A AHB device present here */
dev = ambapp_alloc_dev_struct (DEV_AHB_MST);
if (!dev)
return -1;
ambapp_ahb_dev_init (ioarea, mmaps, &ahb_buf, dev);
if (*root == NULL)
*root = dev;
if (prev != parent)
prev->next = dev;
dev->prev = prev;
prev = dev;
}
ahb++;
}
/* AHB SLAVES */
ahb =
(struct ambapp_pnp_ahb *) (ioarea | AMBA_CONF_AREA |
AMBA_AHB_SLAVE_CONF_AREA);
for (i = 0; i < maxloops; i++)
{
memfunc (&ahb_buf, ahb, sizeof (struct ambapp_pnp_ahb));
if (ahb_buf.id != 0)
{
/* A AHB device present here */
dev = ambapp_alloc_dev_struct (DEV_AHB_SLV);
if (!dev)
return -1;
ambapp_ahb_dev_init (ioarea, mmaps, &ahb_buf, dev);
if (prev != parent)
prev->next = dev;
dev->prev = prev;
prev = dev;
/* Is it a AHB/AHB Bridge ? */
if ((dev->device == GAISLER_AHB2AHB)
&& (dev->vendor == VENDOR_GAISLER))
{
/* AHB/AHB Bridge Found, recurse down the Bridge */
ahb_info = dev->devinfo;
if (ahb_info->ver)
{
bridge_address =
ambapp_addr_from (mmaps, ahb_info->custom[1]);
DPRINTF (("+(AHBAHB:0x%x)\n", bridge_address));
/* Makes sure bus only scanned once */
if (ambapp_has_been_scanned (internal, bridge_address) ==
NULL)
{
ambapp_add_scanned_bus (internal, bridge_address);
if (ambapp_scan
(bridge_address, dev, mmaps, memfunc,
&dev->children, internal))
return -1;
}
}
}
else if ((dev->device == GAISLER_APBMST)
&& (dev->vendor == VENDOR_GAISLER))
{
/* AHB/APB Bridge Found, add the APB devices to this AHB Slave's children */
prevapb = dev;
ahb_info = dev->devinfo;
apbbase = ahb_info->start[0];
apb = (struct ambapp_pnp_apb *) (apbbase | AMBA_CONF_AREA);
for (j = 0; j < AMBA_APB_SLAVES; j++)
{
memfunc (&apb_buf, apb, sizeof (struct ambapp_pnp_apb));
if (apb_buf.id)
{
apbdev = ambapp_alloc_dev_struct (DEV_APB_SLV);
if (!dev)
return -1;
ambapp_apb_dev_init (apbbase, mmaps, &apb_buf, apbdev);
if (prevapb != dev)
prevapb->next = apbdev;
else
dev->children = apbdev;
apbdev->prev = prevapb;
prevapb = apbdev;
}
apb++;
}
}
}
ahb++;
}
if (parent == NULL)
{
free (internal);
}
return 0;
}
/* Match search options againt device */
int
ambapp_dev_match_options (struct ambapp_dev_hdr *dev, unsigned int options,
int vendor, int device)
{
if ((((options & (OPTIONS_ALL_DEVS)) == OPTIONS_ALL_DEVS) || /* Match TYPE */
((options & OPTIONS_AHB_MSTS) && (dev->dev_type == DEV_AHB_MST)) || ((options & OPTIONS_AHB_SLVS) && (dev->dev_type == DEV_AHB_SLV)) || ((options & OPTIONS_APB_SLVS) && (dev->dev_type == DEV_APB_SLV))) && ((vendor == -1) || (vendor == dev->vendor)) && /* Match ID */
((device == -1) || (device == dev->device)) && (((options & OPTIONS_ALL) == OPTIONS_ALL) || /* Match Allocated State */
((options &
OPTIONS_FREE)
&& DEV_IS_FREE (dev))
||
((options &
OPTIONS_ALLOCATED)
&&
DEV_IS_ALLOCATED
(dev))))
{
return 1;
}
return 0;
}
/* If device is an APB bridge all devices on the APB bridge is processed */
static int
ambapp_for_each_apb (struct ambapp_dev_hdr *dev,
unsigned int options,
int vendor,
int device, int maxdepth, ambapp_func_t func, void *arg)
{
int index;
struct ambapp_dev_hdr *apbslv;
if (maxdepth < 0)
return 0;
if (dev->children && (dev->children->dev_type == DEV_APB_SLV))
{
/* Found a APB Bridge */
index = 0;
apbslv = dev->children;
while (apbslv)
{
if (ambapp_dev_match_options (apbslv, options, vendor, device) == 1)
{
if (func (apbslv, index, maxdepth, arg) == 1)
return 1; /* Signalled stopped */
}
index++;
apbslv = apbslv->next;
}
}
return 0;
}
/* Traverse the prescanned device information */
int
ambapp_for_each (struct ambapp_dev_hdr *root,
unsigned int options,
int vendor,
int device, int maxdepth, ambapp_func_t func, void *arg)
{
struct ambapp_dev_hdr *dev;
int ahb_slave = 0;
int index;
if (maxdepth < 0)
return 0;
/* Start at device 'root' and process downwards.
*
* Breadth first search, search order
* 1. AHB MSTS
* 2. AHB SLVS
* 3. APB SLVS on primary bus
* 4. AHB/AHB secondary... -> step to 1.
*/
/* AHB MST / AHB SLV */
if (options & (OPTIONS_AHB_MSTS | OPTIONS_AHB_SLVS | OPTIONS_DEPTH_FIRST))
{
index = 0;
dev = root;
while (dev)
{
if ((dev->dev_type == DEV_AHB_SLV) && !ahb_slave)
{
/* First AHB Slave */
ahb_slave = 1;
index = 0;
}
/* Conditions must be fullfilled for function to be called */
if (ambapp_dev_match_options (dev, options, vendor, device) == 1)
{
/* Correct device and vendor ID */
if (func (dev, index, maxdepth, arg) == 1)
return 1; /* Signalled stopped */
}
if ((options & OPTIONS_DEPTH_FIRST) && (options & OPTIONS_APB_SLVS))
{
/* Check is APB bridge, and process all APB Slaves in that case */
if (ambapp_for_each_apb
(dev, options, vendor, device, (maxdepth - 1), func,
arg) == 1)
return 1; /* Signalled stopped */
}
if (options & OPTIONS_DEPTH_FIRST)
{
if (dev->children && (dev->children->dev_type != DEV_APB_SLV))
{
/* Found AHB Bridge, recurse */
if (ambapp_for_each
(dev->children, options, vendor, device, (maxdepth - 1),
func, arg) == 1)
return 1;
}
}
index++;
dev = dev->next;
}
}
/* Find APB Bridges */
if ((options & OPTIONS_APB_SLVS) && !(options & OPTIONS_DEPTH_FIRST))
{
dev = root;
while (dev)
{
/* Check is APB bridge, and process all APB Slaves in that case */
if (ambapp_for_each_apb
(dev, options, vendor, device, (maxdepth - 1), func, arg) == 1)
return 1; /* Signalled stopped */
dev = dev->next;
}
}
/* Find AHB Bridges */
if (!(options & OPTIONS_DEPTH_FIRST))
{
dev = root;
while (dev)
{
if (dev->children && (dev->children->dev_type != DEV_APB_SLV))
{
/* Found AHB Bridge, recurse */
if (ambapp_for_each
(dev->children, options, vendor, device, (maxdepth - 1),
func, arg) == 1)
return 1;
}
dev = dev->next;
}
}
return 0;
}
int
ambapp_alloc_dev (struct ambapp_dev_hdr *dev, void *owner)
{
if (dev->owner)
return -1;
dev->owner = owner;
return 0;
}
void
ambapp_free_dev (struct ambapp_dev_hdr *dev)
{
dev->owner = NULL;
}
struct ambapp_dev_find_match_arg
{
int index;
int count;
int type;
void *dev;
};
/* AMBA PP find routines */
int
ambapp_dev_find_match (struct ambapp_dev_hdr *dev, int index, int maxdepth,
void *arg)
{
struct ambapp_dev_find_match_arg *p = arg;
if (p->index == 0)
{
/* Found controller, stop */
if (p->type == DEV_APB_SLV)
{
*(struct ambapp_apb_info *) p->dev =
*(struct ambapp_apb_info *) dev->devinfo;
p->dev = ((struct ambapp_apb_info *) p->dev) + 1;
}
else
{
*(struct ambapp_ahb_info *) p->dev =
*(struct ambapp_ahb_info *) dev->devinfo;
p->dev = ((struct ambapp_ahb_info *) p->dev) + 1;
}
p->count--;
if (p->count < 1)
return 1;
}
else
{
p->index--;
}
return 0;
}
int
ambapp_find_apbslvs_next (struct ambapp_dev_hdr *root, int vendor, int device,
struct ambapp_apb_info *dev, int index, int maxno)
{
struct ambapp_dev_find_match_arg arg;
arg.index = index;
arg.count = maxno;
arg.type = DEV_APB_SLV; /* APB */
arg.dev = dev;
ambapp_for_each (root, (OPTIONS_ALL | OPTIONS_APB_SLVS), vendor, device, 10,
ambapp_dev_find_match, &arg);
return maxno - arg.count;
}
int
ambapp_find_apbslv (struct ambapp_dev_hdr *root, int vendor, int device,
struct ambapp_apb_info *dev)
{
return ambapp_find_apbslvs_next (root, vendor, device, dev, 0, 1);
}
int
ambapp_find_apbslv_next (struct ambapp_dev_hdr *root, int vendor, int device,
struct ambapp_apb_info *dev, int index)
{
return ambapp_find_apbslvs_next (root, vendor, device, dev, index, 1);
}
int
ambapp_find_apbslvs (struct ambapp_dev_hdr *root, int vendor, int device,
struct ambapp_apb_info *dev, int maxno)
{
return ambapp_find_apbslvs_next (root, vendor, device, dev, 0, maxno);
}
int
ambapp_find_ahbslvs_next (struct ambapp_dev_hdr *root, int vendor, int device,
struct ambapp_ahb_info *dev, int index, int maxno)
{
struct ambapp_dev_find_match_arg arg;
arg.index = index;
arg.count = maxno;
arg.type = DEV_AHB_SLV; /* AHB SLV */
arg.dev = dev;
ambapp_for_each (root, (OPTIONS_ALL | OPTIONS_AHB_SLVS), vendor, device, 10,
ambapp_dev_find_match, &arg);
return maxno - arg.count;
}
int
ambapp_find_ahbslv_next (struct ambapp_dev_hdr *root, int vendor, int device,
struct ambapp_ahb_info *dev, int index)
{
return ambapp_find_ahbslvs_next (root, vendor, device, dev, index, 1);
}
int
ambapp_find_ahbslv (struct ambapp_dev_hdr *root, int vendor, int device,
struct ambapp_ahb_info *dev)
{
return ambapp_find_ahbslvs_next (root, vendor, device, dev, 0, 1);
}
int
ambapp_find_ahbslvs (struct ambapp_dev_hdr *root, int vendor, int device,
struct ambapp_ahb_info *dev, int maxno)
{
return ambapp_find_ahbslvs_next (root, vendor, device, dev, 0, maxno);
}
struct ambapp_dev_hdr *
ambapp_find_parent (struct ambapp_dev_hdr *dev)
{
while (dev->prev)
{
if (dev == dev->prev->children)
{
return dev->prev;
}
dev = dev->prev;
}
return NULL;
}
struct ambapp_dev_hdr *ambapp_root = NULL;
extern unsigned int console;
extern unsigned int rtc;
void
pnpinit (void)
{
struct ambapp_apb_info dev;
int n;
ambapp_scan (LEON3_IO_AREA, NULL, NULL, NULL, &ambapp_root, NULL);
if ((n =
ambapp_find_apbslv (ambapp_root, VENDOR_GAISLER, GAISLER_APBUART,
&dev)) == 1)
{
console = dev.start;
DPRINTF (("Found abuart at 0x%x\n", console));
}
if ((n =
ambapp_find_apbslv (ambapp_root, VENDOR_GAISLER, GAISLER_GPTIMER,
&dev)) == 1)
{
rtc = dev.start + 0x10;
DPRINTF (("Found rtc at 0x%x\n", rtc));
}
}

View File

@ -0,0 +1,34 @@
/*
* Copyright (c) 2011 Aeroflex Gaisler
*
* BSD license:
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
#include <asm-leon/amba.h>
#undef AMBA_TYPE_AHBIO_ADDR
#include <asm-leon/lambapp.h>
#include <string.h>
void
pnpinit (void)
{
}

View File

@ -0,0 +1,134 @@
/*
* Copyright (c) 2011 Aeroflex Gaisler
*
* BSD license:
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
#include <asm-leon/leon.h>
#include <asm-leon/leonstack.h>
#include <asm-leon/asmmacro.h>
.seg "text"
/* Number of register windows */
.global _nwindows_min1, _nwindows
! Window overflow trap handler on save.
! Touches %g1
/* ------- */
.weak _window_overflow
.set _window_overflow,__window_overflow
.weak _window_overflow_svt
.set _window_overflow_svt,__window_overflow_svt
/* ------- */
!.global _window_overflow,_window_overflow_svt
.global __window_overflow_rettseq,__window_overflow_rettseq_ret,__window_overflow_slow1
__window_overflow_svt:
__window_overflow:
#ifndef _FLAT
__window_overflow_rettseq:
mov %wim, %l3 ! Calculate next WIM
mov %g1, %l7
srl %l3, 1, %g1
__window_overflow_rettseq_ret:
sethi %hi(_nwindows_min1), %l4 ! NWINDOWS-1
ld [%l4+%lo(_nwindows_min1)], %l4
sll %l3, %l4 , %l4
or %l4, %g1, %g1
save ! Get into window to be saved.
mov %g1, %wim
nop; nop; nop
std %l0, [%sp + 0];
std %l2, [%sp + 8];
std %l4, [%sp + 16];
std %l6, [%sp + 24];
std %i0, [%sp + 32];
std %i2, [%sp + 40];
std %i4, [%sp + 48];
std %i6, [%sp + 56];
restore ! Go back to trap window.
mov %l7, %g1
jmp %l1 ! Re-execute save.
rett %l2
nop
__window_overflow_slow1: ! space for possible stackcheck patch
nop
nop
#else
ta 0 ! halt
__window_overflow_rettseq:
__window_overflow_rettseq_ret:
__window_overflow_slow1:
nop
nop
nop
#endif
/* Window underflow trap handler on restore. */
! Touches %g1
/* ------- */
.weak _window_underflow
.set _window_underflow,__window_underflow
.weak _window_underflow_svt
.set _window_underflow_svt,__window_underflow_svt
/* ------- */
!.global _window_underflow,_window_underflow_svt
__window_underflow_svt:
__window_underflow:
#ifndef _FLAT
mov %wim, %l3 ! Calculate next WIM
sll %l3, 1, %l4
sethi %hi(_nwindows_min1), %l5 ! NWINDOWS-1
ld [%l5+%lo(_nwindows_min1)], %l5
srl %l3, %l5, %l5
or %l5, %l4, %l5
mov %l5, %wim
nop; nop; nop
restore ! Two restores to get into the
restore ! window to restore
ldd [%sp + 0], %l0; ! Restore window from the stack
ldd [%sp + 8], %l2;
ldd [%sp + 16], %l4;
ldd [%sp + 24], %l6;
ldd [%sp + 32], %i0;
ldd [%sp + 40], %i2;
ldd [%sp + 48], %i4;
ldd [%sp + 56], %i6;
save ! Get back to the trap window.
save
jmp %l1 ! Re-execute restore.
rett %l2
#else
ta 0 ! halt
#endif

View File

@ -0,0 +1,82 @@
/*
* Copyright (c) 2011 Aeroflex Gaisler
*
* BSD license:
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
#include <asm-leon/leon.h>
#include <asm-leon/leonstack.h>
#include <asm-leon/asmmacro.h>
extern volatile unsigned int __window_overflow_rettseq[3];
extern volatile unsigned int __window_overflow_slow1[2];
static unsigned int installed = 0;
static unsigned int save__window_overflow_rettseq[3];
int
install_winoverflow_hook (void (*func) (void))
{
if (installed)
{
return 0;
}
if (!installed)
{
/*
a7 50 00 00 rd %wim, %l3
ae 10 00 01 mov %g1, %l7
83 34 e0 01 srl %l3, 1, %g1
81 c4 40 00 jmp %l1
81 cc 80 00 rett %l2 */
save__window_overflow_rettseq[0] = __window_overflow_rettseq[0];
save__window_overflow_rettseq[1] = __window_overflow_rettseq[1];
save__window_overflow_rettseq[2] = __window_overflow_rettseq[2];
/*29 10 00 31 sethi %hi(0x4000c400), %l4
81 c5 22 48 jmp %l4 + 0x248
01 00 00 00 nop */
__window_overflow_rettseq[0] = ((((unsigned int) func) >> 10) & 0x3fffff) | 0x29000000; /* upper 22 */
__window_overflow_rettseq[1] = ((((unsigned int) func)) & 0x03ff) | 0x81c52000; /* lower 10 */
__window_overflow_rettseq[2] = 0x01000000; /* nop */
sparc_leon23_icache_flush ();
installed = 1;
}
return 0;
}
void
uninstall_winoverflow_hook ()
{
if (installed)
{
__window_overflow_rettseq[0] = save__window_overflow_rettseq[0];
__window_overflow_rettseq[1] = save__window_overflow_rettseq[1];
__window_overflow_rettseq[2] = save__window_overflow_rettseq[2];
sparc_leon23_icache_flush ();
installed = 0;
}
}

View File

@ -0,0 +1,135 @@
/*
* Copyright (c) 2011 Aeroflex Gaisler
*
* BSD license:
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
#include <asm-leon/leon.h>
#include <asm-leon/leonstack.h>
#include <asm-leon/asmmacro.h>
.seg "text"
/* Number of register windows */
.global _nwindows_min1, _nwindows
! Window overflow trap handler on save.
! Touches %g1
/* ------- */
.weak _window_overflow
.set _window_overflow,__window_overflow
.weak _window_overflow_svt
.set _window_overflow_svt,__window_overflow_svt
/* ------- */
!.global _window_overflow,_window_overflow_svt
.global __window_overflow_rettseq,__window_overflow_rettseq_ret,__window_overflow_slow1
__window_overflow_svt:
__window_overflow:
#ifndef _FLAT
__window_overflow_rettseq:
mov %wim, %l3 ! Calculate next WIM
mov %g1, %l7
srl %l3, 1, %g1
__window_overflow_rettseq_ret:
sethi %hi(_nwindows_min1), %l4 ! NWINDOWS-1
ld [%l4+%lo(_nwindows_min1)], %l4
sll %l3, %l4 , %l4
or %l4, %g1, %g1
save ! Get into window to be saved.
mov %g1, %wim
nop; nop; nop
std %l0, [%sp + 0];
std %l2, [%sp + 8];
std %l4, [%sp + 16];
std %l6, [%sp + 24];
std %i0, [%sp + 32];
std %i2, [%sp + 40];
std %i4, [%sp + 48];
std %i6, [%sp + 56];
restore ! Go back to trap window.
mov %l7, %g1
jmp %l1 ! Re-execute save.
rett %l2
nop
__window_overflow_slow1: ! space for possible stackcheck patch
nop
nop
#else
ta 0 ! halt
__window_overflow_rettseq:
__window_overflow_rettseq_ret:
__window_overflow_slow1:
nop
nop
nop
#endif
/* Window underflow trap handler on restore. */
! Touches %g1
/* ------- */
.weak _window_underflow
.set _window_underflow,__window_underflow
.weak _window_underflow_svt
.set _window_underflow_svt,__window_underflow_svt
/* ------- */
!.global _window_underflow,_window_underflow_svt
__window_underflow_svt:
__window_underflow:
#ifndef _FLAT
mov %wim, %l3 ! Calculate next WIM
sll %l3, 1, %l4
sethi %hi(_nwindows_min1), %l5 ! NWINDOWS-1
ld [%l5+%lo(_nwindows_min1)], %l5
srl %l3, %l5, %l5
or %l5, %l4, %l5
mov %l5, %wim
nop; nop; nop
restore ! Two restores to get into the
restore ! window to restore
ldd [%sp + 0], %l0; ! Restore window from the stack
ldd [%sp + 8], %l2;
ldd [%sp + 16], %l4;
ldd [%sp + 24], %l6;
ldd [%sp + 32], %i0;
ldd [%sp + 40], %i2;
ldd [%sp + 48], %i4;
ldd [%sp + 56], %i6;
save ! Get back to the trap window.
save
jmp %l1 ! Re-execute restore.
rett %l2
#else
ta 0 ! halt
#endif

View File

@ -0,0 +1,285 @@
/*
* Copyright (c) 2011 Aeroflex Gaisler
*
* BSD license:
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
#include <asm-leon/leon.h>
#include <asm-leon/leonstack.h>
#include <asm-leon/asmmacro.h>
.seg "data"
.global _lb_spillglobals, _lb_issideflush
.align 4
_lb_spillglobals:
.word 0
.word 0
.word 0
.word 0
.word 0
.word 0
.word 0
_lb_issideflush:
.word 0 /* off: 28 */
.seg "text"
/* =============================================== */
#define _SV save %sp, -SF_REGS_SZ, %sp
#define _RS restore
/* ------- */
.weak _flush_windows
.set _flush_windows,__flush_windows
.weak _flush_windows_svt
.set _flush_windows_svt,__flush_windows_svt
/* ------- */
!.global _flush_windows,_flush_windows_svt
__flush_windows_svt:
rd %wim, %l3
__flush_windows:
SAVE_ALL
#ifndef _FLAT
set _lb_issideflush, %l3
st %l0, [%l3] /* mark as inside flush */
wr %l0, SPARC_PSR_ET_MASK, %psr
nop; nop; nop
_SV; _SV; _SV; _SV; _SV; _SV; _SV;
_RS; _RS; _RS; _RS; _RS; _RS; _RS;
set _lb_issideflush, %l3
st %g0, [%l3] /* mark as outside flush */
/* Advance over the trap instruction. */
ld [%sp + SF_REGS_SZ + PT_NPC], %l1
add %l1, 0x4, %l2
st %l1, [%sp + SF_REGS_SZ + PT_PC]
st %l2, [%sp + SF_REGS_SZ + PT_NPC]
#endif
RESTORE_ALL
/* =============================================== */
_irqcall_flush_windows:
#ifndef _FLAT
set _lb_spillglobals,%l4
st %g1,[%l4+0]
st %g4,[%l4+4]
st %l0,[%l4+16]
st %l1,[%l4+20]
st %l2,[%l4+24]
st %l4,[%l4+28] /* mark as inside flush */
restore
mov %psr, %g1
or %g1, SPARC_PSR_PIL_MASK, %g1
wr %g1, SPARC_PSR_ET_MASK, %psr /* disable irq, enable traps */
nop
nop
nop
sethi %hi(_nwindows_min1), %g4 /* flush registers */
ld [%g4+%lo(_nwindows_min1)], %g4
1: save /* NWINDOWS-1 times */
sub %g4,1,%g4
/*****************/
andncc %g4,0xff,%g0
be .lab1
nop
nop
.lab1: /*****************/
cmp %g4,%g0
bne 1b
nop
sethi %hi(_nwindows_min1), %g4
ld [%g4+%lo(_nwindows_min1)], %g4
2: restore /* NWINDOWS-1 times */
/*****************/
andncc %g4,0xff,%g0
be .lab2
nop
nop
.lab2: /*****************/
sub %g4,1,%g4
cmp %g4,%g0
bne 2b
nop
save
set _lb_spillglobals,%l4
ld [%l4+4], %g4
ld [%l4+0], %g1
ld [%l4+16],%l0
ld [%l4+20],%l1
ld [%l4+24],%l2
st %g0,[%l4+28] /* clean inside flush mark */
#endif
wr %l0, 0, %psr /* restore psr */
nop
nop
nop
jmpl %l2, %g0
rett %l2 + 4
/* =============================================== */
/* ------- */
.weak _irqcall_disableirq
.set _irqcall_disableirq,__irqcall_disableirq
.weak _irqcall_disableirq_svt
.set _irqcall_disableirq_svt,__irqcall_disableirq_svt
/* ------- */
__irqcall_disableirq:
__irqcall_disableirq_svt:
or %l0, SPARC_PSR_PIL_MASK, %l0
mov %l0, %psr
nop; nop; nop
jmpl %l2, %g0
rett %l2 + 4
/* =============================================== */
/*
* system call (ta 0x2):
* 2: irq_disable:
* o1 = 2
* 3: irq_enable:
* o0 = old_flags
* o1 = 3
* 4: enter supervisor mode (from user mode):
* o1 = 4
* 5: enter user mode:
* o1 = 5
* 6: flush windows
*
* On entry:
*
* l0 = psr (from trap table)
* l1 = pc
* l2 = npc
* i0 = system call id
*/
/* ------- */
.weak _irqcall
.set _irqcall,__irqcall
.weak _irqcall_svt
.set _irqcall_svt,__irqcall_svt
/* ------- */
!.global _irqcall,_irqcall_svt
__irqcall_svt:
__irqcall:
subcc %i1, 2, %g0 ! syscall 2, disable interrupts
bne 3f
or %l0, 0x0f00, %l4 ! set PIL=15
mov %l4, %psr
or %l0, SPARC_PSR_ET_MASK, %i0 ! return old psr with ET=1
ba,a 9f
3:
subcc %i1, 3, %g0 ! syscall 3, enable interrupts
bne 4f
and %i0, SPARC_PSR_PIL_MASK, %l4
andn %l0, SPARC_PSR_PIL_MASK, %l5
or %l5, %l4, %l4
mov %l4, %psr
ba,a 9f
4:
subcc %i1, 4, %g0 ! syscall 4, enter supervisor
bne 5f
mov %psr, %l4
or %l4,SPARC_PSR_PS_MASK,%l4
mov %l4, %psr ! set previous supervisor %psr
nop; nop; nop
ba,a 9f
5:
subcc %i1, 5, %g0 ! syscall 5, enter user
bne 6f
mov %psr, %l4
andn %l4,SPARC_PSR_PS_MASK,%l4
mov %l4, %psr ! clear previous supervisor %psr, return to user mode
nop; nop; nop
ba,a 9f
6:
subcc %i1, 6, %g0 ! syscall 6, flush windows
bne 1f
nop
ba,a _irqcall_flush_windows
1:
ta 0 ! halt
9: ! leave
jmpl %l2, %g0
rett %l2 + 4
/* =============================================== */
/* call _irqcall through trap */
.global leonbare_enable_traps !void leonbare_enable_traps(unsigned long old_flags);
leonbare_enable_traps:
set 3,%o1
retl
ta 0x2
/* =============================================== */
/* call _irqcall through trap */
.global leonbare_disable_traps !unsigned long leonbare_disable_traps();
leonbare_disable_traps:
set 2,%o1
retl
ta 0x2
/* =============================================== */
/* flush all windows */
.global leonbare_flush_windows !void leonbare_flush_windows();
leonbare_flush_windows:
set 6,%o1
retl
ta 0x2

26
libgloss/sparc_leon/rtc.c Normal file
View File

@ -0,0 +1,26 @@
/*
* Copyright (c) 2011 Aeroflex Gaisler
*
* BSD license:
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
int *rtc = (int *) 0x80000310;

132
libgloss/sparc_leon/rtrap.S Normal file
View File

@ -0,0 +1,132 @@
/*
* Copyright (c) 2011 Aeroflex Gaisler
*
* BSD license:
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
#include <asm-leon/leonstack.h>
#include <asm-leon/winmacros.h>
/* Registers to not touch at all. */
#define t_psr l0
#define t_pc l1
#define t_npc l2
#define t_wim l3
#define twin_tmp1 l4
#define glob_tmp g4
#define curptr g6
/* Number of register windows */
.global _nwindows_min1, _nwindows
.text
.align 4
.globl leonbare_trapreturn, schedule_callback
leonbare_trapreturn:
/* a optional scheduler can be called here */
set schedule_callback, %g2
ld [%g2], %g2
cmp %g2,%g0
beq 3f
nop
jmpl %g2,%o7
#ifndef _SOFT_FLOAT
add %sp, FW_REGS_SZ + 8 + SF_REGS_SZ , %o1 ! pt_regs ptr
#else
add %sp, SF_REGS_SZ , %o1 ! pt_regs ptr
#endif
3:
#ifndef _SOFT_FLOAT
ld [%sp + (SF_REGS_SZ + PT_REGS_SZ + FW_REGS_SZ - 4)],%g2
sethi %hi(fpustate_current), %g3
st %g2, [%g3+%lo(fpustate_current)]
#endif
wr %t_psr, 0x0, %psr ! enable nesting again, clear ET
#ifndef _FLAT
/* Will the rett land us in the invalid window? */
mov 2, %g1
sll %g1, %t_psr, %g1
sethi %hi(_nwindows), %g2 !NWINDOWS
ld [%g2+%lo(_nwindows)], %g2
srl %g1, %g2, %g2
or %g1, %g2, %g1
rd %wim, %g2
andcc %g2, %g1, %g0
be 1f ! Nope, just return from the trap
sll %g2, 0x1, %g1
/* We have to grab a window before returning. */
sethi %hi(_nwindows_min1), %g3 !NWINDOWS-1
ld [%g3+%lo(_nwindows_min1)], %g3
srl %g2, %g3, %g2
or %g1, %g2, %g1
and %g1, 0xff, %g1
wr %g1, 0x0, %wim
/* Grrr, make sure we load from the right %sp... */
PT_LOAD_ALL(sp, t_psr, t_pc, t_npc, g1)
restore %g0, %g0, %g0
RW_LOAD(sp)
b 2f
save %g0, %g0, %g0
/* Reload the entire frame in case this is from a
* kernel system call or whatever...
*/
1:
#endif
PT_LOAD_ALL(sp, t_psr, t_pc, t_npc, g1)
2:
#ifdef _FLAT
restore
RW_LOAD(sp)
save
#endif
wr %t_psr, 0x0, %psr
nop; nop; nop
jmp %t_pc
rett %t_npc
#ifdef _FLAT
#warning _FLAT not implemented
#endif

View File

@ -0,0 +1,158 @@
/*
* Copyright (c) 2011 Aeroflex Gaisler
*
* BSD license:
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
#include <asm-leon/leonstack.h>
#include <asm-leon/winmacros.h>
/* Registers to not touch at all. */
#define t_psr l0
#define t_pc l1
#define t_npc l2
#define t_wim l3
#define twin_tmp1 l4
#define glob_tmp g4
#define curptr g6
/* Number of register windows */
.global _nwindows_min1, _nwindows
.text
.align 4
.globl leonbare_trapreturn_fast, schedule_callback
/* rtap return special for irqtrap.S */
leonbare_trapreturn_fast:
/* a optional scheduler can be called here */
set schedule_callback, %g2
ld [%g2], %g2
cmp %g2,%g0
beq 3f
nop
jmpl %g2,%o7
#ifndef _SOFT_FLOAT
add %sp, FW_REGS_SZ + 8 + SF_REGS_SZ , %o1 ! pt_regs ptr
#else
add %sp, SF_REGS_SZ , %o1 ! pt_regs ptr
#endif
3:
#ifndef _SOFT_FLOAT
ld [%sp + (SF_REGS_SZ + PT_REGS_SZ + FW_REGS_SZ - 4)],%g2
sethi %hi(fpustate_current), %g3
st %g2, [%g3+%lo(fpustate_current)]
sethi %hi(fpustate_owner), %g3
ld [%g3+%lo(fpustate_owner)], %g3
cmp %g2, %g3
bne didusefpu
nop
/* avoid fpu exception */
ld [%sp + (SF_REGS_SZ + PT_REGS_SZ + FW_REGS_SZ - 8)], %g2
set SPARC_PSR_EF_MASK, %g3
and %g2, %g3, %g2
andn %t_psr, %g3, %t_psr
or %t_psr, %g2, %t_psr
ba,a 1f
didusefpu:
add %sp,SF_REGS_SZ + PT_REGS_SZ,%g2
cmp %g2, %g3
bne 1f
sethi %hi(fpustate_owner), %g3
st %g0, [%g3+%lo(fpustate_owner)]
1:
#endif
wr %t_psr, 0x0, %psr ! enable nesting again, clear ET
#ifndef _FLAT
/* Will the rett land us in the invalid window? */
mov 2, %g1
sll %g1, %t_psr, %g1
sethi %hi(_nwindows), %g2 !NWINDOWS
ld [%g2+%lo(_nwindows)], %g2
srl %g1, %g2, %g2
or %g1, %g2, %g1
rd %wim, %g2
andcc %g2, %g1, %g0
be 1f ! Nope, just return from the trap
sll %g2, 0x1, %g1
/* We have to grab a window before returning. */
sethi %hi(_nwindows_min1), %g3 !NWINDOWS-1
ld [%g3+%lo(_nwindows_min1)], %g3
srl %g2, %g3, %g2
or %g1, %g2, %g1
and %g1, 0xff, %g1
wr %g1, 0x0, %wim
/* Grrr, make sure we load from the right %sp... */
PT_LOAD_ALL_FAST(sp, t_psr, t_pc, t_npc, g1)
restore %g0, %g0, %g0
RW_LOAD(sp)
b 2f
save %g0, %g0, %g0
/* Reload the entire frame in case this is from a
* kernel system call or whatever...
*/
1:
#endif
PT_LOAD_ALL_FAST(sp, t_psr, t_pc, t_npc, g1)
2: /*PT_LOAD_GLOBALS(sp)*/
#ifdef _FLAT
restore
RW_LOAD(sp)
save
#endif
wr %t_psr, 0x0, %psr
nop; nop; nop
jmp %t_pc
rett %t_npc
#ifdef _FLAT
#warning _FLAT not implemented
#endif

View File

@ -0,0 +1,31 @@
/*
* Copyright (c) 2011 Aeroflex Gaisler
*
* BSD license:
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
.seg "text"
.global _leonbase_Stop
_leonbase_Stop:
ta 0
nop

146
libgloss/sparc_leon/timer.c Normal file
View File

@ -0,0 +1,146 @@
/*
* Copyright (c) 2011 Aeroflex Gaisler
*
* BSD license:
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
#include <sys/types.h>
#include <sys/time.h>
#include <sys/errno.h>
#include <asm-leon/leon.h>
#include <asm-leon/irq.h>
#include <asm-leon/timer.h>
#include <asm-leon/leoncompat.h>
// '''''''''''''''''''''''''''''''''''''''''''''''''''''
TAILQ_HEAD (timer_queue, timerevent) timers = TAILQ_HEAD_INITIALIZER (timers);
int
addtimer (struct timerevent *e)
{
struct timerevent *next;
unsigned long old = leonbare_disable_traps ();
TAILQ_FOREACH (next, &timers, n)
{
if (!GT_TIMESPEC (e->expire, next->expire))
break;
}
if (next)
{
TAILQ_INSERT_BEFORE (next, e, n);
}
else
{
TAILQ_INSERT_TAIL (&timers, e, n);
}
leonbare_enable_traps (old);
}
extern unsigned long noalarm;
void
settimer ()
{
struct timeval tv, te;
struct timerevent *e = TAILQ_FIRST (&timers), *n;
while (e)
{
n = TAILQ_NEXT (e, n);
te.tv_sec = e->expire.tv_sec;
te.tv_usec = e->expire.tv_nsec / NSEC_PER_USEC;
do_gettimeofday (&tv);
if (GT_TIMEVAL (te, tv))
{
MINUS_TIMEVAL (te, te, tv);
if (!tv.tv_sec || te.tv_usec <= tick_usec)
{
if (!noalarm)
{
//---------------------
switch (LEONCOMPAT_VERSION)
{
case 3:
default:
LEON3_GpTimer_Regs->e[1].val = 0;
LEON3_GpTimer_Regs->e[1].rld = te.tv_usec - 1;
LEON3_GpTimer_Regs->e[1].ctrl = 0;
LEON3_GpTimer_Regs->e[1].ctrl =
LEON3_GPTIMER_EN |
LEON3_GPTIMER_LD | LEON3_GPTIMER_IRQEN;
break;
}
}
//---------------------
}
}
else
{
unsigned long old = leonbare_disable_traps ();
TAILQ_REMOVE (&timers, e, n);
e->handler (e->arg);
leonbare_enable_traps (old);
}
e = n;
}
}
int
Timer_getTimer1 (unsigned int **count, unsigned int **reload,
unsigned int **ctrl)
{
//---------------------
switch (LEONCOMPAT_VERSION)
{
case 3:
default:
amba_init ();
*count = (unsigned int *) &(LEON3_GpTimer_Regs->e[0].val);
*reload = (unsigned int *) &(LEON3_GpTimer_Regs->e[0].rld);
*ctrl = (unsigned int *) &(LEON3_GpTimer_Regs->e[0].ctrl);
break;
}
//---------------------
return 1;
}
int
Timer_getTimer2 (unsigned int **count, unsigned int **reload,
unsigned int **ctrl)
{
//---------------------
switch (LEONCOMPAT_VERSION)
{
case 3:
default:
amba_init ();
if (!noalarm)
{
*count = (unsigned int *) &(LEON3_GpTimer_Regs->e[1].val);
*reload = (unsigned int *) &(LEON3_GpTimer_Regs->e[1].rld);
*ctrl = (unsigned int *) &(LEON3_GpTimer_Regs->e[1].ctrl);
break;
}
return 0;
}
//---------------------
return 1;
}

Some files were not shown because too many files have changed in this diff Show More