contrib: replace the GPLv2-or-later license tag
[fw/openocd] / contrib / loaders / flash / stmqspi / stmoctospi_erase_check.S
1 /* SPDX-License-Identifier: GPL-2.0-or-later */
2
3 /***************************************************************************
4  *   Copyright (C) 2019 by Andreas Bolsch                                  *
5  *   andreas.bolsch@mni.thm.de                                             *
6  ***************************************************************************/
7
8         .text
9         .syntax unified
10         .cpu cortex-m0
11         .thumb
12         .thumb_func
13
14 /* Params:
15  * r0 - sector count
16  * r1 - QSPI io_base
17
18  * Clobbered:
19  * r2 - r7 tmp */
20
21 #include "../../../../src/flash/nor/stmqspi.h"
22
23 #define OCTOSPI_CCR_CCR                                 (OCTOSPI_CCR - OCTOSPI_CCR)
24 #define OCTOSPI_TCR_CCR                                 (OCTOSPI_TCR - OCTOSPI_CCR)
25 #define OCTOSPI_IR_CCR                                  (OCTOSPI_IR - OCTOSPI_CCR)
26
27         .macro  octospi_abort
28         movs    r5, #(1<<SPI_ABORT)                     /* abort bit mask */
29         ldr             r7, [r1, #OCTOSPI_CR]           /* get OCTOSPI_CR register */
30         orrs    r7, r7, r5                                      /* set abort bit */
31         str             r7, [r1, #OCTOSPI_CR]           /* store new CR register */
32         .endm
33
34         .macro  wait_busy
35 0:
36         ldr             r7, [r1, #OCTOSPI_SR]           /* load status */
37         lsrs    r7, r7, #(SPI_BUSY+1)           /* shift BUSY into C */
38         bcs             0b                                                      /* loop until BUSY cleared */
39         movs    r7, #(1<<SPI_TCF)                       /* TCF bitmask */
40         str             r7, [r1, #OCTOSPI_FCR]          /* clear TCF flag */
41         .endm
42
43 start:
44         adr             r2, buffer                                      /* pointer to start of buffer */
45         movs    r3, #OCTOSPI_DR                         /* load OCTOSPI_DR address offset */
46         adds    r3, r3, r1                                      /* address of OCTOSPI_DR */
47 sector_start:
48         octospi_abort                                           /* start in clean state */
49         movs    r6, #OCTOSPI_CCR-OCTOSPI_DR     /* load OCTOSPI_CCR address offset */
50         adds    r6, r6, r3                                      /* address of OCTOSPI_CCR */
51         wait_busy
52         ldr             r7, cr_page_read                        /* indirect read mode */
53         str             r7, [r1, #OCTOSPI_CR]           /* set mode */
54         ldmia   r2!, {r4, r5}                           /* load address offset, length */
55         subs    r2, r2, #4                                      /* point to length */
56         subs    r5, r5, #1                                      /* decrement sector length for DLR */
57         str             r5, [r1, #OCTOSPI_DLR]          /* size-1 in DLR register */
58         ldr             r7, ccr_page_read                       /* CCR for read */
59         str             r7, [r6, #OCTOSPI_CCR_CCR]      /* initiate transfer */
60         ldr             r7, tcr_page_read                       /* TCR for read */
61         str             r7, [r6, #OCTOSPI_TCR_CCR]      /* instruction */
62         ldr             r7, ir_page_read                        /* IR for read */
63         str             r7, [r6, #OCTOSPI_IR_CCR]       /* instruction */
64         str             r4, [r1, #OCTOSPI_AR]           /* store SPI start address */
65         ldr             r6, [r2, #4]                            /* load initial value */
66 read_loop:
67         ldrb    r4, [r3, #0]                            /* read next byte from DR */
68         movs    r7, #0xFF                                       /* fill bits 8-15 */
69         lsls    r7, r7, #8                                      /* with ones */
70         orrs    r4, r4, r7                                      /* copy ones to left of read byte */
71         ands    r6, r6, r4                                      /* and read byte to result */
72         lsls    r4, r4, #8                                      /* shift result into higher byte */
73         orrs    r6, r6, r4                                      /* or read byte to result */
74         subs    r5, r5, #1                                      /* decrement byte (count-1) */
75         bpl             read_loop                                       /* again if sector not completed */
76         adds    r5, r5, #1                                      /* increment count due to the -1 */
77         stmia   r2!, {r5, r6}                           /* save final count and result for sector */
78         subs    r0, r0, #1                                      /* decrement sector count */
79         bne             sector_start                            /* next sector? */
80         octospi_abort                                           /* to idle state */
81
82 exit:
83         .align  2                                                       /* align to word, bkpt is 4 words */
84         bkpt    #0                                                      /* before code end for exit_point */
85         .align  2                                                       /* align to word */
86
87 cr_page_read:
88         .space  4                                                       /* OCTOSPI_CR value for read command */
89 ccr_page_read:
90         .space  4                                                       /* OCTOSPI_CCR value for read command */
91 tcr_page_read:
92         .space  4                                                       /* OCTOSPI_TCR value for read command */
93 ir_page_read:
94         .space  4                                                       /* OCTOSPI_IR value for read command */
95
96         .equ buffer, .
97