f6f5b30a490e9163aa55bd639d97e8e643db5bf6
[fw/openocd] / contrib / loaders / flash / stm32 / stm32f2x.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  *   This program is free software; you can redistribute it and/or modify  *
9  *   it under the terms of the GNU General Public License as published by  *
10  *   the Free Software Foundation; either version 2 of the License, or     *
11  *   (at your option) any later version.                                   *
12  *                                                                         *
13  *   This program is distributed in the hope that it will be useful,       *
14  *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
15  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
16  *   GNU General Public License for more details.                          *
17  *                                                                         *
18  *   You should have received a copy of the GNU General Public License     *
19  *   along with this program; if not, write to the                         *
20  *   Free Software Foundation, Inc.,                                       *
21  *   51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.           *
22  ***************************************************************************/
23
24         .text
25         .syntax unified
26         .cpu cortex-m3
27         .thumb
28
29 /*
30  * Params :
31  * r0 = workarea start, status (out)
32  * r1 = workarea end
33  * r2 = target address
34  * r3 = count (16bit words)
35  * r4 = flash base
36  *
37  * Clobbered:
38  * r6 - temp
39  * r7 - rp
40  * r8 - wp, tmp
41  */
42
43 #define STM32_FLASH_CR_OFFSET   0x10                    /* offset of CR register in FLASH struct */
44 #define STM32_FLASH_SR_OFFSET   0x0c                    /* offset of SR register in FLASH struct */
45
46 #define STM32_PROG16            0x101                   /* PG | PSIZE_16*/
47
48         .thumb_func
49         .global _start
50 _start:
51 wait_fifo:
52         ldr     r8, [r0, #0]    /* read wp */
53         cmp     r8, #0                  /* abort if wp == 0 */
54         beq     exit
55         ldr     r7, [r0, #4]    /* read rp */
56         cmp     r7, r8                  /* wait until rp != wp */
57         beq     wait_fifo
58
59         ldr             r6, =STM32_PROG16
60         str             r6, [r4, #STM32_FLASH_CR_OFFSET]
61         ldrh    r6, [r7], #0x02                                         /* read one half-word from src, increment ptr */
62         strh    r6, [r2], #0x02                                         /* write one half-word from src, increment ptr */
63         dsb
64 busy:
65         ldr     r6, [r4, #STM32_FLASH_SR_OFFSET]
66         tst     r6, #0x10000                                            /* BSY (bit16) == 1 => operation in progress */
67         bne     busy                                                            /* wait more... */
68         tst             r6, #0xf0                                                       /* PGSERR | PGPERR | PGAERR | WRPERR */
69         bne             error                                                           /* fail... */
70
71         cmp     r7, r1                  /* wrap rp at end of buffer */
72         it      cs
73         addcs   r7, r0, #8              /* skip loader args */
74         str     r7, [r0, #4]    /* store rp */
75         subs    r3, r3, #1              /* decrement halfword count */
76         cbz     r3, exit                /* loop if not done */
77         b               wait_fifo
78 error:
79         movs    r1, #0
80         str             r1, [r0, #4]    /* set rp = 0 on error */
81 exit:
82         mov             r0, r6                  /* return status in r0 */
83         bkpt    #0x00
84
85         .pool