contrib: replace the GPLv2-or-later license tag
[fw/openocd] / contrib / loaders / flash / kinetis_ke / kinetis_ke_flash.s
1 /* SPDX-License-Identifier: GPL-2.0-or-later */
2
3 /***************************************************************************
4  *   Copyright (C) 2015 by Ivan Meleca                                     *
5  *   ivan@artekit.eu                                                       *
6  ***************************************************************************/
7
8         /* Params:
9          * r0 = flash destination address, status
10          * r1 = longword count
11          * r2 = workarea start address
12          * r3 = workarea end address
13          */
14
15         .text
16         .cpu cortex-m0plus
17         .code 16
18         .thumb_func
19
20         .align  2
21
22         /* r5 = rp
23          * r6 = wp, tmp
24          * r7 = tmp
25          */
26
27 wait_fifo:
28         ldr     r6, [r2, #0]    /* read wp */
29         cmp     r6, #0                  /* abort if wp == 0 */
30         beq     exit
31         ldr     r5, [r2, #4]    /* read rp */
32         cmp     r5, r6                  /* wait until rp != wp */
33         beq     wait_fifo
34
35         ldr             r6, fstat               /* Clear error flags */
36         mov             r7, #48
37         strb    r7, [r6]
38
39         ldr             r6, fccobix             /* FCCOBIX = 0 */
40         mov             r7, #0
41         strb    r7, [r6]
42
43         ldr     r6, fccobhi             /* Program FLASH command */
44         mov             r7, #6                  /* FCCOBHI = 6 */
45         strb    r7, [r6]
46
47         lsr             r7, r0, #16             /* FCCOBLO = flash destination address >> 16 */
48         ldr             r6, fccoblo
49         strb    r7, [r6]
50
51         ldr             r6, fccobix             /* Index for lower byte address bits[15:0] */
52         mov             r7, #1
53         strb    r7, [r6]                /* FCCOBIX = 1*/
54
55         uxtb    r7, r0                  /* Memory address bits[15:0] */
56         ldr     r6, fccoblo
57         strb    r7, [r6]                /* FCCOBLO = flash destination address */
58
59         lsr             r7, r0, #8
60         ldr             r6, fccobhi
61         strb    r7, [r6]                /* FCCOBHI = flash destination address >> 8 */
62
63         ldr             r6, fccobix             /* FCCOBIX = 2 */
64         mov             r7, #2
65         strb    r7, [r6]
66
67         ldrb    r7, [r5, #1]    /* FCCOBHI = rp >> 8 */
68         ldr             r6, fccobhi
69         strb    r7, [r6]
70
71         ldrb    r7, [r5]                /* FCCOBLO = rp */
72         ldr     r6, fccoblo
73         strb    r7, [r6]
74
75         ldr             r6, fccobix             /* FCCOBIX = 3 */
76         mov             r7, #3
77         strb    r7, [r6]
78
79         ldrb    r7, [r5, #3]    /* FCCOBHI = rp >> 24 */
80         ldr             r6, fccobhi
81         strb    r7, [r6]
82
83         ldrb    r7, [r5, #2]    /* FCCOBLO = rp >> 16 */
84         ldr             r6, fccoblo
85         strb    r7, [r6]
86
87         sub             r1, r1, #1              /* Two words (4 bytes) queued, decrement counter */
88         add             r0, r0, #4              /* flash address += 4 */
89         add             r5, r5, #4              /* rp += 4 */
90
91         cmp     r5, r3                  /* Wrap? */
92         bcc     no_wrap
93         mov     r5, r2
94         add     r5, r5, #8
95
96 no_wrap:
97         cmp             r1, #0                  /* Done? */
98         beq             execute
99
100         ldr     r6, [r2, #0]    /* read wp */
101         cmp     r6, r5
102         beq             execute                 /* execute if rp == wp */
103
104         ldr             r6, fccobix             /* FCCOBIX = 4 */
105         mov             r7, #4
106         strb    r7, [r6]
107
108         ldrb    r7, [r5, #1]    /* FCCOBHI = rp >> 8 */
109         ldr             r6, fccobhi
110         strb    r7, [r6]
111
112         ldrb    r7, [r5]                /* FCCOBLO = rp */
113         ldr     r6, fccoblo
114         strb    r7, [r6]
115
116         ldr             r6, fccobix             /* FCCOBIX = 5 */
117         mov             r7, #5
118         strb    r7, [r6]
119
120         ldrb    r7, [r5, #3]    /* FCCOBHI = rp >> 24 */
121         ldr             r6, fccobhi
122         strb    r7, [r6]
123
124         ldrb    r7, [r5, #2]    /* FCCOBLO = rp >> 16 */
125         ldr             r6, fccoblo
126         strb    r7, [r6]
127
128         sub             r1, r1, #1              /* Two words (4 bytes) queued, decrement counter */
129         add             r0, r0, #4              /* flash address += 4 */
130         add             r5, r5, #4              /* rp += 4 */
131
132         cmp     r5, r3                  /* Wrap? */
133         bcc     execute
134         mov     r5, r2
135         add     r5, r5, #8
136
137 execute:
138         ldr             r6, fstat               /* Launch the command */
139         mov             r7, #128
140         strb    r7, [r6]
141
142 wait_busy:
143         ldr             r6, fstat
144         ldrb    r6, [r6]                /* Wait until finished */
145         tst             r6, r7
146         beq             wait_busy
147
148         mov             r7, #48                 /* Check error */
149         tst             r6, r7
150         bne             error
151
152         mov             r6, #0                  /* Clear error */
153
154         str     r5, [r2, #4]    /* Store rp */
155
156         cmp             r1, #0                  /* Done? */
157         beq             done
158         b               wait_fifo
159
160 error:
161         mov             r0, #0
162         str     r0, [r2, #4]    /* set rp = 0 on error */
163
164 done:
165         mov             r0, r6                  /* Set result code */
166         bkpt    #0
167
168         .align  2
169 fstat:
170         .word   0
171 fccobix:
172         .word   0
173 fccobhi:
174         .word   0
175 fccoblo:
176         .word   0