diff options
author | 2015-08-28 09:58:54 +0800 | |
---|---|---|
committer | 2015-09-01 12:44:00 +0800 | |
commit | e44e3482bdb4d0ebde2d8b41830ac2cdb07948fb (patch) | |
tree | 66b09f592c55df2878107a468a91d21506104d3f /qemu/roms/SLOF/slof/entry.S | |
parent | 9ca8dbcc65cfc63d6f5ef3312a33184e1d726e00 (diff) |
Add qemu 2.4.0
Change-Id: Ic99cbad4b61f8b127b7dc74d04576c0bcbaaf4f5
Signed-off-by: Yang Zhang <yang.z.zhang@intel.com>
Diffstat (limited to 'qemu/roms/SLOF/slof/entry.S')
-rw-r--r-- | qemu/roms/SLOF/slof/entry.S | 210 |
1 files changed, 210 insertions, 0 deletions
diff --git a/qemu/roms/SLOF/slof/entry.S b/qemu/roms/SLOF/slof/entry.S new file mode 100644 index 000000000..dcff57ba0 --- /dev/null +++ b/qemu/roms/SLOF/slof/entry.S @@ -0,0 +1,210 @@ +/****************************************************************************** + * Copyright (c) 2004, 2008 IBM Corporation + * All rights reserved. + * This program and the accompanying materials + * are made available under the terms of the BSD License + * which accompanies this distribution, and is available at + * http://www.opensource.org/licenses/bsd-license.php + * + * Contributors: + * IBM Corporation - initial implementation + *****************************************************************************/ + +#include <macros.h> + +#define STACKSIZE 0x2000 + + # + # The generic exception code. + # + # Enter with GPR0 = vector, SPRG0 = saved GPR0 + # + + .section ".entry_text" + +the_handler: + .quad handler + +eregs: + /* the_exception_frame is a C variable which is usually + * defined in $(TARG).c + * the_exception_frame can be accessed from paflof through + * the word eregs + * in the case an excpetion is handled paflof will read + * from eregs the values of all registers and print them + * out in the exception handler */ + .quad the_exception_frame + +handler: + mtsprg 1,1 # SPRG1 = saved GPR1 + bcl 20,31,$+4 + mflr 1 + ld 1,eregs-$+4(1) # GPR1 = address of register save area + + .irp i, 2,3,4,5,6,7,8,9,10,11,12,13,14,15, \ + 16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31 + std \i,\i*8(1) + .endr # save GPR2..GPR31 + + li r3, 3 // GPR3 = mode (param_1, param_2) + mr 4,0 // GPR4 = vector + + mfsprg 0,0 + std 0,0(1) # save GPR0 + mfsprg 0,1 + std 0,8(1) # save GPR1 + + cmpwi r4, 0x900 # Decrementer interrupt + bne 0f + mfdec r5 # Save old value of decrementer as reason + lis r0,0x7fff # Set decrementer to highest value + mtdec r0 +0: + mfcr 0 + std 0,0x100(1) + mfxer 0 + std 0,0x108(1) + mfsprg 0,3 # save lr + std 0,0x110(1) + mfsprg 0,2 # save ctr + std 0,0x118(1) + mfsrr0 0 + std 0,0x120(1) + mfsrr1 0 + std 0,0x128(1) + mfdar 0 + std 0,0x130(1) + mfdsisr 0 + std 0,0x138(1) # save special regs + + bcl 20, 31, over +base: + .align 3 +.the_system_stack: + .quad the_system_stack+STACKSIZE-base +over: + mflr r2 /* gpr 2 is the base */ + ld r1, .the_system_stack-base(r2) /* load stack pointer */ + add r1, r1, r2 /* add base */ + li r0, 0 + stdu r0, -0x10(r1) + stdu r1, -0x100(r1) + + lis 2,engine@ha + ld 0,engine@l(2) # set up entry + mtsrr0 0 + + ld 2,8+engine@l(2) # set up TOC pointer + + rfid +# b .engine # ...and run! + + + + # + # Swap non-volatile client interface regs, plus GPR3..GPR7. + # + +swap_ci_regs: + /* save lr */ + mflr r0 + /* let's find out where our client stack is */ + bcl 20, 31, client_over +client_base: + .align 3 +.the_client_frame: + .quad the_client_frame-client_base +client_over: + mflr r8 /* gpr 2 is the client_base */ + mtlr r0 /* restore the original lr */ + ld r0, .the_client_frame-client_base(r8) + add r8, r0, r8 /* add the client_base */ + /* r8 now contains the address of the_client_frame */ + + .irp i, 1,2,3,4,5,6,7, \ + 13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31 + ld 0,\i*8(8) + std \i,\i*8(8) + mr \i,0 + .endr # swap GPR1..7, GPR13..31 + + ld 0,0x100(8) + mfcr 9 + mtcrf 0xff,0 + std 9,0x100(8) # swap CR + + ld 0,0x128(8) + mfmsr 9 + mtmsrd 0 + sync + isync + std 9,0x128(8) # swap MSR + + blr + + # + # Entry point for the OF client interface. + # + + .globl client_entry_point + .section ".opd","aw" + .align 3 +client_entry_point: + .quad .client_entry_point,.TOC.@tocbase,0 + .previous + .type .client_entry_point,@function + .globl .client_entry_point +.client_entry_point: + mflr 4 + bl swap_ci_regs # swap regs + mtlr 4 + li 3, 0 # client call + blr + + # + # Start the client. + # + + .globl call_client + .section ".opd","aw" + .align 3 +call_client: + .quad .call_client,.TOC.@tocbase,0 + .previous + .type .call_client,@function + .globl .call_client + +.call_client: # called with r3 = address, returns r3 + mflr 4 + mtctr 3 + bl swap_ci_regs + /* Check if LE loading */ + cmpwi 0,13,1 + beq 0f + bctrl + b 1f +0: /* handle LE */ + mfmsr 13 + xori 13,13,1 + mtsrr1 13 + mfctr 13 + mr 12,13 + mtsrr0 13 + rfid +#if 0 /* in case we return back, still to be tested */ + .long 0x05009f42; /* bcl 20,31,$+4 */ + .long 0xa602c87d; /* mflr r14 */ + .long 0x1c00ce39; /* addi r14,r14,28 */ + .long 0xa600e07d; /* mfmsr r15 */ + .long 0x0100ef69; /* xori r15,r15,1 */ + .long 0xa603da7d; /* mtsrr0 r14 */ + .long 0xa603fb7d; /* mtsrr1 r15 */ + .long 0x2400004c; /* rfid */ +#endif +1: + bl swap_ci_regs + mtlr 4 + li 3, -1 # client app return + blr + + .lcomm the_system_stack, STACKSIZE, 16 |