X-Git-Url: https://review.openocd.org/gitweb?p=openocd.git;a=blobdiff_plain;f=src%2Fflash%2Fnor%2Fstr9xpec.c;h=f0af53a4154801647a2b15d86708ce90490cdd0b;hp=734f2d1524ebb9d5f24dd47eb2faf39b1d48f3d2;hb=90ae846fc4009f8e466566ee0371398e52beecca;hpb=d9dc604a4d790f557a7ba502babdabffa27eaa17 diff --git a/src/flash/nor/str9xpec.c b/src/flash/nor/str9xpec.c index 734f2d1524..f0af53a415 100644 --- a/src/flash/nor/str9xpec.c +++ b/src/flash/nor/str9xpec.c @@ -18,40 +18,85 @@ * 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., * - * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * ***************************************************************************/ + #ifdef HAVE_CONFIG_H #include "config.h" #endif #include "imp.h" -#include "str9xpec.h" #include +/* 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) { + if (tap == NULL) return ERROR_TARGET_INVALID; - } - if (buf_get_u32(tap->cur_instr, 0, tap->ir_length) != new_instr) - { + if (buf_get_u32(tap->cur_instr, 0, tap->ir_length) != new_instr) { 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; @@ -65,13 +110,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); @@ -99,8 +143,7 @@ static int str9xpec_isc_enable(struct flash_bank *bank) /* check ISC status */ status = str9xpec_isc_status(tap); - if (status & ISC_STATUS_MODE) - { + if (status & ISC_STATUS_MODE) { /* we have entered isc mode */ str9xpec_info->isc_enable = 1; LOG_DEBUG("ISC_MODE Enabled"); @@ -128,8 +171,7 @@ static int str9xpec_isc_disable(struct flash_bank *bank) /* check ISC status */ status = str9xpec_isc_status(tap); - if (!(status & ISC_STATUS_MODE)) - { + if (!(status & ISC_STATUS_MODE)) { /* we have left isc mode */ str9xpec_info->isc_enable = 0; LOG_DEBUG("ISC_MODE Disabled"); @@ -153,13 +195,11 @@ 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); @@ -177,8 +217,7 @@ static int str9xpec_build_block_list(struct flash_bank *bank) uint32_t offset = 0; int b1_size = 0x2000; - switch (bank->size) - { + switch (bank->size) { case (256 * 1024): b0_sectors = 4; break; @@ -211,8 +250,7 @@ static int str9xpec_build_block_list(struct flash_bank *bank) num_sectors = 0; - for (i = 0; i < b0_sectors; i++) - { + for (i = 0; i < b0_sectors; i++) { bank->sectors[num_sectors].offset = offset; bank->sectors[num_sectors].size = 0x10000; offset += bank->sectors[i].size; @@ -221,8 +259,7 @@ static int str9xpec_build_block_list(struct flash_bank *bank) str9xpec_info->sector_bits[num_sectors++] = i; } - for (i = 0; i < b1_sectors; i++) - { + for (i = 0; i < b1_sectors; i++) { bank->sectors[num_sectors].offset = offset; bank->sectors[num_sectors].size = b1_size; offset += bank->sectors[i].size; @@ -239,15 +276,12 @@ static int str9xpec_build_block_list(struct flash_bank *bank) FLASH_BANK_COMMAND_HANDLER(str9xpec_flash_bank_command) { struct str9xpec_flash_controller *str9xpec_info; - struct arm *armv4_5 = NULL; + struct arm *arm = NULL; struct arm7_9_common *arm7_9 = NULL; struct arm_jtag *jtag_info = NULL; 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)); bank->driver_priv = str9xpec_info; @@ -255,11 +289,12 @@ FLASH_BANK_COMMAND_HANDLER(str9xpec_flash_bank_command) /* REVISIT verify that the jtag position of flash controller is * right after *THIS* core, which must be a STR9xx core ... */ - armv4_5 = bank->target->arch_info; - arm7_9 = armv4_5->arch_info; + arm = bank->target->arch_info; + arm7_9 = arm->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); @@ -282,46 +317,40 @@ static int str9xpec_blank_check(struct flash_bank *bank, int first, int last) tap = str9xpec_info->tap; - if (!str9xpec_info->isc_enable) { + if (!str9xpec_info->isc_enable) str9xpec_isc_enable(bank); - } - if (!str9xpec_info->isc_enable) { + if (!str9xpec_info->isc_enable) return ERROR_FLASH_OPERATION_FAILED; - } buffer = calloc(DIV_ROUND_UP(64, 8), 1); LOG_DEBUG("blank check: first_bank: %i, last_bank: %i", first, last); - for (i = first; i <= last; i++) { + for (i = first; i <= last; i++) buf_set_u32(buffer, str9xpec_info->sector_bits[i], 1, 1); - } /* 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); - for (i = first; i <= last; i++) - { + for (i = first; i <= last; i++) { if (buf_get_u32(buffer, str9xpec_info->sector_bits[i], 1)) bank->sectors[i].is_erased = 0; else @@ -346,8 +375,7 @@ static int str9xpec_protect_check(struct flash_bank *bank) status = str9xpec_read_config(bank); - for (i = 0; i < bank->num_sectors; i++) - { + for (i = 0; i < bank->num_sectors; i++) { if (buf_get_u32(str9xpec_info->options, str9xpec_info->sector_bits[i], 1)) bank->sectors[i].is_protected = 1; else @@ -371,13 +399,11 @@ static int str9xpec_erase_area(struct flash_bank *bank, int first, int last) tap = str9xpec_info->tap; - if (!str9xpec_info->isc_enable) { + if (!str9xpec_info->isc_enable) str9xpec_isc_enable(bank); - } - if (!str9xpec_info->isc_enable) { + if (!str9xpec_info->isc_enable) return ISC_STATUS_ERROR; - } buffer = calloc(DIV_ROUND_UP(64, 8), 1); @@ -385,21 +411,14 @@ static int str9xpec_erase_area(struct flash_bank *bank, int first, int last) /* last bank: 0xFF signals a full erase (unlock complete device) */ /* last bank: 0xFE signals a option byte erase */ - if (last == 0xFF) - { - for (i = 0; i < 64; i++) { + if (last == 0xFF) { + for (i = 0; i < 64; i++) buf_set_u32(buffer, i, 1, 1); - } - } - else if (last == 0xFE) - { + } else if (last == 0xFE) buf_set_u32(buffer, 49, 1, 1); - } - else - { - for (i = first; i <= last; i++) { + else { + for (i = first; i <= last; i++) buf_set_u32(buffer, str9xpec_info->sector_bits[i], 1, 1); - } } LOG_DEBUG("ISC_ERASE"); @@ -407,20 +426,18 @@ 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); /* wait for erase completion */ - while (!((status = str9xpec_isc_status(tap)) & ISC_STATUS_BUSY)) { + while (!((status = str9xpec_isc_status(tap)) & ISC_STATUS_BUSY)) alive_sleep(1); - } free(buffer); @@ -451,13 +468,11 @@ static int str9xpec_lock_device(struct flash_bank *bank) str9xpec_info = bank->driver_priv; tap = str9xpec_info->tap; - if (!str9xpec_info->isc_enable) { + if (!str9xpec_info->isc_enable) str9xpec_isc_enable(bank); - } - if (!str9xpec_info->isc_enable) { + if (!str9xpec_info->isc_enable) return ISC_STATUS_ERROR; - } /* set security address */ str9xpec_set_address(bank, 0x80); @@ -468,12 +483,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)); @@ -507,22 +521,15 @@ static int str9xpec_protect(struct flash_bank *bank, int set, int first, int las LOG_DEBUG("protect: first_bank: %i, last_bank: %i", first, last); /* last bank: 0xFF signals a full device protect */ - if (last == 0xFF) - { + if (last == 0xFF) { if (set) - { status = str9xpec_lock_device(bank); - } - else - { + else { /* perform full erase to unlock device */ status = str9xpec_unlock_device(bank); } - } - else - { - for (i = first; i <= last; i++) - { + } else { + for (i = first; i <= last; i++) { if (set) buf_set_u32(str9xpec_info->options, str9xpec_info->sector_bits[i], 1, 1); else @@ -549,17 +556,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 = §or; 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, const uint8_t *buffer, + uint32_t offset, uint32_t count) { struct str9xpec_flash_controller *str9xpec_info = bank->driver_priv; uint32_t dwords_remaining = (count / 8); @@ -576,28 +583,23 @@ static int str9xpec_write(struct flash_bank *bank, uint8_t *buffer, uint32_t off tap = str9xpec_info->tap; - if (!str9xpec_info->isc_enable) { + if (!str9xpec_info->isc_enable) str9xpec_isc_enable(bank); - } - if (!str9xpec_info->isc_enable) { + if (!str9xpec_info->isc_enable) return ERROR_FLASH_OPERATION_FAILED; - } - if (offset & 0x7) - { + if (offset & 0x7) { LOG_WARNING("offset 0x%" PRIx32 " breaks required 8-byte alignment", offset); return ERROR_FLASH_DST_BREAKS_ALIGNMENT; } - for (i = 0; i < bank->num_sectors; i++) - { + for (i = 0; i < bank->num_sectors; i++) { uint32_t sec_start = bank->sectors[i].offset; uint32_t sec_end = sec_start + bank->sectors[i].size; /* check if destination falls within the current sector */ - if ((check_address >= sec_start) && (check_address < sec_end)) - { + if ((check_address >= sec_start) && (check_address < sec_end)) { /* check if destination ends in the current sector */ if (offset + count < sec_end) check_address = offset + count; @@ -605,13 +607,11 @@ static int str9xpec_write(struct flash_bank *bank, uint8_t *buffer, uint32_t off check_address = sec_end; } - if ((offset >= sec_start) && (offset < sec_end)) { + if ((offset >= sec_start) && (offset < sec_end)) first_sector = i; - } - if ((offset + count >= sec_start) && (offset + count < sec_end)) { + if ((offset + count >= sec_start) && (offset + count < sec_end)) last_sector = i; - } } if (check_address != offset + count) @@ -623,22 +623,20 @@ static int str9xpec_write(struct flash_bank *bank, uint8_t *buffer, uint32_t off LOG_DEBUG("ISC_PROGRAM"); - for (i = first_sector; i <= last_sector; i++) - { + for (i = first_sector; i <= last_sector; i++) { 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) - { + 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); @@ -646,12 +644,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); @@ -669,26 +666,19 @@ static int str9xpec_write(struct flash_bank *bank, uint8_t *buffer, uint32_t off } } - if (bytes_remaining) - { + 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); @@ -696,12 +686,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); @@ -750,12 +739,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); @@ -772,22 +760,13 @@ 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) -{ - snprintf(buf, buf_size, "str9xpec flash driver info"); - return ERROR_OK; -} - COMMAND_HANDLER(str9xpec_handle_flash_options_read_command) { uint8_t status; struct str9xpec_flash_controller *str9xpec_info = NULL; if (CMD_ARGC < 1) - { - command_print(CMD_CTX, "str9xpec options_read "); - return ERROR_OK; - } + return ERROR_COMMAND_SYNTAX_ERROR; struct flash_bank *bank; int retval = CALL_COMMAND_HANDLER(flash_command_get_bank, 0, &bank); @@ -850,13 +829,11 @@ static int str9xpec_write_options(struct flash_bank *bank) if ((status & ISC_STATUS_ERROR) != STR9XPEC_ISC_SUCCESS) return status; - if (!str9xpec_info->isc_enable) { + if (!str9xpec_info->isc_enable) str9xpec_isc_enable(bank); - } - if (!str9xpec_info->isc_enable) { + if (!str9xpec_info->isc_enable) return ISC_STATUS_ERROR; - } /* according to data 64th bit has to be set */ buf_set_u32(str9xpec_info->options, 63, 1, 1); @@ -867,12 +844,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); @@ -880,12 +856,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,10 +875,7 @@ COMMAND_HANDLER(str9xpec_handle_flash_options_write_command) uint8_t status; if (CMD_ARGC < 1) - { - command_print(CMD_CTX, "str9xpec options_write "); - return ERROR_OK; - } + return ERROR_COMMAND_SYNTAX_ERROR; struct flash_bank *bank; int retval = CALL_COMMAND_HANDLER(flash_command_get_bank, 0, &bank); @@ -915,6 +887,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,10 +899,7 @@ COMMAND_HANDLER(str9xpec_handle_flash_options_cmap_command) struct str9xpec_flash_controller *str9xpec_info = NULL; if (CMD_ARGC < 2) - { - command_print(CMD_CTX, "str9xpec options_cmap "); - return ERROR_OK; - } + return ERROR_COMMAND_SYNTAX_ERROR; struct flash_bank *bank; int retval = CALL_COMMAND_HANDLER(flash_command_get_bank, 0, &bank); @@ -936,13 +909,9 @@ COMMAND_HANDLER(str9xpec_handle_flash_options_cmap_command) str9xpec_info = bank->driver_priv; if (strcmp(CMD_ARGV[1], "bank1") == 0) - { buf_set_u32(str9xpec_info->options, STR9XPEC_OPT_CSMAPBIT, 1, 1); - } else - { buf_set_u32(str9xpec_info->options, STR9XPEC_OPT_CSMAPBIT, 1, 0); - } return ERROR_OK; } @@ -952,10 +921,7 @@ COMMAND_HANDLER(str9xpec_handle_flash_options_lvdthd_command) struct str9xpec_flash_controller *str9xpec_info = NULL; if (CMD_ARGC < 2) - { - command_print(CMD_CTX, "str9xpec options_lvdthd <2.4v | 2.7v>"); - return ERROR_OK; - } + return ERROR_COMMAND_SYNTAX_ERROR; struct flash_bank *bank; int retval = CALL_COMMAND_HANDLER(flash_command_get_bank, 0, &bank); @@ -965,13 +931,9 @@ COMMAND_HANDLER(str9xpec_handle_flash_options_lvdthd_command) str9xpec_info = bank->driver_priv; if (strcmp(CMD_ARGV[1], "2.7v") == 0) - { buf_set_u32(str9xpec_info->options, STR9XPEC_OPT_LVDTHRESBIT, 1, 1); - } else - { buf_set_u32(str9xpec_info->options, STR9XPEC_OPT_LVDTHRESBIT, 1, 0); - } return ERROR_OK; } @@ -981,10 +943,7 @@ COMMAND_HANDLER(str9xpec_handle_flash_options_lvdsel_command) struct str9xpec_flash_controller *str9xpec_info = NULL; if (CMD_ARGC < 2) - { - command_print(CMD_CTX, "str9xpec options_lvdsel "); - return ERROR_OK; - } + return ERROR_COMMAND_SYNTAX_ERROR; struct flash_bank *bank; int retval = CALL_COMMAND_HANDLER(flash_command_get_bank, 0, &bank); @@ -994,13 +953,9 @@ COMMAND_HANDLER(str9xpec_handle_flash_options_lvdsel_command) str9xpec_info = bank->driver_priv; if (strcmp(CMD_ARGV[1], "vdd_vddq") == 0) - { buf_set_u32(str9xpec_info->options, STR9XPEC_OPT_LVDSELBIT, 1, 1); - } else - { buf_set_u32(str9xpec_info->options, STR9XPEC_OPT_LVDSELBIT, 1, 0); - } return ERROR_OK; } @@ -1010,10 +965,7 @@ COMMAND_HANDLER(str9xpec_handle_flash_options_lvdwarn_command) struct str9xpec_flash_controller *str9xpec_info = NULL; if (CMD_ARGC < 2) - { - command_print(CMD_CTX, "str9xpec options_lvdwarn "); - return ERROR_OK; - } + return ERROR_COMMAND_SYNTAX_ERROR; struct flash_bank *bank; int retval = CALL_COMMAND_HANDLER(flash_command_get_bank, 0, &bank); @@ -1023,13 +975,9 @@ COMMAND_HANDLER(str9xpec_handle_flash_options_lvdwarn_command) str9xpec_info = bank->driver_priv; if (strcmp(CMD_ARGV[1], "vdd_vddq") == 0) - { buf_set_u32(str9xpec_info->options, STR9XPEC_OPT_LVDWARNBIT, 1, 1); - } else - { buf_set_u32(str9xpec_info->options, STR9XPEC_OPT_LVDWARNBIT, 1, 0); - } return ERROR_OK; } @@ -1039,10 +987,7 @@ COMMAND_HANDLER(str9xpec_handle_flash_lock_command) uint8_t status; if (CMD_ARGC < 1) - { - command_print(CMD_CTX, "str9xpec lock "); - return ERROR_OK; - } + return ERROR_COMMAND_SYNTAX_ERROR; struct flash_bank *bank; int retval = CALL_COMMAND_HANDLER(flash_command_get_bank, 0, &bank); @@ -1062,10 +1007,7 @@ COMMAND_HANDLER(str9xpec_handle_flash_unlock_command) uint8_t status; if (CMD_ARGC < 1) - { - command_print(CMD_CTX, "str9xpec unlock "); - return ERROR_OK; - } + return ERROR_COMMAND_SYNTAX_ERROR; struct flash_bank *bank; int retval = CALL_COMMAND_HANDLER(flash_command_get_bank, 0, &bank); @@ -1077,6 +1019,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,10 +1034,7 @@ COMMAND_HANDLER(str9xpec_handle_flash_enable_turbo_command) struct str9xpec_flash_controller *str9xpec_info = NULL; if (CMD_ARGC < 1) - { - command_print(CMD_CTX, "str9xpec enable_turbo "); - return ERROR_OK; - } + return ERROR_COMMAND_SYNTAX_ERROR; struct flash_bank *bank; int retval = CALL_COMMAND_HANDLER(flash_command_get_bank, 0, &bank); @@ -1100,27 +1043,30 @@ COMMAND_HANDLER(str9xpec_handle_flash_enable_turbo_command) str9xpec_info = bank->driver_priv; - tap0 = str9xpec_info->tap; - /* remove arm core from chain - enter turbo mode */ + tap0 = str9xpec_info->tap; + if (tap0 == NULL) { + /* things are *WRONG* */ + command_print(CMD_CTX, "**STR9FLASH** (tap0) invalid chain?"); + return ERROR_FAIL; + } tap1 = tap0->next_tap; - if (tap1 == NULL) - { + if (tap1 == NULL) { /* things are *WRONG* */ - command_print(CMD_CTX,"**STR9FLASH** (tap1) invalid chain?"); - return ERROR_OK; + command_print(CMD_CTX, "**STR9FLASH** (tap1) invalid chain?"); + return ERROR_FAIL; } tap2 = tap1->next_tap; - if (tap2 == NULL) - { + if (tap2 == NULL) { /* things are *WRONG* */ - command_print(CMD_CTX,"**STR9FLASH** (tap2) invalid chain?"); - return ERROR_OK; + command_print(CMD_CTX, "**STR9FLASH** (tap2) invalid chain?"); + return ERROR_FAIL; } /* enable turbo mode - TURBO-PROG-ENABLE */ str9xpec_set_instr(tap2, 0xD, TAP_IDLE); - if ((retval = jtag_execute_queue()) != ERROR_OK) + retval = jtag_execute_queue(); + if (retval != ERROR_OK) return retval; /* modify scan chain - str9 core has been removed */ @@ -1135,10 +1081,7 @@ COMMAND_HANDLER(str9xpec_handle_flash_disable_turbo_command) struct str9xpec_flash_controller *str9xpec_info = NULL; if (CMD_ARGC < 1) - { - command_print(CMD_CTX, "str9xpec disable_turbo "); - return ERROR_OK; - } + return ERROR_COMMAND_SYNTAX_ERROR; struct flash_bank *bank; int retval = CALL_COMMAND_HANDLER(flash_command_get_bank, 0, &bank); @@ -1157,9 +1100,8 @@ COMMAND_HANDLER(str9xpec_handle_flash_disable_turbo_command) jtag_execute_queue(); /* restore previous scan chain */ - if (tap->next_tap) { + if (tap->next_tap) tap->next_tap->enabled = 1; - } return ERROR_OK; } @@ -1167,60 +1109,70 @@ COMMAND_HANDLER(str9xpec_handle_flash_disable_turbo_command) static const struct command_registration str9xpec_config_command_handlers[] = { { .name = "enable_turbo", + .usage = "", .handler = str9xpec_handle_flash_enable_turbo_command, .mode = COMMAND_EXEC, .help = "enable str9xpec turbo mode", }, { .name = "disable_turbo", + .usage = "", .handler = str9xpec_handle_flash_disable_turbo_command, .mode = COMMAND_EXEC, .help = "disable str9xpec turbo mode", }, { .name = "options_cmap", + .usage = " ", .handler = str9xpec_handle_flash_options_cmap_command, .mode = COMMAND_EXEC, .help = "configure str9xpec boot sector", }, { .name = "options_lvdthd", + .usage = " <2.4v | 2.7v>", .handler = str9xpec_handle_flash_options_lvdthd_command, .mode = COMMAND_EXEC, .help = "configure str9xpec lvd threshold", }, { .name = "options_lvdsel", + .usage = " ", .handler = str9xpec_handle_flash_options_lvdsel_command, .mode = COMMAND_EXEC, .help = "configure str9xpec lvd selection", }, { .name = "options_lvdwarn", + .usage = " ", .handler = str9xpec_handle_flash_options_lvdwarn_command, .mode = COMMAND_EXEC, .help = "configure str9xpec lvd warning", }, { .name = "options_read", + .usage = "", .handler = str9xpec_handle_flash_options_read_command, .mode = COMMAND_EXEC, .help = "read str9xpec options", }, { .name = "options_write", + .usage = "", .handler = str9xpec_handle_flash_options_write_command, .mode = COMMAND_EXEC, .help = "write str9xpec options", }, { .name = "lock", + .usage = "", .handler = str9xpec_handle_flash_lock_command, .mode = COMMAND_EXEC, .help = "lock str9xpec device", }, { .name = "unlock", + .usage = "", .handler = str9xpec_handle_flash_unlock_command, .mode = COMMAND_EXEC, .help = "unlock str9xpec device", @@ -1233,26 +1185,28 @@ 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, +};