forked from Imagelibrary/rtems
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.
This commit is contained in:
@@ -64,7 +64,7 @@ void _CPU_Context_Initialize(
|
|||||||
)
|
)
|
||||||
{
|
{
|
||||||
ppc_context *the_ppc_context;
|
ppc_context *the_ppc_context;
|
||||||
uint32_t msr_value;
|
uint32_t msr_value = 0;
|
||||||
uintptr_t sp;
|
uintptr_t sp;
|
||||||
uintptr_t stack_alignment;
|
uintptr_t stack_alignment;
|
||||||
|
|
||||||
@@ -75,10 +75,11 @@ void _CPU_Context_Initialize(
|
|||||||
|
|
||||||
sp = (uintptr_t) memset((void *) sp, 0, PPC_MINIMUM_STACK_FRAME_SIZE);
|
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 );
|
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
|
* Setting the interrupt mask here is not strictly necessary
|
||||||
* since the IRQ level will be established from _Thread_Handler()
|
* since the IRQ level will be established from _Thread_Handler()
|
||||||
@@ -113,7 +114,10 @@ void _CPU_Context_Initialize(
|
|||||||
|
|
||||||
#ifdef PPC_MULTILIB_ALTIVEC
|
#ifdef PPC_MULTILIB_ALTIVEC
|
||||||
msr_value |= MSR_VE;
|
msr_value |= MSR_VE;
|
||||||
|
#endif
|
||||||
|
#endif /* END PPC_DISABLE_MSR_ACCESS */
|
||||||
|
|
||||||
|
#ifdef PPC_MULTILIB_ALTIVEC
|
||||||
the_ppc_context->vrsave = 0;
|
the_ppc_context->vrsave = 0;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|||||||
@@ -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
|
/* 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!
|
* available. Therefore, we must explicitely enable it here!
|
||||||
*/
|
*/
|
||||||
|
#if !defined(PPC_DISABLE_MSR_ACCESS)
|
||||||
mfmsr r4
|
mfmsr r4
|
||||||
andi. r5,r4,MSR_FP
|
andi. r5,r4,MSR_FP
|
||||||
bne 1f
|
bne 1f
|
||||||
ori r5,r4,MSR_FP
|
ori r5,r4,MSR_FP
|
||||||
mtmsr r5
|
mtmsr r5
|
||||||
isync
|
isync
|
||||||
|
#endif /* END PPC_DISABLE_MSR_ACCESS */
|
||||||
|
|
||||||
1:
|
1:
|
||||||
lwz r3, 0(r3)
|
lwz r3, 0(r3)
|
||||||
STF f0, FP_0(r3)
|
STF f0, FP_0(r3)
|
||||||
@@ -170,9 +173,12 @@ PROC (_CPU_Context_save_fp):
|
|||||||
STF f31, FP_31(r3)
|
STF f31, FP_31(r3)
|
||||||
mffs f2
|
mffs f2
|
||||||
STF f2, FP_FPSCR(r3)
|
STF f2, FP_FPSCR(r3)
|
||||||
|
#if !defined(PPC_DISABLE_MSR_ACCESS)
|
||||||
bne 1f
|
bne 1f
|
||||||
mtmsr r4
|
mtmsr r4
|
||||||
isync
|
isync
|
||||||
|
#endif /* END PPC_DISABLE_MSR_ACCESS */
|
||||||
|
|
||||||
1:
|
1:
|
||||||
blr
|
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
|
/* 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!
|
* available. Therefore, we must explicitely enable it here!
|
||||||
*/
|
*/
|
||||||
|
#if !defined(PPC_DISABLE_MSR_ACCESS)
|
||||||
mfmsr r4
|
mfmsr r4
|
||||||
andi. r5,r4,MSR_FP
|
andi. r5,r4,MSR_FP
|
||||||
bne 1f
|
bne 1f
|
||||||
ori r5,r4,MSR_FP
|
ori r5,r4,MSR_FP
|
||||||
mtmsr r5
|
mtmsr r5
|
||||||
isync
|
isync
|
||||||
|
#endif /* END PPC_DISABLE_MSR_ACCESS */
|
||||||
|
|
||||||
1:
|
1:
|
||||||
LDF f2, FP_FPSCR(r3)
|
LDF f2, FP_FPSCR(r3)
|
||||||
mtfsf 255, f2
|
mtfsf 255, f2
|
||||||
@@ -238,8 +247,11 @@ PROC (_CPU_Context_restore_fp):
|
|||||||
LDF f30, FP_30(r3)
|
LDF f30, FP_30(r3)
|
||||||
LDF f31, FP_31(r3)
|
LDF f31, FP_31(r3)
|
||||||
bne 1f
|
bne 1f
|
||||||
|
#if !defined(PPC_DISABLE_MSR_ACCESS)
|
||||||
mtmsr r4
|
mtmsr r4
|
||||||
isync
|
isync
|
||||||
|
#endif /* END PPC_DISABLE_MSR_ACCESS */
|
||||||
|
|
||||||
1:
|
1:
|
||||||
blr
|
blr
|
||||||
#endif /* PPC_HAS_FPU == 1 */
|
#endif /* PPC_HAS_FPU == 1 */
|
||||||
@@ -266,7 +278,9 @@ PROC (_CPU_Context_switch):
|
|||||||
/* Save context to r3 */
|
/* Save context to r3 */
|
||||||
|
|
||||||
GET_SELF_CPU_CONTROL r12
|
GET_SELF_CPU_CONTROL r12
|
||||||
|
#if !defined(PPC_DISABLE_MSR_ACCESS)
|
||||||
mfmsr r6
|
mfmsr r6
|
||||||
|
#endif /* END PPC_DISABLE_MSR_ACCESS */
|
||||||
mfcr r7
|
mfcr r7
|
||||||
mflr r8
|
mflr r8
|
||||||
lwz r11, PER_CPU_ISR_DISPATCH_DISABLE(r12)
|
lwz r11, PER_CPU_ISR_DISPATCH_DISABLE(r12)
|
||||||
@@ -529,7 +543,9 @@ restore_context:
|
|||||||
|
|
||||||
mtlr r8
|
mtlr r8
|
||||||
mtcr r7
|
mtcr r7
|
||||||
|
#if !defined(PPC_DISABLE_MSR_ACCESS)
|
||||||
mtmsr r6
|
mtmsr r6
|
||||||
|
#endif /* END PPC_DISABLE_MSR_ACCESS */
|
||||||
stw r11, PER_CPU_ISR_DISPATCH_DISABLE(r12)
|
stw r11, PER_CPU_ISR_DISPATCH_DISABLE(r12)
|
||||||
|
|
||||||
#ifdef BSP_USE_SYNC_IN_CONTEXT_SWITCH
|
#ifdef BSP_USE_SYNC_IN_CONTEXT_SWITCH
|
||||||
|
|||||||
@@ -17,4 +17,5 @@ include_rtems_score_HEADERS =
|
|||||||
include_rtems_score_HEADERS += include/rtems/score/cpu.h
|
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/cpuatomic.h
|
||||||
include_rtems_score_HEADERS += include/rtems/score/cpuimpl.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
|
include_rtems_score_HEADERS += include/rtems/score/powerpc.h
|
||||||
|
|||||||
@@ -672,6 +672,7 @@ extern "C" {
|
|||||||
*
|
*
|
||||||
* A one bit means that this bit should be cleared.
|
* A one bit means that this bit should be cleared.
|
||||||
*/
|
*/
|
||||||
|
#if !defined(PPC_DISABLE_INLINE_ISR_DISABLE_ENABLE)
|
||||||
extern char _PPC_INTERRUPT_DISABLE_MASK[];
|
extern char _PPC_INTERRUPT_DISABLE_MASK[];
|
||||||
|
|
||||||
static inline uint32_t ppc_interrupt_get_disable_mask( void )
|
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)
|
: "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 ) \
|
#define _CPU_ISR_Disable( _isr_cookie ) \
|
||||||
do { \
|
do { \
|
||||||
|
|||||||
@@ -36,6 +36,9 @@
|
|||||||
#define _RTEMS_SCORE_CPU_H
|
#define _RTEMS_SCORE_CPU_H
|
||||||
|
|
||||||
#include <rtems/score/basedefs.h>
|
#include <rtems/score/basedefs.h>
|
||||||
|
#if defined(RTEMS_PARAVIRT)
|
||||||
|
#include <rtems/score/paravirt.h>
|
||||||
|
#endif
|
||||||
#include <rtems/score/powerpc.h>
|
#include <rtems/score/powerpc.h>
|
||||||
#include <rtems/powerpc/registers.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;
|
return ( level & MSR_EE ) != 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if !defined(PPC_DISABLE_INLINE_ISR_DISABLE_ENABLE)
|
||||||
|
|
||||||
static inline uint32_t _CPU_ISR_Get_level( void )
|
static inline uint32_t _CPU_ISR_Get_level( void )
|
||||||
{
|
{
|
||||||
register unsigned int msr;
|
register unsigned int msr;
|
||||||
@@ -674,6 +679,13 @@ static inline void _CPU_ISR_Set_level( uint32_t level )
|
|||||||
}
|
}
|
||||||
_CPU_MSR_SET(msr);
|
_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 */
|
#endif /* ASM */
|
||||||
|
|
||||||
|
|||||||
74
cpukit/score/cpu/powerpc/include/rtems/score/paravirt.h
Normal file
74
cpukit/score/cpu/powerpc/include/rtems/score/paravirt.h
Normal file
@@ -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
|
||||||
Reference in New Issue
Block a user