target: generic ARM CTI function wrapper 86/3986/3
authorMatthias Welwarsky <matthias.welwarsky@sysgo.com>
Sat, 19 Nov 2016 09:02:34 +0000 (10:02 +0100)
committerPaul Fertser <fercerpav@gmail.com>
Fri, 24 Feb 2017 09:13:52 +0000 (09:13 +0000)
Not specific to ARMv8, the Cross Trigger Interface
deserves an independent access wrapper.

Change-Id: I84f8faad15ed3515e0fff7f6cc5d1109ef91a869
Signed-off-by: Matthias Welwarsky <matthias.welwarsky@sysgo.com>
Reviewed-on: http://openocd.zylin.com/3986
Tested-by: jenkins
Reviewed-by: Paul Fertser <fercerpav@gmail.com>
src/target/Makefile.am
src/target/arm_cti.c [new file with mode: 0644]
src/target/arm_cti.h [new file with mode: 0644]

index e936d3f404bd447ebfe20ea9873140b98975bf1a..597070c4b86b0b4e4814fea10dc2face80694a07 100644 (file)
@@ -96,7 +96,8 @@ ARM_DEBUG_SRC = \
        %D%/etb.c \
        %D%/etm.c \
        $(OOCD_TRACE_FILES) \
-       %D%/etm_dummy.c
+       %D%/etm_dummy.c \
+       %D%/arm_cti.c
 
 AVR32_SRC = \
        %D%/avr32_ap7k.c \
@@ -205,6 +206,7 @@ INTEL_IA32_SRC = \
        %D%/nds32_v3m.h \
        %D%/nds32_aice.h \
        %D%/lakemont.h \
-       %D%/x86_32_common.h
+       %D%/x86_32_common.h \
+       %D%/arm_cti.h
 
 include %D%/openrisc/Makefile.am
diff --git a/src/target/arm_cti.c b/src/target/arm_cti.c
new file mode 100644 (file)
index 0000000..75169b2
--- /dev/null
@@ -0,0 +1,148 @@
+/***************************************************************************
+ *   Copyright (C) 2016 by Matthias Welwarsky                              *
+ *                                                                         *
+ *   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 of the License, 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.,                                       *
+ *                                                                         *
+ ***************************************************************************/
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <stdlib.h>
+#include <stdint.h>
+#include "target/arm_adi_v5.h"
+#include "target/arm_cti.h"
+#include "target/target.h"
+#include "helper/time_support.h"
+
+struct arm_cti {
+       uint32_t base;
+       struct adiv5_ap *ap;
+};
+
+struct arm_cti *arm_cti_create(struct adiv5_ap *ap, uint32_t base)
+{
+       struct arm_cti *self = calloc(1, sizeof(struct arm_cti));
+       if (!self)
+               return NULL;
+
+       self->base = base;
+       self->ap = ap;
+       return self;
+}
+
+static int arm_cti_mod_reg_bits(struct arm_cti *self, unsigned int reg, uint32_t mask, uint32_t value)
+{
+       uint32_t tmp;
+
+       /* Read register */
+       int retval = mem_ap_read_atomic_u32(self->ap, self->base + reg, &tmp);
+       if (ERROR_OK != retval)
+               return retval;
+
+       /* clear bitfield */
+       tmp &= ~mask;
+       /* put new value */
+       tmp |= value & mask;
+
+       /* write new value */
+       return mem_ap_write_atomic_u32(self->ap, self->base + reg, tmp);
+}
+
+int arm_cti_enable(struct arm_cti *self, bool enable)
+{
+       uint32_t val = enable ? 1 : 0;
+
+       return mem_ap_write_atomic_u32(self->ap, self->base + CTI_CTR, val);
+}
+
+int arm_cti_ack_events(struct arm_cti *self, uint32_t event)
+{
+       int retval;
+       uint32_t tmp;
+
+       retval = mem_ap_write_atomic_u32(self->ap, self->base + CTI_INACK, event);
+       if (retval == ERROR_OK) {
+               int64_t then = timeval_ms();
+               for (;;) {
+                       retval = mem_ap_read_atomic_u32(self->ap, self->base + CTI_TROUT_STATUS, &tmp);
+                       if (retval != ERROR_OK)
+                               break;
+                       if ((tmp & event) == 0)
+                               break;
+                       if (timeval_ms() > then + 1000) {
+                               LOG_ERROR("timeout waiting for target");
+                               retval = ERROR_TARGET_TIMEOUT;
+                               break;
+                       }
+               }
+       }
+
+       return retval;
+}
+
+int arm_cti_gate_channel(struct arm_cti *self, uint32_t channel)
+{
+       if (channel > 31)
+               return ERROR_COMMAND_ARGUMENT_INVALID;
+
+       return arm_cti_mod_reg_bits(self, CTI_GATE, CTI_CHNL(channel), 0);
+}
+
+int arm_cti_ungate_channel(struct arm_cti *self, uint32_t channel)
+{
+       if (channel > 31)
+               return ERROR_COMMAND_ARGUMENT_INVALID;
+
+       return arm_cti_mod_reg_bits(self, CTI_GATE, CTI_CHNL(channel), 0xFFFFFFFF);
+}
+
+int arm_cti_write_reg(struct arm_cti *self, unsigned int reg, uint32_t value)
+{
+       return mem_ap_write_atomic_u32(self->ap, self->base + reg, value);
+}
+
+int arm_cti_read_reg(struct arm_cti *self, unsigned int reg, uint32_t *p_value)
+{
+       if (p_value == NULL)
+               return ERROR_COMMAND_ARGUMENT_INVALID;
+
+       return mem_ap_read_atomic_u32(self->ap, self->base + reg, p_value);
+}
+
+int arm_cti_pulse_channel(struct arm_cti *self, uint32_t channel)
+{
+       if (channel > 31)
+               return ERROR_COMMAND_ARGUMENT_INVALID;
+
+       return arm_cti_write_reg(self, CTI_APPPULSE, CTI_CHNL(channel));
+}
+
+int arm_cti_set_channel(struct arm_cti *self, uint32_t channel)
+{
+       if (channel > 31)
+               return ERROR_COMMAND_ARGUMENT_INVALID;
+
+       return arm_cti_write_reg(self, CTI_APPSET, CTI_CHNL(channel));
+}
+
+int arm_cti_clear_channel(struct arm_cti *self, uint32_t channel)
+{
+       if (channel > 31)
+               return ERROR_COMMAND_ARGUMENT_INVALID;
+
+       return arm_cti_write_reg(self, CTI_APPCLEAR, CTI_CHNL(channel));
+}
diff --git a/src/target/arm_cti.h b/src/target/arm_cti.h
new file mode 100644 (file)
index 0000000..99724c4
--- /dev/null
@@ -0,0 +1,73 @@
+/***************************************************************************
+ *   Copyright (C) 2016 by Matthias Welwarsky                              *
+ *                                                                         *
+ *   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 of the License, 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.,                                       *
+ *                                                                         *
+ ***************************************************************************/
+
+#ifndef OPENOCD_TARGET_ARM_CTI_H
+#define OPENOCD_TARGET_ARM_CTI_H
+
+/*define CTI(cross trigger interface)*/
+#define CTI_CTR                                0x0
+#define CTI_INACK                      0x10
+#define CTI_APPSET                     0x14
+#define CTI_APPCLEAR           0x18
+#define CTI_APPPULSE           0x1C
+#define CTI_INEN0                      0x20
+#define CTI_INEN1                      0x24
+#define CTI_INEN2                      0x28
+#define CTI_INEN3                      0x2C
+#define CTI_INEN4                      0x30
+#define CTI_INEN5                      0x34
+#define CTI_INEN6                      0x38
+#define CTI_INEN7                      0x3C
+#define CTI_INEN(n)                    (0x20 + 4 * n)
+#define CTI_OUTEN0                     0xA0
+#define CTI_OUTEN1                     0xA4
+#define CTI_OUTEN2                     0xA8
+#define CTI_OUTEN3                     0xAC
+#define CTI_OUTEN4                     0xB0
+#define CTI_OUTEN5                     0xB4
+#define CTI_OUTEN6                     0xB8
+#define CTI_OUTEN7                     0xBC
+#define CTI_OUTEN(n)           (0xA0 + 4 * n)
+#define CTI_TRIN_STATUS                0x130
+#define CTI_TROUT_STATUS       0x134
+#define CTI_CHIN_STATUS                0x138
+#define CTI_CHOU_STATUS                0x13C
+#define CTI_GATE                       0x140
+#define CTI_UNLOCK                     0xFB0
+
+#define CTI_CHNL(x)                    (1 << x)
+#define CTI_TRIG_HALT          0
+#define CTI_TRIG_RESUME                1
+#define CTI_TRIG(n)                    (1 << CTI_TRIG_##n)
+
+/* forward-declare arm_cti struct */
+struct arm_cti;
+
+extern struct arm_cti *arm_cti_create(struct adiv5_ap *ap, uint32_t base);
+extern int arm_cti_enable(struct arm_cti *self, bool enable);
+extern int arm_cti_ack_events(struct arm_cti *self, uint32_t event);
+extern int arm_cti_gate_channel(struct arm_cti *self, uint32_t channel);
+extern int arm_cti_ungate_channel(struct arm_cti *self, uint32_t channel);
+extern int arm_cti_write_reg(struct arm_cti *self, unsigned int reg, uint32_t value);
+extern int arm_cti_read_reg(struct arm_cti *self, unsigned int reg, uint32_t *value);
+extern int arm_cti_pulse_channel(struct arm_cti *self, uint32_t channel);
+extern int arm_cti_set_channel(struct arm_cti *self, uint32_t channel);
+extern int arm_cti_clear_channel(struct arm_cti *self, uint32_t channel);
+
+#endif /* OPENOCD_TARGET_ARM_CTI_H */

Linking to existing account procedure

If you already have an account and want to add another login method you MUST first sign in with your existing account and then change URL to read https://review.openocd.org/login/?link to get to this page again but this time it'll work for linking. Thank you.

SSH host keys fingerprints

1024 SHA256:YKx8b7u5ZWdcbp7/4AeXNaqElP49m6QrwfXaqQGJAOk gerrit-code-review@openocd.zylin.com (DSA)
384 SHA256:jHIbSQa4REvwCFG4cq5LBlBLxmxSqelQPem/EXIrxjk gerrit-code-review@openocd.org (ECDSA)
521 SHA256:UAOPYkU9Fjtcao0Ul/Rrlnj/OsQvt+pgdYSZ4jOYdgs gerrit-code-review@openocd.org (ECDSA)
256 SHA256:A13M5QlnozFOvTllybRZH6vm7iSt0XLxbA48yfc2yfY gerrit-code-review@openocd.org (ECDSA)
256 SHA256:spYMBqEYoAOtK7yZBrcwE8ZpYt6b68Cfh9yEVetvbXg gerrit-code-review@openocd.org (ED25519)
+--[ED25519 256]--+
|=..              |
|+o..   .         |
|*.o   . .        |
|+B . . .         |
|Bo. = o S        |
|Oo.+ + =         |
|oB=.* = . o      |
| =+=.+   + E     |
|. .=o   . o      |
+----[SHA256]-----+
2048 SHA256:0Onrb7/PHjpo6iVZ7xQX2riKN83FJ3KGU0TvI0TaFG4 gerrit-code-review@openocd.zylin.com (RSA)