[rtems commit] powerpc: Remove _BSP_Fatal_error()

Sebastian Huber sebh at rtems.org
Wed Nov 22 12:02:37 UTC 2017


Module:    rtems
Branch:    master
Commit:    07d96453a98c9df64be87eaf1f9023ba05e90297
Changeset: http://git.rtems.org/rtems/commit/?id=07d96453a98c9df64be87eaf1f9023ba05e90297

Author:    Sebastian Huber <sebastian.huber at embedded-brains.de>
Date:      Tue Nov 21 12:00:49 2017 +0100

powerpc: Remove _BSP_Fatal_error()

BSPs can use the bsp_fatal_extension() to provide BSP-specific fatal
error handling.  There is no need for a _BSP_Fatal_error().

Close #3246.

---

 c/src/lib/libbsp/powerpc/beatnik/Makefile.am       |  1 -
 .../lib/libbsp/powerpc/gen5200/startup/bspstart.c  |  6 --
 .../lib/libbsp/powerpc/gen83xx/startup/bspstart.c  | 14 ----
 .../libbsp/powerpc/haleakala/startup/bspstart.c    | 13 ----
 .../libbsp/powerpc/mpc55xxevb/startup/bspstart.c   | 12 ----
 .../libbsp/powerpc/mpc8260ads/startup/bspstart.c   |  8 ---
 .../lib/libbsp/powerpc/mvme3100/startup/bspstart.c |  6 --
 .../lib/libbsp/powerpc/mvme5500/startup/bspstart.c |  6 --
 c/src/lib/libbsp/powerpc/psim/startup/bspstart.c   |  6 --
 c/src/lib/libbsp/powerpc/qemuppc/Makefile.am       |  2 +-
 .../lib/libbsp/powerpc/qemuppc/startup/bsppanic.c  | 14 ----
 c/src/lib/libbsp/powerpc/qoriq/startup/bspstart.c  | 14 ----
 c/src/lib/libbsp/powerpc/shared/startup/bspstart.c |  9 ---
 c/src/lib/libbsp/powerpc/shared/startup/panic.c    | 79 ----------------------
 c/src/lib/libbsp/powerpc/ss555/startup/bspstart.c  |  6 --
 .../lib/libbsp/powerpc/t32mppc/startup/bspstart.c  | 14 ----
 c/src/lib/libbsp/powerpc/tqm8xx/startup/bspstart.c | 14 ----
 c/src/lib/libbsp/powerpc/virtex/startup/bspstart.c | 12 ----
 c/src/lib/libbsp/powerpc/virtex4/include/bsp.h     |  1 -
 .../lib/libbsp/powerpc/virtex4/startup/bspstart.c  | 12 ----
 c/src/lib/libbsp/powerpc/virtex5/include/bsp.h     |  1 -
 .../lib/libbsp/powerpc/virtex5/startup/bspstart.c  | 12 ----
 cpukit/score/cpu/powerpc/rtems/score/cpu.h         | 25 ++++---
 23 files changed, 13 insertions(+), 274 deletions(-)

diff --git a/c/src/lib/libbsp/powerpc/beatnik/Makefile.am b/c/src/lib/libbsp/powerpc/beatnik/Makefile.am
index e764c9e..e359c08 100644
--- a/c/src/lib/libbsp/powerpc/beatnik/Makefile.am
+++ b/c/src/lib/libbsp/powerpc/beatnik/Makefile.am
@@ -58,7 +58,6 @@ libbsp_a_SOURCES =
 
 libbsp_a_SOURCES += startup/bspstart.c \
     ../shared/motorola/vpd.c startup/bspreset.c startup/i2c_init.c \
-    ../../powerpc/shared/startup/panic.c \
     ../../powerpc/shared/startup/bspgetworkarea.c \
     ../../powerpc/shared/startup/probeMemEnd.c \
     ../../powerpc/shared/startup/bsppredriverhook.c \
diff --git a/c/src/lib/libbsp/powerpc/gen5200/startup/bspstart.c b/c/src/lib/libbsp/powerpc/gen5200/startup/bspstart.c
index f09d97e..209cc77 100644
--- a/c/src/lib/libbsp/powerpc/gen5200/startup/bspstart.c
+++ b/c/src/lib/libbsp/powerpc/gen5200/startup/bspstart.c
@@ -112,12 +112,6 @@ uint32_t bsp_time_base_frequency;
 /* Legacy */
 uint32_t bsp_clicks_per_usec;
 
-void _BSP_Fatal_error(unsigned int v)
-{
-  printk("%s PANIC ERROR %x\n",_RTEMS_version, v);
-  __asm__ __volatile ("sc");
-}
-
 void bsp_start(void)
 {
   /*
diff --git a/c/src/lib/libbsp/powerpc/gen83xx/startup/bspstart.c b/c/src/lib/libbsp/powerpc/gen83xx/startup/bspstart.c
index db89f5e..cd729a8 100644
--- a/c/src/lib/libbsp/powerpc/gen83xx/startup/bspstart.c
+++ b/c/src/lib/libbsp/powerpc/gen83xx/startup/bspstart.c
@@ -51,20 +51,6 @@ static int mpc83xx_decrementer_exception_handler( BSP_Exception_frame *frame, un
   return 0;
 }
 
-void _BSP_Fatal_error(unsigned n)
-{
-  rtems_interrupt_level level;
-
-  rtems_interrupt_disable( level);
-  (void) level;
-
-  printk( "%s PANIC ERROR %u\n", rtems_get_version_string(), n);
-
-  while (1) {
-    /* Do nothing */
-  }
-}
-
 void bsp_start( void)
 {
   rtems_status_code sc = RTEMS_SUCCESSFUL;
diff --git a/c/src/lib/libbsp/powerpc/haleakala/startup/bspstart.c b/c/src/lib/libbsp/powerpc/haleakala/startup/bspstart.c
index dc53ed7..098145b 100644
--- a/c/src/lib/libbsp/powerpc/haleakala/startup/bspstart.c
+++ b/c/src/lib/libbsp/powerpc/haleakala/startup/bspstart.c
@@ -200,16 +200,3 @@ void bsp_start( void )
    */
   BSP_rtems_irq_mng_init(0);
 }
-
-static void BSP_ask_for_reset(void)
-{
-  printk("system stopped, press RESET");
-  while(1) {};
-}
-
-void _BSP_Fatal_error(unsigned int v)
-{
-  printk("%s FATAL ERROR %x\n",_RTEMS_version, v);
-  BSP_ask_for_reset();
-}
-
diff --git a/c/src/lib/libbsp/powerpc/mpc55xxevb/startup/bspstart.c b/c/src/lib/libbsp/powerpc/mpc55xxevb/startup/bspstart.c
index e218b2d..9042fc3 100644
--- a/c/src/lib/libbsp/powerpc/mpc55xxevb/startup/bspstart.c
+++ b/c/src/lib/libbsp/powerpc/mpc55xxevb/startup/bspstart.c
@@ -49,18 +49,6 @@ unsigned int bsp_clock_speed = 0;
 
 uint32_t bsp_clicks_per_usec = 0;
 
-void _BSP_Fatal_error(unsigned n)
-{
-	rtems_interrupt_level level;
-
-	(void) level;
-	rtems_interrupt_disable( level);
-
-	while (true) {
-		mpc55xx_wait_for_interrupt();
-	}
-}
-
 static void null_pointer_protection(void)
 {
 #ifdef MPC55XX_NULL_POINTER_PROTECTION
diff --git a/c/src/lib/libbsp/powerpc/mpc8260ads/startup/bspstart.c b/c/src/lib/libbsp/powerpc/mpc8260ads/startup/bspstart.c
index b1f0219..7e3a070 100644
--- a/c/src/lib/libbsp/powerpc/mpc8260ads/startup/bspstart.c
+++ b/c/src/lib/libbsp/powerpc/mpc8260ads/startup/bspstart.c
@@ -103,14 +103,6 @@ static void _BSP_GPLED1_off(void)
   csr->bcsr0 |=  GP1_LED;		/* Turn off GP1 LED */
 }
 
-void _BSP_Fatal_error(unsigned int v)
-{
-  _BSP_GPLED0_on();
-  _BSP_GPLED1_on();
-  printk("%s PANIC ERROR %x\n",_RTEMS_version, v);
-  __asm__ __volatile ("sc");
-}
-
 static void _BSP_Uart1_enable(void)
 {
   BCSR *csr;
diff --git a/c/src/lib/libbsp/powerpc/mvme3100/startup/bspstart.c b/c/src/lib/libbsp/powerpc/mvme3100/startup/bspstart.c
index f222908..e0c30b6 100644
--- a/c/src/lib/libbsp/powerpc/mvme3100/startup/bspstart.c
+++ b/c/src/lib/libbsp/powerpc/mvme3100/startup/bspstart.c
@@ -105,12 +105,6 @@ int i;
 BSP_output_char_function_type     BSP_output_char = BSP_output_char_via_serial;
 BSP_polling_getchar_function_type BSP_poll_char = NULL;
 
-void _BSP_Fatal_error(unsigned int v)
-{
-  printk("\n%s PANIC ERROR %x\n",_RTEMS_version, v);
-  __asm__ __volatile ("sc");
-}
-
 char *rtems_progname;
 
 /*
diff --git a/c/src/lib/libbsp/powerpc/mvme5500/startup/bspstart.c b/c/src/lib/libbsp/powerpc/mvme5500/startup/bspstart.c
index 66fcd2b..2310be7 100644
--- a/c/src/lib/libbsp/powerpc/mvme5500/startup/bspstart.c
+++ b/c/src/lib/libbsp/powerpc/mvme5500/startup/bspstart.c
@@ -111,12 +111,6 @@ static unsigned char ConfVPD_buff[200];
 static char cmdline_buf[CMDLINE_BUF_SIZE];
 char *BSP_commandline_string = cmdline_buf;
 
-void _BSP_Fatal_error(unsigned int v)
-{
-  printk("%s PANIC ERROR %x\n",_RTEMS_version, v);
-  __asm__ __volatile ("sc");
-}
-
 /* NOTE: we cannot simply malloc the commandline string;
  * save_boot_params() is called during a very early stage when
  * libc/malloc etc. are not yet initialized!
diff --git a/c/src/lib/libbsp/powerpc/psim/startup/bspstart.c b/c/src/lib/libbsp/powerpc/psim/startup/bspstart.c
index b0dc1e6..3a9809c 100644
--- a/c/src/lib/libbsp/powerpc/psim/startup/bspstart.c
+++ b/c/src/lib/libbsp/powerpc/psim/startup/bspstart.c
@@ -60,12 +60,6 @@ unsigned int BSP_time_base_divisor;
 
 extern unsigned long __rtems_end[];
 
-void _BSP_Fatal_error(unsigned int v)
-{
-  printk("%s PANIC ERROR %x\n",_RTEMS_version, v);
-  __asm__ __volatile ("sc");
-}
-
 /*
  *  bsp_start
  *
diff --git a/c/src/lib/libbsp/powerpc/qemuppc/Makefile.am b/c/src/lib/libbsp/powerpc/qemuppc/Makefile.am
index 6764dc2..6b8b852 100644
--- a/c/src/lib/libbsp/powerpc/qemuppc/Makefile.am
+++ b/c/src/lib/libbsp/powerpc/qemuppc/Makefile.am
@@ -34,7 +34,7 @@ startup_SOURCES = ../../shared/bspclean.c \
     ../../shared/bootcard.c ../../shared/sbrk.c \
     ../../shared/getentropy-cpucounter.c \
     ../../shared/gnatinstallhandler.c \
-    startup/cmain.c startup/bspstart.c startup/bsppanic.c
+    startup/cmain.c startup/bspstart.c
 # pclock
 # clock_SOURCES = ../../shared/clock_driver_simidle.c
 clock_SOURCES = ../shared/clock/clock.c
diff --git a/c/src/lib/libbsp/powerpc/qemuppc/startup/bsppanic.c b/c/src/lib/libbsp/powerpc/qemuppc/startup/bsppanic.c
deleted file mode 100644
index 3748600..0000000
--- a/c/src/lib/libbsp/powerpc/qemuppc/startup/bsppanic.c
+++ /dev/null
@@ -1,14 +0,0 @@
-#include <rtems.h>
-#include <rtems/bspIo.h>
-
-static void
-__outb(int port, unsigned char v)
-{
-  *((volatile unsigned char *)(0x80000000 + port)) = v;
-}
-
-void _BSP_Fatal_error(unsigned int v)
-{
-  printk("%s PANIC ERROR %x\n",_RTEMS_version, v);
-  __outb (0x92, 0x01);
-}
diff --git a/c/src/lib/libbsp/powerpc/qoriq/startup/bspstart.c b/c/src/lib/libbsp/powerpc/qoriq/startup/bspstart.c
index 3030d37..4815b4e 100644
--- a/c/src/lib/libbsp/powerpc/qoriq/startup/bspstart.c
+++ b/c/src/lib/libbsp/powerpc/qoriq/startup/bspstart.c
@@ -52,20 +52,6 @@ uint32_t bsp_time_base_frequency;
 
 uint32_t qoriq_clock_frequency;
 
-void _BSP_Fatal_error(unsigned n)
-{
-  rtems_interrupt_level level;
-
-  rtems_interrupt_local_disable(level);
-  (void) level;
-
-  printk("%s PANIC ERROR %u\n", rtems_get_version_string(), n);
-
-  while (1) {
-    /* Do nothing */
-  }
-}
-
 static void initialize_frequency_parameters(void)
 {
   const void *fdt = bsp_fdt_get();
diff --git a/c/src/lib/libbsp/powerpc/shared/startup/bspstart.c b/c/src/lib/libbsp/powerpc/shared/startup/bspstart.c
index 8a3695a..5a97cc8 100644
--- a/c/src/lib/libbsp/powerpc/shared/startup/bspstart.c
+++ b/c/src/lib/libbsp/powerpc/shared/startup/bspstart.c
@@ -84,15 +84,6 @@ unsigned int BSP_processor_frequency;
  */
 unsigned int BSP_time_base_divisor;
 
-void _BSP_Fatal_error(unsigned int v)
-{
-  printk("%s PANIC ERROR %x\n",_RTEMS_version, v);
-
-  while (true) {
-    /* Do nothing */
-  }
-}
-
 /*
  *  Use the shared implementations of the following routines
  */
diff --git a/c/src/lib/libbsp/powerpc/shared/startup/panic.c b/c/src/lib/libbsp/powerpc/shared/startup/panic.c
deleted file mode 100644
index 636dbe6..0000000
--- a/c/src/lib/libbsp/powerpc/shared/startup/panic.c
+++ /dev/null
@@ -1,79 +0,0 @@
-#include <rtems.h>
-#include <bsp.h>
-#include <bsp/bootcard.h>
-#include <bsp/uart.h>
-#include <rtems/bspIo.h>
-#include <rtems/error.h>
-#include <libcpu/stackTrace.h>
-#include <rtems/score/percpu.h>
-#include <rtems/score/threaddispatch.h>
-
-#include <inttypes.h>
-
-static void
-rebootQuestion(void)
-{
-  printk("Press a key to reboot\n");
-  BSP_poll_char_via_serial();
-  bsp_reset();
-}
-
-#define THESRC _Internal_errors_What_happened.the_source
-#define THEERR _Internal_errors_What_happened.the_error
-
-void _BSP_Fatal_error(unsigned int v)
-{
-  unsigned long flags;
-  const char *err = 0;
-
-  rtems_interrupt_disable(flags);
-  (void) flags; /* avoid set but not used warning */
-
-  printk("%s\n",_RTEMS_version);
-  printk("FATAL ERROR:\n");
-  printk("Environment:");
-  switch (THESRC) {
-    case INTERNAL_ERROR_CORE:
-      printk(" RTEMS Core\n");
-      err = rtems_internal_error_text(THEERR);
-    break;
-
-      case INTERNAL_ERROR_RTEMS_API:
-      printk(" RTEMS API\n");
-      err = rtems_status_text(THEERR);
-    break;
-
-      case INTERNAL_ERROR_POSIX_API:
-      printk(" POSIX API (errno)\n");
-      /* could use strerror but I'd rather avoid using this here */
-    break;
-
-    default:
-      printk("  UNKNOWN (0x%x)\n",THESRC);
-  break;
-  }
-  if ( _Thread_Dispatch_is_enabled() )
-    printk("enabled\n");
-  else
-    printk(
-      "  Error occurred in a Thread Dispatching DISABLED"
-      "  context (level %" PRIu32 ")\n",
-      _Thread_Dispatch_get_disable_level());
-
-  if ( _ISR_Nest_level ) {
-    printk(
-      "  Error occurred from ISR context (ISR nest level %" PRIu32 ")\n",
-      _ISR_Nest_level
-    );
-  }
-
-  printk("Error %d",THEERR);
-  if (err) {
-    printk(": %s",err);
-  }
-  printk("\n");
-  printk("Stack Trace:\n");
-  CPU_print_stack();
-
-  rebootQuestion();
-}
diff --git a/c/src/lib/libbsp/powerpc/ss555/startup/bspstart.c b/c/src/lib/libbsp/powerpc/ss555/startup/bspstart.c
index 98bf9e0..56be333 100644
--- a/c/src/lib/libbsp/powerpc/ss555/startup/bspstart.c
+++ b/c/src/lib/libbsp/powerpc/ss555/startup/bspstart.c
@@ -42,12 +42,6 @@ uint32_t   bsp_clock_speed;	       /* Serial clocks per second */
 uint32_t   bsp_timer_least_valid;
 uint32_t   bsp_timer_average_overhead;
 
-void _BSP_Fatal_error(unsigned int v)
-{
-  printk("%s PANIC ERROR %x\n",_RTEMS_version, v);
-  __asm__ __volatile ("sc");
-}
-
 /*
  *  bsp_start()
  *
diff --git a/c/src/lib/libbsp/powerpc/t32mppc/startup/bspstart.c b/c/src/lib/libbsp/powerpc/t32mppc/startup/bspstart.c
index 2a88329..5fc36b4 100644
--- a/c/src/lib/libbsp/powerpc/t32mppc/startup/bspstart.c
+++ b/c/src/lib/libbsp/powerpc/t32mppc/startup/bspstart.c
@@ -33,20 +33,6 @@ LINKER_SYMBOL(bsp_exc_vector_base);
  */
 uint32_t bsp_time_base_frequency = 10000000;
 
-void _BSP_Fatal_error(unsigned n)
-{
-  rtems_interrupt_level level;
-
-  rtems_interrupt_local_disable(level);
-  (void) level;
-
-  printk("%s PANIC ERROR %u\n", rtems_get_version_string(), n);
-
-  while (1) {
-    /* Do nothing */
-  }
-}
-
 #define MTIVPR(base) \
   __asm__ volatile ("mtivpr %0" : : "r" (base))
 
diff --git a/c/src/lib/libbsp/powerpc/tqm8xx/startup/bspstart.c b/c/src/lib/libbsp/powerpc/tqm8xx/startup/bspstart.c
index 4cc368a..7e7999c 100644
--- a/c/src/lib/libbsp/powerpc/tqm8xx/startup/bspstart.c
+++ b/c/src/lib/libbsp/powerpc/tqm8xx/startup/bspstart.c
@@ -51,20 +51,6 @@ uint32_t   bsp_timer_average_overhead; /* Average overhead of timer in ticks */
 uint32_t   bsp_timer_least_valid;      /* Least valid number from timer      */
 bool       bsp_timer_internal_clock;   /* TRUE, when timer runs with CPU clk */
 
-void _BSP_Fatal_error( unsigned n)
-{
-  rtems_interrupt_level level;
-
-  rtems_interrupt_disable( level);
-  (void) level;
-
-  printk( "%s PANIC ERROR %u\n", _RTEMS_version, n);
-
-  while (1) {
-    /* Do nothing */
-  }
-}
-
 static const char *bsp_tqm_get_cib_string( const char *cib_id)
 {
   char srch_pattern[10] = "";
diff --git a/c/src/lib/libbsp/powerpc/virtex/startup/bspstart.c b/c/src/lib/libbsp/powerpc/virtex/startup/bspstart.c
index 1625428..5b4a4a1 100644
--- a/c/src/lib/libbsp/powerpc/virtex/startup/bspstart.c
+++ b/c/src/lib/libbsp/powerpc/virtex/startup/bspstart.c
@@ -103,15 +103,3 @@ void bsp_start( void )
 
   bsp_interrupt_initialize();
 }
-
-void _BSP_Fatal_error(unsigned int v)
-{
-  rtems_interrupt_level level;
-
-  rtems_interrupt_disable(level);
-  (void) level;
-
-  while (true) {
-    /* Do nothing */
-  }
-}
diff --git a/c/src/lib/libbsp/powerpc/virtex4/include/bsp.h b/c/src/lib/libbsp/powerpc/virtex4/include/bsp.h
index 747dfdf..91e7ddf 100644
--- a/c/src/lib/libbsp/powerpc/virtex4/include/bsp.h
+++ b/c/src/lib/libbsp/powerpc/virtex4/include/bsp.h
@@ -70,7 +70,6 @@ extern rtems_configuration_table BSP_Configuration;     /* owned by BSP */
 #endif /* ASM */
 
 void BSP_ask_for_reset(void);
-void _BSP_Fatal_error(unsigned int v);
 
 /*
  * Prototypes for BSP methods shared across file boundaries
diff --git a/c/src/lib/libbsp/powerpc/virtex4/startup/bspstart.c b/c/src/lib/libbsp/powerpc/virtex4/startup/bspstart.c
index 8a8004d..473b846 100644
--- a/c/src/lib/libbsp/powerpc/virtex4/startup/bspstart.c
+++ b/c/src/lib/libbsp/powerpc/virtex4/startup/bspstart.c
@@ -133,18 +133,6 @@ void BSP_ask_for_reset(void)
 }
 
 
-void _BSP_Fatal_error(unsigned int v)
-{
-  RTEMS_UNUSED rtems_interrupt_level level;
-
-  rtems_interrupt_disable(level);
-
-  printk("\n%s FATAL ERROR %x\n", rtems_get_version_string(), v);
-
-  BSP_ask_for_reset();
-}
-
-
 /*===================================================================*/
 
 /*
diff --git a/c/src/lib/libbsp/powerpc/virtex5/include/bsp.h b/c/src/lib/libbsp/powerpc/virtex5/include/bsp.h
index 490ed8f..ee9f200 100644
--- a/c/src/lib/libbsp/powerpc/virtex5/include/bsp.h
+++ b/c/src/lib/libbsp/powerpc/virtex5/include/bsp.h
@@ -99,7 +99,6 @@ void zero_bss(void);
 #endif /* ASM */
 
 void BSP_ask_for_reset(void);
-void _BSP_Fatal_error(unsigned int v);
 
 #ifdef __cplusplus
 }
diff --git a/c/src/lib/libbsp/powerpc/virtex5/startup/bspstart.c b/c/src/lib/libbsp/powerpc/virtex5/startup/bspstart.c
index ff7a384..ec69d84 100644
--- a/c/src/lib/libbsp/powerpc/virtex5/startup/bspstart.c
+++ b/c/src/lib/libbsp/powerpc/virtex5/startup/bspstart.c
@@ -147,18 +147,6 @@ void BSP_ask_for_reset(void)
 }
 
 
-void _BSP_Fatal_error(unsigned int v)
-{
-  RTEMS_UNUSED rtems_interrupt_level level;
-
-  rtems_interrupt_disable(level);
-
-  printk("\n%s FATAL ERROR %x\n", rtems_get_version_string(), v);
-
-  BSP_ask_for_reset();
-}
-
-
 /*===================================================================*/
 
 /*
diff --git a/cpukit/score/cpu/powerpc/rtems/score/cpu.h b/cpukit/score/cpu/powerpc/rtems/score/cpu.h
index b8f00bf..8c0f200 100644
--- a/cpukit/score/cpu/powerpc/rtems/score/cpu.h
+++ b/cpukit/score/cpu/powerpc/rtems/score/cpu.h
@@ -675,22 +675,21 @@ static inline void _CPU_ISR_Set_level( uint32_t   level )
   _CPU_MSR_SET(msr);
 }
 
-/* Fatal Error manager macros */
-
-/*
- *  This routine copies _error into a known place -- typically a stack
- *  location or a register, optionally disables interrupts, and
- *  halts/stops the CPU.
- */
-
-void _BSP_Fatal_error(unsigned int);
-
 #endif /* ASM */
 
 #define _CPU_Fatal_halt( _source, _error ) \
-  _BSP_Fatal_error(_error)
-
-/* end of Fatal Error manager macros */
+  do { \
+    ppc_interrupt_disable(); \
+    __asm__ volatile ( \
+      "mr 3, %0\n" \
+      "mr 4, %1\n" \
+      "1:\n" \
+      "b 1b\n" \
+      : \
+      : "r" (_source), "r" (_error) \
+      : "memory" \
+    ); \
+  } while ( 0 )
 
 /*
  *  Should be large enough to run all RTEMS tests.  This ensures



More information about the vc mailing list