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