1/****************************************************************************** 2 * Copyright (c) 2004, 2008 IBM Corporation 3 * All rights reserved. 4 * This program and the accompanying materials 5 * are made available under the terms of the BSD License 6 * which accompanies this distribution, and is available at 7 * http://www.opensource.org/licenses/bsd-license.php 8 * 9 * Contributors: 10 * IBM Corporation - initial implementation 11 *****************************************************************************/ 12 13#include <macros.h> 14 15#define STACKSIZE 0x2000 16 17 # 18 # The generic exception code. 19 # 20 # Enter with GPR0 = vector, SPRG0 = saved GPR0 21 # 22 23 .section ".entry_text" 24 25the_handler: 26 .quad handler 27 28eregs: 29 /* the_exception_frame is a C variable which is usually 30 * defined in $(TARG).c 31 * the_exception_frame can be accessed from paflof through 32 * the word eregs 33 * in the case an excpetion is handled paflof will read 34 * from eregs the values of all registers and print them 35 * out in the exception handler */ 36 .quad the_exception_frame 37 38handler: 39 mtsprg 1,1 # SPRG1 = saved GPR1 40 bcl 20,31,$+4 41 mflr 1 42 ld 1,eregs-$+4(1) # GPR1 = address of register save area 43 44 .irp i, 2,3,4,5,6,7,8,9,10,11,12,13,14,15, \ 45 16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31 46 std \i,\i*8(1) 47 .endr # save GPR2..GPR31 48 49 li r3, 3 // GPR3 = mode (param_1, param_2) 50 mr 4,0 // GPR4 = vector 51 52 mfsprg 0,0 53 std 0,0(1) # save GPR0 54 mfsprg 0,1 55 std 0,8(1) # save GPR1 56 57 cmpwi r4, 0x900 # Decrementer interrupt 58 bne 0f 59 mfdec r5 # Save old value of decrementer as reason 60 lis r0,0x7fff # Set decrementer to highest value 61 mtdec r0 620: 63 mfcr 0 64 std 0,0x100(1) 65 mfxer 0 66 std 0,0x108(1) 67 mfsprg 0,3 # save lr 68 std 0,0x110(1) 69 mfsprg 0,2 # save ctr 70 std 0,0x118(1) 71 mfsrr0 0 72 std 0,0x120(1) 73 mfsrr1 0 74 std 0,0x128(1) 75 mfdar 0 76 std 0,0x130(1) 77 mfdsisr 0 78 std 0,0x138(1) # save special regs 79 80 bcl 20, 31, over 81base: 82 .align 3 83.the_system_stack: 84 .quad the_system_stack+STACKSIZE-base 85over: 86 mflr r2 /* gpr 2 is the base */ 87 ld r1, .the_system_stack-base(r2) /* load stack pointer */ 88 add r1, r1, r2 /* add base */ 89 li r0, 0 90 stdu r0, -0x10(r1) 91 stdu r1, -0x100(r1) 92 93 lis 2,engine@ha 94 ld 0,engine@l(2) # set up entry 95 mtsrr0 0 96 97 ld 2,8+engine@l(2) # set up TOC pointer 98 99 rfid 100# b .engine # ...and run! 101 102 103 104 # 105 # Swap non-volatile client interface regs, plus GPR3..GPR7. 106 # 107 108swap_ci_regs: 109 /* save lr */ 110 mflr r0 111 /* let's find out where our client stack is */ 112 bcl 20, 31, client_over 113client_base: 114 .align 3 115.the_client_frame: 116 .quad the_client_frame-client_base 117client_over: 118 mflr r8 /* gpr 2 is the client_base */ 119 mtlr r0 /* restore the original lr */ 120 ld r0, .the_client_frame-client_base(r8) 121 add r8, r0, r8 /* add the client_base */ 122 /* r8 now contains the address of the_client_frame */ 123 124 .irp i, 1,2,3,4,5,6,7, \ 125 13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31 126 ld 0,\i*8(8) 127 std \i,\i*8(8) 128 mr \i,0 129 .endr # swap GPR1..7, GPR13..31 130 131 ld 0,0x100(8) 132 mfcr 9 133 mtcrf 0xff,0 134 std 9,0x100(8) # swap CR 135 136 ld 0,0x128(8) 137 mfmsr 9 138 mtmsrd 0 139 sync 140 isync 141 std 9,0x128(8) # swap MSR 142 143 blr 144 145 # 146 # Entry point for the OF client interface. 147 # 148 149 .globl client_entry_point 150 .section ".opd","aw" 151 .align 3 152client_entry_point: 153 .quad .client_entry_point,.TOC.@tocbase,0 154 .previous 155 .type .client_entry_point,@function 156 .globl .client_entry_point 157.client_entry_point: 158 mflr 4 159 bl swap_ci_regs # swap regs 160 mtlr 4 161 li 3, 0 # client call 162 blr 163 164 # 165 # Start the client. 166 # 167 168 .globl call_client 169 .section ".opd","aw" 170 .align 3 171call_client: 172 .quad .call_client,.TOC.@tocbase,0 173 .previous 174 .type .call_client,@function 175 .globl .call_client 176 177.call_client: # called with r3 = address, returns r3 178 mflr 4 179 mtctr 3 180 bl swap_ci_regs 181 /* Check if LE loading */ 182 cmpwi 0,13,1 183 beq 0f 184 bctrl 185 b 1f 1860: /* handle LE */ 187 mfmsr 13 188 xori 13,13,1 189 mtsrr1 13 190 mfctr 13 191 mr 12,13 192 mtsrr0 13 193 rfid 194#if 0 /* in case we return back, still to be tested */ 195 .long 0x05009f42; /* bcl 20,31,$+4 */ 196 .long 0xa602c87d; /* mflr r14 */ 197 .long 0x1c00ce39; /* addi r14,r14,28 */ 198 .long 0xa600e07d; /* mfmsr r15 */ 199 .long 0x0100ef69; /* xori r15,r15,1 */ 200 .long 0xa603da7d; /* mtsrr0 r14 */ 201 .long 0xa603fb7d; /* mtsrr1 r15 */ 202 .long 0x2400004c; /* rfid */ 203#endif 2041: 205 bl swap_ci_regs 206 mtlr 4 207 li 3, -1 # client app return 208 blr 209 210 211 # Call another function via pointer in r6 212 # (arguments can be provided in r3 to r5) 213 # Destination function should jump back to lr 214C_ENTRY(call_c) 215 mtctr r6 216 bctr 217 218.global the_system_stack 219 .lcomm the_system_stack, STACKSIZE, 16 220