1/* 2 * Entry point and assembler functions for ppc64 tests. 3 * 4 * Copyright (C) 2016, Red Hat Inc, Andrew Jones <drjones@redhat.com> 5 * 6 * This work is licensed under the terms of the GNU LGPL, version 2. 7 */ 8#define __ASSEMBLY__ 9#include <asm/hcall.h> 10#include <asm/ppc_asm.h> 11#include <asm/rtas.h> 12#include <asm/ptrace.h> 13 14#include "spapr.h" 15 16#define P_HANDLER 0x2ff8 17 18.section .init 19 20/* 21 * start is the entry point. r3 points to the DTB 22 */ 23.globl start 24start: 25 FIXUP_ENDIAN 26 /* Switch to 64-bit mode */ 27 mfmsr r1 28 li r2,1 29 sldi r2,r2,MSR_SF_BIT 30 or r1,r1,r2 31 mtmsrd r1 32 /* 33 * We were loaded at QEMU's kernel load address, but we're not 34 * allowed to link there due to how QEMU deals with linker VMAs, 35 * so we just linked at zero. This means the first thing to do is 36 * to find our stack and toc, and then do a relocate. powernv and 37 * pseries load addresses are not the same, so find the address 38 * dynamically: 39 */ 40 bl 0f 410: mflr r31 42 subi r31, r31, 0b - start /* QEMU's kernel load address */ 43 44 ld r1, (p_stack - start)(r31) 45 ld r2, (p_toc - start)(r31) 46 add r1, r1, r31 47 add r2, r2, r31 48 49 /* Zero backpointers in initial stack frame so backtrace() stops */ 50 li r0,0 51 std r0,0(r1) 52 std r0,16(r1) 53 54 /* save DTB pointer */ 55 std r3, 56(r1) 56 57 /* 58 * Call relocate. relocate is C code, but careful to not use 59 * any global references, as they may use absolute addresses, 60 * which are, obviously, not yet relocated. 61 */ 62 mr r3, r31 63 ld r4, (p_dyn - start)(r31) 64 add r4, r4, r31 65 bl relocate 66 67 /* compute address of call_handler */ 68 69 LOAD_REG_ADDR(r4, call_handler) 70 std r4, P_HANDLER(0) 71 72 /* relocate vector table to base address 0x0 (MSR_IP = 0) */ 73 74 /* source: r4, dest end: r5, destination: r6 */ 75 76 LOAD_REG_ADDR(r4, __start_interrupts) 77 LOAD_REG_ADDR(r5, __end_interrupts) 78 sub r5,r5,r4 79 li r6,0x100 80 81 sub r4,r4,r6 82 add r5,r5,r6 83 addi r6,r6,-8 842: li r0,8 85 mtctr r0 86 /* copy a cache line size */ 873: addi r6,r6,8 88 ldx r0,r6,r4 89 stdx r0,0,r6 90 bdnz 3b 91 dcbst 0,r6 92 /* flush icache */ 93 sync 94 icbi 0,r6 95 cmpld 0,r6,r5 96 blt 2b 97 sync 98 isync 99 100 /* patch sc1 if needed */ 101 bl hcall_have_broken_sc1 102 cmpwi r3, 0 103 beq 1f 104 LOAD_REG_ADDR(r3, hcall) 105 LOAD_REG_IMMEDIATE(r4, SC1_REPLACEMENT) 106 stw r4, 0(r3) 107 108 /* complete setup */ 1091: ld r3, 56(r1) 110 bl setup 111 112 /* run the test */ 113 LOAD_REG_ADDR(r3, __argc) 114 LOAD_REG_ADDR(r4, __argv) 115 LOAD_REG_ADDR(r5, __environ) 116 lwz r3, 0(r3) 117 bl main 118 bl exit 119 b halt 120 121.align 3 122p_stack: .llong stackptr 123p_toc: .llong tocptr 124p_dyn: .llong dynamic_start 125 126.text 127start_text: 128.align 3 129p_toc_text: .llong tocptr 130 131.align 3 132.globl hcall 133hcall: 134 sc 1 135 blr 136 137.globl halt 138halt: 1391: b 1b 140 141.globl enter_rtas 142enter_rtas: 143 LOAD_REG_ADDR(r11, rtas_entry) 144 ld r10, 0(r11) 145 146 cmpdi r10,0 147 bne external_rtas 148 149 /* Use H_RTAS directly */ 150 mr r4,r3 151 lis r3,KVMPPC_H_RTAS@h 152 ori r3,r3,KVMPPC_H_RTAS@l 153 b hcall 154 155external_rtas: 156 /* Use external RTAS blob */ 157 mflr r0 158 std r0, 16(r1) 159 160 LOAD_REG_ADDR(r11, rtas_return_loc) 161 mtlr r11 162 163 mfmsr r11 164 LOAD_REG_IMMEDIATE(r9, RTAS_MSR_MASK) 165 and r11, r11, r9 166 mtsrr0 r10 167 mtsrr1 r11 168 rfid 169 b . 170 171rtas_return_loc: 172 FIXUP_ENDIAN 173 ld r0, 16(r1) 174 mtlr r0 175 blr 176 177call_handler: 178 /* save context */ 179 180 /* GPRs */ 181 182 .irp i, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16 \ 183 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31 184 SAVE_GPR(\i, r1) 185 .endr 186 mfsprg1 r0 187 std r0,GPR1(r1) 188 std r0,0(r1) /* Backchain from interrupt stack to regular stack */ 189 190 /* lr, xer, ccr */ 191 192 mflr r0 193 std r0,_LINK(r1) 194 195 mfxer r0 196 std r0,_XER(r1) 197 198 mfcr r0 199 std r0,_CCR(r1) 200 201 /* restore TOC pointer */ 202 bl 0f 2030: mflr r31 204 subi r31, r31, 0b - start_text 205 ld r2, (p_toc_text - start_text)(r31) 206 207 /* call generic handler */ 208 209 addi r3,r1,STACK_FRAME_OVERHEAD 210 bl do_handle_exception 211 .global do_handle_exception_return 212do_handle_exception_return: 213 214 /* restore context */ 215 216 ld r0,_CTR(r1) 217 mtctr r0 218 219 ld r0,_LINK(r1) 220 mtlr r0 221 222 ld r0,_XER(r1) 223 mtxer r0 224 225 ld r0,_CCR(r1) 226 mtcr r0 227 228 ld r0, _NIP(r1) 229 mtsrr0 r0 230 231 ld r0, _MSR(r1) 232 mtsrr1 r0 233 234 .irp i, 0, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16 \ 235 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31 236 REST_GPR(\i, r1) 237 .endr 238 239 /* restore r1, as we don't need it anymore */ 240 241 REST_GPR(1,r1) 242 243 rfid 244 b . 245 246.section .text.ex 247 248/* [H]VECTOR must not be more than 8 instructions to fit in 0x20 vectors */ 249.macro VECTOR vec 250 . = \vec 251 252 mtsprg1 r1 /* save r1 */ 253 mfsprg0 r1 /* get exception stack address */ 254 subi r1,r1, INT_FRAME_SIZE 255 256 /* save r0 and ctr to call generic handler */ 257 SAVE_GPR(0,r1) 258 259 li r0,\vec 260 std r0,_TRAP(r1) 261 262 b handler_trampoline 263.endm 264 265.macro HVECTOR vec 266 . = \vec 267 268 mtsprg1 r1 /* save r1 */ 269 mfsprg0 r1 /* get exception stack address */ 270 subi r1,r1, INT_FRAME_SIZE 271 272 /* save r0 and ctr to call generic handler */ 273 SAVE_GPR(0,r1) 274 275 li r0,\vec 276 std r0,_TRAP(r1) 277 278 b handler_htrampoline 279.endm 280 281 . = 0x100 282 .globl __start_interrupts 283__start_interrupts: 284 285VECTOR(0x100) 286VECTOR(0x200) 287VECTOR(0x300) 288VECTOR(0x380) 289VECTOR(0x400) 290VECTOR(0x480) 291VECTOR(0x500) 292VECTOR(0x600) 293VECTOR(0x700) 294VECTOR(0x800) 295VECTOR(0x900) 296HVECTOR(0x980) 297VECTOR(0xa00) 298VECTOR(0xc00) 299VECTOR(0xd00) 300HVECTOR(0xe00) 301HVECTOR(0xe20) 302HVECTOR(0xe40) 303HVECTOR(0xe60) 304HVECTOR(0xe80) 305HVECTOR(0xea0) 306VECTOR(0xf00) 307VECTOR(0xf20) 308VECTOR(0xf40) 309VECTOR(0xf60) 310HVECTOR(0xf80) 311 312handler_trampoline: 313 mfctr r0 314 std r0,_CTR(r1) 315 316 ld r0, P_HANDLER(0) 317 mtctr r0 318 319 /* nip and msr */ 320 mfsrr0 r0 321 std r0, _NIP(r1) 322 323 mfsrr1 r0 324 std r0, _MSR(r1) 325 326 bctr 327 328handler_htrampoline: 329 mfctr r0 330 std r0,_CTR(r1) 331 332 ld r0, P_HANDLER(0) 333 mtctr r0 334 335 /* nip and msr */ 336 mfspr r0, SPR_HSRR0 337 std r0, _NIP(r1) 338 339 mfspr r0, SPR_HSRR1 340 std r0, _MSR(r1) 341 342 bctr 343 344 .align 7 345 .globl __end_interrupts 346__end_interrupts: 347 .org P_HANDLER 348 .llong 0 349