contrib: replace the GPLv2-or-later license tag
[fw/openocd] / contrib / loaders / flash / pic32mx.s
1 /* SPDX-License-Identifier: GPL-2.0-or-later */
2
3 /***************************************************************************
4  *   Copyright (C) 2010 by Spencer Oliver                                  *
5  *   spen@spen-soft.co.uk                                                  *
6  ***************************************************************************/
7
8         .text
9         .arch m4k
10         .set noreorder
11         .set noat
12
13 /* params:
14  * $a0 src adr - ram + result
15  * $a1 dest adr - flash
16  * $a2 count (32bit words)
17  * vars
18  *
19  * temps:
20  * $t0, $t1, $t2, $t3, $t4, $t5
21  * $s0, $s1, $s3, $s4, $s5
22  */
23
24         .type main, @function
25         .global main
26
27 .ent main
28 main:
29         /* setup constants */
30         lui             $t0, 0xaa99
31         ori             $t0, 0x6655                             /* NVMKEY1 */
32         lui             $t1, 0x5566
33         ori             $t1, 0x99AA                             /* NVMKEY2 */
34         lui             $t2, 0xBF80
35         ori             $t2, 0xF400                             /* NVMCON */
36         ori             $t3, $zero, 0x4003              /* NVMCON row write cmd */
37         ori             $t4, $zero, 0x8000              /* NVMCON start cmd */
38
39 write_row:
40         /* can we perform a row write: 128 32bit words */
41         sltiu   $s3, $a2, 128
42         bne             $s3, $zero, write_word
43         ori             $t5, $zero, 0x4000              /* NVMCON clear cmd */
44
45         /* perform row write 512 bytes */
46         sw              $a1, 32($t2)    /* set NVMADDR with dest addr - real addr */
47         sw              $a0, 64($t2)    /* set NVMSRCADDR with src addr - real addr */
48
49         bal             progflash
50         addiu   $a0, $a0, 512
51         addiu   $a1, $a1, 512
52         beq             $zero, $zero, write_row
53         addiu   $a2, $a2, -128
54
55 write_word:
56         /* write 32bit words */
57         lui             $s5, 0xa000
58         ori             $s5, 0x0000
59         or              $a0, $a0, $s5                   /* convert to virtual addr */
60
61         beq             $zero, $zero, next_word
62         ori             $t3, $zero, 0x4001              /* NVMCON word write cmd */
63
64 prog_word:
65         lw              $s4, 0($a0)             /* load data - from virtual addr */
66         sw              $s4, 48($t2)    /* set NVMDATA with data */
67         sw              $a1, 32($t2)    /* set NVMADDR with dest addr - real addr */
68
69         bal             progflash
70         addiu   $a0, $a0, 4
71         addiu   $a1, $a1, 4
72         addiu   $a2, $a2, -1
73 next_word:
74         bne             $a2, $zero, prog_word
75         nop
76
77 done:
78         beq             $zero, $zero, exit
79         addiu   $a0, $zero, 0
80
81 error:
82         /* save result to $a0 */
83         addiu   $a0, $s1, 0
84
85 exit:
86         sdbbp
87 .end main
88
89         .type progflash, @function
90         .global progflash
91
92 .ent progflash
93 progflash:
94         sw              $t3, 0($t2)             /* set NVMWREN */
95         sw              $t0, 16($t2)    /* write NVMKEY1 */
96         sw              $t1, 16($t2)    /* write NVMKEY2 */
97         sw              $t4, 8($t2)             /* start operation */
98
99 waitflash:
100         lw              $s0, 0($t2)
101         and             $s0, $s0, $t4
102         bne             $s0, $zero, waitflash
103         nop
104
105         /* following is to comply with errata #34
106          * 500ns delay required */
107         nop
108         nop
109         nop
110         nop
111         /* check for errors */
112         lw              $s1, 0($t2)
113         andi    $s1, $zero, 0x3000
114         bne             $s1, $zero, error
115         sw              $t5, 4($t2)             /* clear NVMWREN */
116         jr              $ra
117         nop
118
119 .end progflash