MCCI Trusted Bootloader
Simple trusted bootloader and tools for small embedded systems
mccibootloader_stm32h7_systemflash.c
Go to the documentation of this file.
1/*
2
3Module: mccibootloader_stm32h7_systemflash.c
4
5Function:
6 McciBootloader_Stm32h7_systemFlashErase() and
7 McciBootloader_Stm32h7_systemFlashWrite()
8
9Copyright and License:
10 This file copyright (C) 2021 by
11
12 MCCI Corporation
13 3520 Krums Corners Road
14 Ithaca, NY 14850
15
16 See accompanying LICENSE file for copyright and license information.
17
18Author:
19 ChaeHee Won, MCCI Corporation July 2021
20
21*/
22
24#include "mcci_stm32h7xx.h"
25
26/****************************************************************************\
27|
28| Manifest constants & typedefs.
29|
30\****************************************************************************/
31
32#define MCCI_STM32H7_REG_FLASH_SR_ERRORS \
33 (/*MCCI_STM32H7_REG_FLASH_SR_CRCRDERR |*/ \
34 MCCI_STM32H7_REG_FLASH_SR_DBECCERR | \
35 MCCI_STM32H7_REG_FLASH_SR_SNECCERR | \
36 MCCI_STM32H7_REG_FLASH_SR_RDSERR | \
37 MCCI_STM32H7_REG_FLASH_SR_RDPERR | \
38 MCCI_STM32H7_REG_FLASH_SR_INCERR | \
39 MCCI_STM32H7_REG_FLASH_SR_STRBERR | \
40 MCCI_STM32H7_REG_FLASH_SR_PGSERR | \
41 MCCI_STM32H7_REG_FLASH_SR_WRPERR)
42
43void
45 uint32_t flash_addr
46 );
47
48void
50 uint32_t flash_addr
51 );
52
53bool
55 uint32_t flash_addr
56 );
57
58bool
60 uint32_t flash_addr
61 );
62
63
64/****************************************************************************\
65|
66| Read-only data.
67|
68\****************************************************************************/
69
70
71/****************************************************************************\
72|
73| Variables.
74|
75\****************************************************************************/
76
77bool
79 volatile const void * pBase,
80 size_t nBytes
81 )
82 {
83 uint32_t p;
84 uint32_t pEnd;
85 size_t nSectors;
86 bool status;
87
88 p = (uint32_t) pBase;
90 return false;
91
92 // round nBytes up if necessary for partial sectors.
93 nBytes = (nBytes + MCCI_STM32H7_FLASH_SECTOR_SIZE - 1) &
95 nSectors = nBytes / MCCI_STM32H7_FLASH_SECTOR_SIZE;
96 pEnd = p + nBytes - MCCI_STM32H7_FLASH_SECTOR_SIZE;
97
98 // wait
100
101 // unlock
104
105 for (status = true; nSectors > 0; --nSectors)
106 {
107 // start the erase
109 if (! status)
110 {
111 break;
112 }
113
115 }
116
117 // lock
118 McciBootloader_Stm32h7_Lock((uint32_t) pBase);
120 return status;
121 }
122
123bool
125 uint32_t flash_addr
126 )
127 {
128 uint32_t rSR;
129 uint32_t r;
130
131 if (MCCI_STM32H7_FLASH_IS_BANK2(flash_addr))
132 {
134 }
135 else
136 {
138 }
139
140 do {
141 r = McciArm_getReg(rSR);
142 } while (r & (MCCI_STM32H7_REG_FLASH_SR_QW |
144
145 /* Clear status */
147 rSR + 4,
150 );
151 return (r & MCCI_STM32H7_REG_FLASH_SR_ERRORS) ? false : true;
152 }
153
154void
156 uint32_t flash_addr
157 )
158 {
159 uint32_t rCR;
160 uint32_t r;
161
162 if (MCCI_STM32H7_FLASH_IS_BANK2(flash_addr))
163 {
165 }
166 else
167 {
169 }
170
171 r = McciArm_getReg(rCR);
172 if ((r & MCCI_STM32H7_REG_FLASH_CR_LOCK) == 0)
173 {
175 }
176 }
177
178void
216
217bool
219 uint32_t flash_addr
220 )
221 {
222 uint32_t rCR;
223 uint32_t sector;
224 bool status;
225
226 if (MCCI_STM32H7_FLASH_IS_BANK2(flash_addr))
227 {
229 }
230 else
231 {
233 }
234
235 sector = MCCI_STM32H7_FLASH_GET_SECTOR(flash_addr);
238 rCR,
242 );
243
244 status = McciBootloader_Stm32h7_waitForDone(flash_addr);
245
247 rCR,
249 );
250 return status;
251 }
252
253bool
255 volatile const void * pDest,
256 const void * pSrc,
257 size_t nBytes
258 )
259 {
260 bool result;
261 uint32_t srcAddr;
262 uint32_t destAddr;
263 uint32_t destEndAddr;
264 volatile uint32_t * pFlashAddr;
265 const uint32_t * pSrcData;
266
267 srcAddr = (uint32_t) pSrc;
268 if ((srcAddr & 3) != 0)
269 return false;
270
271 if ((nBytes % MCCI_STM32H7_FLASH_PROGRAM_FLASH_SIZE) != 0)
272 return false;
273
274 destAddr = (uint32_t) pDest;
275 if ((destAddr % MCCI_STM32H7_FLASH_PROGRAM_FLASH_SIZE) != 0)
276 return false;
277
278 destEndAddr = destAddr + nBytes - MCCI_STM32H7_FLASH_PROGRAM_FLASH_SIZE;
279
280 pFlashAddr = (volatile uint32_t *) destAddr;
281 pSrcData = (const uint32_t *) srcAddr;
282
283 // wait
285
286 // unlock
289
290 for (result = true;
291 nBytes > 0;
293 {
294 uint32_t rCR;
295 uint32_t i;
296
297 if (MCCI_STM32H7_FLASH_IS_BANK2(destAddr))
298 {
300 }
301 else
302 {
304 }
305
307
308 McciArm_InstructionSynchBarrier();
309 McciArm_DataSynchBarrier();
310
311 for (i = 0; i < (MCCI_STM32H7_FLASH_PROGRAM_FLASH_SIZE / sizeof(uint32_t)); ++i)
312 {
313 *pFlashAddr++ = *pSrcData++;
314 }
315
316 McciArm_InstructionSynchBarrier();
317 McciArm_DataSynchBarrier();
318
319 // wait for done
320 result = McciBootloader_Stm32h7_waitForDone(destAddr);
321
323
324 if (! result)
325 {
326 break;
327 }
328
330 }
331
332 // lock
333 McciBootloader_Stm32h7_Lock((uint32_t) pDest);
334 McciBootloader_Stm32h7_Lock(destEndAddr);
335 return result;
336 }
337
338/**** end of mccibootloader_stm32h7_systemflash.c ****/
static uint32_t McciArm_putRegOr(uint32_t reg, uint32_t orVal)
or 32-bit values to a cm0plus register
static uint32_t McciArm_getReg(uint32_t reg)
read a 32-bit value from a cm0plus register
static uint32_t McciArm_putReg(uint32_t reg, uint32_t val)
write a 32-bit value to a cm0plus register
static uint32_t McciArm_putRegClear(uint32_t reg, uint32_t clearVal)
clear out 32-bit values to a cm0plus register
McciBootloaderPlatform_SystemFlashWriteFn_t McciBootloader_Stm32h7_systemFlashWrite
McciBootloaderPlatform_SystemFlashEraseFn_t McciBootloader_Stm32h7_systemFlashErase
#define MCCI_STM32H7_REG_FLASH_KEYR_UNLOCK1
unlock word 1 for FLASH_CR1
#define MCCI_STM32H7_FLASH_IS_BANK2(f)
#define MCCI_STM32H7_FLASH_PROGRAM_FLASH_SIZE
size in bytes of a FLASH program
#define MCCI_STM32H7_REG_FLASH_CR_LOCK
Lock the FLASH_CR register.
#define MCCI_STM32H7_REG_FLASH_CR2
Flash control register for bank 2.
#define MCCI_STM32H7_REG_FLASH_KEYR1
Flash key register for bank 1.
#define MCCI_STM32H7_REG_FLASH_CR_SSN
Sector erase selection number.
#define MCCI_STM32H7_REG_FLASH_CR_SER
Sector erase request.
#define MCCI_STM32H7_REG_FLASH_CR1
Flash control register for bank 1.
#define MCCI_STM32H7_REG_FLASH_SR_EOP
End-of-program flag.
#define MCCI_STM32H7_FLASH_IS_VALID(f)
#define MCCI_STM32H7_REG_FLASH_KEYR_UNLOCK2
unlock word 2 for FLASH_CR1
#define MCCI_STM32H7_REG_FLASH_CR_START
Erase start control.
#define MCCI_STM32H7_REG_FLASH_SR_BSY
Busy flag.
#define MCCI_STM32H7_REG_FLASH_CR_PG
Internal buffer control.
#define MCCI_STM32H7_REG_FLASH_SR_QW
wait queue flag
#define MCCI_STM32H7_REG_FLASH_CR_SSN_N(n)
Sector erase selection number.
#define MCCI_STM32H7_REG_FLASH_SR1
Flash status register for bank 1.
#define MCCI_STM32H7_FLASH_SECTOR_SIZE
size in bytes of a sector
#define MCCI_STM32H7_REG_FLASH_SR2
Flash status register for bank 2.
#define MCCI_STM32H7_REG_FLASH_KEYR2
Flash key register for bank 2.
#define MCCI_STM32H7_FLASH_GET_SECTOR(f)
bool McciBootloader_Stm32h7_waitForDone(uint32_t flash_addr)
void McciBootloader_Stm32h7_Unlock(uint32_t flash_addr)
#define MCCI_STM32H7_REG_FLASH_SR_ERRORS
bool McciBootloader_Stm32h7_EraseSector(uint32_t flash_addr)
void McciBootloader_Stm32h7_Lock(uint32_t flash_addr)