Add qemu 2.4.0
[kvmfornfv.git] / qemu / roms / openhackware / src / vectors.S
diff --git a/qemu/roms/openhackware/src/vectors.S b/qemu/roms/openhackware/src/vectors.S
new file mode 100644 (file)
index 0000000..1c1bfee
--- /dev/null
@@ -0,0 +1,468 @@
+/* 
+ *   <vectors.S>
+ *      
+ *   Second stage boot-loader and exception vectors for Open Hack'Ware.
+ *   
+ *   Copyright (C) 2004-2005 Jocelyn Mayer (l_indien@magic.fr)
+ *   
+ *   This program is free software; you can redistribute it and/or
+ *   modify it under the terms of the GNU General Public License V2
+ *   as published by the Free Software Foundation
+ *
+ *   This program is distributed in the hope that it will be useful,
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *   GNU General Public License for more details.
+ *
+ *   You should have received a copy of the GNU General Public License
+ *   along with this program; if not, write to the Free Software
+ *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+#define ASSEMBLY_CODE
+#include "bios.h"
+
+.section .text
+.align 2
+
+.globl _start
+_start:
+        /* Entry point */
+        li      r0, 0                                     ;
+_turn_off_mmu:
+        /* Be sure MMU is off and we are in 32 bits mode (for PPC64) */
+        lis     r11, _hw_init@h                           ;
+        ori     r11, r11, _hw_init@l                      ;
+        mtspr   26, r11                                   ;
+        mtspr   27, r0                                    ;
+        rfi                                               ;
+_hw_init:
+        /* May need more hw init here */
+_load_bios:
+        /* Load the full BIOS into RAM */
+        lis     r12, bios_base@h                          ;
+        ori     r12, r12, bios_base@l                     ;
+        lmw     r29, 0(r12)                               ;
+        /* Set up the C stack */
+        addis   r1, r29, 0x0040                           ;
+        clrrwi  r1, r1, 19                                ;
+        stw     r1, -16(r1)                               ;
+        stwu    r0, -4(r1)                                ;
+        stwu    r0, -4(r1)                                ;
+        stwu    r0, -4(r1)                                ;
+        stwu    r0, -4(r1)                                ;
+        /* Skip frame pointer */        
+        stwu    r0, -8(r1)                                ;
+        stwu    r0, -4(r1)                                ;
+        stwu    r0, -4(r1)                                ;
+        /* Start copying */
+        mtctr   r30                                       ;
+        subi    r12, r3, 4                                ;
+        subi    r13, r29, 4                               ;
+_bios_copy_loop:
+        lwzu    r14, 4(r12)                               ;
+        stwu    r14, 4(r13)                               ;
+        bdnz    _bios_copy_loop                           ;
+        /* Synchronize the whole execution context */
+        /* Also enable FPU */
+        ori     r0, r0, (1 << 13)                         ;
+        mtspr   26, r29                                   ;
+        mtspr   27, r0                                    ;
+        rfi                                               ;
+        /* If we ever return, stop */
+        bl      bug                                       ;
+
+.org 0x0080
+.section .text
+.align 2
+bug:
+        /* Dump the exception and its context */
+        mflr    r3                                        ;
+        mfspr   r4, SRR0                                  ;
+        mfspr   r5, SRR1                                  ;
+        mfspr   r6, DAR                                   ;
+        mfspr   r7, DSISR                                 ;
+        /* Turn MMU off */
+        lis     r0, _bug_no_mmu@h                         ;
+        ori     r0, r0, _bug_no_mmu@l                     ;
+        mtspr   26, r0                                    ;
+        li      r0, 0                                     ;
+        mtspr   27, r0                                    ;
+        rfi                                               ;
+_bug_no_mmu:
+        bl      dump_exception                            ;
+_forever:
+        /* Loop forever */
+        b       _forever                                  ;
+
+skip_exception:
+        /* Skip external interrupts and decrementer exception */
+        /* BEWARE: be sure not to modify any register */
+        stw     r11, save_area@l(0)                       ;
+        mfspr   r11, 27                                   ;
+        clrlwi  r11, r11, 16                              ;
+        mtspr   27, r11                                   ;
+        lwz     r11, save_area@l(0)                       ;
+        rfi                                               ;
+
+#define EXCP_BUG(entry)                                     \
+.org 0x##entry                                            ; \
+.section .text                                            ; \
+.align 2                                                  ; \
+excp_##entry:                                             ; \
+        bl bug
+
+#define EXCP_SKIP(entry)                                    \
+.org 0x##entry                                            ; \
+.section .text                                            ; \
+.align 2                                                  ; \
+excp_##entry##:                                           ; \
+        b skip_exception
+
+        /* Exception vectors */
+        /* Reset exception */
+.org 0x0100
+excp_0100:
+        ba 0xfffffffc
+
+        /* Machine check exception */
+        EXCP_BUG(0200)                                    ;
+
+        /* DSI exception */
+        EXCP_BUG(0300)                                    ;
+
+        /* ISI exception */
+        EXCP_BUG(0400)                                    ;
+
+        /* External interrupt: skip it */
+        EXCP_SKIP(0500)                                   ;
+
+        /* Alignment exception */
+        EXCP_BUG(0600)                                    ;
+
+        /* Program exception */
+        EXCP_BUG(0700)                                    ;
+
+        /* No floating point exception */
+        EXCP_BUG(0800)                                    ;
+
+        /* Decrementer exception: skip it */
+        EXCP_SKIP(0900)                                   ;
+
+        /* Reserved A exception */
+        EXCP_BUG(0A00)                                    ;
+
+        /* Reserved B exception */
+        EXCP_BUG(0B00)                                    ;
+
+        /* System call exception */
+        EXCP_BUG(0C00)                                    ;
+
+        /* Trace exception */
+        EXCP_BUG(0D00)                                    ;
+
+        /* Floating point assist exception */
+        EXCP_BUG(0E00)                                    ;
+
+        /* Performance monitor exception */
+        EXCP_BUG(0F00)                                    ;
+
+        /* Instruction TLB miss exception */
+        EXCP_BUG(1000)                                    ;
+
+        /* Data TLB miss for store exception */
+        EXCP_BUG(1100)                                    ;
+
+        /* Data TLB miss for load exception */
+        EXCP_BUG(1200)                                    ;
+
+        /* Instruction address breakpoint exception */
+        EXCP_BUG(1300)                                    ;
+
+        /* System management interrupt exception */
+        EXCP_BUG(1400)                                    ;
+
+        /* Thermal management exception */
+        EXCP_BUG(1500)                                    ;
+
+        /* Unknown exceptions */
+        EXCP_BUG(1600)                                    ;
+
+        EXCP_BUG(1700)                                    ;
+
+        EXCP_BUG(1800)                                    ;
+
+        EXCP_BUG(1900)                                    ;
+
+        EXCP_BUG(1A00)                                    ;
+
+        EXCP_BUG(1B00)                                    ;
+
+        EXCP_BUG(1C00)                                    ;
+
+        EXCP_BUG(1D00)                                    ;
+
+        EXCP_BUG(1E00)                                    ;
+
+        EXCP_BUG(1F00)                                    ;
+        /* End of exception vectors list */
+
+.org 0x2000
+.section .text
+.align 2
+helpers_start:
+
+outb:
+        /* void outb (uint32_t port, uint32_t data);
+         * Writes a single character on an IO port.
+         * Used for serial console.
+         */
+        stb     r4, 0(r3)                                 ;
+        eieio                                             ;
+        blr                                               ;
+
+outstr:
+        /* void outstr (uint32_t port, const unsigned char *str);
+         * Writes a string on an IO port.
+         */
+        mflr    r20                                       ;
+        subi    r11, r4, 1                                ;
+        
+_outstr_next:
+        lbzu    r4, 1(r11)                                ;
+        cmpi    0, r4, 0                                  ;
+        beq     _outstr_done                              ;
+        bl      outb                                      ;
+        b       _outstr_next                              ;
+_outstr_done:
+        mtlr    r20                                       ;
+        blr                                               ;
+
+outdigit:
+        /* void outdigit (uint32_t port, uint32_t digit);
+         * Dumps a single digit on serial port.
+         */
+        mflr    r20                                       ;
+        addi    r4, r4, '0'                               ;
+        bl      outb                                      ;
+        mtlr    r20                                       ;
+        blr                                               ;
+
+outhex:
+        /* void outhex (uint32_t port, uint32_t value);
+         * Dumps a 32 bits hex number on serial port
+         */
+        mflr    r21
+        li      r11, 8                                    ;
+        mtctr   r11                                       ;
+        mr      r11, r4                                   ;
+_outhex_next:
+        rlwinm  r11, r11, 4, 0, 31                        ;
+        clrlwi  r4, r11, 28                               ;
+        cmpi    0, r4, 9                                  ;
+        bgt     _outhex_xdigit                            ;
+        bl      outdigit                                  ;
+        bdnz    _outhex_next                              ;
+        b       _outhex_done                              ;
+_outhex_xdigit:
+        addi    r4, r4, 'a' - 10                          ;
+        bl      outb                                      ;
+        bdnz    _outhex_next                              ;
+_outhex_done:
+        mtlr    r21                                       ;
+        blr                                               ;
+
+        /* void dump_exception (uint32_t lr, uint32_t srr0, uint32_t srr1,
+         *                      uint32_t dar, uint32_t dsisr);
+         * Dump a message when catching an exception
+         */
+dump_exception:
+        /* Save call parameters */
+        mflr    r19                                       ;
+        mr      r22, r3                                   ;
+        mr      r23, r4                                   ;
+        mr      r24, r5                                   ;
+        mr      r25, r6                                   ;
+        mr      r26, r7                                   ;
+        lis     r11, registers_area@h                     ;
+        ori     r11, r11, registers_area@l                ;
+        lmw     r27, 0(r11)                               ;
+        /* Now, serial IO port is in r27,
+         * message table start is in r28,
+         * first exception message offset is in r29,
+         * and last known exception number is in r30
+         */
+        /* Print error prompt message */
+        mr      r3, r27                                   ;
+        lwzu    r4, 4(r28)                                ;
+        bl      outstr                                    ;
+        /* Find message corresponding to the caught exception */
+        srwi    r12, r22, 8                               ;
+        cmp     0, r12, r30                               ;
+        ble     _dump_excp_msg                            ;
+        subi    r12, r30, 1                               ;
+_dump_excp_msg:
+        rlwinm  r12, r12, 2, 0, 31                        ;
+        /* Dump execption message */
+        mr      r3, r27                                   ;
+        lwzx    r4, r12, r29                              ;
+        bl      outstr                                    ;
+        /* Complete exception message */
+        mr      r3, r27                                   ;
+        lwzu    r4, 4(r28)                                ;
+        bl      outstr                                    ;
+        /* Dump nip */
+        mr      r3, r27                                   ;
+        lwzu    r4, 4(r28)                                ;
+        bl      outstr                                    ;
+        mr      r3, r27                                   ;
+        mr      r4, r23                                   ;
+        bl      outhex                                    ;
+        /* dump msr */
+        mr      r3, r27                                   ;
+        lwzu    r4, 4(r28)                                ;
+        bl      outstr                                    ;
+        mr      r3, r27                                   ;
+        mr      r4, r24                                   ;
+        bl      outhex                                    ;
+        /* dump dar */
+        mr      r3, r27                                   ;
+        lwzu    r4, 4(r28)                                ;
+        bl      outstr                                    ;
+        mr      r3, r27                                   ;
+        mr      r4, r25                                   ;
+        bl      outhex                                    ;
+        /* dump dsisr */
+        mr      r3, r27                                   ;
+        lwzu    r4, 4(r28)                                ;
+        bl      outstr                                    ;
+        mr      r3, r27                                   ;
+        mr      r4, r26                                   ;
+        bl      outhex                                    ;
+        /* All done, dump last message and return */
+        mr      r3, r27                                   ;
+        lwzu    r4, 4(r28)                                ;
+        bl      outstr                                    ;
+        mtlr    r19                                       ;
+        blr                                               ;
+
+.section .rodata
+.align 2
+_BUG_message_0:
+        .string "ERROR: BUG caught...\n"
+_BUG_message_1:
+        .string " exception"
+_BUG_message_2:
+        .string "\nnip=0x"
+_BUG_message_3:
+        .string " msr=0x"
+_BUG_message_4:
+        .string " dar=0x"
+_BUG_message_5:
+        .string " dsisr=0x"
+_BUG_message_6:
+        .string "\nStopping execution\n"
+
+_excp_message_0x00:
+        .string "BIOS execution"
+_excp_message_0x01:
+        .string "Reset"
+_excp_message_0x02:
+        .string "Machine check"
+_excp_message_0x03:
+        .string "Data memory access"
+_excp_message_0x04:
+        .string "Instruction fetch"
+_excp_message_0x05:
+        .string "External"
+_excp_message_0x06:
+        .string "Alignment"
+_excp_message_0x07:
+        .string "Program"
+_excp_message_0x08:
+        .string "No floating point"
+_excp_message_0x09:
+        .string "Decrementer"
+_excp_message_0x0a:
+        .string "Reserved A"
+_excp_message_0x0b:
+        .string "Reserved B"
+_excp_message_0x0c:
+        .string "System call"
+_excp_message_0x0d:
+        .string "Trace"
+_excp_message_0x0e:
+        .string "Floating point assist"
+_excp_message_0x0f:
+        .string "Performance monitor"
+_excp_message_0x10:
+        .string "Instruction TLB miss"
+_excp_message_0x11:
+        .string "Data TLB miss for store"
+_excp_message_0x12:
+        .string "Data TLB miss for load"
+_excp_message_0x13:
+        .string "Instruction address breakpoint"
+_excp_message_0x14:
+        .string "System management"
+_excp_message_0x15:
+        .string "Thermal management"
+_excp_message_0x16:
+        .string "Unknown"
+_messages_table:
+        .long _BUG_message_0
+        .long _BUG_message_1
+        .long _BUG_message_2
+        .long _BUG_message_3
+        .long _BUG_message_4
+        .long _BUG_message_5
+        .long _BUG_message_6
+_excp_messages_table:
+        .long _excp_message_0x00
+        .long _excp_message_0x01
+        .long _excp_message_0x02
+        .long _excp_message_0x03
+        .long _excp_message_0x04
+        .long _excp_message_0x05
+        .long _excp_message_0x06
+        .long _excp_message_0x07
+        .long _excp_message_0x08
+        .long _excp_message_0x09
+        .long _excp_message_0x0a
+        .long _excp_message_0x0b
+        .long _excp_message_0x0c
+        .long _excp_message_0x0d
+        .long _excp_message_0x0e
+        .long _excp_message_0x0f
+        .long _excp_message_0x10
+        .long _excp_message_0x11
+        .long _excp_message_0x12
+        .long _excp_message_0x13
+        .long _excp_message_0x14
+        .long _excp_message_0x15
+        .long _excp_message_0x16
+_last_excp_message:
+
+bios_base:
+        .long BIOS_BASE
+bios_size:
+        .long BIOS_SIZE / 4
+_dummy_0:
+        .long 0x00000000
+
+registers_area: /* To be loaded in register when an exception is caught */
+_serial_IO:      /* r27 */
+        .long 0x800003F8
+_messages_start: /* r28 */
+        .long _messages_table - 4
+_excp_messages:  /* r29 */
+        .long _excp_messages_table
+_max_excp:       /* r30 */
+        .long (_last_excp_message - _excp_messages_table) / 4
+_dummy_1:        /* r31: dummy */
+        .long 0x00000000
+        
+.section .data
+.align 2
+save_area: /* Area for r11 save when an exception is skipped */
+        .long 0x00000000