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