contrib: replace the GPLv2-or-later license tag
[fw/openocd] / contrib / loaders / flash / k1921vk01t.S
1 /* SPDX-License-Identifier: GPL-2.0-or-later */
2
3 /***************************************************************************
4  *   Copyright (C) 2015 by Bogdan Kolbov                                   *
5  *   kolbov@niiet.ru                                                       *
6  ***************************************************************************/
7
8         .text
9         .syntax unified
10         .cpu cortex-m4
11         .thumb
12         .thumb_func
13
14 /* K1921VK01T has 128-bitwidth flash, so it`s able to load 4x32-bit words at the time.
15  * And only after all words loaded we can start write
16  */
17
18 /* Registers addresses */
19 #define FLASH_FMA       0x00            /* Address reg */
20 #define FLASH_FMD1      0x04            /* Data1 reg */
21 #define FLASH_FMC       0x08            /* Command reg */
22 #define FLASH_FCIS      0x0C            /* Operation Status reg */
23 #define FLASH_FCIC      0x14            /* Operation Status Clear reg */
24 #define FLASH_FMD2      0x50            /* Data2 reg */
25 #define FLASH_FMD3      0x54            /* Data3 reg */
26 #define FLASH_FMD4      0x58            /* Data4 reg*/
27
28         /* Params:
29          * r0 - write cmd (in), status (out)
30          * r1 - count
31          * r2 - workarea start
32          * r3 - workarea end
33          * r4 - target address
34          * Clobbered:
35          * r5 - rp
36          * r6 - wp, tmp
37          * r7 - flash base
38          */
39
40 ldr     r7, =#0xA001C000  /* Flash reg base*/
41
42 wait_fifo:
43         ldr             r6, [r2, #0]    /* read wp */
44         cmp             r6, #0                  /* abort if wp == 0 */
45         beq             exit
46         ldr             r5, [r2, #4]    /* read rp */
47         cmp             r5, r6                  /* wait until rp != wp */
48         beq             wait_fifo
49
50
51 load_data:
52         ldr r6, [r5]                    /* read data1 */
53         str r6, [r7, #FLASH_FMD1]
54         adds    r5, #4
55
56         ldr r6, [r5]                    /* read data2 */
57         str r6, [r7, #FLASH_FMD2]
58         adds    r5, #4
59
60         ldr r6, [r5]                    /* read data3 */
61         str r6, [r7, #FLASH_FMD3]
62         adds    r5, #4
63
64         ldr r6, [r5]                    /* read data4 */
65         str r6, [r7, #FLASH_FMD4]
66         adds    r5, #4
67
68 start_write:
69         str r4, [r7, #FLASH_FMA]                /* set addr */
70         adds    r4, #16
71         str r0, [r7, #FLASH_FMC]                /* write cmd */
72
73 busy:
74         ldr             r6, [r7, #FLASH_FCIS]   /* wait until flag set */
75         cmp             r6, #0x0
76         beq             busy
77
78         cmp             r6, #2                  /* check the error bit */
79         beq             error
80
81         movs    r6, #1                  /* clear flags */
82         str r6, [r7, #FLASH_FCIC]
83
84         cmp     r5, r3                  /* wrap rp at end of buffer */
85         bcc     no_wrap
86         mov     r5, r2
87         adds    r5, #8
88 no_wrap:
89         str     r5, [r2, #4]    /* store rp */
90         subs    r1, r1, #1              /* decrement 16-byte block count */
91         cmp     r1, #0
92         beq     exit            /* loop if not done */
93         b       wait_fifo
94
95 error:
96         movs    r0, #0
97         str             r0, [r2, #4]    /* set rp = 0 on error */
98 exit:
99         mov             r0, r6                  /* return status in r0 */
100         bkpt    #0