1/* 2 * Copyright (c) 2020 Carlo Caione <ccaione@baylibre.com> 3 * 4 * SPDX-License-Identifier: Apache-2.0 5 */ 6 7#include <zephyr/toolchain.h> 8#include <zephyr/linker/sections.h> 9#include <offsets_short.h> 10#include <zephyr/arch/cpu.h> 11#include <zephyr/syscall.h> 12#include <zephyr/arch/arm64/mm.h> 13#include "macro_priv.inc" 14 15_ASM_FILE_PROLOGUE 16 17/* 18 * size_t arch_user_string_nlen(const char *s, size_t maxsize, int *err_arg) 19 */ 20 21GTEXT(z_arm64_user_string_nlen_fault_start) 22GTEXT(z_arm64_user_string_nlen_fault_end) 23GTEXT(z_arm64_user_string_nlen_fixup) 24 25GTEXT(arch_user_string_nlen) 26SECTION_FUNC(TEXT, arch_user_string_nlen) 27 28 mov x3, x0 29 mov x0, #0 30 mov x4, #0 31 32strlen_loop: 33 34 cmp x0, x1 35 beq strlen_done 36 37z_arm64_user_string_nlen_fault_start: 38 ldrb w5, [x3, x0] 39z_arm64_user_string_nlen_fault_end: 40 cbz x5, strlen_done 41 42 add x0, x0, #1 43 b strlen_loop 44 45z_arm64_user_string_nlen_fixup: 46 mov x4, #-1 47 mov x0, #0 48 49strlen_done: 50 str w4, [x2] 51 ret 52 53/* 54 * int arch_buffer_validate(const void *addr, size_t size, int write) 55 */ 56 57GTEXT(arch_buffer_validate) 58SECTION_FUNC(TEXT, arch_buffer_validate) 59 60 add x1, x1, x0 61 mrs x3, DAIF 62 msr DAIFSET, #DAIFSET_IRQ_BIT 63 64abv_loop: 65 cbnz w2, 1f 66 at S1E0R, x0 67 b 2f 681: at S1E0W, x0 69 702: orr x0, x0, #(MEM_DOMAIN_ALIGN_AND_SIZE - 1) 71 add x0, x0, #1 72 73 isb 74 mrs x4, PAR_EL1 75 tbnz x4, #0, abv_fail 76 77 cmp x0, x1 78 blo abv_loop 79 80 msr DAIF, x3 81 mov x0, #0 82 ret 83 84abv_fail: 85 msr DAIF, x3 86 mov x0, #-1 87 ret 88 89/* 90 * System call entry point. 91 */ 92 93GTEXT(z_arm64_do_syscall) 94SECTION_FUNC(TEXT, z_arm64_do_syscall) 95 /* Recover the syscall parameters from the ESF */ 96 ldp x0, x1, [sp, ___esf_t_x0_x1_OFFSET] 97 ldp x2, x3, [sp, ___esf_t_x2_x3_OFFSET] 98 ldp x4, x5, [sp, ___esf_t_x4_x5_OFFSET] 99 100 /* Use the ESF as SSF */ 101 mov x6, sp 102 103 /* Recover the syscall ID */ 104 ldr x8, [sp, ___esf_t_x8_x9_OFFSET] 105 106 /* Check whether the ID is valid */ 107 ldr x9, =K_SYSCALL_LIMIT 108 cmp x8, x9 109 blo valid_syscall_id 110 111 /* Save the bad ID for handler_bad_syscall() */ 112 mov x0, x8 113 ldr x8, =K_SYSCALL_BAD 114 115valid_syscall_id: 116 ldr x9, =_k_syscall_table 117 ldr x9, [x9, x8, lsl #3] 118 119 /* Jump into the syscall */ 120 msr daifclr, #(DAIFSET_IRQ_BIT) 121 blr x9 122 msr daifset, #(DAIFSET_IRQ_BIT) 123 124 /* Save the return value into the ESF */ 125 str x0, [sp, ___esf_t_x0_x1_OFFSET] 126 127 /* Return from exception */ 128 b z_arm64_exit_exc 129