[PATCH 1/2] cpu part of the virtualization layer for i386
Gedare Bloom
gedare at rtems.org
Tue Dec 3 16:41:46 UTC 2013
On Wed, Nov 27, 2013 at 5:55 PM, Philipp Eppelt
<philipp.eppelt at mailbox.tu-dresden.de> wrote:
> ---
> cpukit/score/cpu/i386/Makefile.am | 1 +
> cpukit/score/cpu/i386/cpu.c | 20 +++++
> cpukit/score/cpu/i386/preinstall.am | 4 +
> cpukit/score/cpu/i386/rtems/score/cpu.h | 50 ++++++++++---
> cpukit/score/cpu/i386/rtems/score/interrupts.h | 31 ++++++++
> .../cpu/i386/rtems/score/virtualizationlayercpu.h | 85 ++++++++++++++++++++++
> 6 files changed, 179 insertions(+), 12 deletions(-)
> create mode 100644 cpukit/score/cpu/i386/rtems/score/virtualizationlayercpu.h
>
> diff --git a/cpukit/score/cpu/i386/Makefile.am b/cpukit/score/cpu/i386/Makefile.am
> index e35a81c..8f196c5 100644
> --- a/cpukit/score/cpu/i386/Makefile.am
> +++ b/cpukit/score/cpu/i386/Makefile.am
> @@ -12,6 +12,7 @@ include_rtems_score_HEADERS += rtems/score/registers.h
> include_rtems_score_HEADERS += rtems/score/idtr.h
> include_rtems_score_HEADERS += rtems/score/cpuatomic.h
> include_rtems_score_HEADERS += rtems/score/cpusmplock.h
> +include_rtems_score_HEADERS += rtems/score/virtualizationlayercpu.h
>
> noinst_LIBRARIES = libscorecpu.a
> libscorecpu_a_SOURCES = cpu.c cpu_asm.S
> diff --git a/cpukit/score/cpu/i386/cpu.c b/cpukit/score/cpu/i386/cpu.c
> index c87a76d..4dd44bb 100644
> --- a/cpukit/score/cpu/i386/cpu.c
> +++ b/cpukit/score/cpu/i386/cpu.c
> @@ -26,6 +26,10 @@
> #include <rtems/bspIo.h>
> #include <rtems/score/thread.h>
>
> +#if defined(RTEMS_PARAVIRT)
> +#include <rtems/score/virtualizationlayercpu.h>
> +#endif
> +
> void _CPU_Initialize(void)
> {
> #if CPU_HARDWARE_FP
> @@ -97,6 +101,20 @@ uint32_t _CPU_ISR_Get_level( void )
> return level;
> }
>
> +
> +#if defined(RTEMS_PARAVIRT)
> +
> +void *_CPU_Thread_Idle_body( uintptr_t ignored )
> +{
> + while(1)
> + {
> + _CPU_Virtual_idle_thread();
> + }
> + return NULL;
> +}
> +
> +#else
> +
> void *_CPU_Thread_Idle_body( uintptr_t ignored )
> {
> while(1){
> @@ -105,6 +123,8 @@ void *_CPU_Thread_Idle_body( uintptr_t ignored )
> return NULL;
> }
>
> +#endif /*RTEMS_PARAVIRT*/
> +
> struct Frame_ {
> struct Frame_ *up;
> uintptr_t pc;
> diff --git a/cpukit/score/cpu/i386/preinstall.am b/cpukit/score/cpu/i386/preinstall.am
> index f9faf87..363e1fb 100644
> --- a/cpukit/score/cpu/i386/preinstall.am
> +++ b/cpukit/score/cpu/i386/preinstall.am
> @@ -59,3 +59,7 @@ $(PROJECT_INCLUDE)/rtems/score/cpusmplock.h: rtems/score/cpusmplock.h $(PROJECT_
> $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/rtems/score/cpusmplock.h
> PREINSTALL_FILES += $(PROJECT_INCLUDE)/rtems/score/cpusmplock.h
>
> +$(PROJECT_INCLUDE)/rtems/score/virtualizationlayercpu.h: rtems/score/virtualizationlayercpu.h $(PROJECT_INCLUDE)/rtems/score/$(dirstamp)
> + $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/rtems/score/virtualizationlayercpu.h
> +PREINSTALL_FILES += $(PROJECT_INCLUDE)/rtems/score/virtualizationlayercpu.h
> +
> diff --git a/cpukit/score/cpu/i386/rtems/score/cpu.h b/cpukit/score/cpu/i386/rtems/score/cpu.h
> index 43422ed..4e509b7 100644
> --- a/cpukit/score/cpu/i386/rtems/score/cpu.h
> +++ b/cpukit/score/cpu/i386/rtems/score/cpu.h
> @@ -35,6 +35,10 @@ extern "C" {
> #include <rtems/score/registers.h> /* formerly part of libcpu */
> #endif
>
> +#if defined(RTEMS_PARAVIRT)
> +#include <rtems/score/virtualizationlayercpu.h>
> +#endif
> +
> /* conditional compilation parameters */
>
> #define CPU_INLINE_ENABLE_DISPATCH TRUE
> @@ -376,11 +380,22 @@ SCORE_EXTERN Context_Control_fp _CPU_Null_fp_context;
>
> #define _CPU_ISR_Flash( _level ) i386_flash_interrupts( _level )
>
> -#define _CPU_ISR_Set_level( _new_level ) \
> - { \
> - if ( _new_level ) __asm__ volatile ( "cli" ); \
> - else __asm__ volatile ( "sti" ); \
> - }
> +#if defined(RTEMS_PARAVIRT)
> + #define _CPU_ISR_Set_level( _new_level ) \
> + { \
> + if( _new_level ) _CPU_Virtual_Interrupts_close(); \
> + else _CPU_Virtual_Interrupts_open(); \
> + }
> +
> +#else
> +
> + #define _CPU_ISR_Set_level( _new_level ) \
> + { \
> + if ( _new_level ) __asm__ volatile ( "cli" ); \
> + else __asm__ volatile ( "sti" ); \
> + }
> +
> +#endif /*RTEMS_PARAVIRT*/
>
> uint32_t _CPU_ISR_Get_level( void );
>
> @@ -497,16 +512,27 @@ uint32_t _CPU_ISR_Get_level( void );
> * + disable interrupts and halt the CPU
> */
>
> -#define _CPU_Fatal_halt( _error ) \
> +#if defined(RTEMS_PARAVIRT)
> + #define _CPU_Fatal_halt( _error ) \
> { \
> - uint32_t _error_lvalue = ( _error ); \
> - __asm__ volatile ( "cli ; \
> - movl %0,%%eax ; \
> - hlt" \
> - : "=r" ((_error_lvalue)) : "0" ((_error_lvalue)) \
> - ); \
> + _CPU_Virtual_Interrupts_close(); \
> + _CPU_Virtual_exec_stop_error( _error ); \
> }
Why doesn't "_CPU_Virtual_exec_stop_error() follow the naming/style convention?
>
> +#else
> +
> + #define _CPU_Fatal_halt( _error ) \
> + { \
> + uint32_t _error_lvalue = ( _error ); \
> + __asm__ volatile ( "cli ; \
> + movl %0,%%eax ; \
> + hlt" \
> + : "=r" ((_error_lvalue)) : "0" ((_error_lvalue)) \
> + ); \
> + }
> +
> +#endif /*RTEMS_PARAVIRT*/
> +
> #endif /* ASM */
>
> /* end of Fatal Error manager macros */
> diff --git a/cpukit/score/cpu/i386/rtems/score/interrupts.h b/cpukit/score/cpu/i386/rtems/score/interrupts.h
> index bed6330..8d47ea5 100644
> --- a/cpukit/score/cpu/i386/rtems/score/interrupts.h
> +++ b/cpukit/score/cpu/i386/rtems/score/interrupts.h
> @@ -33,6 +33,36 @@ typedef int (*rtems_raw_irq_is_enabled) (const struct __rtems_raw_irq_connect_d
> *
> */
> /**@{**/
> +#if defined(RTEMS_PARAVIRT)
> + #include <rtems/score/virtualizationlayercpu.h>
> +
> +#define i386_disable_interrupts( _level ) \
> + { \
> + _CPU_Virtual_Interrupts_disable( _level ); \
> + }
> +
> +#define i386_enable_interrupts( _level ) \
> + { \
> + _CPU_Virtual_Interrupts_enable( _level ); \
> + }
> +
> +#define i386_flash_interrupts( _level ) \
> + { \
> + _CPU_Virtual_Interrupts_enable(_level); \
> + _CPU_Virtual_Interrupts_disable(_level); \
> + }
> +
> +#define i386_get_interrupt_level( _level ) \
> + { \
> + _CPU_Virtual_Interrupts_get_level( _level ); \
> + }
> +
> +#define _CPU_ISR_Disable( _level ) i386_disable_interrupts( _level )
> +#define _CPU_ISR_Enable( _level ) i386_enable_interrupts( _level )
> +
> +
> +#else /*RTEMS_PARAVIRT*/
> +
>
> #define i386_disable_interrupts( _level ) \
> { \
> @@ -75,6 +105,7 @@ typedef int (*rtems_raw_irq_is_enabled) (const struct __rtems_raw_irq_connect_d
> #define _CPU_ISR_Disable( _level ) i386_disable_interrupts( _level )
> #define _CPU_ISR_Enable( _level ) i386_enable_interrupts( _level )
>
> +#endif /*RTEMS_PARAVIRT*/
> /** @} */
>
> #endif
> diff --git a/cpukit/score/cpu/i386/rtems/score/virtualizationlayercpu.h b/cpukit/score/cpu/i386/rtems/score/virtualizationlayercpu.h
> new file mode 100644
> index 0000000..ce269fa
> --- /dev/null
> +++ b/cpukit/score/cpu/i386/rtems/score/virtualizationlayercpu.h
> @@ -0,0 +1,85 @@
> +/*
> + *
> + * COPYRIGHT (c) 2013 Philipp Eppelt.
> + * philipp.eppelt at mailbox.tu-dresden.de
> + *
> + * Purpose: CPU part of the virtualization layer.
> + * Licencse: see RTEMS License.
Fix typo. It might be better to include the boilerplate text here that
identifies the license, which you can copy from other files.
> + */
> +
> +
> +#ifndef RTEMS_VIRT_LAYER_CPU_H
> +#define RTEMS_VIRT_LAYER_CPU_H
> +
> +#ifndef ASM
> +
> +/* Interrupts */
> +
> +/**
> + * \brief Requests an interrupt vector.
> + */
> +int
> +_CPU_Virtual_Irq_request( int vector );
> +
> +/**
> + * \brief Releases an interrupt vector.
> + */
> +void
> +_CPU_Virtual_Irq_detach( int vector );
Should we use release instead of detach? what is "normal"?
> +
> +/**
> + * \brief Enables interrupt delivery or sets it to the specified level.
> + *
> + * Use this function in collaboration with _CPU_Virtual_Interrupts_disable and
> + * use its returned _level as argument to this function to assure proper
> + * behaviour.
> + */
> +void
> +_CPU_Virtual_Interrupts_enable( int _level );
> +
> +/**
> + * \brief Disables interrupt delivery and returns the previous level.
> + *
> + */
> +void
> +_CPU_Virtual_Interrupts_disable( int _level );
> +
> +/**
> + * \brief Enables and directly disables interrupt delivery.
> + */
> +void
> +_CPU_Virtual_Interrupts_flash( int _level );
> +
> +/**
> + * \brief Requests the current interrupt level.
> + */
> +int
> +_CPU_Virtual_Interrupts_get_level( int _level );
> +
> +
> +void
> +_CPU_Virtual_Interrupts_open(void);
> +void
> +_CPU_Virtual_Interrupts_close( void );
> +
> +/* Idle Thread */
> +
> +/**
> + * \brief Lowest priority thread, doing nothing, never returns;
> + */
> +
> +void
> +_CPU_Virtual_idle_thread( void );
s/idle/Idle ?
> +
> +
> +/* Error handling */
> +
> +/**
> + * \brief Handlers execution errors.
> + */
> +void
> +_CPU_Virtual_exec_stop_error( int _error );
Perhaps _CPU_Virtual_Stop_with_error()?
> +#endif /* ASM */
> +
> +#endif /* RTEMS_VIRT_LAYER_CPU_H */
> --
> 1.8.1.4
>
> _______________________________________________
> rtems-devel mailing list
> rtems-devel at rtems.org
> http://www.rtems.org/mailman/listinfo/rtems-devel
More information about the devel
mailing list