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(r5, __argc) 98 LOAD_REG_ADDR(r4, __argv) 99 lwz r3, 0(r5) 100 bl main 101 bl exit 102 b halt 103 104.align 3 105p_stack: .llong stackptr 106p_toc: .llong tocptr 107p_dyn: .llong dynamic_start 108 109.text 110.align 3 111 112.globl hcall 113hcall: 114 sc 1 115 blr 116 117.globl halt 118halt: 1191: b 1b 120 121.globl enter_rtas 122enter_rtas: 123 mflr r0 124 std r0, 16(r1) 125 126 LOAD_REG_ADDR(r10, rtas_return_loc) 127 mtlr r10 128 LOAD_REG_ADDR(r11, rtas_entry) 129 ld r10, 0(r11) 130 131 mfmsr r11 132 LOAD_REG_IMMEDIATE(r9, RTAS_MSR_MASK) 133 and r11, r11, r9 134 mtsrr0 r10 135 mtsrr1 r11 136 rfid 137 b . 138 139rtas_return_loc: 140 FIXUP_ENDIAN 141 ld r0, 16(r1) 142 mtlr r0 143 blr 144 145call_handler: 146 /* save context */ 147 148 /* GPRs */ 149 150 .irp i, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16 \ 151 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31 152 SAVE_GPR(\i, r1) 153 .endr 154 mfsprg1 r0 155 std r0,GPR1(r1) 156 157 /* lr, xer, ccr */ 158 159 mflr r0 160 std r0,_LINK(r1) 161 162 mfxer r0 163 std r0,_XER(r1) 164 165 mfcr r0 166 std r0,_CCR(r1) 167 168 /* nip and msr */ 169 170 mfsrr0 r0 171 std r0, _NIP(r1) 172 173 mfsrr1 r0 174 std r0, _MSR(r1) 175 176 /* restore TOC pointer */ 177 178 LOAD_REG_IMMEDIATE(r31, SPAPR_KERNEL_LOAD_ADDR) 179 ld r2, (p_toc - start)(r31) 180 181 /* FIXME: build stack frame */ 182 183 /* call generic handler */ 184 185 addi r3,r1,STACK_FRAME_OVERHEAD 186 bl do_handle_exception 187 188 /* restore context */ 189 190 ld r0,_CTR(r1) 191 mtctr r0 192 193 ld r0,_LINK(r1) 194 mtlr r0 195 196 ld r0,_XER(r1) 197 mtxer r0 198 199 ld r0,_CCR(r1) 200 mtcr r0 201 202 ld r0, _NIP(r1) 203 mtsrr0 r0 204 205 ld r0, _MSR(r1) 206 mtsrr1 r0 207 208 .irp i, 0, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16 \ 209 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31 210 REST_GPR(\i, r1) 211 .endr 212 213 /* restore r1, as we don't need it anymore */ 214 215 REST_GPR(1,r1) 216 217 rfid 218 b . 219 220.section .text.ex 221 222.macro VECTOR vec 223 . = \vec 224 225 mtsprg1 r1 /* save r1 */ 226 mfsprg0 r1 /* get exception stack address */ 227 subi r1,r1, INT_FRAME_SIZE 228 229 /* save r0 and ctr to call generic handler */ 230 231 SAVE_GPR(0,r1) 232 233 mfctr r0 234 std r0,_CTR(r1) 235 236 ld r0, P_HANDLER(0) 237 mtctr r0 238 239 li r0,\vec 240 std r0,_TRAP(r1) 241 242 bctr 243.endm 244 245 . = 0x100 246 .globl __start_interrupts 247__start_interrupts: 248 249VECTOR(0x300) 250VECTOR(0x400) 251VECTOR(0x500) 252VECTOR(0x600) 253VECTOR(0x700) 254VECTOR(0x800) 255VECTOR(0x900) 256 257 .align 7 258 .globl __end_interrupts 259__end_interrupts: 260 .org P_HANDLER 261 .llong 0 262