|
|||
Prex Home / Browse Source - Prex Version: 0.9.0 |
|||
root/bsp/hal/ppc/arch/locore.S/* [<][>][^][v][top][bottom][index][help] */DEFINITIONSThis source file includes following definitions.1 /*- 2 * Copyright (c) 2009, Kohsuke Ohtani 3 * All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions 7 * are met: 8 * 1. Redistributions of source code must retain the above copyright 9 * notice, this list of conditions and the following disclaimer. 10 * 2. Redistributions in binary form must reproduce the above copyright 11 * notice, this list of conditions and the following disclaimer in the 12 * documentation and/or other materials provided with the distribution. 13 * 3. Neither the name of the author nor the names of any co-contributors 14 * may be used to endorse or promote products derived from this software 15 * without specific prior written permission. 16 * 17 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 18 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 19 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 20 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 21 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 22 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 23 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 24 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 25 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 26 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 27 * SUCH DAMAGE. 28 */ 29 30 /* 31 * locore.S - low level platform support 32 */ 33 34 /* 35 * Memo: SPRG usage 36 * SPRG0 - kernel stack pointer 37 * SPRG1 - saved stack pointer 38 * SPRG2 - interrupt nest counter 39 * SPRG3 - scratch pad 40 */ 41 42 #include <conf/config.h> 43 #include <machine/asm.h> 44 #include <machine/syspage.h> 45 #include <machine/memory.h> 46 #include <sys/errno.h> 47 #include <context.h> 48 #include <trap.h> 49 #include <cpu.h> 50 51 .section ".text","ax" 52 53 #define ABS_JUMP(target) \ 54 lis r12, (target)@ha ; \ 55 ori r12, r12, (target)@l ; \ 56 mtctr r12 ;\ 57 bctr 58 59 /* 60 * Macro to save all registers. 61 */ 62 #define SAVE_ALL \ 63 subi r1, r1, CTXREGS; \ 64 stw r0, REG_R0(r1); \ 65 stw r2, REG_R2(r1); \ 66 stw r3, REG_R3(r1); \ 67 stw r4, REG_R4(r1); \ 68 stw r5, REG_R5(r1); \ 69 stw r6, REG_R6(r1); \ 70 stw r7, REG_R7(r1); \ 71 stw r8, REG_R8(r1); \ 72 stw r9, REG_R9(r1); \ 73 stw r10, REG_R10(r1); \ 74 stw r11, REG_R11(r1); \ 75 stw r12, REG_R12(r1); \ 76 stw r13, REG_R13(r1); \ 77 stw r14, REG_R14(r1); \ 78 stw r15, REG_R15(r1); \ 79 stw r16, REG_R16(r1); \ 80 stw r17, REG_R17(r1); \ 81 stw r18, REG_R18(r1); \ 82 stw r19, REG_R19(r1); \ 83 stw r20, REG_R20(r1); \ 84 stw r21, REG_R21(r1); \ 85 stw r22, REG_R22(r1); \ 86 stw r23, REG_R23(r1); \ 87 stw r24, REG_R24(r1); \ 88 stw r25, REG_R25(r1); \ 89 stw r26, REG_R26(r1); \ 90 stw r27, REG_R27(r1); \ 91 stw r28, REG_R28(r1); \ 92 stw r29, REG_R29(r1); \ 93 stw r30, REG_R30(r1); \ 94 stw r31, REG_R31(r1); \ 95 mfsprg1 r10; /* Get saved sp */ \ 96 stw r10, REG_R1(r1); \ 97 mfspr r10, SPR_SRR0; \ 98 stw r10, REG_SRR0(r1); \ 99 mfspr r10, SPR_SRR1; \ 100 stw r10, REG_SRR1(r1); \ 101 mfspr r10, SPR_LR; \ 102 stw r10, REG_LR(r1); \ 103 mfspr r10, SPR_CTR; \ 104 stw r10, REG_CTR(r1); \ 105 mfspr r10, SPR_XER; \ 106 stw r10, REG_XER(r1); \ 107 mfspr r10, SPR_LR; \ 108 stw r10, REG_LR(r1); \ 109 mfcr r10; \ 110 stw r10, REG_CR(r1); 111 112 /* 113 * Macro to restore all registers. 114 */ 115 #define RESTORE_ALL \ 116 lwz r10, REG_SRR0(r1); \ 117 mtspr SPR_SRR0, r10; \ 118 lwz r10, REG_SRR1(r1); \ 119 mtspr SPR_SRR1, r10; \ 120 lwz r10, REG_LR(r1); \ 121 mtspr SPR_LR, r10; \ 122 lwz r10, REG_XER(r1); \ 123 mtspr SPR_XER, r10; \ 124 lwz r10, REG_CTR(r1); \ 125 mtspr SPR_CTR, r10; \ 126 lwz r10, REG_LR(r1); \ 127 mtspr SPR_LR, r10; \ 128 lwz r10, REG_CR(r1); \ 129 mtcr r10; \ 130 lwz r10, REG_R1(r1); \ 131 mtsprg1 r10; /* Restore saved sp */ \ 132 lwz r0, REG_R0(r1); \ 133 lwz r2, REG_R2(r1); \ 134 lwz r3, REG_R3(r1); \ 135 lwz r4, REG_R4(r1); \ 136 lwz r5, REG_R5(r1); \ 137 lwz r6, REG_R6(r1); \ 138 lwz r7, REG_R7(r1); \ 139 lwz r8, REG_R8(r1); \ 140 lwz r9, REG_R9(r1); \ 141 lwz r10, REG_R10(r1); \ 142 lwz r11, REG_R11(r1); \ 143 lwz r12, REG_R12(r1); \ 144 lwz r13, REG_R13(r1); \ 145 lwz r14, REG_R14(r1); \ 146 lwz r15, REG_R15(r1); \ 147 lwz r16, REG_R16(r1); \ 148 lwz r17, REG_R17(r1); \ 149 lwz r18, REG_R18(r1); \ 150 lwz r19, REG_R19(r1); \ 151 lwz r20, REG_R20(r1); \ 152 lwz r21, REG_R21(r1); \ 153 lwz r22, REG_R22(r1); \ 154 lwz r23, REG_R23(r1); \ 155 lwz r24, REG_R24(r1); \ 156 lwz r25, REG_R25(r1); \ 157 lwz r26, REG_R26(r1); \ 158 lwz r27, REG_R27(r1); \ 159 lwz r28, REG_R28(r1); \ 160 lwz r29, REG_R29(r1); \ 161 lwz r30, REG_R30(r1); \ 162 lwz r31, REG_R31(r1); 163 164 /* 165 * Macro to build an exception entry. 166 * We assume interrupts are disabled. 167 */ 168 #define EXCEPTION_ENTRY(offset, name, id, xfer) \ 169 .skip offset - (. - exception_vector); \ 170 exception_##name: \ 171 mtsprg1 r1; /* sprg1: current sp */ \ 172 mtsprg3 r10; /* sprg3: saved r10 */ \ 173 mfcr r10; /* r10: saved cr */ \ 174 mfsrr1 r1; /* Get msr */ \ 175 mtcr r1; \ 176 bt 17, 1f; /* Exception from user mode? */ \ 177 mfsprg1 r1; /* Kernel mode => restore orignal sp */ \ 178 b 2f; \ 179 1: mfsprg0 r1; /* User mode => Load kernel stack */ \ 180 2: mtcr r10; /* Restore cr */ \ 181 mfsprg3 r10; /* Restore r10 */ \ 182 SAVE_ALL ; \ 183 li r10, id; \ 184 ABS_JUMP(xfer); 185 186 #define INTR_ENTRY(offset, name, id) \ 187 EXCEPTION_ENTRY(offset, name, id, interrupt_common) 188 189 #define TRAP_ENTRY(offset, name, id) \ 190 EXCEPTION_ENTRY(offset, name, id, trap_common) 191 192 /* 193 * Macro to build a system call entry. 194 */ 195 #define SYSC_ENTRY(offset, name, id) \ 196 .skip offset - (. - exception_vector); \ 197 exception_##name: \ 198 mtsprg1 r1; /* sprg1: current sp */ \ 199 mfsprg0 r1; /* Load kernel stack */ \ 200 SAVE_ALL ; \ 201 li r10, id; \ 202 ABS_JUMP(syscall_entry); 203 204 /* 205 * Exception vectors 206 */ 207 .globl exception_vector 208 exception_vector: 209 .long 0 210 211 .skip 0x100 - (. - exception_vector); \ 212 ENTRY(system_reset) 213 ABS_JUMP(kernel_start) 214 215 TRAP_ENTRY(0x200, machine_check ,TRAP_MACHINE_CHECK) 216 TRAP_ENTRY(0x300, dsi ,TRAP_DSI) 217 TRAP_ENTRY(0x400, isi ,TRAP_ISI) 218 INTR_ENTRY(0x500, external_intr ,TRAP_EXT_INTERRUPT) 219 TRAP_ENTRY(0x600, alignment ,TRAP_ALIGNMENT) 220 TRAP_ENTRY(0x700, program ,TRAP_PROGRAM) 221 TRAP_ENTRY(0x800, fp_unavailable ,TRAP_FP_UNAVAILABLE) 222 INTR_ENTRY(0x900, decrementer ,TRAP_DECREMENTER) 223 SYSC_ENTRY(0xc00, syscall ,TRAP_SYSTEM_CALL) 224 TRAP_ENTRY(0xd00, trace ,TRAP_TRACE) 225 TRAP_ENTRY(0xe00, fp_assist ,TRAP_FP_ASSIST) 226 227 .globl exception_vector_end 228 exception_vector_end: 229 230 231 /* 232 * Kernel start point 233 */ 234 ENTRY(kernel_start) 235 /* 236 * Setup CPU registers. 237 */ 238 li r3, MSR_IP /* Establish default MSR value */ 239 mtmsr r3 240 241 li r3, 0 /* Init interrupt nest count */ 242 mtspr SPR_SPRG2, r3 243 244 li r3, 0 /* Reset timebase */ 245 mttbl r3 246 mttbu r3 247 mttbl r3 248 249 /* 250 * Init boot stack 251 */ 252 lis r1, BOOTSTKTOP@ha 253 addi r1, r1, BOOTSTKTOP@l 254 subi r1, r1, 16 255 256 mtspr SPR_SPRG0, r1 /* Keep kernel stack */ 257 258 /* 259 * Clear kernel BSS 260 */ 261 lis r3, __bss@ha 262 addi r3, r3, __bss@l 263 lis r4, __end@ha 264 addi r4, r4, __end@l 265 li r0, 0 266 1: 267 stwu r0, 4(r3) 268 cmplw cr0, r3, r4 269 blt 1b 270 271 /* 272 * Call kernel main routine 273 */ 274 b main 275 /* NOTREACHED */ 276 277 278 /* 279 * Common entry for interrupts. 280 * r3 - trap id 281 */ 282 ENTRY(interrupt_common) 283 stw r10, CTX_TRAPNO(r1) 284 285 mfsprg2 r28 /* r28: current IRQ nesting level */ 286 addi r3, r28, 1 /* Increment IRQ nesting level */ 287 mtsprg2 r3 288 289 mfmsr r29 /* r29: current msr value */ 290 isync 291 mr r30, r1 /* r30: trap frame */ 292 subi r1, r1, STKFRAME_LEN /* Adjust stack frame for C routine */ 293 294 cmpwi cr0, r28, 0 /* Outermost interrupt? */ 295 bne 1f 296 bl sched_lock /* If outermost, lock scheduler */ 297 1: 298 mr r3, r30 299 bl interrupt_handler /* Call main interrupt handler */ 300 301 mtsprg2 r28 /* Restore IRQ nesting level */ 302 cmpwi cr0, r28, 0 /* Outermost interrupt? */ 303 bne interrupt_ret 304 bl sched_unlock /* Try to preempt */ 305 306 mtcr r29 /* Exception from user mode? */ 307 bf 17, interrupt_ret /* Exit if it's from kernel mode */ 308 309 mfmsr r27 /* Enable IRQ */ 310 andi. r4, r27, ~MSR_EE@l 311 mtmsr r4 312 bl exception_deliver /* Check exception */ 313 mtmsr r27 /* Disable IRQ */ 314 interrupt_ret: 315 mr r1, r30 /* Restore stack */ 316 RESTORE_ALL 317 mfsprg1 r1 /* restore original sp */ 318 rfi 319 320 /* 321 * System call entry 322 */ 323 .global syscall_ret 324 ENTRY(syscall_entry) 325 stw r10, CTX_TRAPNO(r1) 326 327 mfmsr r29 /* r29: current msr value */ 328 mr r30, r1 /* r30: trap frame */ 329 subi r1, r1, STKFRAME_LEN /* Adjust stack frame for C routine */ 330 331 mfmsr r27 /* Enable IRQ */ 332 andi. r27, r27, ~MSR_EE@l 333 mtmsr r27 334 335 mr r26, r0 /* r26: saved syscall number */ 336 mr r7, r0 337 bl syscall_handler /* System call dispatcher */ 338 339 cmpwi cr0, r26, 0 /* exception_return? */ 340 beq 1f /* Skip storing error if so */ 341 stw r3, REG_R3(30) /* Set return value */ 342 1: 343 bl exception_deliver /* Check exception */ 344 mr r1, r30 /* Restore stack */ 345 syscall_ret: 346 mfmsr r27 /* Disable IRQ */ 347 ori r27, r27, MSR_EE@l 348 mtmsr r27 349 RESTORE_ALL 350 mfsprg1 r1 /* Restore original sp */ 351 rfi 352 353 /* 354 * Common entry for exceptions. 355 * r3 - trap id 356 */ 357 ENTRY(trap_common) 358 stw r10, CTX_TRAPNO(r1) 359 360 mfsprg2 r3 /* increment nest counter */ 361 addi r3, r3, 1 362 mtsprg2 r3 363 364 mr r3, r1 365 subi r1, r1, STKFRAME_LEN 366 bl trap_handler 367 addi r1, r1, STKFRAME_LEN 368 369 mfsprg2 r3 /* decrement nest counter */ 370 addi r3, r3, -1 371 mtsprg2 r3 372 373 RESTORE_ALL 374 mfsprg1 r1 /* restore original sp */ 375 rfi 376 377 /* 378 * Switch register context. 379 * r3 = previous kern_regs, r4 = next kern_regs 380 * Interrupts must be disabled by caller. 381 * 382 * syntax - void cpu_switch(kern_regs *prev, kern_regs *next) 383 * 384 * Note: GCC uses r0-r12 as scratch registers 385 */ 386 ENTRY(cpu_switch) 387 isync 388 stw r13, 0x00(r3) 389 stw r14, 0x04(r3) 390 stw r15, 0x08(r3) 391 stw r16, 0x0c(r3) 392 stw r17, 0x10(r3) 393 stw r18, 0x14(r3) 394 stw r19, 0x18(r3) 395 stw r20, 0x1c(r3) 396 stw r21, 0x20(r3) 397 stw r22, 0x24(r3) 398 stw r23, 0x28(r3) 399 stw r24, 0x2c(r3) 400 stw r25, 0x30(r3) 401 stw r26, 0x34(r3) 402 stw r27, 0x38(r3) 403 stw r28, 0x3c(r3) 404 stw r29, 0x40(r3) 405 stw r30, 0x44(r3) 406 stw r31, 0x48(r3) 407 stw r2, 0x4c(r3) 408 stw r1, 0x50(r3) 409 mflr r5 410 stw r5, 0x54(r3) 411 mfcr r5 412 stw r5, 0x58(r3) 413 mfsprg0 r5 /* Save kernel stack */ 414 stw r5, 0x5c(r3) 415 416 lwz r13, 0x00(r4) 417 lwz r14, 0x04(r4) 418 lwz r15, 0x08(r4) 419 lwz r16, 0x0c(r4) 420 lwz r17, 0x10(r4) 421 lwz r18, 0x14(r4) 422 lwz r19, 0x18(r4) 423 lwz r20, 0x1c(r4) 424 lwz r21, 0x20(r4) 425 lwz r22, 0x24(r4) 426 lwz r23, 0x28(r4) 427 lwz r24, 0x2c(r4) 428 lwz r25, 0x30(r4) 429 lwz r26, 0x34(r4) 430 lwz r27, 0x38(r4) 431 lwz r28, 0x3c(r4) 432 lwz r29, 0x40(r4) 433 lwz r30, 0x44(r4) 434 lwz r31, 0x48(r4) 435 lwz r2, 0x4c(r4) 436 lwz r1, 0x50(r4) 437 lwz r5, 0x54(r4) 438 mtlr r5 439 lwz r5, 0x58(r4) 440 mtcr r5 441 lwz r5, 0x5c(r4) 442 mtsprg0 r5 /* Restore kernel stack */ 443 isync 444 blr 445 446 /* 447 * void sploff(void); 448 */ 449 ENTRY(sploff) 450 mfmsr r3 451 andi. r4, r3, ~MSR_EE@l 452 mtmsr r4 453 blr 454 455 /* 456 * void splon(void); 457 */ 458 ENTRY(splon) 459 mfmsr r3 460 ori r4, r3, MSR_EE@l 461 mtmsr r4 462 blr 463 /* [<][>][^][v][top][bottom][index][help] */ | |||
Copyright© 2005-2009 Kohsuke Ohtani |