[rtems commit] Add PowerPC paravirtualization support

Joel Sherrill joel at rtems.org
Tue Mar 13 15:01:38 UTC 2018


Module:    rtems
Branch:    master
Commit:    0a7a30d19d7d2e3067fc7d7be0d54730b8275f2f
Changeset: http://git.rtems.org/rtems/commit/?id=0a7a30d19d7d2e3067fc7d7be0d54730b8275f2f

Author:    Joel Sherrill <joel at rtems.org>
Date:      Mon Mar 12 14:53:09 2018 -0500

Add PowerPC paravirtualization support

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 +++++
 cpukit/score/cpu/powerpc/headers.am                |  1 +
 .../cpu/powerpc/include/rtems/powerpc/registers.h  |  7 ++
 cpukit/score/cpu/powerpc/include/rtems/score/cpu.h | 12 ++++
 .../cpu/powerpc/include/rtems/score/paravirt.h     | 74 ++++++++++++++++++++++
 6 files changed, 117 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..7c37f0e 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(PPC_DISABLE_MSR_ACCESS)
+  _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 PPC_DISABLE_MSR_ACCESS */
 
+#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..5b095d9 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(PPC_DISABLE_MSR_ACCESS)
 	mfmsr	r4
 	andi.	r5,r4,MSR_FP
 	bne	1f
 	ori	r5,r4,MSR_FP
 	mtmsr	r5
 	isync
+#endif  /* END PPC_DISABLE_MSR_ACCESS */
+
 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(PPC_DISABLE_MSR_ACCESS)
 	bne	1f
 	mtmsr	r4
 	isync
+#endif  /* END PPC_DISABLE_MSR_ACCESS */
+
 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(PPC_DISABLE_MSR_ACCESS)
 	mfmsr	r4
 	andi.	r5,r4,MSR_FP
 	bne	1f
 	ori	r5,r4,MSR_FP
 	mtmsr	r5
 	isync
+#endif  /* END PPC_DISABLE_MSR_ACCESS */
+
 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(PPC_DISABLE_MSR_ACCESS)
 	mtmsr	r4
 	isync
+#endif  /* END PPC_DISABLE_MSR_ACCESS */
+
 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(PPC_DISABLE_MSR_ACCESS)
 	mfmsr	r6
+#endif  /* END PPC_DISABLE_MSR_ACCESS */
 	mfcr	r7
 	mflr	r8
 	lwz	r11, PER_CPU_ISR_DISPATCH_DISABLE(r12)
@@ -529,7 +543,9 @@ restore_context:
 
 	mtlr	r8
 	mtcr	r7
+#if !defined(PPC_DISABLE_MSR_ACCESS)
 	mtmsr	r6
+#endif  /* END PPC_DISABLE_MSR_ACCESS */
 	stw	r11, PER_CPU_ISR_DISPATCH_DISABLE(r12)
 
 #ifdef BSP_USE_SYNC_IN_CONTEXT_SWITCH
diff --git a/cpukit/score/cpu/powerpc/headers.am b/cpukit/score/cpu/powerpc/headers.am
index 5d8037c..df026fa 100644
--- a/cpukit/score/cpu/powerpc/headers.am
+++ b/cpukit/score/cpu/powerpc/headers.am
@@ -17,4 +17,5 @@ include_rtems_score_HEADERS =
 include_rtems_score_HEADERS += include/rtems/score/cpu.h
 include_rtems_score_HEADERS += include/rtems/score/cpuatomic.h
 include_rtems_score_HEADERS += include/rtems/score/cpuimpl.h
+include_rtems_score_HEADERS += include/rtems/score/paravirt.h
 include_rtems_score_HEADERS += include/rtems/score/powerpc.h
diff --git a/cpukit/score/cpu/powerpc/include/rtems/powerpc/registers.h b/cpukit/score/cpu/powerpc/include/rtems/powerpc/registers.h
index 4d93503..b63060d 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(PPC_DISABLE_INLINE_ISR_DISABLE_ENABLE)
 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 /* PPC_DISABLE_INLINE_ISR_DISABLE_ENABLE */
 
 #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 7b6948a..0256069 100644
--- a/cpukit/score/cpu/powerpc/include/rtems/score/cpu.h
+++ b/cpukit/score/cpu/powerpc/include/rtems/score/cpu.h
@@ -36,6 +36,9 @@
 #define _RTEMS_SCORE_CPU_H
 
 #include <rtems/score/basedefs.h>
+#if defined(RTEMS_PARAVIRT)
+#include <rtems/score/paravirt.h>
+#endif
 #include <rtems/score/powerpc.h>
 #include <rtems/powerpc/registers.h>
 
@@ -654,6 +657,8 @@ RTEMS_INLINE_ROUTINE bool _CPU_ISR_Is_enabled( uint32_t level )
   return ( level & MSR_EE ) != 0;
 }
 
+#if !defined(PPC_DISABLE_INLINE_ISR_DISABLE_ENABLE)
+
 static inline uint32_t   _CPU_ISR_Get_level( void )
 {
   register unsigned int msr;
@@ -674,6 +679,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 */
 
diff --git a/cpukit/score/cpu/powerpc/include/rtems/score/paravirt.h b/cpukit/score/cpu/powerpc/include/rtems/score/paravirt.h
new file mode 100644
index 0000000..c9fee7d
--- /dev/null
+++ b/cpukit/score/cpu/powerpc/include/rtems/score/paravirt.h
@@ -0,0 +1,74 @@
+/**
+ * @file
+ *
+ * @brief PowerPC Paravirtualization Definitions
+ *
+ * This include file contains definitions pertaining to paravirtualization
+ * of the PowerPC port.
+ */
+
+/*
+ *  COPYRIGHT (c) 2018.
+ *  On-Line Applications Research Corporation (OAR).
+ *
+ *  The license and distribution terms for this file may in
+ *  the file LICENSE in this distribution or at
+ *  http://www.rtems.org/license/LICENSE.
+ */
+
+
+#ifndef RTEMS_PARAVIRT
+#error "This file should only be included with paravirtualization is enabled."
+#endif
+
+#ifndef _RTEMS_SCORE_PARAVIRT_H
+#define _RTEMS_SCORE_PARAVIRT_H
+
+/**
+ * @defgroup ParavirtPowerPC Paravirtualization PowerPC Support
+ *
+ * @ingroup Score
+ *
+ * This handler encapulates the functionality (primarily conditional
+ * feature defines) related to paravirtualization on the PowerPC.
+ *
+ * Paravirtualization on the PowerPC makes the following assumptions:
+ *
+ *   - RTEMS executes in user space
+ *   - In user space there is no access to the MSR.
+ *   - Interrupt enable/disable support using the MSR must be disabled
+ *     and replaced with BSP provided methods which are adapted to the
+ *     hosting environment.
+ */
+
+#ifndef ASM
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif  /* !ASM */
+
+/**
+ * In a paravirtualized environment, RTEMS executes in user space
+ * and cannot disable/enable external exceptions (e.g. interrupts).
+ * The BSP which acts as an adapter to the hosting environment will
+ * provide the interrupt enable/disable methods.
+ */
+#define PPC_DISABLE_INLINE_ISR_DISABLE_ENABLE
+
+/**
+ * In a paravirtualized environment, RTEMS executes in user space
+ * and cannot access the MSR.
+ *
+ * Try to have as little impact as possible with this define.  Leave
+ * the msr in the thread context because that would impact the definition
+ * of offsets for assembly code.
+ */
+#define PPC_DISABLE_MSR_ACCESS
+
+#endif




More information about the vc mailing list