1 /****************************************************************************** 2 * Copyright (c) 2022 Telink Semiconductor (Shanghai) Co., Ltd. ("TELINK") 3 * All rights reserved. 4 * 5 * Licensed under the Apache License, Version 2.0 (the "License"); 6 * you may not use this file except in compliance with the License. 7 * You may obtain a copy of the License at 8 * 9 * http://www.apache.org/licenses/LICENSE-2.0 10 * 11 * Unless required by applicable law or agreed to in writing, software 12 * distributed under the License is distributed on an "AS IS" BASIS, 13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 * See the License for the specific language governing permissions and 15 * limitations under the License. 16 * 17 *****************************************************************************/ 18 19 #include <B91/flash.h> 20 21 #include <bootloader.h> 22 23 #define FLASH_START 0x20000000u 24 25 #define META_DATA_ADDR (1024 * 1024 - PAGE_SIZE) 26 27 typedef struct { 28 UINT32 run_addr; 29 } ota_meta_data_t; 30 31 #define META_DATA ((ota_meta_data_t *)(META_DATA_ADDR + FLASH_START)) 32 bl_main(void)33void bl_main(void) 34 { 35 UINT32 run_addr = META_DATA->run_addr; 36 37 if (run_addr == 0xFFFFFFFFu) { 38 return; 39 } 40 41 unsigned int pc; 42 __asm__("auipc t0, 0\n" 43 "mv %0, t0" : "=r"(pc)); 44 45 unsigned cur_part = (pc - FLASH_START) / OTA_PARTITION_SIZE; 46 unsigned needed_part = run_addr / OTA_PARTITION_SIZE; 47 48 if (cur_part == needed_part) { 49 return; 50 } 51 52 __attribute__((noreturn)) void (*f)(void) = (void *)(run_addr + FLASH_START); 53 f(); 54 55 __builtin_unreachable(); 56 } 57 bl_save_run_address(UINT32 addr)58_attribute_ram_code_sec_ void bl_save_run_address(UINT32 addr) 59 { 60 ota_meta_data_t data; 61 data.run_addr = addr; 62 if (*(volatile unsigned int *)(FLASH_START + META_DATA_ADDR) != 0xFFFFFFFFu) { 63 flash_erase_page_ram(META_DATA_ADDR); 64 } 65 flash_write_page_ram(META_DATA_ADDR, sizeof(data), (unsigned char *)&data); 66 } 67