flash/nor/stm32l4x: fix minor errors in flash write/async algo
[fw/openocd] / contrib / loaders / flash / stm32 / stm32l4x.S
1 /***************************************************************************
2  *   Copyright (C) 2010 by Spencer Oliver                                  *
3  *   spen@spen-soft.co.uk                                                  *
4  *                                                                         *
5  *   Copyright (C) 2011 Ã˜yvind Harboe                                      *
6  *   oyvind.harboe@zylin.com                                               *
7  *                                                                         *
8  *   Copyright (C) 2015 Uwe Bonnes                                         *
9  *   bon@elektron.ikp.physik.tu-darmstadt.de                               *
10  *                                                                         *
11  *   This program is free software; you can redistribute it and/or modify  *
12  *   it under the terms of the GNU General Public License as published by  *
13  *   the Free Software Foundation; either version 2 of the License, or     *
14  *   (at your option) any later version.                                   *
15  *                                                                         *
16  *   This program is distributed in the hope that it will be useful,       *
17  *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
18  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
19  *   GNU General Public License for more details.                          *
20  *                                                                         *
21  *   You should have received a copy of the GNU General Public License     *
22  *   along with this program; if not, write to the                         *
23  *   Free Software Foundation, Inc.                                        *
24  ***************************************************************************/
25
26         .text
27         .syntax unified
28         .cpu cortex-m4
29         .thumb
30
31 /*
32  * Params :
33  * r0 = workarea start, status (out)
34  * r1 = workarea end
35  * r2 = target address
36  * r3 = count (64bit words)
37  * r4 = flash base
38  *
39  * Clobbered:
40  * r5   - rp
41  * r6/7 - temp (64-bit)
42  * r8   - wp, tmp
43  */
44
45 #define STM32_FLASH_CR_OFFSET   0x14    /* offset of CR register in FLASH struct */
46 #define STM32_FLASH_SR_OFFSET   0x10    /* offset of SR register in FLASH struct */
47
48 #define STM32_PROG       0x1    /* PG */
49
50         .thumb_func
51         .global _start
52 _start:
53 wait_fifo:
54         ldr     r8, [r0, #0]    /* read wp */
55         cmp     r8, #0          /* abort if wp == 0 */
56         beq     exit
57         ldr     r5, [r0, #4]    /* read rp */
58         subs    r6, r8, r5      /* number of bytes available for read in r6*/
59         itt     mi              /* if wrapped around*/
60         addmi   r6, r1          /* add size of buffer */
61         submi   r6, r0
62         cmp     r6, #8          /* wait until 8 bytes are available */
63         bcc     wait_fifo
64
65         ldr     r6, =STM32_PROG
66         str     r6, [r4, #STM32_FLASH_CR_OFFSET]
67         ldrd    r6, [r5], #0x08 /* read one word from src, increment ptr */
68         strd    r6, [r2], #0x08 /* write one word to dst, increment ptr */
69         dsb
70 busy:
71         ldr     r6, [r4, #STM32_FLASH_SR_OFFSET]
72         tst     r6, #0x10000    /* BSY (bit16) == 1 => operation in progress */
73         bne     busy            /* wait more... */
74         tst     r6, #0xfa       /* PGSERR | SIZERR | PGAERR | WRPERR | PROGERR | OPERR */
75         bne     error           /* fail... */
76
77         cmp     r5, r1          /* wrap rp at end of buffer */
78         it      cs
79         addcs   r5, r0, #8      /* skip loader args */
80         str     r5, [r0, #4]    /* store rp */
81         subs    r3, r3, #1      /* decrement dword count */
82         cbz     r3, exit        /* loop if not done */
83         b       wait_fifo
84 error:
85         movs    r1, #0
86         str     r1, [r0, #4]    /* set rp = 0 on error */
87 exit:
88         mov     r0, r6          /* return status in r0 */
89         bkpt    #0x00
90
91         .pool
92