1 // Copyright (C) 2022 Beken Corporation
2 //
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 #include <os/mem.h>
16 #include <driver/flash.h>
17 #include <driver/flash_partition.h>
18 #include "flash_driver.h"
19 #include "flash_hal.h"
20
21 #if CONFIG_FLASH_ORIGIN_API
22 #define PAR_OPT_READ_POS (0)
23 #define PAR_OPT_WRITE_POS (1)
24
25 #define PAR_OPT_READ_DIS (0x0u << PAR_OPT_READ_POS)
26 #define PAR_OPT_READ_EN (0x1u << PAR_OPT_READ_POS)
27 #define PAR_OPT_WRITE_DIS (0x0u << PAR_OPT_WRITE_POS)
28 #define PAR_OPT_WRITE_EN (0x1u << PAR_OPT_WRITE_POS)
29 #endif
30
31 /* Logic partition on flash devices */
32 #if (CONFIG_SOC_BK7256XX)
33 extern const bk_logic_partition_t bk7256_partitions[BK_PARTITION_MAX];
34 #else
35 static const bk_logic_partition_t bk7231_partitions[BK_PARTITION_MAX] = {
36 [BK_PARTITION_BOOTLOADER] =
37 {
38 .partition_owner = BK_FLASH_EMBEDDED,
39 .partition_description = "Bootloader",
40 .partition_start_addr = 0x00000000,
41 .partition_length = 0x0F000,
42 .partition_options = PAR_OPT_READ_EN | PAR_OPT_WRITE_DIS,
43 },
44 [BK_PARTITION_APPLICATION] =
45 {
46 .partition_owner = BK_FLASH_EMBEDDED,
47 .partition_description = "Application",
48 .partition_start_addr = 0x11000,
49 #if CONFIG_SUPPORT_MATTER || CONFIG_FLASH_SIZE_4M
50 .partition_length = 0x1A9000,
51 #else
52 .partition_length = 0x143000,
53 #endif
54 .partition_options = PAR_OPT_READ_EN | PAR_OPT_WRITE_DIS,
55 },
56 [BK_PARTITION_OTA] =
57 {
58 .partition_owner = BK_FLASH_EMBEDDED,
59 .partition_description = "ota",
60 #if CONFIG_FLASH_SIZE_4M
61 .partition_start_addr = 0x1BA000,
62 .partition_length = 0x1A9000, //1700KB
63 #elif CONFIG_SUPPORT_MATTER
64 .partition_start_addr = 0x1BA000,
65 .partition_length = 0x11000, //68KB
66 #else
67 .partition_start_addr = 0x132000,
68 .partition_length = 0xAE000, //696KB
69 #endif
70 .partition_options = PAR_OPT_READ_EN | PAR_OPT_WRITE_DIS,
71 },
72 #if CONFIG_SUPPORT_MATTER
73 [BK_PARTITION_MATTER_FLASH] =
74 {
75 .partition_owner = BK_FLASH_EMBEDDED,
76 .partition_description = "Matter",
77 #if CONFIG_FLASH_SIZE_4M
78 .partition_start_addr = 0x363000,
79 #else
80 partition_start_addr = 0x1CB000,
81 #endif
82 .partition_length = 0x15000, //84KB
83 .partition_options = PAR_OPT_READ_EN | PAR_OPT_WRITE_DIS,
84 },
85 #endif
86 [BK_PARTITION_RF_FIRMWARE] =
87 {
88 .partition_owner = BK_FLASH_EMBEDDED,
89 .partition_description = "RF Firmware",
90 #if (CONFIG_SOC_BK7251)
91 .partition_start_addr = 0x1e0000,// bootloader unused space for rf cal+mac related info.
92 #elif (CONFIG_SOC_BK7271)
93 .partition_start_addr = 0x3FE000,
94 #else
95 #if (CONFIG_FLASH_SIZE_4M)
96 .partition_start_addr = 0x3FE000,
97 #else
98 .partition_start_addr = 0x1e0000,// for rf related info
99 #endif
100 #endif
101 .partition_length = 0x1000,
102 .partition_options = PAR_OPT_READ_EN | PAR_OPT_WRITE_DIS,
103 },
104 [BK_PARTITION_NET_PARAM] =
105 {
106 .partition_owner = BK_FLASH_EMBEDDED,
107 .partition_description = "NET info",
108 #if (CONFIG_SOC_BK7251)
109 .partition_start_addr = 0x1FF000,// for net related info
110 #elif (CONFIG_SOC_BK7271)
111 .partition_start_addr = 0x3FF000,
112 #else
113 #if (CONFIG_FLASH_SIZE_4M)
114 .partition_start_addr = 0x3FF000,
115 #else
116 .partition_start_addr = 0x1e1000,// for net related info
117 #endif
118 #endif
119 .partition_length = 0x1000,
120 .partition_options = PAR_OPT_READ_EN | PAR_OPT_WRITE_DIS,
121 },
122 };
123 #endif
124
flash_partition_is_valid(bk_partition_t partition)125 static bool flash_partition_is_valid(bk_partition_t partition)
126 {
127 if ((partition >= BK_PARTITION_BOOTLOADER) && (partition < BK_PARTITION_MAX)) {
128 return true;
129 } else {
130 return false;
131 }
132 }
133
bk_flash_partition_get_info(bk_partition_t partition)134 bk_logic_partition_t *bk_flash_partition_get_info(bk_partition_t partition)
135 {
136 bk_logic_partition_t *pt = NULL;
137
138 BK_ASSERT(BK_PARTITION_BOOTLOADER < BK_PARTITION_MAX);
139
140 if (flash_partition_is_valid(partition)) {
141 #if (CONFIG_SOC_BK7256XX)
142 pt = (bk_logic_partition_t *)&bk7256_partitions[partition];
143 #else
144 pt = (bk_logic_partition_t *)&bk7231_partitions[partition];
145 #endif
146 }
147 return pt;
148 }
149
bk_flash_partition_erase(bk_partition_t partition,uint32_t offset,uint32_t size)150 bk_err_t bk_flash_partition_erase(bk_partition_t partition, uint32_t offset, uint32_t size)
151 {
152 uint32_t erase_addr = 0;
153 uint32_t start_sector, end_sector = 0;
154 bk_logic_partition_t *partition_info = NULL;
155 GLOBAL_INT_DECLARATION();
156
157 partition_info = bk_flash_partition_get_info(partition);
158 start_sector = offset >> FLASH_SECTOR_SIZE_OFFSET; /* offset / FLASH_SECTOR_SIZE */
159 end_sector = (offset + size - 1) >> FLASH_SECTOR_SIZE_OFFSET;
160
161 for (uint32_t i = start_sector; i <= end_sector; i ++) {
162 erase_addr = partition_info->partition_start_addr + (i << FLASH_SECTOR_SIZE_OFFSET);
163 GLOBAL_INT_DISABLE();
164 bk_flash_erase_sector(erase_addr);
165 GLOBAL_INT_RESTORE();
166 }
167
168 return BK_OK;
169 }
170
bk_flash_partition_write(bk_partition_t partition,const uint8_t * buffer,uint32_t offset,uint32_t buffer_len)171 bk_err_t bk_flash_partition_write(bk_partition_t partition, const uint8_t *buffer, uint32_t offset, uint32_t buffer_len)
172 {
173 BK_RETURN_ON_NULL(buffer);
174
175 uint32_t start_addr;
176 bk_logic_partition_t *partition_info;
177 GLOBAL_INT_DECLARATION();
178
179 partition_info = bk_flash_partition_get_info(partition);
180 if (NULL == partition_info) {
181 FLASH_LOGW("%s partition not found\r\n", __func__);
182 return BK_ERR_FLASH_PARTITION_NOT_FOUND;
183 }
184
185 start_addr = partition_info->partition_start_addr + offset;
186 GLOBAL_INT_DISABLE();
187 bk_flash_write_bytes(start_addr, buffer, buffer_len);
188 GLOBAL_INT_RESTORE();
189
190 return BK_OK;
191 }
192
bk_flash_partition_read(bk_partition_t partition,uint8_t * out_buffer,uint32_t offset,uint32_t buffer_len)193 bk_err_t bk_flash_partition_read(bk_partition_t partition, uint8_t *out_buffer, uint32_t offset, uint32_t buffer_len)
194 {
195 BK_RETURN_ON_NULL(out_buffer);
196
197 uint32_t start_addr;
198 bk_logic_partition_t *partition_info;
199 GLOBAL_INT_DECLARATION();
200
201 partition_info = bk_flash_partition_get_info(partition);
202 if (NULL == partition_info) {
203 FLASH_LOGW("%s partiion not found\r\n", __func__);
204 return BK_ERR_FLASH_PARTITION_NOT_FOUND;
205 }
206
207 start_addr = partition_info->partition_start_addr + offset;
208 GLOBAL_INT_DISABLE();
209 bk_flash_read_bytes(start_addr, out_buffer, buffer_len);
210 GLOBAL_INT_RESTORE();
211
212 return BK_OK;
213 }
214
215