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 /* powernv machine does not check broken_sc1 */ 101 mfmsr r3 102 li r4,1 103 sldi r4,r4,MSR_HV_BIT 104 and. r3,r3,r4 105 bne 1f 106 107 /* patch sc1 if needed */ 108 bl hcall_have_broken_sc1 109 cmpwi r3, 0 110 beq 1f 111 LOAD_REG_ADDR(r3, hcall) 112 LOAD_REG_IMMEDIATE(r4, SC1_REPLACEMENT) 113 stw r4, 0(r3) 114 115 /* complete setup */ 1161: ld r3, 56(r1) 117 bl setup 118 119 /* run the test */ 120 LOAD_REG_ADDR(r3, __argc) 121 LOAD_REG_ADDR(r4, __argv) 122 LOAD_REG_ADDR(r5, __environ) 123 lwz r3, 0(r3) 124 bl main 125 bl exit 126 b halt 127 128.align 3 129p_stack: .llong stackptr 130p_toc: .llong tocptr 131p_dyn: .llong dynamic_start 132 133.text 134start_text: 135.align 3 136p_toc_text: .llong tocptr 137 138.align 3 139.globl hcall 140hcall: 141 sc 1 142 blr 143 144.globl halt 145halt: 1461: b 1b 147 148.globl enter_rtas 149enter_rtas: 150 LOAD_REG_ADDR(r11, rtas_entry) 151 ld r10, 0(r11) 152 153 cmpdi r10,0 154 bne external_rtas 155 156 /* Use H_RTAS directly */ 157 mr r4,r3 158 lis r3,KVMPPC_H_RTAS@h 159 ori r3,r3,KVMPPC_H_RTAS@l 160 b hcall 161 162external_rtas: 163 /* Use external RTAS blob */ 164 mflr r0 165 std r0, 16(r1) 166 167 LOAD_REG_ADDR(r11, rtas_return_loc) 168 mtlr r11 169 170 mfmsr r11 171 LOAD_REG_IMMEDIATE(r9, RTAS_MSR_MASK) 172 and r11, r11, r9 173 mtsrr0 r10 174 mtsrr1 r11 175 rfid 176 b . 177 178rtas_return_loc: 179 FIXUP_ENDIAN 180 ld r0, 16(r1) 181 mtlr r0 182 blr 183 184call_handler: 185 /* save context */ 186 187 /* GPRs */ 188 189 .irp i, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16 \ 190 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31 191 SAVE_GPR(\i, r1) 192 .endr 193 mfsprg1 r0 194 std r0,GPR1(r1) 195 std r0,0(r1) /* Backchain from interrupt stack to regular stack */ 196 197 /* lr, xer, ccr */ 198 199 mflr r0 200 std r0,_LINK(r1) 201 202 mfxer r0 203 std r0,_XER(r1) 204 205 mfcr r0 206 std r0,_CCR(r1) 207 208 /* restore TOC pointer */ 209 bl 0f 2100: mflr r31 211 subi r31, r31, 0b - start_text 212 ld r2, (p_toc_text - start_text)(r31) 213 214 /* call generic handler */ 215 216 addi r3,r1,STACK_FRAME_OVERHEAD 217 bl do_handle_exception 218 .global do_handle_exception_return 219do_handle_exception_return: 220 221 /* restore context */ 222 223 ld r0,_CTR(r1) 224 mtctr r0 225 226 ld r0,_LINK(r1) 227 mtlr r0 228 229 ld r0,_XER(r1) 230 mtxer r0 231 232 ld r0,_CCR(r1) 233 mtcr r0 234 235 ld r0, _NIP(r1) 236 mtsrr0 r0 237 238 ld r0, _MSR(r1) 239 mtsrr1 r0 240 241 .irp i, 0, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16 \ 242 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31 243 REST_GPR(\i, r1) 244 .endr 245 246 /* restore r1, as we don't need it anymore */ 247 248 REST_GPR(1,r1) 249 250 rfid 251 b . 252 253.section .text.ex 254 255/* [H]VECTOR must not be more than 8 instructions to fit in 0x20 vectors */ 256.macro VECTOR vec 257 . = \vec 258 259 mtsprg1 r1 /* save r1 */ 260 mfsprg0 r1 /* get exception stack address */ 261 subi r1,r1, INT_FRAME_SIZE 262 263 /* save r0 and ctr to call generic handler */ 264 SAVE_GPR(0,r1) 265 266 li r0,\vec 267 std r0,_TRAP(r1) 268 269 b handler_trampoline 270.endm 271 272.macro HVECTOR vec 273 . = \vec 274 275 mtsprg1 r1 /* save r1 */ 276 mfsprg0 r1 /* get exception stack address */ 277 subi r1,r1, INT_FRAME_SIZE 278 279 /* save r0 and ctr to call generic handler */ 280 SAVE_GPR(0,r1) 281 282 li r0,\vec 283 std r0,_TRAP(r1) 284 285 b handler_htrampoline 286.endm 287 288 . = 0x100 289 .globl __start_interrupts 290__start_interrupts: 291 292VECTOR(0x100) 293VECTOR(0x200) 294VECTOR(0x300) 295VECTOR(0x380) 296VECTOR(0x400) 297VECTOR(0x480) 298VECTOR(0x500) 299VECTOR(0x600) 300VECTOR(0x700) 301VECTOR(0x800) 302VECTOR(0x900) 303HVECTOR(0x980) 304VECTOR(0xa00) 305VECTOR(0xc00) 306VECTOR(0xd00) 307HVECTOR(0xe00) 308HVECTOR(0xe20) 309HVECTOR(0xe40) 310HVECTOR(0xe60) 311HVECTOR(0xe80) 312HVECTOR(0xea0) 313VECTOR(0xf00) 314VECTOR(0xf20) 315VECTOR(0xf40) 316VECTOR(0xf60) 317HVECTOR(0xf80) 318 319handler_trampoline: 320 mfctr r0 321 std r0,_CTR(r1) 322 323 ld r0, P_HANDLER(0) 324 mtctr r0 325 326 /* nip and msr */ 327 mfsrr0 r0 328 std r0, _NIP(r1) 329 330 mfsrr1 r0 331 std r0, _MSR(r1) 332 333 bctr 334 335handler_htrampoline: 336 mfctr r0 337 std r0,_CTR(r1) 338 339 ld r0, P_HANDLER(0) 340 mtctr r0 341 342 /* nip and msr */ 343 mfspr r0, SPR_HSRR0 344 std r0, _NIP(r1) 345 346 mfspr r0, SPR_HSRR1 347 std r0, _MSR(r1) 348 349 bctr 350 351 .align 7 352 .globl __end_interrupts 353__end_interrupts: 354 .org P_HANDLER 355 .llong 0 356