diff options
Diffstat (limited to 'c/src/lib/libcpu')
-rw-r--r-- | c/src/lib/libcpu/sparc/Makefile.am | 7 | ||||
-rw-r--r-- | c/src/lib/libcpu/sparc/access/access.S | 65 | ||||
-rw-r--r-- | c/src/lib/libcpu/sparc/access/access_le.c | 32 | ||||
-rw-r--r-- | c/src/lib/libcpu/sparc/include/libcpu/access.h | 48 | ||||
-rw-r--r-- | c/src/lib/libcpu/sparc/include/libcpu/byteorder.h | 66 | ||||
-rw-r--r-- | c/src/lib/libcpu/sparc/preinstall.am | 8 | ||||
-rw-r--r-- | c/src/lib/libcpu/sparc/reg_win/window.S | 35 |
7 files changed, 241 insertions, 20 deletions
diff --git a/c/src/lib/libcpu/sparc/Makefile.am b/c/src/lib/libcpu/sparc/Makefile.am index 7bebd9417e..711d6b1fa8 100644 --- a/c/src/lib/libcpu/sparc/Makefile.am +++ b/c/src/lib/libcpu/sparc/Makefile.am @@ -10,6 +10,8 @@ noinst_PROGRAMS = include_libcpudir = $(includedir)/libcpu include_libcpu_HEADERS = ../shared/include/cache.h +include_libcpu_HEADERS += include/libcpu/byteorder.h +include_libcpu_HEADERS += include/libcpu/access.h noinst_PROGRAMS += cache.rel cache_rel_SOURCES = cache/cache.c cache/cache_.h \ @@ -31,5 +33,10 @@ 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 $(srcdir)/preinstall.am 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 new file mode 100644 index 0000000000..7e69f64c9d --- /dev/null +++ b/c/src/lib/libcpu/sparc/access/access.S @@ -0,0 +1,65 @@ +/* + * 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.com/license/LICENSE. + */ + +#include <rtems/asm.h> + + .align 4 + .seg "text" + PUBLIC(_ld8) + PUBLIC(_ld16) + PUBLIC(_ld32) + PUBLIC(_ld64) + PUBLIC(_st8) + PUBLIC(_st16) + PUBLIC(_st32) + PUBLIC(_st64) + PUBLIC(_ld_be16) + PUBLIC(_ld_be32) + PUBLIC(_st_be16) + PUBLIC(_st_be32) + +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 + +SYM(_st8): + retl + stub %o1, [%o0] + +SYM(_st_be16): +SYM(_st16): + retl + stuh %o1, [%o0] + +SYM(_st_be32): +SYM(_st32): + retl + st %o1, [%o0] + +SYM(_st_be64): +SYM(_st64): + retl + std %o1, [%o0] diff --git a/c/src/lib/libcpu/sparc/access/access_le.c b/c/src/lib/libcpu/sparc/access/access_le.c new file mode 100644 index 0000000000..15031ccf50 --- /dev/null +++ b/c/src/lib/libcpu/sparc/access/access_le.c @@ -0,0 +1,32 @@ +/* + * 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.com/license/LICENSE. + */ + +#include <libcpu/byteorder.h> + +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/include/libcpu/access.h b/c/src/lib/libcpu/sparc/include/libcpu/access.h new file mode 100644 index 0000000000..2d87c2ad48 --- /dev/null +++ b/c/src/lib/libcpu/sparc/include/libcpu/access.h @@ -0,0 +1,48 @@ +/* + * 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.com/license/LICENSE. + */ + +#ifndef _LIBCPU_ACCESS_H +#define _LIBCPU_ACCESS_H + +#include <rtems/system.h> +#include <rtems/score/cpu.h> + +#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); + +/* 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/libcpu/sparc/include/libcpu/byteorder.h b/c/src/lib/libcpu/sparc/include/libcpu/byteorder.h new file mode 100644 index 0000000000..d626f28068 --- /dev/null +++ b/c/src/lib/libcpu/sparc/include/libcpu/byteorder.h @@ -0,0 +1,66 @@ +/* + * byteorder.h - Endian conversion 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.com/license/LICENSE. + */ + +#ifndef _LIBCPU_BYTEORDER_H +#define _LIBCPU_BYTEORDER_H + +#include <rtems/system.h> +#include <rtems/score/cpu.h> + +#ifdef __cplusplus +extern "C" { +#endif + +RTEMS_INLINE_ROUTINE uint16_t ld_le16(volatile uint16_t *addr) +{ + return CPU_swap_u16(*addr); +} + +RTEMS_INLINE_ROUTINE void st_le16(volatile uint16_t *addr, uint16_t val) +{ + *addr = CPU_swap_u16(val); +} + +RTEMS_INLINE_ROUTINE uint32_t ld_le32(volatile uint32_t *addr) +{ + return CPU_swap_u32(*addr); +} + +RTEMS_INLINE_ROUTINE void st_le32(volatile uint32_t *addr, uint32_t val) +{ + *addr = CPU_swap_u32(val); +} + +RTEMS_INLINE_ROUTINE uint16_t ld_be16(volatile uint16_t *addr) +{ + return *addr; +} + +RTEMS_INLINE_ROUTINE void st_be16(volatile uint16_t *addr, uint16_t val) +{ + *addr = val; +} + +RTEMS_INLINE_ROUTINE uint32_t ld_be32(volatile uint32_t *addr) +{ + return *addr; +} + +RTEMS_INLINE_ROUTINE void st_be32(volatile uint32_t *addr, uint32_t val) +{ + *addr = val; +} + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/c/src/lib/libcpu/sparc/preinstall.am b/c/src/lib/libcpu/sparc/preinstall.am index 412b683681..2efe38bb30 100644 --- a/c/src/lib/libcpu/sparc/preinstall.am +++ b/c/src/lib/libcpu/sparc/preinstall.am @@ -22,3 +22,11 @@ $(PROJECT_INCLUDE)/libcpu/cache.h: ../shared/include/cache.h $(PROJECT_INCLUDE)/ $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/libcpu/cache.h PREINSTALL_FILES += $(PROJECT_INCLUDE)/libcpu/cache.h +$(PROJECT_INCLUDE)/libcpu/byteorder.h: include/libcpu/byteorder.h $(PROJECT_INCLUDE)/libcpu/$(dirstamp) + $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/libcpu/byteorder.h +PREINSTALL_FILES += $(PROJECT_INCLUDE)/libcpu/byteorder.h + +$(PROJECT_INCLUDE)/libcpu/access.h: include/libcpu/access.h $(PROJECT_INCLUDE)/libcpu/$(dirstamp) + $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/libcpu/access.h +PREINSTALL_FILES += $(PROJECT_INCLUDE)/libcpu/access.h + diff --git a/c/src/lib/libcpu/sparc/reg_win/window.S b/c/src/lib/libcpu/sparc/reg_win/window.S index e28774d74e..3ec3f50a10 100644 --- a/c/src/lib/libcpu/sparc/reg_win/window.S +++ b/c/src/lib/libcpu/sparc/reg_win/window.S @@ -130,8 +130,7 @@ SYM(window_underflow_trap_handler): /* * Flush All Windows trap handler. * - * Flush all windows with valid contents except the current one - * and the one we will be returning to. + * Flush all windows with valid contents except the current one. * * In examining the set register windows, one may logically divide * the windows into sets (some of which may be empty) based on their @@ -154,8 +153,8 @@ SYM(window_underflow_trap_handler): * + 5 - current * + 6-7 - used * - * In this case, we only would save the used windows which we - * will not be returning to -- 6. + * In this case, we only would save the used windows 6 and 7, but + * not 5. * * Register Usage while saving the windows: * g1 = current PSR @@ -194,22 +193,9 @@ SYM(window_flush_trap_handler): 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 + restore ! go back one register window /* * Now save the window just as if we overflowed to it. @@ -225,8 +211,17 @@ save_frame_loop: std %i4, [%sp + CPU_STACK_FRAME_I4_OFFSET] std %i6, [%sp + CPU_STACK_FRAME_I6_FP_OFFSET] - ba save_frame_loop - nop + 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? + be save_frame_loop ! Yes, then continue saving + nop done_flushing: |