diff options
Diffstat (limited to 'qemu/roms/openhackware/src/vectors.S')
-rw-r--r-- | qemu/roms/openhackware/src/vectors.S | 468 |
1 files changed, 468 insertions, 0 deletions
diff --git a/qemu/roms/openhackware/src/vectors.S b/qemu/roms/openhackware/src/vectors.S new file mode 100644 index 000000000..1c1bfee50 --- /dev/null +++ b/qemu/roms/openhackware/src/vectors.S @@ -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 |