1/* 2 * PowerPC linux replacement vdso. 3 * 4 * Copyright 2023 Linaro, Ltd. 5 * 6 * SPDX-License-Identifier: GPL-2.0-or-later 7 */ 8 9#include <asm/unistd.h> 10#include <asm/errno.h> 11 12#ifndef _ARCH_PPC64 13# define TARGET_ABI32 14#endif 15#include "vdso-asmoffset.h" 16 17 18 .text 19 20.macro endf name 21 .globl \name 22 .size \name, .-\name 23 /* For PPC64, functions have special linkage; we export pointers. */ 24#ifndef _ARCH_PPC64 25 .type \name, @function 26#endif 27.endm 28 29.macro raw_syscall nr 30 addi 0, 0, \nr 31 sc 32.endm 33 34.macro vdso_syscall name, nr 35\name: 36 raw_syscall \nr 37 blr 38endf \name 39.endm 40 41 .cfi_startproc 42 43vdso_syscall __kernel_gettimeofday, __NR_gettimeofday 44vdso_syscall __kernel_clock_gettime, __NR_clock_gettime 45vdso_syscall __kernel_clock_getres, __NR_clock_getres 46vdso_syscall __kernel_getcpu, __NR_getcpu 47vdso_syscall __kernel_time, __NR_time 48 49#ifdef __NR_clock_gettime64 50vdso_syscall __kernel_clock_gettime64, __NR_clock_gettime64 51#endif 52 53__kernel_sync_dicache: 54 /* qemu does not need to flush caches */ 55 blr 56endf __kernel_sync_dicache 57 58 .cfi_endproc 59 60/* 61 * TODO: __kernel_get_tbfreq 62 * This is probably a constant for QEMU. 63 */ 64 65/* 66 * Start the unwind info at least one instruction before the signal 67 * trampoline, because the unwinder will assume we are returning 68 * after a call site. 69 */ 70 71 .cfi_startproc simple 72 .cfi_signal_frame 73 74#ifdef _ARCH_PPC64 75# define __kernel_sigtramp_rt __kernel_sigtramp_rt64 76# define sizeof_reg 8 77#else 78# define __kernel_sigtramp_rt __kernel_sigtramp_rt32 79# define sizeof_reg 4 80#endif 81#define sizeof_freg 8 82#define sizeof_vreg 16 83 84 .cfi_def_cfa 1, SIGNAL_FRAMESIZE + offsetof_rt_sigframe_mcontext 85 86 /* Return address */ 87 .cfi_return_column 67 88 .cfi_offset 67, 32 * sizeof_reg /* nip */ 89 90 /* Integer registers */ 91 .cfi_offset 0, 0 * sizeof_reg 92 .cfi_offset 1, 1 * sizeof_reg 93 .cfi_offset 2, 2 * sizeof_reg 94 .cfi_offset 3, 3 * sizeof_reg 95 .cfi_offset 4, 4 * sizeof_reg 96 .cfi_offset 5, 5 * sizeof_reg 97 .cfi_offset 6, 6 * sizeof_reg 98 .cfi_offset 7, 7 * sizeof_reg 99 .cfi_offset 8, 8 * sizeof_reg 100 .cfi_offset 9, 9 * sizeof_reg 101 .cfi_offset 10, 10 * sizeof_reg 102 .cfi_offset 11, 11 * sizeof_reg 103 .cfi_offset 12, 12 * sizeof_reg 104 .cfi_offset 13, 13 * sizeof_reg 105 .cfi_offset 14, 14 * sizeof_reg 106 .cfi_offset 15, 15 * sizeof_reg 107 .cfi_offset 16, 16 * sizeof_reg 108 .cfi_offset 17, 17 * sizeof_reg 109 .cfi_offset 18, 18 * sizeof_reg 110 .cfi_offset 19, 19 * sizeof_reg 111 .cfi_offset 20, 20 * sizeof_reg 112 .cfi_offset 21, 21 * sizeof_reg 113 .cfi_offset 22, 22 * sizeof_reg 114 .cfi_offset 23, 23 * sizeof_reg 115 .cfi_offset 24, 24 * sizeof_reg 116 .cfi_offset 25, 25 * sizeof_reg 117 .cfi_offset 26, 26 * sizeof_reg 118 .cfi_offset 27, 27 * sizeof_reg 119 .cfi_offset 28, 28 * sizeof_reg 120 .cfi_offset 29, 29 * sizeof_reg 121 .cfi_offset 30, 30 * sizeof_reg 122 .cfi_offset 31, 31 * sizeof_reg 123 .cfi_offset 65, 36 * sizeof_reg /* lr */ 124 .cfi_offset 70, 38 * sizeof_reg /* ccr */ 125 126 /* Floating point registers */ 127 .cfi_offset 32, offsetof_mcontext_fregs 128 .cfi_offset 33, offsetof_mcontext_fregs + 1 * sizeof_freg 129 .cfi_offset 34, offsetof_mcontext_fregs + 2 * sizeof_freg 130 .cfi_offset 35, offsetof_mcontext_fregs + 3 * sizeof_freg 131 .cfi_offset 36, offsetof_mcontext_fregs + 4 * sizeof_freg 132 .cfi_offset 37, offsetof_mcontext_fregs + 5 * sizeof_freg 133 .cfi_offset 38, offsetof_mcontext_fregs + 6 * sizeof_freg 134 .cfi_offset 39, offsetof_mcontext_fregs + 7 * sizeof_freg 135 .cfi_offset 40, offsetof_mcontext_fregs + 8 * sizeof_freg 136 .cfi_offset 41, offsetof_mcontext_fregs + 9 * sizeof_freg 137 .cfi_offset 42, offsetof_mcontext_fregs + 10 * sizeof_freg 138 .cfi_offset 43, offsetof_mcontext_fregs + 11 * sizeof_freg 139 .cfi_offset 44, offsetof_mcontext_fregs + 12 * sizeof_freg 140 .cfi_offset 45, offsetof_mcontext_fregs + 13 * sizeof_freg 141 .cfi_offset 46, offsetof_mcontext_fregs + 14 * sizeof_freg 142 .cfi_offset 47, offsetof_mcontext_fregs + 15 * sizeof_freg 143 .cfi_offset 48, offsetof_mcontext_fregs + 16 * sizeof_freg 144 .cfi_offset 49, offsetof_mcontext_fregs + 17 * sizeof_freg 145 .cfi_offset 50, offsetof_mcontext_fregs + 18 * sizeof_freg 146 .cfi_offset 51, offsetof_mcontext_fregs + 19 * sizeof_freg 147 .cfi_offset 52, offsetof_mcontext_fregs + 20 * sizeof_freg 148 .cfi_offset 53, offsetof_mcontext_fregs + 21 * sizeof_freg 149 .cfi_offset 54, offsetof_mcontext_fregs + 22 * sizeof_freg 150 .cfi_offset 55, offsetof_mcontext_fregs + 23 * sizeof_freg 151 .cfi_offset 56, offsetof_mcontext_fregs + 24 * sizeof_freg 152 .cfi_offset 57, offsetof_mcontext_fregs + 25 * sizeof_freg 153 .cfi_offset 58, offsetof_mcontext_fregs + 26 * sizeof_freg 154 .cfi_offset 59, offsetof_mcontext_fregs + 27 * sizeof_freg 155 .cfi_offset 60, offsetof_mcontext_fregs + 28 * sizeof_freg 156 .cfi_offset 61, offsetof_mcontext_fregs + 29 * sizeof_freg 157 .cfi_offset 62, offsetof_mcontext_fregs + 30 * sizeof_freg 158 .cfi_offset 63, offsetof_mcontext_fregs + 31 * sizeof_freg 159 160 /* 161 * Unlike the kernel, unconditionally represent the Altivec/VSX regs. 162 * The space within the stack frame is always available, and most of 163 * our supported processors have them enabled. The only complication 164 * for PPC64 is the misalignment, so that we have to use indirection. 165 */ 166.macro save_vreg_ofs reg, ofs 167#ifdef _ARCH_PPC64 168 /* 169 * vreg = *(cfa + offsetof(v_regs)) + ofs 170 * 171 * The CFA is input to the expression on the stack, so: 172 * DW_CFA_expression reg, length (7), 173 * DW_OP_plus_uconst (0x23), vreg_ptr, DW_OP_deref (0x06), 174 * DW_OP_plus_uconst (0x23), ofs 175 */ 176 .cfi_escape 0x10, 77 + \reg, 7, 0x23, (offsetof_mcontext_vregs_ptr & 0x7f) + 0x80, offsetof_mcontext_vregs_ptr >> 7, 0x06, 0x23, (\ofs & 0x7f) | 0x80, \ofs >> 7 177#else 178 .cfi_offset 77 + \reg, offsetof_mcontext_vregs + \ofs 179#endif 180.endm 181 182.macro save_vreg reg 183 save_vreg_ofs \reg, (\reg * sizeof_vreg) 184.endm 185 186 save_vreg 0 187 save_vreg 1 188 save_vreg 2 189 save_vreg 3 190 save_vreg 4 191 save_vreg 5 192 save_vreg 6 193 save_vreg 7 194 save_vreg 8 195 save_vreg 9 196 save_vreg 10 197 save_vreg 11 198 save_vreg 12 199 save_vreg 13 200 save_vreg 14 201 save_vreg 15 202 save_vreg 16 203 save_vreg 17 204 save_vreg 18 205 save_vreg 19 206 save_vreg 20 207 save_vreg 21 208 save_vreg 22 209 save_vreg 23 210 save_vreg 24 211 save_vreg 25 212 save_vreg 26 213 save_vreg 27 214 save_vreg 28 215 save_vreg 29 216 save_vreg 30 217 save_vreg 31 218 save_vreg 32 219 save_vreg_ofs 33, (32 * sizeof_vreg + 12) 220 221 nop 222 223__kernel_sigtramp_rt: 224 raw_syscall __NR_rt_sigreturn 225endf __kernel_sigtramp_rt 226 227#ifndef _ARCH_PPC64 228 /* 229 * The non-rt sigreturn has the same layout at a different offset. 230 * Move the CFA and leave all othe other descriptions the same. 231 */ 232 .cfi_def_cfa 1, SIGNAL_FRAMESIZE + offsetof_sigframe_mcontext 233 nop 234__kernel_sigtramp32: 235 raw_syscall __NR_sigreturn 236endf __kernel_sigtramp32 237#endif 238 239 .cfi_endproc 240