1 /***************************************************************************
2 * Copyright (C) 2017 by STMicroelectronics *
4 * This program is free software; you can redistribute it and/or modify *
5 * it under the terms of the GNU General Public License as published by *
6 * the Free Software Foundation; either version 2 of the License, or *
7 * (at your option) any later version. *
9 * This program is distributed in the hope that it will be useful, *
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
12 * GNU General Public License for more details. *
14 * You should have received a copy of the GNU General Public License *
15 * along with this program; if not, write to the *
16 * Free Software Foundation, Inc. *
17 ***************************************************************************/
27 * arm-none-eabi-gcc -c stm32h7x.S
30 * arm-none-eabi-objdump -d stm32h7x.o
32 * To generate binary file:
33 * arm-none-eabi-objcopy -O binary stm32h7x.o stm32h7_flash_write_code.bin
35 * To generate include file:
36 * xxd -i stm32h7_flash_write_code.bin
41 * The workarea must have size multiple of 4 bytes, since R/W
42 * operations are all at 32 bits.
43 * The workarea must be big enough to contain 32 bytes of data,
44 * thus the minimum size is (rp, wp, data) = 4 + 4 + 32 = 40 bytes.
45 * To benefit from concurrent host write-to-buffer and target
46 * write-to-flash, the workarea must be way bigger than the minimum.
51 * r0 = workarea start, status (out)
54 * r3 = count (256 bit words)
59 * r6 - wp, status, tmp
60 * r7 - loop index, tmp
63 #define STM32_FLASH_CR_OFFSET 0x0C /* offset of CR register in FLASH struct */
64 #define STM32_FLASH_SR_OFFSET 0x10 /* offset of SR register in FLASH struct */
65 #define STM32_CR_PROG 0x00000032 /* PSIZE64 | PG */
66 #define STM32_SR_BUSY_MASK 0x00000001 /* BSY */
67 #define STM32_SR_ERROR_MASK 0x03ee0000 /* DBECCERR | SNECCERR | RDSERR | RDPERR | OPERR
68 | INCERR | STRBERR | PGSERR | WRPERR */
71 ldr r5, [r0, #4] /* read rp */
74 ldr r6, [r0, #0] /* read wp */
75 cbz r6, exit /* abort if wp == 0, status = 0 */
76 subs r6, r6, r5 /* number of bytes available for read in r6 */
77 ittt mi /* if wrapped around */
78 addmi r6, r1 /* add size of buffer */
81 cmp r6, #32 /* wait until 32 bytes are available */
84 mov r6, #STM32_CR_PROG
85 str r6, [r4, #STM32_FLASH_CR_OFFSET]
87 mov r7, #8 /* program by 8 words = 32 bytes */
89 ldr r6, [r5], #0x04 /* read one word from src, increment ptr */
90 str r6, [r2], #0x04 /* write one word to dst, increment ptr */
92 cmp r5, r1 /* if rp >= end of buffer ... */
94 addcs r5, r0, #8 /* ... then wrap at buffer start */
95 subs r7, r7, #1 /* decrement loop index */
96 bne write_flash /* loop if not done */
99 ldr r6, [r4, #STM32_FLASH_SR_OFFSET]
100 tst r6, #STM32_SR_BUSY_MASK
101 bne busy /* operation in progress, wait ... */
103 ldr r7, stm32_sr_error_mask
105 bne error /* fail... */
107 str r5, [r0, #4] /* store rp */
108 subs r3, r3, #1 /* decrement count */
109 bne wait_fifo /* loop if not done */
114 str r7, [r0, #4] /* set rp = 0 on error */
117 mov r0, r6 /* return status in r0 */
121 .word STM32_SR_ERROR_MASK