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