diff 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 diff
new file mode 100644
--- /dev/null
+++ b/packages/hal/common/current/src/bplist-dynamic.c
@@ -0,0 +1,238 @@
+//==========================================================================
+//
+//      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
+