summaryrefslogtreecommitdiffstats
path: root/sys/sparc64
diff options
context:
space:
mode:
authorjake <jake@FreeBSD.org>2001-08-20 23:50:08 +0000
committerjake <jake@FreeBSD.org>2001-08-20 23:50:08 +0000
commitcf997765b7d2f87010b3806ff9702e7945379849 (patch)
treeb34148ed180a13968f107398ed9d01576804aed1 /sys/sparc64
parentc5b148f1dd58e38e841a54b3181ac77ce0af1b7d (diff)
downloadFreeBSD-src-cf997765b7d2f87010b3806ff9702e7945379849.zip
FreeBSD-src-cf997765b7d2f87010b3806ff9702e7945379849.tar.gz
Add code for supporting hardware watch points.
Submitted by: tmm
Diffstat (limited to 'sys/sparc64')
-rw-r--r--sys/sparc64/include/watch.h41
-rw-r--r--sys/sparc64/sparc64/db_hwwatch.c214
2 files changed, 255 insertions, 0 deletions
diff --git a/sys/sparc64/include/watch.h b/sys/sparc64/include/watch.h
new file mode 100644
index 0000000..bd0e2f0
--- /dev/null
+++ b/sys/sparc64/include/watch.h
@@ -0,0 +1,41 @@
+/*-
+ * Copyright 2001 by Thomas Moestl <tmm@FreeBSD.org>. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
+ * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
+ * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * $FreeBSD$
+ */
+
+#ifndef _MACHINE_WATCH_H_
+#define _MACHINE_WATCH_H_
+
+int watch_phys_set_mask(vm_offset_t pa, u_long mask);
+int watch_phys_set(vm_offset_t pa, int sz);
+vm_offset_t watch_phys_get(int *bm);
+void watch_phys_clear(void);
+int watch_phys_active(void);
+int watch_virt_set_mask(vm_offset_t va, u_long mask);
+int watch_virt_set(vm_offset_t va, int sz);
+vm_offset_t watch_virt_get(int *bm);
+void watch_virt_clear(void);
+int watch_virt_active(void);
+
+#endif /* _MACHINE_WATCH_H_ */
diff --git a/sys/sparc64/sparc64/db_hwwatch.c b/sys/sparc64/sparc64/db_hwwatch.c
new file mode 100644
index 0000000..3d6e2c8
--- /dev/null
+++ b/sys/sparc64/sparc64/db_hwwatch.c
@@ -0,0 +1,214 @@
+/*-
+ * Copyright (c) 2001 Jake Burkholder.
+ * All rights reserved.
+ * Copyright 2001 by Thomas Moestl <tmm@FreeBSD.org>. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $FreeBSD$
+ */
+
+#include <sys/param.h>
+
+#include <vm/vm.h>
+
+#include <machine/asi.h>
+#include <machine/cpufunc.h>
+#include <machine/lsu.h>
+#include <machine/watch.h>
+
+#include <ddb/ddb.h>
+#include <ddb/db_access.h>
+#include <ddb/db_sym.h>
+#include <ddb/db_variables.h>
+#include <ddb/db_watch.h>
+
+int db_md_set_watchpoint __P((db_expr_t addr, db_expr_t size));
+int db_md_clr_watchpoint __P((db_expr_t addr, db_expr_t size));
+void db_md_list_watchpoints __P((void));
+
+static void db_watch_print(vm_offset_t wp, int bm);
+
+int
+watch_phys_set_mask(vm_offset_t pa, u_long mask)
+{
+ u_long lsucr;
+
+ stxa(AA_DMMU_PWPR, ASI_DMMU, pa & (((2UL << 38) - 1) << 3));
+ lsucr = ldxa(0, ASI_LSU_CTL_REG);
+ lsucr = ((lsucr | LSU_PW) & ~LSU_PM_MASK) |
+ (mask << LSU_PM_SHIFT);
+ stxa(0, ASI_LSU_CTL_REG, lsucr);
+ return (0);
+}
+
+int
+watch_phys_set(vm_offset_t pa, int sz)
+{
+ u_long off;
+
+ off = (u_long)pa & 7;
+ /* Test for misaligned watch points. */
+ if (off + sz > 8)
+ return (-1);
+ return (watch_phys_set_mask(pa, ((1 << sz) - 1) << off));
+}
+
+vm_offset_t
+watch_phys_get(int *bm)
+{
+ u_long pa;
+ u_long lsucr;
+
+ if (!watch_phys_active())
+ return (0);
+
+ pa = ldxa(AA_DMMU_PWPR, ASI_DMMU);
+ lsucr = ldxa(0, ASI_LSU_CTL_REG);
+ *bm = (lsucr & LSU_PM_MASK) >> LSU_PM_SHIFT;
+
+ return ((vm_offset_t)pa);
+}
+
+void
+watch_phys_clear()
+{
+ stxa(0, ASI_LSU_CTL_REG,
+ ldxa(0, ASI_LSU_CTL_REG) & ~LSU_PW);
+}
+
+int
+watch_phys_active()
+{
+
+ return (ldxa(0, ASI_LSU_CTL_REG) & LSU_PW);
+}
+
+int
+watch_virt_set_mask(vm_offset_t va, u_long mask)
+{
+ u_long lsucr;
+
+ stxa(AA_DMMU_VWPR, ASI_DMMU, va & (((2UL << 41) - 1) << 3));
+ lsucr = ldxa(0, ASI_LSU_CTL_REG);
+ lsucr = ((lsucr | LSU_VW) & ~LSU_VM_MASK) |
+ (mask << LSU_VM_SHIFT);
+ stxa(0, ASI_LSU_CTL_REG, lsucr);
+ return (0);
+}
+
+int
+watch_virt_set(vm_offset_t va, int sz)
+{
+ u_long off;
+
+ off = (u_long)va & 7;
+ /* Test for misaligned watch points. */
+ if (off + sz > 8)
+ return (-1);
+ return (watch_virt_set_mask(va, ((1 << sz) - 1) << off));
+}
+
+vm_offset_t
+watch_virt_get(int *bm)
+{
+ u_long va;
+ u_long lsucr;
+
+ if (!watch_virt_active())
+ return (0);
+
+ va = ldxa(AA_DMMU_VWPR, ASI_DMMU);
+ lsucr = ldxa(0, ASI_LSU_CTL_REG);
+ *bm = (lsucr & LSU_VM_MASK) >> LSU_VM_SHIFT;
+
+ return ((vm_offset_t)va);
+}
+
+void
+watch_virt_clear()
+{
+ stxa(0, ASI_LSU_CTL_REG,
+ ldxa(0, ASI_LSU_CTL_REG) & ~LSU_VW);
+}
+
+int
+watch_virt_active()
+{
+
+ return (ldxa(0, ASI_LSU_CTL_REG) & LSU_VW);
+}
+
+int
+db_md_set_watchpoint(db_expr_t addr, db_expr_t size)
+{
+ int dummy;
+
+ if (watch_virt_active()) {
+ db_printf("Overwriting previously active watch point at "
+ "0x%lx\n", watch_virt_get(&dummy));
+ }
+ return (watch_virt_set(addr, size));
+}
+
+int
+db_md_clr_watchpoint(db_expr_t addr, db_expr_t size)
+{
+
+ watch_virt_clear();
+ return (0);
+}
+
+void
+db_watch_print(vm_offset_t wp, int bm)
+{
+ int i;
+
+ db_printf("\tat 0x%lx, active bytes: ", (u_long)wp);
+ for (i = 0; i < 8; i++) {
+ if ((bm & (1 << i)) != 0)
+ db_printf("%d ", i);
+ }
+ if (bm == 0)
+ db_printf("none");
+ db_printf("\n");
+}
+
+void
+db_md_list_watchpoints(void)
+{
+ vm_offset_t wp;
+ int bm;
+
+ db_printf("Physical address watchpoint:\n");
+ if (watch_phys_active()) {
+ wp = watch_phys_get(&bm);
+ db_watch_print(wp, bm);
+ } else
+ db_printf("\tnot active.\n");
+ db_printf("Virtual address watchpoint:\n");
+ if (watch_virt_active()) {
+ wp = watch_virt_get(&bm);
+ db_watch_print(wp, bm);
+ } else
+ db_printf("\tnot active.\n");
+}
OpenPOWER on IntegriCloud