1 /*
2 * Copyright (c) 2020 HiSilicon (Shanghai) Technologies CO., LIMITED.
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 * http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15
16 #include <hi_flashboot.h>
17 #include <boot_start.h>
18 #include <hi_boot_rom.h>
19 #include "main.h"
20 #ifdef CONFIG_FLASH_ENCRYPT_SUPPORT
21 #include <crypto.h>
22 #endif
23
24 #define KERNEL_START_ADDR 0x40D3C0
25
26 hi_u32 g_uart_auth;
27 #define FLASHBOOT_UART_DEFAULT_PARAM {115200, 8, 1, 0, 0, 0, 2, 1, 4}
28
boot_kernel(uintptr_t kaddr)29 hi_void boot_kernel(uintptr_t kaddr)
30 {
31 __asm__ __volatile__("ecall"); /* switch U-MODE -> M-MODE */
32 hi_void (*entry)(hi_void) = (hi_void*)(kaddr);
33 entry();
34 }
35
boot_io_init(hi_void)36 hi_void boot_io_init(hi_void)
37 {
38 hi_io_set_func(HI_IO_NAME_GPIO_3, HI_IO_FUNC_GPIO_3_UART0_TXD); /* uart0 tx */
39 hi_io_set_func(HI_IO_NAME_GPIO_4, HI_IO_FUNC_GPIO_4_UART0_RXD); /* uart0 rx */
40 }
41
boot_flash_init(hi_void)42 hi_void boot_flash_init(hi_void)
43 {
44 hi_flash_cmd_func flash_funcs = {0};
45 flash_funcs.init = hi_flash_init;
46 flash_funcs.read = hi_flash_read;
47 flash_funcs.write = hi_flash_write;
48 flash_funcs.erase = hi_flash_erase;
49 hi_cmd_regist_flash_cmd(&flash_funcs);
50 (hi_void) hi_flash_init();
51 }
52 #define XTAL_DS 0x7
53 #define OSC_DRV_CTL 0x2
54
boot_extern_32k(hi_void)55 hi_void boot_extern_32k(hi_void)
56 {
57 hi_u16 chip_id, chip_id_bk;
58 hi_u32 ret;
59 ret = hi_efuse_read(HI_EFUSE_CHIP_RW_ID, (hi_u8 *)&chip_id, (hi_u8)sizeof(hi_u8));
60 if (ret != HI_ERR_SUCCESS) {
61 return;
62 }
63 ret = hi_efuse_read(HI_EFUSE_CHIP_BK_RW_ID, (hi_u8 *)&chip_id_bk, (hi_u8)sizeof(hi_u8));
64 if (ret != HI_ERR_SUCCESS) {
65 return;
66 }
67 hi_u8 chip_ver = (chip_id >> OFFSET_4_B) & MSK_3_B; /* chip_id bit[4:7] is chip_ver. */
68 hi_u8 chip_ver_bk = (chip_id_bk >> OFFSET_4_B) & MSK_3_B; /* chip_id bit[4:7] is chip_ver. */
69 if (chip_ver != HI_CHIP_VER_HI3861L) {
70 if (chip_ver_bk != HI_CHIP_VER_HI3861L) {
71 return;
72 }
73 }
74 hi_u32 reg_val;
75 hi_reg_read(HI_IOCFG_REG_BASE + IO_CTRL_REG_BASE_ADDR, reg_val);
76 reg_val &= ~(MSK_2_B << OFFSET_4_B); /* Maximum drive capability */
77 reg_val |= (MSK_2_B << OFFSET_22_B); /* external xtal, osc enable */
78 reg_val &= ~(MSK_3_B << OFFSET_25_B);
79 reg_val |= XTAL_DS << OFFSET_25_B; /* 1.6ua */
80 reg_val &= ~(MSK_2_B << OFFSET_28_B);
81 reg_val |= OSC_DRV_CTL << OFFSET_28_B; /* 4Mohm */
82 hi_reg_write(HI_IOCFG_REG_BASE + IO_CTRL_REG_BASE_ADDR, reg_val);
83 }
84
85 /* the entry of C. */
start_fastboot(hi_void)86 hi_void start_fastboot(hi_void)
87 {
88 #ifndef CONFIG_QUICK_SEND_MODE
89 hi_u32 ret;
90 hi_malloc_func malloc_funcs = {0, };
91 uart_param_stru default_uart_param = FLASHBOOT_UART_DEFAULT_PARAM;
92 hi_watchdog_disable();
93 hi_watchdog_enable(WDG_TIME_US);
94
95 /* io config */
96 boot_io_init();
97
98 /* Registering and Initializing the Heap Area */
99 malloc_funcs.init = rom_boot_malloc_init;
100 malloc_funcs.boot_malloc = rom_boot_malloc;
101 malloc_funcs.boot_free = rom_boot_free;
102
103 hi_register_malloc((uintptr_t)&__heap_begin__, &malloc_funcs);
104 hi_u32 check_sum = ((uintptr_t)&__heap_begin__) ^ ((uintptr_t)&__heap_end__);
105 boot_malloc_init((uintptr_t)&__heap_begin__, (uintptr_t)&__heap_end__, check_sum);
106
107 /* Initializing the Debugging Serial Port */
108 ret = serial_init(UART0, default_uart_param);
109 if (ret != HI_ERR_SUCCESS) {
110 boot_msg0("uart err"); /* Use the serial port of the romboot to configure the printing. */
111 }
112
113 boot_extern_32k();
114 /* Initializing the Flash Driver */
115 boot_flash_init();
116 /* NV initialization */
117 ret = hi_factory_nv_init(HI_FNV_DEFAULT_ADDR, HI_NV_DEFAULT_TOTAL_SIZE, HI_NV_DEFAULT_BLOCK_SIZE);
118 if (ret != HI_ERR_SUCCESS) {
119 boot_msg0("fnv err");
120 }
121
122 ret = hi_flash_partition_init();
123 if (ret != HI_ERR_SUCCESS) {
124 boot_msg0("parti err");
125 }
126
127 execute_upg_boot();
128 #else
129
130 #ifdef CHIP_HI3861L
131 boot_extern_32k();
132 #endif
133 hi_flash_init();
134 boot_kernel(KERNEL_START_ADDR);
135 #endif
136 mdelay(RESET_DELAY_MS);
137 global_reset();
138 }
139