cmd: add missing usage var
[fw/openocd] / src / flash / nor / str9xpec.c
index 87a4b062520f1de8b85407eff73ace3d4710a06a..fc2ed3590f4dd772e910e2cc5913c1c636f08dfc 100644 (file)
 #include "config.h"
 #endif
 
-#include "str9xpec.h"
+#include "imp.h"
 #include <target/arm7_9_common.h>
 
 
+/* ISC commands */
+
+#define ISC_IDCODE                             0xFE
+#define ISC_MFG_READ                   0x4C
+#define ISC_CONFIGURATION              0x07
+#define ISC_ENABLE                             0x0C
+#define ISC_DISABLE                            0x0F
+#define ISC_NOOP                               0x10
+#define ISC_ADDRESS_SHIFT              0x11
+#define ISC_CLR_STATUS                 0x13
+#define ISC_PROGRAM                            0x20
+#define ISC_PROGRAM_SECURITY   0x22
+#define ISC_PROGRAM_UC                 0x23
+#define ISC_ERASE                              0x30
+#define ISC_READ                               0x50
+#define ISC_BLANK_CHECK                        0x60
+
+/* ISC_DEFAULT bit definitions */
+
+#define ISC_STATUS_SECURITY            0x40
+#define ISC_STATUS_INT_ERROR   0x30
+#define ISC_STATUS_MODE                        0x08
+#define ISC_STATUS_BUSY                        0x04
+#define ISC_STATUS_ERROR               0x03
+
+/* Option bytes definitions */
+
+#define STR9XPEC_OPT_CSMAPBIT          48
+#define STR9XPEC_OPT_LVDTHRESBIT       49
+#define STR9XPEC_OPT_LVDSELBIT         50
+#define STR9XPEC_OPT_LVDWARNBIT                51
+#define STR9XPEC_OPT_OTPBIT                    63
+
+enum str9xpec_status_codes
+{
+       STR9XPEC_INVALID_COMMAND = 1,
+       STR9XPEC_ISC_SUCCESS = 2,
+       STR9XPEC_ISC_DISABLED = 3,
+       STR9XPEC_ISC_INTFAIL = 32,
+};
+
+struct str9xpec_flash_controller
+{
+       struct jtag_tap *tap;
+       uint32_t *sector_bits;
+       int chain_pos;
+       int isc_enable;
+       uint8_t options[8];
+};
+
 static int str9xpec_erase_area(struct flash_bank *bank, int first, int last);
 static int str9xpec_set_address(struct flash_bank *bank, uint8_t sector);
 static int str9xpec_write_options(struct flash_bank *bank);
 
-int str9xpec_set_instr(struct jtag_tap *tap, uint32_t new_instr, tap_state_t end_state)
+static int str9xpec_set_instr(struct jtag_tap *tap, uint32_t new_instr, tap_state_t end_state)
 {
        if (tap == NULL) {
                return ERROR_TARGET_INVALID;
@@ -42,15 +92,15 @@ int str9xpec_set_instr(struct jtag_tap *tap, uint32_t new_instr, tap_state_t end
        {
                struct scan_field field;
 
-               field.tap = tap;
                field.num_bits = tap->ir_length;
-               field.out_value = calloc(DIV_ROUND_UP(field.num_bits, 8), 1);
-               buf_set_u32(field.out_value, 0, field.num_bits, new_instr);
+               void * t = calloc(DIV_ROUND_UP(field.num_bits, 8), 1);
+               field.out_value = t;
+               buf_set_u32(t, 0, field.num_bits, new_instr);
                field.in_value = NULL;
 
-               jtag_add_ir_scan(1, &field, end_state);
+               jtag_add_ir_scan(tap, &field, end_state);
 
-               free(field.out_value);
+               free(t);
        }
 
        return ERROR_OK;
@@ -64,13 +114,12 @@ static uint8_t str9xpec_isc_status(struct jtag_tap *tap)
        if (str9xpec_set_instr(tap, ISC_NOOP, TAP_IRPAUSE) != ERROR_OK)
                return ISC_STATUS_ERROR;
 
-       field.tap = tap;
        field.num_bits = 8;
        field.out_value = NULL;
        field.in_value = &status;
 
 
-       jtag_add_dr_scan(1, &field, jtag_set_end_state(TAP_IDLE));
+       jtag_add_dr_scan(tap, 1, &field, TAP_IDLE);
        jtag_execute_queue();
 
        LOG_DEBUG("status: 0x%2.2x", status);
@@ -152,13 +201,12 @@ static int str9xpec_read_config(struct flash_bank *bank)
        /* execute ISC_CONFIGURATION command */
        str9xpec_set_instr(tap, ISC_CONFIGURATION, TAP_IRPAUSE);
 
-       field.tap = tap;
        field.num_bits = 64;
        field.out_value = NULL;
        field.in_value = str9xpec_info->options;
 
 
-       jtag_add_dr_scan(1, &field, jtag_set_end_state(TAP_IDLE));
+       jtag_add_dr_scan(tap, 1, &field, TAP_IDLE);
        jtag_execute_queue();
 
        status = str9xpec_isc_status(tap);
@@ -244,8 +292,7 @@ FLASH_BANK_COMMAND_HANDLER(str9xpec_flash_bank_command)
 
        if (CMD_ARGC < 6)
        {
-               LOG_WARNING("incomplete flash_bank str9x configuration");
-               return ERROR_FLASH_BANK_INVALID;
+               return ERROR_COMMAND_SYNTAX_ERROR;
        }
 
        str9xpec_info = malloc(sizeof(struct str9xpec_flash_controller));
@@ -258,7 +305,8 @@ FLASH_BANK_COMMAND_HANDLER(str9xpec_flash_bank_command)
        arm7_9 = armv4_5->arch_info;
        jtag_info = &arm7_9->jtag_info;
 
-       str9xpec_info->tap = bank->target->tap;
+       /* The core is the next tap after the flash controller in the chain */
+       str9xpec_info->tap = jtag_tap_by_position(jtag_info->tap->abs_chain_position - 1);
        str9xpec_info->isc_enable = 0;
 
        str9xpec_build_block_list(bank);
@@ -300,21 +348,19 @@ static int str9xpec_blank_check(struct flash_bank *bank, int first, int last)
        /* execute ISC_BLANK_CHECK command */
        str9xpec_set_instr(tap, ISC_BLANK_CHECK, TAP_IRPAUSE);
 
-       field.tap = tap;
        field.num_bits = 64;
        field.out_value = buffer;
        field.in_value = NULL;
 
-       jtag_add_dr_scan(1, &field, jtag_set_end_state(TAP_IDLE));
+       jtag_add_dr_scan(tap, 1, &field, TAP_IDLE);
        jtag_add_sleep(40000);
 
        /* read blank check result */
-       field.tap = tap;
        field.num_bits = 64;
        field.out_value = NULL;
        field.in_value = buffer;
 
-       jtag_add_dr_scan(1, &field, TAP_IRPAUSE);
+       jtag_add_dr_scan(tap, 1, &field, TAP_IRPAUSE);
        jtag_execute_queue();
 
        status = str9xpec_isc_status(tap);
@@ -406,12 +452,11 @@ static int str9xpec_erase_area(struct flash_bank *bank, int first, int last)
        /* execute ISC_ERASE command */
        str9xpec_set_instr(tap, ISC_ERASE, TAP_IRPAUSE);
 
-       field.tap = tap;
        field.num_bits = 64;
        field.out_value = buffer;
        field.in_value = NULL;
 
-       jtag_add_dr_scan(1, &field, jtag_set_end_state(TAP_IDLE));
+       jtag_add_dr_scan(tap, 1, &field, TAP_IDLE);
        jtag_execute_queue();
 
        jtag_add_sleep(10);
@@ -467,12 +512,11 @@ static int str9xpec_lock_device(struct flash_bank *bank)
        str9xpec_set_instr(tap, ISC_NOOP, TAP_IRPAUSE);
 
        do {
-               field.tap = tap;
                field.num_bits = 8;
                field.out_value = NULL;
                field.in_value = &status;
 
-               jtag_add_dr_scan(1, &field, jtag_get_end_state());
+               jtag_add_dr_scan(tap, 1, &field, TAP_IDLE);
                jtag_execute_queue();
 
        } while (!(status & ISC_STATUS_BUSY));
@@ -548,17 +592,17 @@ static int str9xpec_set_address(struct flash_bank *bank, uint8_t sector)
        /* set flash controller address */
        str9xpec_set_instr(tap, ISC_ADDRESS_SHIFT, TAP_IRPAUSE);
 
-       field.tap = tap;
        field.num_bits = 8;
        field.out_value = &sector;
        field.in_value = NULL;
 
-       jtag_add_dr_scan(1, &field, jtag_get_end_state());
+       jtag_add_dr_scan(tap, 1, &field, TAP_IRPAUSE);
 
        return ERROR_OK;
 }
 
-static int str9xpec_write(struct flash_bank *bank, uint8_t *buffer, uint32_t offset, uint32_t count)
+static int str9xpec_write(struct flash_bank *bank, uint8_t *buffer,
+               uint32_t offset, uint32_t count)
 {
        struct str9xpec_flash_controller *str9xpec_info = bank->driver_priv;
        uint32_t dwords_remaining = (count / 8);
@@ -626,18 +670,18 @@ static int str9xpec_write(struct flash_bank *bank, uint8_t *buffer, uint32_t off
        {
                str9xpec_set_address(bank, str9xpec_info->sector_bits[i]);
 
-               dwords_remaining = dwords_remaining < (bank->sectors[i].size/8) ? dwords_remaining : (bank->sectors[i].size/8);
+               dwords_remaining = dwords_remaining < (bank->sectors[i].size/8)
+                               ? dwords_remaining : (bank->sectors[i].size/8);
 
                while (dwords_remaining > 0)
                {
                        str9xpec_set_instr(tap, ISC_PROGRAM, TAP_IRPAUSE);
 
-                       field.tap = tap;
                        field.num_bits = 64;
                        field.out_value = (buffer + bytes_written);
                        field.in_value = NULL;
 
-                       jtag_add_dr_scan(1, &field, jtag_set_end_state(TAP_IDLE));
+                       jtag_add_dr_scan(tap, 1, &field, TAP_IDLE);
 
                        /* small delay before polling */
                        jtag_add_sleep(50);
@@ -645,12 +689,11 @@ static int str9xpec_write(struct flash_bank *bank, uint8_t *buffer, uint32_t off
                        str9xpec_set_instr(tap, ISC_NOOP, TAP_IRPAUSE);
 
                        do {
-                               field.tap = tap;
                                field.num_bits = 8;
                                field.out_value = NULL;
                                field.in_value = scanbuf;
 
-                               jtag_add_dr_scan(1, &field, jtag_get_end_state());
+                               jtag_add_dr_scan(tap, 1, &field, TAP_IRPAUSE);
                                jtag_execute_queue();
 
                                status = buf_get_u32(scanbuf, 0, 8);
@@ -671,23 +714,17 @@ static int str9xpec_write(struct flash_bank *bank, uint8_t *buffer, uint32_t off
        if (bytes_remaining)
        {
                uint8_t last_dword[8] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
-               int i = 0;
 
-               while (bytes_remaining > 0)
-               {
-                       last_dword[i++] = *(buffer + bytes_written);
-                       bytes_remaining--;
-                       bytes_written++;
-               }
+               /* copy the last remaining bytes into the write buffer */
+               memcpy(last_dword, buffer+bytes_written, bytes_remaining);
 
                str9xpec_set_instr(tap, ISC_PROGRAM, TAP_IRPAUSE);
 
-               field.tap = tap;
                field.num_bits = 64;
                field.out_value = last_dword;
                field.in_value = NULL;
 
-               jtag_add_dr_scan(1, &field, jtag_set_end_state(TAP_IDLE));
+               jtag_add_dr_scan(tap, 1, &field, TAP_IDLE);
 
                /* small delay before polling */
                jtag_add_sleep(50);
@@ -695,12 +732,11 @@ static int str9xpec_write(struct flash_bank *bank, uint8_t *buffer, uint32_t off
                str9xpec_set_instr(tap, ISC_NOOP, TAP_IRPAUSE);
 
                do {
-                       field.tap = tap;
                        field.num_bits = 8;
                        field.out_value = NULL;
                        field.in_value = scanbuf;
 
-                       jtag_add_dr_scan(1, &field, jtag_get_end_state());
+                       jtag_add_dr_scan(tap, 1, &field, TAP_IRPAUSE);
                        jtag_execute_queue();
 
                        status = buf_get_u32(scanbuf, 0, 8);
@@ -749,12 +785,11 @@ COMMAND_HANDLER(str9xpec_handle_part_id_command)
 
        str9xpec_set_instr(tap, ISC_IDCODE, TAP_IRPAUSE);
 
-       field.tap = tap;
        field.num_bits = 32;
        field.out_value = NULL;
        field.in_value = buffer;
 
-       jtag_add_dr_scan(1, &field, jtag_set_end_state(TAP_IDLE));
+       jtag_add_dr_scan(tap, 1, &field, TAP_IDLE);
        jtag_execute_queue();
 
        idcode = buf_get_u32(buffer, 0, 32);
@@ -771,7 +806,7 @@ static int str9xpec_erase_check(struct flash_bank *bank)
        return str9xpec_blank_check(bank, 0, bank->num_sectors - 1);
 }
 
-static int str9xpec_info(struct flash_bank *bank, char *buf, int buf_size)
+static int get_str9xpec_info(struct flash_bank *bank, char *buf, int buf_size)
 {
        snprintf(buf, buf_size, "str9xpec flash driver info");
        return ERROR_OK;
@@ -784,8 +819,7 @@ COMMAND_HANDLER(str9xpec_handle_flash_options_read_command)
 
        if (CMD_ARGC < 1)
        {
-               command_print(CMD_CTX, "str9xpec options_read <bank>");
-               return ERROR_OK;
+               return ERROR_COMMAND_SYNTAX_ERROR;
        }
 
        struct flash_bank *bank;
@@ -866,12 +900,11 @@ static int str9xpec_write_options(struct flash_bank *bank)
        /* execute ISC_PROGRAM command */
        str9xpec_set_instr(tap, ISC_PROGRAM, TAP_IRPAUSE);
 
-       field.tap = tap;
        field.num_bits = 64;
        field.out_value = str9xpec_info->options;
        field.in_value = NULL;
 
-       jtag_add_dr_scan(1, &field, jtag_set_end_state(TAP_IDLE));
+       jtag_add_dr_scan(tap, 1, &field, TAP_IDLE);
 
        /* small delay before polling */
        jtag_add_sleep(50);
@@ -879,12 +912,11 @@ static int str9xpec_write_options(struct flash_bank *bank)
        str9xpec_set_instr(tap, ISC_NOOP, TAP_IRPAUSE);
 
        do {
-               field.tap = tap;
                field.num_bits = 8;
                field.out_value = NULL;
                field.in_value = &status;
 
-               jtag_add_dr_scan(1, &field, jtag_get_end_state());
+               jtag_add_dr_scan(tap, 1, &field, TAP_IRPAUSE);
                jtag_execute_queue();
 
        } while (!(status & ISC_STATUS_BUSY));
@@ -900,8 +932,7 @@ COMMAND_HANDLER(str9xpec_handle_flash_options_write_command)
 
        if (CMD_ARGC < 1)
        {
-               command_print(CMD_CTX, "str9xpec options_write <bank>");
-               return ERROR_OK;
+               return ERROR_COMMAND_SYNTAX_ERROR;
        }
 
        struct flash_bank *bank;
@@ -914,6 +945,10 @@ COMMAND_HANDLER(str9xpec_handle_flash_options_write_command)
        if ((status & ISC_STATUS_ERROR) != STR9XPEC_ISC_SUCCESS)
                return ERROR_FLASH_OPERATION_FAILED;
 
+       command_print(CMD_CTX, "str9xpec write options complete.\n"
+                       "INFO: a reset or power cycle is required "
+                       "for the new settings to take effect.");
+
        return ERROR_OK;
 }
 
@@ -923,8 +958,7 @@ COMMAND_HANDLER(str9xpec_handle_flash_options_cmap_command)
 
        if (CMD_ARGC < 2)
        {
-               command_print(CMD_CTX, "str9xpec options_cmap <bank> <bank0 | bank1>");
-               return ERROR_OK;
+               return ERROR_COMMAND_SYNTAX_ERROR;
        }
 
        struct flash_bank *bank;
@@ -952,8 +986,7 @@ COMMAND_HANDLER(str9xpec_handle_flash_options_lvdthd_command)
 
        if (CMD_ARGC < 2)
        {
-               command_print(CMD_CTX, "str9xpec options_lvdthd <bank> <2.4v | 2.7v>");
-               return ERROR_OK;
+               return ERROR_COMMAND_SYNTAX_ERROR;
        }
 
        struct flash_bank *bank;
@@ -981,8 +1014,7 @@ COMMAND_HANDLER(str9xpec_handle_flash_options_lvdsel_command)
 
        if (CMD_ARGC < 2)
        {
-               command_print(CMD_CTX, "str9xpec options_lvdsel <bank> <vdd | vdd_vddq>");
-               return ERROR_OK;
+               return ERROR_COMMAND_SYNTAX_ERROR;
        }
 
        struct flash_bank *bank;
@@ -1010,8 +1042,7 @@ COMMAND_HANDLER(str9xpec_handle_flash_options_lvdwarn_command)
 
        if (CMD_ARGC < 2)
        {
-               command_print(CMD_CTX, "str9xpec options_lvdwarn <bank> <vdd | vdd_vddq>");
-               return ERROR_OK;
+               return ERROR_COMMAND_SYNTAX_ERROR;
        }
 
        struct flash_bank *bank;
@@ -1039,8 +1070,7 @@ COMMAND_HANDLER(str9xpec_handle_flash_lock_command)
 
        if (CMD_ARGC < 1)
        {
-               command_print(CMD_CTX, "str9xpec lock <bank>");
-               return ERROR_OK;
+               return ERROR_COMMAND_SYNTAX_ERROR;
        }
 
        struct flash_bank *bank;
@@ -1062,8 +1092,7 @@ COMMAND_HANDLER(str9xpec_handle_flash_unlock_command)
 
        if (CMD_ARGC < 1)
        {
-               command_print(CMD_CTX, "str9xpec unlock <bank>");
-               return ERROR_OK;
+               return ERROR_COMMAND_SYNTAX_ERROR;
        }
 
        struct flash_bank *bank;
@@ -1076,6 +1105,10 @@ COMMAND_HANDLER(str9xpec_handle_flash_unlock_command)
        if ((status & ISC_STATUS_ERROR) != STR9XPEC_ISC_SUCCESS)
                return ERROR_FLASH_OPERATION_FAILED;
 
+       command_print(CMD_CTX, "str9xpec unlocked.\n"
+                       "INFO: a reset or power cycle is required "
+                       "for the new settings to take effect.");
+
        return ERROR_OK;
 }
 
@@ -1088,8 +1121,7 @@ COMMAND_HANDLER(str9xpec_handle_flash_enable_turbo_command)
 
        if (CMD_ARGC < 1)
        {
-               command_print(CMD_CTX, "str9xpec enable_turbo <bank>");
-               return ERROR_OK;
+               return ERROR_COMMAND_SYNTAX_ERROR;
        }
 
        struct flash_bank *bank;
@@ -1135,8 +1167,7 @@ COMMAND_HANDLER(str9xpec_handle_flash_disable_turbo_command)
 
        if (CMD_ARGC < 1)
        {
-               command_print(CMD_CTX, "str9xpec disable_turbo <bank>");
-               return ERROR_OK;
+               return ERROR_COMMAND_SYNTAX_ERROR;
        }
 
        struct flash_bank *bank;
@@ -1166,60 +1197,70 @@ COMMAND_HANDLER(str9xpec_handle_flash_disable_turbo_command)
 static const struct command_registration str9xpec_config_command_handlers[] = {
        {
                .name = "enable_turbo",
+               .usage = "<bank>",
                .handler = str9xpec_handle_flash_enable_turbo_command,
                .mode = COMMAND_EXEC,
                .help = "enable str9xpec turbo mode",
        },
        {
                .name = "disable_turbo",
+               .usage = "<bank>",
                .handler = str9xpec_handle_flash_disable_turbo_command,
                .mode = COMMAND_EXEC,
                .help = "disable str9xpec turbo mode",
        },
        {
                .name = "options_cmap",
+               .usage = "<bank> <bank0 | bank1>",
                .handler = str9xpec_handle_flash_options_cmap_command,
                .mode = COMMAND_EXEC,
                .help = "configure str9xpec boot sector",
        },
        {
                .name = "options_lvdthd",
+               .usage = "<bank> <2.4v | 2.7v>",
                .handler = str9xpec_handle_flash_options_lvdthd_command,
                .mode = COMMAND_EXEC,
                .help = "configure str9xpec lvd threshold",
        },
        {
                .name = "options_lvdsel",
+               .usage = "<bank> <vdd | vdd_vddq>",
                .handler = str9xpec_handle_flash_options_lvdsel_command,
                .mode = COMMAND_EXEC,
                .help = "configure str9xpec lvd selection",
        },
        {
                .name = "options_lvdwarn",
+               .usage = "<bank> <vdd | vdd_vddq>",
                .handler = str9xpec_handle_flash_options_lvdwarn_command,
                .mode = COMMAND_EXEC,
                .help = "configure str9xpec lvd warning",
        },
        {
                .name = "options_read",
+               .usage = "<bank>",
                .handler = str9xpec_handle_flash_options_read_command,
                .mode = COMMAND_EXEC,
                .help = "read str9xpec options",
        },
        {
                .name = "options_write",
+               .usage = "<bank>",
                .handler = str9xpec_handle_flash_options_write_command,
                .mode = COMMAND_EXEC,
                .help = "write str9xpec options",
        },
        {
                .name = "lock",
+               .usage = "<bank>",
                .handler = str9xpec_handle_flash_lock_command,
                .mode = COMMAND_EXEC,
                .help = "lock str9xpec device",
        },
        {
                .name = "unlock",
+               .usage = "<bank>",
                .handler = str9xpec_handle_flash_unlock_command,
                .mode = COMMAND_EXEC,
                .help = "unlock str9xpec device",
@@ -1232,26 +1273,29 @@ static const struct command_registration str9xpec_config_command_handlers[] = {
        },
        COMMAND_REGISTRATION_DONE
 };
+
 static const struct command_registration str9xpec_command_handlers[] = {
        {
                .name = "str9xpec",
                .mode = COMMAND_ANY,
                .help = "str9xpec flash command group",
+               .usage = "",
                .chain = str9xpec_config_command_handlers,
        },
        COMMAND_REGISTRATION_DONE
 };
 
 struct flash_driver str9xpec_flash = {
-               .name = "str9xpec",
-               .commands = str9xpec_command_handlers,
-               .flash_bank_command = &str9xpec_flash_bank_command,
-               .erase = &str9xpec_erase,
-               .protect = &str9xpec_protect,
-               .write = &str9xpec_write,
-               .probe = &str9xpec_probe,
-               .auto_probe = &str9xpec_probe,
-               .erase_check = &str9xpec_erase_check,
-               .protect_check = &str9xpec_protect_check,
-               .info = &str9xpec_info,
-       };
+       .name = "str9xpec",
+       .commands = str9xpec_command_handlers,
+       .flash_bank_command = str9xpec_flash_bank_command,
+       .erase = str9xpec_erase,
+       .protect = str9xpec_protect,
+       .write = str9xpec_write,
+       .read = default_flash_read,
+       .probe = str9xpec_probe,
+       .auto_probe = str9xpec_probe,
+       .erase_check = str9xpec_erase_check,
+       .protect_check = str9xpec_protect_check,
+       .info = get_str9xpec_info,
+};