1/* 2 * Low level routines for legacy iSeries support. 3 * 4 * Extracted from head_64.S 5 * 6 * PowerPC version 7 * Copyright (C) 1995-1996 Gary Thomas (gdt@linuxppc.org) 8 * 9 * Rewritten by Cort Dougan (cort@cs.nmt.edu) for PReP 10 * Copyright (C) 1996 Cort Dougan <cort@cs.nmt.edu> 11 * Adapted for Power Macintosh by Paul Mackerras. 12 * Low-level exception handlers and MMU support 13 * rewritten by Paul Mackerras. 14 * Copyright (C) 1996 Paul Mackerras. 15 * 16 * Adapted for 64bit PowerPC by Dave Engebretsen, Peter Bergner, and 17 * Mike Corrigan {engebret|bergner|mikejc}@us.ibm.com 18 * 19 * This file contains the low-level support and setup for the 20 * PowerPC-64 platform, including trap and interrupt dispatch. 21 * 22 * This program is free software; you can redistribute it and/or 23 * modify it under the terms of the GNU General Public License 24 * as published by the Free Software Foundation; either version 25 * 2 of the License, or (at your option) any later version. 26 */ 27 28#include <asm/reg.h> 29#include <asm/ppc_asm.h> 30#include <asm/asm-offsets.h> 31#include <asm/thread_info.h> 32#include <asm/ptrace.h> 33#include <asm/cputable.h> 34 35#include "exception.h" 36 37 .text 38 39 .globl system_reset_iSeries 40system_reset_iSeries: 41 bl .relative_toc 42 mfspr r13,SPRN_SPRG3 /* Get alpaca address */ 43 LOAD_REG_ADDR(r23, alpaca) 44 li r0,ALPACA_SIZE 45 sub r23,r13,r23 46 divdu r24,r23,r0 /* r24 has cpu number */ 47 cmpwi 0,r24,0 /* Are we processor 0? */ 48 bne 1f 49 LOAD_REG_ADDR(r13, boot_paca) 50 mtspr SPRN_SPRG_PACA,r13 /* Save it away for the future */ 51 mfmsr r23 52 ori r23,r23,MSR_RI 53 mtmsrd r23 /* RI on */ 54 b .__start_initialization_iSeries /* Start up the first processor */ 551: mfspr r4,SPRN_CTRLF 56 li r5,CTRL_RUNLATCH /* Turn off the run light */ 57 andc r4,r4,r5 58 mtspr SPRN_CTRLT,r4 59 60/* Spin on __secondary_hold_spinloop until it is updated by the boot cpu. */ 61/* In the UP case we'll yield() later, and we will not access the paca anyway */ 62#ifdef CONFIG_SMP 631: 64 HMT_LOW 65 LOAD_REG_ADDR(r23, __secondary_hold_spinloop) 66 ld r23,0(r23) 67 sync 68 LOAD_REG_ADDR(r3,current_set) 69 sldi r28,r24,3 /* get current_set[cpu#] */ 70 ldx r3,r3,r28 71 addi r1,r3,THREAD_SIZE 72 subi r1,r1,STACK_FRAME_OVERHEAD 73 74 cmpwi 0,r23,0 /* Keep poking the Hypervisor until */ 75 bne 2f /* we're released */ 76 /* Let the Hypervisor know we are alive */ 77 /* 8002 is a call to HvCallCfg::getLps, a harmless Hypervisor function */ 78 lis r3,0x8002 79 rldicr r3,r3,32,15 /* r0 = (r3 << 32) & 0xffff000000000000 */ 80 li r0,-1 /* r0=-1 indicates a Hypervisor call */ 81 sc /* Invoke the hypervisor via a system call */ 82 b 1b 83#endif 84 852: 86 /* Load our paca now that it's been allocated */ 87 LOAD_REG_ADDR(r13, paca) 88 ld r13,0(r13) 89 mulli r0,r24,PACA_SIZE 90 add r13,r13,r0 91 mtspr SPRN_SPRG_PACA,r13 /* Save it away for the future */ 92 mfmsr r23 93 ori r23,r23,MSR_RI 94 mtmsrd r23 /* RI on */ 95 96 HMT_LOW 97#ifdef CONFIG_SMP 98 lbz r23,PACAPROCSTART(r13) /* Test if this processor 99 * should start */ 100 sync 101 LOAD_REG_ADDR(r3,current_set) 102 sldi r28,r24,3 /* get current_set[cpu#] */ 103 ldx r3,r3,r28 104 addi r1,r3,THREAD_SIZE 105 subi r1,r1,STACK_FRAME_OVERHEAD 106 107 cmpwi 0,r23,0 108 beq iSeries_secondary_smp_loop /* Loop until told to go */ 109 b __secondary_start /* Loop until told to go */ 110iSeries_secondary_smp_loop: 111 /* Let the Hypervisor know we are alive */ 112 /* 8002 is a call to HvCallCfg::getLps, a harmless Hypervisor function */ 113 lis r3,0x8002 114 rldicr r3,r3,32,15 /* r0 = (r3 << 32) & 0xffff000000000000 */ 115#else /* CONFIG_SMP */ 116 /* Yield the processor. This is required for non-SMP kernels 117 which are running on multi-threaded machines. */ 118 lis r3,0x8000 119 rldicr r3,r3,32,15 /* r3 = (r3 << 32) & 0xffff000000000000 */ 120 addi r3,r3,18 /* r3 = 0x8000000000000012 which is "yield" */ 121 li r4,0 /* "yield timed" */ 122 li r5,-1 /* "yield forever" */ 123#endif /* CONFIG_SMP */ 124 li r0,-1 /* r0=-1 indicates a Hypervisor call */ 125 sc /* Invoke the hypervisor via a system call */ 126 mfspr r13,SPRN_SPRG_PACA /* Put r13 back ???? */ 127 b 2b /* If SMP not configured, secondaries 128 * loop forever */ 129 130/*** ISeries-LPAR interrupt handlers ***/ 131 132 STD_EXCEPTION_ISERIES(machine_check, PACA_EXMC) 133 134 .globl data_access_iSeries 135data_access_iSeries: 136 mtspr SPRN_SPRG_SCRATCH0,r13 137BEGIN_FTR_SECTION 138 mfspr r13,SPRN_SPRG_PACA 139 std r9,PACA_EXSLB+EX_R9(r13) 140 std r10,PACA_EXSLB+EX_R10(r13) 141 mfspr r10,SPRN_DAR 142 mfspr r9,SPRN_DSISR 143 srdi r10,r10,60 144 rlwimi r10,r9,16,0x20 145 mfcr r9 146 cmpwi r10,0x2c 147 beq .do_stab_bolted_iSeries 148 ld r10,PACA_EXSLB+EX_R10(r13) 149 std r11,PACA_EXGEN+EX_R11(r13) 150 ld r11,PACA_EXSLB+EX_R9(r13) 151 std r12,PACA_EXGEN+EX_R12(r13) 152 mfspr r12,SPRN_SPRG_SCRATCH0 153 std r10,PACA_EXGEN+EX_R10(r13) 154 std r11,PACA_EXGEN+EX_R9(r13) 155 std r12,PACA_EXGEN+EX_R13(r13) 156 EXCEPTION_PROLOG_ISERIES_1 157FTR_SECTION_ELSE 158 EXCEPTION_PROLOG_1(PACA_EXGEN) 159 EXCEPTION_PROLOG_ISERIES_1 160ALT_FTR_SECTION_END_IFCLR(CPU_FTR_SLB) 161 b data_access_common 162 163.do_stab_bolted_iSeries: 164 std r11,PACA_EXSLB+EX_R11(r13) 165 std r12,PACA_EXSLB+EX_R12(r13) 166 mfspr r10,SPRN_SPRG_SCRATCH0 167 std r10,PACA_EXSLB+EX_R13(r13) 168 EXCEPTION_PROLOG_ISERIES_1 169 b .do_stab_bolted 170 171 .globl data_access_slb_iSeries 172data_access_slb_iSeries: 173 mtspr SPRN_SPRG_SCRATCH0,r13 /* save r13 */ 174 mfspr r13,SPRN_SPRG_PACA /* get paca address into r13 */ 175 std r3,PACA_EXSLB+EX_R3(r13) 176 mfspr r3,SPRN_DAR 177 std r9,PACA_EXSLB+EX_R9(r13) 178 mfcr r9 179#ifdef __DISABLED__ 180 cmpdi r3,0 181 bge slb_miss_user_iseries 182#endif 183 std r10,PACA_EXSLB+EX_R10(r13) 184 std r11,PACA_EXSLB+EX_R11(r13) 185 std r12,PACA_EXSLB+EX_R12(r13) 186 mfspr r10,SPRN_SPRG_SCRATCH0 187 std r10,PACA_EXSLB+EX_R13(r13) 188 ld r12,PACALPPACAPTR(r13) 189 ld r12,LPPACASRR1(r12) 190 b .slb_miss_realmode 191 192 STD_EXCEPTION_ISERIES(instruction_access, PACA_EXGEN) 193 194 .globl instruction_access_slb_iSeries 195instruction_access_slb_iSeries: 196 mtspr SPRN_SPRG_SCRATCH0,r13 /* save r13 */ 197 mfspr r13,SPRN_SPRG_PACA /* get paca address into r13 */ 198 std r3,PACA_EXSLB+EX_R3(r13) 199 ld r3,PACALPPACAPTR(r13) 200 ld r3,LPPACASRR0(r3) /* get SRR0 value */ 201 std r9,PACA_EXSLB+EX_R9(r13) 202 mfcr r9 203#ifdef __DISABLED__ 204 cmpdi r3,0 205 bge slb_miss_user_iseries 206#endif 207 std r10,PACA_EXSLB+EX_R10(r13) 208 std r11,PACA_EXSLB+EX_R11(r13) 209 std r12,PACA_EXSLB+EX_R12(r13) 210 mfspr r10,SPRN_SPRG_SCRATCH0 211 std r10,PACA_EXSLB+EX_R13(r13) 212 ld r12,PACALPPACAPTR(r13) 213 ld r12,LPPACASRR1(r12) 214 b .slb_miss_realmode 215 216#ifdef __DISABLED__ 217slb_miss_user_iseries: 218 std r10,PACA_EXGEN+EX_R10(r13) 219 std r11,PACA_EXGEN+EX_R11(r13) 220 std r12,PACA_EXGEN+EX_R12(r13) 221 mfspr r10,SPRG_SCRATCH0 222 ld r11,PACA_EXSLB+EX_R9(r13) 223 ld r12,PACA_EXSLB+EX_R3(r13) 224 std r10,PACA_EXGEN+EX_R13(r13) 225 std r11,PACA_EXGEN+EX_R9(r13) 226 std r12,PACA_EXGEN+EX_R3(r13) 227 EXCEPTION_PROLOG_ISERIES_1 228 b slb_miss_user_common 229#endif 230 231 MASKABLE_EXCEPTION_ISERIES(hardware_interrupt) 232 STD_EXCEPTION_ISERIES(alignment, PACA_EXGEN) 233 STD_EXCEPTION_ISERIES(program_check, PACA_EXGEN) 234 STD_EXCEPTION_ISERIES(fp_unavailable, PACA_EXGEN) 235 MASKABLE_EXCEPTION_ISERIES(decrementer) 236 STD_EXCEPTION_ISERIES(trap_0a, PACA_EXGEN) 237 STD_EXCEPTION_ISERIES(trap_0b, PACA_EXGEN) 238 239 .globl system_call_iSeries 240system_call_iSeries: 241 mr r9,r13 242 mfspr r13,SPRN_SPRG_PACA 243 EXCEPTION_PROLOG_ISERIES_1 244 b system_call_common 245 246 STD_EXCEPTION_ISERIES(single_step, PACA_EXGEN) 247 STD_EXCEPTION_ISERIES(trap_0e, PACA_EXGEN) 248 STD_EXCEPTION_ISERIES(performance_monitor, PACA_EXGEN) 249 250decrementer_iSeries_masked: 251 /* We may not have a valid TOC pointer in here. */ 252 li r11,1 253 ld r12,PACALPPACAPTR(r13) 254 stb r11,LPPACADECRINT(r12) 255 li r12,-1 256 clrldi r12,r12,33 /* set DEC to 0x7fffffff */ 257 mtspr SPRN_DEC,r12 258 /* fall through */ 259 260hardware_interrupt_iSeries_masked: 261 mtcrf 0x80,r9 /* Restore regs */ 262 ld r12,PACALPPACAPTR(r13) 263 ld r11,LPPACASRR0(r12) 264 ld r12,LPPACASRR1(r12) 265 mtspr SPRN_SRR0,r11 266 mtspr SPRN_SRR1,r12 267 ld r9,PACA_EXGEN+EX_R9(r13) 268 ld r10,PACA_EXGEN+EX_R10(r13) 269 ld r11,PACA_EXGEN+EX_R11(r13) 270 ld r12,PACA_EXGEN+EX_R12(r13) 271 ld r13,PACA_EXGEN+EX_R13(r13) 272 rfid 273 b . /* prevent speculative execution */ 274 275_INIT_STATIC(__start_initialization_iSeries) 276 /* Clear out the BSS */ 277 LOAD_REG_ADDR(r11,__bss_stop) 278 LOAD_REG_ADDR(r8,__bss_start) 279 sub r11,r11,r8 /* bss size */ 280 addi r11,r11,7 /* round up to an even double word */ 281 rldicl. r11,r11,61,3 /* shift right by 3 */ 282 beq 4f 283 addi r8,r8,-8 284 li r0,0 285 mtctr r11 /* zero this many doublewords */ 2863: stdu r0,8(r8) 287 bdnz 3b 2884: 289 LOAD_REG_ADDR(r1,init_thread_union) 290 addi r1,r1,THREAD_SIZE 291 li r0,0 292 stdu r0,-STACK_FRAME_OVERHEAD(r1) 293 294 bl .iSeries_early_setup 295 bl .early_setup 296 297 /* relocation is on at this point */ 298 299 b .start_here_common 300