X-Git-Url: https://gerrit.opnfv.org/gerrit/gitweb?a=blobdiff_plain;f=qemu%2Froms%2Fopenbios%2Farch%2Fppc%2Fqemu%2Fstart.S;fp=qemu%2Froms%2Fopenbios%2Farch%2Fppc%2Fqemu%2Fstart.S;h=ae2fd53dc8d852e9c2422d2410bc21f4336c1187;hb=e44e3482bdb4d0ebde2d8b41830ac2cdb07948fb;hp=0000000000000000000000000000000000000000;hpb=9ca8dbcc65cfc63d6f5ef3312a33184e1d726e00;p=kvmfornfv.git diff --git a/qemu/roms/openbios/arch/ppc/qemu/start.S b/qemu/roms/openbios/arch/ppc/qemu/start.S new file mode 100644 index 000000000..ae2fd53dc --- /dev/null +++ b/qemu/roms/openbios/arch/ppc/qemu/start.S @@ -0,0 +1,729 @@ +/* + * Creation Date: <2001/06/16 21:30:18 samuel> + * Time-stamp: <2003/04/04 16:32:06 samuel> + * + * + * + * Asm glue for ELF images + * + * Copyright (C) 2001, 2002, 2003 Samuel Rydh (samuel@ibrium.se) + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation + * + */ + +#include "autoconf.h" +#include "asm/asmdefs.h" +#include "asm/processor.h" + +/************************************************************************/ +/* Macros */ +/************************************************************************/ + +#define ILLEGAL_VECTOR( v ) .org __vectors + v ; vector__##v: bl trap_error ; +#define VECTOR( v, dummystr ) .org __vectors + v ; vector__##v + +#ifdef CONFIG_PPC_64BITSUPPORT + +/* We're trying to use the same code for the ppc32 and ppc64 handlers here. + * On ppc32 we only save/restore the registers, C considers volatile. + * + * On ppc64 on the other hand, we have to save/restore all registers, because + * all OF code is 32 bits, which only saves/restores the low 32 bits of the + * registers it clobbers. + */ + +#define EXCEPTION_PREAMBLE_TEMPLATE \ + mtsprg1 r1 ; /* scratch */ \ + mfcr r1 ; \ + mtsprg2 r1 ; /* scratch */ \ + lis r1, 0x8000 ; /* r1=0x80000000 */ \ + add. r1,r1,r1 ; /* r1=r1+r1 (high 32bit !0) */ \ + beq 1f; \ + \ + mfmsr r1 ; /* unset MSR_SF */ \ + clrldi r1,r1,1 ; \ + mtmsrd r1 ; \ +1: \ + mfsprg0 r1 ; /* exception stack in sprg0 */ \ +.ifc ULONG_SIZE, 8 ; \ + addi r1,r1,-(40 * ULONG_SIZE) ; /* push exception frame */ \ +.else ; \ + addi r1,r1,-(20 * ULONG_SIZE) ; /* push exception frame */ \ +.endif ; \ + \ + stl r0,(0 * ULONG_SIZE)(r1) ; /* save r0 */ \ + mfsprg1 r0 ; \ + stl r0,(1 * ULONG_SIZE)(r1) ; /* save r1 */ \ + stl r2,(2 * ULONG_SIZE)(r1) ; /* save r2 */ \ + stl r3,(3 * ULONG_SIZE)(r1) ; /* save r3 */ \ + stl r4,(4 * ULONG_SIZE)(r1) ; \ + stl r5,(5 * ULONG_SIZE)(r1) ; \ + stl r6,(6 * ULONG_SIZE)(r1) ; \ + stl r7,(7 * ULONG_SIZE)(r1) ; \ + stl r8,(8 * ULONG_SIZE)(r1) ; \ + stl r9,(9 * ULONG_SIZE)(r1) ; \ + stl r10,(10 * ULONG_SIZE)(r1) ; \ + stl r11,(11 * ULONG_SIZE)(r1) ; \ + stl r12,(12 * ULONG_SIZE)(r1) ; \ +.ifc ULONG_SIZE, 8 ; \ + stl r13,(17 * ULONG_SIZE)(r1) ; \ + stl r14,(18 * ULONG_SIZE)(r1) ; \ + stl r15,(19 * ULONG_SIZE)(r1) ; \ + stl r16,(20 * ULONG_SIZE)(r1) ; \ + stl r17,(21 * ULONG_SIZE)(r1) ; \ + stl r18,(22 * ULONG_SIZE)(r1) ; \ + stl r19,(23 * ULONG_SIZE)(r1) ; \ + stl r20,(24 * ULONG_SIZE)(r1) ; \ + stl r21,(25 * ULONG_SIZE)(r1) ; \ + stl r22,(26 * ULONG_SIZE)(r1) ; \ + stl r23,(27 * ULONG_SIZE)(r1) ; \ + stl r24,(28 * ULONG_SIZE)(r1) ; \ + stl r25,(29 * ULONG_SIZE)(r1) ; \ + stl r26,(30 * ULONG_SIZE)(r1) ; \ + stl r27,(31 * ULONG_SIZE)(r1) ; \ + stl r28,(32 * ULONG_SIZE)(r1) ; \ + stl r29,(33 * ULONG_SIZE)(r1) ; \ + stl r30,(34 * ULONG_SIZE)(r1) ; \ + stl r31,(35 * ULONG_SIZE)(r1) ; \ +.endif ; \ + \ + mflr r0 ; \ + stl r0,(13 * ULONG_SIZE)(r1) ; \ + mfsprg2 r0 ; \ + stl r0,(14 * ULONG_SIZE)(r1) ; \ + mfctr r0 ; \ + stl r0,(15 * ULONG_SIZE)(r1) ; \ + mfxer r0 ; \ + stl r0,(16 * ULONG_SIZE)(r1) ; \ + \ + /* 76(r1) unused */ \ + addi r1,r1,-16 ; /* C ABI uses 0(r1) and 4(r1)... */ + +#define EXCEPTION_EPILOGUE_TEMPLATE \ + addi r1,r1,16 ; /* pop ABI frame */ \ +\ + ll r0,(13 * ULONG_SIZE)(r1) ; \ + mtlr r0 ; \ + ll r0,(14 * ULONG_SIZE)(r1) ; \ + mtcr r0 ; \ + ll r0,(15 * ULONG_SIZE)(r1) ; \ + mtctr r0 ; \ + ll r0,(16 * ULONG_SIZE)(r1) ; \ + mtxer r0 ; \ +\ + ll r0,(0 * ULONG_SIZE)(r1) ; \ + ll r2,(2 * ULONG_SIZE)(r1) ; \ + ll r3,(3 * ULONG_SIZE)(r1) ; \ + ll r4,(4 * ULONG_SIZE)(r1) ; \ + ll r5,(5 * ULONG_SIZE)(r1) ; \ + ll r6,(6 * ULONG_SIZE)(r1) ; \ + ll r7,(7 * ULONG_SIZE)(r1) ; \ + ll r8,(8 * ULONG_SIZE)(r1) ; \ + ll r9,(9 * ULONG_SIZE)(r1) ; \ + ll r10,(10 * ULONG_SIZE)(r1) ; \ + ll r11,(11 * ULONG_SIZE)(r1) ; \ + ll r12,(12 * ULONG_SIZE)(r1) ; \ +.ifc ULONG_SIZE, 8 ; \ + ll r13,(17 * ULONG_SIZE)(r1) ; \ + ll r14,(18 * ULONG_SIZE)(r1) ; \ + ll r15,(19 * ULONG_SIZE)(r1) ; \ + ll r16,(20 * ULONG_SIZE)(r1) ; \ + ll r17,(21 * ULONG_SIZE)(r1) ; \ + ll r18,(22 * ULONG_SIZE)(r1) ; \ + ll r19,(23 * ULONG_SIZE)(r1) ; \ + ll r20,(24 * ULONG_SIZE)(r1) ; \ + ll r21,(25 * ULONG_SIZE)(r1) ; \ + ll r22,(26 * ULONG_SIZE)(r1) ; \ + ll r23,(27 * ULONG_SIZE)(r1) ; \ + ll r24,(28 * ULONG_SIZE)(r1) ; \ + ll r25,(29 * ULONG_SIZE)(r1) ; \ + ll r26,(30 * ULONG_SIZE)(r1) ; \ + ll r27,(31 * ULONG_SIZE)(r1) ; \ + ll r28,(32 * ULONG_SIZE)(r1) ; \ + ll r29,(33 * ULONG_SIZE)(r1) ; \ + ll r30,(34 * ULONG_SIZE)(r1) ; \ + ll r31,(35 * ULONG_SIZE)(r1) ; \ +.endif ; \ + ll r1,(1 * ULONG_SIZE)(r1) ; /* restore stack at last */ \ + rfi + +// PPC32 + +#define ULONG_SIZE 4 +#define stl stw +#define ll lwz + +.macro EXCEPTION_PREAMBLE + EXCEPTION_PREAMBLE_TEMPLATE +.endm + +.macro EXCEPTION_EPILOGUE + EXCEPTION_EPILOGUE_TEMPLATE +.endm + +#undef ULONG_SIZE +#undef stl +#undef ll + +// PPC64 + +#define ULONG_SIZE 8 +#define stl std +#define ll ld + +.macro EXCEPTION_PREAMBLE_64 + EXCEPTION_PREAMBLE_TEMPLATE +.endm + +.macro EXCEPTION_EPILOGUE_64 + EXCEPTION_EPILOGUE_TEMPLATE +.endm + +#undef ULONG_SIZE +#undef stl +#undef ll + +#define ULONG_SIZE 4 +#define STACKFRAME_MINSIZE 16 + +#else /* !CONFIG_PPC_64BITSUPPORT */ + +#ifdef __powerpc64__ + +#define ULONG_SIZE 8 +#define STACKFRAME_MINSIZE 48 +#define stl std +#define ll ld + +#else + +#define ULONG_SIZE 4 +#define STACKFRAME_MINSIZE 16 +#define stl stw +#define ll lwz + +#endif + +.macro EXCEPTION_PREAMBLE + mtsprg1 r1 /* scratch */ + mfsprg0 r1 /* exception stack in sprg0 */ + addi r1, r1, -(20 * ULONG_SIZE) /* push exception frame */ + + stl r0, ( 0 * ULONG_SIZE)(r1) /* save r0 */ + mfsprg1 r0 + stl r0, ( 1 * ULONG_SIZE)(r1) /* save r1 */ + stl r2, ( 2 * ULONG_SIZE)(r1) /* save r2 */ + stl r3, ( 3 * ULONG_SIZE)(r1) /* save r3 */ + stl r4, ( 4 * ULONG_SIZE)(r1) + stl r5, ( 5 * ULONG_SIZE)(r1) + stl r6, ( 6 * ULONG_SIZE)(r1) + stl r7, ( 7 * ULONG_SIZE)(r1) + stl r8, ( 8 * ULONG_SIZE)(r1) + stl r9, ( 9 * ULONG_SIZE)(r1) + stl r10, (10 * ULONG_SIZE)(r1) + stl r11, (11 * ULONG_SIZE)(r1) + stl r12, (12 * ULONG_SIZE)(r1) + + mflr r0 + stl r0, (13 * ULONG_SIZE)(r1) + mfcr r0 + stl r0, (14 * ULONG_SIZE)(r1) + mfctr r0 + stl r0, (15 * ULONG_SIZE)(r1) + mfxer r0 + stl r0, (16 * ULONG_SIZE)(r1) + + addi r1, r1, -STACKFRAME_MINSIZE /* C ABI saves LR and SP */ +.endm + +.macro EXCEPTION_EPILOGUE + addi r1, r1, STACKFRAME_MINSIZE /* pop ABI frame */ + + ll r0, (13 * ULONG_SIZE)(r1) + mtlr r0 + ll r0, (14 * ULONG_SIZE)(r1) + mtcr r0 + ll r0, (15 * ULONG_SIZE)(r1) + mtctr r0 + ll r0, (16 * ULONG_SIZE)(r1) + mtxer r0 + + ll r0, ( 0 * ULONG_SIZE)(r1) + ll r2, ( 2 * ULONG_SIZE)(r1) + ll r3, ( 3 * ULONG_SIZE)(r1) + ll r4, ( 4 * ULONG_SIZE)(r1) + ll r5, ( 5 * ULONG_SIZE)(r1) + ll r6, ( 6 * ULONG_SIZE)(r1) + ll r7, ( 7 * ULONG_SIZE)(r1) + ll r8, ( 8 * ULONG_SIZE)(r1) + ll r9, ( 9 * ULONG_SIZE)(r1) + ll r10, (10 * ULONG_SIZE)(r1) + ll r11, (11 * ULONG_SIZE)(r1) + ll r12, (12 * ULONG_SIZE)(r1) + + ll r1, ( 1 * ULONG_SIZE)(r1) /* restore stack at last */ + RFI +.endm + +#endif /* !CONFIG_PPC_64BITSUPPORT */ + +/************************************************************************/ +/* vectors */ +/************************************************************************/ + + .section .text.vectors, "ax" +GLOBL(__vectors): + nop // NULL-jmp trap +1: nop // + b 1b + +VECTOR( 0x100, "SRE" ): + b _entry + +trap_error: + lis r1, 0x8000 /* r1=0x80000000 */ + add. r1,r1,r1 /* r1=r1+r1 (high 32bit !0) */ + beq 1f + + mfmsr r1 /* unset MSR_SF */ + clrldi r1,r1,1 + mtmsrd r1 +1: + mflr r3 + LOAD_REG_FUNC(r4, unexpected_excep) + mtctr r4 + bctr + +ILLEGAL_VECTOR( 0x200 ) + +VECTOR( 0x300, "DSI" ): + b real_dsi + +ILLEGAL_VECTOR( 0x380 ) + +VECTOR( 0x400, "ISI" ): + b real_isi + +ILLEGAL_VECTOR( 0x480 ) + + ILLEGAL_VECTOR( 0x500 ) + ILLEGAL_VECTOR( 0x600 ) + ILLEGAL_VECTOR( 0x700 ) + +VECTOR( 0x800, "FPU" ): + mtsprg1 r3 + mfsrr1 r3 + ori r3,r3,0x2000 + mtsrr1 r3 + mfsprg1 r3 + RFI + +ILLEGAL_VECTOR( 0x900 ) +ILLEGAL_VECTOR( 0xa00 ) +ILLEGAL_VECTOR( 0xb00 ) +ILLEGAL_VECTOR( 0xc00 ) +ILLEGAL_VECTOR( 0xd00 ) +ILLEGAL_VECTOR( 0xe00 ) +ILLEGAL_VECTOR( 0xf00 ) +ILLEGAL_VECTOR( 0xf20 ) +ILLEGAL_VECTOR( 0x1000 ) +ILLEGAL_VECTOR( 0x1100 ) +ILLEGAL_VECTOR( 0x1200 ) +ILLEGAL_VECTOR( 0x1300 ) +ILLEGAL_VECTOR( 0x1400 ) +ILLEGAL_VECTOR( 0x1500 ) +ILLEGAL_VECTOR( 0x1600 ) +ILLEGAL_VECTOR( 0x1700 ) + +#ifdef CONFIG_PPC_64BITSUPPORT + +VECTOR( 0x2000, "DSI_64" ): + EXCEPTION_PREAMBLE_64 + LOAD_REG_IMMEDIATE(r3, dsi_exception) + mtctr r3 + bctrl + EXCEPTION_EPILOGUE_64 + +VECTOR( 0x2200, "ISI_64" ): + EXCEPTION_PREAMBLE_64 + LOAD_REG_IMMEDIATE(r3, isi_exception) + mtctr r3 + bctrl + EXCEPTION_EPILOGUE_64 + +#endif + +real_dsi: + EXCEPTION_PREAMBLE + LOAD_REG_FUNC(r3, dsi_exception) + mtctr r3 + bctrl + b exception_return + +real_isi: + EXCEPTION_PREAMBLE + LOAD_REG_FUNC(r3, isi_exception) + mtctr r3 + bctrl + b exception_return + +exception_return: + EXCEPTION_EPILOGUE + +GLOBL(__vectors_end): + +/************************************************************************/ +/* entry */ +/************************************************************************/ + +GLOBL(_entry): + +#ifdef CONFIG_PPC_64BITSUPPORT + li r0,0 + + lis r3, 0x8000 /* r1=0x80000000 */ + add. r3,r3,r3 /* r1=r1+r1 (high 32bit !0) */ + beq no_64bit /* only true when !MSR_SF */ + + /* clear MSR, disable MMU, SF */ + mtmsrd r0 + b real_entry + +no_64bit: + /* clear MSR, disable MMU */ + mtmsr r0 + +real_entry: +#endif + + /* copy exception vectors */ + + LOAD_REG_IMMEDIATE(r3, __vectors) + li r4,0 + li r5,__vectors_end - __vectors + 16 + rlwinm r5,r5,0,0,28 +1: lwz r6,0(r3) + lwz r7,4(r3) + lwz r8,8(r3) + lwz r9,12(r3) + stw r6,0(r4) + stw r7,4(r4) + stw r8,8(r4) + stw r9,12(r4) + dcbst 0,r4 + sync + icbi 0,r4 + sync + addi r5,r5,-16 + addi r3,r3,16 + addi r4,r4,16 + cmpwi r5,0 + bgt 1b + isync + + bl compute_ramsize + + /* Memory map: + * + * Top +-------------------------+ + * | | + * | ROM into RAM (1 MB) | + * | | + * +-------------------------+ + * | | + * | MMU Hash Table (64 kB) | + * | | + * +-------------------------+ + * | | + * | Exception Stack (32 kB) | + * | | + * +-------------------------+ + * | | + * | Stack (64 kB) | + * | | + * +-------------------------+ + * | | + * | Client Stack (64 kB) | + * | | + * +-------------------------+ + * | | + * | Malloc Zone (2 MiB) | + * | | + * +-------------------------+ + * : : + * Bottom + */ + + addis r1, r3, -16 /* ramsize - 1MB */ + + /* setup hash table */ + + addis r1, r1, -1 /* - 64 kB */ + clrrwi r1, r1, 5*4 /* & ~0xfffff */ + + /* setup exception stack */ + + mtsprg0 r1 + + /* setup stack */ + + addi r1, r1, -32768 /* - 32 kB */ + + /* save memory size in stack */ + +#ifdef __powerpc64__ + /* set up TOC pointer */ + + LOAD_REG_IMMEDIATE(r2, setup_mmu) + ld r2, 8(r2) +#endif + + bl BRANCH_LABEL(setup_mmu) + bl BRANCH_LABEL(entry) +1: nop + b 1b + + + /* According to IEEE 1275, PPC bindings: + * + * MSR = FP, ME + (DR|IR) + * r1 = stack (32 K + 32 bytes link area above) + * r5 = client interface handler + * r6 = address of client program arguments (unused) + * r7 = length of client program arguments (unused) + * + * Yaboot and Linux use r3 and r4 for initrd address and size + */ + .data +saved_stack: + DATA_LONG(0) + .previous + /* void call_elf( arg1, arg2, entry ) */ +_GLOBAL(call_elf): + mflr r0 + PPC_STLU r1, -STACKFRAME_MINSIZE(r1) + PPC_STL r0, (STACKFRAME_MINSIZE + PPC_LR_STKOFF)(r1) + mtlr r5 + LOAD_REG_IMMEDIATE(r8, saved_stack) // save our stack pointer + PPC_STL r1,0(r8) + mfsdr1 r1 + addi r1, r1, -32768 /* - 32 KiB exception stack */ + addis r1, r1, -1 /* - 64 KiB stack */ + LOAD_REG_IMMEDIATE(r5, of_client_callback) // r5 = callback + li r6,0 // r6 = address of client program arguments (unused) + li r7,0 // r7 = length of client program arguments (unused) + li r0,MSR_FP | MSR_ME | MSR_DR | MSR_IR + MTMSRD(r0) + blrl + +#ifdef CONFIG_PPC64 + /* Restore SF bit */ + LOAD_REG_IMMEDIATE(r0, MSR_SF | MSR_FP | MSR_ME | MSR_DR | MSR_IR) + MTMSRD(r0) +#endif + LOAD_REG_IMMEDIATE(r8, saved_stack) // restore stack pointer + mr r1,r8 + PPC_LL r0, (STACKFRAME_MINSIZE + PPC_LR_STKOFF)(r1) + mtlr r0 + addi r1, r1, STACKFRAME_MINSIZE + // XXX: should restore r12-r31 etc.. + // we should not really come here though + blr + +#ifdef __powerpc64__ +#define STKOFF STACKFRAME_MINSIZE +#define SAVE_SPACE 320 +#else +#define STKOFF 8 +#define SAVE_SPACE 144 +#endif +GLOBL(of_client_callback): + +#ifdef CONFIG_PPC64 + PPC_STLU r1, -(STACKFRAME_MINSIZE + 16)(r1) +#else + PPC_STLU r1, -STACKFRAME_MINSIZE(r1) /* fits within alignment */ +#endif + + /* save r4 */ + + PPC_STL r4, STKOFF(r1) + + /* save lr */ + + mflr r4 + PPC_STL r4, PPC_LR_STKOFF(r1) + + /* restore OF stack */ + + LOAD_REG_IMMEDIATE(r4, saved_stack) + PPC_LL r4, 0(r4) + + PPC_STLU r4,-SAVE_SPACE(r4) + PPC_STL r1,(STKOFF)(r4) // save caller stack + mr r1,r4 + + PPC_STL r2, (STKOFF + 1 * ULONG_SIZE)(r1) + PPC_STL r0, (STKOFF + 2 * ULONG_SIZE)(r1) + + /* save ctr, cr and xer */ + + mfctr r2 + PPC_STL r2, (STKOFF + 3 * ULONG_SIZE)(r1) + mfcr r2 + PPC_STL r2, (STKOFF + 4 * ULONG_SIZE)(r1) + mfxer r2 + PPC_STL r2, (STKOFF + 5 * ULONG_SIZE)(r1) + + /* save r5 - r31 */ + + PPC_STL r5, (STKOFF + 6 * ULONG_SIZE)(r1) + PPC_STL r6, (STKOFF + 7 * ULONG_SIZE)(r1) + PPC_STL r7, (STKOFF + 8 * ULONG_SIZE)(r1) + PPC_STL r8, (STKOFF + 9 * ULONG_SIZE)(r1) + PPC_STL r9, (STKOFF + 10 * ULONG_SIZE)(r1) + PPC_STL r10, (STKOFF + 11 * ULONG_SIZE)(r1) + PPC_STL r11, (STKOFF + 12 * ULONG_SIZE)(r1) + PPC_STL r12, (STKOFF + 13 * ULONG_SIZE)(r1) + PPC_STL r13, (STKOFF + 14 * ULONG_SIZE)(r1) + PPC_STL r14, (STKOFF + 15 * ULONG_SIZE)(r1) + PPC_STL r15, (STKOFF + 16 * ULONG_SIZE)(r1) + PPC_STL r16, (STKOFF + 17 * ULONG_SIZE)(r1) + PPC_STL r17, (STKOFF + 18 * ULONG_SIZE)(r1) + PPC_STL r18, (STKOFF + 19 * ULONG_SIZE)(r1) + PPC_STL r19, (STKOFF + 20 * ULONG_SIZE)(r1) + PPC_STL r20, (STKOFF + 21 * ULONG_SIZE)(r1) + PPC_STL r21, (STKOFF + 22 * ULONG_SIZE)(r1) + PPC_STL r22, (STKOFF + 23 * ULONG_SIZE)(r1) + PPC_STL r23, (STKOFF + 24 * ULONG_SIZE)(r1) + PPC_STL r24, (STKOFF + 25 * ULONG_SIZE)(r1) + PPC_STL r25, (STKOFF + 26 * ULONG_SIZE)(r1) + PPC_STL r26, (STKOFF + 27 * ULONG_SIZE)(r1) + PPC_STL r27, (STKOFF + 28 * ULONG_SIZE)(r1) + PPC_STL r28, (STKOFF + 29 * ULONG_SIZE)(r1) + PPC_STL r29, (STKOFF + 30 * ULONG_SIZE)(r1) + PPC_STL r30, (STKOFF + 31 * ULONG_SIZE)(r1) + PPC_STL r31, (STKOFF + 32 * ULONG_SIZE)(r1) + +#ifdef CONFIG_PPC64 + LOAD_REG_IMMEDIATE(r2, of_client_interface) + ld r2, 8(r2) +#endif + bl BRANCH_LABEL(of_client_interface) + + /* restore r5 - r31 */ + + PPC_LL r5, (STKOFF + 6 * ULONG_SIZE)(r1) + PPC_LL r6, (STKOFF + 7 * ULONG_SIZE)(r1) + PPC_LL r7, (STKOFF + 8 * ULONG_SIZE)(r1) + PPC_LL r8, (STKOFF + 9 * ULONG_SIZE)(r1) + PPC_LL r9, (STKOFF + 10 * ULONG_SIZE)(r1) + PPC_LL r10, (STKOFF + 11 * ULONG_SIZE)(r1) + PPC_LL r11, (STKOFF + 12 * ULONG_SIZE)(r1) + PPC_LL r12, (STKOFF + 13 * ULONG_SIZE)(r1) + PPC_LL r13, (STKOFF + 14 * ULONG_SIZE)(r1) + PPC_LL r14, (STKOFF + 15 * ULONG_SIZE)(r1) + PPC_LL r15, (STKOFF + 16 * ULONG_SIZE)(r1) + PPC_LL r16, (STKOFF + 17 * ULONG_SIZE)(r1) + PPC_LL r17, (STKOFF + 18 * ULONG_SIZE)(r1) + PPC_LL r18, (STKOFF + 19 * ULONG_SIZE)(r1) + PPC_LL r19, (STKOFF + 20 * ULONG_SIZE)(r1) + PPC_LL r20, (STKOFF + 21 * ULONG_SIZE)(r1) + PPC_LL r21, (STKOFF + 22 * ULONG_SIZE)(r1) + PPC_LL r22, (STKOFF + 23 * ULONG_SIZE)(r1) + PPC_LL r23, (STKOFF + 24 * ULONG_SIZE)(r1) + PPC_LL r24, (STKOFF + 25 * ULONG_SIZE)(r1) + PPC_LL r25, (STKOFF + 26 * ULONG_SIZE)(r1) + PPC_LL r26, (STKOFF + 27 * ULONG_SIZE)(r1) + PPC_LL r27, (STKOFF + 28 * ULONG_SIZE)(r1) + PPC_LL r28, (STKOFF + 29 * ULONG_SIZE)(r1) + PPC_LL r29, (STKOFF + 30 * ULONG_SIZE)(r1) + PPC_LL r30, (STKOFF + 31 * ULONG_SIZE)(r1) + PPC_LL r31, (STKOFF + 32 * ULONG_SIZE)(r1) + + /* restore ctr, cr and xer */ + + PPC_LL r2, (STKOFF + 3 * ULONG_SIZE)(r1) + mtctr r2 + PPC_LL r2, (STKOFF + 4 * ULONG_SIZE)(r1) + mtcr r2 + PPC_LL r2, (STKOFF + 5 * ULONG_SIZE)(r1) + mtxer r2 + + /* restore r0 and r2 */ + + PPC_LL r2, (STKOFF + 1 * ULONG_SIZE)(r1) + PPC_LL r0, (STKOFF + 2 * ULONG_SIZE)(r1) + + /* restore caller stack */ + + PPC_LL r1, (STKOFF)(r1) + + PPC_LL r4, PPC_LR_STKOFF(r1) + mtlr r4 + PPC_LL r4, STKOFF(r1) + PPC_LL r1, 0(r1) + + blr + + /* rtas glue (must be reloctable) */ +GLOBL(of_rtas_start): + /* r3 = argument buffer, r4 = of_rtas_start */ + /* according to the CHRP standard, cr must be preserved (cr0/cr1 too?) */ + blr +GLOBL(of_rtas_end): + + +#define CACHE_LINE_SIZE 32 +#define LG_CACHE_LINE_SIZE 5 + +/* flush_icache_range( unsigned long start, unsigned long stop) */ +_GLOBAL(flush_icache_range): + li r5,CACHE_LINE_SIZE-1 + andc r3,r3,r5 + subf r4,r3,r4 + add r4,r4,r5 + srwi. r4,r4,LG_CACHE_LINE_SIZE + beqlr + mtctr r4 + mr r6,r3 +1: dcbst 0,r3 + addi r3,r3,CACHE_LINE_SIZE + bdnz 1b + sync /* wait for dcbst's to get to ram */ + mtctr r4 +2: icbi 0,r6 + addi r6,r6,CACHE_LINE_SIZE + bdnz 2b + sync /* additional sync needed on g4 */ + isync + blr + + /* Get RAM size from QEMU configuration device */ + +#define CFG_ADDR 0xf0000510 +#define FW_CFG_RAM_SIZE 0x03 + +compute_ramsize: + LOAD_REG_IMMEDIATE(r9, CFG_ADDR) + li r0,FW_CFG_RAM_SIZE + sth r0,0(r9) + LOAD_REG_IMMEDIATE(r9, CFG_ADDR + 2) + lbz r1,0(r9) + lbz r0,0(r9) + slwi r0,r0,8 + or r1,r1,r0 + lbz r0,0(r9) + slwi r0,r0,16 + or r1,r1,r0 + lbz r0,0(r9) + slwi r0,r0,24 + or r3,r1,r0 + blr + + /* Hard reset vector */ + .section .romentry,"ax" + bl _entry