contrib: add ram loader src code
[openocd.git] / contrib / loaders / flash / pic32mx.s
1 /***************************************************************************
2  *   Copyright (C) 2010 by Spencer Oliver                                  *
3  *   spen@spen-soft.co.uk                                                  *
4  *                                                                         *
5  *   This program is free software; you can redistribute it and/or modify  *
6  *   it under the terms of the GNU General Public License as published by  *
7  *   the Free Software Foundation; either version 2 of the License, or     *
8  *   (at your option) any later version.                                   *
9  *                                                                         *
10  *   This program is distributed in the hope that it will be useful,       *
11  *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
12  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
13  *   GNU General Public License for more details.                          *
14  *                                                                         *
15  *   You should have received a copy of the GNU General Public License     *
16  *   along with this program; if not, write to the                         *
17  *   Free Software Foundation, Inc.,                                       *
18  *   59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
19  ***************************************************************************/
20
21         .text
22         .set noreorder
23         .set noat
24
25 /* params:
26  * $a0 src adr - ram + result
27  * $a1 dest adr - flash
28  * $a2 count (32bit words)
29  * vars
30  *
31  * temps:
32  * $t0, $t1, $t2, $t3, $t4, $t5
33  * $s0, $s1, $s3, $s4, $s5
34  */
35
36         .type main, @function
37         .global main
38
39 .ent main
40 main:
41         /* setup constants */
42         lui             $t0, 0xaa99
43         ori             $t0, 0x6655                             /* NVMKEY1 */
44         lui             $t1, 0x5566
45         ori             $t1, 0x99AA                             /* NVMKEY2 */
46         lui             $t2, 0xBF80
47         ori             $t2, 0xF400                             /* NVMCON */
48         ori             $t3, $zero, 0x4003              /* NVMCON row write cmd */
49         ori             $t4, $zero, 0x8000              /* NVMCON start cmd */
50
51 write_row:
52         /* can we perform a row write: 128 32bit words */
53         sltiu   $s3, $a2, 128
54         bne             $s3, $zero, write_word
55         ori             $t5, $zero, 0x4000              /* NVMCON clear cmd */
56
57         /* perform row write 512 bytes */
58         sw              $a1, 32($t2)    /* set NVMADDR with dest addr - real addr */
59         sw              $a0, 64($t2)    /* set NVMSRCADDR with src addr - real addr */
60
61         bal             progflash
62         addiu   $a0, $a0, 512
63         addiu   $a1, $a1, 512
64         beq             $zero, $zero, write_row
65         addiu   $a2, $a2, -128
66
67 write_word:
68         /* write 32bit words */
69         lui             $s5, 0xa000
70         ori             $s5, 0x0000
71         or              $a0, $a0, $s5                   /* convert to virtual addr */
72
73         beq             $zero, $zero, next_word
74         ori             $t3, $zero, 0x4001              /* NVMCON word write cmd */
75
76 prog_word:
77         lw              $s4, 0($a0)             /* load data - from virtual addr */
78         sw              $s4, 48($t2)    /* set NVMDATA with data */
79         sw              $a1, 32($t2)    /* set NVMADDR with dest addr - real addr */
80
81         bal             progflash
82         addiu   $a0, $a0, 4
83         addiu   $a1, $a1, 4
84         addiu   $a2, $a2, -1
85 next_word:
86         bne             $a2, $zero, prog_word
87         nop
88
89 done:
90         beq             $zero, $zero, exit
91         addiu   $a0, $zero, 0
92
93 error:
94         /* save result to $a0 */
95         addiu   $a0, $s1, 0
96         
97 exit:
98         sdbbp
99 .end main
100
101         .type progflash, @function
102         .global progflash
103
104 .ent progflash
105 progflash:
106         sw              $t3, 0($t2)             /* set NVMWREN */
107         sw              $t0, 16($t2)    /* write NVMKEY1 */
108         sw              $t1, 16($t2)    /* write NVMKEY2 */
109         sw              $t4, 8($t2)             /* start operation */
110
111 waitflash:
112         lw              $s0, 0($t2)
113         and             $s0, $s0, $t4
114         bne             $s0, $zero, waitflash
115         nop
116
117         /* following is to comply with errata #34
118          * 500ns delay required */
119         nop
120         nop
121         nop
122         nop
123         /* check for errors */
124         lw              $s1, 0($t2)
125         andi    $s1, $zero, 0x3000
126         bne             $s1, $zero, error
127         sw              $t5, 4($t2)             /* clear NVMWREN */
128         jr              $ra
129         nop
130         
131 .end progflash