[PATCH] cpukit/cpu/i386: RTEMS_PARAVIRT guards, functionality and virt.layer

Gedare Bloom gedare at rtems.org
Fri Jul 18 15:57:10 UTC 2014


On Fri, Jul 18, 2014 at 11:37 AM, Philipp Eppelt
<philipp.eppelt at mailbox.tu-dresden.de> wrote:
> ---
> This is an updated version of an earlier unmerged patch, which extends the
> cpukit/score/cpu/i386/ model with guards to distinguish between
> paravirtualized (--enable-paravirt) and native environments.
>
>  cpukit/score/cpu/i386/Makefile.am                  |  1 +
>  cpukit/score/cpu/i386/cpu.c                        | 18 +++++
>  cpukit/score/cpu/i386/preinstall.am                |  3 +
>  cpukit/score/cpu/i386/rtems/score/cpu.h            | 48 +++++++++---
>  cpukit/score/cpu/i386/rtems/score/interrupts.h     | 38 ++++++++-
>  .../cpu/i386/rtems/score/virtualizationlayercpu.h  | 91 ++++++++++++++++++++++
>  6 files changed, 185 insertions(+), 14 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 494cd67..2293a3b 100644
> --- a/cpukit/score/cpu/i386/Makefile.am
> +++ b/cpukit/score/cpu/i386/Makefile.am
> @@ -11,6 +11,7 @@ include_rtems_score_HEADERS += rtems/score/interrupts.h
>  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/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 38b84e6..fb89df1 100644
> --- a/cpukit/score/cpu/i386/cpu.c
> +++ b/cpukit/score/cpu/i386/cpu.c
> @@ -26,6 +26,8 @@
>  #include <rtems/bspIo.h>
>  #include <rtems/score/thread.h>
>
> +#include <rtems/score/virtualizationlayercpu.h>
> +
>  #define I386_ASSERT_OFFSET(field, off) \
>    RTEMS_STATIC_ASSERT( \
>      offsetof(Context_Control, field) \
> @@ -115,6 +117,20 @@ uint32_t   _CPU_ISR_Get_level( void )
>    return level;
>  }
>
> +
avoid more than 1 blank line.

> +#if defined(RTEMS_PARAVIRT)
> +
> +void *_CPU_Thread_Idle_body( uintptr_t ignored )
> +{
> +  while(1)
> +  {
> +    _CPU_Virtual_Idle_thread();
Where is this function defined?

> +  }
> +  return NULL;
> +}
Does it make more sense for paravirtualized targets (e.g. i386/pok) to
put the idle thread in the paravirtualized bsp?

You do this by putting at score/cpu/i386/rtems/score/cpu.h:
#define CPU_PROVIDES_IDLE_THREAD_BODY    FALSE

And then in something like libbsp/shared/virtbspidle.c define:
void *bsp_virtual_idle_thread( uintptr_t ignored )
{
  while (1) {
    _CPU_Virtual_Idle_thread(); /* or some pok-specific implementation
at libbsp/shared/pokbspidle.c */
  }
  return NULL;
}

and in libbsp/i386/pok/include/bsp.h
#define BSP_IDLE_TASK_BODY bsp_virtual_idle_thread

> +
> +#else
> +
>  void *_CPU_Thread_Idle_body( uintptr_t ignored )
>  {
>    while(1){
> @@ -123,6 +139,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 060176b..4fd8533 100644
> --- a/cpukit/score/cpu/i386/preinstall.am
> +++ b/cpukit/score/cpu/i386/preinstall.am
> @@ -55,3 +55,6 @@ $(PROJECT_INCLUDE)/rtems/score/cpuatomic.h: rtems/score/cpuatomic.h $(PROJECT_IN
>         $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/rtems/score/cpuatomic.h
>  PREINSTALL_FILES += $(PROJECT_INCLUDE)/rtems/score/cpuatomic.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 2d1472d..7567777 100644
> --- a/cpukit/score/cpu/i386/rtems/score/cpu.h
> +++ b/cpukit/score/cpu/i386/rtems/score/cpu.h
> @@ -35,6 +35,8 @@ extern "C" {
>  #include <rtems/score/registers.h>     /* formerly part of libcpu */
>  #endif
>
> +#include <rtems/score/virtualizationlayercpu.h>
> +
>  /* conditional compilation parameters */
>
>  #define CPU_INLINE_ENABLE_DISPATCH       TRUE
> @@ -400,11 +402,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 );
>
> @@ -525,16 +538,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_Stop_with_error( _error ); \
>    }
>
> +#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*/
> +
You could do the same thing here by calling bsp_fatal_halt and
implementing halt at libbsp layer. Since performance is not an issue,
a function call is fine for this.

>  #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 5ae172a..4233a34 100644
> --- a/cpukit/score/cpu/i386/rtems/score/interrupts.h
> +++ b/cpukit/score/cpu/i386/rtems/score/interrupts.h
> @@ -8,6 +8,8 @@
>
>  /*
>   *  COPYRIGHT (c) 1998 valette at crf.canon.fr
> + *  COPYRIGHT (c) 2014 Philipp Eppelt.
> + *     philipp.eppelt at mailbox.tu-dresden.de
>   *
>   *  The license and distribution terms for this file may be
>   *  found in the file LICENSE in this distribution or at
> @@ -19,6 +21,8 @@
>  #ifndef _RTEMS_SCORE_INTERRUPTS_H
>  #define _RTEMS_SCORE_INTERRUPTS_H
>
> +#include <rtems/score/virtualizationlayercpu.h>
> +
>  #ifndef ASM
>
>  struct         __rtems_raw_irq_connect_data__;
> @@ -33,6 +37,35 @@ typedef int  (*rtems_raw_irq_is_enabled)     (const struct __rtems_raw_irq_connect_d
>   *
>   */
>  /**@{**/
> +#if defined(RTEMS_PARAVIRT)
> +
> +#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,7 +108,8 @@ 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
> -#endif
> +#endif /* ASM */
> +#endif /* _RTEMS_SCORE_INTERRUPTS_H */
> 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..9834f82
> --- /dev/null
> +++ b/cpukit/score/cpu/i386/rtems/score/virtualizationlayercpu.h
> @@ -0,0 +1,91 @@
> +/*
> + *
> + * COPYRIGHT (c) 2013 Philipp Eppelt.
> + *    philipp.eppelt at mailbox.tu-dresden.de
> + *
> + *  Purpose:   CPU part of the virtualization layer.
> + *
> + *  The license and distribution terms for this file may be
> + *  found in the file LICENSE in this distribution or at
> + *  http://www.rtems.com/license/LICENSE.
> + */
> +
> +#if defined(RTEMS_PARAVIRT)
> +
> +#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 );
> +
Where are these functions implemented?

> +/**
> + * \brief Releases an interrupt vector.
> + */
> +void
> +_CPU_Virtual_Irq_detach( int vector );
> +
> +/**
> + * \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 );
> +
> +
> +/* Error handling */
> +
> +/**
> + * \brief Handlers execution errors.
> + */
> +void
> +_CPU_Virtual_Stop_with_error( int _error );
> +
> +#endif /* ASM */
> +
> +#endif /* RTEMS_VIRT_LAYER_CPU_H */
> +
> +#endif /*RTEMS_PARAVIRT*/
> --
> 1.9.3
>
> _______________________________________________
> devel mailing list
> devel at rtems.org
> http://lists.rtems.org/mailman/listinfo/devel



More information about the devel mailing list