1 /* SPDX-License-Identifier: BSD-3-Clause */
3 /******************************************************************************
5 * Copyright (C) 2017-2018 Texas Instruments Incorporated - http://www.ti.com/
7 ******************************************************************************/
11 #include "flashloader.h"
14 /* Array holding erased state of the flash sectors. */
15 static bool g_is_erased[FLASH_MAX_SECTOR_COUNT];
17 extern uint8_t g_retain_buf[];
19 uint32_t flashloader_init(struct flash_params *params, uint8_t *buf1,
22 /* Initialize params buffers */
23 memset((void *)params, 0, 2 * sizeof(struct flash_params));
24 params[0].buf_addr = (uint32_t)buf1;
25 params[1].buf_addr = (uint32_t)buf2;
27 /* Mark all sectors at "not erased" */
28 memset(g_is_erased, false, sizeof(g_is_erased));
33 uint32_t flashloader_erase_and_program(uint8_t *src, uint32_t address,
36 if (byte_count > BUFFER_LEN)
37 return STATUS_FAILED_INVALID_ARGUMENTS;
39 /* Erase affected sectors */
40 uint32_t status = flashloader_erase_sectors(address, byte_count);
42 if (status != STATUS_OK)
46 status = flashloader_program(src, address, byte_count);
51 uint32_t flashloader_program_with_retain(uint8_t *src, uint32_t address,
54 #if (BUFFER_LEN > FLASH_ERASE_SIZE)
55 #error Buffer size cannot be larger than the flash sector size!
58 uint32_t first_sector_idx;
59 uint32_t last_sector_idx;
60 uint32_t status = STATUS_OK;
63 first_sector_idx = flashloader_address_to_sector(address);
64 last_sector_idx = flashloader_address_to_sector(address + byte_count - 1);
66 /* Mark all sectors as "not erased" before starting */
67 memset(g_is_erased, false, sizeof(g_is_erased));
69 uint32_t sec_offset = address % FLASH_ERASE_SIZE;
71 uint32_t src_offset = 0;
73 for (i = first_sector_idx; i <= last_sector_idx; i++) {
75 /* Chop off at sector boundary if data goes into the next sector. */
76 curr_count = byte_count;
77 if ((address + byte_count) > ((i+1) * FLASH_ERASE_SIZE))
78 curr_count -= (address + byte_count) % FLASH_ERASE_SIZE;
80 /* Copy flash sector to retain buffer */
81 memcpy(g_retain_buf, (void *)(i * FLASH_ERASE_SIZE), FLASH_ERASE_SIZE);
83 /* Copy data buffer to retain buffer */
84 memcpy(&g_retain_buf[sec_offset], &src[src_offset], curr_count);
86 /* Erase and program from retain buffer */
87 status = flashloader_erase_and_program(g_retain_buf,
88 (i * FLASH_ERASE_SIZE), FLASH_ERASE_SIZE);
89 if (status != STATUS_OK)
92 address += curr_count;
93 sec_offset = address % FLASH_ERASE_SIZE;
94 byte_count -= curr_count;
95 src_offset += curr_count;
101 uint32_t flashloader_erase_all(void)
103 if (flash_bank_erase(true) != FAPI_STATUS_SUCCESS)
104 return STATUS_FAILED_ERASE_ALL;
106 memset(g_is_erased, true, sizeof(g_is_erased));
111 uint32_t flashloader_erase_sectors(uint32_t address, uint32_t byte_count)
113 uint32_t first_sector_idx;
114 uint32_t last_sector_idx;
118 /* Floor address to the start of the sector and convert to sector number */
119 first_sector_idx = flashloader_address_to_sector(address);
120 last_sector_idx = flashloader_address_to_sector(address + byte_count - 1);
122 /* Erase given sector(s) */
123 for (idx = first_sector_idx; idx <= last_sector_idx; idx++) {
125 /* Only erase sectors that haven't already been erased */
126 if (g_is_erased[idx] == false) {
127 status = flash_sector_erase(idx * FLASH_ERASE_SIZE);
128 if (status != FAPI_STATUS_SUCCESS) {
129 status = (STATUS_FAILED_SECTOR_ERASE |
130 ((idx << STATUS_EXT_INFO_S) & STATUS_EXT_INFO_M) |
131 ((status << STATUS_ROM_CODE_S) & STATUS_ROM_CODE_M));
134 g_is_erased[idx] = true;
141 uint32_t flashloader_program(uint8_t *src, uint32_t address,
144 uint32_t status = flash_program(src, address, byte_count);
145 if (status != FAPI_STATUS_SUCCESS) {
146 status = (STATUS_FAILED_PROGRAM |
147 ((status << STATUS_ROM_CODE_S) & STATUS_ROM_CODE_M));