X-Git-Url: https://review.openocd.org/gitweb?p=openocd.git;a=blobdiff_plain;f=src%2Fflash%2Fnor%2Fxmc4xxx.c;h=5677ef0f1634a7c2d853ea79942a63ab088d8a8d;hp=d4242a24df20e9312a996bd0663ee47c15d32f4d;hb=38030e011542a894237b517c065d22db97525954;hpb=e3a81e2e7bd533d1fbb048d9573d89483da6e830 diff --git a/src/flash/nor/xmc4xxx.c b/src/flash/nor/xmc4xxx.c index d4242a24df..5677ef0f16 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,6 +183,7 @@ /* Flash controller configuration values */ #define FLASH_ID_XMC4500 0xA2 +#define FLASH_ID_XMC4300_XMC4700_4800 0x92 #define FLASH_ID_XMC4100_4200 0x9C #define FLASH_ID_XMC4400 0x9F @@ -251,6 +254,10 @@ static const unsigned int sector_capacity_12[12] = { 16, 16, 16, 16, 16, 16, 16, 16, 128, 256, 256, 256 }; +static const unsigned int sector_capacity_16[16] = { + 16, 16, 16, 16, 16, 16, 16, 16, 128, 256, 256, 256, 256, 256, 256, 256 +}; + static int xmc4xxx_write_command_sequence(struct flash_bank *bank, struct xmc4xxx_command_seq *seq, int seq_len) @@ -285,6 +292,9 @@ static int xmc4xxx_load_bank_layout(struct flash_bank *bank) case 12: capacity = sector_capacity_12; break; + case 16: + capacity = sector_capacity_16; + break; default: LOG_ERROR("Unexpected number of sectors, %d\n", bank->num_sectors); @@ -309,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; } @@ -373,6 +383,10 @@ static int xmc4xxx_probe(struct flash_bank *bank) bank->num_sectors = 12; LOG_DEBUG("XMC4xxx: XMC4500 detected."); break; + case FLASH_ID_XMC4300_XMC4700_4800: + bank->num_sectors = 16; + LOG_DEBUG("XMC4xxx: XMC4700/4800 detected."); + break; default: LOG_ERROR("XMC4xxx: Unexpected flash ID. got %02" PRIx8, flash_id); @@ -603,106 +617,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. */ -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; - - /* see contrib/loaders/erase_check/armv7m_0_erase_check.s for src */ - - static const uint8_t erase_check_code[] = { - /* loop: */ - 0x03, 0x78, /* ldrb r3, [r0] */ - 0x01, 0x30, /* adds r0, #1 */ - 0x1A, 0x43, /* orrs r2, r2, r3 */ - 0x01, 0x39, /* subs r1, r1, #1 */ - 0xFA, 0xD1, /* bne loop */ - 0x00, 0xBE /* bkpt #0 */ - }; - - /* 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) - return retval; - - 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]); - - 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; - 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 ERROR_OK; -} - static int xmc4xxx_write_page(struct flash_bank *bank, const uint8_t *pg_buf, uint32_t offset, bool user_config) { @@ -937,6 +851,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"; @@ -971,6 +893,24 @@ static int xmc4xxx_get_info_command(struct flash_bank *bank, char *buf, int buf_ break; } break; + case 0x700: + dev_str = "XMC4700"; + + switch (rev_id) { + case 0x1: + rev_str = "EES-AA"; + break; + } + break; + case 0x800: + dev_str = "XMC4800"; + + switch (rev_id) { + case 0x1: + rev_str = "EES-AA"; + break; + } + break; default: snprintf(buf, buf_size, @@ -991,13 +931,13 @@ static int xmc4xxx_get_info_command(struct flash_bank *bank, char *buf, int buf_ /* 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++) { 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); } } } @@ -1066,11 +1006,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; @@ -1078,6 +1013,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); @@ -1414,7 +1352,7 @@ 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,