Add lm32 cpu and milkymist port
[mw/micromonitor-lm32.git] / umon_ports / milkymist / reset.S
1 /* reset.S:
2  *
3  * First bit of boot code run by the processor.
4  *
5  */
6     .file   "reset.S"
7
8     .extern start
9     .extern MonStack
10     .extern exception
11     .global reset
12     .global warmstart
13     .global coldstart
14
15 #include "config.h"
16 #include "warmstart.h"
17 #include "cpu.h"
18
19 /*********************************************************************
20  *
21  * coldstart:
22  * The reset point.
23  */
24 reset:
25 _reset_handler:
26     /* set r0 to zero */
27     xor r0, r0, r0
28     /* disable and mask irq */
29     wcsr IE, r0
30     wcsr IM, r0
31     /* set exception base address */
32     mvhi r1, hi(_reset_handler)
33     ori r1, r1, lo(_reset_handler)
34     wcsr EBA, r1
35     /* do coldstart */
36     bi coldstart
37     nop
38
39 _breakpoint_handler:
40     addi sp, sp, -16
41     sw (sp+0), r1
42     sw (sp+4), r2
43     addi r1, ba, -4
44     mvi r2, EXCP_BREAKPOINT
45     bi exception_handler
46     nop
47     nop
48
49 _instruction_bus_error_handler:
50     addi sp, sp, -16
51     sw (sp+0), r1
52     sw (sp+4), r2
53     addi r1, ea, -4
54     mvi r2, EXCP_I_BUS_ERROR
55     bi exception_handler
56     nop
57     nop
58
59 _watchpoint_handler:
60     addi sp, sp, -16
61     sw (sp+0), r1
62     sw (sp+4), r2
63     addi r1, ba, -4
64     mvi r2, EXCP_WATCHPOINT
65     bi exception_handler
66     nop
67     nop
68
69 _data_bus_error_handler:
70     addi sp, sp, -16
71     sw (sp+0), r1
72     sw (sp+4), r2
73     addi r1, ea, -4
74     mvi r2, EXCP_D_BUS_ERROR
75     bi exception_handler
76     nop
77     nop
78
79 _divide_by_zero_handler:
80     addi sp, sp, -16
81     sw (sp+0), r1
82     sw (sp+4), r2
83     addi r1, ea, -4
84     mvi r2, EXCP_DIVIDE_BY_ZERO
85     bi exception_handler
86     nop
87     nop
88
89 _interrupt_handler:
90     addi sp, sp, -16
91     sw (sp+0), r1
92     sw (sp+4), r2
93     addi r1, ea, -4
94     mvi r2, EXCP_INTERRUPT
95     bi exception_handler
96     nop
97     nop
98
99 _system_call_handler:
100     addi sp, sp, -16
101     sw (sp+0), r1
102     sw (sp+4), r2
103     addi r1, ea, -4
104     mvi r2, EXCP_SYSTEM_CALL
105     bi exception_handler
106     nop
107     nop
108
109 coldstart:
110     mvi r1, 1
111
112     /* flush data cache */
113     wcsr DCC, r1
114     nop
115     nop
116     nop
117     nop
118
119     /* flush instruction cache */
120     wcsr ICC, r1
121     nop
122     nop
123     nop
124     nop
125
126     mvi r1, INITIALIZE
127     bi warmstart
128     
129 /*********************************************************************
130  *
131  * moncomptr:
132  * Pointer to the moncom function, used to link application to monitor.
133  * Refer to umon_main/target/core/moncomptr.S
134  */
135 #include "moncomptr.S"
136
137 /*********************************************************************
138  *
139  * etheraddr:
140  * Location that could be used to store a fixed MAC address.
141  * Refer to umon_main/target/core/etheraddr.S.
142  * NOTE:
143  * This should only be included in flash-resident code, then
144  * the address in flash should be accessible to ram-based versions of
145  * uMon via tags in the linker map file.
146  */
147 #include "etheraddr.S"
148
149 /*********************************************************************
150  *
151  * alttfsdevtbl.S:
152  * Location that could be used to store an "alternate" TFS device
153  * table for use by the "tfs cfg" command.
154  * Refer to umon_main/target/core/alttfsdevtbl.S.
155  * NOTE:
156  * This should only be included in flash-resident code, then
157  * the address in flash should be accessible to ram-based versions of
158  * uMon via tags in the linker map file.
159  */
160 #include "alttfsdevtbl.S"
161     
162 /*********************************************************************
163  *
164  * warmstart:
165  * A point callable by C, as warmstart(int type), where
166  * 'type' is one of the values defined in warmstart.h.
167  */
168 warmstart:
169     mv r11, r1
170     /* Minimal CPU/IO Initialization (i.e. chip selects) here.
171      * Stay in assembler here if possible.
172      */
173     
174 /*********************************************************************
175  *
176  * SPInit:
177  * Establish a stack frame.
178  */
179 SPInit:
180     /* First initialize stack to point to MonStack+MONSTACKSIZE+64
181      * (an address that is outside the MonStack array), and then
182      * call stkinit().  This loads the MonStack[] array with a known
183      * pattern that allows uMon to later analyze the running stack usage.
184      */
185     mvhi sp, hi(MonStack)
186     ori sp, sp, lo(MonStack)
187     addi sp, sp, MONSTACKSIZE+64
188     mvhi r1, hi(stkinit)
189     ori r1, r1, lo(stkinit)
190     call r1
191     
192     /* Next, re-initialize stack to point to MonStack+MONSTACKSIZE...
193      * This is important because other portions of the code
194      * assume this is where the stack resides.
195      */
196     mvhi sp, hi(MonStack)
197     ori sp, sp, lo(MonStack)
198     addi sp, sp, MONSTACKSIZE-4
199
200 /*********************************************************************
201  *
202  * gotoC:
203  * This code jumps to the start() function in the monitor
204  * and should never return.
205  */
206 gotoC:
207     /* - Retrieve the variable passed to warmstart and place it
208      *   whereever it needs to be so that the start() function in
209      *   'C' sees it as an argument.  Note that if FORCE_BSS_INIT
210      *   is defined, then start() will ignore this argument.
211      * - Branch to start().
212      */
213     mv r1, r11
214     mvhi r2, hi(start)
215     ori r2, r2, lo(start)
216     b r2
217
218 exception_handler:
219     /* store registers we use here */
220     sw (sp+8), r3
221     sw (sp+12), r4
222
223     /* save registers to regtbl */
224     mvhi r3, hi(regtbl)
225     ori r3, r3, lo(regtbl)
226
227     sw (r3+0), r0
228
229     /* store r1 */
230     lw r4, (sp+0)
231     sw (r3+4), r4
232
233     /* store r2 */
234     lw r4, (sp+4)
235     sw (r3+8), r4
236
237     /* store r3 */
238     lw r4, (sp+8)
239     sw (r3+12), r4
240
241     /* r4 is stored at the end */
242
243     sw (r3+20), r5
244     sw (r3+24), r6
245     sw (r3+28), r7
246     sw (r3+32), r8
247     sw (r3+36), r9
248     sw (r3+40), r10
249     sw (r3+44), r11
250     sw (r3+48), r12
251     sw (r3+52), r13
252     sw (r3+56), r14
253     sw (r3+60), r15
254     sw (r3+64), r16
255     sw (r3+68), r17
256     sw (r3+72), r18
257     sw (r3+76), r19
258     sw (r3+80), r20
259     sw (r3+84), r21
260     sw (r3+88), r22
261     sw (r3+92), r23
262     sw (r3+96), r24
263     sw (r3+100), r25
264     sw (r3+104), r26   /* gp */
265     sw (r3+108), r27   /* fp */
266
267     /* store r28/sp */
268     addi r4, sp, 16
269     sw (r3+112), r4    /* sp */
270     sw (r3+116), r29   /* ra */
271     sw (r3+120), r30   /* ea */
272     sw (r3+124), r31   /* ba */
273
274     /* PC is exception address */
275     sw (r3+128), r1
276
277     /* EID is exception type */
278     sw (r3+132), r2
279
280     /* store eba */
281     rcsr r4, eba
282     sw (r3+136), r4
283
284     /* store deba */
285     rcsr r4, deba
286     sw (r3+140), r4
287
288     /* store ie */
289     rcsr r4, ie
290     sw (r3+144), r4
291
292     /* store im */
293     rcsr r4, im
294     sw (r3+148), r4
295
296     /* store ip */
297     rcsr r4, ip
298     sw (r3+152), r4
299
300     /* now we can store r4 */
301     lw r5, (sp+12)
302     sw (r3+16), r4
303
304     /* should never return */
305     calli exception
306
307 dead_end:
308     bi dead_end
309