summaryrefslogtreecommitdiff
path: root/c/src/lib/libcpu
diff options
context:
space:
mode:
Diffstat (limited to 'c/src/lib/libcpu')
-rw-r--r--c/src/lib/libcpu/sparc/Makefile.am7
-rw-r--r--c/src/lib/libcpu/sparc/access/access.S65
-rw-r--r--c/src/lib/libcpu/sparc/access/access_le.c32
-rw-r--r--c/src/lib/libcpu/sparc/include/libcpu/access.h48
-rw-r--r--c/src/lib/libcpu/sparc/include/libcpu/byteorder.h66
-rw-r--r--c/src/lib/libcpu/sparc/preinstall.am8
-rw-r--r--c/src/lib/libcpu/sparc/reg_win/window.S35
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: