This is an automated email from Gerrit. Lars Poeschel (poeschell+open...@mailbox.org) just uploaded a new patch set to Gerrit, which you can find at http://openocd.zylin.com/5885
-- gerrit commit 5315aef17191048f52a911f8a4d8dc2915cbf438 Author: Lars Pöschel <poesc...@lemonage.de> Date: Fri Mar 13 13:15:17 2020 +0100 avrf.c: Add a driver for user signature This adds a driver to use the user signature part of some avr devices. Change-Id: Ia3607c4c66b83cc664fb2c4ee0d224ac4d39df7d Signed-off-by: Lars Pöschel <poeschell+open...@mailbox.org> diff --git a/src/flash/nor/avrf.c b/src/flash/nor/avrf.c index 31c07b1..5668408 100644 --- a/src/flash/nor/avrf.c +++ b/src/flash/nor/avrf.c @@ -54,6 +54,7 @@ struct avrf_type { int flash_page_num; int eeprom_page_size; int eeprom_page_num; + int user_signature_page_num; }; struct avrf_flash_bank { @@ -63,18 +64,19 @@ struct avrf_flash_bank { static const struct avrf_type avft_chips_info[] = { /* name, chip_id, flash_page_size, flash_page_num, - * eeprom_page_size, eeprom_page_num + * eeprom_page_size, eeprom_page_num, + * user_signature_num */ - {"atmega128", 0x9702, 256, 512, 8, 512}, - {"atmega128rfa1", 0xa701, 128, 512, 8, 512}, - {"atmega256rfr2", 0xa802, 256, 1024, 8, 1024}, - {"at90can128", 0x9781, 256, 512, 8, 512}, - {"at90usb128", 0x9782, 256, 512, 8, 512}, - {"atmega164p", 0x940a, 128, 128, 4, 128}, - {"atmega324p", 0x9508, 128, 256, 4, 256}, - {"atmega324pa", 0x9511, 128, 256, 4, 256}, - {"atmega644p", 0x960a, 256, 256, 8, 256}, - {"atmega1284p", 0x9705, 256, 512, 8, 512}, + {"atmega128", 0x9702, 256, 512, 8, 512, 0}, + {"atmega128rfa1", 0xa701, 128, 512, 8, 512, 3}, + {"atmega256rfr2", 0xa802, 256, 1024, 8, 1024, 3}, + {"at90can128", 0x9781, 256, 512, 8, 512, 0}, + {"at90usb128", 0x9782, 256, 512, 8, 512, 0}, + {"atmega164p", 0x940a, 128, 128, 4, 128, 0}, + {"atmega324p", 0x9508, 128, 256, 4, 256, 0}, + {"atmega324pa", 0x9511, 128, 256, 4, 256, 0}, + {"atmega644p", 0x960a, 256, 256, 8, 256, 0}, + {"atmega1284p", 0x9705, 256, 512, 8, 512, 0}, }; /* avr program functions */ @@ -118,12 +120,12 @@ static int avr_jtagprg_leaveprogmode(struct avr_common *avr) return ERROR_OK; } -static int avr_jtagprg_chiperase(struct avr_common *avr) +static int avr_jtagprg_chiperase(struct avr_common *avr, uint32_t enter_cmd) { uint32_t poll_value; avr_jtag_sendinstr(avr->jtag_info.tap, NULL, AVR_JTAG_INS_PROG_COMMANDS); - avr_jtag_senddat(avr->jtag_info.tap, NULL, 0x2380, AVR_JTAG_REG_ProgrammingCommand_Len); + avr_jtag_senddat(avr->jtag_info.tap, NULL, enter_cmd /* 0x2380 */, AVR_JTAG_REG_ProgrammingCommand_Len); avr_jtag_senddat(avr->jtag_info.tap, NULL, 0x3180, AVR_JTAG_REG_ProgrammingCommand_Len); avr_jtag_senddat(avr->jtag_info.tap, NULL, 0x3380, AVR_JTAG_REG_ProgrammingCommand_Len); avr_jtag_senddat(avr->jtag_info.tap, NULL, 0x3380, AVR_JTAG_REG_ProgrammingCommand_Len); @@ -147,12 +149,13 @@ static int avr_jtagprg_writeflashpage(struct avr_common *avr, const uint8_t *page_buf, uint32_t buf_size, uint32_t addr, - uint32_t page_size) + uint32_t page_size, + uint32_t enter_cmd) { uint32_t poll_value; avr_jtag_sendinstr(avr->jtag_info.tap, NULL, AVR_JTAG_INS_PROG_COMMANDS); - avr_jtag_senddat(avr->jtag_info.tap, NULL, 0x2310, AVR_JTAG_REG_ProgrammingCommand_Len); + avr_jtag_senddat(avr->jtag_info.tap, NULL, enter_cmd/* 0x2310 */, AVR_JTAG_REG_ProgrammingCommand_Len); /* load extended high byte */ if (ext_addressing) @@ -338,8 +341,7 @@ FLASH_BANK_COMMAND_HANDLER(avrf_flash_bank_command) return ERROR_OK; } -static int avrf_erase(struct flash_bank *bank, unsigned int first, - unsigned int last) +static int avrf_common_erase(struct flash_bank *bank, int first, int last, uint32_t enter_cmd) { struct target *target = bank->target; struct avr_common *avr = target->arch_info; @@ -356,14 +358,19 @@ static int avrf_erase(struct flash_bank *bank, unsigned int first, if (status != ERROR_OK) return status; - status = avr_jtagprg_chiperase(avr); + status = avr_jtagprg_chiperase(avr, enter_cmd); if (status != ERROR_OK) return status; return avr_jtagprg_leaveprogmode(avr); } -static int avrf_write(struct flash_bank *bank, const uint8_t *buffer, uint32_t offset, uint32_t count) +static int avrf_erase(struct flash_bank *bank, unsigned int first, unsigned int last) +{ + return avrf_common_erase(bank, first, last, 0x2380); +} + +static int avrf_common_write(struct flash_bank *bank, const uint8_t *buffer, uint32_t offset, uint32_t count, uint32_t enter_cmd) { struct target *target = bank->target; struct avr_common *avr = target->arch_info; @@ -405,7 +412,8 @@ static int avrf_write(struct flash_bank *bank, const uint8_t *buffer, uint32_t o buffer + cur_size, cur_buffer_size, offset + cur_size, - page_size); + page_size, + enter_cmd); count -= cur_buffer_size; cur_size += cur_buffer_size; @@ -415,7 +423,12 @@ static int avrf_write(struct flash_bank *bank, const uint8_t *buffer, uint32_t o return avr_jtagprg_leaveprogmode(avr); } -static int avrf_read(struct flash_bank *bank, uint8_t *buffer, uint32_t offset, uint32_t count) +static int avrf_write(struct flash_bank *bank, const uint8_t *buffer, uint32_t offset, uint32_t count) +{ + return avrf_common_write(bank, buffer, offset, count, 0x2310); +} + +static int avr_common_flash_read(struct flash_bank *bank, uint8_t *buffer, uint32_t offset, uint32_t count, uint32_t enter_cmd) { struct target *target = bank->target; struct avr_common *avr = target->arch_info; @@ -445,7 +458,7 @@ static int avrf_read(struct flash_bank *bank, uint8_t *buffer, uint32_t offset, ext_addressing = false; avr_jtag_sendinstr(avr->jtag_info.tap, NULL, AVR_JTAG_INS_PROG_COMMANDS); - avr_jtag_senddat(avr->jtag_info.tap, NULL, 0x2302, AVR_JTAG_REG_ProgrammingCommand_Len); + avr_jtag_senddat(avr->jtag_info.tap, NULL, enter_cmd, AVR_JTAG_REG_ProgrammingCommand_Len); for (uint32_t i = 0; i < count; i += 2) { /* load extended high byte */ @@ -480,6 +493,11 @@ static int avrf_read(struct flash_bank *bank, uint8_t *buffer, uint32_t offset, return avr_jtagprg_leaveprogmode(avr); } +static int avrf_read(struct flash_bank *bank, uint8_t *buffer, uint32_t offset, uint32_t count) +{ + return avr_common_flash_read(bank, buffer, offset, count, 0x2302); +} + #define EXTRACT_MFG(X) (((X) & 0xffe) >> 1) #define EXTRACT_PART(X) (((X) & 0xffff000) >> 12) #define EXTRACT_VER(X) (((X) & 0xf0000000) >> 28) @@ -594,7 +612,7 @@ static int avrf_mass_erase(struct flash_bank *bank) } if ((ERROR_OK != avr_jtagprg_enterprogmode(avr)) - || (ERROR_OK != avr_jtagprg_chiperase(avr)) + || (ERROR_OK != avr_jtagprg_chiperase(avr, 0x2380)) || (ERROR_OK != avr_jtagprg_leaveprogmode(avr))) return ERROR_FAIL; @@ -1074,3 +1092,141 @@ const struct flash_driver avr_fuses = { .write = avr_fuses_write, .free_driver_priv = default_flash_free_driver_priv, }; + +/* + * User Signature data + */ +struct avr_user_signature_flash_bank { + int ppage_size; + int probed; + const struct avrf_type *avr_info; +}; + +static int avr_user_signature_erase(struct flash_bank *bank, unsigned int first, unsigned int last) +{ + return avrf_common_erase(bank, first, last, 0x2384); +} + +static int avr_user_signature_write(struct flash_bank *bank, const uint8_t *buffer, uint32_t offset, uint32_t count) +{ + return avrf_common_write(bank, buffer, offset, count, 0x2312); +} + +static int avr_user_signature_read(struct flash_bank *bank, uint8_t *buffer, uint32_t offset, uint32_t count) +{ + return avr_common_flash_read(bank, buffer, offset, count, 0x2308); +} + +static int avr_user_signature_probe(struct flash_bank *bank) +{ + uint8_t ver; + struct avrf_flash_bank *avrf_info = bank->driver_priv; + const struct avrf_type *avr_info; + int error = avrf_identify_chip(bank, &avr_info, &ver); + + if ((error == ERROR_OK) && (avr_info->user_signature_page_num > 0)) { + if (bank->sectors) { + free(bank->sectors); + bank->sectors = NULL; + } + + /* chip found */ + bank->base = 0x00000000; + bank->size = (avr_info->flash_page_size * avr_info->user_signature_page_num); + bank->num_sectors = avr_info->user_signature_page_num; + bank->sectors = malloc(sizeof(struct flash_sector) * avr_info->user_signature_page_num); + + for (int i = 0; i < avr_info->user_signature_page_num; i++) { + bank->sectors[i].offset = i * avr_info->flash_page_size; + bank->sectors[i].size = avr_info->flash_page_size; + bank->sectors[i].is_erased = -1; + bank->sectors[i].is_protected = -1; + } + + avrf_info->probed = true; + return ERROR_OK; + } + + avrf_info->probed = true; + if (error == ERROR_FLASH_OPERATION_FAILED) { + /* chip not supported */ + LOG_ERROR("device id is not supported for avr"); + return ERROR_FAIL; + } + + if (avr_info->user_signature_page_num == 0) { + LOG_ERROR("This chip does not have user signature pages."); + } + + return error; +} + +static int avr_user_signature_auto_probe(struct flash_bank *bank) +{ + struct avrf_flash_bank *avrf_info = bank->driver_priv; + if (avrf_info->probed) + return ERROR_OK; + return avr_user_signature_probe(bank); +} + +FLASH_BANK_COMMAND_HANDLER(avr_user_signature_flash_bank_command) +{ + struct avr_user_signature_flash_bank *avr_user_signature_bank; + + avr_user_signature_bank = malloc(sizeof(struct avr_user_signature_flash_bank)); + if (!avr_user_signature_bank) + return ERROR_FLASH_OPERATION_FAILED; + + avr_user_signature_bank->probed = false; + bank->driver_priv = avr_user_signature_bank; + + return ERROR_OK; +} + +static int avr_user_signature_info(struct flash_bank *bank, char *buf, int buf_size) +{ + uint8_t ver; + struct avr_user_signature_flash_bank *avr_user_signature_bank = bank->driver_priv; + const struct avrf_type *avr_info; + int error = avrf_identify_chip(bank, &avr_info, &ver); + + if (error == ERROR_OK) { + /* chip found */ + snprintf(buf, buf_size, "%s - Rev: 0x%" PRIx32 "", avr_info->name, + ver); + avr_user_signature_bank->avr_info = avr_info; + } else + if (error == ERROR_FLASH_OPERATION_FAILED) + snprintf(buf, buf_size, "Cannot identify target as a avr\n"); + + return error; +} + +static const struct command_registration avr_user_signature_exec_command_handlers[] = { + COMMAND_REGISTRATION_DONE +}; + +static const struct command_registration avr_user_signature_command_handlers[] = { + { + .name = "avr_user_signature", + .mode = COMMAND_ANY, + .help = "AVR flash command group", + .usage = "", + .chain = avr_user_signature_exec_command_handlers, + }, + COMMAND_REGISTRATION_DONE +}; + +const struct flash_driver avr_user_signature = { + .name = "avr_user_signature", + .commands = avr_user_signature_command_handlers, + .flash_bank_command = avr_user_signature_flash_bank_command, + .erase = avr_user_signature_erase, + .write = avr_user_signature_write, + .read = avr_user_signature_read, + .probe = avr_user_signature_probe, + .auto_probe = avr_user_signature_auto_probe, + .erase_check = default_flash_blank_check, + .info = avr_user_signature_info, + .free_driver_priv = default_flash_free_driver_priv, +}; diff --git a/src/flash/nor/drivers.c b/src/flash/nor/drivers.c index ebaab91..ca2f1cf 100644 --- a/src/flash/nor/drivers.c +++ b/src/flash/nor/drivers.c @@ -34,6 +34,7 @@ extern const struct flash_driver atsamv_flash; extern const struct flash_driver avr_flash; extern const struct flash_driver avr_eeprom; extern const struct flash_driver avr_fuses; +extern const struct flash_driver avr_user_signature; extern const struct flash_driver bluenrgx_flash; extern const struct flash_driver cc3220sf_flash; extern const struct flash_driver cc26xx_flash; @@ -108,6 +109,7 @@ static const struct flash_driver * const flash_drivers[] = { &avr_flash, &avr_eeprom, &avr_fuses, + &avr_user_signature, &bluenrgx_flash, &cc3220sf_flash, &cc26xx_flash, -- _______________________________________________ OpenOCD-devel mailing list OpenOCD-devel@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/openocd-devel