view packages/hal/common/current/src/bplist-dynamic.c @ 112:02ea4320376c ecos-sw-2000-07-21

Merge from eCos master repository on 2000-07-21-21:01:39-BST
author jlarmour
date Fri, 21 Jul 2000 21:34:11 +0000
parents
children 5ad2b71d525e
line wrap: on
line source

//==========================================================================
//
//      bplist-dynamic.c
//
//      Dynamic breakpoint list.
//      Currently only statically allocated.  (ie NO_MALLOC is assumed)
//
//==========================================================================
//####COPYRIGHTBEGIN####
//                                                                          
// -------------------------------------------                              
// The contents of this file are subject to the Red Hat eCos Public License 
// Version 1.1 (the "License"); you may not use this file except in         
// compliance with the License.  You may obtain a copy of the License at    
// http://www.redhat.com/                                                   
//                                                                          
// Software distributed under the License is distributed on an "AS IS"      
// basis, WITHOUT WARRANTY OF ANY KIND, either express or implied.  See the 
// License for the specific language governing rights and limitations under 
// the License.                                                             
//                                                                          
// The Original Code is eCos - Embedded Configurable Operating System,      
// released September 30, 1998.                                             
//                                                                          
// The Initial Developer of the Original Code is Red Hat.                   
// Portions created by Red Hat are                                          
// Copyright (C) 1998, 1999, 2000 Red Hat, Inc.                             
// All Rights Reserved.                                                     
// -------------------------------------------                              
//                                                                          
//####COPYRIGHTEND####
//==========================================================================
//#####DESCRIPTIONBEGIN####
//
// Author(s):    
// Contributors: dmoseley
// Date:         2000-07-11
// Purpose:      Dynamic breakpoint list.
// Description:  
//               
//
//####DESCRIPTIONEND####
//
//=========================================================================

#include <cyg/hal/hal_stub.h>

#ifdef CYGDBG_HAL_DEBUG_GDB_INCLUDE_STUBS

#if defined(CYGNUM_HAL_BREAKPOINT_LIST_SIZE) && (CYGNUM_HAL_BREAKPOINT_LIST_SIZE > 0)

/*
 * A simple target breakpoint list without using malloc.
 * To use this package, you must define HAL_BREAKINST_SIZE to be the size
 * in bytes of a trap instruction (max if there's more than one),
 * HAL_BREAKINST to the opcode value of the instruction, and
 * HAL_BREAKINST_TYPE to be the type necessary to hold the opcode value.
 */

struct breakpoint_list {
  target_register_t  addr;
  char old_contents [HAL_BREAKINST_SIZE];
  struct breakpoint_list *next;
  char in_memory;
} *breakpoint_list = NULL;

static HAL_BREAKINST_TYPE break_inst = HAL_BREAKINST;
static void *_break_inst = &break_inst;

static struct breakpoint_list bp_list [CYGNUM_HAL_BREAKPOINT_LIST_SIZE];
static struct breakpoint_list *free_bp_list = NULL;
static int curr_bp_num = 0;

int
__set_breakpoint (target_register_t addr)
{
  struct breakpoint_list **addent = &breakpoint_list;
  struct breakpoint_list *l = breakpoint_list;
  struct breakpoint_list *newent;

  while (l != NULL && l->addr < addr)
    {
      addent = &l->next;
      l =  l->next;
    }

  if (l != NULL && l->addr == addr)
    return 2;

  if (free_bp_list != NULL)
    {
      newent = free_bp_list;
      free_bp_list = free_bp_list->next;
    }
  else
    {
      if (curr_bp_num < CYGNUM_HAL_BREAKPOINT_LIST_SIZE)
	{
	  newent = &bp_list[curr_bp_num++];
	}
      else
	{
	  return 1;
	}
    }

  newent->addr = addr;
  newent->in_memory = 0;
  newent->next = l;
  *addent = newent;
  return 0;
}

int
__remove_breakpoint (target_register_t addr)
{
  struct breakpoint_list *l = breakpoint_list;
  struct breakpoint_list *prev = NULL;

  while (l != NULL && l->addr < addr)
    {
      prev = l;
      l = l->next;
    }

  if ((l == NULL) || (l->addr != addr))
    return 1;

  if (l->in_memory)
    {
      __write_mem_safe (&l->old_contents[0],
			(void*)l->addr,
			sizeof (l->old_contents));
    }

  if (prev == NULL)
    breakpoint_list = l->next;
  else
    prev->next = l->next;

  l->next = free_bp_list;
  free_bp_list = l;

  return 0;
}

void
__install_breakpoint_list (void)
{
  struct breakpoint_list *l = breakpoint_list;

  while (l != NULL)
    {
      if (! l->in_memory)
	{
	  int len = sizeof (l->old_contents);
	  if (__read_mem_safe (&l->old_contents[0], (void*)l->addr, len) == len)
	    {
	      if (__write_mem_safe (_break_inst, (void*)l->addr, len) == len)
		{
		  l->in_memory = 1;
		}
	    }

	}
      l = l->next;
    }
  flush_i_cache ();
}

void
__clear_breakpoint_list ()
{
  struct breakpoint_list *l = breakpoint_list;

  while (l != NULL)
    {
      if (l->in_memory)
	{
	  int len = sizeof (l->old_contents);
	  if (__write_mem_safe (&l->old_contents[0], (void*)l->addr, len) == len)
	    {
	      l->in_memory = 0;
	    }
	}
      l = l->next;
    }
  flush_i_cache ();
}

int
__display_breakpoint_list (void (*print_func)(target_register_t))
{
  struct breakpoint_list *l = breakpoint_list;

  while (l != NULL)
    {
      print_func(l->addr);
      l = l->next;
    }

  return 0;
}

#else  // (CYGNUM_HAL_BREAKPOINT_LIST_SIZE == 0) or UNDEFINED

#include <cyg/hal/hal_stub.h>           // Our header

int
__set_breakpoint (target_register_t addr)
{
  return 1;
}

int
__remove_breakpoint (target_register_t addr)
{
  return 1;
}

void
__install_breakpoint_list (void)
{
}

void
__clear_breakpoint_list (void)
{
}

int
__display_breakpoint_list (void (*print_func)(target_register_t))
{
}
#endif // (CYGNUM_HAL_BREAKPOINT_LIST_SIZE > 0)

#endif // CYGDBG_HAL_DEBUG_GDB_INCLUDE_STUBS