#endif
#include "imp.h"
-#include "str9xpec.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;
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));
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);
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);
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;
if (CMD_ARGC < 1)
{
- command_print(CMD_CTX, "str9xpec options_read <bank>");
- return ERROR_OK;
+ return ERROR_COMMAND_SYNTAX_ERROR;
}
struct flash_bank *bank;
if (CMD_ARGC < 1)
{
- command_print(CMD_CTX, "str9xpec options_write <bank>");
- return ERROR_OK;
+ return ERROR_COMMAND_SYNTAX_ERROR;
}
struct flash_bank *bank;
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;
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;
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;
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;
if (CMD_ARGC < 1)
{
- command_print(CMD_CTX, "str9xpec lock <bank>");
- return ERROR_OK;
+ return ERROR_COMMAND_SYNTAX_ERROR;
}
struct flash_bank *bank;
if (CMD_ARGC < 1)
{
- command_print(CMD_CTX, "str9xpec unlock <bank>");
- return ERROR_OK;
+ return ERROR_COMMAND_SYNTAX_ERROR;
}
struct flash_bank *bank;
if (CMD_ARGC < 1)
{
- command_print(CMD_CTX, "str9xpec enable_turbo <bank>");
- return ERROR_OK;
+ return ERROR_COMMAND_SYNTAX_ERROR;
}
struct flash_bank *bank;
if (CMD_ARGC < 1)
{
- command_print(CMD_CTX, "str9xpec disable_turbo <bank>");
- return ERROR_OK;
+ return ERROR_COMMAND_SYNTAX_ERROR;
}
struct flash_bank *bank;
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",
.name = "str9xpec",
.mode = COMMAND_ANY,
.help = "str9xpec flash command group",
+ .usage = "",
.chain = str9xpec_config_command_handlers,
},
COMMAND_REGISTRATION_DONE
.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 = str9xpec_info,
+ .info = get_str9xpec_info,
};