[PATCH] cpukit/cpu/i386: RTEMS_PARAVIRT guards, functionality and virt.layer
Philipp Eppelt
philipp.eppelt at mailbox.tu-dresden.de
Fri Jul 18 16:27:24 UTC 2014
On 07/18/2014 05:57 PM, Gedare Bloom wrote:
> 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?
At the moment the host provides this idle thread implementation via the
paravirtualization layer.
In case of POK, the implementation is provided via libpart.a in the
libbsp/i386/virtualpok directory. So from a host point of view, it
doesn't matter, where this goes.
However, as the virtualpok BSP isn't going to make it upstream any time
soon, I would keep this as it is for now and make this change, when
there is a BSP upstream too.
I had to provide this patch to Youren and Janek, so they would be able
to work with POK. In the current state, rtems isn't able to run on POK.
>
> 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?
In the host system. In the POK case they are provided via libpart.a in
the virtualpok BSP directory.
>
>> +/**
>> + * \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