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. 37 */ 38 LOAD_REG_IMMEDIATE(r31, SPAPR_KERNEL_LOAD_ADDR) 39 ld r1, (p_stack - start)(r31) 40 ld r2, (p_toc - start)(r31) 41 add r1, r1, r31 42 add r2, r2, r31 43 44 /* save DTB pointer */ 45 std r3, 56(r1) 46 47 /* 48 * Call relocate. relocate is C code, but careful to not use 49 * any global references, as they may use absolute addresses, 50 * which are, obviously, not yet relocated. 51 */ 52 mr r3, r31 53 ld r4, (p_dyn - start)(r31) 54 add r4, r4, r31 55 bl relocate 56 57 /* compute address of call_handler */ 58 59 LOAD_REG_ADDR(r4, call_handler) 60 std r4, P_HANDLER(0) 61 62 /* relocate vector table to base address 0x0 (MSR_IP = 0) */ 63 64 /* source: r4, dest end: r5, destination: r6 */ 65 66 LOAD_REG_ADDR(r4, __start_interrupts) 67 LOAD_REG_ADDR(r5, __end_interrupts) 68 sub r5,r5,r4 69 li r6,0x100 70 71 sub r4,r4,r6 72 add r5,r5,r6 73 addi r6,r6,-8 742: li r0,8 75 mtctr r0 76 /* copy a cache line size */ 773: addi r6,r6,8 78 ldx r0,r6,r4 79 stdx r0,0,r6 80 bdnz 3b 81 dcbst 0,r6 82 /* flush icache */ 83 sync 84 icbi 0,r6 85 cmpld 0,r6,r5 86 blt 2b 87 sync 88 isync 89 90 /* patch sc1 if needed */ 91 bl hcall_have_broken_sc1 92 cmpwi r3, 0 93 beq 1f 94 LOAD_REG_ADDR(r3, hcall) 95 LOAD_REG_IMMEDIATE(r4, SC1_REPLACEMENT) 96 stw r4, 0(r3) 97 98 /* complete setup */ 991: ld r3, 56(r1) 100 bl setup 101 102 /* run the test */ 103 LOAD_REG_ADDR(r3, __argc) 104 LOAD_REG_ADDR(r4, __argv) 105 LOAD_REG_ADDR(r5, __environ) 106 lwz r3, 0(r3) 107 bl main 108 bl exit 109 b halt 110 111.align 3 112p_stack: .llong stackptr 113p_toc: .llong tocptr 114p_dyn: .llong dynamic_start 115 116.text 117.align 3 118 119.globl hcall 120hcall: 121 sc 1 122 blr 123 124.globl halt 125halt: 1261: b 1b 127 128.globl enter_rtas 129enter_rtas: 130 LOAD_REG_ADDR(r11, rtas_entry) 131 ld r10, 0(r11) 132 133 cmpdi r10,0 134 bne external_rtas 135 136 /* Use H_RTAS directly */ 137 mr r4,r3 138 lis r3,KVMPPC_H_RTAS@h 139 ori r3,r3,KVMPPC_H_RTAS@l 140 b hcall 141 142external_rtas: 143 /* Use external RTAS blob */ 144 mflr r0 145 std r0, 16(r1) 146 147 LOAD_REG_ADDR(r11, rtas_return_loc) 148 mtlr r11 149 150 mfmsr r11 151 LOAD_REG_IMMEDIATE(r9, RTAS_MSR_MASK) 152 and r11, r11, r9 153 mtsrr0 r10 154 mtsrr1 r11 155 rfid 156 b . 157 158rtas_return_loc: 159 FIXUP_ENDIAN 160 ld r0, 16(r1) 161 mtlr r0 162 blr 163 164call_handler: 165 /* save context */ 166 167 /* GPRs */ 168 169 .irp i, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16 \ 170 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31 171 SAVE_GPR(\i, r1) 172 .endr 173 mfsprg1 r0 174 std r0,GPR1(r1) 175 176 /* lr, xer, ccr */ 177 178 mflr r0 179 std r0,_LINK(r1) 180 181 mfxer r0 182 std r0,_XER(r1) 183 184 mfcr r0 185 std r0,_CCR(r1) 186 187 /* nip and msr */ 188 189 mfsrr0 r0 190 std r0, _NIP(r1) 191 192 mfsrr1 r0 193 std r0, _MSR(r1) 194 195 /* restore TOC pointer */ 196 197 LOAD_REG_IMMEDIATE(r31, SPAPR_KERNEL_LOAD_ADDR) 198 ld r2, (p_toc - start)(r31) 199 200 /* FIXME: build stack frame */ 201 202 /* call generic handler */ 203 204 addi r3,r1,STACK_FRAME_OVERHEAD 205 bl do_handle_exception 206 207 /* restore context */ 208 209 ld r0,_CTR(r1) 210 mtctr r0 211 212 ld r0,_LINK(r1) 213 mtlr r0 214 215 ld r0,_XER(r1) 216 mtxer r0 217 218 ld r0,_CCR(r1) 219 mtcr r0 220 221 ld r0, _NIP(r1) 222 mtsrr0 r0 223 224 ld r0, _MSR(r1) 225 mtsrr1 r0 226 227 .irp i, 0, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16 \ 228 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31 229 REST_GPR(\i, r1) 230 .endr 231 232 /* restore r1, as we don't need it anymore */ 233 234 REST_GPR(1,r1) 235 236 rfid 237 b . 238 239.section .text.ex 240 241.macro VECTOR vec 242 . = \vec 243 244 mtsprg1 r1 /* save r1 */ 245 mfsprg0 r1 /* get exception stack address */ 246 subi r1,r1, INT_FRAME_SIZE 247 248 /* save r0 and ctr to call generic handler */ 249 250 SAVE_GPR(0,r1) 251 252 mfctr r0 253 std r0,_CTR(r1) 254 255 ld r0, P_HANDLER(0) 256 mtctr r0 257 258 li r0,\vec 259 std r0,_TRAP(r1) 260 261 bctr 262.endm 263 264 . = 0x100 265 .globl __start_interrupts 266__start_interrupts: 267 268VECTOR(0x100) 269VECTOR(0x200) 270VECTOR(0x300) 271VECTOR(0x400) 272VECTOR(0x500) 273VECTOR(0x600) 274VECTOR(0x700) 275VECTOR(0x800) 276VECTOR(0x900) 277 278 .align 7 279 .globl __end_interrupts 280__end_interrupts: 281 .org P_HANDLER 282 .llong 0 283