123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296 |
- /* Copyright (C) 2017 RDA Technologies Limited and/or its affiliates("RDA").
- * All rights reserved.
- *
- * This software is supplied "AS IS" without any warranties.
- * RDA assumes no responsibility or liability for the use of the software,
- * conveys no license or title under any patent, copyright, or mask work
- * right to the product. RDA reserves the right to make changes in the
- * software without notification. RDA also make no representation or
- * warranty that such application will be suitable for the specified use
- * without further testing or modification.
- */
- // #define LOCAL_LOG_LEVEL LOG_LEVEL_DEBUG
- #include "boot_fdl.h"
- #include "boot_entry.h"
- #include "boot_platform.h"
- #include "boot_debuguart.h"
- #include "boot_mem.h"
- #include "boot_spi_flash.h"
- #include "boot_bsl_cmd.h"
- #include "hal_chip.h"
- #include "hal_config.h"
- #include "hal_spi_flash.h"
- #include "hal_adi_bus.h"
- #include "cmsis_core.h"
- #include "osi_log.h"
- #include "osi_api.h"
- #include "drv_names.h"
- #include <sys/reent.h>
- #include <stdint.h>
- #include <string.h>
- #include <machine/endian.h>
- #define FDL_SIZE_4K (0x1000)
- #define FDL_SIZE_32K (0x8000)
- #define FDL_SIZE_64K (0x10000)
- #define ALIGN_SIZE(v, a) (((v) & ~((a)-1)) == 0 ? 1 : 0)
- #define FLASH_TEST_ACK 0xD0
- #define FLASH_TEST_ERR 0xD1
- #define PATTERN_LEN 4096
- uint32_t test_cnt;
- static uint8_t pattern[PATTERN_LEN];
- struct flashtest_time
- {
- uint32_t erase;
- uint32_t write;
- };
- typedef struct flashtest_time flashtest_time_t;
- static void _arrayValueInit(void)
- {
- uint16_t arr_len = PATTERN_LEN;
- uint16_t val_len = 64;
- uint8_t values[] = {0xa, 0x5, 0xa, 0x5, 0xa, 0x5, 0xa, 0x5, 0x5, 0xa, 0x5, 0xa, 0x5, 0xa, 0x5, 0xa,
- 0x0, 0x0, 0x0, 0x0, 0xf, 0xf, 0xf, 0xf, 0xf, 0xf, 0xf, 0xf, 0x0, 0x0, 0x0, 0x0,
- 0xf, 0xf, 0x0, 0x0, 0xf, 0xf, 0x0, 0x0, 0x0, 0x0, 0xf, 0xf, 0x0, 0x0, 0xf, 0xf,
- 0xf, 0x0, 0xf, 0x0, 0xf, 0x0, 0xf, 0x0, 0x0, 0xf, 0x0, 0xf, 0x0, 0xf, 0x0, 0xf};
- int i = 0;
- while (i < arr_len)
- {
- memcpy(&pattern[i], values, val_len);
- i += val_len;
- }
- OSI_LOGI(0x10009096, "FLASH: init pattern %x %x %x ... %x %x %x", pattern[0], pattern[1], pattern[2], pattern[4093], pattern[4094], pattern[4095]);
- }
- static bool _bootFlashChipErase(bootSpiFlash_t *flash)
- {
- bootSpiFlashChipErase(flash);
- uint8_t *rd_data = (uint8_t *)bootSpiFlashMapAddress(flash, 0);
- uint32_t rd_size = bootSpiFlashCapacity(flash);
- while (rd_size > 0)
- {
- if (*(rd_data++) != 0xff)
- {
- OSI_LOGE(0x10009097, "FLASH: Erase whole flash error2 0x%x != 0xff...", rd_data);
- return false;
- }
- rd_size--;
- }
- return true;
- }
- static bool _bootFlashErase(bootSpiFlash_t *flash, uint32_t offset, size_t size, size_t sector)
- {
- bool res = false;
- switch (sector)
- {
- case FDL_SIZE_4K:
- case FDL_SIZE_32K:
- case FDL_SIZE_64K:
- res = bootSpiFlashErase(flash, offset, size);
- break;
- default:
- OSI_LOGE(0x10009098, "FLASH: sector invalid 0x%x", sector);
- }
- return res;
- }
- static bool _bootFlashWrite(bootSpiFlash_t *flash, uint32_t offset, size_t size)
- {
- uint32_t len = PATTERN_LEN;
- uint32_t wr_addr = offset;
- uint32_t wr_size = size;
- while (wr_size > 0)
- {
- if (!bootSpiFlashWrite(flash, wr_addr, &pattern[0], len))
- {
- OSI_LOGE(0x10009099, "FLASH: Write flash error offset %x", wr_addr);
- return false;
- }
- wr_addr += len;
- wr_size -= len;
- }
- // check write ok
- uint32_t rd_size = size;
- const void *fdata = bootSpiFlashMapAddress(flash, offset);
- uint8_t *rd_data = (uint8_t *)fdata;
- while (rd_size > 0)
- {
- for (int i = 0; i < len; i++)
- {
- if (*(rd_data + i) != pattern[i])
- {
- OSI_LOGE(0x1000909a, "FLASH: Check write flash error %x shoule be %x", *(rd_data + i), pattern[i]);
- return false;
- }
- }
- rd_data += len;
- rd_size -= len;
- }
- return true;
- }
- static void flashEraseWriteStart(fdlEngine_t *fdl, fdlPacket_t *pkt, bootSpiFlash_t *flash)
- {
- uint32_t *ptr = (uint32_t *)pkt->content;
- uint32_t offset = __ntohl(*ptr++);
- uint32_t test_size = __ntohl(*ptr++);
- uint32_t sector_size = __ntohl(*ptr++);
- flashtest_time_t flash_time = {};
- osiElapsedTimer_t elapsed;
- OSI_LOGI(0x1000909b, "FLASH: offset 0x%x, size 0x%x sector 0x%x...", offset, test_size, sector_size);
- if (!offset && !test_size)
- {
- osiElapsedTimerStart(&elapsed);
- if (!_bootFlashChipErase(flash))
- {
- OSI_LOGE(0x1000909c, "FLASH: erase whole flash fail");
- const char erase_string[] = "Erase whole flash fail";
- size_t er_len = strlen(erase_string);
- fdlEngineSendRespData(fdl, FLASH_TEST_ERR, erase_string, er_len);
- osiPanic();
- }
- flash_time.erase = osiElapsedTime(&elapsed);
- flash_time.write = 0;
- OSI_LOGI(0x1000909d, "FLASH: erase whole flash time %d, use %d ms ...", ++test_cnt, flash_time.erase);
- }
- else
- {
- if (!bootSpiFlashOffsetValid(flash, offset) ||
- !bootSpiFlashOffsetValid(flash, offset + test_size - 1))
- {
- OSI_LOGE(0x1000909e, "FLASH: addr and size invalid");
- // send cmd err
- const char cmd_string[] = "Cmd addr or size invalid";
- size_t cmd_len = strlen(cmd_string);
- fdlEngineSendRespData(fdl, FLASH_TEST_ERR, cmd_string, cmd_len);
- }
- OSI_LOGI(0x1000909f, "start test flash...");
- // erase flash test
- osiElapsedTimerStart(&elapsed);
- if (!_bootFlashErase(flash, offset, test_size, sector_size))
- {
- OSI_LOGE(0x100090a0, "FLASH: erase flash error");
- const char sector_string[] = "Erase sector flash fail";
- size_t sec_len = strlen(sector_string);
- fdlEngineSendRespData(fdl, FLASH_TEST_ERR, sector_string, sec_len);
- osiPanic();
- }
- flash_time.erase = osiElapsedTime(&elapsed);
- // write flash test
- osiElapsedTimerStart(&elapsed);
- if (!_bootFlashWrite(flash, offset, test_size))
- {
- OSI_LOGE(0x100090a1, "FLASH: write flash error");
- const char wr_string[] = "Write sector flash fail";
- size_t wr_len = strlen(wr_string);
- fdlEngineSendRespData(fdl, FLASH_TEST_ERR, wr_string, wr_len);
- osiPanic();
- }
- flash_time.write = osiElapsedTime(&elapsed);
- OSI_LOGI(0x100090a2, "FLASH:time %d erase/write ~~~ %d ms / %d ms...", ++test_cnt, flash_time.erase, flash_time.write);
- }
- fdlEngineSendRespData(fdl, FLASH_TEST_ACK, &flash_time, sizeof(flashtest_time_t));
- }
- static void _process_flash(fdlEngine_t *fdl, fdlPacket_t *pkt, void *flash_)
- {
- if (fdl == NULL || pkt == NULL)
- osiPanic();
- bootSpiFlash_t *flash = (bootSpiFlash_t *)flash_;
- switch (pkt->type)
- {
- case BSL_CMD_CONNECT:
- fdlEngineSendRespNoData(fdl, BSL_REP_ACK);
- break;
- case BSL_CMD_ERASE_FLASH:
- flashEraseWriteStart(fdl, pkt, flash);
- break;
- default:
- OSI_LOGE(0x1000908e, "FDL1, cmd not support yet %x", pkt->type);
- osiPanic();
- break;
- }
- }
- void bootStart(uint32_t param)
- {
- OSI_CLEAR_SECTION(bss);
- halClockInit(HAL_CLOCK_INIT_FDL);
- __FPU_Enable();
- _impure_ptr = _GLOBAL_REENT;
- bootTraceInit(true);
- halAdiBusInit();
- extern unsigned __sram_heap_start[];
- extern unsigned __sram_heap_end[];
- unsigned sram_heap_size = OSI_PTR_DIFF(__sram_heap_end, __sram_heap_start);
- bootHeapInit((uint32_t *)__sram_heap_start, sram_heap_size, 0, 0);
- OSI_LOGI(0x100090a3, "FLASH_TEST_RUN ......");
- fdlChannel_t *ch = fdlOpenUart(CONFIG_FDL_DEFAULT_UART, CONFIG_FDL_UART_BAUD, true);
- if (ch == NULL)
- {
- OSI_LOGE(0x100090a4, "FDL1 fail, can't open uart fdl channel");
- osiPanic();
- }
- fdlEngine_t *fdl = fdlEngineCreate(ch, CONFIG_FDL_PACKET_MAX_LEN);
- if (fdl == NULL)
- {
- OSI_LOGE(0x100090a5, "FDL1 fail, can not create fdl engine");
- osiPanic();
- }
- for (;;)
- {
- uint8_t sync;
- if (fdlEngineReadRaw(fdl, &sync, 1))
- {
- if (sync == HDLC_FLAG)
- {
- if (!fdlEngineSendVersion(fdl))
- {
- OSI_LOGE(0x100090a6, "FDL1 fail, fail to send version string");
- osiPanic();
- }
- break;
- }
- }
- }
- _arrayValueInit();
- bootSpiFlash_t *flash = bootSpiFlashOpen(DRV_NAME_SPI_FLASH);
- fdlEngineProcess(fdl, _process_flash, NULL, flash);
- // never return here
- fdlEngineDestroy(fdl);
- osiPanic();
- }
|