Index: c/src/lib/libbsp/hppa1.1/simhppa/include/bsp.h
===================================================================
--- c/src/lib/libbsp/hppa1.1/simhppa/include/bsp.h	(revision ac7d5ef06a6d6e8d84abbd1f0b82162725f98326)
+++ c/src/lib/libbsp/hppa1.1/simhppa/include/bsp.h	(revision ac7d5ef06a6d6e8d84abbd1f0b82162725f98326)
@@ -0,0 +1,93 @@
+/*  bsp.h
+ *
+ *  This include file contains all HP PA-RISC simulator definitions.
+ *
+ *  COPYRIGHT (c) 1989, 1990, 1991, 1992, 1993, 1994.
+ *  On-Line Applications Research Corporation (OAR).
+ *  All rights assigned to U.S. Government, 1994.
+ *
+ *  This material may be reproduced by or for the U.S. Government pursuant
+ *  to the copyright license under the clause at DFARS 252.227-7013.  This
+ *  notice must appear in all copies of this file and its derivatives.
+ *
+ *  $Id$
+ */
+
+#ifndef __SIMHPPA_h
+#define __SIMHPPA_h
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <rtems.h>
+#include <iosupp.h>
+
+/*
+ *  Define the time limits for RTEMS Test Suite test durations.
+ *  Long test and short test duration limits are provided.  These
+ *  values are in seconds and need to be converted to ticks for the
+ *  application.
+ *
+ */
+
+#define MAX_LONG_TEST_DURATION       3   /* 3 seconds */
+#define MAX_SHORT_TEST_DURATION      3   /* 3 seconds */
+
+/*
+ *  Define the interrupt mechanism for Time Test 27
+ */
+
+#define MUST_WAIT_FOR_INTERRUPT 1
+
+#define Install_tm27_vector( handler ) \
+    ( void ) set_vector( handler, HPPA_INTERRUPT_EXTERNAL_INTERVAL_TIMER, 1 );
+
+#define Cause_tm27_intr() \
+  set_itimer( get_itimer() + 20 )
+
+#define Clear_tm27_intr()  \
+  set_eirr( 0x80000000 )
+
+#define Lower_tm27_intr() \
+  { \
+    register unsigned32 ignored; \
+    HPPA_ASM_SSM( HPPA_PSW_I, ignored ); \
+  }
+
+/*
+ *  Simple spin delay in microsecond units for device drivers.
+ *  This is very dependent on the clock speed of the target.
+ */
+
+extern void Clock_delay(rtems_unsigned32 microseconds);
+#define delay( microseconds ) \
+        Clock_delay(microseconds);
+
+/*
+ * We printf() to a buffer if multiprocessing, *or* if this is set.
+ * ref: src/lib/libbsp/hppa/simhppa/iosupp/consupp.c
+ */
+
+extern int use_print_buffer;
+
+#define HPPA_INTERRUPT_EXTERNAL_MPCI        HPPA_INTERRUPT_EXTERNAL_10
+
+void bsp_start( void );
+void bsp_cleanup( void );
+
+/* miscellaneous stuff assumed to exist */
+
+extern rtems_configuration_table BSP_Configuration;     /* owned by BSP */
+extern rtems_cpu_table           Cpu_table;             /* owned by BSP */
+
+extern rtems_unsigned32          bsp_isr_level;
+
+extern int cpu_number;         /* from 0; cpu number in a multi cpu system */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+/* end of include file */
Index: c/src/lib/libbsp/hppa1.1/simhppa/include/coverhd.h
===================================================================
--- c/src/lib/libbsp/hppa1.1/simhppa/include/coverhd.h	(revision ac7d5ef06a6d6e8d84abbd1f0b82162725f98326)
+++ c/src/lib/libbsp/hppa1.1/simhppa/include/coverhd.h	(revision ac7d5ef06a6d6e8d84abbd1f0b82162725f98326)
@@ -0,0 +1,104 @@
+/*  coverhd.h
+ *
+ *  This include file has defines to represent the overhead associated
+ *  with calling a particular directive from C for this target.
+ *
+ *  COPYRIGHT (c) 1989, 1990, 1991, 1992, 1993, 1994.
+ *  On-Line Applications Research Corporation (OAR).
+ *  All rights assigned to U.S. Government, 1994.
+ *
+ *  This material may be reproduced by or for the U.S. Government pursuant
+ *  to the copyright license under the clause at DFARS 252.227-7013.  This
+ *  notice must appear in all copies of this file and its derivatives.
+ *
+ *  $Id$
+ */
+
+#ifndef __COVERHD_h
+#define __COVERHD_h
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define CALLING_OVERHEAD_INITIALIZE_EXECUTIVE      0
+#define CALLING_OVERHEAD_SHUTDOWN_EXECUTIVE        0
+#define CALLING_OVERHEAD_TASK_CREATE               0
+#define CALLING_OVERHEAD_TASK_IDENT                0
+#define CALLING_OVERHEAD_TASK_START                0
+#define CALLING_OVERHEAD_TASK_RESTART              0
+#define CALLING_OVERHEAD_TASK_DELETE               0
+#define CALLING_OVERHEAD_TASK_SUSPEND              0
+#define CALLING_OVERHEAD_TASK_RESUME               0
+#define CALLING_OVERHEAD_TASK_SET_PRIORITY         0
+#define CALLING_OVERHEAD_TASK_MODE                 0
+#define CALLING_OVERHEAD_TASK_GET_NOTE             0
+#define CALLING_OVERHEAD_TASK_SET_NOTE             0
+#define CALLING_OVERHEAD_TASK_WAKE_WHEN            0
+#define CALLING_OVERHEAD_TASK_WAKE_AFTER           0
+#define CALLING_OVERHEAD_INTERRUPT_CATCH           0
+#define CALLING_OVERHEAD_CLOCK_GET                 0
+#define CALLING_OVERHEAD_CLOCK_SET                 0
+#define CALLING_OVERHEAD_CLOCK_TICK                0
+
+#define CALLING_OVERHEAD_TIMER_CREATE              0
+#define CALLING_OVERHEAD_TIMER_IDENT               0
+#define CALLING_OVERHEAD_TIMER_DELETE              0
+#define CALLING_OVERHEAD_TIMER_FIRE_AFTER          0
+#define CALLING_OVERHEAD_TIMER_FIRE_WHEN           0
+#define CALLING_OVERHEAD_TIMER_RESET               0
+#define CALLING_OVERHEAD_TIMER_CANCEL              0
+#define CALLING_OVERHEAD_SEMAPHORE_CREATE          0
+#define CALLING_OVERHEAD_SEMAPHORE_IDENT           0
+#define CALLING_OVERHEAD_SEMAPHORE_DELETE          0
+#define CALLING_OVERHEAD_SEMAPHORE_OBTAIN          0
+#define CALLING_OVERHEAD_SEMAPHORE_RELEASE         0
+#define CALLING_OVERHEAD_MESSAGE_QUEUE_CREATE      0
+#define CALLING_OVERHEAD_MESSAGE_QUEUE_IDENT       0
+#define CALLING_OVERHEAD_MESSAGE_QUEUE_DELETE      0
+#define CALLING_OVERHEAD_MESSAGE_QUEUE_SEND        0
+#define CALLING_OVERHEAD_MESSAGE_QUEUE_URGENT      0
+#define CALLING_OVERHEAD_MESSAGE_QUEUE_BROADCAST   0
+#define CALLING_OVERHEAD_MESSAGE_QUEUE_RECEIVE     0
+#define CALLING_OVERHEAD_MESSAGE_QUEUE_FLUSH       0
+
+#define CALLING_OVERHEAD_EVENT_SEND                0
+#define CALLING_OVERHEAD_EVENT_RECEIVE             0
+#define CALLING_OVERHEAD_SIGNAL_CATCH              0
+#define CALLING_OVERHEAD_SIGNAL_SEND               0
+#define CALLING_OVERHEAD_PARTITION_CREATE          0
+#define CALLING_OVERHEAD_PARTITION_IDENT           0
+#define CALLING_OVERHEAD_PARTITION_DELETE          0
+#define CALLING_OVERHEAD_PARTITION_GET_BUFFER      0
+#define CALLING_OVERHEAD_PARTITION_RETURN_BUFFER   0
+#define CALLING_OVERHEAD_REGION_CREATE             0
+#define CALLING_OVERHEAD_REGION_IDENT              0
+#define CALLING_OVERHEAD_REGION_DELETE             0
+#define CALLING_OVERHEAD_REGION_GET_SEGMENT        0
+#define CALLING_OVERHEAD_REGION_RETURN_SEGMENT     0
+#define CALLING_OVERHEAD_PORT_CREATE               0
+#define CALLING_OVERHEAD_PORT_IDENT                0
+#define CALLING_OVERHEAD_PORT_DELETE               0
+#define CALLING_OVERHEAD_PORT_EXTERNAL_TO_INTERNAL 0
+#define CALLING_OVERHEAD_PORT_INTERNAL_TO_EXTERNAL 0
+
+#define CALLING_OVERHEAD_IO_INITIALIZE             0
+#define CALLING_OVERHEAD_IO_OPEN                   0
+#define CALLING_OVERHEAD_IO_CLOSE                  0
+#define CALLING_OVERHEAD_IO_READ                   0
+#define CALLING_OVERHEAD_IO_WRITE                  0
+#define CALLING_OVERHEAD_IO_CONTROL                0
+#define CALLING_OVERHEAD_FATAL_ERROR_OCCURRED      0
+#define CALLING_OVERHEAD_RATE_MONOTONIC_CREATE     0
+#define CALLING_OVERHEAD_RATE_MONOTONIC_IDENT      0
+#define CALLING_OVERHEAD_RATE_MONOTONIC_DELETE     0
+#define CALLING_OVERHEAD_RATE_MONOTONIC_CANCEL     0
+#define CALLING_OVERHEAD_RATE_MONOTONIC_PERIOD     0
+#define CALLING_OVERHEAD_MULTIPROCESSING_ANNOUNCE  0
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+/* end of include file */
Index: c/src/lib/libbsp/hppa1.1/simhppa/shmsupp/README
===================================================================
--- c/src/lib/libbsp/hppa1.1/simhppa/shmsupp/README	(revision ac7d5ef06a6d6e8d84abbd1f0b82162725f98326)
+++ c/src/lib/libbsp/hppa1.1/simhppa/shmsupp/README	(revision ac7d5ef06a6d6e8d84abbd1f0b82162725f98326)
@@ -0,0 +1,9 @@
+#
+#  $Id$
+#
+
+This directory contains the SHM driver support files for the
+HP PA-RISC simulator for the 72000 processor.
+
+WARNING: The interrupt support in this directory currently will
+         only work in a homogeneous system.
Index: c/src/lib/libbsp/hppa1.1/simhppa/shmsupp/addrconv.c
===================================================================
--- c/src/lib/libbsp/hppa1.1/simhppa/shmsupp/addrconv.c	(revision ac7d5ef06a6d6e8d84abbd1f0b82162725f98326)
+++ c/src/lib/libbsp/hppa1.1/simhppa/shmsupp/addrconv.c	(revision ac7d5ef06a6d6e8d84abbd1f0b82162725f98326)
@@ -0,0 +1,30 @@
+/*  Shm_Convert_address
+ *
+ *  No address range conversion is required.
+ *
+ *  Input parameters:
+ *    address - address to convert
+ *
+ *  Output parameters:
+ *    returns - converted address
+ *
+ *  COPYRIGHT (c) 1989, 1990, 1991, 1992, 1993, 1994.
+ *  On-Line Applications Research Corporation (OAR).
+ *  All rights assigned to U.S. Government, 1994.
+ *
+ *  This material may be reproduced by or for the U.S. Government pursuant
+ *  to the copyright license under the clause at DFARS 252.227-7013.  This
+ *  notice must appear in all copies of this file and its derivatives.
+ *
+ *  $Id$
+ */
+
+#include <bsp.h>
+#include <shm.h>
+
+void *Shm_Convert_address(
+  void *address
+)
+{
+  return ( address );
+}
Index: c/src/lib/libbsp/hppa1.1/simhppa/shmsupp/getcfg.c
===================================================================
--- c/src/lib/libbsp/hppa1.1/simhppa/shmsupp/getcfg.c	(revision ac7d5ef06a6d6e8d84abbd1f0b82162725f98326)
+++ c/src/lib/libbsp/hppa1.1/simhppa/shmsupp/getcfg.c	(revision ac7d5ef06a6d6e8d84abbd1f0b82162725f98326)
@@ -0,0 +1,84 @@
+/*  void Shm_Get_configuration( localnode, &shmcfg )
+ *
+ *  This routine initializes, if necessary, and returns a pointer
+ *  to the Shared Memory Configuration Table for the HP PA-RISC
+ *  simulator.
+ *
+ *  INPUT PARAMETERS:
+ *    localnode - local node number
+ *    shmcfg    - address of pointer to SHM Config Table
+ *
+ *  OUTPUT PARAMETERS:
+ *    *shmcfg   - pointer to SHM Config Table
+ *
+ *  NOTES:  The MP interrupt used is the Runway bus' ability to directly
+ *          address the control registers of up to four CPUs and cause
+ *          interrupts on them.
+ *
+ *          The following table illustrates the configuration limitations:
+ *
+ *                                   BUS     MAX
+ *                          MODE    ENDIAN  NODES
+ *                        ========= ====== =======
+ *                         POLLED    BIG    2+
+ *                        INTERRUPT  BIG    2..4 (on Runway)
+ *
+ *  COPYRIGHT (c) 1989, 1990, 1991, 1992, 1993, 1994.
+ *  On-Line Applications Research Corporation (OAR).
+ *  All rights assigned to U.S. Government, 1994.
+ *
+ *  This material may be reproduced by or for the U.S. Government pursuant
+ *  to the copyright license under the clause at DFARS 252.227-7013.  This
+ *  notice must appear in all copies of this file and its derivatives.
+ *
+ *  $Id$
+ */
+
+#include <bsp.h>
+#include <runway.h>
+
+#include "shm.h"
+
+#define INTERRUPT 0        /* can be interrupt or polling */
+#define POLLING   1
+
+shm_config_table BSP_shm_cfgtbl;
+
+void Shm_Cause_interrupt_simhppa(
+  rtems_unsigned32 node
+);
+
+void Shm_Get_configuration(
+  rtems_unsigned32   localnode,
+  shm_config_table **shmcfg
+)
+{
+   BSP_shm_cfgtbl.base         = (vol_u32 *) 0x44000000;
+   BSP_shm_cfgtbl.length       = 16 * KILOBYTE;
+   BSP_shm_cfgtbl.format       = SHM_BIG;
+
+   BSP_shm_cfgtbl.cause_intr   = Shm_Cause_interrupt_simhppa;
+
+#ifdef NEUTRAL_BIG
+   BSP_shm_cfgtbl.convert      = NULL_CONVERT;
+#else
+   BSP_shm_cfgtbl.convert      = CPU_swap_u32;
+#endif
+
+#if ( POLLING == 1 )
+   BSP_shm_cfgtbl.poll_intr    = POLLED_MODE;
+   BSP_shm_cfgtbl.Intr.address = NO_INTERRUPT;
+   BSP_shm_cfgtbl.Intr.value   = NO_INTERRUPT;
+   BSP_shm_cfgtbl.Intr.length  = NO_INTERRUPT;
+#else
+   BSP_shm_cfgtbl.poll_intr    = INTR_MODE;
+   BSP_shm_cfgtbl.Intr.address =
+        (vol_u32 *) (HPPA_RUNWAY_HPA( localnode - 1) +
+                     HPPA_RUNWAY_REG_IO_EIR_OFFSET);
+   BSP_shm_cfgtbl.Intr.value   = HPPA_INTERRUPT_EXTERNAL_MPCI;
+   BSP_shm_cfgtbl.Intr.length  = LONG;
+#endif
+
+   *shmcfg = &BSP_shm_cfgtbl;
+}
+
Index: c/src/lib/libbsp/hppa1.1/simhppa/shmsupp/intr.c
===================================================================
--- c/src/lib/libbsp/hppa1.1/simhppa/shmsupp/intr.c	(revision ac7d5ef06a6d6e8d84abbd1f0b82162725f98326)
+++ c/src/lib/libbsp/hppa1.1/simhppa/shmsupp/intr.c	(revision ac7d5ef06a6d6e8d84abbd1f0b82162725f98326)
@@ -0,0 +1,64 @@
+/*  void Shm_Cause_interrupt_simhppa( node )
+ *
+ *  This routine is the shared memory driver routine which
+ *  generates interrupts to other CPUs.
+ *
+ *  Input parameters:
+ *    node          - destination of this packet (0 = broadcast)
+ *
+ *  Output parameters: NONE
+ *
+ *  COPYRIGHT (c) 1989, 1990, 1991, 1992, 1993, 1994.
+ *  On-Line Applications Research Corporation (OAR).
+ *  All rights assigned to U.S. Government, 1994.
+ *
+ *  This material may be reproduced by or for the U.S. Government pursuant
+ *  to the copyright license under the clause at DFARS 252.227-7013.  This
+ *  notice must appear in all copies of this file and its derivatives.
+ *
+ *  $Id$
+ */
+
+#include "stdio.h"
+
+#include <rtems.h>
+#include "shm.h"
+
+void Shm_Cause_interrupt_simhppa(
+  rtems_unsigned32 node
+)
+{
+  Shm_Interrupt_information *intr;
+  rtems_unsigned8  *u8;
+  rtems_unsigned16 *u16;
+  rtems_unsigned32 *u32;
+  rtems_unsigned32  value;
+
+  intr = &Shm_Interrupt_table[node];
+  value = intr->value;
+
+  switch ( intr->length ) {
+    case NO_INTERRUPT:
+       break;
+    case BYTE:
+      u8   = (rtems_unsigned8 *)intr->address;
+      fprintf(
+        stderr,
+        "Shm_Cause_interrupt_simhppa: Writes of unsigned8 not supported!!!\n"
+      );
+      rtems_shutdown_executive( 0 );
+      break;
+    case WORD:
+      u16   = (rtems_unsigned16 *)intr->address;
+      fprintf(
+        stderr,
+        "Shm_Cause_interrupt_simhppa: Writes of unsigned8 not supported!!!\n"
+      );
+      rtems_shutdown_executive( 0 );
+      break;
+    case LONG:
+      u32   = (rtems_unsigned32 *)intr->address;
+      HPPA_ASM_STWAS( value, 0, u32 );
+      break;
+  }
+}
Index: c/src/lib/libbsp/hppa1.1/simhppa/shmsupp/lock.c
===================================================================
--- c/src/lib/libbsp/hppa1.1/simhppa/shmsupp/lock.c	(revision ac7d5ef06a6d6e8d84abbd1f0b82162725f98326)
+++ c/src/lib/libbsp/hppa1.1/simhppa/shmsupp/lock.c	(revision ac7d5ef06a6d6e8d84abbd1f0b82162725f98326)
@@ -0,0 +1,75 @@
+/*  Shared Memory Lock Routines
+ *
+ *  This shared memory locked queue support routine need to be
+ *  able to lock the specified locked queue.  Interrupts are
+ *  disabled while the queue is locked to prevent preemption
+ *  and deadlock when two tasks poll for the same lock.
+ *  previous level.
+ *
+ *  COPYRIGHT (c) 1989, 1990, 1991, 1992, 1993, 1994.
+ *  On-Line Applications Research Corporation (OAR).
+ *  All rights assigned to U.S. Government, 1994.
+ *
+ *  This material may be reproduced by or for the U.S. Government pursuant
+ *  to the copyright license under the clause at DFARS 252.227-7013.  This
+ *  notice must appear in all copies of this file and its derivatives.
+ *
+ *  $Id$
+ */
+
+#include <bsp.h>
+#include <shm.h>
+
+/*
+ *  Shm_Initialize_lock
+ *
+ *  Initialize the lock for the specified locked queue.
+ */
+
+void Shm_Initialize_lock(
+  Shm_Locked_queue_Control *lq_cb
+)
+{
+  lq_cb->lock = LQ_UNLOCKED;
+}
+
+/*  Shm_Lock( &lq_cb )
+ *
+ *  This shared memory locked queue support routine locks the
+ *  specified locked queue.  It disables interrupts to prevent
+ *  a deadlock condition.
+ */
+
+void Shm_Lock(
+  Shm_Locked_queue_Control *lq_cb
+)
+{
+  rtems_unsigned32  isr_level;
+  vol_u32          *lockptr = &lq_cb->lock;
+  rtems_unsigned32  lock_value;
+
+  rtems_interrupt_disable( isr_level );
+
+    Shm_isrstat = isr_level;
+
+    do {
+      HPPA_ASM_LDCWS( 0, 0, lockptr, lock_value );
+    } while (lock_value == SHM_LOCK_VALUE);
+}
+
+/*
+ *  Shm_Unlock
+ *
+ *  Unlock the lock for the specified locked queue.
+ */
+
+void Shm_Unlock(
+  Shm_Locked_queue_Control *lq_cb
+)
+{
+  rtems_unsigned32 isr_level;
+
+  lq_cb->lock = SHM_UNLOCK_VALUE;
+  isr_level = Shm_isrstat;
+  rtems_interrupt_enable( isr_level );
+}
Index: c/src/lib/libbsp/hppa1.1/simhppa/shmsupp/mpisr.c
===================================================================
--- c/src/lib/libbsp/hppa1.1/simhppa/shmsupp/mpisr.c	(revision ac7d5ef06a6d6e8d84abbd1f0b82162725f98326)
+++ c/src/lib/libbsp/hppa1.1/simhppa/shmsupp/mpisr.c	(revision ac7d5ef06a6d6e8d84abbd1f0b82162725f98326)
@@ -0,0 +1,27 @@
+/*  Shm_setvec
+ *
+ *  This driver routine sets the SHM interrupt vector to point to the
+ *  driver's SHM interrupt service routine.
+ *
+ *  Input parameters:  NONE
+ *
+ *  Output parameters: NONE
+ *
+ *  COPYRIGHT (c) 1989, 1990, 1991, 1992, 1993, 1994.
+ *  On-Line Applications Research Corporation (OAR).
+ *  All rights assigned to U.S. Government, 1994.
+ *
+ *  This material may be reproduced by or for the U.S. Government pursuant
+ *  to the copyright license under the clause at DFARS 252.227-7013.  This
+ *  notice must appear in all copies of this file and its derivatives.
+ *
+ *  $Id$
+ */
+
+#include <bsp.h>
+#include <shm.h>
+
+void Shm_setvec( void )
+{
+  set_vector( Shm_isr, HPPA_INTERRUPT_EXTERNAL_MPCI, 1 );
+}
Index: c/src/lib/libbsp/hppa1.1/simhppa/startup/bspclean.c
===================================================================
--- c/src/lib/libbsp/hppa1.1/simhppa/startup/bspclean.c	(revision ac7d5ef06a6d6e8d84abbd1f0b82162725f98326)
+++ c/src/lib/libbsp/hppa1.1/simhppa/startup/bspclean.c	(revision ac7d5ef06a6d6e8d84abbd1f0b82162725f98326)
@@ -0,0 +1,36 @@
+/*  bsp_cleanup()
+ *
+ *  This routine normally is part of start.s and returns
+ *  control to a monitor but on the HP PA-RISC simulator
+ *  we do that directly from main.c.
+ *
+ *  INPUT:  NONE
+ *
+ *  OUTPUT: NONE
+ *
+ *  COPYRIGHT (c) 1989, 1990, 1991, 1992, 1993, 1994.
+ *  On-Line Applications Research Corporation (OAR).
+ *  All rights assigned to U.S. Government, 1994.
+ *
+ *  This material may be reproduced by or for the U.S. Government pursuant
+ *  to the copyright license under the clause at DFARS 252.227-7013.  This
+ *  notice must appear in all copies of this file and its derivatives.
+ *
+ *  $Id$
+ */
+
+#include <bsp.h>
+
+/*
+ * The app has "exited" (called rtems_shutdown_executive)
+ */
+
+void bsp_cleanup( void )
+{
+    /*
+     * Invoke any fatal error extension and "halt"
+     * By definition, rtems_fatal_error_occurred does not return.
+     */
+
+    rtems_fatal_error_occurred(0);
+}
Index: c/src/lib/libbsp/hppa1.1/simhppa/startup/bspstart.c
===================================================================
--- c/src/lib/libbsp/hppa1.1/simhppa/startup/bspstart.c	(revision ac7d5ef06a6d6e8d84abbd1f0b82162725f98326)
+++ c/src/lib/libbsp/hppa1.1/simhppa/startup/bspstart.c	(revision ac7d5ef06a6d6e8d84abbd1f0b82162725f98326)
@@ -0,0 +1,387 @@
+/*
+ *	@(#)bspstart.c	1.13 - 95/04/25
+ *	
+ */
+
+/*  bsp_start()
+ *
+ *  This routine starts the application.  It includes application,
+ *  board, and monitor specific initialization and configuration.
+ *  The generic CPU dependent initialization has been performed
+ *  before this routine is invoked.
+ *
+ *  Called by RTEMS::RTEMS constructor in startup-ctor.cc
+ *
+ *  INPUT:  NONE
+ *
+ *  OUTPUT: NONE
+ *
+ *  COPYRIGHT (c) 1989, 1990, 1991, 1992, 1993, 1994.
+ *  On-Line Applications Research Corporation (OAR).
+ *  All rights assigned to U.S. Government, 1994.
+ *
+ *  This material may be reproduced by or for the U.S. Government pursuant
+ *  to the copyright license under the clause at DFARS 252.227-7013.  This
+ *  notice must appear in all copies of this file and its derivatives.
+ *
+ *  $Id$
+ */
+
+#include <bsp.h>
+#include <libcsupport.h>
+
+#include <string.h>
+
+#ifdef STACK_CHECKER_ON
+#include <stackchk.h>
+#endif
+
+extern rtems_configuration_table  Configuration;
+
+rtems_configuration_table BSP_Configuration;
+rtems_cpu_table           Cpu_table;
+rtems_unsigned32          bsp_isr_level;
+
+#define WORKSPACE_SIZE (1024 * 1024)
+rtems_unsigned8   MY_WORK_SPACE[ WORKSPACE_SIZE ];
+
+/*
+ * Amount to increment itimer by each pass
+ * It is a variable instead of a #define to allow the 'looptest'
+ * script to bump it without recompiling rtems
+ */
+
+rtems_unsigned32 CPU_HPPA_CLICKS_PER_TICK;
+
+#if SIMHPPA_FAST_IDLE
+
+/*
+ * Many of the tests are very slow on the simulator because they have
+ * have 5 second delays hardwired in.
+ * Try to speed those tests up by speeding up the clock when in idle
+ */
+
+rtems_extension
+fast_idle_switch_hook(rtems_tcb *current_task,
+                      rtems_tcb *heir_task)
+{
+    static rtems_unsigned32 normal_clock = ~0;
+    static rtems_unsigned32 fast_clock;
+
+    /* init our params on first call */
+    if (normal_clock == ~0)
+    {
+        normal_clock = CPU_HPPA_CLICKS_PER_TICK;
+        fast_clock = CPU_HPPA_CLICKS_PER_TICK / 0x100;
+        if (fast_clock == 0)    /* who? me?  pathological?  never! */
+            fast_clock++;
+    }
+
+    /*
+     * Checking for 'name' field of 'IDLE' is not the best/safest,
+     * but its the best we could think of at the moment.
+     */
+
+    if (heir_task->name == rtems_build_name('I', 'D', 'L', 'E'))
+        CPU_HPPA_CLICKS_PER_TICK = fast_clock;
+    else if (current_task->name == rtems_build_name('I', 'D', 'L', 'E'))
+        CPU_HPPA_CLICKS_PER_TICK = normal_clock;
+}
+
+#endif
+
+/*
+ *  Function:   bsp_libc_init
+ *  Created:    94/12/6
+ *
+ *  Description:
+ *      Initialize whatever libc we are using
+ *      called from bsp_postdriver_hook
+ *
+ *
+ *  Parameters:
+ *      none
+ *
+ *  Returns:
+ *      none.
+ *
+ *  Side Effects:
+ *
+ *
+ *  Notes:
+ *
+ *  Deficiencies/ToDo:
+ *
+ *
+ */
+
+void
+bsp_libc_init(void)
+{
+    extern int end;
+    rtems_unsigned32        heap_start;
+
+    heap_start = (rtems_unsigned32) &end;
+    if (heap_start & (CPU_ALIGNMENT-1))
+        heap_start = (heap_start + CPU_ALIGNMENT) & ~(CPU_ALIGNMENT-1);
+
+    RTEMS_Malloc_Initialize((void *) heap_start, 64 * 1024, 0);
+
+    /*
+     * Set up for the libc handling.
+     */
+
+    if (BSP_Configuration.ticks_per_timeslice > 0)
+        libc_init(1);                /* reentrant if possible */
+    else
+        libc_init(0);                /* non-reentrant */
+
+    /*
+     * on MP systems, always use the print buffer
+     *  instead of the (broken) system calls
+     */
+
+    if (BSP_Configuration.User_multiprocessing_table)
+        use_print_buffer = 1;
+
+#ifdef SIMHPPA_ROM
+    use_print_buffer = 1;
+#endif
+}
+
+
+/*
+ *  Function:   bsp_pretasking_hook
+ *  Created:    95/03/10
+ *
+ *  Description:
+ *      BSP pretasking hook.  Called just before drivers are initialized.
+ *      Used to setup libc and install any BSP extensions.
+ *
+ *  Parameters:
+ *      none
+ *
+ *  Returns:
+ *      nada
+ *
+ *  Side Effects:
+ *      installs a few extensions
+ *
+ *  Notes:
+ *      Must not use libc (to do io) from here, since drivers are
+ *      not yet initialized.
+ *
+ *  Deficiencies/ToDo:
+ *
+ *
+ */
+
+void
+bsp_pretasking_hook(void)
+{
+    bsp_libc_init();
+
+#if SIMHPPA_FAST_IDLE
+    /*
+     * Install the fast idle task switch extension
+     *
+     * on MP systems, might now want to do this; it confuses at least
+     * one test (mp06)
+     */
+
+#if 0
+    if (BSP_Configuration.User_multiprocessing_table == 0)
+#endif
+    {
+        rtems_extensions_table  fast_idle_extension;
+        rtems_id                extension_id;
+        rtems_status_code       rc;
+
+        memset(&fast_idle_extension, 0, sizeof(fast_idle_extension));
+
+        fast_idle_extension.task_switch  = fast_idle_switch_hook;
+
+        rc = rtems_extension_create(rtems_build_name('F', 'D', 'L', 'E'),
+                              &fast_idle_extension, &extension_id);
+        if (rc != RTEMS_SUCCESSFUL)
+            rtems_fatal_error_occurred(rc);
+    }
+#endif
+
+
+#ifdef STACK_CHECKER_ON
+    /*
+     *  Initialize the stack bounds checker
+     *  We can either turn it on here or from the app.
+     */
+
+    Stack_check_Initialize();
+#endif
+}
+
+/*
+ *  Function:   bsp_start
+ *  Created:    94/12/6
+ *
+ *  Description:
+ *      called by crt0 as our "main" equivalent
+ *
+ *
+ *
+ *  Parameters:
+ *
+ *
+ *  Returns:
+ *
+ *
+ *  Side Effects:
+ *
+ *
+ *  Notes:
+ *
+ *
+ *  Deficiencies/ToDo:
+ *
+ *
+ */
+
+
+void
+bsp_start(void)
+{
+    /*
+     * Set cpu_number to accurately reflect our cpu number
+     */
+
+#ifdef hppa7200
+    /*
+     * Use DR0 if supported
+     */
+    {
+        int dr0;
+        HPPA_ASM_MFCPU(DR0, dr0);
+        cpu_number = (dr0 >> 4) & 0x7;
+    }
+#else
+    if (Configuration.User_multiprocessing_table)
+        cpu_number = Configuration.User_multiprocessing_table->node - 1;
+    else
+        cpu_number = 0;
+#endif
+
+    /*
+     *  Copy the table
+     */
+
+    BSP_Configuration = Configuration;
+
+    BSP_Configuration.work_space_start = (void *)MY_WORK_SPACE;
+    if (BSP_Configuration.work_space_size)
+        BSP_Configuration.work_space_size = WORKSPACE_SIZE;
+
+    /*
+     * Set up our hooks
+     * Make sure libc_init is done before drivers init'd so that
+     * they can use atexit()
+     */
+
+    Cpu_table.pretasking_hook = bsp_pretasking_hook;    /* init libc, etc. */
+
+    Cpu_table.predriver_hook = NULL;
+
+    Cpu_table.postdriver_hook = NULL;
+
+    Cpu_table.idle_task = NULL;  /* do not override system IDLE task */
+
+    /*
+     *  Don't zero out the workspace.  The simulator did it for us.
+     */
+
+    Cpu_table.do_zero_of_workspace = FALSE;
+
+    Cpu_table.interrupt_stack_size = (12 * 1024);
+
+    Cpu_table.extra_system_initialization_stack = 0;
+
+    /*
+     * Set this artificially low for the simulator
+     */
+
+    Cpu_table.itimer_clicks_per_microsecond = 1;
+
+    /*
+     * Determine the external interrupt processing order
+     * the external interrupt handler walks thru this table, in
+     * order checking for posted interrupts.
+     */
+
+    Cpu_table.external_interrupts = 0;
+
+    Cpu_table.external_interrupt[ Cpu_table.external_interrupts ] =
+         HPPA_INTERRUPT_EXTERNAL_INTERVAL_TIMER - HPPA_INTERRUPT_EXTERNAL_BASE;
+    Cpu_table.external_interrupts++;
+
+    if ( Configuration.User_multiprocessing_table ) {
+      Cpu_table.external_interrupt[ Cpu_table.external_interrupts ] =
+         HPPA_INTERRUPT_EXTERNAL_10 - HPPA_INTERRUPT_EXTERNAL_BASE;
+      Cpu_table.external_interrupts++;
+    }
+
+    /*
+     * Add 1 region for RTEMS Malloc
+     */
+
+    BSP_Configuration.maximum_regions++;
+
+#ifdef RTEMS_NEWLIB
+    /*
+     * Add 1 extension for newlib libc
+     */
+
+    BSP_Configuration.maximum_extensions++;
+#endif
+
+#ifdef STACK_CHECKER_ON
+  /*
+   * Add 1 extension for stack checker
+   */
+
+    BSP_Configuration.maximum_extensions++;
+#endif
+
+#if SIMHPPA_FAST_IDLE
+  /*
+   * Add 1 extension for fast idle
+   */
+
+    BSP_Configuration.maximum_extensions++;
+#endif
+
+    /*
+     * Add 1 extension for MPCI_fatal
+     */
+
+    if (BSP_Configuration.User_multiprocessing_table)
+        BSP_Configuration.maximum_extensions++;
+
+    /*
+     * Set the "clicks per tick" for the simulator
+     *  used by libcpu/hppa/clock/clock.c to schedule interrupts
+     *
+     * Set it only if 0 to allow for simulator setting it via script
+     *   on test startup.
+     */
+
+    if (CPU_HPPA_CLICKS_PER_TICK == 0)
+        CPU_HPPA_CLICKS_PER_TICK = 0x4000;
+
+    /*
+     *  Start most of RTEMS
+     *  main() will start the rest
+     */
+
+    bsp_isr_level = rtems_initialize_executive_early(
+      &BSP_Configuration,
+      &Cpu_table
+    );
+}
Index: c/src/lib/libbsp/hppa1.1/simhppa/startup/setvec.c
===================================================================
--- c/src/lib/libbsp/hppa1.1/simhppa/startup/setvec.c	(revision ac7d5ef06a6d6e8d84abbd1f0b82162725f98326)
+++ c/src/lib/libbsp/hppa1.1/simhppa/startup/setvec.c	(revision ac7d5ef06a6d6e8d84abbd1f0b82162725f98326)
@@ -0,0 +1,66 @@
+/*  set_vector
+ *
+ *  This routine installs an interrupt vector on the HP PA-RISC simulator.
+ *
+ *  INPUT:
+ *    handler - interrupt handler entry point
+ *    vector  - vector number
+ *    type    - 0 indicates raw hardware connect
+ *              1 indicates RTEMS interrupt connect
+ *
+ *  NOTE 'type' is ignored on hppa; all interrupts are owned by RTEMS
+ *
+ *  RETURNS:
+ *    address of previous interrupt handler
+ *
+ *  COPYRIGHT (c) 1989, 1990, 1991, 1992, 1993, 1994.
+ *  On-Line Applications Research Corporation (OAR).
+ *  All rights assigned to U.S. Government, 1994.
+ *
+ *  This material may be reproduced by or for the U.S. Government pursuant
+ *  to the copyright license under the clause at DFARS 252.227-7013.  This
+ *  notice must appear in all copies of this file and its derivatives.
+ *
+ *  $Id$
+ */
+
+#include <rtems.h>
+
+/*
+ * Install an interrupt handler in the right place
+ * given its vector number from cpu/hppa.h
+ * There are 2 places an interrupt can be installed
+ *      _ISR_Vector_table
+ *      bsp interrupt      XXX: nyi
+ *
+ * We decide which based on the vector number
+ */
+
+rtems_isr_entry
+set_vector(                                     /* returns old vector */
+    rtems_isr_entry     handler,                /* isr routine        */
+    rtems_vector_number vector,                 /* vector number      */
+    int                 type                    /* RTEMS or RAW intr  */
+)
+{
+    rtems_isr_entry previous_isr;
+
+    /* is it an on chip interrupt? */
+    /* XXX this should say CPU_INTERRUPT_NUMBER_OF_VECTORS */
+    if (vector < HPPA_INTERRUPT_MAX)
+    {
+        rtems_interrupt_catch(handler, vector, &previous_isr);
+    }
+#if 0   /* XXX */
+    else if ((vector >= HPPA_INTERRUPT_BSP_BASE) &&
+             (vector < (HPPA_INTERRUPT_BSP_BASE + HPPA_BSP_INTERRUPTS)))
+    {
+        simhppa_interrupt_install(handler,
+                                  vector - HPPA_INTERRUPT_BSP_BASE,
+                                  (rtems_isr_entry *) &previous_isr);
+    }
+#endif
+
+    return previous_isr;
+}
+
Index: c/src/lib/libbsp/hppa1.1/simhppa/tools/print_dump.c
===================================================================
--- c/src/lib/libbsp/hppa1.1/simhppa/tools/print_dump.c	(revision ac7d5ef06a6d6e8d84abbd1f0b82162725f98326)
+++ c/src/lib/libbsp/hppa1.1/simhppa/tools/print_dump.c	(revision ac7d5ef06a6d6e8d84abbd1f0b82162725f98326)
@@ -0,0 +1,332 @@
+/*
+ *  print_dump
+ *
+ * $Id$
+ *
+ *  COPYRIGHT (c) 1994 by Division Incorporated
+ *
+ *  To anyone who acknowledges that this file is provided "AS IS"
+ *  without any express or implied warranty:
+ *      permission to use, copy, modify, and distribute this file
+ *      for any purpose is hereby granted without fee, provided that
+ *      the above copyright notice and this notice appears in all
+ *      copies, and that the name of Division Incorporated not be
+ *      used in advertising or publicity pertaining to distribution
+ *      of the software without specific, written prior permission.
+ *      Division Incorporated makes no representations about the
+ *      suitability of this software for any purpose.
+ */
+
+#define GETOPTARGS "v"
+
+char *USAGE = "\
+usage:  print_dump  [ -v ] \n\
+            -v          -- verbose\n\
+ Reads HP simulator 'memdump' output of 'print_buffer' structure
+ on stdin.  Dumps it out in vanilla ASCII.
+";
+
+#include <stdio.h>
+#include <fcntl.h>
+#include <ctype.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <string.h>
+#include <memory.h>
+#include <stdarg.h>
+
+#define Failed(x)       (((int) (x)) == -1)
+#define TRUE    1
+#define FALSE   0
+#define STREQ(a,b)      (strcmp(a,b) == 0)
+#define NUMELEMS(arr)   (sizeof(arr) / sizeof(arr[0]))
+
+/*
+ * Definitions for unsigned "ints"; especially for use in data structures
+ *  that will be shared among (potentially) different cpu's (we punt on
+ *  byte ordering problems tho)
+ */
+
+typedef unsigned char   u8;
+typedef unsigned short  u16;
+typedef unsigned int    u32;
+
+typedef union uval {
+    u8      uv_chars[4];
+    u16     uv_words[2];
+    u32     uv_long;
+    void    *uv_ptr[sizeof(long) / sizeof(void *)];
+} uval_t;
+
+
+/*
+ * vars controlled by command line options
+ */
+
+int verbose = FALSE;                    /* be verbose */
+
+extern char *optarg;                    /* getopt(3) control vars */
+extern int optind, opterr;
+extern int errno;
+
+char *progname;                         /* for error() */
+
+void error(int errn, ...);
+
+#define ERR_ERRNO  (1<<((sizeof(int) * 8) - 2)) /* hi bit; use 'errno' */
+#define ERR_FATAL  (ERR_ERRNO / 2)              /* error is fatal; no return */
+#define ERR_ABORT  (ERR_ERRNO / 4)              /* error is fatal; abort */
+#define ERR_MASK   (ERR_ERRNO | ERR_FATAL | ERR_ABORT) /* all */
+
+int  process(void);
+void prchar(unsigned int ch);
+
+
+int
+main(int argc, char **argv, char **env)
+{
+    register int c;
+    int showusage = FALSE;                      /* usage error? */
+
+    /*
+     * figure out invocation leaf-name
+     */
+
+    if ((progname = strrchr(argv[0], '/')) == (char *) NULL)
+        progname = argv[0];
+    else
+        progname++;
+
+    argv[0] = progname;                         /* for getopt err reporting */
+
+    /*
+     *  Check options and arguments.
+     */
+
+    opterr = 0;                                 /* we'll report all errors */
+    while ((c = getopt(argc, argv, GETOPTARGS)) != EOF)
+        switch (c)
+        {
+            case 'v':                           /* toggle verbose */
+                verbose = ! verbose;
+                break;
+
+            case '?':
+                showusage = TRUE;
+        }
+
+    if (showusage)
+    {
+        (void) fprintf(stderr, "%s", USAGE);
+        exit(1);
+    }
+
+    return process();
+}
+
+
+/*
+ * process(arg)
+ *
+ * Input looks like this
+ *
+ *   Starting address: 00000001.480035a0
+ *   -----------------------------------
+
++0000 / 0d0a0d0a 2a2a2a20 53454d20 54455354 202d2d20 4e4f4445 2032202a 2a2a0d0a
++0020 / 73703a20 30783433 30303030 31300d0a 30783438 30613161 38383a20 676f7420
+  ....
++0b40 / xxxxxxxx xxxxxxxx xxxxxxxx xxxxxxxx xxxxxxxx xxxxxxxx xxxxxxxx xxxxxxxx
+
+ *
+ * The 'xxxxxxxxx' shows up if the page has not been allocated.
+ */
+
+int
+process(void)
+{
+    uval_t b[8];
+    u32   ignore;
+    char *p;
+    int  i;
+    int  failed_once;
+
+    char line[1024];
+
+#define PRINT_BUFFER_SIZE (16 * 1024)
+    struct {
+        int  index;
+        int  size;
+        u8   buffer[PRINT_BUFFER_SIZE];
+    } print_buffer;
+
+    /* we stuff the data into print_buffer using memcpy() */
+    p = (char *) &print_buffer;
+
+    failed_once = 0;
+
+    while (gets(line))
+    {
+        char *cp;
+
+        /* hack; deal with the 'xxxxxxxx' problem noted above */
+        for (cp=line; *cp; cp++)
+            if (*cp == 'x')
+                *cp = '0';
+
+        if (*line != '+')
+            continue;
+        if (sscanf(line, "+%x / %x %x %x %x %x %x %x %x\n",
+                   &ignore,
+                   &b[0].uv_long,
+                   &b[1].uv_long,
+                   &b[2].uv_long,
+                   &b[3].uv_long,
+                   &b[4].uv_long,
+                   &b[5].uv_long,
+                   &b[6].uv_long,
+                   &b[7].uv_long) != 9)
+        {
+            if (failed_once)
+                error(ERR_FATAL, "2nd format problem; giving up");
+            error(0, "format problem in line: `%s`", line);
+            failed_once = 1;
+        }
+
+        memcpy((void *) p, (void *) b, sizeof(b));
+        p += sizeof(b);
+    }
+
+    if (verbose)
+        printf("buffer size: %d\n", print_buffer.size);
+
+    if (print_buffer.size < 0)
+        error(ERR_FATAL, "size is too small");
+
+    if (print_buffer.size != sizeof(print_buffer.buffer))
+    {
+        error(ERR_FATAL, "buffer size mismatch, expected %d",
+              sizeof(print_buffer.buffer));
+        /* XXX we really should just dynamically allocate the buffer */
+    }
+
+    i = print_buffer.index + 1;
+    while (i != print_buffer.index)
+    {
+        unsigned int c;
+        c = print_buffer.buffer[i++];
+        if (c && (c != '\r'))
+            prchar(c);
+        i %= print_buffer.size;
+    }
+    printf("\n");
+    return 0;
+}
+
+/* de-controlify */
+char *de_control[] = {
+    "^@", "^A", "^B", "^C", "^D", "^E", "^F", "^G", "^H", "^I", "^J", "^K",
+    "^L", "^M", "^N", "^O", "^P", "^Q", "^R", "^S", "^T", "^U", "^V", "^W",
+    "^X", "^Y", "^Z", "^[", "^\\", "^]", "^~", "^_",
+    " ", "!", "\"", "#", "$",  "%", "&", "'", "(", ")", "*", "+", ",", "-",
+    ".", "/", "0",  "1", "2",  "3", "4", "5", "6", "7", "8", "9", ":", ";",
+    "<", "=", ">",  "?", "@",  "A", "B", "C", "D", "E", "F", "G", "H", "I",
+    "J", "K", "L",  "M", "N",  "O", "P", "Q", "R", "S", "T", "U", "V", "W",
+    "X", "Y", "Z",  "[", "\\", "]", "^", "_", "`", "a", "b", "c", "d", "e",
+    "f", "g", "h",  "i", "j",  "k", "l", "m", "n", "o", "p", "q", "r", "s",
+    "t", "u", "v",  "w", "x",  "y", "z", "{", "|", "}", "~", "^?",
+    "M-^@", "M-^A", "M-^B", "M-^C", "M-^D", "M-^E", "M-^F", "M-^G",
+    "M-^H", "M-^I", "M-^J", "M-^K", "M-^L", "M-^M", "M-^N", "M-^O",
+    "M-^P", "M-^Q", "M-^R", "M-^S", "M-^T", "M-^U", "M-^V", "M-^W",
+    "M-^X", "M-^Y", "M-^Z", "M-^[", "M-^\\", "M-^]", "M-^~", "M-^_",
+    "M- ", "M-!", "M-\"", "M-#", "M-$", "M-%", "M-&", "M-'",
+    "M-(", "M-)", "M-*", "M-+", "M-,", "M--", "M-.", "M-/",
+    "M-0", "M-1", "M-2", "M-3", "M-4", "M-5", "M-6", "M-7",
+    "M-8", "M-9", "M-:", "M-;", "M-<", "M-=", "M->", "M-?",
+    "M-@", "M-A", "M-B", "M-C", "M-D", "M-E", "M-F", "M-G",
+    "M-H", "M-I", "M-J", "M-K", "M-L", "M-M", "M-N", "M-O",
+    "M-P", "M-Q", "M-R", "M-S", "M-T", "M-U", "M-V", "M-W",
+    "M-X", "M-Y", "M-Z", "M-[", "M-\\", "M-]", "M-^", "M-_",
+    "M-`", "M-a", "M-b", "M-c", "M-d", "M-e", "M-f", "M-g",
+    "M-h", "M-i", "M-j", "M-k", "M-l", "M-m", "M-n", "M-o",
+    "M-p", "M-q", "M-r", "M-s", "M-t", "M-u", "M-v", "M-w",
+    "M-x", "M-y", "M-z", "M-{", "M-|", "M-}", "M-~", "M-^?"
+};
+
+/*
+ * prchar(ch); print ch in a readable format, ie ^X or X or ~^X or DEL, etc.
+ */
+
+void
+prchar(unsigned int ch)
+{
+    if (isprint(ch) || isspace(ch))
+        putchar(ch);
+    else
+        printf("%s", de_control[ch]);
+}
+
+
+/*
+ * error(errn, arglist)
+ *      report an error to stderr using printf(3) conventions.
+ *      Any output is preceded by '<progname>: '
+ *
+ * Uses ERR_EXIT  bit to request exit(errn)
+ *      ERR_ABORT to request abort()
+ *      ERR_ERRNO to indicate use of errno instead of argument.
+ *
+ * If resulting 'errn' is non-zero, it is assumed to be an 'errno' and its
+ *      associated error message is appended to the output.
+ */
+
+/*VARARGS*/
+
+void
+error(int error_flag, ...)
+{
+    va_list arglist;
+    register char *format;
+    extern char *sys_errlist[];
+    extern int sys_nerr;
+    int local_errno;
+
+    extern int errno;
+
+    (void) fflush(stdout);          /* in case stdout/stderr same */
+
+    local_errno = error_flag & ~ERR_MASK;
+    if (error_flag & ERR_ERRNO)     /* use errno? */
+        local_errno = errno;
+
+    va_start(arglist, error_flag);
+    format = va_arg(arglist, char *);
+    (void) fprintf(stderr, "%s: ", progname);
+    (void) vfprintf(stderr, format, arglist);
+    va_end(arglist);
+
+    if (local_errno)
+        if ((local_errno > 0) && (local_errno < sys_nerr))
+            (void) fprintf(stderr, " (%s)\n", sys_errlist[local_errno]);
+        else
+            (void) fprintf(stderr, " (unknown errno=%d)\n", local_errno);
+    else
+        (void) fprintf(stderr, "\n");
+
+    (void) fflush(stderr);
+
+    if (error_flag & (ERR_FATAL | ERR_ABORT))
+    {
+        if (error_flag & ERR_FATAL)
+        {
+            error(0, local_errno ? "fatal error, exiting" : "exiting");
+            exit(local_errno);
+        }
+        else
+        {
+            error(0, "fatal error, aborting");
+            abort();
+        }
+    }
+}
+
