changeset 317:4882695334f2

HW watch/breakpoint support change
author msalter
date Thu, 29 Aug 2002 16:15:32 +0000
parents e17d1cf55283
children 5f33b08f9a93
files packages/hal/arm/iq80310/current/ChangeLog packages/hal/arm/iq80310/current/include/plf_stub.h packages/hal/arm/xscale/verde/current/ChangeLog packages/hal/arm/xscale/verde/current/include/plf_stub.h packages/hal/common/current/ChangeLog packages/hal/common/current/include/generic-stub.h packages/hal/common/current/include/hal_stub.h packages/hal/common/current/src/bplist-dynamic.c packages/hal/common/current/src/generic-stub.c packages/hal/frv/frv400/current/ChangeLog packages/hal/frv/frv400/current/include/plf_stub.h
diffstat 11 files changed, 251 insertions(+), 12 deletions(-) [+]
line wrap: on
line diff
--- a/packages/hal/arm/iq80310/current/ChangeLog
+++ b/packages/hal/arm/iq80310/current/ChangeLog
@@ -1,3 +1,8 @@
+2002-08-29  Mark Salter  <msalter@redhat.com>
+
+	* include/plf_stub.h: Add HAL_STUB_HW_BREAKPOINT_LIST_SIZE and
+	HAL_STUB_HW_WATCHPOINT_LIST_SIZE.
+
 2002-08-12  Mark Salter  <msalter@redhat.com>
 
 	* cdl/hal_arm_iq80310.cdl: Remove CYGSEM_REDBOOT_ARM_LINUX_BOOT ref.
--- a/packages/hal/arm/iq80310/current/include/plf_stub.h
+++ b/packages/hal/arm/iq80310/current/include/plf_stub.h
@@ -86,6 +86,9 @@ extern int   cyg_hal_plf_hw_breakpoint(i
 extern int   cyg_hal_plf_hw_watchpoint(int setflag, void *addr, int len, int type);
 extern int   cyg_hal_plf_is_stopped_by_hardware(void **paddr);
 
+#define HAL_STUB_HW_BREAKPOINT_LIST_SIZE 2
+#define HAL_STUB_HW_WATCHPOINT_LIST_SIZE 1
+
 #define HAL_STUB_HW_BREAKPOINT(f,a,l)      cyg_hal_plf_hw_breakpoint((f),(a),(l))
 #define HAL_STUB_HW_WATCHPOINT(f,a,l,t)    cyg_hal_plf_hw_watchpoint((f),(a),(l),(t))
 #define HAL_STUB_IS_STOPPED_BY_HARDWARE(p) cyg_hal_plf_is_stopped_by_hardware(&(p))
--- a/packages/hal/arm/xscale/verde/current/ChangeLog
+++ b/packages/hal/arm/xscale/verde/current/ChangeLog
@@ -1,3 +1,8 @@
+2002-08-29  Mark Salter  <msalter@redhat.com>
+
+	* include/plf_stub.h: Add HAL_STUB_HW_BREAKPOINT_LIST_SIZE and
+	HAL_STUB_HW_WATCHPOINT_LIST_SIZE.
+
 2002-08-12  Mark Salter  <msalter@redhat.com>
 
 	* cdl/hal_arm_xscale_verde.cdl: Remove CYGSEM_REDBOOT_ARM_LINUX_BOOT
--- a/packages/hal/arm/xscale/verde/current/include/plf_stub.h
+++ b/packages/hal/arm/xscale/verde/current/include/plf_stub.h
@@ -82,6 +82,9 @@ extern int   cyg_hal_plf_hw_breakpoint(i
 extern int   cyg_hal_plf_hw_watchpoint(int setflag, void *addr, int len, int type);
 extern int   cyg_hal_plf_is_stopped_by_hardware(void **paddr);
 
+#define HAL_STUB_HW_BREAKPOINT_LIST_SIZE 2
+#define HAL_STUB_HW_WATCHPOINT_LIST_SIZE 1
+
 #define HAL_STUB_HW_BREAKPOINT(f,a,l)      cyg_hal_plf_hw_breakpoint((f),(a),(l))
 #define HAL_STUB_HW_WATCHPOINT(f,a,l,t)    cyg_hal_plf_hw_watchpoint((f),(a),(l),(t))
 #define HAL_STUB_IS_STOPPED_BY_HARDWARE(p) cyg_hal_plf_is_stopped_by_hardware(&(p))
--- a/packages/hal/common/current/ChangeLog
+++ b/packages/hal/common/current/ChangeLog
@@ -1,3 +1,12 @@
+2002-08-29  Mark Salter  <msalter@redhat.com>
+
+	* include/generic-stub.h: Add defines for Z packet types.
+	* src/bplist-dynamic.c: Add support for deferred hardware breakpoint
+	and watchpoint insertion/deletion. This gets around gdb problem where
+	gdb tries accessing watched memory before removing watchpoint.
+	* src/generic-stub.c (__process_packet): Ditto.
+	* include/hal_stub.h: Ditto.
+
 2002-05-23  Jesper Skov  <jskov@redhat.com>
 
 	* cdl/hal.cdl: Don't build tests that are not applicable with the
--- a/packages/hal/common/current/include/generic-stub.h
+++ b/packages/hal/common/current/include/generic-stub.h
@@ -347,6 +347,13 @@ extern void __install_breakpoint_list (v
 extern void __clear_breakpoint_list (void);
 extern int __display_breakpoint_list (void (*print_func)(target_register_t));
 
+/* 'Z' packet types */
+#define ZTYPE_SW_BREAKPOINT        0
+#define ZTYPE_HW_BREAKPOINT        1
+#define ZTYPE_HW_WATCHPOINT_WRITE  2
+#define ZTYPE_HW_WATCHPOINT_READ   3
+#define ZTYPE_HW_WATCHPOINT_ACCESS 4
+
 #endif /* ASM */
 
 #ifdef __cplusplus
--- a/packages/hal/common/current/include/hal_stub.h
+++ b/packages/hal/common/current/include/hal_stub.h
@@ -212,6 +212,18 @@ extern int __set_breakpoint (target_regi
 #ifndef __remove_breakpoint
 extern int __remove_breakpoint (target_register_t addr, target_register_t len);
 #endif
+#ifndef __set_hw_breakpoint
+extern int __set_hw_breakpoint (target_register_t addr, target_register_t len);
+#endif
+#ifndef __remove_hw_breakpoint
+extern int __remove_hw_breakpoint (target_register_t addr, target_register_t len);
+#endif
+#ifndef __set_hw_watchpoint
+extern int __set_hw_watchpoint (target_register_t addr, target_register_t len, int ztype);
+#endif
+#ifndef __remove_hw_watchpoint
+extern int __remove_hw_watchpoint (target_register_t addr, target_register_t len, int ztype);
+#endif
 
 /* Install the standard set of trap handlers for the stub. */
 extern void __install_traps (void);
--- a/packages/hal/common/current/src/bplist-dynamic.c
+++ b/packages/hal/common/current/src/bplist-dynamic.c
@@ -167,6 +167,176 @@ int
   return 0;
 }
 
+#if defined(HAL_STUB_HW_BREAKPOINT_LIST_SIZE) && (HAL_STUB_HW_BREAKPOINT_LIST_SIZE > 0)
+#ifndef HAL_STUB_HW_BREAKPOINT
+#error "Must define HAL_STUB_HW_BREAKPOINT"
+#endif
+struct hw_breakpoint_list {
+  target_register_t  addr;
+  target_register_t  len;
+  char used;
+  char installed;
+};
+static struct hw_breakpoint_list hw_bp_list [HAL_STUB_HW_BREAKPOINT_LIST_SIZE];
+
+int
+__set_hw_breakpoint (target_register_t addr, target_register_t len)
+{
+  int i;
+
+  for (i = 0; i < HAL_STUB_HW_BREAKPOINT_LIST_SIZE; i++)
+    {
+      if (hw_bp_list[i].used == 0)
+	{
+	  hw_bp_list[i].addr = addr;
+	  hw_bp_list[i].len = len;
+	  hw_bp_list[i].used = 1;
+	  hw_bp_list[i].installed = 0;
+	  return 0;
+	}
+    }
+  return -1;
+}
+
+int
+__remove_hw_breakpoint (target_register_t addr, target_register_t len)
+{
+  int i;
+
+  for (i = 0; i < HAL_STUB_HW_BREAKPOINT_LIST_SIZE; i++)
+    {
+      if (hw_bp_list[i].used && hw_bp_list[i].addr == addr
+	  && hw_bp_list[i].len == len)
+	{
+	  if (hw_bp_list[i].installed)
+	    HAL_STUB_HW_BREAKPOINT(0, (void *)addr, (int)len);
+	  hw_bp_list[i].used = 0;
+	  return 0;
+	}
+    }
+  return -1;
+}
+
+static void
+__install_hw_breakpoint_list (void)
+{
+  int i;
+
+  for (i = 0; i < HAL_STUB_HW_BREAKPOINT_LIST_SIZE; i++)
+    {
+      if (hw_bp_list[i].used && hw_bp_list[i].installed == 0)
+	{
+	  HAL_STUB_HW_BREAKPOINT(1, (void *)hw_bp_list[i].addr,
+				 (int)hw_bp_list[i].len);
+	  hw_bp_list[i].installed = 1;
+	}
+    }
+}
+
+static void
+__clear_hw_breakpoint_list (void)
+{
+  int i;
+
+  for (i = 0; i < HAL_STUB_HW_BREAKPOINT_LIST_SIZE; i++)
+    {
+      if (hw_bp_list[i].used && hw_bp_list[i].installed)
+	{
+	  HAL_STUB_HW_BREAKPOINT(0, (void *)hw_bp_list[i].addr,
+				 (int)hw_bp_list[i].len);
+	  hw_bp_list[i].installed = 0;
+	}
+    }
+}
+#endif // HAL_STUB_HW_BREAKPOINT_LIST_SIZE
+
+#if defined(HAL_STUB_HW_WATCHPOINT_LIST_SIZE) && (HAL_STUB_HW_WATCHPOINT_LIST_SIZE > 0)
+#ifndef HAL_STUB_HW_WATCHPOINT
+#error "Must define HAL_STUB_HW_WATCHPOINT"
+#endif
+struct hw_watchpoint_list {
+  target_register_t  addr;
+  target_register_t  len;
+  int ztype;
+  char used;
+  char installed;
+};
+static struct hw_watchpoint_list hw_wp_list [HAL_STUB_HW_WATCHPOINT_LIST_SIZE];
+
+int
+__set_hw_watchpoint (target_register_t addr, target_register_t len, int ztype)
+{
+  int i;
+
+  for (i = 0; i < HAL_STUB_HW_WATCHPOINT_LIST_SIZE; i++)
+    {
+      if (hw_wp_list[i].used == 0)
+	{
+	  hw_wp_list[i].addr = addr;
+	  hw_wp_list[i].len = len;
+	  hw_wp_list[i].ztype = ztype;
+	  hw_wp_list[i].used = 1;
+	  hw_wp_list[i].installed = 0;
+	  return 0;
+	}
+    }
+  return -1;
+}
+
+int
+__remove_hw_watchpoint (target_register_t addr, target_register_t len, int ztype)
+{
+  int i;
+
+  for (i = 0; i < HAL_STUB_HW_WATCHPOINT_LIST_SIZE; i++)
+    {
+      if (hw_wp_list[i].used && hw_wp_list[i].addr == addr
+	  && hw_wp_list[i].len == len && hw_wp_list[i].ztype == ztype )
+	{
+	  if (hw_wp_list[i].installed)
+	    HAL_STUB_HW_WATCHPOINT(0, (void *)addr, (int)len, ztype);
+	  hw_wp_list[i].used = 0;
+	  return 0;
+	}
+    }
+  return -1;
+}
+
+static void
+__install_hw_watchpoint_list (void)
+{
+  int i;
+
+  for (i = 0; i < HAL_STUB_HW_WATCHPOINT_LIST_SIZE; i++)
+    {
+      if (hw_wp_list[i].used && hw_wp_list[i].installed == 0)
+	{
+	  HAL_STUB_HW_WATCHPOINT(1, (void *)hw_wp_list[i].addr,
+				 (int)hw_wp_list[i].len, hw_wp_list[i].ztype);
+	  hw_wp_list[i].installed = 1;
+	}
+    }
+}
+
+static void
+__clear_hw_watchpoint_list (void)
+{
+  int i;
+
+  for (i = 0; i < HAL_STUB_HW_WATCHPOINT_LIST_SIZE; i++)
+    {
+      if (hw_wp_list[i].used && hw_wp_list[i].installed)
+	{
+	  HAL_STUB_HW_WATCHPOINT(0, (void *)hw_wp_list[i].addr,
+				 (int)hw_wp_list[i].len, hw_wp_list[i].ztype);
+	  hw_wp_list[i].installed = 0;
+	}
+    }
+}
+#endif // HAL_STUB_HW_WATCHPOINT_LIST_SIZE
+
+
+
 void
 __install_breakpoint_list (void)
 {
@@ -188,6 +358,12 @@ void
 	}
       l = l->next;
     }
+#if defined(HAL_STUB_HW_BREAKPOINT_LIST_SIZE) && (HAL_STUB_HW_BREAKPOINT_LIST_SIZE > 0)
+  __install_hw_breakpoint_list();
+#endif
+#if defined(HAL_STUB_HW_WATCHPOINT_LIST_SIZE) && (HAL_STUB_HW_WATCHPOINT_LIST_SIZE > 0)
+  __install_hw_watchpoint_list();
+#endif
   HAL_ICACHE_SYNC();
 }
 
@@ -208,6 +384,12 @@ void
 	}
       l = l->next;
     }
+#if defined(HAL_STUB_HW_BREAKPOINT_LIST_SIZE) && (HAL_STUB_HW_BREAKPOINT_LIST_SIZE > 0)
+  __clear_hw_breakpoint_list();
+#endif
+#if defined(HAL_STUB_HW_WATCHPOINT_LIST_SIZE) && (HAL_STUB_HW_WATCHPOINT_LIST_SIZE > 0)
+  __clear_hw_watchpoint_list();
+#endif
   HAL_ICACHE_INVALIDATE_ALL();
 }
 
@@ -224,7 +406,6 @@ int
 
   return 0;
 }
-
 #else  // (CYGNUM_HAL_BREAKPOINT_LIST_SIZE == 0) or UNDEFINED
 
 #include <cyg/hal/hal_stub.h>           // Our header
--- a/packages/hal/common/current/src/generic-stub.c
+++ b/packages/hal/common/current/src/generic-stub.c
@@ -1523,7 +1523,7 @@ int
 
 		switch (ztype)
 		  {
-		    case 0:
+		    case ZTYPE_SW_BREAKPOINT:
 		      /* sw breakpoint */
 		      if (is_Z)
 			err = __set_breakpoint(addr,length);
@@ -1534,21 +1534,27 @@ int
 		      else
 			strcpy (__remcomOutBuffer, "E02");
 		      break;
-		    case 1:
-		      /* hw breakpoint */
-#ifdef HAL_STUB_HW_BREAKPOINT
-		      if (!HAL_STUB_HW_BREAKPOINT(is_Z, (void *)addr, length))
+		    case ZTYPE_HW_BREAKPOINT:
+#if defined(HAL_STUB_HW_BREAKPOINT_LIST_SIZE) && (HAL_STUB_HW_BREAKPOINT_LIST_SIZE > 0)
+		      if (is_Z)
+			err = __set_hw_breakpoint(addr, length);
+		      else
+			err = __remove_hw_breakpoint(addr, length);
+		      if (!err)
 			strcpy (__remcomOutBuffer, "OK");
 		      else
 #endif
 			strcpy (__remcomOutBuffer, "E02");
 		      break;
-		    case 2:
-		    case 3:
-		    case 4:
-		      /* hw watchpoint */
-#ifdef HAL_STUB_HW_WATCHPOINT
-		      if (!HAL_STUB_HW_WATCHPOINT(is_Z, (void *)addr, length, ztype))
+		    case ZTYPE_HW_WATCHPOINT_WRITE:
+		    case ZTYPE_HW_WATCHPOINT_READ:
+		    case ZTYPE_HW_WATCHPOINT_ACCESS:
+#if defined(HAL_STUB_HW_WATCHPOINT_LIST_SIZE) && (HAL_STUB_HW_WATCHPOINT_LIST_SIZE > 0)
+		      if (is_Z)
+			err = __set_hw_watchpoint(addr, length, ztype);
+		      else
+			err = __remove_hw_watchpoint(addr, length, ztype);
+		      if (!err)
 			strcpy (__remcomOutBuffer, "OK");
 		      else
 #endif
--- a/packages/hal/frv/frv400/current/ChangeLog
+++ b/packages/hal/frv/frv400/current/ChangeLog
@@ -1,3 +1,8 @@
+2002-08-29  Mark Salter  <msalter@redhat.com>
+
+	* include/plf_stub.h: Add HAL_STUB_HW_BREAKPOINT_LIST_SIZE and
+	HAL_STUB_HW_WATCHPOINT_LIST_SIZE.
+
 2002-05-07  Gary Thomas  <gthomas@redhat.com>
 
 	* cdl/hal_frv_frv400.cdl: 
--- a/packages/hal/frv/frv400/current/include/plf_stub.h
+++ b/packages/hal/frv/frv400/current/include/plf_stub.h
@@ -82,6 +82,9 @@ extern int   cyg_hal_plf_hw_breakpoint(i
 extern int   cyg_hal_plf_hw_watchpoint(int setflag, void *addr, int len, int type);
 extern int   cyg_hal_plf_is_stopped_by_hardware(void **paddr);
 
+#define HAL_STUB_HW_BREAKPOINT_LIST_SIZE 4
+#define HAL_STUB_HW_WATCHPOINT_LIST_SIZE 2
+
 #define HAL_STUB_HW_BREAKPOINT(f,a,l)      cyg_hal_plf_hw_breakpoint((f),(a),(l))
 #define HAL_STUB_HW_WATCHPOINT(f,a,l,t)    cyg_hal_plf_hw_watchpoint((f),(a),(l),(t))
 #define HAL_STUB_IS_STOPPED_BY_HARDWARE(p) cyg_hal_plf_is_stopped_by_hardware(&(p))