OpenCores
URL https://opencores.org/ocsvn/or1k/or1k/trunk

Subversion Repositories or1k

[/] [or1k/] [branches/] [oc/] [gdb-5.0/] [sim/] [common/] [sim-break.c] - Rev 1765

Compare with Previous | Blame | View Log

/* Simulator breakpoint support.
   Copyright (C) 1997 Free Software Foundation, Inc.
   Contributed by Cygnus Support.
 
This file is part of GDB, the GNU debugger.
 
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 2, 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, write to the Free Software Foundation, Inc.,
59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
 
#include <stdio.h>
 
#include "sim-main.h"
#include "sim-assert.h"
#include "sim-break.h"
 
#ifndef SIM_BREAKPOINT
#define SIM_BREAKPOINT {0x00}
#define SIM_BREAKPOINT_SIZE (1)
#endif
 
struct
sim_breakpoint
{
  struct sim_breakpoint *next;
  SIM_ADDR addr;		/* Address of this breakpoint */
  int flags;
  unsigned char loc_contents[SIM_BREAKPOINT_SIZE]; /* Contents of addr while
						      BP is enabled */
};
 
#define SIM_BREAK_INSERTED 0x1	/* Breakpoint has been inserted */
#define SIM_BREAK_DISABLED 0x2	/* Breakpoint is disabled */
 
static unsigned char sim_breakpoint [] = SIM_BREAKPOINT;
 
static void insert_breakpoint PARAMS ((SIM_DESC sd,
				       struct sim_breakpoint *bp));
static void remove_breakpoint PARAMS ((SIM_DESC sd,
				       struct sim_breakpoint *bp));
static SIM_RC resume_handler PARAMS ((SIM_DESC sd));
static SIM_RC suspend_handler PARAMS ((SIM_DESC sd));
 
 
/* Do the actual work of inserting a breakpoint into the instruction
   stream. */
 
static void
insert_breakpoint (sd, bp)
     SIM_DESC sd;
     struct sim_breakpoint *bp;
{
  if (bp->flags & (SIM_BREAK_INSERTED | SIM_BREAK_DISABLED))
    return;
 
  sim_core_read_buffer (sd, NULL, exec_map, bp->loc_contents,
			bp->addr, SIM_BREAKPOINT_SIZE);
  sim_core_write_buffer (sd, NULL, exec_map, sim_breakpoint,
			 bp->addr, SIM_BREAKPOINT_SIZE);
  bp->flags |= SIM_BREAK_INSERTED;
}
 
/* Do the actual work of removing a breakpoint. */
 
static void
remove_breakpoint (sd, bp)
     SIM_DESC sd;
     struct sim_breakpoint *bp;
{
  if (!(bp->flags & SIM_BREAK_INSERTED))
    return;
 
  sim_core_write_buffer (sd, NULL, exec_map, bp->loc_contents,
			 bp->addr, SIM_BREAKPOINT_SIZE);
  bp->flags &= ~SIM_BREAK_INSERTED;
}
 
/* Come here when a breakpoint insn is hit.  If it's really a breakpoint, we
   halt things, and never return.  If it's a false hit, we return to let the
   caller handle things.  */
 
void
sim_handle_breakpoint (sd, cpu, cia)
     SIM_DESC sd;
     sim_cpu *cpu;
     sim_cia cia;
{
  struct sim_breakpoint *bp;
 
  for (bp = STATE_BREAKPOINTS (sd); bp; bp = bp->next)
    if (bp->addr == CIA_ADDR (cia))
      break;
 
  if (!bp || !(bp->flags & SIM_BREAK_INSERTED))
    return;
 
  sim_engine_halt (sd, STATE_CPU (sd, 0), NULL, cia, sim_stopped, SIM_SIGTRAP);
}
 
/* Handler functions for simulator resume and suspend events. */
 
static SIM_RC
resume_handler (sd)
     SIM_DESC sd;
{
  struct sim_breakpoint *bp;
 
  for (bp = STATE_BREAKPOINTS (sd); bp; bp = bp->next)
    insert_breakpoint (sd, bp);
 
  return SIM_RC_OK;
}
 
static SIM_RC
suspend_handler (sd)
     SIM_DESC sd;
{
  struct sim_breakpoint *bp;
 
  for (bp = STATE_BREAKPOINTS (sd); bp; bp = bp->next)
    remove_breakpoint (sd, bp);
 
  return SIM_RC_OK;
}
 
/* Called from simulator module initialization.  */
 
SIM_RC
sim_break_install (sd)
     SIM_DESC sd;
{
  sim_module_add_resume_fn (sd, resume_handler);
  sim_module_add_suspend_fn (sd, suspend_handler);
 
  return SIM_RC_OK;
}
 
/* Install a breakpoint.  This is a user-function.  The breakpoint isn't
   actually installed here.  We just record it.  Resume_handler does the
   actual work.
*/
 
SIM_RC
sim_set_breakpoint (sd, addr)
     SIM_DESC sd;
     SIM_ADDR addr;
{
  struct sim_breakpoint *bp;
 
  for (bp = STATE_BREAKPOINTS (sd); bp; bp = bp->next)
    if (bp->addr == addr)
      return SIM_RC_DUPLICATE_BREAKPOINT; /* Already there */
    else
      break; /* FIXME: why not scan all bp's? */
 
  bp = ZALLOC (struct sim_breakpoint);
 
  bp->addr = addr;
  bp->next = STATE_BREAKPOINTS (sd);
  bp->flags = 0;
  STATE_BREAKPOINTS (sd) = bp;
 
  return SIM_RC_OK;
}
 
/* Delete a breakpoint.  All knowlege of the breakpoint is removed from the
   simulator.
*/
 
SIM_RC
sim_clear_breakpoint (sd, addr)
     SIM_DESC sd;
     SIM_ADDR addr;
{
  struct sim_breakpoint *bp, *bpprev;
 
  for (bp = STATE_BREAKPOINTS (sd), bpprev = NULL;
       bp;
       bpprev = bp, bp = bp->next)
    if (bp->addr == addr)
      break;
 
  if (!bp)
    return SIM_RC_UNKNOWN_BREAKPOINT;
 
  remove_breakpoint (sd, bp);
 
  if (bpprev)
    bpprev->next = bp->next;
  else
    STATE_BREAKPOINTS (sd) = NULL;
 
  zfree (bp);
 
  return SIM_RC_OK;
}
 
SIM_RC
sim_clear_all_breakpoints (sd)
     SIM_DESC sd;
{
  while (STATE_BREAKPOINTS (sd))
    sim_clear_breakpoint (sd, STATE_BREAKPOINTS (sd)->addr);
 
  return SIM_RC_OK;
}
 
SIM_RC
sim_enable_breakpoint (sd, addr)
     SIM_DESC sd;
     SIM_ADDR addr;
{
  struct sim_breakpoint *bp;
 
  for (bp = STATE_BREAKPOINTS (sd); bp; bp = bp->next)
    if (bp->addr == addr)
      break;
 
  if (!bp)
    return SIM_RC_UNKNOWN_BREAKPOINT;
 
  bp->flags &= ~SIM_BREAK_DISABLED;
 
  return SIM_RC_OK;
}
 
SIM_RC
sim_disable_breakpoint (sd, addr)
     SIM_DESC sd;
     SIM_ADDR addr;
{
  struct sim_breakpoint *bp;
 
  for (bp = STATE_BREAKPOINTS (sd); bp; bp = bp->next)
    if (bp->addr == addr)
      break;
 
  if (!bp)
    return SIM_RC_UNKNOWN_BREAKPOINT;
 
  bp->flags |= SIM_BREAK_DISABLED;
 
  return SIM_RC_OK;
}
 
SIM_RC
sim_enable_all_breakpoints (sd)
     SIM_DESC sd;
{
  struct sim_breakpoint *bp;
 
  for (bp = STATE_BREAKPOINTS (sd); bp; bp = bp->next)
    bp->flags &= ~SIM_BREAK_DISABLED;
 
  return SIM_RC_OK;
}
 
SIM_RC
sim_disable_all_breakpoints (sd)
     SIM_DESC sd;
{
  struct sim_breakpoint *bp;
 
  for (bp = STATE_BREAKPOINTS (sd); bp; bp = bp->next)
    bp->flags |= SIM_BREAK_DISABLED;
 
  return SIM_RC_OK;
}
 

Compare with Previous | Blame | View Log

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.