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

Philipp Eppelt philipp.eppelt at mailbox.tu-dresden.de
Fri Jul 18 16:34:43 UTC 2014


---
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,19 @@ 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){
@@ -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*/
+
 #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 );
+
+/**
+ * \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




More information about the devel mailing list