Fix compilation with biarch compilers
[openhackware.git] / src / vectors.S
blob691d56863452b0d69c1447568c98c6ef61430dc2
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  */
22 #define ASSEMBLY_CODE
23 #include "bios.h"
25 .section .text
26 .align 2
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                                       ;
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                                  ;
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                                               ;
108 #define EXCP_BUG(entry)                                     \
109 .org 0x##entry                                            ; \
110 .section .text                                            ; \
111 .align 2                                                  ; \
112 excp_##entry:                                             ; \
113         bl bug
115 #define EXCP_SKIP(entry)                                    \
116 .org 0x##entry                                            ; \
117 .section .text                                            ; \
118 .align 2                                                  ; \
119 excp_##entry##:                                           ; \
120         b skip_exception
122         /* Exception vectors */
123         /* Reset exception */
124         EXCP_BUG(0100)                                    ;
126         /* Machine check exception */
127         EXCP_BUG(0200)                                    ;
129         /* DSI exception */
130         EXCP_BUG(0300)                                    ;
132         /* ISI exception */
133         EXCP_BUG(0400)                                    ;
135         /* External interrupt: skip it */
136         EXCP_SKIP(0500)                                   ;
138         /* Alignment exception */
139         EXCP_BUG(0600)                                    ;
141         /* Program exception */
142         EXCP_BUG(0700)                                    ;
144         /* No floating point exception */
145         EXCP_BUG(0800)                                    ;
147         /* Decrementer exception: skip it */
148         EXCP_SKIP(0900)                                   ;
150         /* Reserved A exception */
151         EXCP_BUG(0A00)                                    ;
153         /* Reserved B exception */
154         EXCP_BUG(0B00)                                    ;
156         /* System call exception */
157         EXCP_BUG(0C00)                                    ;
159         /* Trace exception */
160         EXCP_BUG(0D00)                                    ;
162         /* Floating point assist exception */
163         EXCP_BUG(0E00)                                    ;
165         /* Performance monitor exception */
166         EXCP_BUG(0F00)                                    ;
168         /* Instruction TLB miss exception */
169         EXCP_BUG(1000)                                    ;
171         /* Data TLB miss for store exception */
172         EXCP_BUG(1100)                                    ;
174         /* Data TLB miss for load exception */
175         EXCP_BUG(1200)                                    ;
177         /* Instruction address breakpoint exception */
178         EXCP_BUG(1300)                                    ;
180         /* System management interrupt exception */
181         EXCP_BUG(1400)                                    ;
183         /* Thermal management exception */
184         EXCP_BUG(1500)                                    ;
186         /* Unknown exceptions */
187         EXCP_BUG(1600)                                    ;
189         EXCP_BUG(1700)                                    ;
191         EXCP_BUG(1800)                                    ;
193         EXCP_BUG(1900)                                    ;
195         EXCP_BUG(1A00)                                    ;
197         EXCP_BUG(1B00)                                    ;
199         EXCP_BUG(1C00)                                    ;
201         EXCP_BUG(1D00)                                    ;
203         EXCP_BUG(1E00)                                    ;
205         EXCP_BUG(1F00)                                    ;
206         /* End of exception vectors list */
208 .org 0x2000
209 .section .text
210 .align 2
211 helpers_start:
213 outb:
214         /* void outb (uint32_t port, uint32_t data);
215          * Writes a single character on an IO port.
216          * Used for serial console.
217          */
218         stb     r4, 0(r3)                                 ;
219         eieio                                             ;
220         blr                                               ;
222 outstr:
223         /* void outstr (uint32_t port, const unsigned char *str);
224          * Writes a string on an IO port.
225          */
226         mflr    r20                                       ;
227         subi    r11, r4, 1                                ;
228         
229 _outstr_next:
230         lbzu    r4, 1(r11)                                ;
231         cmpi    0, r4, 0                                  ;
232         beq     _outstr_done                              ;
233         bl      outb                                      ;
234         b       _outstr_next                              ;
235 _outstr_done:
236         mtlr    r20                                       ;
237         blr                                               ;
239 outdigit:
240         /* void outdigit (uint32_t port, uint32_t digit);
241          * Dumps a single digit on serial port.
242          */
243         mflr    r20                                       ;
244         addi    r4, r4, '0'                               ;
245         bl      outb                                      ;
246         mtlr    r20                                       ;
247         blr                                               ;
249 outhex:
250         /* void outhex (uint32_t port, uint32_t value);
251          * Dumps a 32 bits hex number on serial port
252          */
253         mflr    r21
254         li      r11, 8                                    ;
255         mtctr   r11                                       ;
256         mr      r11, r4                                   ;
257 _outhex_next:
258         rlwinm  r11, r11, 4, 0, 31                        ;
259         clrlwi  r4, r11, 28                               ;
260         cmpi    0, r4, 9                                  ;
261         bgt     _outhex_xdigit                            ;
262         bl      outdigit                                  ;
263         bdnz    _outhex_next                              ;
264         b       _outhex_done                              ;
265 _outhex_xdigit:
266         addi    r4, r4, 'a' - 10                          ;
267         bl      outb                                      ;
268         bdnz    _outhex_next                              ;
269 _outhex_done:
270         mtlr    r21                                       ;
271         blr                                               ;
273         /* void dump_exception (uint32_t lr, uint32_t srr0, uint32_t srr1,
274          *                      uint32_t dar, uint32_t dsisr);
275          * Dump a message when catching an exception
276          */
277 dump_exception:
278         /* Save call parameters */
279         mflr    r19                                       ;
280         mr      r22, r3                                   ;
281         mr      r23, r4                                   ;
282         mr      r24, r5                                   ;
283         mr      r25, r6                                   ;
284         mr      r26, r7                                   ;
285         lis     r11, registers_area@h                     ;
286         ori     r11, r11, registers_area@l                ;
287         lmw     r27, 0(r11)                               ;
288         /* Now, serial IO port is in r27,
289          * message table start is in r28,
290          * first exception message offset is in r29,
291          * and last known exception number is in r30
292          */
293         /* Print error prompt message */
294         mr      r3, r27                                   ;
295         lwzu    r4, 4(r28)                                ;
296         bl      outstr                                    ;
297         /* Find message corresponding to the caught exception */
298         srwi    r12, r22, 8                               ;
299         cmp     0, r12, r30                               ;
300         ble     _dump_excp_msg                            ;
301         subi    r12, r30, 1                               ;
302 _dump_excp_msg:
303         rlwinm  r12, r12, 2, 0, 31                        ;
304         /* Dump execption message */
305         mr      r3, r27                                   ;
306         lwzx    r4, r12, r29                              ;
307         bl      outstr                                    ;
308         /* Complete exception message */
309         mr      r3, r27                                   ;
310         lwzu    r4, 4(r28)                                ;
311         bl      outstr                                    ;
312         /* Dump nip */
313         mr      r3, r27                                   ;
314         lwzu    r4, 4(r28)                                ;
315         bl      outstr                                    ;
316         mr      r3, r27                                   ;
317         mr      r4, r23                                   ;
318         bl      outhex                                    ;
319         /* dump msr */
320         mr      r3, r27                                   ;
321         lwzu    r4, 4(r28)                                ;
322         bl      outstr                                    ;
323         mr      r3, r27                                   ;
324         mr      r4, r24                                   ;
325         bl      outhex                                    ;
326         /* dump dar */
327         mr      r3, r27                                   ;
328         lwzu    r4, 4(r28)                                ;
329         bl      outstr                                    ;
330         mr      r3, r27                                   ;
331         mr      r4, r25                                   ;
332         bl      outhex                                    ;
333         /* dump dsisr */
334         mr      r3, r27                                   ;
335         lwzu    r4, 4(r28)                                ;
336         bl      outstr                                    ;
337         mr      r3, r27                                   ;
338         mr      r4, r26                                   ;
339         bl      outhex                                    ;
340         /* All done, dump last message and return */
341         mr      r3, r27                                   ;
342         lwzu    r4, 4(r28)                                ;
343         bl      outstr                                    ;
344         mtlr    r19                                       ;
345         blr                                               ;
347 .section .rodata
348 .align 2
349 _BUG_message_0:
350         .string "ERROR: BUG caught...\n"
351 _BUG_message_1:
352         .string " exception"
353 _BUG_message_2:
354         .string "\nnip=0x"
355 _BUG_message_3:
356         .string " msr=0x"
357 _BUG_message_4:
358         .string " dar=0x"
359 _BUG_message_5:
360         .string " dsisr=0x"
361 _BUG_message_6:
362         .string "\nStopping execution\n"
364 _excp_message_0x00:
365         .string "BIOS execution"
366 _excp_message_0x01:
367         .string "Reset"
368 _excp_message_0x02:
369         .string "Machine check"
370 _excp_message_0x03:
371         .string "Data memory access"
372 _excp_message_0x04:
373         .string "Instruction fetch"
374 _excp_message_0x05:
375         .string "External"
376 _excp_message_0x06:
377         .string "Alignment"
378 _excp_message_0x07:
379         .string "Program"
380 _excp_message_0x08:
381         .string "No floating point"
382 _excp_message_0x09:
383         .string "Decrementer"
384 _excp_message_0x0a:
385         .string "Reserved A"
386 _excp_message_0x0b:
387         .string "Reserved B"
388 _excp_message_0x0c:
389         .string "System call"
390 _excp_message_0x0d:
391         .string "Trace"
392 _excp_message_0x0e:
393         .string "Floating point assist"
394 _excp_message_0x0f:
395         .string "Performance monitor"
396 _excp_message_0x10:
397         .string "Instruction TLB miss"
398 _excp_message_0x11:
399         .string "Data TLB miss for store"
400 _excp_message_0x12:
401         .string "Data TLB miss for load"
402 _excp_message_0x13:
403         .string "Instruction address breakpoint"
404 _excp_message_0x14:
405         .string "System management"
406 _excp_message_0x15:
407         .string "Thermal management"
408 _excp_message_0x16:
409         .string "Unknown"
410 _messages_table:
411         .long _BUG_message_0
412         .long _BUG_message_1
413         .long _BUG_message_2
414         .long _BUG_message_3
415         .long _BUG_message_4
416         .long _BUG_message_5
417         .long _BUG_message_6
418 _excp_messages_table:
419         .long _excp_message_0x00
420         .long _excp_message_0x01
421         .long _excp_message_0x02
422         .long _excp_message_0x03
423         .long _excp_message_0x04
424         .long _excp_message_0x05
425         .long _excp_message_0x06
426         .long _excp_message_0x07
427         .long _excp_message_0x08
428         .long _excp_message_0x09
429         .long _excp_message_0x0a
430         .long _excp_message_0x0b
431         .long _excp_message_0x0c
432         .long _excp_message_0x0d
433         .long _excp_message_0x0e
434         .long _excp_message_0x0f
435         .long _excp_message_0x10
436         .long _excp_message_0x11
437         .long _excp_message_0x12
438         .long _excp_message_0x13
439         .long _excp_message_0x14
440         .long _excp_message_0x15
441         .long _excp_message_0x16
442 _last_excp_message:
444 bios_base:
445         .long BIOS_BASE
446 bios_size:
447         .long BIOS_SIZE / 4
448 _dummy_0:
449         .long 0x00000000
451 registers_area: /* To be loaded in register when an exception is caught */
452 _serial_IO:      /* r27 */
453         .long 0x800003F8
454 _messages_start: /* r28 */
455         .long _messages_table - 4
456 _excp_messages:  /* r29 */
457         .long _excp_messages_table
458 _max_excp:       /* r30 */
459         .long (_last_excp_message - _excp_messages_table) / 4
460 _dummy_1:        /* r31: dummy */
461         .long 0x00000000
462         
463 .section .data
464 .align 2
465 save_area: /* Area for r11 save when an exception is skipped */
466         .long 0x00000000