helper/jim-nvp: comply with coding style [2/2]
[fw/openocd] / src / target / arm_cti.c
index 75169b2eee33277647391a755615b15a7247965f..30212cbf4e2867b57d0e5e0144b30617538965e5 100644 (file)
 #include "target/arm_cti.h"
 #include "target/target.h"
 #include "helper/time_support.h"
+#include "helper/list.h"
+#include "helper/command.h"
 
 struct arm_cti {
-       uint32_t base;
-       struct adiv5_ap *ap;
+       struct list_head lh;
+       char *name;
+       struct adiv5_mem_ap_spot spot;
 };
 
-struct arm_cti *arm_cti_create(struct adiv5_ap *ap, uint32_t base)
+static LIST_HEAD(all_cti);
+
+const char *arm_cti_name(struct arm_cti *self)
+{
+       return self->name;
+}
+
+struct arm_cti *cti_instance_by_jim_obj(Jim_Interp *interp, Jim_Obj *o)
 {
-       struct arm_cti *self = calloc(1, sizeof(struct arm_cti));
-       if (!self)
-               return NULL;
+       struct arm_cti *obj = NULL;
+       const char *name;
+       bool found = false;
+
+       name = Jim_GetString(o, NULL);
+
+       list_for_each_entry(obj, &all_cti, lh) {
+               if (!strcmp(name, obj->name)) {
+                       found = true;
+                       break;
+               }
+       }
 
-       self->base = base;
-       self->ap = ap;
-       return self;
+       if (found)
+               return obj;
+       return NULL;
 }
 
 static int arm_cti_mod_reg_bits(struct arm_cti *self, unsigned int reg, uint32_t mask, uint32_t value)
 {
+       struct adiv5_ap *ap = dap_ap(self->spot.dap, self->spot.ap_num);
        uint32_t tmp;
 
        /* Read register */
-       int retval = mem_ap_read_atomic_u32(self->ap, self->base + reg, &tmp);
+       int retval = mem_ap_read_atomic_u32(ap, self->spot.base + reg, &tmp);
        if (ERROR_OK != retval)
                return retval;
 
@@ -59,26 +79,28 @@ static int arm_cti_mod_reg_bits(struct arm_cti *self, unsigned int reg, uint32_t
        tmp |= value & mask;
 
        /* write new value */
-       return mem_ap_write_atomic_u32(self->ap, self->base + reg, tmp);
+       return mem_ap_write_atomic_u32(ap, self->spot.base + reg, tmp);
 }
 
 int arm_cti_enable(struct arm_cti *self, bool enable)
 {
+       struct adiv5_ap *ap = dap_ap(self->spot.dap, self->spot.ap_num);
        uint32_t val = enable ? 1 : 0;
 
-       return mem_ap_write_atomic_u32(self->ap, self->base + CTI_CTR, val);
+       return mem_ap_write_atomic_u32(ap, self->spot.base + CTI_CTR, val);
 }
 
 int arm_cti_ack_events(struct arm_cti *self, uint32_t event)
 {
+       struct adiv5_ap *ap = dap_ap(self->spot.dap, self->spot.ap_num);
        int retval;
        uint32_t tmp;
 
-       retval = mem_ap_write_atomic_u32(self->ap, self->base + CTI_INACK, event);
+       retval = mem_ap_write_atomic_u32(ap, self->spot.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);
+                       retval = mem_ap_read_atomic_u32(ap, self->spot.base + CTI_TROUT_STATUS, &tmp);
                        if (retval != ERROR_OK)
                                break;
                        if ((tmp & event) == 0)
@@ -112,15 +134,19 @@ int arm_cti_ungate_channel(struct arm_cti *self, uint32_t channel)
 
 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);
+       struct adiv5_ap *ap = dap_ap(self->spot.dap, self->spot.ap_num);
+
+       return mem_ap_write_atomic_u32(ap, self->spot.base + reg, value);
 }
 
 int arm_cti_read_reg(struct arm_cti *self, unsigned int reg, uint32_t *p_value)
 {
+       struct adiv5_ap *ap = dap_ap(self->spot.dap, self->spot.ap_num);
+
        if (p_value == NULL)
                return ERROR_COMMAND_ARGUMENT_INVALID;
 
-       return mem_ap_read_atomic_u32(self->ap, self->base + reg, p_value);
+       return mem_ap_read_atomic_u32(ap, self->spot.base + reg, p_value);
 }
 
 int arm_cti_pulse_channel(struct arm_cti *self, uint32_t channel)
@@ -146,3 +172,409 @@ int arm_cti_clear_channel(struct arm_cti *self, uint32_t channel)
 
        return arm_cti_write_reg(self, CTI_APPCLEAR, CTI_CHNL(channel));
 }
+
+static uint32_t cti_regs[28];
+
+static const struct {
+       uint32_t offset;
+       const char *label;
+       uint32_t *p_val;
+} cti_names[] = {
+       { CTI_CTR,              "CTR",          &cti_regs[0] },
+       { CTI_GATE,             "GATE",         &cti_regs[1] },
+       { CTI_INEN0,    "INEN0",        &cti_regs[2] },
+       { CTI_INEN1,    "INEN1",        &cti_regs[3] },
+       { CTI_INEN2,    "INEN2",        &cti_regs[4] },
+       { CTI_INEN3,    "INEN3",        &cti_regs[5] },
+       { CTI_INEN4,    "INEN4",        &cti_regs[6] },
+       { CTI_INEN5,    "INEN5",        &cti_regs[7] },
+       { CTI_INEN6,    "INEN6",        &cti_regs[8] },
+       { CTI_INEN7,    "INEN7",        &cti_regs[9] },
+       { CTI_INEN8,    "INEN8",        &cti_regs[10] },
+       { CTI_OUTEN0,   "OUTEN0",       &cti_regs[11] },
+       { CTI_OUTEN1,   "OUTEN1",       &cti_regs[12] },
+       { CTI_OUTEN2,   "OUTEN2",       &cti_regs[13] },
+       { CTI_OUTEN3,   "OUTEN3",       &cti_regs[14] },
+       { CTI_OUTEN4,   "OUTEN4",       &cti_regs[15] },
+       { CTI_OUTEN5,   "OUTEN5",       &cti_regs[16] },
+       { CTI_OUTEN6,   "OUTEN6",       &cti_regs[17] },
+       { CTI_OUTEN7,   "OUTEN7",       &cti_regs[18] },
+       { CTI_OUTEN8,   "OUTEN8",       &cti_regs[19] },
+       { CTI_TRIN_STATUS,      "TRIN", &cti_regs[20] },
+       { CTI_TROUT_STATUS,     "TROUT", &cti_regs[21] },
+       { CTI_CHIN_STATUS,      "CHIN", &cti_regs[22] },
+       { CTI_CHOU_STATUS,      "CHOUT", &cti_regs[23] },
+       { CTI_APPSET,   "APPSET",       &cti_regs[24] },
+       { CTI_APPCLEAR, "APPCLR",       &cti_regs[25] },
+       { CTI_APPPULSE, "APPPULSE",     &cti_regs[26] },
+       { CTI_INACK,    "INACK",        &cti_regs[27] },
+};
+
+static int cti_find_reg_offset(const char *name)
+{
+       unsigned int i;
+
+       for (i = 0; i < ARRAY_SIZE(cti_names); i++) {
+               if (!strcmp(name, cti_names[i].label))
+                       return cti_names[i].offset;
+       }
+
+       LOG_ERROR("unknown CTI register %s", name);
+       return -1;
+}
+
+int arm_cti_cleanup_all(void)
+{
+       struct arm_cti *obj, *tmp;
+
+       list_for_each_entry_safe(obj, tmp, &all_cti, lh) {
+               free(obj->name);
+               free(obj);
+       }
+
+       return ERROR_OK;
+}
+
+COMMAND_HANDLER(handle_cti_dump)
+{
+       struct arm_cti *cti = CMD_DATA;
+       struct adiv5_ap *ap = dap_ap(cti->spot.dap, cti->spot.ap_num);
+       int retval = ERROR_OK;
+
+       for (int i = 0; (retval == ERROR_OK) && (i < (int)ARRAY_SIZE(cti_names)); i++)
+               retval = mem_ap_read_u32(ap,
+                               cti->spot.base + cti_names[i].offset, cti_names[i].p_val);
+
+       if (retval == ERROR_OK)
+               retval = dap_run(ap->dap);
+
+       if (retval != ERROR_OK)
+               return JIM_ERR;
+
+       for (int i = 0; i < (int)ARRAY_SIZE(cti_names); i++)
+               command_print(CMD, "%8.8s (0x%04"PRIx32") 0x%08"PRIx32,
+                               cti_names[i].label, cti_names[i].offset, *cti_names[i].p_val);
+
+       return JIM_OK;
+}
+
+COMMAND_HANDLER(handle_cti_enable)
+{
+       struct arm_cti *cti = CMD_DATA;
+       bool on_off;
+
+       if (CMD_ARGC != 1)
+               return ERROR_COMMAND_SYNTAX_ERROR;
+
+       COMMAND_PARSE_ON_OFF(CMD_ARGV[0], on_off);
+
+       return arm_cti_enable(cti, on_off);
+}
+
+COMMAND_HANDLER(handle_cti_testmode)
+{
+       struct arm_cti *cti = CMD_DATA;
+       bool on_off;
+
+       if (CMD_ARGC != 1)
+               return ERROR_COMMAND_SYNTAX_ERROR;
+
+       COMMAND_PARSE_ON_OFF(CMD_ARGV[0], on_off);
+
+       return arm_cti_write_reg(cti, 0xf00, on_off ? 0x1 : 0x0);
+}
+
+COMMAND_HANDLER(handle_cti_write)
+{
+       struct arm_cti *cti = CMD_DATA;
+       int offset;
+       uint32_t value;
+
+       if (CMD_ARGC != 2)
+               return ERROR_COMMAND_SYNTAX_ERROR;
+
+       offset = cti_find_reg_offset(CMD_ARGV[0]);
+       if (offset < 0)
+               return ERROR_FAIL;
+
+       COMMAND_PARSE_NUMBER(u32, CMD_ARGV[1], value);
+
+       return arm_cti_write_reg(cti, offset, value);
+}
+
+COMMAND_HANDLER(handle_cti_read)
+{
+       struct arm_cti *cti = CMD_DATA;
+       int offset;
+       int retval;
+       uint32_t value;
+
+       if (CMD_ARGC != 1)
+               return ERROR_COMMAND_SYNTAX_ERROR;
+
+       offset = cti_find_reg_offset(CMD_ARGV[0]);
+       if (offset < 0)
+               return ERROR_FAIL;
+
+       retval = arm_cti_read_reg(cti, offset, &value);
+       if (retval != ERROR_OK)
+               return retval;
+
+       command_print(CMD, "0x%08"PRIx32, value);
+
+       return ERROR_OK;
+}
+
+COMMAND_HANDLER(handle_cti_ack)
+{
+       struct arm_cti *cti = CMD_DATA;
+       uint32_t event;
+
+       if (CMD_ARGC != 1)
+               return ERROR_COMMAND_SYNTAX_ERROR;
+
+       COMMAND_PARSE_NUMBER(u32, CMD_ARGV[0], event);
+
+       int retval = arm_cti_ack_events(cti, 1 << event);
+
+
+       if (retval != ERROR_OK)
+               return retval;
+
+       return ERROR_OK;
+}
+
+COMMAND_HANDLER(handle_cti_channel)
+{
+       struct arm_cti *cti = CMD_DATA;
+       int retval = ERROR_OK;
+       uint32_t ch_num;
+
+       if (CMD_ARGC != 2)
+               return ERROR_COMMAND_SYNTAX_ERROR;
+
+       COMMAND_PARSE_NUMBER(u32, CMD_ARGV[0], ch_num);
+
+       if (!strcmp(CMD_ARGV[1], "gate"))
+               retval = arm_cti_gate_channel(cti, ch_num);
+       else if (!strcmp(CMD_ARGV[1], "ungate"))
+               retval = arm_cti_ungate_channel(cti, ch_num);
+       else if (!strcmp(CMD_ARGV[1], "pulse"))
+               retval = arm_cti_pulse_channel(cti, ch_num);
+       else if (!strcmp(CMD_ARGV[1], "set"))
+               retval = arm_cti_set_channel(cti, ch_num);
+       else if (!strcmp(CMD_ARGV[1], "clear"))
+               retval = arm_cti_clear_channel(cti, ch_num);
+       else {
+               command_print(CMD, "Possible channel operations: gate|ungate|set|clear|pulse");
+               return ERROR_COMMAND_ARGUMENT_INVALID;
+       }
+
+       if (retval != ERROR_OK)
+               return retval;
+
+       return ERROR_OK;
+}
+
+static const struct command_registration cti_instance_command_handlers[] = {
+       {
+               .name  = "dump",
+               .mode  = COMMAND_EXEC,
+               .handler = handle_cti_dump,
+               .help  = "dump CTI registers",
+               .usage = "",
+       },
+       {
+               .name = "enable",
+               .mode = COMMAND_EXEC,
+               .handler = handle_cti_enable,
+               .help = "enable or disable the CTI",
+               .usage = "'on'|'off'",
+       },
+       {
+               .name = "testmode",
+               .mode = COMMAND_EXEC,
+               .handler = handle_cti_testmode,
+               .help = "enable or disable integration test mode",
+               .usage = "'on'|'off'",
+       },
+       {
+               .name = "write",
+               .mode = COMMAND_EXEC,
+               .handler = handle_cti_write,
+               .help = "write to a CTI register",
+               .usage = "register_name value",
+       },
+       {
+               .name = "read",
+               .mode = COMMAND_EXEC,
+               .handler = handle_cti_read,
+               .help = "read a CTI register",
+               .usage = "register_name",
+       },
+       {
+               .name = "ack",
+               .mode = COMMAND_EXEC,
+               .handler = handle_cti_ack,
+               .help = "acknowledge a CTI event",
+               .usage = "event",
+       },
+       {
+               .name = "channel",
+               .mode = COMMAND_EXEC,
+               .handler = handle_cti_channel,
+               .help = "do an operation on one CTI channel, possible operations: "
+                               "gate, ungate, set, clear and pulse",
+               .usage = "channel_number operation",
+       },
+       COMMAND_REGISTRATION_DONE
+};
+
+static int cti_configure(struct jim_getopt_info *goi, struct arm_cti *cti)
+{
+       /* parse config or cget options ... */
+       while (goi->argc > 0) {
+               int e = adiv5_jim_mem_ap_spot_configure(&cti->spot, goi);
+               if (e != JIM_OK)
+                       return e;
+       }
+
+       if (!cti->spot.dap) {
+               Jim_SetResultString(goi->interp, "-dap required when creating CTI", -1);
+               return JIM_ERR;
+       }
+
+       return JIM_OK;
+}
+static int cti_create(struct jim_getopt_info *goi)
+{
+       struct command_context *cmd_ctx;
+       static struct arm_cti *cti;
+       Jim_Obj *new_cmd;
+       Jim_Cmd *cmd;
+       const char *cp;
+       int e;
+
+       cmd_ctx = current_command_context(goi->interp);
+       assert(cmd_ctx != NULL);
+
+       if (goi->argc < 3) {
+               Jim_WrongNumArgs(goi->interp, 1, goi->argv, "?name? ..options...");
+               return JIM_ERR;
+       }
+       /* COMMAND */
+       jim_getopt_obj(goi, &new_cmd);
+       /* does this command exist? */
+       cmd = Jim_GetCommand(goi->interp, new_cmd, JIM_ERRMSG);
+       if (cmd) {
+               cp = Jim_GetString(new_cmd, NULL);
+               Jim_SetResultFormatted(goi->interp, "Command: %s Exists", cp);
+               return JIM_ERR;
+       }
+
+       /* Create it */
+       cti = calloc(1, sizeof(*cti));
+       if (cti == NULL)
+               return JIM_ERR;
+
+       adiv5_mem_ap_spot_init(&cti->spot);
+
+       /* Do the rest as "configure" options */
+       goi->isconfigure = 1;
+       e = cti_configure(goi, cti);
+       if (e != JIM_OK) {
+               free(cti);
+               return e;
+       }
+
+       cp = Jim_GetString(new_cmd, NULL);
+       cti->name = strdup(cp);
+
+       /* now - create the new cti name command */
+       const struct command_registration cti_subcommands[] = {
+               {
+                       .chain = cti_instance_command_handlers,
+               },
+               COMMAND_REGISTRATION_DONE
+       };
+       const struct command_registration cti_commands[] = {
+               {
+                       .name = cp,
+                       .mode = COMMAND_ANY,
+                       .help = "cti instance command group",
+                       .usage = "",
+                       .chain = cti_subcommands,
+               },
+               COMMAND_REGISTRATION_DONE
+       };
+       e = register_commands_with_data(cmd_ctx, NULL, cti_commands, cti);
+       if (ERROR_OK != e)
+               return JIM_ERR;
+
+       list_add_tail(&cti->lh, &all_cti);
+
+       return JIM_OK;
+}
+
+static int jim_cti_create(Jim_Interp *interp, int argc, Jim_Obj *const *argv)
+{
+       struct jim_getopt_info goi;
+       jim_getopt_setup(&goi, interp, argc - 1, argv + 1);
+       if (goi.argc < 2) {
+               Jim_WrongNumArgs(goi.interp, goi.argc, goi.argv,
+                       "<name> [<cti_options> ...]");
+               return JIM_ERR;
+       }
+       return cti_create(&goi);
+}
+
+static int jim_cti_names(Jim_Interp *interp, int argc, Jim_Obj *const *argv)
+{
+       struct arm_cti *obj;
+
+       if (argc != 1) {
+               Jim_WrongNumArgs(interp, 1, argv, "Too many parameters");
+               return JIM_ERR;
+       }
+       Jim_SetResult(interp, Jim_NewListObj(interp, NULL, 0));
+       list_for_each_entry(obj, &all_cti, lh) {
+               Jim_ListAppendElement(interp, Jim_GetResult(interp),
+                       Jim_NewStringObj(interp, obj->name, -1));
+       }
+       return JIM_OK;
+}
+
+
+static const struct command_registration cti_subcommand_handlers[] = {
+       {
+               .name = "create",
+               .mode = COMMAND_ANY,
+               .jim_handler = jim_cti_create,
+               .usage = "name '-chain-position' name [options ...]",
+               .help = "Creates a new CTI object",
+       },
+       {
+               .name = "names",
+               .mode = COMMAND_ANY,
+               .jim_handler = jim_cti_names,
+               .usage = "",
+               .help = "Lists all registered CTI objects by name",
+       },
+       COMMAND_REGISTRATION_DONE
+};
+
+static const struct command_registration cti_command_handlers[] = {
+       {
+               .name = "cti",
+               .mode = COMMAND_CONFIG,
+               .help = "CTI commands",
+               .chain = cti_subcommand_handlers,
+               .usage = "",
+       },
+       COMMAND_REGISTRATION_DONE
+};
+
+int cti_register_commands(struct command_context *cmd_ctx)
+{
+       return register_commands(cmd_ctx, NULL, cti_command_handlers);
+}