• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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)33 void 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