From 8b5778e69e7fc8393f7e192067116da09aec71df Mon Sep 17 00:00:00 2001 From: Sebastian Huber Date: Mon, 12 Mar 2018 06:37:36 +0100 Subject: sparc: Move libcpu content to cpukit This patch is a part of the BSP source reorganization. Update #3285. --- bsps/sparc/headers.am | 4 - bsps/sparc/include/libcpu/access.h | 50 ---- c/src/lib/libbsp/sparc/erc32/Makefile.am | 5 - c/src/lib/libbsp/sparc/erc32/make/custom/erc32.cfg | 1 - c/src/lib/libbsp/sparc/leon2/Makefile.am | 5 - .../lib/libbsp/sparc/leon2/make/custom/at697f.cfg | 1 - c/src/lib/libbsp/sparc/leon2/make/custom/leon2.cfg | 1 - c/src/lib/libbsp/sparc/leon3/Makefile.am | 5 - .../lib/libbsp/sparc/leon3/make/custom/gr712rc.cfg | 1 - c/src/lib/libbsp/sparc/leon3/make/custom/leon3.cfg | 1 - c/src/lib/libbsp/sparc/leon3/make/custom/ut699.cfg | 1 - c/src/lib/libbsp/sparc/leon3/make/custom/ut700.cfg | 1 - c/src/lib/libcpu/sparc/Makefile.am | 22 -- c/src/lib/libcpu/sparc/access/access.S | 109 -------- c/src/lib/libcpu/sparc/access/access_le.c | 33 --- c/src/lib/libcpu/sparc/configure.ac | 29 -- c/src/lib/libcpu/sparc/reg_win/window.S | 259 ------------------ c/src/lib/libcpu/sparc/syscall/syscall.S | 295 --------------------- c/src/lib/libcpu/sparc/syscall/syscall.h | 1 - cpukit/score/cpu/sparc/Makefile.am | 12 +- cpukit/score/cpu/sparc/access.S | 109 ++++++++ cpukit/score/cpu/sparc/access_le.c | 33 +++ cpukit/score/cpu/sparc/headers.am | 1 + cpukit/score/cpu/sparc/include/libcpu/access.h | 50 ++++ cpukit/score/cpu/sparc/syscall.S | 295 +++++++++++++++++++++ cpukit/score/cpu/sparc/syscall.h | 1 + cpukit/score/cpu/sparc/window.S | 259 ++++++++++++++++++ 27 files changed, 756 insertions(+), 828 deletions(-) delete mode 100644 bsps/sparc/include/libcpu/access.h delete mode 100644 c/src/lib/libcpu/sparc/Makefile.am delete mode 100644 c/src/lib/libcpu/sparc/access/access.S delete mode 100644 c/src/lib/libcpu/sparc/access/access_le.c delete mode 100644 c/src/lib/libcpu/sparc/configure.ac delete mode 100644 c/src/lib/libcpu/sparc/reg_win/window.S delete mode 100644 c/src/lib/libcpu/sparc/syscall/syscall.S delete mode 100644 c/src/lib/libcpu/sparc/syscall/syscall.h create mode 100644 cpukit/score/cpu/sparc/access.S create mode 100644 cpukit/score/cpu/sparc/access_le.c create mode 100644 cpukit/score/cpu/sparc/include/libcpu/access.h create mode 100644 cpukit/score/cpu/sparc/syscall.S create mode 100644 cpukit/score/cpu/sparc/syscall.h create mode 100644 cpukit/score/cpu/sparc/window.S diff --git a/bsps/sparc/headers.am b/bsps/sparc/headers.am index c561e0c06f..5b4236e1b1 100644 --- a/bsps/sparc/headers.am +++ b/bsps/sparc/headers.am @@ -69,7 +69,3 @@ include_drvmgr_HEADERS += ../../../../../bsps/sparc/include/drvmgr/ambapp_bus.h include_drvmgr_HEADERS += ../../../../../bsps/sparc/include/drvmgr/ambapp_bus_grlib.h include_drvmgr_HEADERS += ../../../../../bsps/sparc/include/drvmgr/bspcommon.h include_drvmgr_HEADERS += ../../../../../bsps/sparc/include/drvmgr/leon2_amba_bus.h - -include_libcpudir = $(includedir)/libcpu -include_libcpu_HEADERS = -include_libcpu_HEADERS += ../../../../../bsps/sparc/include/libcpu/access.h diff --git a/bsps/sparc/include/libcpu/access.h b/bsps/sparc/include/libcpu/access.h deleted file mode 100644 index cdf6b77122..0000000000 --- a/bsps/sparc/include/libcpu/access.h +++ /dev/null @@ -1,50 +0,0 @@ -/* - * access.h - access routines for SPARC. SPARC is big endian only. - * - * COPYRIGHT (c) 2011 - * Aeroflex Gaisler. - * - * The license and distribution terms for this file may be - * found in the file LICENSE in this distribution or at - * http://www.rtems.org/license/LICENSE. - */ - -#ifndef _LIBCPU_ACCESS_H -#define _LIBCPU_ACCESS_H - -#include -#include - -#ifdef __cplusplus -extern "C" { -#endif - -/* "Raw" access */ -extern uint8_t _ld8(uint8_t *addr); -extern void _st8(uint8_t *addr, uint8_t val); -extern uint16_t _ld16(uint16_t *addr); -extern void _st16(uint16_t *addr, uint16_t val); -extern uint32_t _ld32(uint32_t *addr); -extern void _st32(uint32_t *addr, uint32_t val); -extern uint64_t _ld64(uint64_t *addr); -extern void _st64(uint64_t *addr, uint64_t val); - -/* Aliases for Big Endian */ -extern uint16_t _ld_be16(uint16_t *addr); -extern void _st_be16(uint16_t *addr, uint16_t val); -extern uint32_t _ld_be32(uint32_t *addr); -extern void _st_be32(uint32_t *addr, uint32_t val); -extern uint64_t _ld_be64(uint64_t *addr); -extern void _st_be64(uint64_t *addr, uint64_t val); - -/* Little endian */ -extern uint16_t _ld_le16(uint16_t *addr); -extern void _st_le16(uint16_t *addr, uint16_t val); -extern uint32_t _ld_le32(uint32_t *addr); -extern void _st_le32(uint32_t *addr, uint32_t val); - -#ifdef __cplusplus -} -#endif - -#endif diff --git a/c/src/lib/libbsp/sparc/erc32/Makefile.am b/c/src/lib/libbsp/sparc/erc32/Makefile.am index 52017ba0d6..1cfc273c21 100644 --- a/c/src/lib/libbsp/sparc/erc32/Makefile.am +++ b/c/src/lib/libbsp/sparc/erc32/Makefile.am @@ -78,11 +78,6 @@ endif libbsp_a_SOURCES += ../../../../../../bsps/shared/cache/nocache.c -libbsp_a_LIBADD = \ - ../../../libcpu/@RTEMS_CPU@/access.rel \ - ../../../libcpu/@RTEMS_CPU@/reg_win.rel \ - ../../../libcpu/@RTEMS_CPU@/syscall.rel - EXTRA_DIST += times include $(top_srcdir)/../../../../automake/local.am diff --git a/c/src/lib/libbsp/sparc/erc32/make/custom/erc32.cfg b/c/src/lib/libbsp/sparc/erc32/make/custom/erc32.cfg index 28593726a7..84cc752daf 100644 --- a/c/src/lib/libbsp/sparc/erc32/make/custom/erc32.cfg +++ b/c/src/lib/libbsp/sparc/erc32/make/custom/erc32.cfg @@ -5,7 +5,6 @@ include $(RTEMS_ROOT)/make/custom/default.cfg RTEMS_CPU=sparc -RTEMS_CPU_MODEL=erc32 # This contains the compiler options necessary to select the CPU model # and (hopefully) optimize for it. diff --git a/c/src/lib/libbsp/sparc/leon2/Makefile.am b/c/src/lib/libbsp/sparc/leon2/Makefile.am index f2d7e56a4f..24cfa7b853 100644 --- a/c/src/lib/libbsp/sparc/leon2/Makefile.am +++ b/c/src/lib/libbsp/sparc/leon2/Makefile.am @@ -176,11 +176,6 @@ libbsp_a_SOURCES += ../../sparc/shared/net/greth.c libbsp_a_SOURCES += ../../sparc/shared/net/network_interface_add.c endif -libbsp_a_LIBADD = \ - ../../../libcpu/@RTEMS_CPU@/access.rel \ - ../../../libcpu/@RTEMS_CPU@/reg_win.rel \ - ../../../libcpu/@RTEMS_CPU@/syscall.rel - EXTRA_DIST += times include $(top_srcdir)/../../../../automake/local.am diff --git a/c/src/lib/libbsp/sparc/leon2/make/custom/at697f.cfg b/c/src/lib/libbsp/sparc/leon2/make/custom/at697f.cfg index 3facbbee81..94ab6efbe9 100644 --- a/c/src/lib/libbsp/sparc/leon2/make/custom/at697f.cfg +++ b/c/src/lib/libbsp/sparc/leon2/make/custom/at697f.cfg @@ -5,7 +5,6 @@ include $(RTEMS_ROOT)/make/custom/default.cfg RTEMS_CPU=sparc -RTEMS_CPU_MODEL=leon2 # This contains the compiler options necessary to select the CPU model # and (hopefully) optimize for it. diff --git a/c/src/lib/libbsp/sparc/leon2/make/custom/leon2.cfg b/c/src/lib/libbsp/sparc/leon2/make/custom/leon2.cfg index 4db836ea3b..a5e76e7aa9 100644 --- a/c/src/lib/libbsp/sparc/leon2/make/custom/leon2.cfg +++ b/c/src/lib/libbsp/sparc/leon2/make/custom/leon2.cfg @@ -5,7 +5,6 @@ include $(RTEMS_ROOT)/make/custom/default.cfg RTEMS_CPU=sparc -RTEMS_CPU_MODEL=leon2 # This contains the compiler options necessary to select the CPU model # and (hopefully) optimize for it. diff --git a/c/src/lib/libbsp/sparc/leon3/Makefile.am b/c/src/lib/libbsp/sparc/leon3/Makefile.am index 614a5d5d26..ebceda15e1 100644 --- a/c/src/lib/libbsp/sparc/leon3/Makefile.am +++ b/c/src/lib/libbsp/sparc/leon3/Makefile.am @@ -202,11 +202,6 @@ libbsp_a_SOURCES += shmsupp/addrconv.c shmsupp/getcfg.c shmsupp/lock.c \ shmsupp/mpisr.c endif -libbsp_a_LIBADD = \ - ../../../libcpu/@RTEMS_CPU@/access.rel \ - ../../../libcpu/@RTEMS_CPU@/reg_win.rel \ - ../../../libcpu/@RTEMS_CPU@/syscall.rel - EXTRA_DIST += times include $(top_srcdir)/../../../../automake/local.am diff --git a/c/src/lib/libbsp/sparc/leon3/make/custom/gr712rc.cfg b/c/src/lib/libbsp/sparc/leon3/make/custom/gr712rc.cfg index 40c6d12524..897dd0142f 100644 --- a/c/src/lib/libbsp/sparc/leon3/make/custom/gr712rc.cfg +++ b/c/src/lib/libbsp/sparc/leon3/make/custom/gr712rc.cfg @@ -5,7 +5,6 @@ include $(RTEMS_ROOT)/make/custom/default.cfg RTEMS_CPU=sparc -RTEMS_CPU_MODEL=leon3 # This contains the compiler options necessary to select the CPU model # and (hopefully) optimize for it. diff --git a/c/src/lib/libbsp/sparc/leon3/make/custom/leon3.cfg b/c/src/lib/libbsp/sparc/leon3/make/custom/leon3.cfg index ef9a86851a..d931d6c5f1 100644 --- a/c/src/lib/libbsp/sparc/leon3/make/custom/leon3.cfg +++ b/c/src/lib/libbsp/sparc/leon3/make/custom/leon3.cfg @@ -5,7 +5,6 @@ include $(RTEMS_ROOT)/make/custom/default.cfg RTEMS_CPU=sparc -RTEMS_CPU_MODEL=leon3 # This contains the compiler options necessary to select the CPU model # and (hopefully) optimize for it. diff --git a/c/src/lib/libbsp/sparc/leon3/make/custom/ut699.cfg b/c/src/lib/libbsp/sparc/leon3/make/custom/ut699.cfg index 2150428a3d..a8fff49b3a 100644 --- a/c/src/lib/libbsp/sparc/leon3/make/custom/ut699.cfg +++ b/c/src/lib/libbsp/sparc/leon3/make/custom/ut699.cfg @@ -5,7 +5,6 @@ include $(RTEMS_ROOT)/make/custom/default.cfg RTEMS_CPU=sparc -RTEMS_CPU_MODEL=leon3 # This contains the compiler options necessary to select the CPU model # and (hopefully) optimize for it. diff --git a/c/src/lib/libbsp/sparc/leon3/make/custom/ut700.cfg b/c/src/lib/libbsp/sparc/leon3/make/custom/ut700.cfg index 9ee473eed2..bcca9010ed 100644 --- a/c/src/lib/libbsp/sparc/leon3/make/custom/ut700.cfg +++ b/c/src/lib/libbsp/sparc/leon3/make/custom/ut700.cfg @@ -5,7 +5,6 @@ include $(RTEMS_ROOT)/make/custom/default.cfg RTEMS_CPU=sparc -RTEMS_CPU_MODEL=leon3 # This contains the compiler options necessary to select the CPU model # and (hopefully) optimize for it. diff --git a/c/src/lib/libcpu/sparc/Makefile.am b/c/src/lib/libcpu/sparc/Makefile.am deleted file mode 100644 index 95e473d622..0000000000 --- a/c/src/lib/libcpu/sparc/Makefile.am +++ /dev/null @@ -1,22 +0,0 @@ -ACLOCAL_AMFLAGS = -I ../../../aclocal - -include $(top_srcdir)/../../../automake/compile.am - -noinst_PROGRAMS = - -noinst_PROGRAMS += syscall.rel -syscall_rel_SOURCES = syscall/syscall.S syscall/syscall.h -syscall_rel_CPPFLAGS = $(AM_CPPFLAGS) -syscall_rel_LDFLAGS = $(RTEMS_RELLDFLAGS) - -noinst_PROGRAMS += reg_win.rel -reg_win_rel_SOURCES = reg_win/window.S -reg_win_rel_CPPFLAGS = $(AM_CPPFLAGS) -reg_win_rel_LDFLAGS = $(RTEMS_RELLDFLAGS) - -noinst_PROGRAMS += access.rel -access_rel_SOURCES = access/access.S access/access_le.c -access_rel_CPPFLAGS = $(AM_CPPFLAGS) -access_rel_LDFLAGS = $(RTEMS_RELLDFLAGS) - -include $(top_srcdir)/../../../automake/local.am diff --git a/c/src/lib/libcpu/sparc/access/access.S b/c/src/lib/libcpu/sparc/access/access.S deleted file mode 100644 index 9397cb815b..0000000000 --- a/c/src/lib/libcpu/sparc/access/access.S +++ /dev/null @@ -1,109 +0,0 @@ -/* - * Optimized access routines for SPARC. - * - * Note the difference between byteorder.h (inlined functions) and access.S - * where the functions will be declared in the library archive librtemscpu.a. - * Function names starting with _ are in library and can be referenced by - * function pointers. - * - * _ldN, _stN standard machine endianess access (SPARC: big-endian) - * _ld_beN, _st_beN forced big-endian - * _ld_leN, _st_leN forced little-endian (defined in access_le.C) - * - * This file is written in assembly because the big-endian functions maps to - * machine dependant access methods, i.e. same function has two names. - * - * COPYRIGHT (c) 2011 - * Aeroflex Gaisler. - * - * The license and distribution terms for this file may be - * found in the file LICENSE in this distribution or at - * http://www.rtems.org/license/LICENSE. - */ - -#include - - .align 4 - .section ".text" - PUBLIC(_ld8) - PUBLIC(_ld16) - PUBLIC(_ld32) - PUBLIC(_ld64) - PUBLIC(_st8) - PUBLIC(_st16) - PUBLIC(_st32) - PUBLIC(_st64) - PUBLIC(_ld_be16) - PUBLIC(_ld_be32) - PUBLIC(_ld_be64) - PUBLIC(_st_be16) - PUBLIC(_st_be32) - PUBLIC(_st_be64) - -SYM(_ld8): - retl - ldub [%o0], %o0 - -SYM(_ld_be16): -SYM(_ld16): - retl - lduh [%o0], %o0 - -SYM(_ld_be32): -SYM(_ld32): - retl - ld [%o0], %o0 - -SYM(_ld_be64): -SYM(_ld64): - retl - ldd [%o0], %o0 - -#if defined(__FIX_LEON3FT_B2BST) - -SYM(_st8): - stub %o1, [%o0] - retl - nop - -SYM(_st_be16): -SYM(_st16): - stuh %o1, [%o0] - retl - nop - -SYM(_st_be32): -SYM(_st32): - st %o1, [%o0] - retl - nop - -SYM(_st_be64): -SYM(_st64): - std %o1, [%o0] - retl - nop - -#else - -SYM(_st8): - retl - stb %o1, [%o0] - -SYM(_st_be16): -SYM(_st16): - retl - sth %o1, [%o0] - -SYM(_st_be32): -SYM(_st32): - retl - st %o1, [%o0] - -SYM(_st_be64): -SYM(_st64): - mov %o2, %o3 - mov %o1, %o2 - retl - std %o2, [%o0] -#endif diff --git a/c/src/lib/libcpu/sparc/access/access_le.c b/c/src/lib/libcpu/sparc/access/access_le.c deleted file mode 100644 index d3a0e93adb..0000000000 --- a/c/src/lib/libcpu/sparc/access/access_le.c +++ /dev/null @@ -1,33 +0,0 @@ -/* - * Little-endian access routines for SPARC - * - * COPYRIGHT (c) 2011 - * Aeroflex Gaisler. - * - * The license and distribution terms for this file may be - * found in the file LICENSE in this distribution or at - * http://www.rtems.org/license/LICENSE. - */ - -#include -#include - -uint16_t _ld_le16(uint16_t *addr) -{ - return ld_le16(addr); -} - -void _st_le16(uint16_t *addr, uint16_t val) -{ - st_le16(addr, val); -} - -uint32_t _ld_le32(uint32_t *addr) -{ - return ld_le32(addr); -} - -void _st_le32(uint32_t *addr, uint32_t val) -{ - st_le32(addr, val); -} diff --git a/c/src/lib/libcpu/sparc/configure.ac b/c/src/lib/libcpu/sparc/configure.ac deleted file mode 100644 index 7107f971a9..0000000000 --- a/c/src/lib/libcpu/sparc/configure.ac +++ /dev/null @@ -1,29 +0,0 @@ -## Process this file with autoconf to produce a configure script. - -AC_PREREQ([2.69]) -AC_INIT([rtems-c-src-lib-libcpu-sparc],[_RTEMS_VERSION],[https://devel.rtems.org/newticket]) -AC_CONFIG_SRCDIR([reg_win]) -RTEMS_TOP([../../../../..],[../../..]) -RTEMS_SOURCE_TOP -RTEMS_BUILD_TOP - -RTEMS_CANONICAL_TARGET_CPU - -AM_INIT_AUTOMAKE([no-define foreign subdir-objects 1.12.2]) -AM_MAINTAINER_MODE - -RTEMS_ENV_RTEMSBSP - -RTEMS_PROJECT_ROOT - -RTEMS_PROG_CC_FOR_TARGET -AM_PROG_CC_C_O -RTEMS_CANONICALIZE_TOOLS -RTEMS_PROG_CCAS - -RTEMS_AMPOLISH3 - -# Explicitly list all Makefiles here -AC_CONFIG_FILES([Makefile]) -AC_OUTPUT - diff --git a/c/src/lib/libcpu/sparc/reg_win/window.S b/c/src/lib/libcpu/sparc/reg_win/window.S deleted file mode 100644 index 5a36fd65be..0000000000 --- a/c/src/lib/libcpu/sparc/reg_win/window.S +++ /dev/null @@ -1,259 +0,0 @@ -/* - * window.s - * - * This file contains the register window management routines for the - * SPARC architecture. Trap handlers for the following capabilities - * are included in this file: - * - * + Window Overflow - * + Window Underflow - * + Flushing All Windows - * - * COPYRIGHT: - * - * This file includes the window overflow and underflow handlers from - * the file srt0.s provided with the binary distribution of the SPARC - * Instruction Simulator (SIS) found at - * ftp://ftp.estec.esa.nl/pub/ws/wsd/erc32. - * - * COPYRIGHT (c) 1995. European Space Agency. - * - * This terms of the RTEMS license apply to this file. - */ - -#include - - .section ".text" - /* - * Window overflow trap handler. - * - * On entry: - * - * prev regwin l1 = pc - * prev regwin l2 = npc - */ - - PUBLIC(window_overflow_trap_handler) - -SYM(window_overflow_trap_handler): - - /* - * Calculate new WIM by "rotating" the valid bits in the WIM right - * by one position. The following shows how the bits move for a SPARC - * cpu implementation where SPARC_NUMBER_OF_REGISTER_WINDOWS is 8. - * - * OLD WIM = 76543210 - * NEW WIM = 07654321 - * - * NOTE: New WIM must be stored in a global register since the - * "save" instruction just prior to the load of the wim - * register will result in the local register set changing. - */ - - std %l0, [%sp + 0x00] ! save local register set - SPARC_LEON3FT_B2BST_NOP - std %l2, [%sp + 0x08] - mov %wim, %l3 - sll %l3, SPARC_NUMBER_OF_REGISTER_WINDOWS-1 , %l2 - ! l2 = WIM << (Number Windows - 1) - std %l4, [%sp + 0x10] - SPARC_LEON3FT_B2BST_NOP - std %l6, [%sp + 0x18] - srl %l3, 1, %l3 ! l3 = WIM >> 1 - wr %l3, %l2, %wim ! WIM = (WIM >> 1) ^ - ! (WIM << (Number Windows - 1)) - ! 3 instruction delay not needed here - std %i0, [%sp + 0x20] ! save input register set - SPARC_LEON3FT_B2BST_NOP - std %i2, [%sp + 0x28] - SPARC_LEON3FT_B2BST_NOP - std %i4, [%sp + 0x30] - SPARC_LEON3FT_B2BST_NOP - std %i6, [%sp + 0x38] - restore ! Go back to trap window. - jmp %l1 ! Re-execute save. - rett %l2 - - /* - * Window underflow trap handler. - * - * On entry: - * - * l1 = pc - * l2 = npc - * l3 = wim (from trap vector) - * l4 = wim << 1 (from trap vector) - */ - - PUBLIC(window_underflow_trap_handler) - -SYM(window_underflow_trap_handler): - - /* - * Calculate new WIM by "rotating" the valid bits in the WIM left - * by one position. The following shows how the bits move for a SPARC - * cpu implementation where SPARC_NUMBER_OF_REGISTER_WINDOWS is 8. - * - * OLD WIM = 76543210 - * NEW WIM = 07654321 - * - * NOTE: New WIM must be stored in a global register since the - * "save" instruction just prior to the load of the wim - * register will result in the local register set changing. - */ - - srl %l3, SPARC_NUMBER_OF_REGISTER_WINDOWS-1, %l5 - or %l5, %l4, %l5 ! l5 = (WIM << 1) | - ! (WIM >> (Number Windows-1)) - mov %l5, %wim ! load the new WIM - nop; nop; nop ! 3 slot delay - restore ! Two restores to get into the - restore ! window to restore - ldd [%sp + 0x00], %l0 ! First the local register set - ldd [%sp + 0x08], %l2 - ldd [%sp + 0x10], %l4 - ldd [%sp + 0x18], %l6 - ldd [%sp + 0x20], %i0 ! Then the input registers - ldd [%sp + 0x28], %i2 - ldd [%sp + 0x30], %i4 - ldd [%sp + 0x38], %i6 - save ! Get back to the trap window. - save - jmp %l1 ! Re-execute restore. - rett %l2 - - /* - * Flush All Windows trap handler. - * - * Flush all windows with valid contents except the current one - * and the one we will be returning to. - * - * In examining the set register windows, one may logically divide - * the windows into sets (some of which may be empty) based on their - * current status: - * - * + current (i.e. in use), - * + used (i.e. a restore would not trap) - * + invalid (i.e. 1 in corresponding bit in WIM) - * + unused - * - * Either the used or unused set of windows may be empty. - * - * NOTE: We assume only one bit is set in the WIM at a time. - * - * Given a CWP of 5 and a WIM of 0x1, the registers are divided - * into sets as follows: - * - * + 0 - invalid - * + 1-4 - unused - * + 5 - current - * + 6-7 - used - * - * In this case, we only would save the used windows which we - * will not be returning to -- 6. - * - * Register Usage while saving the windows: - * g1 = current PSR - * g2 = current wim - * g3 = CWP - * g4 = wim scratch - * g5 = scratch - * - * On entry: - * - * l0 = psr (from trap table) - * l1 = pc - * l2 = npc - */ - - PUBLIC(window_flush_trap_handler) - -SYM(window_flush_trap_handler): - /* - * Save the global registers we will be using - */ - - mov %g1, %l3 - mov %g2, %l4 - mov %g3, %l5 - mov %g4, %l6 - mov %g5, %l7 - - mov %l0, %g1 ! g1 = psr - mov %wim, %g2 ! g2 = wim - and %l0, SPARC_PSR_CWP_MASK, %g3 ! g3 = CWP - - add %g3, 1, %g5 ! g5 = CWP + 1 - and %g5, SPARC_NUMBER_OF_REGISTER_WINDOWS - 1, %g5 - - mov 1, %g4 - sll %g4, %g5, %g4 ! g4 = WIM mask for CWP+1 invalid - - restore ! go back one register window - -save_frame_loop: - sll %g4, 1, %g5 ! rotate the "wim" left 1 - srl %g4, SPARC_NUMBER_OF_REGISTER_WINDOWS - 1, %g4 - or %g4, %g5, %g4 ! g4 = wim if we do one restore - - /* - * If a restore would not underflow, then continue. - */ - - andcc %g4, %g2, %g0 ! Any windows to flush? - bnz done_flushing ! No, then continue - nop - - restore ! back one window - - /* - * Now save the window just as if we overflowed to it. - */ - - std %l0, [%sp + CPU_STACK_FRAME_L0_OFFSET] - SPARC_LEON3FT_B2BST_NOP - std %l2, [%sp + CPU_STACK_FRAME_L2_OFFSET] - SPARC_LEON3FT_B2BST_NOP - std %l4, [%sp + CPU_STACK_FRAME_L4_OFFSET] - SPARC_LEON3FT_B2BST_NOP - std %l6, [%sp + CPU_STACK_FRAME_L6_OFFSET] - SPARC_LEON3FT_B2BST_NOP - - std %i0, [%sp + CPU_STACK_FRAME_I0_OFFSET] - SPARC_LEON3FT_B2BST_NOP - std %i2, [%sp + CPU_STACK_FRAME_I2_OFFSET] - SPARC_LEON3FT_B2BST_NOP - std %i4, [%sp + CPU_STACK_FRAME_I4_OFFSET] - SPARC_LEON3FT_B2BST_NOP - std %i6, [%sp + CPU_STACK_FRAME_I6_FP_OFFSET] - - ba save_frame_loop - nop - -done_flushing: - - add %g3, 2, %g3 ! calculate desired WIM - and %g3, SPARC_NUMBER_OF_REGISTER_WINDOWS - 1, %g3 - mov 1, %g4 - sll %g4, %g3, %g4 ! g4 = new WIM - mov %g4, %wim - - mov %g1, %psr ! restore PSR - nop - nop - nop - - /* - * Restore the global registers we used - */ - - mov %l3, %g1 - mov %l4, %g2 - mov %l5, %g3 - mov %l6, %g4 - mov %l7, %g5 - - jmpl %l2, %g0 - rett %l2 + 4 - -/* end of file */ diff --git a/c/src/lib/libcpu/sparc/syscall/syscall.S b/c/src/lib/libcpu/sparc/syscall/syscall.S deleted file mode 100644 index da0ee43889..0000000000 --- a/c/src/lib/libcpu/sparc/syscall/syscall.S +++ /dev/null @@ -1,295 +0,0 @@ -/* - * systrap.S - * - * This file contains emulated system calls using software trap 0. - * The following calls are supported: - * - * + SYS_exit (halt) - * + SYS_irqdis (disable interrupts) - * + SYS_irqset (set interrupt level) - * - * COPYRIGHT: - * - * COPYRIGHT (c) 1995. European Space Agency. - * Copyright (c) 2016, 2017 embedded brains GmbH - * - * This terms of the RTEMS license apply to this file. - * - */ - -#include -#include -#include -#include "syscall.h" - - .section ".text" - /* - * system call - halt - * - * On entry: - * - * l0 = psr (from trap table) - * l1 = pc - * l2 = npc - * g1 = system call id (1) - * - * System Call 1 (exit): - * g2 = additional exit code 1 - * g3 = additional exit code 2 - */ - - PUBLIC(syscall) - -SYM(syscall): - ta 0 ! syscall 1, halt with %g1,%g2,%g3 info - - PUBLIC(sparc_syscall_exit) - -SYM(sparc_syscall_exit): - - mov SYS_exit, %g1 - mov %o0, %g2 ! Additional exit code 1 - mov %o1, %g3 ! Additional exit code 2 - ta SPARC_SWTRAP_SYSCALL - - /* - * system call - Interrupt Disable - * - * On entry: - * - * l0 = psr (from trap table) - * l1 = pc - * l2 = npc - * l3 = psr | SPARC_PSR_PIL_MASK - * - * On exit: - * g1 = old psr (to user) - */ - -.align 32 ! Align to 32-byte cache-line - PUBLIC(syscall_irqdis) - -SYM(syscall_irqdis): - mov %l3, %psr ! Set PSR. Write delay 3 instr - or %l0, SPARC_PSR_ET_MASK, %g1 ! return old PSR with ET=1 - nop ! PSR write delay - jmp %l2 ! Return to after TA 9. - rett %l2 + 4 - - /* - * system call - Interrupt Enable - * - * On entry: - * - * l0 = psr (from trap table) - * l1 = pc - * l2 = npc - * l3 = psr & ~0x0f00 - * g1 = new PIL to write (from user) - */ - -.align 32 ! Align to 32-byte cache-line - PUBLIC(syscall_irqen) - -SYM(syscall_irqen): - and %g1, SPARC_PSR_PIL_MASK, %l4 ! %l4 = (%g1 & 0xf00) - wr %l3, %l4, %psr ! PSR = (PSR & ~0xf00) ^ %l4 - nop; nop ! PSR write delay; - jmp %l2 ! Return to after TA 10. - rett %l2 + 4 - -#if defined(SPARC_USE_SYNCHRONOUS_FP_SWITCH) - /* - * system call - Interrupt disable and set PSR[EF] according to caller - * specified %g1 - * - * On entry: - * - * g1 = the desired PSR[EF] value (from caller) - * l0 = psr (from trap table) - * l1 = pc - * l2 = npc - * l3 = psr | SPARC_PSR_PIL_MASK - * - * On exit: - * g1 = old psr (to user) - */ - -.align 32 ! Align to 32-byte cache-line - PUBLIC(syscall_irqdis_fp) - -SYM(syscall_irqdis_fp): - /* - * We cannot use an intermediate value for operations with the PSR[EF] - * bit since they use a 13-bit sign extension and PSR[EF] is bit 12. - */ - sethi %hi(SPARC_PSR_EF_MASK), %l4 - - andn %l3, %l4, %l3 ! Clear PSR[EF] - and %g1, %l4, %g1 ! Select PSR[EF] only from %g1 - or %l3, %g1, %l3 ! Set PSR[EF] according to %g1 - mov %l3, %psr ! Set PSR. Write delay 3 instr - or %l0, SPARC_PSR_ET_MASK, %g1 ! return old PSR with ET=1 - nop ! PSR write delay - jmp %l2 ! Return to after TA 9. - rett %l2 + 4 -#endif - -#if defined(SPARC_USE_LAZY_FP_SWITCH) - - /* - * system call - Perform a lazy floating point switch - * - * On entry: - * - * l0 = psr (from trap table) - * l1 = pc - * l2 = npc - * l3 = SPARC_PSR_EF_MASK - */ - -.align 32 ! Align to 32-byte cache-line - PUBLIC(syscall_lazy_fp_switch) - -SYM(syscall_lazy_fp_switch): - ld [%g6 + PER_CPU_OFFSET_EXECUTING], %l4 - ld [%g6 + PER_CPU_ISR_NEST_LEVEL], %l5 - ld [%l4 + %lo(SPARC_THREAD_CONTROL_FP_CONTEXT_OFFSET)], %l6 - ld [%g6 + SPARC_PER_CPU_FP_OWNER_OFFSET], %l7 - - /* Ensure that we are not in interrupt context */ - cmp %l5, 0 - bne .Lillegal_use_of_floating_point_unit - or %l0, %l3, %l0 - - /* Ensure that we are a proper floating point thread */ - cmp %l6, 0 - be .Lillegal_use_of_floating_point_unit - ld [%l4 + %lo(SPARC_THREAD_CONTROL_REGISTERS_FP_CONTEXT_OFFSET)], %l6 - - /* Set PSR[EF] to 1, PSR write delay 3 instructions! */ - mov %l0, %psr - - /* - * Check if there is a floating point owner. We have to check this - * here, since the floating point owner may have been deleted in the - * meantime. Save the floating point context if necessary. - */ - cmp %l7, 0 - be .Lfp_save_done - nop - ld [%l7 + %lo(SPARC_THREAD_CONTROL_FP_CONTEXT_OFFSET)], %l5 - std %f0, [%l5 + SPARC_FP_CONTEXT_OFFSET_F0_F1] - SPARC_LEON3FT_B2BST_NOP - std %f2, [%l5 + SPARC_FP_CONTEXT_OFFSET_F2_F3] - SPARC_LEON3FT_B2BST_NOP - std %f4, [%l5 + SPARC_FP_CONTEXT_OFFSET_F4_F5] - SPARC_LEON3FT_B2BST_NOP - std %f6, [%l5 + SPARC_FP_CONTEXT_OFFSET_F6_F7] - SPARC_LEON3FT_B2BST_NOP - std %f8, [%l5 + SPARC_FP_CONTEXT_OFFSET_F8_F9] - SPARC_LEON3FT_B2BST_NOP - std %f10, [%l5 + SPARC_FP_CONTEXT_OFFSET_F10_F11] - SPARC_LEON3FT_B2BST_NOP - std %f12, [%l5 + SPARC_FP_CONTEXT_OFFSET_F12_F13] - SPARC_LEON3FT_B2BST_NOP - std %f14, [%l5 + SPARC_FP_CONTEXT_OFFSET_F14_F15] - SPARC_LEON3FT_B2BST_NOP - std %f16, [%l5 + SPARC_FP_CONTEXT_OFFSET_F16_F17] - SPARC_LEON3FT_B2BST_NOP - std %f18, [%l5 + SPARC_FP_CONTEXT_OFFSET_F18_F19] - SPARC_LEON3FT_B2BST_NOP - std %f20, [%l5 + SPARC_FP_CONTEXT_OFFSET_F20_F21] - SPARC_LEON3FT_B2BST_NOP - std %f22, [%l5 + SPARC_FP_CONTEXT_OFFSET_F22_F23] - SPARC_LEON3FT_B2BST_NOP - std %f24, [%l5 + SPARC_FP_CONTEXT_OFFSET_F24_F25] - SPARC_LEON3FT_B2BST_NOP - std %f26, [%l5 + SPARC_FP_CONTEXT_OFFSET_F26_F27] - SPARC_LEON3FT_B2BST_NOP - std %f28, [%l5 + SPARC_FP_CONTEXT_OFFSET_F28_F29] - SPARC_LEON3FT_B2BST_NOP - std %f30, [%l5 + SPARC_FP_CONTEXT_OFFSET_F30_F31] - SPARC_LEON3FT_B2BST_NOP - st %fsr, [%l5 + SPARC_FP_CONTEXT_OFFSET_FSR] - SPARC_LEON3FT_B2BST_NOP - st %g0, [%g6 + SPARC_PER_CPU_FP_OWNER_OFFSET] - SPARC_LEON3FT_B2BST_NOP - st %l5, [%l7 + %lo(SPARC_THREAD_CONTROL_REGISTERS_FP_CONTEXT_OFFSET)] - -.Lfp_save_done: - - /* Restore the floating point context if necessary */ - cmp %l6, 0 - be .Lfp_restore_done - st %g0, [%l4 + %lo(SPARC_THREAD_CONTROL_REGISTERS_FP_CONTEXT_OFFSET)] - ldd [%l6 + SPARC_FP_CONTEXT_OFFSET_F0_F1], %f0 - ldd [%l6 + SPARC_FP_CONTEXT_OFFSET_F2_F3], %f2 - ldd [%l6 + SPARC_FP_CONTEXT_OFFSET_F4_F5], %f4 - ldd [%l6 + SPARC_FP_CONTEXT_OFFSET_F6_F7], %f6 - ldd [%l6 + SPARC_FP_CONTEXT_OFFSET_F8_F9], %f8 - ldd [%l6 + SPARC_FP_CONTEXT_OFFSET_F10_F11], %f10 - ldd [%l6 + SPARC_FP_CONTEXT_OFFSET_F12_F13], %f12 - ldd [%l6 + SPARC_FP_CONTEXT_OFFSET_F14_F15], %f14 - ldd [%l6 + SPARC_FP_CONTEXT_OFFSET_F16_F17], %f16 - ldd [%l6 + SPARC_FP_CONTEXT_OFFSET_F18_F19], %f18 - ldd [%l6 + SPARC_FP_CONTEXT_OFFSET_F20_F21], %f20 - ldd [%l6 + SPARC_FP_CONTEXT_OFFSET_F22_F23], %f22 - ldd [%l6 + SPARC_FP_CONTEXT_OFFSET_F24_F25], %f24 - ldd [%l6 + SPARC_FP_CONTEXT_OFFSET_F26_F27], %f26 - ldd [%l6 + SPARC_FP_CONTEXT_OFFSET_F28_F29], %f28 - ldd [%l6 + SPARC_FP_CONTEXT_OFFSET_F30_F31], %f30 - ld [%l6 + SPARC_FP_CONTEXT_OFFSET_FSR], %fsr - -.Lfp_restore_done: - - /* Now, retry the floating point instruction with PSR[EF] == 1 */ - jmp %l1 - rett %l1 + 4 - -.Lillegal_use_of_floating_point_unit: - - sethi %hi(_Internal_error), %l1 - or %l1, %lo(_Internal_error), %l1 - mov 38, %i0 - jmp %l1 - rett %l1 + 4 -#endif - -#if defined(RTEMS_PARAVIRT) - - PUBLIC(_SPARC_Get_PSR) - -SYM(_SPARC_Get_PSR): - - retl - rd %psr, %o0 - - PUBLIC(_SPARC_Set_PSR) - -SYM(_SPARC_Set_PSR): - - mov %o0, %psr - nop - nop - nop - retl - nop - - PUBLIC(_SPARC_Get_TBR) - -SYM(_SPARC_Get_TBR): - - retl - rd %tbr, %o0 - - PUBLIC(_SPARC_Set_TBR) - -SYM(_SPARC_Set_TBR): - - retl - wr %o0, 0, %tbr - -#endif /* defined(RTEMS_PARAVIRT) */ - -/* end of file */ diff --git a/c/src/lib/libcpu/sparc/syscall/syscall.h b/c/src/lib/libcpu/sparc/syscall/syscall.h deleted file mode 100644 index 2f20886840..0000000000 --- a/c/src/lib/libcpu/sparc/syscall/syscall.h +++ /dev/null @@ -1 +0,0 @@ -#define SYS_exit 1 diff --git a/cpukit/score/cpu/sparc/Makefile.am b/cpukit/score/cpu/sparc/Makefile.am index 1a76a2f009..817cc11741 100644 --- a/cpukit/score/cpu/sparc/Makefile.am +++ b/cpukit/score/cpu/sparc/Makefile.am @@ -1,12 +1,16 @@ include $(top_srcdir)/automake/compile.am noinst_LIBRARIES = libscorecpu.a -libscorecpu_a_SOURCES = cpu.c -libscorecpu_a_SOURCES += sparc-context-volatile-clobber.S +libscorecpu_a_SOURCES = +libscorecpu_a_SOURCES += access_le.c +libscorecpu_a_SOURCES += access.S +libscorecpu_a_SOURCES += cpu.c libscorecpu_a_SOURCES += sparc-context-validate.S -libscorecpu_a_SOURCES += sparc-counter.c +libscorecpu_a_SOURCES += sparc-context-volatile-clobber.S libscorecpu_a_SOURCES += sparc-counter-asm.S -libscorecpu_a_CPPFLAGS = $(AM_CPPFLAGS) +libscorecpu_a_SOURCES += sparc-counter.c +libscorecpu_a_SOURCES += syscall.S +libscorecpu_a_SOURCES += window.S include $(top_srcdir)/automake/local.am include $(srcdir)/headers.am diff --git a/cpukit/score/cpu/sparc/access.S b/cpukit/score/cpu/sparc/access.S new file mode 100644 index 0000000000..9397cb815b --- /dev/null +++ b/cpukit/score/cpu/sparc/access.S @@ -0,0 +1,109 @@ +/* + * Optimized access routines for SPARC. + * + * Note the difference between byteorder.h (inlined functions) and access.S + * where the functions will be declared in the library archive librtemscpu.a. + * Function names starting with _ are in library and can be referenced by + * function pointers. + * + * _ldN, _stN standard machine endianess access (SPARC: big-endian) + * _ld_beN, _st_beN forced big-endian + * _ld_leN, _st_leN forced little-endian (defined in access_le.C) + * + * This file is written in assembly because the big-endian functions maps to + * machine dependant access methods, i.e. same function has two names. + * + * COPYRIGHT (c) 2011 + * Aeroflex Gaisler. + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.org/license/LICENSE. + */ + +#include + + .align 4 + .section ".text" + PUBLIC(_ld8) + PUBLIC(_ld16) + PUBLIC(_ld32) + PUBLIC(_ld64) + PUBLIC(_st8) + PUBLIC(_st16) + PUBLIC(_st32) + PUBLIC(_st64) + PUBLIC(_ld_be16) + PUBLIC(_ld_be32) + PUBLIC(_ld_be64) + PUBLIC(_st_be16) + PUBLIC(_st_be32) + PUBLIC(_st_be64) + +SYM(_ld8): + retl + ldub [%o0], %o0 + +SYM(_ld_be16): +SYM(_ld16): + retl + lduh [%o0], %o0 + +SYM(_ld_be32): +SYM(_ld32): + retl + ld [%o0], %o0 + +SYM(_ld_be64): +SYM(_ld64): + retl + ldd [%o0], %o0 + +#if defined(__FIX_LEON3FT_B2BST) + +SYM(_st8): + stub %o1, [%o0] + retl + nop + +SYM(_st_be16): +SYM(_st16): + stuh %o1, [%o0] + retl + nop + +SYM(_st_be32): +SYM(_st32): + st %o1, [%o0] + retl + nop + +SYM(_st_be64): +SYM(_st64): + std %o1, [%o0] + retl + nop + +#else + +SYM(_st8): + retl + stb %o1, [%o0] + +SYM(_st_be16): +SYM(_st16): + retl + sth %o1, [%o0] + +SYM(_st_be32): +SYM(_st32): + retl + st %o1, [%o0] + +SYM(_st_be64): +SYM(_st64): + mov %o2, %o3 + mov %o1, %o2 + retl + std %o2, [%o0] +#endif diff --git a/cpukit/score/cpu/sparc/access_le.c b/cpukit/score/cpu/sparc/access_le.c new file mode 100644 index 0000000000..d3a0e93adb --- /dev/null +++ b/cpukit/score/cpu/sparc/access_le.c @@ -0,0 +1,33 @@ +/* + * Little-endian access routines for SPARC + * + * COPYRIGHT (c) 2011 + * Aeroflex Gaisler. + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.org/license/LICENSE. + */ + +#include +#include + +uint16_t _ld_le16(uint16_t *addr) +{ + return ld_le16(addr); +} + +void _st_le16(uint16_t *addr, uint16_t val) +{ + st_le16(addr, val); +} + +uint32_t _ld_le32(uint32_t *addr) +{ + return ld_le32(addr); +} + +void _st_le32(uint32_t *addr, uint32_t val) +{ + st_le32(addr, val); +} diff --git a/cpukit/score/cpu/sparc/headers.am b/cpukit/score/cpu/sparc/headers.am index 0e1aea959b..f0c179c827 100644 --- a/cpukit/score/cpu/sparc/headers.am +++ b/cpukit/score/cpu/sparc/headers.am @@ -2,6 +2,7 @@ include_libcpudir = $(includedir)/libcpu include_libcpu_HEADERS = +include_libcpu_HEADERS += include/libcpu/access.h include_libcpu_HEADERS += include/libcpu/byteorder.h include_machinedir = $(includedir)/machine diff --git a/cpukit/score/cpu/sparc/include/libcpu/access.h b/cpukit/score/cpu/sparc/include/libcpu/access.h new file mode 100644 index 0000000000..cdf6b77122 --- /dev/null +++ b/cpukit/score/cpu/sparc/include/libcpu/access.h @@ -0,0 +1,50 @@ +/* + * access.h - access routines for SPARC. SPARC is big endian only. + * + * COPYRIGHT (c) 2011 + * Aeroflex Gaisler. + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.org/license/LICENSE. + */ + +#ifndef _LIBCPU_ACCESS_H +#define _LIBCPU_ACCESS_H + +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/* "Raw" access */ +extern uint8_t _ld8(uint8_t *addr); +extern void _st8(uint8_t *addr, uint8_t val); +extern uint16_t _ld16(uint16_t *addr); +extern void _st16(uint16_t *addr, uint16_t val); +extern uint32_t _ld32(uint32_t *addr); +extern void _st32(uint32_t *addr, uint32_t val); +extern uint64_t _ld64(uint64_t *addr); +extern void _st64(uint64_t *addr, uint64_t val); + +/* Aliases for Big Endian */ +extern uint16_t _ld_be16(uint16_t *addr); +extern void _st_be16(uint16_t *addr, uint16_t val); +extern uint32_t _ld_be32(uint32_t *addr); +extern void _st_be32(uint32_t *addr, uint32_t val); +extern uint64_t _ld_be64(uint64_t *addr); +extern void _st_be64(uint64_t *addr, uint64_t val); + +/* Little endian */ +extern uint16_t _ld_le16(uint16_t *addr); +extern void _st_le16(uint16_t *addr, uint16_t val); +extern uint32_t _ld_le32(uint32_t *addr); +extern void _st_le32(uint32_t *addr, uint32_t val); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/cpukit/score/cpu/sparc/syscall.S b/cpukit/score/cpu/sparc/syscall.S new file mode 100644 index 0000000000..da0ee43889 --- /dev/null +++ b/cpukit/score/cpu/sparc/syscall.S @@ -0,0 +1,295 @@ +/* + * systrap.S + * + * This file contains emulated system calls using software trap 0. + * The following calls are supported: + * + * + SYS_exit (halt) + * + SYS_irqdis (disable interrupts) + * + SYS_irqset (set interrupt level) + * + * COPYRIGHT: + * + * COPYRIGHT (c) 1995. European Space Agency. + * Copyright (c) 2016, 2017 embedded brains GmbH + * + * This terms of the RTEMS license apply to this file. + * + */ + +#include +#include +#include +#include "syscall.h" + + .section ".text" + /* + * system call - halt + * + * On entry: + * + * l0 = psr (from trap table) + * l1 = pc + * l2 = npc + * g1 = system call id (1) + * + * System Call 1 (exit): + * g2 = additional exit code 1 + * g3 = additional exit code 2 + */ + + PUBLIC(syscall) + +SYM(syscall): + ta 0 ! syscall 1, halt with %g1,%g2,%g3 info + + PUBLIC(sparc_syscall_exit) + +SYM(sparc_syscall_exit): + + mov SYS_exit, %g1 + mov %o0, %g2 ! Additional exit code 1 + mov %o1, %g3 ! Additional exit code 2 + ta SPARC_SWTRAP_SYSCALL + + /* + * system call - Interrupt Disable + * + * On entry: + * + * l0 = psr (from trap table) + * l1 = pc + * l2 = npc + * l3 = psr | SPARC_PSR_PIL_MASK + * + * On exit: + * g1 = old psr (to user) + */ + +.align 32 ! Align to 32-byte cache-line + PUBLIC(syscall_irqdis) + +SYM(syscall_irqdis): + mov %l3, %psr ! Set PSR. Write delay 3 instr + or %l0, SPARC_PSR_ET_MASK, %g1 ! return old PSR with ET=1 + nop ! PSR write delay + jmp %l2 ! Return to after TA 9. + rett %l2 + 4 + + /* + * system call - Interrupt Enable + * + * On entry: + * + * l0 = psr (from trap table) + * l1 = pc + * l2 = npc + * l3 = psr & ~0x0f00 + * g1 = new PIL to write (from user) + */ + +.align 32 ! Align to 32-byte cache-line + PUBLIC(syscall_irqen) + +SYM(syscall_irqen): + and %g1, SPARC_PSR_PIL_MASK, %l4 ! %l4 = (%g1 & 0xf00) + wr %l3, %l4, %psr ! PSR = (PSR & ~0xf00) ^ %l4 + nop; nop ! PSR write delay; + jmp %l2 ! Return to after TA 10. + rett %l2 + 4 + +#if defined(SPARC_USE_SYNCHRONOUS_FP_SWITCH) + /* + * system call - Interrupt disable and set PSR[EF] according to caller + * specified %g1 + * + * On entry: + * + * g1 = the desired PSR[EF] value (from caller) + * l0 = psr (from trap table) + * l1 = pc + * l2 = npc + * l3 = psr | SPARC_PSR_PIL_MASK + * + * On exit: + * g1 = old psr (to user) + */ + +.align 32 ! Align to 32-byte cache-line + PUBLIC(syscall_irqdis_fp) + +SYM(syscall_irqdis_fp): + /* + * We cannot use an intermediate value for operations with the PSR[EF] + * bit since they use a 13-bit sign extension and PSR[EF] is bit 12. + */ + sethi %hi(SPARC_PSR_EF_MASK), %l4 + + andn %l3, %l4, %l3 ! Clear PSR[EF] + and %g1, %l4, %g1 ! Select PSR[EF] only from %g1 + or %l3, %g1, %l3 ! Set PSR[EF] according to %g1 + mov %l3, %psr ! Set PSR. Write delay 3 instr + or %l0, SPARC_PSR_ET_MASK, %g1 ! return old PSR with ET=1 + nop ! PSR write delay + jmp %l2 ! Return to after TA 9. + rett %l2 + 4 +#endif + +#if defined(SPARC_USE_LAZY_FP_SWITCH) + + /* + * system call - Perform a lazy floating point switch + * + * On entry: + * + * l0 = psr (from trap table) + * l1 = pc + * l2 = npc + * l3 = SPARC_PSR_EF_MASK + */ + +.align 32 ! Align to 32-byte cache-line + PUBLIC(syscall_lazy_fp_switch) + +SYM(syscall_lazy_fp_switch): + ld [%g6 + PER_CPU_OFFSET_EXECUTING], %l4 + ld [%g6 + PER_CPU_ISR_NEST_LEVEL], %l5 + ld [%l4 + %lo(SPARC_THREAD_CONTROL_FP_CONTEXT_OFFSET)], %l6 + ld [%g6 + SPARC_PER_CPU_FP_OWNER_OFFSET], %l7 + + /* Ensure that we are not in interrupt context */ + cmp %l5, 0 + bne .Lillegal_use_of_floating_point_unit + or %l0, %l3, %l0 + + /* Ensure that we are a proper floating point thread */ + cmp %l6, 0 + be .Lillegal_use_of_floating_point_unit + ld [%l4 + %lo(SPARC_THREAD_CONTROL_REGISTERS_FP_CONTEXT_OFFSET)], %l6 + + /* Set PSR[EF] to 1, PSR write delay 3 instructions! */ + mov %l0, %psr + + /* + * Check if there is a floating point owner. We have to check this + * here, since the floating point owner may have been deleted in the + * meantime. Save the floating point context if necessary. + */ + cmp %l7, 0 + be .Lfp_save_done + nop + ld [%l7 + %lo(SPARC_THREAD_CONTROL_FP_CONTEXT_OFFSET)], %l5 + std %f0, [%l5 + SPARC_FP_CONTEXT_OFFSET_F0_F1] + SPARC_LEON3FT_B2BST_NOP + std %f2, [%l5 + SPARC_FP_CONTEXT_OFFSET_F2_F3] + SPARC_LEON3FT_B2BST_NOP + std %f4, [%l5 + SPARC_FP_CONTEXT_OFFSET_F4_F5] + SPARC_LEON3FT_B2BST_NOP + std %f6, [%l5 + SPARC_FP_CONTEXT_OFFSET_F6_F7] + SPARC_LEON3FT_B2BST_NOP + std %f8, [%l5 + SPARC_FP_CONTEXT_OFFSET_F8_F9] + SPARC_LEON3FT_B2BST_NOP + std %f10, [%l5 + SPARC_FP_CONTEXT_OFFSET_F10_F11] + SPARC_LEON3FT_B2BST_NOP + std %f12, [%l5 + SPARC_FP_CONTEXT_OFFSET_F12_F13] + SPARC_LEON3FT_B2BST_NOP + std %f14, [%l5 + SPARC_FP_CONTEXT_OFFSET_F14_F15] + SPARC_LEON3FT_B2BST_NOP + std %f16, [%l5 + SPARC_FP_CONTEXT_OFFSET_F16_F17] + SPARC_LEON3FT_B2BST_NOP + std %f18, [%l5 + SPARC_FP_CONTEXT_OFFSET_F18_F19] + SPARC_LEON3FT_B2BST_NOP + std %f20, [%l5 + SPARC_FP_CONTEXT_OFFSET_F20_F21] + SPARC_LEON3FT_B2BST_NOP + std %f22, [%l5 + SPARC_FP_CONTEXT_OFFSET_F22_F23] + SPARC_LEON3FT_B2BST_NOP + std %f24, [%l5 + SPARC_FP_CONTEXT_OFFSET_F24_F25] + SPARC_LEON3FT_B2BST_NOP + std %f26, [%l5 + SPARC_FP_CONTEXT_OFFSET_F26_F27] + SPARC_LEON3FT_B2BST_NOP + std %f28, [%l5 + SPARC_FP_CONTEXT_OFFSET_F28_F29] + SPARC_LEON3FT_B2BST_NOP + std %f30, [%l5 + SPARC_FP_CONTEXT_OFFSET_F30_F31] + SPARC_LEON3FT_B2BST_NOP + st %fsr, [%l5 + SPARC_FP_CONTEXT_OFFSET_FSR] + SPARC_LEON3FT_B2BST_NOP + st %g0, [%g6 + SPARC_PER_CPU_FP_OWNER_OFFSET] + SPARC_LEON3FT_B2BST_NOP + st %l5, [%l7 + %lo(SPARC_THREAD_CONTROL_REGISTERS_FP_CONTEXT_OFFSET)] + +.Lfp_save_done: + + /* Restore the floating point context if necessary */ + cmp %l6, 0 + be .Lfp_restore_done + st %g0, [%l4 + %lo(SPARC_THREAD_CONTROL_REGISTERS_FP_CONTEXT_OFFSET)] + ldd [%l6 + SPARC_FP_CONTEXT_OFFSET_F0_F1], %f0 + ldd [%l6 + SPARC_FP_CONTEXT_OFFSET_F2_F3], %f2 + ldd [%l6 + SPARC_FP_CONTEXT_OFFSET_F4_F5], %f4 + ldd [%l6 + SPARC_FP_CONTEXT_OFFSET_F6_F7], %f6 + ldd [%l6 + SPARC_FP_CONTEXT_OFFSET_F8_F9], %f8 + ldd [%l6 + SPARC_FP_CONTEXT_OFFSET_F10_F11], %f10 + ldd [%l6 + SPARC_FP_CONTEXT_OFFSET_F12_F13], %f12 + ldd [%l6 + SPARC_FP_CONTEXT_OFFSET_F14_F15], %f14 + ldd [%l6 + SPARC_FP_CONTEXT_OFFSET_F16_F17], %f16 + ldd [%l6 + SPARC_FP_CONTEXT_OFFSET_F18_F19], %f18 + ldd [%l6 + SPARC_FP_CONTEXT_OFFSET_F20_F21], %f20 + ldd [%l6 + SPARC_FP_CONTEXT_OFFSET_F22_F23], %f22 + ldd [%l6 + SPARC_FP_CONTEXT_OFFSET_F24_F25], %f24 + ldd [%l6 + SPARC_FP_CONTEXT_OFFSET_F26_F27], %f26 + ldd [%l6 + SPARC_FP_CONTEXT_OFFSET_F28_F29], %f28 + ldd [%l6 + SPARC_FP_CONTEXT_OFFSET_F30_F31], %f30 + ld [%l6 + SPARC_FP_CONTEXT_OFFSET_FSR], %fsr + +.Lfp_restore_done: + + /* Now, retry the floating point instruction with PSR[EF] == 1 */ + jmp %l1 + rett %l1 + 4 + +.Lillegal_use_of_floating_point_unit: + + sethi %hi(_Internal_error), %l1 + or %l1, %lo(_Internal_error), %l1 + mov 38, %i0 + jmp %l1 + rett %l1 + 4 +#endif + +#if defined(RTEMS_PARAVIRT) + + PUBLIC(_SPARC_Get_PSR) + +SYM(_SPARC_Get_PSR): + + retl + rd %psr, %o0 + + PUBLIC(_SPARC_Set_PSR) + +SYM(_SPARC_Set_PSR): + + mov %o0, %psr + nop + nop + nop + retl + nop + + PUBLIC(_SPARC_Get_TBR) + +SYM(_SPARC_Get_TBR): + + retl + rd %tbr, %o0 + + PUBLIC(_SPARC_Set_TBR) + +SYM(_SPARC_Set_TBR): + + retl + wr %o0, 0, %tbr + +#endif /* defined(RTEMS_PARAVIRT) */ + +/* end of file */ diff --git a/cpukit/score/cpu/sparc/syscall.h b/cpukit/score/cpu/sparc/syscall.h new file mode 100644 index 0000000000..2f20886840 --- /dev/null +++ b/cpukit/score/cpu/sparc/syscall.h @@ -0,0 +1 @@ +#define SYS_exit 1 diff --git a/cpukit/score/cpu/sparc/window.S b/cpukit/score/cpu/sparc/window.S new file mode 100644 index 0000000000..5a36fd65be --- /dev/null +++ b/cpukit/score/cpu/sparc/window.S @@ -0,0 +1,259 @@ +/* + * window.s + * + * This file contains the register window management routines for the + * SPARC architecture. Trap handlers for the following capabilities + * are included in this file: + * + * + Window Overflow + * + Window Underflow + * + Flushing All Windows + * + * COPYRIGHT: + * + * This file includes the window overflow and underflow handlers from + * the file srt0.s provided with the binary distribution of the SPARC + * Instruction Simulator (SIS) found at + * ftp://ftp.estec.esa.nl/pub/ws/wsd/erc32. + * + * COPYRIGHT (c) 1995. European Space Agency. + * + * This terms of the RTEMS license apply to this file. + */ + +#include + + .section ".text" + /* + * Window overflow trap handler. + * + * On entry: + * + * prev regwin l1 = pc + * prev regwin l2 = npc + */ + + PUBLIC(window_overflow_trap_handler) + +SYM(window_overflow_trap_handler): + + /* + * Calculate new WIM by "rotating" the valid bits in the WIM right + * by one position. The following shows how the bits move for a SPARC + * cpu implementation where SPARC_NUMBER_OF_REGISTER_WINDOWS is 8. + * + * OLD WIM = 76543210 + * NEW WIM = 07654321 + * + * NOTE: New WIM must be stored in a global register since the + * "save" instruction just prior to the load of the wim + * register will result in the local register set changing. + */ + + std %l0, [%sp + 0x00] ! save local register set + SPARC_LEON3FT_B2BST_NOP + std %l2, [%sp + 0x08] + mov %wim, %l3 + sll %l3, SPARC_NUMBER_OF_REGISTER_WINDOWS-1 , %l2 + ! l2 = WIM << (Number Windows - 1) + std %l4, [%sp + 0x10] + SPARC_LEON3FT_B2BST_NOP + std %l6, [%sp + 0x18] + srl %l3, 1, %l3 ! l3 = WIM >> 1 + wr %l3, %l2, %wim ! WIM = (WIM >> 1) ^ + ! (WIM << (Number Windows - 1)) + ! 3 instruction delay not needed here + std %i0, [%sp + 0x20] ! save input register set + SPARC_LEON3FT_B2BST_NOP + std %i2, [%sp + 0x28] + SPARC_LEON3FT_B2BST_NOP + std %i4, [%sp + 0x30] + SPARC_LEON3FT_B2BST_NOP + std %i6, [%sp + 0x38] + restore ! Go back to trap window. + jmp %l1 ! Re-execute save. + rett %l2 + + /* + * Window underflow trap handler. + * + * On entry: + * + * l1 = pc + * l2 = npc + * l3 = wim (from trap vector) + * l4 = wim << 1 (from trap vector) + */ + + PUBLIC(window_underflow_trap_handler) + +SYM(window_underflow_trap_handler): + + /* + * Calculate new WIM by "rotating" the valid bits in the WIM left + * by one position. The following shows how the bits move for a SPARC + * cpu implementation where SPARC_NUMBER_OF_REGISTER_WINDOWS is 8. + * + * OLD WIM = 76543210 + * NEW WIM = 07654321 + * + * NOTE: New WIM must be stored in a global register since the + * "save" instruction just prior to the load of the wim + * register will result in the local register set changing. + */ + + srl %l3, SPARC_NUMBER_OF_REGISTER_WINDOWS-1, %l5 + or %l5, %l4, %l5 ! l5 = (WIM << 1) | + ! (WIM >> (Number Windows-1)) + mov %l5, %wim ! load the new WIM + nop; nop; nop ! 3 slot delay + restore ! Two restores to get into the + restore ! window to restore + ldd [%sp + 0x00], %l0 ! First the local register set + ldd [%sp + 0x08], %l2 + ldd [%sp + 0x10], %l4 + ldd [%sp + 0x18], %l6 + ldd [%sp + 0x20], %i0 ! Then the input registers + ldd [%sp + 0x28], %i2 + ldd [%sp + 0x30], %i4 + ldd [%sp + 0x38], %i6 + save ! Get back to the trap window. + save + jmp %l1 ! Re-execute restore. + rett %l2 + + /* + * Flush All Windows trap handler. + * + * Flush all windows with valid contents except the current one + * and the one we will be returning to. + * + * In examining the set register windows, one may logically divide + * the windows into sets (some of which may be empty) based on their + * current status: + * + * + current (i.e. in use), + * + used (i.e. a restore would not trap) + * + invalid (i.e. 1 in corresponding bit in WIM) + * + unused + * + * Either the used or unused set of windows may be empty. + * + * NOTE: We assume only one bit is set in the WIM at a time. + * + * Given a CWP of 5 and a WIM of 0x1, the registers are divided + * into sets as follows: + * + * + 0 - invalid + * + 1-4 - unused + * + 5 - current + * + 6-7 - used + * + * In this case, we only would save the used windows which we + * will not be returning to -- 6. + * + * Register Usage while saving the windows: + * g1 = current PSR + * g2 = current wim + * g3 = CWP + * g4 = wim scratch + * g5 = scratch + * + * On entry: + * + * l0 = psr (from trap table) + * l1 = pc + * l2 = npc + */ + + PUBLIC(window_flush_trap_handler) + +SYM(window_flush_trap_handler): + /* + * Save the global registers we will be using + */ + + mov %g1, %l3 + mov %g2, %l4 + mov %g3, %l5 + mov %g4, %l6 + mov %g5, %l7 + + mov %l0, %g1 ! g1 = psr + mov %wim, %g2 ! g2 = wim + and %l0, SPARC_PSR_CWP_MASK, %g3 ! g3 = CWP + + add %g3, 1, %g5 ! g5 = CWP + 1 + and %g5, SPARC_NUMBER_OF_REGISTER_WINDOWS - 1, %g5 + + mov 1, %g4 + sll %g4, %g5, %g4 ! g4 = WIM mask for CWP+1 invalid + + restore ! go back one register window + +save_frame_loop: + sll %g4, 1, %g5 ! rotate the "wim" left 1 + srl %g4, SPARC_NUMBER_OF_REGISTER_WINDOWS - 1, %g4 + or %g4, %g5, %g4 ! g4 = wim if we do one restore + + /* + * If a restore would not underflow, then continue. + */ + + andcc %g4, %g2, %g0 ! Any windows to flush? + bnz done_flushing ! No, then continue + nop + + restore ! back one window + + /* + * Now save the window just as if we overflowed to it. + */ + + std %l0, [%sp + CPU_STACK_FRAME_L0_OFFSET] + SPARC_LEON3FT_B2BST_NOP + std %l2, [%sp + CPU_STACK_FRAME_L2_OFFSET] + SPARC_LEON3FT_B2BST_NOP + std %l4, [%sp + CPU_STACK_FRAME_L4_OFFSET] + SPARC_LEON3FT_B2BST_NOP + std %l6, [%sp + CPU_STACK_FRAME_L6_OFFSET] + SPARC_LEON3FT_B2BST_NOP + + std %i0, [%sp + CPU_STACK_FRAME_I0_OFFSET] + SPARC_LEON3FT_B2BST_NOP + std %i2, [%sp + CPU_STACK_FRAME_I2_OFFSET] + SPARC_LEON3FT_B2BST_NOP + std %i4, [%sp + CPU_STACK_FRAME_I4_OFFSET] + SPARC_LEON3FT_B2BST_NOP + std %i6, [%sp + CPU_STACK_FRAME_I6_FP_OFFSET] + + ba save_frame_loop + nop + +done_flushing: + + add %g3, 2, %g3 ! calculate desired WIM + and %g3, SPARC_NUMBER_OF_REGISTER_WINDOWS - 1, %g3 + mov 1, %g4 + sll %g4, %g3, %g4 ! g4 = new WIM + mov %g4, %wim + + mov %g1, %psr ! restore PSR + nop + nop + nop + + /* + * Restore the global registers we used + */ + + mov %l3, %g1 + mov %l4, %g2 + mov %l5, %g3 + mov %l6, %g4 + mov %l7, %g5 + + jmpl %l2, %g0 + rett %l2 + 4 + +/* end of file */ -- cgit v1.2.3