+COMMAND_HANDLER(jlink_handle_jlink_kickstart_command)
+{
+ uint32_t kickstart;
+
+ if (CMD_ARGC < 1)
+ {
+ jlink_config_kickstart_dump(CMD_CTX, &jlink_cfg);
+ return ERROR_OK;
+ }
+
+ COMMAND_PARSE_NUMBER(u32, CMD_ARGV[0], kickstart);
+
+ jlink_cfg.kickstart_power_on_jtag_pin_19 = kickstart;
+ return ERROR_OK;
+}
+
+COMMAND_HANDLER(jlink_handle_jlink_mac_address_command)
+{
+ uint8_t addr[6];
+ int i;
+ char *e;
+ const char *str;
+
+ if (CMD_ARGC < 1)
+ {
+ jlink_config_mac_address_dump(CMD_CTX, &jlink_cfg);
+ return ERROR_OK;
+ }
+
+ str = CMD_ARGV[0];
+
+ if ((strlen(str) != 17) || (str[2] != ':' || str[5] != ':' || str[8] != ':' ||
+ str[11] != ':' || str[14] != ':'))
+ {
+ command_print(CMD_CTX, "ethaddr miss format ff:ff:ff:ff:ff:ff");
+ return ERROR_COMMAND_SYNTAX_ERROR;
+ }
+
+ for (i = 5; i >= 0; i--)
+ {
+ addr[i] = strtoul(str, &e, 16);
+ str = e + 1;
+ }
+
+ if (!(addr[0] | addr[1] | addr[2] | addr[3] | addr[4] | addr[5]))
+ {
+ command_print(CMD_CTX, "invalid it's zero mac_address");
+ return ERROR_COMMAND_SYNTAX_ERROR;
+ }
+
+ if (!(0x01 & addr[0]))
+ {
+ command_print(CMD_CTX, "invalid it's a multicat mac_address");
+ return ERROR_COMMAND_SYNTAX_ERROR;
+ }
+
+ memcpy(jlink_cfg.mac_address, addr, sizeof(addr));
+
+ return ERROR_OK;
+}
+
+static int string_to_ip(const char *s, uint8_t *ip, int *pos)
+{
+ uint8_t lip[4];
+ char *e;
+ const char *s_save = s;
+ int i;
+
+ if (!s)
+ return -EINVAL;
+
+ for (i = 0; i < 4; i++) {
+ lip[i] = strtoul(s, &e, 10);
+
+ if (*e != '.' && i != 3)
+ return -EINVAL;
+
+ s = e + 1;
+ }
+
+ *pos = e - s_save;
+
+ memcpy(ip, lip, sizeof(lip));
+ return ERROR_OK;
+}
+
+static void cpy_ip(uint8_t *dst, uint8_t *src)
+{
+ int i, j;
+
+ for (i = 0, j = 3; i < 4; i++, j--)
+ dst[i] = src[j];
+}
+
+COMMAND_HANDLER(jlink_handle_jlink_ip_command)
+{
+ uint32_t ip_address;
+ uint32_t subnet_mask = 0;
+ int i, len;
+ int ret;
+ uint8_t subnet_bits = 24;
+
+ if (CMD_ARGC < 1)
+ {
+ jlink_config_ip_dump(CMD_CTX, &jlink_cfg);
+ return ERROR_OK;
+ }
+
+ ret = string_to_ip(CMD_ARGV[0], (uint8_t*)&ip_address, &i);
+ if (ret != ERROR_OK)
+ return ret;
+
+ len = strlen(CMD_ARGV[0]);
+
+ /* check for this format A.B.C.D/E */
+
+ if (i < len)
+ {
+ if (CMD_ARGV[0][i] != '/')
+ return ERROR_COMMAND_SYNTAX_ERROR;
+
+ COMMAND_PARSE_NUMBER(u8, CMD_ARGV[0] + i + 1, subnet_bits);
+ }
+ else
+ {
+ if (CMD_ARGC > 1)
+ {
+ ret = string_to_ip(CMD_ARGV[1], (uint8_t*)&subnet_mask, &i);
+ if (ret != ERROR_OK)
+ return ret;
+ }
+ }
+
+ if (!subnet_mask)
+ subnet_mask = (uint32_t)(subnet_bits < 32 ?
+ ((1ULL << subnet_bits) -1) : 0xffffffff);
+
+ cpy_ip(jlink_cfg.ip_address, (uint8_t*)&ip_address);
+ cpy_ip(jlink_cfg.subnet_mask, (uint8_t*)&subnet_mask);
+
+ return ERROR_OK;
+}
+
+COMMAND_HANDLER(jlink_handle_jlink_reset_command)
+{
+ memset(&jlink_cfg, 0xff, sizeof(jlink_cfg));
+ return ERROR_OK;
+}
+
+COMMAND_HANDLER(jlink_handle_jlink_save_command)
+{
+ if (!(jlink_caps & (1 << EMU_CAP_WRITE_CONFIG)))
+ {
+ command_print(CMD_CTX, "J-Link write emulator configuration not supported");
+ return ERROR_OK;
+ }
+
+ command_print(CMD_CTX, "The J-Link need to be unpluged and repluged ta have the config effective");
+ return jlink_set_config(&jlink_cfg);
+}
+
+COMMAND_HANDLER(jlink_handle_jlink_usb_address_command)
+{
+ uint32_t address;
+
+ if (CMD_ARGC < 1)
+ {
+ jlink_config_usb_address_dump(CMD_CTX, &jlink_cfg);
+ return ERROR_OK;
+ }
+
+ COMMAND_PARSE_NUMBER(u32, CMD_ARGV[0], address);
+
+ if (address > 0x3 && address != 0xff)
+ {
+ command_print(CMD_CTX, "USB Address must be between 0x00 and 0x03 or 0xff");
+ return ERROR_COMMAND_SYNTAX_ERROR;
+ }
+
+ jlink_cfg.usb_address = address;
+ return ERROR_OK;
+}
+
+COMMAND_HANDLER(jlink_handle_jlink_config_command)
+{
+ struct jlink_config cfg;
+ int ret = ERROR_OK;
+
+ if (CMD_ARGC == 0)
+ {
+ if (!(jlink_caps & (1 << EMU_CAP_READ_CONFIG)))
+ {
+ command_print(CMD_CTX, "J-Link read emulator configuration not supported");
+ goto exit;
+ }
+
+ ret = jlink_get_config(&cfg);
+
+ if ( ret != ERROR_OK)
+ command_print(CMD_CTX, "J-Link read emulator configuration failled");
+ else
+ jlink_config_dump(CMD_CTX, &jlink_cfg);
+ }
+
+exit:
+ return ret;
+}
+
+static const struct command_registration jlink_config_subcommand_handlers[] = {
+ {
+ .name = "kickstart",
+ .handler = &jlink_handle_jlink_kickstart_command,
+ .mode = COMMAND_EXEC,
+ .help = "set Kickstart power on JTAG-pin 19.",
+ .usage = "[val]",
+ },
+ {
+ .name = "mac_address",
+ .handler = &jlink_handle_jlink_mac_address_command,
+ .mode = COMMAND_EXEC,
+ .help = "set the MAC Address",
+ .usage = "[ff:ff:ff:ff:ff:ff]",
+ },
+ {
+ .name = "ip",
+ .handler = &jlink_handle_jlink_ip_command,
+ .mode = COMMAND_EXEC,
+ .help = "set the ip address of the J-Link Pro, "
+ "where A.B.C.D is the ip, "
+ "E the bit of the subnet mask, "
+ "F.G.H.I the subnet mask",
+ .usage = "[A.B.C.D[/E] [F.G.H.I]]",
+ },
+ {
+ .name = "reset",
+ .handler = &jlink_handle_jlink_reset_command,
+ .mode = COMMAND_EXEC,
+ .help = "reset the current config",
+ },
+ {
+ .name = "save",
+ .handler = &jlink_handle_jlink_save_command,
+ .mode = COMMAND_EXEC,
+ .help = "save the current config",
+ },
+ {
+ .name = "usb_address",
+ .handler = &jlink_handle_jlink_usb_address_command,
+ .mode = COMMAND_EXEC,
+ .help = "set the USB-Address, "
+ "This will change the product id",
+ .usage = "[0x00 to 0x03 or 0xff]",
+ },
+ COMMAND_REGISTRATION_DONE
+};
+