summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorChristian Mauderer <Christian.Mauderer@embedded-brains.de>2014-06-02 16:31:51 +0200
committerSebastian Huber <sebastian.huber@embedded-brains.de>2014-06-03 08:35:47 +0200
commit8df1f408fd8c4f67629f32470b5b7d94123bc305 (patch)
treec64a21cd0f587bae7926c2ff4d7349df026249e3
parent98f2d5c505acaf92cdf03c83361b22de0e7c39a9 (diff)
downloadrtems-8df1f408fd8c4f67629f32470b5b7d94123bc305.tar.bz2
score/sparc: Add support for paravirtualization
Guest systems in paravirtualization environments run usually in user mode. Thus it is not possible to directly access the PSR and TBR registers. Use functions instead of inline assembler to access these registers if RTEMS_PARAVIRT is defined.
-rw-r--r--c/src/lib/libbsp/sparc/erc32/Makefile.am1
-rw-r--r--c/src/lib/libbsp/sparc/leon2/Makefile.am1
-rw-r--r--c/src/lib/libbsp/sparc/leon3/Makefile.am1
-rw-r--r--c/src/lib/libbsp/sparc/leon3/startup/bspsmp.c2
-rw-r--r--c/src/lib/libbsp/sparc/shared/cpu.c36
-rw-r--r--c/src/lib/libcpu/sparc/syscall/syscall.S36
-rw-r--r--cpukit/score/cpu/sparc/cpu.c17
-rw-r--r--cpukit/score/cpu/sparc/rtems/score/cpu.h2
-rw-r--r--cpukit/score/cpu/sparc/rtems/score/sparc.h44
9 files changed, 121 insertions, 19 deletions
diff --git a/c/src/lib/libbsp/sparc/erc32/Makefile.am b/c/src/lib/libbsp/sparc/erc32/Makefile.am
index abf8eca618..d5de3776fa 100644
--- a/c/src/lib/libbsp/sparc/erc32/Makefile.am
+++ b/c/src/lib/libbsp/sparc/erc32/Makefile.am
@@ -46,6 +46,7 @@ libbsp_a_SOURCES += startup/bspidle.c
libbsp_a_SOURCES += startup/bspdelay.c
libbsp_a_SOURCES += ../../sparc/shared/startup/early_malloc.c
# ISR Handler
+libbsp_a_SOURCES += ../../sparc/shared/cpu.c
libbsp_a_SOURCES += ../../sparc/shared/irq_asm.S
# gnatsupp
libbsp_a_SOURCES += gnatsupp/gnatsupp.c ../../sparc/shared/gnatcommon.c
diff --git a/c/src/lib/libbsp/sparc/leon2/Makefile.am b/c/src/lib/libbsp/sparc/leon2/Makefile.am
index f913462a41..e808b33723 100644
--- a/c/src/lib/libbsp/sparc/leon2/Makefile.am
+++ b/c/src/lib/libbsp/sparc/leon2/Makefile.am
@@ -62,6 +62,7 @@ libbsp_a_SOURCES += startup/bspdelay.c
libbsp_a_SOURCES += ../../sparc/shared/startup/early_malloc.c
# ISR Handler
+libbsp_a_SOURCES += ../../sparc/shared/cpu.c
libbsp_a_SOURCES += ../../sparc/shared/irq_asm.S
# gnatsupp
libbsp_a_SOURCES += gnatsupp/gnatsupp.c ../../sparc/shared/gnatcommon.c
diff --git a/c/src/lib/libbsp/sparc/leon3/Makefile.am b/c/src/lib/libbsp/sparc/leon3/Makefile.am
index 789c3d09fc..5dd43c3be9 100644
--- a/c/src/lib/libbsp/sparc/leon3/Makefile.am
+++ b/c/src/lib/libbsp/sparc/leon3/Makefile.am
@@ -43,6 +43,7 @@ libbsp_a_SOURCES += startup/bspreset.c
libbsp_a_SOURCES += startup/cpucounter.c
# ISR Handler
+libbsp_a_SOURCES += ../../sparc/shared/cpu.c
libbsp_a_SOURCES += ../../sparc/shared/irq_asm.S
# gnatsupp
libbsp_a_SOURCES += gnatsupp/gnatsupp.c ../../sparc/shared/gnatcommon.c
diff --git a/c/src/lib/libbsp/sparc/leon3/startup/bspsmp.c b/c/src/lib/libbsp/sparc/leon3/startup/bspsmp.c
index 6eec341f93..567eecc819 100644
--- a/c/src/lib/libbsp/sparc/leon3/startup/bspsmp.c
+++ b/c/src/lib/libbsp/sparc/leon3/startup/bspsmp.c
@@ -20,7 +20,7 @@
#include <rtems/score/smpimpl.h>
#include <stdlib.h>
-#if !defined(__leon__)
+#if !defined(__leon__) || defined(RTEMS_PARAVIRT)
uint32_t _CPU_SMP_Get_current_processor( void )
{
return _LEON3_Get_current_processor();
diff --git a/c/src/lib/libbsp/sparc/shared/cpu.c b/c/src/lib/libbsp/sparc/shared/cpu.c
new file mode 100644
index 0000000000..12d347547b
--- /dev/null
+++ b/c/src/lib/libbsp/sparc/shared/cpu.c
@@ -0,0 +1,36 @@
+/**
+ * @file
+ *
+ * @brief SPARC CPU Dependent Source
+ */
+
+/*
+ * COPYRIGHT (c) 1989-2007.
+ * On-Line Applications Research Corporation (OAR).
+ *
+ * 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 <rtems/score/cpu.h>
+
+/*
+ * This initializes the set of opcodes placed in each trap
+ * table entry. The routine which installs a handler is responsible
+ * for filling in the fields for the _handler address and the _vector
+ * trap type.
+ *
+ * The constants following this structure are masks for the fields which
+ * must be filled in when the handler is installed.
+ *
+ * This table is defined here to allow BSP specific versions, e.g. for guest
+ * systems under paravirtualization.
+ */
+
+const CPU_Trap_table_entry _CPU_Trap_slot_template = {
+ 0xa1480000, /* mov %psr, %l0 */
+ 0x29000000, /* sethi %hi(_handler), %l4 */
+ 0x81c52000, /* jmp %l4 + %lo(_handler) */
+ 0xa6102000 /* mov _vector, %l3 */
+};
diff --git a/c/src/lib/libcpu/sparc/syscall/syscall.S b/c/src/lib/libcpu/sparc/syscall/syscall.S
index a36ffaf220..9ce7fa54ef 100644
--- a/c/src/lib/libcpu/sparc/syscall/syscall.S
+++ b/c/src/lib/libcpu/sparc/syscall/syscall.S
@@ -83,4 +83,40 @@ SYM(sparc_syscall_exit):
mov %o1, %g3 ! Additional exit code 2
ta 0
+#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/cpu.c b/cpukit/score/cpu/sparc/cpu.c
index ee0d622067..c616de4971 100644
--- a/cpukit/score/cpu/sparc/cpu.c
+++ b/cpukit/score/cpu/sparc/cpu.c
@@ -72,23 +72,6 @@ SPARC_ASSERT_OFFSET(is_executing, SPARC_CONTEXT_CONTROL_IS_EXECUTING);
#endif
/*
- * This initializes the set of opcodes placed in each trap
- * table entry. The routine which installs a handler is responsible
- * for filling in the fields for the _handler address and the _vector
- * trap type.
- *
- * The constants following this structure are masks for the fields which
- * must be filled in when the handler is installed.
- */
-
-const CPU_Trap_table_entry _CPU_Trap_slot_template = {
- 0xa1480000, /* mov %psr, %l0 */
- 0x29000000, /* sethi %hi(_handler), %l4 */
- 0x81c52000, /* jmp %l4 + %lo(_handler) */
- 0xa6102000 /* mov _vector, %l3 */
-};
-
-/*
* _CPU_Initialize
*
* This routine performs processor dependent initialization.
diff --git a/cpukit/score/cpu/sparc/rtems/score/cpu.h b/cpukit/score/cpu/sparc/rtems/score/cpu.h
index 532d8824fc..c01000584f 100644
--- a/cpukit/score/cpu/sparc/rtems/score/cpu.h
+++ b/cpukit/score/cpu/sparc/rtems/score/cpu.h
@@ -1192,7 +1192,7 @@ register struct Per_CPU_Control *_SPARC_Per_CPU_current __asm__( "g6" );
void _CPU_SMP_Finalize_initialization( uint32_t cpu_count );
- #if defined(__leon__)
+ #if defined(__leon__) && !defined(RTEMS_PARAVIRT)
static inline uint32_t _CPU_SMP_Get_current_processor( void )
{
return _LEON3_Get_current_processor();
diff --git a/cpukit/score/cpu/sparc/rtems/score/sparc.h b/cpukit/score/cpu/sparc/rtems/score/sparc.h
index 75f6d96e74..abd0f8b987 100644
--- a/cpukit/score/cpu/sparc/rtems/score/sparc.h
+++ b/cpukit/score/cpu/sparc/rtems/score/sparc.h
@@ -164,17 +164,37 @@ extern "C" {
*
* This macro returns the current contents of the PSR register in @a _psr.
*/
+#if defined(RTEMS_PARAVIRT)
+
+uint32_t _SPARC_Get_PSR( void );
+
+#define sparc_get_psr( _psr ) \
+ (_psr) = _SPARC_Get_PSR()
+
+#else /* RTEMS_PARAVIRT */
+
#define sparc_get_psr( _psr ) \
do { \
(_psr) = 0; \
__asm__ volatile( "rd %%psr, %0" : "=r" (_psr) : "0" (_psr) ); \
} while ( 0 )
+#endif /* RTEMS_PARAVIRT */
+
/**
* @brief Macro to set the PSR.
*
* This macro sets the PSR register to the value in @a _psr.
*/
+#if defined(RTEMS_PARAVIRT)
+
+void _SPARC_Set_PSR( uint32_t new_psr );
+
+#define sparc_set_psr( _psr ) \
+ _SPARC_Set_PSR( _psr )
+
+#else /* RTEMS_PARAVIRT */
+
#define sparc_set_psr( _psr ) \
do { \
__asm__ volatile ( "mov %0, %%psr " : "=r" ((_psr)) : "0" ((_psr)) ); \
@@ -183,27 +203,51 @@ extern "C" {
nop(); \
} while ( 0 )
+#endif /* RTEMS_PARAVIRT */
+
/**
* @brief Macro to obtain the TBR.
*
* This macro returns the current contents of the TBR register in @a _tbr.
*/
+#if defined(RTEMS_PARAVIRT)
+
+uint32_t _SPARC_Get_TBR( void );
+
+#define sparc_get_tbr( _tbr ) \
+ (_tbr) = _SPARC_Get_TBR()
+
+#else /* RTEMS_PARAVIRT */
+
#define sparc_get_tbr( _tbr ) \
do { \
(_tbr) = 0; /* to avoid unitialized warnings */ \
__asm__ volatile( "rd %%tbr, %0" : "=r" (_tbr) : "0" (_tbr) ); \
} while ( 0 )
+#endif /* RTEMS_PARAVIRT */
+
/**
* @brief Macro to set the TBR.
*
* This macro sets the TBR register to the value in @a _tbr.
*/
+#if defined(RTEMS_PARAVIRT)
+
+void _SPARC_Set_TBR( uint32_t new_tbr );
+
+#define sparc_set_tbr( _tbr ) \
+ _SPARC_Set_TBR((_tbr))
+
+#else /* RTEMS_PARAVIRT */
+
#define sparc_set_tbr( _tbr ) \
do { \
__asm__ volatile( "wr %0, 0, %%tbr" : "=r" (_tbr) : "0" (_tbr) ); \
} while ( 0 )
+#endif /* RTEMS_PARAVIRT */
+
/**
* @brief Macro to obtain the WIM.
*