/*  armos.c -- ARMulator OS interface:  ARM6 Instruction Emulator.
    Copyright (C) 1994 Advanced RISC Machines Ltd.

    This program is free software; you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation; either version 3 of the License, or
    (at your option) any later version.

    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with this program; if not, see <http://www.gnu.org/licenses/>. */

/* This file contains a model of Demon, ARM Ltd's Debug Monitor,
   including all the SWI's required to support the C library. The code in
   it is not really for the faint-hearted (especially the abort handling
   code), but it is a complete example. Defining NOOS will disable all the
   fun, and definign VAILDATE will define SWI 1 to enter SVC mode, and SWI
   0x11 to halt the emulator.  */

/* This must come before any other includes.  */
#include "defs.h"

#include "ansidecl.h"
#include "libiberty.h"

#include <time.h>
#include <errno.h>
#include <limits.h>
#include <string.h>
#include <unistd.h>		/* For SEEK_SET etc.  */

#include "armdefs.h"
#include "armos.h"
#include "armemu.h"

#ifndef NOOS
#ifndef VALIDATE
/* #ifndef ASIM */
#include "armfpe.h"
/* #endif */
#endif
#endif

/* For RDIError_BreakpointReached.  */
#include "dbg_rdi.h"

#include "sim/callback.h"
extern host_callback *sim_callback;

extern unsigned ARMul_OSInit       (ARMul_State *);
extern unsigned ARMul_OSHandleSWI  (ARMul_State *, ARMword);

#ifndef FOPEN_MAX
#define FOPEN_MAX 64
#endif
#ifndef PATH_MAX
#define PATH_MAX 1024
#endif

/* OS private Information.  */

struct OSblock
{
  ARMword ErrorNo;
};

/* Bit mask of enabled SWI implementations.  */
unsigned int swi_mask = -1;


static ARMword softvectorcode[] =
{
  /* Installed instructions:
       swi    tidyexception + event;
       mov    lr, pc;
       ldmia  fp, {fp, pc};
       swi    generateexception  + event.  */
  0xef000090, 0xe1a0e00f, 0xe89b8800, 0xef000080, /* Reset */
  0xef000091, 0xe1a0e00f, 0xe89b8800, 0xef000081, /* Undef */
  0xef000092, 0xe1a0e00f, 0xe89b8800, 0xef000082, /* SWI */
  0xef000093, 0xe1a0e00f, 0xe89b8800, 0xef000083, /* Prefetch abort */
  0xef000094, 0xe1a0e00f, 0xe89b8800, 0xef000084, /* Data abort */
  0xef000095, 0xe1a0e00f, 0xe89b8800, 0xef000085, /* Address exception */
  0xef000096, 0xe1a0e00f, 0xe89b8800, 0xef000086, /* IRQ */
  0xef000097, 0xe1a0e00f, 0xe89b8800, 0xef000087, /* FIQ */
  0xef000098, 0xe1a0e00f, 0xe89b8800, 0xef000088, /* Error */
  0xe1a0f00e			/* Default handler */
};

/* Time for the Operating System to initialise itself.  */

unsigned
ARMul_OSInit (ARMul_State * state)
{
#ifndef NOOS
#ifndef VALIDATE
  ARMword instr, i, j;
  struct OSblock *OSptr = (struct OSblock *) state->OSptr;

  if (state->OSptr == NULL)
    {
      state->OSptr = (unsigned char *) malloc (sizeof (struct OSblock));
      if (state->OSptr == NULL)
	{
	  perror ("OS Memory");
	  exit (15);
	}
    }

  OSptr = (struct OSblock *) state->OSptr;
  state->Reg[13] = ADDRSUPERSTACK;			/* Set up a stack for the current mode...  */
  ARMul_SetReg (state, SVC32MODE,   13, ADDRSUPERSTACK);/* ...and for supervisor mode...  */
  ARMul_SetReg (state, ABORT32MODE, 13, ADDRSUPERSTACK);/* ...and for abort 32 mode...  */
  ARMul_SetReg (state, UNDEF32MODE, 13, ADDRSUPERSTACK);/* ...and for undef 32 mode...  */
  ARMul_SetReg (state, SYSTEMMODE,  13, ADDRSUPERSTACK);/* ...and for system mode.  */
  instr = 0xe59ff000 | (ADDRSOFTVECTORS - 8);		/* Load pc from soft vector */

  for (i = ARMul_ResetV; i <= ARMFIQV; i += 4)
    /* Write hardware vectors.  */
    ARMul_WriteWord (state, i, instr);

  SWI_vector_installed = 0;

  for (i = ARMul_ResetV; i <= ARMFIQV + 4; i += 4)
    {
      ARMul_WriteWord (state, ADDRSOFTVECTORS + i, SOFTVECTORCODE + i * 4);
      ARMul_WriteWord (state, ADDRSOFHANDLERS + 2 * i + 4L,
		       SOFTVECTORCODE + sizeof (softvectorcode) - 4L);
    }

  for (i = 0; i < sizeof (softvectorcode); i += 4)
    ARMul_WriteWord (state, SOFTVECTORCODE + i, softvectorcode[i / 4]);

  ARMul_ConsolePrint (state, ", Demon 1.01");

/* #ifndef ASIM */

  /* Install FPE.  */
  for (i = 0; i < fpesize; i += 4)
    /* Copy the code.  */
    ARMul_WriteWord (state, FPESTART + i, fpecode[i >> 2]);

  /* Scan backwards from the end of the code.  */
  for (i = FPESTART + fpesize;; i -= 4)
    {
      /* When we reach the marker value, break out of
	 the loop, leaving i pointing at the maker.  */
      if ((j = ARMul_ReadWord (state, i)) == 0xffffffff)
	break;

      /* If necessary, reverse the error strings.  */
      if (state->bigendSig && j < 0x80000000)
	{
	  /* It's part of the string so swap it.  */
	  j = ((j >> 0x18) & 0x000000ff) |
	    ((j >> 0x08) & 0x0000ff00) |
	    ((j << 0x08) & 0x00ff0000) | ((j << 0x18) & 0xff000000);
	  ARMul_WriteWord (state, i, j);
	}
    }

  /* Copy old illegal instr vector.  */
  ARMul_WriteWord (state, FPEOLDVECT, ARMul_ReadWord (state, ARMUndefinedInstrV));
  /* Install new vector.  */
  ARMul_WriteWord (state, ARMUndefinedInstrV, FPENEWVECT (ARMul_ReadWord (state, i - 4)));
  ARMul_ConsolePrint (state, ", FPE");

/* #endif  ASIM */
#endif /* VALIDATE */
#endif /* NOOS */

  /* Intel do not want DEMON SWI support.  */
   if (state->is_XScale)
    swi_mask = SWI_MASK_ANGEL;

   return TRUE;
}

/* These are libgloss defines, but seem to be common across all supported ARM
   targets at the moment.  These should get moved to the callback open_map.  */
#define TARGET_O_BINARY 0
#define TARGET_O_APPEND 0x8
#define TARGET_O_CREAT 0x200
#define TARGET_O_RDONLY 0x0
#define TARGET_O_RDWR 0x2
#define TARGET_O_TRUNC 0x400
#define TARGET_O_WRONLY 0x1

static const int translate_open_mode[] =
{
  TARGET_O_RDONLY,		/* "r"   */
  TARGET_O_RDONLY + TARGET_O_BINARY,	/* "rb"  */
  TARGET_O_RDWR,		/* "r+"  */
  TARGET_O_RDWR + TARGET_O_BINARY,		/* "r+b" */
  TARGET_O_WRONLY + TARGET_O_CREAT + TARGET_O_TRUNC,	/* "w"   */
  TARGET_O_WRONLY + TARGET_O_BINARY + TARGET_O_CREAT + TARGET_O_TRUNC,	/* "wb"  */
  TARGET_O_RDWR + TARGET_O_CREAT + TARGET_O_TRUNC,	/* "w+"  */
  TARGET_O_RDWR + TARGET_O_BINARY + TARGET_O_CREAT + TARGET_O_TRUNC,	/* "w+b" */
  TARGET_O_WRONLY + TARGET_O_APPEND + TARGET_O_CREAT,	/* "a"   */
  TARGET_O_WRONLY + TARGET_O_BINARY + TARGET_O_APPEND + TARGET_O_CREAT,	/* "ab"  */
  TARGET_O_RDWR + TARGET_O_APPEND + TARGET_O_CREAT,	/* "a+"  */
  TARGET_O_RDWR + TARGET_O_BINARY + TARGET_O_APPEND + TARGET_O_CREAT	/* "a+b" */
};

static void
SWIWrite0 (ARMul_State * state, ARMword addr)
{
  ARMword temp;
  struct OSblock *OSptr = (struct OSblock *) state->OSptr;

  while ((temp = ARMul_SafeReadByte (state, addr++)) != 0)
    {
      char buffer = temp;
      /* Note - we cannot just cast 'temp' to a (char *) here,
	 since on a big-endian host the byte value will end
	 up in the wrong place and a nul character will be printed.  */
      (void) sim_callback->write_stdout (sim_callback, & buffer, 1);
    }

  OSptr->ErrorNo = sim_callback->get_errno (sim_callback);
}

static void
WriteCommandLineTo (ARMul_State * state, ARMword addr)
{
  ARMword temp;
  char *cptr = state->CommandLine;

  if (cptr == NULL)
    cptr = "\0";
  do
    {
      temp = (ARMword) * cptr++;
      ARMul_SafeWriteByte (state, addr++, temp);
    }
  while (temp != 0);
}

static int
ReadFileName (ARMul_State * state, char *buf, ARMword src, size_t n)
{
  struct OSblock *OSptr = (struct OSblock *) state->OSptr;
  char *p = buf;

  while (n--)
    if ((*p++ = ARMul_SafeReadByte (state, src++)) == '\0')
      return 0;
  OSptr->ErrorNo = cb_host_to_target_errno (sim_callback, ENAMETOOLONG);
  state->Reg[0] = -1;
  return -1;
}

static void
SWIopen (ARMul_State * state, ARMword name, ARMword SWIflags)
{
  struct OSblock *OSptr = (struct OSblock *) state->OSptr;
  char buf[PATH_MAX];
  int flags;

  if (ReadFileName (state, buf, name, sizeof buf) == -1)
    return;

  /* Now we need to decode the Demon open mode.  */
  if (SWIflags >= ARRAY_SIZE (translate_open_mode))
    flags = 0;
  else
    flags = translate_open_mode[SWIflags];

  /* Filename ":tt" is special: it denotes stdin/out.  */
  if (strcmp (buf, ":tt") == 0)
    {
      if (flags == TARGET_O_RDONLY) /* opening tty "r" */
	state->Reg[0] = 0;	/* stdin */
      else
	state->Reg[0] = 1;	/* stdout */
    }
  else
    {
      state->Reg[0] = sim_callback->open (sim_callback, buf, flags);
      OSptr->ErrorNo = sim_callback->get_errno (sim_callback);
    }
}

static void
SWIread (ARMul_State * state, ARMword f, ARMword ptr, ARMword len)
{
  struct OSblock *OSptr = (struct OSblock *) state->OSptr;
  int res;
  int i;
  char *local = malloc (len);

  if (local == NULL)
    {
      sim_callback->printf_filtered
	(sim_callback,
	 "sim: Unable to read 0x%lx bytes - out of memory\n",
	 (long)len);
      return;
    }

  res = sim_callback->read (sim_callback, f, local, len);
  if (res > 0)
    for (i = 0; i < res; i++)
      ARMul_SafeWriteByte (state, ptr + i, local[i]);

  free (local);
  state->Reg[0] = res == -1 ? -1 : len - res;
  OSptr->ErrorNo = sim_callback->get_errno (sim_callback);
}

static void
SWIwrite (ARMul_State * state, ARMword f, ARMword ptr, ARMword len)
{
  struct OSblock *OSptr = (struct OSblock *) state->OSptr;
  int res;
  ARMword i;
  char *local = malloc (len);

  if (local == NULL)
    {
      sim_callback->printf_filtered
	(sim_callback,
	 "sim: Unable to write 0x%lx bytes - out of memory\n",
	 (long) len);
      return;
    }

  for (i = 0; i < len; i++)
    local[i] = ARMul_SafeReadByte (state, ptr + i);

  res = sim_callback->write (sim_callback, f, local, len);
  state->Reg[0] = res == -1 ? -1 : len - res;
  free (local);

  OSptr->ErrorNo = sim_callback->get_errno (sim_callback);
}

static void
SWIflen (ARMul_State * state, ARMword fh)
{
  struct OSblock *OSptr = (struct OSblock *) state->OSptr;
  ARMword addr;

  if (fh > FOPEN_MAX)
    {
      OSptr->ErrorNo = EBADF;
      state->Reg[0] = -1L;
      return;
    }

  addr = sim_callback->lseek (sim_callback, fh, 0, SEEK_CUR);

  state->Reg[0] = sim_callback->lseek (sim_callback, fh, 0L, SEEK_END);
  (void) sim_callback->lseek (sim_callback, fh, addr, SEEK_SET);

  OSptr->ErrorNo = sim_callback->get_errno (sim_callback);
}

static void
SWIremove (ARMul_State * state, ARMword path)
{
  char buf[PATH_MAX];

  if (ReadFileName (state, buf, path, sizeof buf) != -1)
    {
      struct OSblock *OSptr = (struct OSblock *) state->OSptr;
      state->Reg[0] = sim_callback->unlink (sim_callback, buf);
      OSptr->ErrorNo = sim_callback->get_errno (sim_callback);
    }
}

static void
SWIrename (ARMul_State * state, ARMword old, ARMword new)
{
  char oldbuf[PATH_MAX], newbuf[PATH_MAX];

  if (ReadFileName (state, oldbuf, old, sizeof oldbuf) != -1
      && ReadFileName (state, newbuf, new, sizeof newbuf) != -1)
    {
      struct OSblock *OSptr = (struct OSblock *) state->OSptr;
      state->Reg[0] = sim_callback->rename (sim_callback, oldbuf, newbuf);
      OSptr->ErrorNo = sim_callback->get_errno (sim_callback);
    }
}

/* The emulator calls this routine when a SWI instruction is encuntered.
   The parameter passed is the SWI number (lower 24 bits of the instruction).  */

unsigned
ARMul_OSHandleSWI (ARMul_State * state, ARMword number)
{
  struct OSblock * OSptr = (struct OSblock *) state->OSptr;
  int              unhandled = FALSE;

  switch (number)
    {
    case SWI_Read:
      if (swi_mask & SWI_MASK_DEMON)
	SWIread (state, state->Reg[0], state->Reg[1], state->Reg[2]);
      else
	unhandled = TRUE;
      break;

    case SWI_Write:
      if (swi_mask & SWI_MASK_DEMON)
	SWIwrite (state, state->Reg[0], state->Reg[1], state->Reg[2]);
      else
	unhandled = TRUE;
      break;

    case SWI_Open:
      if (swi_mask & SWI_MASK_DEMON)
	SWIopen (state, state->Reg[0], state->Reg[1]);
      else
	unhandled = TRUE;
      break;

    case SWI_Clock:
      if (swi_mask & SWI_MASK_DEMON)
	{
	  /* Return number of centi-seconds.  */
	  state->Reg[0] =
#ifdef CLOCKS_PER_SEC
	    (CLOCKS_PER_SEC >= 100)
	    ? (ARMword) (clock () / (CLOCKS_PER_SEC / 100))
	    : (ARMword) ((clock () * 100) / CLOCKS_PER_SEC);
#else
	  /* Presume unix... clock() returns microseconds.  */
	  (ARMword) (clock () / 10000);
#endif
	  OSptr->ErrorNo = errno;
	}
      else
	unhandled = TRUE;
      break;

    case SWI_Time:
      if (swi_mask & SWI_MASK_DEMON)
	{
	  state->Reg[0] = (ARMword) sim_callback->time (sim_callback);
	  OSptr->ErrorNo = sim_callback->get_errno (sim_callback);
	}
      else
	unhandled = TRUE;
      break;

    case SWI_Close:
      if (swi_mask & SWI_MASK_DEMON)
	{
	  state->Reg[0] = sim_callback->close (sim_callback, state->Reg[0]);
	  OSptr->ErrorNo = sim_callback->get_errno (sim_callback);
	}
      else
	unhandled = TRUE;
      break;

    case SWI_Flen:
      if (swi_mask & SWI_MASK_DEMON)
	SWIflen (state, state->Reg[0]);
      else
	unhandled = TRUE;
      break;

    case SWI_Exit:
      if (swi_mask & SWI_MASK_DEMON)
	state->Emulate = FALSE;
      else
	unhandled = TRUE;
      break;

    case SWI_Seek:
      if (swi_mask & SWI_MASK_DEMON)
	{
	  /* We must return non-zero for failure.  */
	  state->Reg[0] = -1 >= sim_callback->lseek (sim_callback, state->Reg[0], state->Reg[1], SEEK_SET);
	  OSptr->ErrorNo = sim_callback->get_errno (sim_callback);
	}
      else
	unhandled = TRUE;
      break;

    case SWI_WriteC:
      if (swi_mask & SWI_MASK_DEMON)
	{
	  char tmp = state->Reg[0];
	  (void) sim_callback->write_stdout (sim_callback, &tmp, 1);
	  OSptr->ErrorNo = sim_callback->get_errno (sim_callback);
	}
      else
	unhandled = TRUE;
      break;

    case SWI_Write0:
      if (swi_mask & SWI_MASK_DEMON)
	SWIWrite0 (state, state->Reg[0]);
      else
	unhandled = TRUE;
      break;

    case SWI_GetErrno:
      if (swi_mask & SWI_MASK_DEMON)
	state->Reg[0] = OSptr->ErrorNo;
      else
	unhandled = TRUE;
      break;

    case SWI_GetEnv:
      if (swi_mask & SWI_MASK_DEMON)
	{
	  state->Reg[0] = ADDRCMDLINE;
	  if (state->MemSize)
	    state->Reg[1] = state->MemSize;
	  else
	    state->Reg[1] = ADDRUSERSTACK;

	  WriteCommandLineTo (state, state->Reg[0]);
	}
      else
	unhandled = TRUE;
      break;

    case SWI_Breakpoint:
      state->EndCondition = RDIError_BreakpointReached;
      state->Emulate = FALSE;
      break;

    case SWI_Remove:
      if (swi_mask & SWI_MASK_DEMON)
	SWIremove (state, state->Reg[0]);
      else
	unhandled = TRUE;
      break;

    case SWI_Rename:
      if (swi_mask & SWI_MASK_DEMON)
	SWIrename (state, state->Reg[0], state->Reg[1]);
      else
	unhandled = TRUE;
      break;

    case SWI_IsTTY:
      if (swi_mask & SWI_MASK_DEMON)
	{
	  state->Reg[0] = sim_callback->isatty (sim_callback, state->Reg[0]);
	  OSptr->ErrorNo = sim_callback->get_errno (sim_callback);
	}
      else
	unhandled = TRUE;
      break;

      /* Handle Angel SWIs as well as Demon ones.  */
    case AngelSWI_ARM:
    case AngelSWI_Thumb:
      if (swi_mask & SWI_MASK_ANGEL)
	{
	  ARMword addr;
	  ARMword temp;

	  /* R1 is almost always a parameter block.  */
	  addr = state->Reg[1];
	  /* R0 is a reason code.  */
	  switch (state->Reg[0])
	    {
	    case -1:
	      /* This can happen when a SWI is interrupted (eg receiving a
		 ctrl-C whilst processing SWIRead()).  The SWI will complete
		 returning -1 in r0 to the caller.  If GDB is then used to
		 resume the system call the reason code will now be -1.  */
	      return TRUE;

	      /* Unimplemented reason codes.  */
	    case AngelSWI_Reason_ReadC:
	    case AngelSWI_Reason_TmpNam:
	    case AngelSWI_Reason_System:
	    case AngelSWI_Reason_EnterSVC:
	    default:
	      state->Emulate = FALSE;
	      return FALSE;

	    case AngelSWI_Reason_Clock:
	      /* Return number of centi-seconds.  */
	      state->Reg[0] =
#ifdef CLOCKS_PER_SEC
		(CLOCKS_PER_SEC >= 100)
		? (ARMword) (clock () / (CLOCKS_PER_SEC / 100))
		: (ARMword) ((clock () * 100) / CLOCKS_PER_SEC);
#else
	      /* Presume unix... clock() returns microseconds.  */
	      (ARMword) (clock () / 10000);
#endif
	      OSptr->ErrorNo = errno;
	      break;

	    case AngelSWI_Reason_Time:
	      state->Reg[0] = (ARMword) sim_callback->time (sim_callback);
	      OSptr->ErrorNo = sim_callback->get_errno (sim_callback);
	      break;

	    case AngelSWI_Reason_WriteC:
	      {
		char tmp = ARMul_SafeReadByte (state, addr);
		(void) sim_callback->write_stdout (sim_callback, &tmp, 1);
		OSptr->ErrorNo = sim_callback->get_errno (sim_callback);
		break;
	      }

	    case AngelSWI_Reason_Write0:
	      SWIWrite0 (state, addr);
	      break;

	    case AngelSWI_Reason_Close:
	      state->Reg[0] = sim_callback->close (sim_callback, ARMul_ReadWord (state, addr));
	      OSptr->ErrorNo = sim_callback->get_errno (sim_callback);
	      break;

	    case AngelSWI_Reason_Seek:
	      state->Reg[0] = -1 >= sim_callback->lseek (sim_callback, ARMul_ReadWord (state, addr),
							 ARMul_ReadWord (state, addr + 4),
							 SEEK_SET);
	      OSptr->ErrorNo = sim_callback->get_errno (sim_callback);
	      break;

	    case AngelSWI_Reason_FLen:
	      SWIflen (state, ARMul_ReadWord (state, addr));
	      break;

	    case AngelSWI_Reason_GetCmdLine:
	      WriteCommandLineTo (state, ARMul_ReadWord (state, addr));
	      break;

	    case AngelSWI_Reason_HeapInfo:
	      /* R1 is a pointer to a pointer.  */
	      addr = ARMul_ReadWord (state, addr);

	      /* Pick up the right memory limit.  */
	      if (state->MemSize)
		temp = state->MemSize;
	      else
		temp = ADDRUSERSTACK;

	      ARMul_WriteWord (state, addr, 0);		/* Heap base.  */
	      ARMul_WriteWord (state, addr + 4, temp);	/* Heap limit.  */
	      ARMul_WriteWord (state, addr + 8, temp);	/* Stack base.  */
	      ARMul_WriteWord (state, addr + 12, temp);	/* Stack limit.  */
	      break;

	    case AngelSWI_Reason_ReportException:
	      if (state->Reg[1] == ADP_Stopped_ApplicationExit)
		state->Reg[0] = 0;
	      else
		state->Reg[0] = -1;
	      state->Emulate = FALSE;
	      break;

	    case ADP_Stopped_ApplicationExit:
	      state->Reg[0] = 0;
	      state->Emulate = FALSE;
	      break;

	    case ADP_Stopped_RunTimeError:
	      state->Reg[0] = -1;
	      state->Emulate = FALSE;
	      break;

	    case AngelSWI_Reason_Errno:
	      state->Reg[0] = OSptr->ErrorNo;
	      break;

	    case AngelSWI_Reason_Open:
	      SWIopen (state,
		       ARMul_ReadWord (state, addr),
		       ARMul_ReadWord (state, addr + 4));
	      break;

	    case AngelSWI_Reason_Read:
	      SWIread (state,
		       ARMul_ReadWord (state, addr),
		       ARMul_ReadWord (state, addr + 4),
		       ARMul_ReadWord (state, addr + 8));
	      break;

	    case AngelSWI_Reason_Write:
	      SWIwrite (state,
			ARMul_ReadWord (state, addr),
			ARMul_ReadWord (state, addr + 4),
			ARMul_ReadWord (state, addr + 8));
	      break;

	    case AngelSWI_Reason_IsTTY:
	      state->Reg[0] = sim_callback->isatty (sim_callback,
						    ARMul_ReadWord (state, addr));
	      OSptr->ErrorNo = sim_callback->get_errno (sim_callback);
	      break;

	    case AngelSWI_Reason_Remove:
	      SWIremove (state,
			 ARMul_ReadWord (state, addr));

	    case AngelSWI_Reason_Rename:
	      SWIrename (state,
			 ARMul_ReadWord (state, addr),
			 ARMul_ReadWord (state, addr + 4));
	    }
	}
      else
	unhandled = TRUE;
      break;

      /* The following SWIs are generated by the softvectorcode[]
	 installed by default by the simulator.  */
    case 0x91: /* Undefined Instruction.  */
      {
	ARMword addr = state->RegBank[UNDEFBANK][14] - 4;
	
	sim_callback->printf_filtered
	  (sim_callback, "sim: exception: Unhandled Instruction '0x%08x' at 0x%08x.  Stopping.\n",
	   ARMul_ReadWord (state, addr), addr);
	state->EndCondition = RDIError_SoftwareInterrupt;
	state->Emulate = FALSE;
	return FALSE;
      }

    case 0x90: /* Reset.  */
    case 0x92: /* SWI.  */
      /* These two can be safely ignored.  */
      break;

    case 0x93: /* Prefetch Abort.  */
    case 0x94: /* Data Abort.  */
    case 0x95: /* Address Exception.  */
    case 0x96: /* IRQ.  */
    case 0x97: /* FIQ.  */
    case 0x98: /* Error.  */
      unhandled = TRUE;
      break;

    case -1:
      /* This can happen when a SWI is interrupted (eg receiving a
	 ctrl-C whilst processing SWIRead()).  The SWI will complete
	 returning -1 in r0 to the caller.  If GDB is then used to
	 resume the system call the reason code will now be -1.  */
      return TRUE;

    case 0x180001: /* RedBoot's Syscall SWI in ARM mode.  */
      if (swi_mask & SWI_MASK_REDBOOT)
	{
	  switch (state->Reg[0])
	    {
	      /* These numbers are defined in libgloss/syscall.h
		 but the simulator should not be dependend upon
		 libgloss being installed.  */
	    case 1:  /* Exit.  */
	      state->Emulate = FALSE;
	      /* Copy exit code into r0.  */
	      state->Reg[0] = state->Reg[1];
	      break;

	    case 2:  /* Open.  */
	      SWIopen (state, state->Reg[1], state->Reg[2]);
	      break;

	    case 3:  /* Close.  */
	      state->Reg[0] = sim_callback->close (sim_callback, state->Reg[1]);
	      OSptr->ErrorNo = sim_callback->get_errno (sim_callback);
	      break;

	    case 4:  /* Read.  */
	      SWIread (state, state->Reg[1], state->Reg[2], state->Reg[3]);
	      break;

	    case 5:  /* Write.  */
	      SWIwrite (state, state->Reg[1], state->Reg[2], state->Reg[3]);
	      break;

	    case 6:  /* Lseek.  */
	      state->Reg[0] = sim_callback->lseek (sim_callback,
						   state->Reg[1],
						   state->Reg[2],
						   state->Reg[3]);
	      OSptr->ErrorNo = sim_callback->get_errno (sim_callback);
	      break;

	    case 17: /* Utime.  */
	      state->Reg[0] = state->Reg[1] = (ARMword) sim_callback->time (sim_callback);
	      OSptr->ErrorNo = sim_callback->get_errno (sim_callback);
	      break;

	    case 7:  /* Unlink.  */
	    case 8:  /* Getpid.  */
	    case 9:  /* Kill.  */
	    case 10: /* Fstat.  */
	    case 11: /* Sbrk.  */
	    case 12: /* Argvlen.  */
	    case 13: /* Argv.  */
	    case 14: /* ChDir.  */
	    case 15: /* Stat.  */
	    case 16: /* Chmod.  */
	    case 18: /* Time.  */
	      sim_callback->printf_filtered
		(sim_callback,
		 "sim: unhandled RedBoot syscall `%d' encountered - "
		 "returning ENOSYS\n",
		 state->Reg[0]);
	      state->Reg[0] = -1;
	      OSptr->ErrorNo = cb_host_to_target_errno
		(sim_callback, ENOSYS);
	      break;
	    case 1001: /* Meminfo. */
	      {
		ARMword totmem = state->Reg[1],
			topmem = state->Reg[2];
		ARMword stack = state->MemSize > 0
		  ? state->MemSize : ADDRUSERSTACK;
		if (totmem != 0)
		  ARMul_WriteWord (state, totmem, stack);
		if (topmem != 0)
		  ARMul_WriteWord (state, topmem, stack);
		state->Reg[0] = 0;
		break;
	      }

	    default:
	      sim_callback->printf_filtered
		(sim_callback,
		 "sim: unknown RedBoot syscall '%d' encountered - ignoring\n",
		 state->Reg[0]);
	      return FALSE;
	    }
	  break;
	}

    default:
      unhandled = TRUE;
    }

  if (unhandled)
    {
      if (SWI_vector_installed)
	{
	  ARMword cpsr;
	  ARMword i_size;

	  cpsr = ARMul_GetCPSR (state);
	  i_size = INSN_SIZE;

	  ARMul_SetSPSR (state, SVC32MODE, cpsr);

	  cpsr &= ~0xbf;
	  cpsr |= SVC32MODE | 0x80;
	  ARMul_SetCPSR (state, cpsr);

	  state->RegBank[SVCBANK][14] = state->Reg[14] = state->Reg[15] - i_size;
	  state->NextInstr            = RESUME;
	  state->Reg[15]              = state->pc = ARMSWIV;
	  FLUSHPIPE;
	}
      else
	{
	  sim_callback->printf_filtered
	    (sim_callback,
	     "sim: unknown SWI encountered - %x - ignoring\n",
	     number);
	  return FALSE;
	}
    }

  return TRUE;
}
