99#include < cstdint>
1010#include < span>
1111
12+ #ifdef NORFLASH_WRITER
13+ #include " boot_sd_write_nor.hh"
14+ #endif
15+
1216struct BootSDLoader : BootLoader {
1317 BootSDLoader ()
1418 {
@@ -144,8 +148,10 @@ private:
144148 return false ;
145149 }
146150
151+ auto load_addr = (uint32_t )data.data ();
152+
147153 debug (" SD read " , data.size (), " bytes from 0x" , Hex{address}, " -0x" , Hex{address + data.size ()});
148- debug (" to 0x" , Hex{( uint32_t )data. data () }, " -0x" , Hex{( uint32_t )data. data () + data.size ()}, " \n " );
154+ debug (" to 0x" , Hex{load_addr }, " -0x" , Hex{load_addr + data.size ()}, " \n " );
149155
150156 uint32_t aligned_addr = (address / BlockSize) * BlockSize;
151157 if (aligned_addr < address) {
@@ -160,8 +166,16 @@ private:
160166 debug (" Copying last " , bytes_to_keep, " bytes from tmp to " , Hex{(uint32_t )data.data ()}, " \n " );
161167
162168 auto source = std::span<uint8_t >{&tmp[bytes_to_drop], &tmp[512 ]};
163- for (auto i = 0 ; auto &d : data.subspan (0 , bytes_to_keep))
164- d = source[i++];
169+
170+ #ifdef NORFLASH_WRITER
171+ if (load_addr >= 0x6000'0000 && load_addr < 0x9000'0000 ) {
172+ nor_writer.write ((uint32_t )data.data (), source);
173+ } else
174+ #endif
175+ {
176+ for (auto i = 0 ; auto &d : data.subspan (0 , bytes_to_keep))
177+ d = source[i++];
178+ }
165179
166180 if (data.size () == bytes_to_keep) {
167181 return true ;
@@ -191,7 +205,7 @@ private:
191205 uint32_t numblocks = bytes_to_read / BlockSize;
192206
193207 debug (" Reading " , numblocks, " block(s)\n " );
194- if (HAL_SD_ReadBlocks (&hsd, read_ptr, block_num, numblocks, timeout) != HAL_OK)
208+ if (read_sd_multi_blocks (&hsd, read_ptr, block_num, numblocks, timeout) != HAL_OK)
195209 read_error ();
196210
197211 uint32_t bytes_read = numblocks * BlockSize;
@@ -216,15 +230,57 @@ private:
216230
217231 debug (" Copying first " , bytes_to_copy, " from tmp to " , Hex{uint32_t (read_ptr)}, " \n " );
218232
219- for (unsigned i = 0 ; i < bytes_to_copy; i++) {
220- *read_ptr++ = tmp[i];
233+ #ifdef NORFLASH_WRITER
234+ if ((uint32_t )read_ptr >= 0x6000'0000 && (uint32_t )read_ptr < 0x9000'0000 ) {
235+ nor_writer.write ((uint32_t )read_ptr, std::span<const uint8_t >{tmp, bytes_to_copy});
236+ } else
237+ #endif
238+ {
239+ for (unsigned i = 0 ; i < bytes_to_copy; i++)
240+ *read_ptr++ = tmp[i];
221241 }
242+
222243 bytes_to_read -= bytes_to_copy;
223244 block_num++;
224245 }
225246 return true ;
226247 }
227248
249+ // Reads entire aligned blocks
250+ HAL_StatusTypeDef read_sd_multi_blocks (
251+ SD_HandleTypeDef *hsd, uint8_t *read_ptr, uint32_t block_num, uint32_t numblocks, uint32_t timeout)
252+ {
253+ #ifdef NORFLASH_WRITER
254+ if ((uint32_t )read_ptr >= 0x6000'0000 && (uint32_t )read_ptr < 0x9000'0000 ) {
255+
256+ while (numblocks--) {
257+ alignas (4 ) uint8_t tmp[BlockSize];
258+
259+ debug (" " , " Reading block #" , block_num, " from SD Card to temp memory\n " );
260+
261+ if (auto res = HAL_SD_ReadBlocks (hsd, tmp, block_num, 1 , timeout); res == HAL_OK) {
262+
263+ if (nor_writer.write ((uint32_t )read_ptr, tmp)) {
264+ debug (" Wrote to NOR at 0x" , Hex{(uint32_t )read_ptr}, " \n " );
265+ } else {
266+ pr_err (" Failed to write SD block #" , block_num, " to NOR at 0x" , Hex{(uint32_t )read_ptr}, " \n " );
267+ }
268+
269+ } else {
270+ pr_err (" Failed to reading block #" , block_num, " from SD Card into temp memory.\n " );
271+ return res;
272+ }
273+
274+ block_num++;
275+ read_ptr += BlockSize;
276+ }
277+ return HAL_OK;
278+
279+ } else
280+ #endif
281+ return HAL_SD_ReadBlocks (hsd, read_ptr, block_num, numblocks, timeout);
282+ }
283+
228284 void init_error ()
229285 {
230286 _has_error = true ;
@@ -244,4 +300,8 @@ private:
244300 }
245301
246302 constexpr static uint32_t BlockSize = 512 ;
303+
304+ #ifdef NORFLASH_WRITER
305+ NorFlashWriter nor_writer;
306+ #endif
247307};
0 commit comments