[PATCH v3 4/5] Add PowerPC paravirtualization support
Joel Sherrill
joel at rtems.org
Fri Feb 16 17:31:28 UTC 2018
From: Jennifer Averett <jennifer.averett at oarcorp.com>
Cannot read or write MSR when executing in user mode. This
is used when RTEMS_PARAVIRT is defined.
Provide alternate methods to disable/enable interrupts
Closes #3306.
---
c/src/lib/libcpu/powerpc/new-exceptions/cpu.c | 10 +++++++---
c/src/lib/libcpu/powerpc/new-exceptions/cpu_asm.S | 16 ++++++++++++++++
.../score/cpu/powerpc/include/rtems/powerpc/registers.h | 7 +++++++
cpukit/score/cpu/powerpc/include/rtems/score/cpu.h | 8 ++++++++
4 files changed, 38 insertions(+), 3 deletions(-)
diff --git a/c/src/lib/libcpu/powerpc/new-exceptions/cpu.c b/c/src/lib/libcpu/powerpc/new-exceptions/cpu.c
index ae5065d..3bc44e1 100644
--- a/c/src/lib/libcpu/powerpc/new-exceptions/cpu.c
+++ b/c/src/lib/libcpu/powerpc/new-exceptions/cpu.c
@@ -64,7 +64,7 @@ void _CPU_Context_Initialize(
)
{
ppc_context *the_ppc_context;
- uint32_t msr_value;
+ uint32_t msr_value = 0;
uintptr_t sp;
uintptr_t stack_alignment;
@@ -75,10 +75,11 @@ void _CPU_Context_Initialize(
sp = (uintptr_t) memset((void *) sp, 0, PPC_MINIMUM_STACK_FRAME_SIZE);
- _CPU_MSR_GET( msr_value );
-
the_ppc_context = ppc_get_context( the_context );
+#if !defined(RTEMS_PARAVIRT)
+ _CPU_MSR_GET( msr_value );
+
/*
* Setting the interrupt mask here is not strictly necessary
* since the IRQ level will be established from _Thread_Handler()
@@ -113,7 +114,10 @@ void _CPU_Context_Initialize(
#ifdef PPC_MULTILIB_ALTIVEC
msr_value |= MSR_VE;
+#endif
+#endif /* END RTEMS_PARAVIRT */
+#ifdef PPC_MULTILIB_ALTIVEC
the_ppc_context->vrsave = 0;
#endif
diff --git a/c/src/lib/libcpu/powerpc/new-exceptions/cpu_asm.S b/c/src/lib/libcpu/powerpc/new-exceptions/cpu_asm.S
index cdbf403..359022b 100644
--- a/c/src/lib/libcpu/powerpc/new-exceptions/cpu_asm.S
+++ b/c/src/lib/libcpu/powerpc/new-exceptions/cpu_asm.S
@@ -128,12 +128,15 @@ PROC (_CPU_Context_save_fp):
/* A FP context switch may occur in an ISR or exception handler when the FPU is not
* available. Therefore, we must explicitely enable it here!
*/
+#if !defined(RTEMS_PARAVIRT)
mfmsr r4
andi. r5,r4,MSR_FP
bne 1f
ori r5,r4,MSR_FP
mtmsr r5
isync
+#endif /* END RTEMS_PARAVIRT */
+
1:
lwz r3, 0(r3)
STF f0, FP_0(r3)
@@ -170,9 +173,12 @@ PROC (_CPU_Context_save_fp):
STF f31, FP_31(r3)
mffs f2
STF f2, FP_FPSCR(r3)
+#if !defined(RTEMS_PARAVIRT)
bne 1f
mtmsr r4
isync
+#endif /* END RTEMS_PARAVIRT */
+
1:
blr
@@ -196,12 +202,15 @@ PROC (_CPU_Context_restore_fp):
/* A FP context switch may occur in an ISR or exception handler when the FPU is not
* available. Therefore, we must explicitely enable it here!
*/
+#if !defined(RTEMS_PARAVIRT)
mfmsr r4
andi. r5,r4,MSR_FP
bne 1f
ori r5,r4,MSR_FP
mtmsr r5
isync
+#endif /* END RTEMS_PARAVIRT */
+
1:
LDF f2, FP_FPSCR(r3)
mtfsf 255, f2
@@ -238,8 +247,11 @@ PROC (_CPU_Context_restore_fp):
LDF f30, FP_30(r3)
LDF f31, FP_31(r3)
bne 1f
+#if !defined(RTEMS_PARAVIRT)
mtmsr r4
isync
+#endif /* END RTEMS_PARAVIRT */
+
1:
blr
#endif /* PPC_HAS_FPU == 1 */
@@ -266,7 +278,9 @@ PROC (_CPU_Context_switch):
/* Save context to r3 */
GET_SELF_CPU_CONTROL r12
+#if !defined(RTEMS_PARAVIRT)
mfmsr r6
+#endif
mfcr r7
mflr r8
lwz r11, PER_CPU_ISR_DISPATCH_DISABLE(r12)
@@ -529,7 +543,9 @@ restore_context:
mtlr r8
mtcr r7
+#if !defined(RTEMS_PARAVIRT)
mtmsr r6
+#endif
stw r11, PER_CPU_ISR_DISPATCH_DISABLE(r12)
#ifdef BSP_USE_SYNC_IN_CONTEXT_SWITCH
diff --git a/cpukit/score/cpu/powerpc/include/rtems/powerpc/registers.h b/cpukit/score/cpu/powerpc/include/rtems/powerpc/registers.h
index 4d93503..016c84f 100644
--- a/cpukit/score/cpu/powerpc/include/rtems/powerpc/registers.h
+++ b/cpukit/score/cpu/powerpc/include/rtems/powerpc/registers.h
@@ -672,6 +672,7 @@ extern "C" {
*
* A one bit means that this bit should be cleared.
*/
+#if !defined(RTEMS_PARAVIRT)
extern char _PPC_INTERRUPT_DISABLE_MASK[];
static inline uint32_t ppc_interrupt_get_disable_mask( void )
@@ -734,6 +735,12 @@ static inline void ppc_interrupt_flash( uint32_t level )
: "r" (level)
);
}
+#else
+uint32_t ppc_interrupt_get_disable_mask( void );
+uint32_t ppc_interrupt_disable( void );
+void ppc_interrupt_enable( uint32_t level );
+void ppc_interrupt_flash( uint32_t level );
+#endif /* RTEMS_PARAVIRT */
#define _CPU_ISR_Disable( _isr_cookie ) \
do { \
diff --git a/cpukit/score/cpu/powerpc/include/rtems/score/cpu.h b/cpukit/score/cpu/powerpc/include/rtems/score/cpu.h
index 8c0f200..a3a5dad 100644
--- a/cpukit/score/cpu/powerpc/include/rtems/score/cpu.h
+++ b/cpukit/score/cpu/powerpc/include/rtems/score/cpu.h
@@ -654,6 +654,7 @@ RTEMS_INLINE_ROUTINE bool _CPU_ISR_Is_enabled( uint32_t level )
return ( level & MSR_EE ) != 0;
}
+#if !defined(RTEMS_PARAVIRT)
static inline uint32_t _CPU_ISR_Get_level( void )
{
register unsigned int msr;
@@ -674,6 +675,13 @@ static inline void _CPU_ISR_Set_level( uint32_t level )
}
_CPU_MSR_SET(msr);
}
+#else
+/* disable, enable, etc. are in registers.h */
+uint32_t ppc_get_interrupt_level( void );
+void ppc_set_interrupt_level( uint32_t level );
+#define _CPU_ISR_Get_level( _new_level ) ppc_get_interrupt_level()
+#define _CPU_ISR_Set_level( _new_level ) ppc_set_interrupt_level(_new_level)
+#endif
#endif /* ASM */
--
1.8.3.1
More information about the devel
mailing list