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 <hi3861_platform.h>
17 #include <hi_nv.h>
18 #include <hi_ft_nv.h>
19 #include <hi_partition_table.h>
20 #include <hi_nv.h>
21 #include <hi_flash.h>
22
23 #define FACTORY_NV_ADDR_REG (SYSCTRL_SC_GEN_REG3_REG)
24
25 #define PRODUCT_CFG_DEFAULT_BOOT_ADDR 0x0
26 #define PRODUCT_CFG_DEFAULT_FNV_ADDR 0x8000
27 #define PRODUCT_CFG_DEFAULT_NORMAL_NV_ADDR 0xA000
28 #define PRODUCT_CFG_DEFAULT_NORMAL_NV_BACKUP_ADDR 0xC000
29 #define PRODUCT_CFG_DEFAULT_KERNEL_A_ADDR 0xD000
30 #define PRODUCT_CFG_DEFAULT_KERNEL_B_ADDR 0xF1000
31 #define PRODUCT_CFG_DEFAULT_HILINK_ADDR 0x1E3000
32 #define PRODUCT_CFG_DEFAULT_FILE_SYSTEM_ADDR 0x1E5000
33 #define PRODUCT_CFG_DEFAULT_USER_RESERVE_ADDR 0x1F0000
34 #define PRODUCT_CFG_DEFAULT_HILINK_PKI_ADDR 0x1F5000
35 #define PRODUCT_CFG_DEFAULT_CRASH_INFO_ADDR 0x1F7000
36 #define PRODUCT_CFG_DEFAULT_BOOT_BACK_ADDR 0x1F8000
37
38 #define PRODUCT_CFG_DEFAULT_BOOT_SIZE 0x8000 /* 32K */
39 #define PRODUCT_CFG_DEFAULT_FNV_SIZE 0x2000 /* 8K */
40 #define PRODUCT_CFG_DEFAULT_NORMAL_NV_SIZE 0x2000 /* 8K */
41 #define PRODUCT_CFG_DEFAULT_NORMAL_NV_BACKUP_SIZE 0x1000 /* 4K */
42 #define PRODUCT_CFG_DEFAULT_KERNEL_A_SIZE 0xE4000 /* 912K */
43 #define PRODUCT_CFG_DEFAULT_KERNEL_B_SIZE 0xF2000 /* 968K */
44 #define PRODUCT_CFG_DEFAULT_HILINK_SIZE 0x2000 /* 8K */
45 #define PRODUCT_CFG_DEFAULT_FILE_SYSTEM_SIZE 0xB000 /* 44K */
46 #define PRODUCT_CFG_DEFAULT_USER_RESERVE_SIZE 0x5000 /* 20K */
47 #define PRODUCT_CFG_DEFAULT_HILINK_PKI_SIZE 0x2000 /* 8K */
48 #define PRODUCT_CFG_DEFAULT_CRASH_INFO_SIZE 0x1000 /* 4K */
49 #define PRODUCT_CFG_DEFAULT_BOOT_BACK_SIZE 0x8000 /* 32K */
50
51 #define PRODUCT_CFG_DEFAULT_FACTORY_BIN_ADDR 0x14D000 /* factory bin start addr */
52 #define PRODUCT_CFG_DEFAULT_FACTORY_BIN_SIZE 0x96000 /* factory bin size */
53
54 static hi_flash_partition_table g_partition_table;
hi_get_partition_table(hi_void)55 hi_flash_partition_table* hi_get_partition_table(hi_void)
56 {
57 return &g_partition_table;
58 }
59
hi_flash_partition_init(hi_void)60 hi_u32 hi_flash_partition_init(hi_void)
61 {
62 hi_flash_partition_table* table = hi_get_partition_table();
63 #ifndef CONFIG_QUICK_SEND_MODE
64 hi_u32 ret = hi_factory_nv_read(HI_NV_FTM_FLASH_PARTIRION_TABLE_ID, table, sizeof(hi_flash_partition_table), 0);
65 #else
66 hi_u32 ret = HI_ERR_FAILURE;
67 #endif
68 if (ret != HI_ERR_SUCCESS) { /* read nv fail, set flash partition table default value */
69 table->table[HI_FLASH_PARTITON_BOOT].addr = PRODUCT_CFG_DEFAULT_BOOT_ADDR;
70 table->table[HI_FLASH_PARTITON_BOOT].size = PRODUCT_CFG_DEFAULT_BOOT_SIZE;
71 table->table[HI_FLASH_PARTITON_FACTORY_NV].addr = PRODUCT_CFG_DEFAULT_FNV_ADDR;
72 table->table[HI_FLASH_PARTITON_FACTORY_NV].size = PRODUCT_CFG_DEFAULT_FNV_SIZE;
73 table->table[HI_FLASH_PARTITON_NORMAL_NV].addr = PRODUCT_CFG_DEFAULT_NORMAL_NV_ADDR;
74 table->table[HI_FLASH_PARTITON_NORMAL_NV].size = PRODUCT_CFG_DEFAULT_NORMAL_NV_SIZE;
75 table->table[HI_FLASH_PARTITON_NORMAL_NV_BACKUP].addr = PRODUCT_CFG_DEFAULT_NORMAL_NV_BACKUP_ADDR;
76 table->table[HI_FLASH_PARTITON_NORMAL_NV_BACKUP].size = PRODUCT_CFG_DEFAULT_NORMAL_NV_BACKUP_SIZE;
77 table->table[HI_FLASH_PARTITON_KERNEL_A].addr = PRODUCT_CFG_DEFAULT_KERNEL_A_ADDR;
78 table->table[HI_FLASH_PARTITON_KERNEL_A].size = PRODUCT_CFG_DEFAULT_KERNEL_A_SIZE;
79 table->table[HI_FLASH_PARTITON_KERNEL_B].addr = PRODUCT_CFG_DEFAULT_KERNEL_B_ADDR;
80 table->table[HI_FLASH_PARTITON_KERNEL_B].size = PRODUCT_CFG_DEFAULT_KERNEL_B_SIZE;
81 table->table[HI_FLASH_PARTITON_HILINK].addr = PRODUCT_CFG_DEFAULT_HILINK_ADDR;
82 table->table[HI_FLASH_PARTITON_HILINK].size = PRODUCT_CFG_DEFAULT_HILINK_SIZE;
83 table->table[HI_FLASH_PARTITON_FILE_SYSTEM].addr = PRODUCT_CFG_DEFAULT_FILE_SYSTEM_ADDR;
84 table->table[HI_FLASH_PARTITON_FILE_SYSTEM].size = PRODUCT_CFG_DEFAULT_FILE_SYSTEM_SIZE;
85 table->table[HI_FLASH_PARTITON_USR_RESERVE].addr = PRODUCT_CFG_DEFAULT_USER_RESERVE_ADDR;
86 table->table[HI_FLASH_PARTITON_USR_RESERVE].size = PRODUCT_CFG_DEFAULT_USER_RESERVE_SIZE;
87 table->table[HI_FLASH_PARTITON_HILINK_PKI].addr = PRODUCT_CFG_DEFAULT_HILINK_PKI_ADDR;
88 table->table[HI_FLASH_PARTITON_HILINK_PKI].size = PRODUCT_CFG_DEFAULT_HILINK_PKI_SIZE;
89 table->table[HI_FLASH_PARTITON_CRASH_INFO].addr = PRODUCT_CFG_DEFAULT_CRASH_INFO_ADDR;
90 table->table[HI_FLASH_PARTITON_CRASH_INFO].size = PRODUCT_CFG_DEFAULT_CRASH_INFO_SIZE;
91 table->table[HI_FLASH_PARTITON_BOOT_BACK].addr = PRODUCT_CFG_DEFAULT_BOOT_BACK_ADDR;
92 table->table[HI_FLASH_PARTITON_BOOT_BACK].size = PRODUCT_CFG_DEFAULT_BOOT_BACK_SIZE;
93 }
94 #ifdef CONFIG_QUICK_SEND_MODE
95 ret = HI_ERR_SUCCESS;
96 #endif
97 return ret;
98 }
99
hi_get_hilink_partition_table(hi_u32 * addr,hi_u32 * size)100 hi_u32 hi_get_hilink_partition_table(hi_u32 *addr, hi_u32 *size)
101 {
102 if (addr == HI_NULL || size == HI_NULL) {
103 return HI_ERR_FAILURE;
104 }
105
106 hi_flash_partition_table* flash_partion_table = hi_get_partition_table();
107 *addr = flash_partion_table->table[HI_FLASH_PARTITON_HILINK].addr;
108 *size = flash_partion_table->table[HI_FLASH_PARTITON_HILINK].size;
109
110 return HI_ERR_SUCCESS;
111 }
112
hi_get_hilink_pki_partition_table(hi_u32 * addr,hi_u32 * size)113 hi_u32 hi_get_hilink_pki_partition_table(hi_u32 *addr, hi_u32 *size)
114 {
115 if (addr == HI_NULL || size == HI_NULL) {
116 return HI_ERR_FAILURE;
117 }
118
119 hi_flash_partition_table* flash_partion_table = hi_get_partition_table();
120 *addr = flash_partion_table->table[HI_FLASH_PARTITON_HILINK_PKI].addr;
121 *size = flash_partion_table->table[HI_FLASH_PARTITON_HILINK_PKI].size;
122
123 return HI_ERR_SUCCESS;
124 }
125
hi_get_crash_partition_table(hi_u32 * addr,hi_u32 * size)126 hi_u32 hi_get_crash_partition_table(hi_u32 *addr, hi_u32 *size)
127 {
128 if (addr == HI_NULL || size == HI_NULL) {
129 return HI_ERR_FAILURE;
130 }
131
132 hi_flash_partition_table* flash_partion_table = hi_get_partition_table();
133 *addr = flash_partion_table->table[HI_FLASH_PARTITON_CRASH_INFO].addr;
134 *size = flash_partion_table->table[HI_FLASH_PARTITON_CRASH_INFO].size;
135
136 return HI_ERR_SUCCESS;
137 }
138
hi_get_fs_partition_table(hi_u32 * addr,hi_u32 * size)139 hi_u32 hi_get_fs_partition_table(hi_u32 *addr, hi_u32 *size)
140 {
141 if (addr == HI_NULL || size == HI_NULL) {
142 return HI_ERR_FAILURE;
143 }
144
145 hi_flash_partition_table* flash_partion_table = hi_get_partition_table();
146 *addr = flash_partion_table->table[HI_FLASH_PARTITON_FILE_SYSTEM].addr;
147 *size = flash_partion_table->table[HI_FLASH_PARTITON_FILE_SYSTEM].size;
148
149 return HI_ERR_SUCCESS;
150 }
151
hi_get_normal_nv_partition_table(hi_u32 * addr,hi_u32 * size)152 hi_u32 hi_get_normal_nv_partition_table(hi_u32 *addr, hi_u32 *size)
153 {
154 if (addr == HI_NULL || size == HI_NULL) {
155 return HI_ERR_FAILURE;
156 }
157
158 hi_flash_partition_table* flash_partion_table = hi_get_partition_table();
159 *addr = flash_partion_table->table[HI_FLASH_PARTITON_NORMAL_NV].addr;
160 *size = flash_partion_table->table[HI_FLASH_PARTITON_NORMAL_NV].size;
161
162 return HI_ERR_SUCCESS;
163 }
164
hi_get_normal_nv_backup_partition_table(hi_u32 * addr,hi_u32 * size)165 hi_u32 hi_get_normal_nv_backup_partition_table(hi_u32 *addr, hi_u32 *size)
166 {
167 if (addr == HI_NULL || size == HI_NULL) {
168 return HI_ERR_FAILURE;
169 }
170
171 hi_flash_partition_table* flash_partion_table = hi_get_partition_table();
172 *addr = flash_partion_table->table[HI_FLASH_PARTITON_NORMAL_NV_BACKUP].addr;
173 *size = flash_partion_table->table[HI_FLASH_PARTITON_NORMAL_NV_BACKUP].size;
174
175 return HI_ERR_SUCCESS;
176 }
177
hi_get_usr_partition_table(hi_u32 * addr,hi_u32 * size)178 hi_u32 hi_get_usr_partition_table(hi_u32 *addr, hi_u32 *size)
179 {
180 if (addr == HI_NULL || size == HI_NULL) {
181 return HI_ERR_FAILURE;
182 }
183
184 hi_flash_partition_table* flash_partion_table = hi_get_partition_table();
185 *addr = flash_partion_table->table[HI_FLASH_PARTITON_USR_RESERVE].addr;
186 *size = flash_partion_table->table[HI_FLASH_PARTITON_USR_RESERVE].size;
187
188 return HI_ERR_SUCCESS;
189 }
190
hi_get_factory_bin_partition_table(hi_u32 * addr,hi_u32 * size)191 hi_u32 hi_get_factory_bin_partition_table(hi_u32 *addr, hi_u32 *size)
192 {
193 if (addr == HI_NULL || size == HI_NULL) {
194 return HI_ERR_FAILURE;
195 }
196
197 *addr = PRODUCT_CFG_DEFAULT_FACTORY_BIN_ADDR;
198 *size = PRODUCT_CFG_DEFAULT_FACTORY_BIN_SIZE;
199
200 return HI_ERR_SUCCESS;
201 }
202
hi_nv_restore_by_backup(hi_void)203 hi_u32 hi_nv_restore_by_backup(hi_void)
204 {
205 hi_u32 backup_nv_addr = 0;
206 hi_u32 backup_nv_size = 0;
207 hi_u32 nv_addr = 0;
208 hi_u32 nv_size = 0;
209
210 hi_u32 ret = hi_get_normal_nv_backup_partition_table(&backup_nv_addr, &backup_nv_size);
211 ret |= hi_get_normal_nv_partition_table(&nv_addr, &nv_size);
212 if (ret != HI_ERR_SUCCESS) {
213 return ret;
214 }
215
216 if (nv_size / backup_nv_size != 0x2) {
217 return HI_ERR_FAILURE;
218 }
219
220 ret = hi_flash_write(nv_addr, backup_nv_size, (const hi_u8 *)(HI_FLASH_BASE + backup_nv_addr), HI_TRUE);
221 ret |= hi_flash_write(nv_addr + backup_nv_size, backup_nv_size,
222 (const hi_u8 *)(HI_FLASH_BASE + backup_nv_addr), HI_TRUE);
223
224 return ret;
225 }
226