X-Git-Url: https://review.openocd.org/gitweb?a=blobdiff_plain;f=src%2Fflash%2Fnor%2Fxmc4xxx.c;h=1668e8993d34a7fafcbf310d58255c7161385831;hb=1ad6ed38b6da09b1d5d9e56d1344fced2dce12bc;hp=4fa273b004eaea6f885ebba1db8bec3dd88a132e;hpb=13ff5c129011b9b52b1070bc6bbbf253c773f887;p=openocd.git diff --git a/src/flash/nor/xmc4xxx.c b/src/flash/nor/xmc4xxx.c index 4fa273b004..1668e8993d 100644 --- a/src/flash/nor/xmc4xxx.c +++ b/src/flash/nor/xmc4xxx.c @@ -11,6 +11,8 @@ * 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, see . * ***************************************************************************/ #ifdef HAVE_CONFIG_H @@ -181,7 +183,7 @@ /* Flash controller configuration values */ #define FLASH_ID_XMC4500 0xA2 -#define FLASH_ID_XMC4700_4800 0x92 +#define FLASH_ID_XMC4300_XMC4700_4800 0x92 #define FLASH_ID_XMC4100_4200 0x9C #define FLASH_ID_XMC4400 0x9F @@ -278,7 +280,7 @@ static int xmc4xxx_load_bank_layout(struct flash_bank *bank) /* At this point, we know which flash controller ID we're * talking to and simply need to fill out the bank structure accordingly */ - LOG_DEBUG("%d sectors", bank->num_sectors); + LOG_DEBUG("%u sectors", bank->num_sectors); switch (bank->num_sectors) { case 8: @@ -294,7 +296,7 @@ static int xmc4xxx_load_bank_layout(struct flash_bank *bank) capacity = sector_capacity_16; break; default: - LOG_ERROR("Unexpected number of sectors, %d\n", + LOG_ERROR("Unexpected number of sectors, %u\n", bank->num_sectors); return ERROR_FAIL; } @@ -305,7 +307,7 @@ static int xmc4xxx_load_bank_layout(struct flash_bank *bank) uint32_t total_offset = 0; bank->sectors = calloc(bank->num_sectors, sizeof(struct flash_sector)); - for (int i = 0; i < bank->num_sectors; i++) { + for (unsigned int i = 0; i < bank->num_sectors; i++) { bank->sectors[i].size = capacity[i] * 1024; bank->sectors[i].offset = total_offset; bank->sectors[i].is_erased = -1; @@ -317,8 +319,8 @@ static int xmc4xxx_load_bank_layout(struct flash_bank *bank) } /* This part doesn't follow the typical standard of 0xff - * being the default padding value.*/ - bank->default_padded_value = 0x00; + * being the erased value.*/ + bank->default_padded_value = bank->erased_value = 0x00; return ERROR_OK; } @@ -381,7 +383,7 @@ static int xmc4xxx_probe(struct flash_bank *bank) bank->num_sectors = 12; LOG_DEBUG("XMC4xxx: XMC4500 detected."); break; - case FLASH_ID_XMC4700_4800: + case FLASH_ID_XMC4300_XMC4700_4800: bank->num_sectors = 16; LOG_DEBUG("XMC4xxx: XMC4700/4800 detected."); break; @@ -406,7 +408,7 @@ static int xmc4xxx_probe(struct flash_bank *bank) } static int xmc4xxx_get_sector_start_addr(struct flash_bank *bank, - int sector, uint32_t *ret_addr) + unsigned int sector, uint32_t *ret_addr) { /* Make sure we understand this sector */ if (sector > bank->num_sectors) @@ -536,7 +538,8 @@ static int xmc4xxx_erase_sector(struct flash_bank *bank, uint32_t address, return res; } -static int xmc4xxx_erase(struct flash_bank *bank, int first, int last) +static int xmc4xxx_erase(struct flash_bank *bank, unsigned int first, + unsigned int last) { struct xmc4xxx_flash_bank *fb = bank->driver_priv; int res; @@ -554,14 +557,14 @@ static int xmc4xxx_erase(struct flash_bank *bank, int first, int last) uint32_t tmp_addr; /* Loop through the sectors and erase each one */ - for (int i = first; i <= last; i++) { + for (unsigned int i = first; i <= last; i++) { res = xmc4xxx_get_sector_start_addr(bank, i, &tmp_addr); if (res != ERROR_OK) { - LOG_ERROR("Invalid sector %d", i); + LOG_ERROR("Invalid sector %u", i); return res; } - LOG_DEBUG("Erasing sector %d @ 0x%08"PRIx32, i, tmp_addr); + LOG_DEBUG("Erasing sector %u @ 0x%08"PRIx32, i, tmp_addr); res = xmc4xxx_erase_sector(bank, tmp_addr, false); if (res != ERROR_OK) { @@ -574,8 +577,6 @@ static int xmc4xxx_erase(struct flash_bank *bank, int first, int last) if (res != ERROR_OK) goto clear_status_and_exit; - - bank->sectors[i].is_erased = 1; } clear_status_and_exit: @@ -615,99 +616,6 @@ static int xmc4xxx_enter_page_mode(struct flash_bank *bank) return res; } -/* The logical erase value of an xmc4xxx memory cell is 0x00, - * therefore, we cannot use the built in flash blank check and must - * implement our own */ - -/** Checks whether a memory region is zeroed. */ -static int xmc4xxx_blank_check_memory(struct target *target, - uint32_t address, uint32_t count, uint32_t *blank) -{ - struct working_area *erase_check_algorithm; - struct reg_param reg_params[3]; - struct armv7m_algorithm armv7m_info; - int retval; - - static const uint8_t erase_check_code[] = { -#include "../../../contrib/loaders/erase_check/armv7m_0_erase_check.inc" - }; - - /* make sure we have a working area */ - if (target_alloc_working_area(target, sizeof(erase_check_code), - &erase_check_algorithm) != ERROR_OK) - return ERROR_TARGET_RESOURCE_NOT_AVAILABLE; - - retval = target_write_buffer(target, erase_check_algorithm->address, - sizeof(erase_check_code), (uint8_t *)erase_check_code); - if (retval != ERROR_OK) - goto cleanup; - - armv7m_info.common_magic = ARMV7M_COMMON_MAGIC; - armv7m_info.core_mode = ARM_MODE_THREAD; - - init_reg_param(®_params[0], "r0", 32, PARAM_OUT); - buf_set_u32(reg_params[0].value, 0, 32, address); - - init_reg_param(®_params[1], "r1", 32, PARAM_OUT); - buf_set_u32(reg_params[1].value, 0, 32, count); - - init_reg_param(®_params[2], "r2", 32, PARAM_IN_OUT); - buf_set_u32(reg_params[2].value, 0, 32, 0x00); - - retval = target_run_algorithm(target, - 0, - NULL, - 3, - reg_params, - erase_check_algorithm->address, - erase_check_algorithm->address + (sizeof(erase_check_code) - 2), - 10000, - &armv7m_info); - - if (retval == ERROR_OK) - *blank = buf_get_u32(reg_params[2].value, 0, 32); - - destroy_reg_param(®_params[0]); - destroy_reg_param(®_params[1]); - destroy_reg_param(®_params[2]); - -cleanup: - target_free_working_area(target, erase_check_algorithm); - - return retval; -} - -static int xmc4xxx_flash_blank_check(struct flash_bank *bank) -{ - struct target *target = bank->target; - int i; - int retval = ERROR_OK; - uint32_t blank; - - if (bank->target->state != TARGET_HALTED) { - LOG_ERROR("Target not halted"); - return ERROR_TARGET_NOT_HALTED; - } - - for (i = 0; i < bank->num_sectors; i++) { - uint32_t address = bank->base + bank->sectors[i].offset; - uint32_t size = bank->sectors[i].size; - - LOG_DEBUG("Erase checking 0x%08"PRIx32, address); - retval = xmc4xxx_blank_check_memory(target, address, size, &blank); - - if (retval != ERROR_OK) - break; - - if (blank == 0x00) - bank->sectors[i].is_erased = 1; - else - bank->sectors[i].is_erased = 0; - } - - return retval; -} - static int xmc4xxx_write_page(struct flash_bank *bank, const uint8_t *pg_buf, uint32_t offset, bool user_config) { @@ -869,7 +777,7 @@ static int xmc4xxx_write(struct flash_bank *bank, const uint8_t *buffer, memcpy(&tmp_buf[start_pad], buffer, remaining); if (end_pad) { - LOG_INFO("Padding end of page @%08"PRIx32" by %d bytes", + LOG_INFO("Padding end of page @" TARGET_ADDR_FMT " by %d bytes", bank->base + offset, end_pad); memset(&tmp_buf[256 - end_pad], 0xff, end_pad); } @@ -895,7 +803,7 @@ abort_write_and_exit: } -static int xmc4xxx_get_info_command(struct flash_bank *bank, char *buf, int buf_size) +static int xmc4xxx_get_info_command(struct flash_bank *bank, struct command_invocation *cmd) { struct xmc4xxx_flash_bank *fb = bank->driver_priv; uint32_t scu_idcode; @@ -942,6 +850,14 @@ static int xmc4xxx_get_info_command(struct flash_bank *bank, char *buf, int buf_ break; } break; + case 0x300: + dev_str = "XMC4300"; + + switch (rev_id) { + case 0x1: + rev_str = "AA"; + } + break; case 0x400: dev_str = "XMC4400"; @@ -996,9 +912,7 @@ static int xmc4xxx_get_info_command(struct flash_bank *bank, char *buf, int buf_ break; default: - snprintf(buf, buf_size, - "Cannot identify target as an XMC4xxx. SCU_ID: %"PRIx32"\n", - scu_idcode); + command_print_sameline(cmd, "Cannot identify target as an XMC4xxx. SCU_ID: %"PRIx32 "\n", scu_idcode); return ERROR_OK; } @@ -1008,29 +922,27 @@ static int xmc4xxx_get_info_command(struct flash_bank *bank, char *buf, int buf_ snprintf(prot_str, sizeof(prot_str), "\nFlash is read protected"); bool otp_enabled = false; - for (int i = 0; i < bank->num_sectors; i++) + for (unsigned int i = 0; i < bank->num_sectors; i++) if (fb->write_prot_otp[i]) otp_enabled = true; /* If OTP Write protection is enabled (User 2), list each * sector that has it enabled */ - char otp_str[8]; + char otp_str[14]; if (otp_enabled) { strcat(prot_str, "\nOTP Protection is enabled for sectors:\n"); - for (int i = 0; i < bank->num_sectors; i++) { + for (unsigned int i = 0; i < bank->num_sectors; i++) { if (fb->write_prot_otp[i]) { snprintf(otp_str, sizeof(otp_str), "- %d\n", i); - strncat(prot_str, otp_str, ARRAY_SIZE(otp_str)); + strncat(prot_str, otp_str, sizeof(prot_str) - strlen(prot_str) - 1); } } } - if (rev_str != NULL) - snprintf(buf, buf_size, "%s - Rev: %s%s", - dev_str, rev_str, prot_str); + if (rev_str) + command_print_sameline(cmd, "%s - Rev: %s%s", dev_str, rev_str, prot_str); else - snprintf(buf, buf_size, "%s - Rev: unknown (0x%01x)%s", - dev_str, rev_id, prot_str); + command_print_sameline(cmd, "%s - Rev: unknown (0x%01x)%s", dev_str, rev_id, prot_str); return ERROR_OK; } @@ -1089,11 +1001,6 @@ static int xmc4xxx_flash_unprotect(struct flash_bank *bank, int32_t level) uint32_t addr; int res; - if ((level < 0) || (level > 1)) { - LOG_ERROR("Invalid user level. Must be 0-1"); - return ERROR_FAIL; - } - switch (level) { case 0: addr = UCB0_BASE; @@ -1101,6 +1008,9 @@ static int xmc4xxx_flash_unprotect(struct flash_bank *bank, int32_t level) case 1: addr = UCB1_BASE; break; + default: + LOG_ERROR("Invalid user level. Must be 0-1"); + return ERROR_FAIL; } res = xmc4xxx_erase_sector(bank, addr, true); @@ -1113,7 +1023,7 @@ static int xmc4xxx_flash_unprotect(struct flash_bank *bank, int32_t level) /* Reference: "XMC4500 Flash Protection.pptx" app note */ static int xmc4xxx_flash_protect(struct flash_bank *bank, int level, bool read_protect, - int first, int last) + unsigned int first, unsigned int last) { /* User configuration block buffers */ uint8_t ucp0_buf[8 * sizeof(uint32_t)] = {0}; @@ -1172,7 +1082,7 @@ static int xmc4xxx_flash_protect(struct flash_bank *bank, int level, bool read_p /* We need to fill out the procon register representation * that we will be writing to the device */ - for (int i = first; i <= last; i++) + for (unsigned int i = first; i <= last; i++) procon |= 1 << i; /* If read protection is requested, set the appropriate bit @@ -1229,7 +1139,8 @@ static int xmc4xxx_flash_protect(struct flash_bank *bank, int level, bool read_p return ERROR_OK; } -static int xmc4xxx_protect(struct flash_bank *bank, int set, int first, int last) +static int xmc4xxx_protect(struct flash_bank *bank, int set, unsigned int first, + unsigned int last) { int ret; struct xmc4xxx_flash_bank *fb = bank->driver_priv; @@ -1278,15 +1189,15 @@ static int xmc4xxx_protect_check(struct flash_bank *bank) return ret; } - int sectors = bank->num_sectors; + unsigned int sectors = bank->num_sectors; - /* On devices with 12 sectors, sectors 10 & 11 are ptected + /* On devices with 12 sectors, sectors 10 & 11 are protected * together instead of individually */ if (sectors == 12) sectors--; /* Clear the protection status */ - for (int i = 0; i < bank->num_sectors; i++) { + for (unsigned int i = 0; i < bank->num_sectors; i++) { bank->sectors[i].is_protected = 0; fb->write_prot_otp[i] = false; } @@ -1299,7 +1210,7 @@ static int xmc4xxx_protect_check(struct flash_bank *bank) /* Check for write protection on every available * sector */ - for (int j = 0; j < sectors; j++) { + for (unsigned int j = 0; j < sectors; j++) { int set = (protection[i] & (1 << j)) ? 1 : 0; bank->sectors[j].is_protected |= set; @@ -1320,7 +1231,7 @@ static int xmc4xxx_protect_check(struct flash_bank *bank) } } - /* XMC4xxx also supports read proptection, make a note + /* XMC4xxx also supports read protection, make a note * in the private driver structure */ if (protection[0] & PROCON_RPRO_MASK) fb->read_protected = true; @@ -1357,21 +1268,21 @@ COMMAND_HANDLER(xmc4xxx_handle_flash_password_command) errno = 0; /* We skip over the flash bank */ - fb->pw1 = strtol(CMD_ARGV[1], NULL, 16); + COMMAND_PARSE_NUMBER(u32, CMD_ARGV[1], fb->pw1); if (errno) return ERROR_COMMAND_SYNTAX_ERROR; - fb->pw2 = strtol(CMD_ARGV[2], NULL, 16); + COMMAND_PARSE_NUMBER(u32, CMD_ARGV[2], fb->pw2); if (errno) return ERROR_COMMAND_SYNTAX_ERROR; fb->pw_set = true; - command_print(CMD_CTX, "XMC4xxx flash passwords set to:\n"); - command_print(CMD_CTX, "-0x%08"PRIx32"\n", fb->pw1); - command_print(CMD_CTX, "-0x%08"PRIx32"\n", fb->pw2); + command_print(CMD, "XMC4xxx flash passwords set to:\n"); + command_print(CMD, "-0x%08"PRIx32"\n", fb->pw1); + command_print(CMD, "-0x%08"PRIx32"\n", fb->pw2); return ERROR_OK; } @@ -1414,7 +1325,8 @@ static const struct command_registration xmc4xxx_exec_command_handlers[] = { .usage = "bank_id user_level[0-1]", .help = "Permanently Removes flash protection (read and write) " "for the specified user level", - }, COMMAND_REGISTRATION_DONE + }, + COMMAND_REGISTRATION_DONE }; static const struct command_registration xmc4xxx_command_handlers[] = { @@ -1428,7 +1340,7 @@ static const struct command_registration xmc4xxx_command_handlers[] = { COMMAND_REGISTRATION_DONE }; -struct flash_driver xmc4xxx_flash = { +const struct flash_driver xmc4xxx_flash = { .name = "xmc4xxx", .commands = xmc4xxx_command_handlers, .flash_bank_command = xmc4xxx_flash_bank_command, @@ -1437,8 +1349,9 @@ struct flash_driver xmc4xxx_flash = { .read = default_flash_read, .probe = xmc4xxx_probe, .auto_probe = xmc4xxx_probe, - .erase_check = xmc4xxx_flash_blank_check, + .erase_check = default_flash_blank_check, .info = xmc4xxx_get_info_command, .protect_check = xmc4xxx_protect_check, .protect = xmc4xxx_protect, + .free_driver_priv = default_flash_free_driver_priv, };