X-Git-Url: https://review.openocd.org/gitweb?p=openocd.git;a=blobdiff_plain;f=src%2Fflash%2Fnor%2Fstmsmi.c;h=4d38e949bfca9b487ada44a0c76dc07c48318123;hp=dffc9cd07a86b2de18919fe31ee0f722a0ddeb8e;hb=463257903e61947c942df3fc79519bb49074dd10;hpb=15e19011eae841ca4688f1a6053a4d76419bf10e diff --git a/src/flash/nor/stmsmi.c b/src/flash/nor/stmsmi.c index dffc9cd07a..4d38e949bf 100644 --- a/src/flash/nor/stmsmi.c +++ b/src/flash/nor/stmsmi.c @@ -12,9 +12,7 @@ * 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. * + * along with this program. If not, see . * ***************************************************************************/ /* STM Serial Memory Interface (SMI) controller is a SPI bus controller @@ -120,7 +118,7 @@ struct stmsmi_flash_bank { int probed; uint32_t io_base; uint32_t bank_num; - struct flash_device *dev; + const struct flash_device *dev; }; struct stmsmi_target { @@ -130,7 +128,7 @@ struct stmsmi_target { uint32_t io_base; }; -static struct stmsmi_target target_devices[] = { +static const struct stmsmi_target target_devices[] = { /* name, tap_idcode, smi_base, io_base */ { "SPEAr3xx/6xx", 0x07926041, 0xf8000000, 0xfc000000 }, { "STR75x", 0x4f1f0041, 0x80000000, 0x90000000 }, @@ -162,7 +160,7 @@ FLASH_BANK_COMMAND_HANDLER(stmsmi_flash_bank_command) /* timeout in ms */ static int poll_tff(struct target *target, uint32_t io_base, int timeout) { - long long endtime; + int64_t endtime; if (SMI_READ_REG(SMI_SR) & SMI_TFF) return ERROR_OK; @@ -213,7 +211,7 @@ static int wait_till_ready(struct flash_bank *bank, int timeout) { uint32_t status; int retval; - long long endtime; + int64_t endtime; endtime = timeval_ms() + timeout; do { @@ -271,17 +269,14 @@ static int smi_write_enable(struct flash_bank *bank) static uint32_t erase_command(struct stmsmi_flash_bank *stmsmi_info, uint32_t offset) { - union { - uint32_t command; - uint8_t x[4]; - } cmd; - - cmd.x[0] = stmsmi_info->dev->erase_cmd; - cmd.x[1] = offset >> 16; - cmd.x[2] = offset >> 8; - cmd.x[3] = offset; - - return cmd.command; + uint8_t cmd_bytes[] = { + stmsmi_info->dev->erase_cmd, + offset >> 16, + offset >> 8, + offset + }; + + return le_to_h_u32(cmd_bytes); } static int smi_erase_sector(struct flash_bank *bank, int sector) @@ -350,6 +345,9 @@ static int stmsmi_erase(struct flash_bank *bank, int first, int last) } } + if (stmsmi_info->dev->erase_cmd == 0x00) + return ERROR_FLASH_OPER_UNSUPPORTED; + for (sector = first; sector <= last; sector++) { retval = smi_erase_sector(bank, sector); if (retval != ERROR_OK) @@ -372,7 +370,7 @@ static int stmsmi_protect(struct flash_bank *bank, int set, return ERROR_OK; } -static int smi_write_buffer(struct flash_bank *bank, uint8_t *buffer, +static int smi_write_buffer(struct flash_bank *bank, const uint8_t *buffer, uint32_t address, uint32_t len) { struct target *target = bank->target; @@ -397,7 +395,7 @@ static int smi_write_buffer(struct flash_bank *bank, uint8_t *buffer, return ERROR_OK; } -static int stmsmi_write(struct flash_bank *bank, uint8_t *buffer, +static int stmsmi_write(struct flash_bank *bank, const uint8_t *buffer, uint32_t offset, uint32_t count) { struct target *target = bank->target; @@ -433,7 +431,9 @@ static int stmsmi_write(struct flash_bank *bank, uint8_t *buffer, } } - page_size = stmsmi_info->dev->pagesize; + /* if no valid page_size, use reasonable default */ + page_size = stmsmi_info->dev->pagesize ? + stmsmi_info->dev->pagesize : SPIFLASH_DEF_PAGESIZE; /* unaligned buffer head */ if (count > 0 && (offset & 3) != 0) { @@ -526,10 +526,10 @@ static int stmsmi_probe(struct flash_bank *bank) { struct target *target = bank->target; struct stmsmi_flash_bank *stmsmi_info = bank->driver_priv; - uint32_t io_base; + uint32_t io_base, sectorsize; struct flash_sector *sectors; uint32_t id = 0; /* silence uninitialized warning */ - struct stmsmi_target *target_device; + const struct stmsmi_target *target_device; int retval; if (stmsmi_info->probed) @@ -575,7 +575,7 @@ static int stmsmi_probe(struct flash_bank *bank) return retval; stmsmi_info->dev = NULL; - for (struct flash_device *p = flash_devices; p->name ; p++) + for (const struct flash_device *p = flash_devices; p->name ; p++) if (p->device_id == id) { stmsmi_info->dev = p; break; @@ -591,10 +591,18 @@ static int stmsmi_probe(struct flash_bank *bank) /* Set correct size value */ bank->size = stmsmi_info->dev->size_in_bytes; + if (bank->size <= (1UL << 16)) + LOG_WARNING("device needs 2-byte addresses - not implemented"); + if (bank->size > (1UL << 24)) + LOG_WARNING("device needs paging or 4-byte addresses - not implemented"); + + /* if no sectors, treat whole bank as single sector */ + sectorsize = stmsmi_info->dev->sectorsize ? + stmsmi_info->dev->sectorsize : stmsmi_info->dev->size_in_bytes; /* create and fill sectors array */ bank->num_sectors = - stmsmi_info->dev->size_in_bytes / stmsmi_info->dev->sectorsize; + stmsmi_info->dev->size_in_bytes / sectorsize; sectors = malloc(sizeof(struct flash_sector) * bank->num_sectors); if (sectors == NULL) { LOG_ERROR("not enough memory"); @@ -602,8 +610,8 @@ static int stmsmi_probe(struct flash_bank *bank) } for (int sector = 0; sector < bank->num_sectors; sector++) { - sectors[sector].offset = sector * stmsmi_info->dev->sectorsize; - sectors[sector].size = stmsmi_info->dev->sectorsize; + sectors[sector].offset = sector * sectorsize; + sectors[sector].size = sectorsize; sectors[sector].is_erased = -1; sectors[sector].is_protected = 1; } @@ -638,7 +646,7 @@ static int get_stmsmi_info(struct flash_bank *bank, char *buf, int buf_size) } snprintf(buf, buf_size, "\nSMI flash information:\n" - " Device \'%s\' (ID 0x%08x)\n", + " Device \'%s\' (ID 0x%08" PRIx32 ")\n", stmsmi_info->dev->name, stmsmi_info->dev->device_id); return ERROR_OK; @@ -656,4 +664,5 @@ struct flash_driver stmsmi_flash = { .erase_check = default_flash_blank_check, .protect_check = stmsmi_protect_check, .info = get_stmsmi_info, + .free_driver_priv = default_flash_free_driver_priv, };