diff options
Diffstat (limited to 'src/flash/str9xpec.c')
-rw-r--r-- | src/flash/str9xpec.c | 1257 |
1 files changed, 0 insertions, 1257 deletions
diff --git a/src/flash/str9xpec.c b/src/flash/str9xpec.c deleted file mode 100644 index 96e12596..00000000 --- a/src/flash/str9xpec.c +++ /dev/null @@ -1,1257 +0,0 @@ -/*************************************************************************** - * Copyright (C) 2005 by Dominic Rath * - * Dominic.Rath@gmx.de * - * * - * Copyright (C) 2008 by Spencer Oliver * - * spen@spen-soft.co.uk * - * * - * 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., * - * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * - ***************************************************************************/ -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#include "str9xpec.h" -#include "arm7_9_common.h" - - -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) -{ - if (tap == NULL) { - return ERROR_TARGET_INVALID; - } - - 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); - field.in_value = NULL; - - jtag_add_ir_scan(1, &field, end_state); - - free(field.out_value); - } - - return ERROR_OK; -} - -static uint8_t str9xpec_isc_status(struct jtag_tap *tap) -{ - struct scan_field field; - uint8_t status; - - 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_execute_queue(); - - LOG_DEBUG("status: 0x%2.2x", status); - - if (status & ISC_STATUS_SECURITY) - LOG_INFO("Device Security Bit Set"); - - return status; -} - -static int str9xpec_isc_enable(struct flash_bank *bank) -{ - uint8_t status; - struct jtag_tap *tap; - struct str9xpec_flash_controller *str9xpec_info = bank->driver_priv; - - tap = str9xpec_info->tap; - - if (str9xpec_info->isc_enable) - return ERROR_OK; - - /* enter isc mode */ - if (str9xpec_set_instr(tap, ISC_ENABLE, TAP_IDLE) != ERROR_OK) - return ERROR_TARGET_INVALID; - - /* check ISC status */ - status = str9xpec_isc_status(tap); - if (status & ISC_STATUS_MODE) - { - /* we have entered isc mode */ - str9xpec_info->isc_enable = 1; - LOG_DEBUG("ISC_MODE Enabled"); - } - - return ERROR_OK; -} - -static int str9xpec_isc_disable(struct flash_bank *bank) -{ - uint8_t status; - struct jtag_tap *tap; - struct str9xpec_flash_controller *str9xpec_info = bank->driver_priv; - - tap = str9xpec_info->tap; - - if (!str9xpec_info->isc_enable) - return ERROR_OK; - - if (str9xpec_set_instr(tap, ISC_DISABLE, TAP_IDLE) != ERROR_OK) - return ERROR_TARGET_INVALID; - - /* delay to handle aborts */ - jtag_add_sleep(50); - - /* check ISC status */ - status = str9xpec_isc_status(tap); - if (!(status & ISC_STATUS_MODE)) - { - /* we have left isc mode */ - str9xpec_info->isc_enable = 0; - LOG_DEBUG("ISC_MODE Disabled"); - } - - return ERROR_OK; -} - -static int str9xpec_read_config(struct flash_bank *bank) -{ - struct scan_field field; - uint8_t status; - struct jtag_tap *tap; - - struct str9xpec_flash_controller *str9xpec_info = bank->driver_priv; - - tap = str9xpec_info->tap; - - LOG_DEBUG("ISC_CONFIGURATION"); - - /* 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_execute_queue(); - - status = str9xpec_isc_status(tap); - - return status; -} - -static int str9xpec_build_block_list(struct flash_bank *bank) -{ - struct str9xpec_flash_controller *str9xpec_info = bank->driver_priv; - - int i; - int num_sectors; - int b0_sectors = 0, b1_sectors = 0; - uint32_t offset = 0; - int b1_size = 0x2000; - - switch (bank->size) - { - case (256 * 1024): - b0_sectors = 4; - break; - case (512 * 1024): - b0_sectors = 8; - break; - case (1024 * 1024): - b0_sectors = 16; - break; - case (2048 * 1024): - b0_sectors = 32; - break; - case (128 * 1024): - b1_size = 0x4000; - b1_sectors = 8; - break; - case (32 * 1024): - b1_sectors = 4; - break; - default: - LOG_ERROR("BUG: unknown bank->size encountered"); - exit(-1); - } - - num_sectors = b0_sectors + b1_sectors; - - bank->num_sectors = num_sectors; - bank->sectors = malloc(sizeof(struct flash_sector) * num_sectors); - str9xpec_info->sector_bits = malloc(sizeof(uint32_t) * num_sectors); - - num_sectors = 0; - - for (i = 0; i < b0_sectors; i++) - { - bank->sectors[num_sectors].offset = offset; - bank->sectors[num_sectors].size = 0x10000; - offset += bank->sectors[i].size; - bank->sectors[num_sectors].is_erased = -1; - bank->sectors[num_sectors].is_protected = 1; - str9xpec_info->sector_bits[num_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; - bank->sectors[num_sectors].is_erased = -1; - bank->sectors[num_sectors].is_protected = 1; - str9xpec_info->sector_bits[num_sectors++] = i + 32; - } - - return ERROR_OK; -} - -/* flash bank str9x <base> <size> 0 0 <target#> - */ -FLASH_BANK_COMMAND_HANDLER(str9xpec_flash_bank_command) -{ - struct str9xpec_flash_controller *str9xpec_info; - struct arm *armv4_5 = 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; - } - - str9xpec_info = malloc(sizeof(struct str9xpec_flash_controller)); - bank->driver_priv = str9xpec_info; - - /* 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; - jtag_info = &arm7_9->jtag_info; - - str9xpec_info->tap = bank->target->tap; - str9xpec_info->isc_enable = 0; - - str9xpec_build_block_list(bank); - - /* clear option byte register */ - buf_set_u32(str9xpec_info->options, 0, 64, 0); - - return ERROR_OK; -} - -static int str9xpec_blank_check(struct flash_bank *bank, int first, int last) -{ - struct scan_field field; - uint8_t status; - struct jtag_tap *tap; - int i; - uint8_t *buffer = NULL; - - struct str9xpec_flash_controller *str9xpec_info = bank->driver_priv; - - tap = str9xpec_info->tap; - - if (!str9xpec_info->isc_enable) { - str9xpec_isc_enable(bank); - } - - 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++) { - 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_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_execute_queue(); - - status = str9xpec_isc_status(tap); - - for (i = first; i <= last; i++) - { - if (buf_get_u32(buffer, str9xpec_info->sector_bits[i], 1)) - bank->sectors[i].is_erased = 0; - else - bank->sectors[i].is_erased = 1; - } - - free(buffer); - - str9xpec_isc_disable(bank); - - if ((status & ISC_STATUS_ERROR) != STR9XPEC_ISC_SUCCESS) - return ERROR_FLASH_OPERATION_FAILED; - return ERROR_OK; -} - -static int str9xpec_protect_check(struct flash_bank *bank) -{ - uint8_t status; - int i; - - struct str9xpec_flash_controller *str9xpec_info = bank->driver_priv; - - status = str9xpec_read_config(bank); - - 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 - bank->sectors[i].is_protected = 0; - } - - if ((status & ISC_STATUS_ERROR) != STR9XPEC_ISC_SUCCESS) - return ERROR_FLASH_OPERATION_FAILED; - return ERROR_OK; -} - -static int str9xpec_erase_area(struct flash_bank *bank, int first, int last) -{ - struct scan_field field; - uint8_t status; - struct jtag_tap *tap; - int i; - uint8_t *buffer = NULL; - - struct str9xpec_flash_controller *str9xpec_info = bank->driver_priv; - - tap = str9xpec_info->tap; - - if (!str9xpec_info->isc_enable) { - str9xpec_isc_enable(bank); - } - - if (!str9xpec_info->isc_enable) { - return ISC_STATUS_ERROR; - } - - buffer = calloc(DIV_ROUND_UP(64, 8), 1); - - LOG_DEBUG("erase: first_bank: %i, last_bank: %i", first, 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++) { - buf_set_u32(buffer, i, 1, 1); - } - } - else if (last == 0xFE) - { - buf_set_u32(buffer, 49, 1, 1); - } - else - { - for (i = first; i <= last; i++) { - buf_set_u32(buffer, str9xpec_info->sector_bits[i], 1, 1); - } - } - - LOG_DEBUG("ISC_ERASE"); - - /* 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_execute_queue(); - - jtag_add_sleep(10); - - /* wait for erase completion */ - while (!((status = str9xpec_isc_status(tap)) & ISC_STATUS_BUSY)) { - alive_sleep(1); - } - - free(buffer); - - str9xpec_isc_disable(bank); - - return status; -} - -static int str9xpec_erase(struct flash_bank *bank, int first, int last) -{ - int status; - - status = str9xpec_erase_area(bank, first, last); - - if ((status & ISC_STATUS_ERROR) != STR9XPEC_ISC_SUCCESS) - return ERROR_FLASH_OPERATION_FAILED; - - return ERROR_OK; -} - -static int str9xpec_lock_device(struct flash_bank *bank) -{ - struct scan_field field; - uint8_t status; - struct jtag_tap *tap; - struct str9xpec_flash_controller *str9xpec_info = NULL; - - str9xpec_info = bank->driver_priv; - tap = str9xpec_info->tap; - - if (!str9xpec_info->isc_enable) { - str9xpec_isc_enable(bank); - } - - if (!str9xpec_info->isc_enable) { - return ISC_STATUS_ERROR; - } - - /* set security address */ - str9xpec_set_address(bank, 0x80); - - /* execute ISC_PROGRAM command */ - str9xpec_set_instr(tap, ISC_PROGRAM_SECURITY, TAP_IDLE); - - 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_execute_queue(); - - } while (!(status & ISC_STATUS_BUSY)); - - str9xpec_isc_disable(bank); - - return status; -} - -static int str9xpec_unlock_device(struct flash_bank *bank) -{ - uint8_t status; - - status = str9xpec_erase_area(bank, 0, 255); - - return status; -} - -static int str9xpec_protect(struct flash_bank *bank, int set, int first, int last) -{ - uint8_t status; - int i; - - struct str9xpec_flash_controller *str9xpec_info = bank->driver_priv; - - status = str9xpec_read_config(bank); - - if ((status & ISC_STATUS_ERROR) != STR9XPEC_ISC_SUCCESS) - return ERROR_FLASH_OPERATION_FAILED; - - LOG_DEBUG("protect: first_bank: %i, last_bank: %i", first, last); - - /* last bank: 0xFF signals a full device protect */ - if (last == 0xFF) - { - if (set) - { - status = str9xpec_lock_device(bank); - } - else - { - /* perform full erase to unlock device */ - status = str9xpec_unlock_device(bank); - } - } - else - { - for (i = first; i <= last; i++) - { - if (set) - buf_set_u32(str9xpec_info->options, str9xpec_info->sector_bits[i], 1, 1); - else - buf_set_u32(str9xpec_info->options, str9xpec_info->sector_bits[i], 1, 0); - } - - status = str9xpec_write_options(bank); - } - - if ((status & ISC_STATUS_ERROR) != STR9XPEC_ISC_SUCCESS) - return ERROR_FLASH_OPERATION_FAILED; - - return ERROR_OK; -} - -static int str9xpec_set_address(struct flash_bank *bank, uint8_t sector) -{ - struct jtag_tap *tap; - struct scan_field field; - struct str9xpec_flash_controller *str9xpec_info = bank->driver_priv; - - tap = str9xpec_info->tap; - - /* 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()); - - return ERROR_OK; -} - -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); - uint32_t bytes_remaining = (count & 0x00000007); - uint32_t bytes_written = 0; - uint8_t status; - uint32_t check_address = offset; - struct jtag_tap *tap; - struct scan_field field; - uint8_t *scanbuf; - int i; - int first_sector = 0; - int last_sector = 0; - - tap = str9xpec_info->tap; - - if (!str9xpec_info->isc_enable) { - str9xpec_isc_enable(bank); - } - - if (!str9xpec_info->isc_enable) { - return ERROR_FLASH_OPERATION_FAILED; - } - - 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++) - { - 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)) - { - /* check if destination ends in the current sector */ - if (offset + count < sec_end) - check_address = offset + count; - else - check_address = sec_end; - } - - if ((offset >= sec_start) && (offset < sec_end)) { - first_sector = i; - } - - if ((offset + count >= sec_start) && (offset + count < sec_end)) { - last_sector = i; - } - } - - if (check_address != offset + count) - return ERROR_FLASH_DST_OUT_OF_BANK; - - LOG_DEBUG("first_sector: %i, last_sector: %i", first_sector, last_sector); - - scanbuf = calloc(DIV_ROUND_UP(64, 8), 1); - - LOG_DEBUG("ISC_PROGRAM"); - - 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); - - 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)); - - /* small delay before polling */ - jtag_add_sleep(50); - - 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_execute_queue(); - - status = buf_get_u32(scanbuf, 0, 8); - - } while (!(status & ISC_STATUS_BUSY)); - - if ((status & ISC_STATUS_ERROR) != STR9XPEC_ISC_SUCCESS) - return ERROR_FLASH_OPERATION_FAILED; - - /* if ((status & ISC_STATUS_INT_ERROR) != STR9XPEC_ISC_INTFAIL) - return ERROR_FLASH_OPERATION_FAILED; */ - - dwords_remaining--; - bytes_written += 8; - } - } - - 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++; - } - - 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)); - - /* small delay before polling */ - jtag_add_sleep(50); - - 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_execute_queue(); - - status = buf_get_u32(scanbuf, 0, 8); - - } while (!(status & ISC_STATUS_BUSY)); - - if ((status & ISC_STATUS_ERROR) != STR9XPEC_ISC_SUCCESS) - return ERROR_FLASH_OPERATION_FAILED; - - /* if ((status & ISC_STATUS_INT_ERROR) != STR9XPEC_ISC_INTFAIL) - return ERROR_FLASH_OPERATION_FAILED; */ - } - - free(scanbuf); - - str9xpec_isc_disable(bank); - - return ERROR_OK; -} - -static int str9xpec_probe(struct flash_bank *bank) -{ - return ERROR_OK; -} - -COMMAND_HANDLER(str9xpec_handle_part_id_command) -{ - struct scan_field field; - uint8_t *buffer = NULL; - struct jtag_tap *tap; - uint32_t idcode; - struct str9xpec_flash_controller *str9xpec_info = NULL; - - if (CMD_ARGC < 1) - return ERROR_COMMAND_SYNTAX_ERROR; - - struct flash_bank *bank; - int retval = CALL_COMMAND_HANDLER(flash_command_get_bank, 0, &bank); - if (ERROR_OK != retval) - return retval; - - str9xpec_info = bank->driver_priv; - tap = str9xpec_info->tap; - - buffer = calloc(DIV_ROUND_UP(32, 8), 1); - - 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_execute_queue(); - - idcode = buf_get_u32(buffer, 0, 32); - - command_print(CMD_CTX, "str9xpec part id: 0x%8.8" PRIx32 "", idcode); - - free(buffer); - - return ERROR_OK; -} - -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 <bank>"); - return ERROR_OK; - } - - struct flash_bank *bank; - int retval = CALL_COMMAND_HANDLER(flash_command_get_bank, 0, &bank); - if (ERROR_OK != retval) - return retval; - - str9xpec_info = bank->driver_priv; - - status = str9xpec_read_config(bank); - - if ((status & ISC_STATUS_ERROR) != STR9XPEC_ISC_SUCCESS) - return ERROR_FLASH_OPERATION_FAILED; - - /* boot bank */ - if (buf_get_u32(str9xpec_info->options, STR9XPEC_OPT_CSMAPBIT, 1)) - command_print(CMD_CTX, "CS Map: bank1"); - else - command_print(CMD_CTX, "CS Map: bank0"); - - /* OTP lock */ - if (buf_get_u32(str9xpec_info->options, STR9XPEC_OPT_OTPBIT, 1)) - command_print(CMD_CTX, "OTP Lock: OTP Locked"); - else - command_print(CMD_CTX, "OTP Lock: OTP Unlocked"); - - /* LVD Threshold */ - if (buf_get_u32(str9xpec_info->options, STR9XPEC_OPT_LVDTHRESBIT, 1)) - command_print(CMD_CTX, "LVD Threshold: 2.7v"); - else - command_print(CMD_CTX, "LVD Threshold: 2.4v"); - - /* LVD reset warning */ - if (buf_get_u32(str9xpec_info->options, STR9XPEC_OPT_LVDWARNBIT, 1)) - command_print(CMD_CTX, "LVD Reset Warning: VDD or VDDQ Inputs"); - else - command_print(CMD_CTX, "LVD Reset Warning: VDD Input Only"); - - /* LVD reset select */ - if (buf_get_u32(str9xpec_info->options, STR9XPEC_OPT_LVDSELBIT, 1)) - command_print(CMD_CTX, "LVD Reset Selection: VDD or VDDQ Inputs"); - else - command_print(CMD_CTX, "LVD Reset Selection: VDD Input Only"); - - return ERROR_OK; -} - -static int str9xpec_write_options(struct flash_bank *bank) -{ - struct scan_field field; - uint8_t status; - struct jtag_tap *tap; - struct str9xpec_flash_controller *str9xpec_info = NULL; - - str9xpec_info = bank->driver_priv; - tap = str9xpec_info->tap; - - /* erase config options first */ - status = str9xpec_erase_area(bank, 0xFE, 0xFE); - - if ((status & ISC_STATUS_ERROR) != STR9XPEC_ISC_SUCCESS) - return status; - - if (!str9xpec_info->isc_enable) { - str9xpec_isc_enable(bank); - } - - 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); - - /* set option byte address */ - str9xpec_set_address(bank, 0x50); - - /* 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)); - - /* small delay before polling */ - jtag_add_sleep(50); - - 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_execute_queue(); - - } while (!(status & ISC_STATUS_BUSY)); - - str9xpec_isc_disable(bank); - - return status; -} - -COMMAND_HANDLER(str9xpec_handle_flash_options_write_command) -{ - uint8_t status; - - if (CMD_ARGC < 1) - { - command_print(CMD_CTX, "str9xpec options_write <bank>"); - return ERROR_OK; - } - - struct flash_bank *bank; - int retval = CALL_COMMAND_HANDLER(flash_command_get_bank, 0, &bank); - if (ERROR_OK != retval) - return retval; - - status = str9xpec_write_options(bank); - - if ((status & ISC_STATUS_ERROR) != STR9XPEC_ISC_SUCCESS) - return ERROR_FLASH_OPERATION_FAILED; - - return ERROR_OK; -} - -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 <bank> <bank0 | bank1>"); - return ERROR_OK; - } - - struct flash_bank *bank; - int retval = CALL_COMMAND_HANDLER(flash_command_get_bank, 0, &bank); - if (ERROR_OK != retval) - return retval; - - 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; -} - -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 <bank> <2.4v | 2.7v>"); - return ERROR_OK; - } - - struct flash_bank *bank; - int retval = CALL_COMMAND_HANDLER(flash_command_get_bank, 0, &bank); - if (ERROR_OK != retval) - return retval; - - 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; -} - -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 <bank> <vdd | vdd_vddq>"); - return ERROR_OK; - } - - struct flash_bank *bank; - int retval = CALL_COMMAND_HANDLER(flash_command_get_bank, 0, &bank); - if (ERROR_OK != retval) - return retval; - - 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; -} - -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 <bank> <vdd | vdd_vddq>"); - return ERROR_OK; - } - - struct flash_bank *bank; - int retval = CALL_COMMAND_HANDLER(flash_command_get_bank, 0, &bank); - if (ERROR_OK != retval) - return retval; - - 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; -} - -COMMAND_HANDLER(str9xpec_handle_flash_lock_command) -{ - uint8_t status; - - if (CMD_ARGC < 1) - { - command_print(CMD_CTX, "str9xpec lock <bank>"); - return ERROR_OK; - } - - struct flash_bank *bank; - int retval = CALL_COMMAND_HANDLER(flash_command_get_bank, 0, &bank); - if (ERROR_OK != retval) - return retval; - - status = str9xpec_lock_device(bank); - - if ((status & ISC_STATUS_ERROR) != STR9XPEC_ISC_SUCCESS) - return ERROR_FLASH_OPERATION_FAILED; - - return ERROR_OK; -} - -COMMAND_HANDLER(str9xpec_handle_flash_unlock_command) -{ - uint8_t status; - - if (CMD_ARGC < 1) - { - command_print(CMD_CTX, "str9xpec unlock <bank>"); - return ERROR_OK; - } - - struct flash_bank *bank; - int retval = CALL_COMMAND_HANDLER(flash_command_get_bank, 0, &bank); - if (ERROR_OK != retval) - return retval; - - status = str9xpec_unlock_device(bank); - - if ((status & ISC_STATUS_ERROR) != STR9XPEC_ISC_SUCCESS) - return ERROR_FLASH_OPERATION_FAILED; - - return ERROR_OK; -} - -COMMAND_HANDLER(str9xpec_handle_flash_enable_turbo_command) -{ - struct jtag_tap *tap0; - struct jtag_tap *tap1; - struct jtag_tap *tap2; - struct str9xpec_flash_controller *str9xpec_info = NULL; - - if (CMD_ARGC < 1) - { - command_print(CMD_CTX, "str9xpec enable_turbo <bank>"); - return ERROR_OK; - } - - struct flash_bank *bank; - int retval = CALL_COMMAND_HANDLER(flash_command_get_bank, 0, &bank); - if (ERROR_OK != retval) - return retval; - - str9xpec_info = bank->driver_priv; - - tap0 = str9xpec_info->tap; - - /* remove arm core from chain - enter turbo mode */ - tap1 = tap0->next_tap; - if (tap1 == NULL) - { - /* things are *WRONG* */ - command_print(CMD_CTX,"**STR9FLASH** (tap1) invalid chain?"); - return ERROR_OK; - } - tap2 = tap1->next_tap; - if (tap2 == NULL) - { - /* things are *WRONG* */ - command_print(CMD_CTX,"**STR9FLASH** (tap2) invalid chain?"); - return ERROR_OK; - } - - /* enable turbo mode - TURBO-PROG-ENABLE */ - str9xpec_set_instr(tap2, 0xD, TAP_IDLE); - if ((retval = jtag_execute_queue()) != ERROR_OK) - return retval; - - /* modify scan chain - str9 core has been removed */ - tap1->enabled = 0; - - return ERROR_OK; -} - -COMMAND_HANDLER(str9xpec_handle_flash_disable_turbo_command) -{ - struct jtag_tap *tap; - struct str9xpec_flash_controller *str9xpec_info = NULL; - - if (CMD_ARGC < 1) - { - command_print(CMD_CTX, "str9xpec disable_turbo <bank>"); - return ERROR_OK; - } - - struct flash_bank *bank; - int retval = CALL_COMMAND_HANDLER(flash_command_get_bank, 0, &bank); - if (ERROR_OK != retval) - return retval; - - str9xpec_info = bank->driver_priv; - tap = str9xpec_info->tap; - - if (tap == NULL) - return ERROR_FAIL; - - /* exit turbo mode via RESET */ - str9xpec_set_instr(tap, ISC_NOOP, TAP_IDLE); - jtag_add_tlr(); - jtag_execute_queue(); - - /* restore previous scan chain */ - if (tap->next_tap) { - tap->next_tap->enabled = 1; - } - - return ERROR_OK; -} - -static const struct command_registration str9xpec_config_command_handlers[] = { - { - .name = "enable_turbo", - .handler = str9xpec_handle_flash_enable_turbo_command, - .mode = COMMAND_EXEC, - .help = "enable str9xpec turbo mode", - }, - { - .name = "disable_turbo", - .handler = str9xpec_handle_flash_disable_turbo_command, - .mode = COMMAND_EXEC, - .help = "disable str9xpec turbo mode", - }, - { - .name = "options_cmap", - .handler = str9xpec_handle_flash_options_cmap_command, - .mode = COMMAND_EXEC, - .help = "configure str9xpec boot sector", - }, - { - .name = "options_lvdthd", - .handler = str9xpec_handle_flash_options_lvdthd_command, - .mode = COMMAND_EXEC, - .help = "configure str9xpec lvd threshold", - }, - { - .name = "options_lvdsel", - .handler = str9xpec_handle_flash_options_lvdsel_command, - .mode = COMMAND_EXEC, - .help = "configure str9xpec lvd selection", - }, - { - .name = "options_lvdwarn", - .handler = str9xpec_handle_flash_options_lvdwarn_command, - .mode = COMMAND_EXEC, - .help = "configure str9xpec lvd warning", - }, - { - .name = "options_read", - .handler = str9xpec_handle_flash_options_read_command, - .mode = COMMAND_EXEC, - .help = "read str9xpec options", - }, - { - .name = "options_write", - .handler = str9xpec_handle_flash_options_write_command, - .mode = COMMAND_EXEC, - .help = "write str9xpec options", - }, - { - .name = "lock", - .handler = str9xpec_handle_flash_lock_command, - .mode = COMMAND_EXEC, - .help = "lock str9xpec device", - }, - { - .name = "unlock", - .handler = str9xpec_handle_flash_unlock_command, - .mode = COMMAND_EXEC, - .help = "unlock str9xpec device", - }, - { - .name = "part_id", - .handler = str9xpec_handle_part_id_command, - .mode = COMMAND_EXEC, - .help = "print part id of str9xpec flash bank <num>", - }, - COMMAND_REGISTRATION_DONE -}; -static const struct command_registration str9xpec_command_handlers[] = { - { - .name = "str9xpec", - .mode = COMMAND_ANY, - .help = "str9xpec flash command group", - .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, - }; |