Add qemu 2.4.0
[kvmfornfv.git] / qemu / roms / openhackware / src / vectors.S
1 /* 
2  *   <vectors.S>
3  *      
4  *   Second stage boot-loader and exception vectors for Open Hack'Ware.
5  *   
6  *   Copyright (C) 2004-2005 Jocelyn Mayer (l_indien@magic.fr)
7  *   
8  *   This program is free software; you can redistribute it and/or
9  *   modify it under the terms of the GNU General Public License V2
10  *   as published by the Free Software Foundation
11  *
12  *   This program is distributed in the hope that it will be useful,
13  *   but WITHOUT ANY WARRANTY; without even the implied warranty of
14  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15  *   GNU General Public License for more details.
16  *
17  *   You should have received a copy of the GNU General Public License
18  *   along with this program; if not, write to the Free Software
19  *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
20  */
21
22 #define ASSEMBLY_CODE
23 #include "bios.h"
24
25 .section .text
26 .align 2
27
28 .globl _start
29 _start:
30         /* Entry point */
31         li      r0, 0                                     ;
32 _turn_off_mmu:
33         /* Be sure MMU is off and we are in 32 bits mode (for PPC64) */
34         lis     r11, _hw_init@h                           ;
35         ori     r11, r11, _hw_init@l                      ;
36         mtspr   26, r11                                   ;
37         mtspr   27, r0                                    ;
38         rfi                                               ;
39 _hw_init:
40         /* May need more hw init here */
41 _load_bios:
42         /* Load the full BIOS into RAM */
43         lis     r12, bios_base@h                          ;
44         ori     r12, r12, bios_base@l                     ;
45         lmw     r29, 0(r12)                               ;
46         /* Set up the C stack */
47         addis   r1, r29, 0x0040                           ;
48         clrrwi  r1, r1, 19                                ;
49         stw     r1, -16(r1)                               ;
50         stwu    r0, -4(r1)                                ;
51         stwu    r0, -4(r1)                                ;
52         stwu    r0, -4(r1)                                ;
53         stwu    r0, -4(r1)                                ;
54         /* Skip frame pointer */        
55         stwu    r0, -8(r1)                                ;
56         stwu    r0, -4(r1)                                ;
57         stwu    r0, -4(r1)                                ;
58         /* Start copying */
59         mtctr   r30                                       ;
60         subi    r12, r3, 4                                ;
61         subi    r13, r29, 4                               ;
62 _bios_copy_loop:
63         lwzu    r14, 4(r12)                               ;
64         stwu    r14, 4(r13)                               ;
65         bdnz    _bios_copy_loop                           ;
66         /* Synchronize the whole execution context */
67         /* Also enable FPU */
68         ori     r0, r0, (1 << 13)                         ;
69         mtspr   26, r29                                   ;
70         mtspr   27, r0                                    ;
71         rfi                                               ;
72         /* If we ever return, stop */
73         bl      bug                                       ;
74
75 .org 0x0080
76 .section .text
77 .align 2
78 bug:
79         /* Dump the exception and its context */
80         mflr    r3                                        ;
81         mfspr   r4, SRR0                                  ;
82         mfspr   r5, SRR1                                  ;
83         mfspr   r6, DAR                                   ;
84         mfspr   r7, DSISR                                 ;
85         /* Turn MMU off */
86         lis     r0, _bug_no_mmu@h                         ;
87         ori     r0, r0, _bug_no_mmu@l                     ;
88         mtspr   26, r0                                    ;
89         li      r0, 0                                     ;
90         mtspr   27, r0                                    ;
91         rfi                                               ;
92 _bug_no_mmu:
93         bl      dump_exception                            ;
94 _forever:
95         /* Loop forever */
96         b       _forever                                  ;
97
98 skip_exception:
99         /* Skip external interrupts and decrementer exception */
100         /* BEWARE: be sure not to modify any register */
101         stw     r11, save_area@l(0)                       ;
102         mfspr   r11, 27                                   ;
103         clrlwi  r11, r11, 16                              ;
104         mtspr   27, r11                                   ;
105         lwz     r11, save_area@l(0)                       ;
106         rfi                                               ;
107
108 #define EXCP_BUG(entry)                                     \
109 .org 0x##entry                                            ; \
110 .section .text                                            ; \
111 .align 2                                                  ; \
112 excp_##entry:                                             ; \
113         bl bug
114
115 #define EXCP_SKIP(entry)                                    \
116 .org 0x##entry                                            ; \
117 .section .text                                            ; \
118 .align 2                                                  ; \
119 excp_##entry##:                                           ; \
120         b skip_exception
121
122         /* Exception vectors */
123         /* Reset exception */
124 .org 0x0100
125 excp_0100:
126         ba 0xfffffffc
127
128         /* Machine check exception */
129         EXCP_BUG(0200)                                    ;
130
131         /* DSI exception */
132         EXCP_BUG(0300)                                    ;
133
134         /* ISI exception */
135         EXCP_BUG(0400)                                    ;
136
137         /* External interrupt: skip it */
138         EXCP_SKIP(0500)                                   ;
139
140         /* Alignment exception */
141         EXCP_BUG(0600)                                    ;
142
143         /* Program exception */
144         EXCP_BUG(0700)                                    ;
145
146         /* No floating point exception */
147         EXCP_BUG(0800)                                    ;
148
149         /* Decrementer exception: skip it */
150         EXCP_SKIP(0900)                                   ;
151
152         /* Reserved A exception */
153         EXCP_BUG(0A00)                                    ;
154
155         /* Reserved B exception */
156         EXCP_BUG(0B00)                                    ;
157
158         /* System call exception */
159         EXCP_BUG(0C00)                                    ;
160
161         /* Trace exception */
162         EXCP_BUG(0D00)                                    ;
163
164         /* Floating point assist exception */
165         EXCP_BUG(0E00)                                    ;
166
167         /* Performance monitor exception */
168         EXCP_BUG(0F00)                                    ;
169
170         /* Instruction TLB miss exception */
171         EXCP_BUG(1000)                                    ;
172
173         /* Data TLB miss for store exception */
174         EXCP_BUG(1100)                                    ;
175
176         /* Data TLB miss for load exception */
177         EXCP_BUG(1200)                                    ;
178
179         /* Instruction address breakpoint exception */
180         EXCP_BUG(1300)                                    ;
181
182         /* System management interrupt exception */
183         EXCP_BUG(1400)                                    ;
184
185         /* Thermal management exception */
186         EXCP_BUG(1500)                                    ;
187
188         /* Unknown exceptions */
189         EXCP_BUG(1600)                                    ;
190
191         EXCP_BUG(1700)                                    ;
192
193         EXCP_BUG(1800)                                    ;
194
195         EXCP_BUG(1900)                                    ;
196
197         EXCP_BUG(1A00)                                    ;
198
199         EXCP_BUG(1B00)                                    ;
200
201         EXCP_BUG(1C00)                                    ;
202
203         EXCP_BUG(1D00)                                    ;
204
205         EXCP_BUG(1E00)                                    ;
206
207         EXCP_BUG(1F00)                                    ;
208         /* End of exception vectors list */
209
210 .org 0x2000
211 .section .text
212 .align 2
213 helpers_start:
214
215 outb:
216         /* void outb (uint32_t port, uint32_t data);
217          * Writes a single character on an IO port.
218          * Used for serial console.
219          */
220         stb     r4, 0(r3)                                 ;
221         eieio                                             ;
222         blr                                               ;
223
224 outstr:
225         /* void outstr (uint32_t port, const unsigned char *str);
226          * Writes a string on an IO port.
227          */
228         mflr    r20                                       ;
229         subi    r11, r4, 1                                ;
230         
231 _outstr_next:
232         lbzu    r4, 1(r11)                                ;
233         cmpi    0, r4, 0                                  ;
234         beq     _outstr_done                              ;
235         bl      outb                                      ;
236         b       _outstr_next                              ;
237 _outstr_done:
238         mtlr    r20                                       ;
239         blr                                               ;
240
241 outdigit:
242         /* void outdigit (uint32_t port, uint32_t digit);
243          * Dumps a single digit on serial port.
244          */
245         mflr    r20                                       ;
246         addi    r4, r4, '0'                               ;
247         bl      outb                                      ;
248         mtlr    r20                                       ;
249         blr                                               ;
250
251 outhex:
252         /* void outhex (uint32_t port, uint32_t value);
253          * Dumps a 32 bits hex number on serial port
254          */
255         mflr    r21
256         li      r11, 8                                    ;
257         mtctr   r11                                       ;
258         mr      r11, r4                                   ;
259 _outhex_next:
260         rlwinm  r11, r11, 4, 0, 31                        ;
261         clrlwi  r4, r11, 28                               ;
262         cmpi    0, r4, 9                                  ;
263         bgt     _outhex_xdigit                            ;
264         bl      outdigit                                  ;
265         bdnz    _outhex_next                              ;
266         b       _outhex_done                              ;
267 _outhex_xdigit:
268         addi    r4, r4, 'a' - 10                          ;
269         bl      outb                                      ;
270         bdnz    _outhex_next                              ;
271 _outhex_done:
272         mtlr    r21                                       ;
273         blr                                               ;
274
275         /* void dump_exception (uint32_t lr, uint32_t srr0, uint32_t srr1,
276          *                      uint32_t dar, uint32_t dsisr);
277          * Dump a message when catching an exception
278          */
279 dump_exception:
280         /* Save call parameters */
281         mflr    r19                                       ;
282         mr      r22, r3                                   ;
283         mr      r23, r4                                   ;
284         mr      r24, r5                                   ;
285         mr      r25, r6                                   ;
286         mr      r26, r7                                   ;
287         lis     r11, registers_area@h                     ;
288         ori     r11, r11, registers_area@l                ;
289         lmw     r27, 0(r11)                               ;
290         /* Now, serial IO port is in r27,
291          * message table start is in r28,
292          * first exception message offset is in r29,
293          * and last known exception number is in r30
294          */
295         /* Print error prompt message */
296         mr      r3, r27                                   ;
297         lwzu    r4, 4(r28)                                ;
298         bl      outstr                                    ;
299         /* Find message corresponding to the caught exception */
300         srwi    r12, r22, 8                               ;
301         cmp     0, r12, r30                               ;
302         ble     _dump_excp_msg                            ;
303         subi    r12, r30, 1                               ;
304 _dump_excp_msg:
305         rlwinm  r12, r12, 2, 0, 31                        ;
306         /* Dump execption message */
307         mr      r3, r27                                   ;
308         lwzx    r4, r12, r29                              ;
309         bl      outstr                                    ;
310         /* Complete exception message */
311         mr      r3, r27                                   ;
312         lwzu    r4, 4(r28)                                ;
313         bl      outstr                                    ;
314         /* Dump nip */
315         mr      r3, r27                                   ;
316         lwzu    r4, 4(r28)                                ;
317         bl      outstr                                    ;
318         mr      r3, r27                                   ;
319         mr      r4, r23                                   ;
320         bl      outhex                                    ;
321         /* dump msr */
322         mr      r3, r27                                   ;
323         lwzu    r4, 4(r28)                                ;
324         bl      outstr                                    ;
325         mr      r3, r27                                   ;
326         mr      r4, r24                                   ;
327         bl      outhex                                    ;
328         /* dump dar */
329         mr      r3, r27                                   ;
330         lwzu    r4, 4(r28)                                ;
331         bl      outstr                                    ;
332         mr      r3, r27                                   ;
333         mr      r4, r25                                   ;
334         bl      outhex                                    ;
335         /* dump dsisr */
336         mr      r3, r27                                   ;
337         lwzu    r4, 4(r28)                                ;
338         bl      outstr                                    ;
339         mr      r3, r27                                   ;
340         mr      r4, r26                                   ;
341         bl      outhex                                    ;
342         /* All done, dump last message and return */
343         mr      r3, r27                                   ;
344         lwzu    r4, 4(r28)                                ;
345         bl      outstr                                    ;
346         mtlr    r19                                       ;
347         blr                                               ;
348
349 .section .rodata
350 .align 2
351 _BUG_message_0:
352         .string "ERROR: BUG caught...\n"
353 _BUG_message_1:
354         .string " exception"
355 _BUG_message_2:
356         .string "\nnip=0x"
357 _BUG_message_3:
358         .string " msr=0x"
359 _BUG_message_4:
360         .string " dar=0x"
361 _BUG_message_5:
362         .string " dsisr=0x"
363 _BUG_message_6:
364         .string "\nStopping execution\n"
365
366 _excp_message_0x00:
367         .string "BIOS execution"
368 _excp_message_0x01:
369         .string "Reset"
370 _excp_message_0x02:
371         .string "Machine check"
372 _excp_message_0x03:
373         .string "Data memory access"
374 _excp_message_0x04:
375         .string "Instruction fetch"
376 _excp_message_0x05:
377         .string "External"
378 _excp_message_0x06:
379         .string "Alignment"
380 _excp_message_0x07:
381         .string "Program"
382 _excp_message_0x08:
383         .string "No floating point"
384 _excp_message_0x09:
385         .string "Decrementer"
386 _excp_message_0x0a:
387         .string "Reserved A"
388 _excp_message_0x0b:
389         .string "Reserved B"
390 _excp_message_0x0c:
391         .string "System call"
392 _excp_message_0x0d:
393         .string "Trace"
394 _excp_message_0x0e:
395         .string "Floating point assist"
396 _excp_message_0x0f:
397         .string "Performance monitor"
398 _excp_message_0x10:
399         .string "Instruction TLB miss"
400 _excp_message_0x11:
401         .string "Data TLB miss for store"
402 _excp_message_0x12:
403         .string "Data TLB miss for load"
404 _excp_message_0x13:
405         .string "Instruction address breakpoint"
406 _excp_message_0x14:
407         .string "System management"
408 _excp_message_0x15:
409         .string "Thermal management"
410 _excp_message_0x16:
411         .string "Unknown"
412 _messages_table:
413         .long _BUG_message_0
414         .long _BUG_message_1
415         .long _BUG_message_2
416         .long _BUG_message_3
417         .long _BUG_message_4
418         .long _BUG_message_5
419         .long _BUG_message_6
420 _excp_messages_table:
421         .long _excp_message_0x00
422         .long _excp_message_0x01
423         .long _excp_message_0x02
424         .long _excp_message_0x03
425         .long _excp_message_0x04
426         .long _excp_message_0x05
427         .long _excp_message_0x06
428         .long _excp_message_0x07
429         .long _excp_message_0x08
430         .long _excp_message_0x09
431         .long _excp_message_0x0a
432         .long _excp_message_0x0b
433         .long _excp_message_0x0c
434         .long _excp_message_0x0d
435         .long _excp_message_0x0e
436         .long _excp_message_0x0f
437         .long _excp_message_0x10
438         .long _excp_message_0x11
439         .long _excp_message_0x12
440         .long _excp_message_0x13
441         .long _excp_message_0x14
442         .long _excp_message_0x15
443         .long _excp_message_0x16
444 _last_excp_message:
445
446 bios_base:
447         .long BIOS_BASE
448 bios_size:
449         .long BIOS_SIZE / 4
450 _dummy_0:
451         .long 0x00000000
452
453 registers_area: /* To be loaded in register when an exception is caught */
454 _serial_IO:      /* r27 */
455         .long 0x800003F8
456 _messages_start: /* r28 */
457         .long _messages_table - 4
458 _excp_messages:  /* r29 */
459         .long _excp_messages_table
460 _max_excp:       /* r30 */
461         .long (_last_excp_message - _excp_messages_table) / 4
462 _dummy_1:        /* r31: dummy */
463         .long 0x00000000
464         
465 .section .data
466 .align 2
467 save_area: /* Area for r11 save when an exception is skipped */
468         .long 0x00000000