LCOV - code coverage report
Current view: top level - zephyr/arch/xtensa - syscall.h Hit Total Coverage
Test: new.info Lines: 2 10 20.0 %
Date: 2024-12-22 00:14:23

          Line data    Source code
       1           1 : /*
       2             :  * Copyright (c) 2022 Intel Corporation.
       3             :  *
       4             :  * SPDX-License-Identifier: Apache-2.0
       5             :  */
       6             : 
       7             : /**
       8             :  * @file
       9             :  * @brief Xtensa specific syscall header
      10             :  *
      11             :  * This header contains the Xtensa specific syscall interface.  It is
      12             :  * included by the syscall interface architecture-abstraction header
      13             :  * (include/arch/syscall.h)
      14             :  */
      15             : 
      16             : #ifndef ZEPHYR_INCLUDE_ARCH_XTENSA_SYSCALL_H_
      17             : #define ZEPHYR_INCLUDE_ARCH_XTENSA_SYSCALL_H_
      18             : 
      19             : #ifdef CONFIG_USERSPACE
      20             : #ifndef _ASMLANGUAGE
      21             : 
      22             : #include <zephyr/types.h>
      23             : #include <stdbool.h>
      24             : #include <zephyr/linker/sections.h>
      25             : #include <zephyr/sys/util_macro.h>
      26             : 
      27             : #include <xtensa/config/core-isa.h>
      28             : 
      29             : #ifdef __cplusplus
      30             : extern "C" {
      31             : #endif
      32             : 
      33             : #ifdef CONFIG_XTENSA_SYSCALL_USE_HELPER
      34             : uintptr_t xtensa_syscall_helper_args_6(uintptr_t arg1, uintptr_t arg2,
      35             :                                        uintptr_t arg3, uintptr_t arg4,
      36             :                                        uintptr_t arg5, uintptr_t arg6,
      37             :                                        uintptr_t call_id);
      38             : 
      39             : uintptr_t xtensa_syscall_helper_args_5(uintptr_t arg1, uintptr_t arg2,
      40             :                                        uintptr_t arg3, uintptr_t arg4,
      41             :                                        uintptr_t arg5, uintptr_t call_id);
      42             : 
      43             : uintptr_t xtensa_syscall_helper_args_4(uintptr_t arg1, uintptr_t arg2,
      44             :                                        uintptr_t arg3, uintptr_t arg4,
      45             :                                        uintptr_t call_id);
      46             : 
      47             : #define SYSINL ALWAYS_INLINE
      48             : #else
      49           0 : #define SYSINL inline
      50             : #endif /* CONFIG_XTENSA_SYSCALL_USE_HELPER */
      51             : 
      52             : /**
      53             :  * We are following Linux Xtensa syscall ABI:
      54             :  *
      55             :  *  syscall number     arg1, arg2, arg3, arg4, arg5, arg6
      56             :  *  --------------     ----------------------------------
      57             :  *  a2                 a6,   a3,   a4,   a5,   a8,   a9
      58             :  *
      59             :  **/
      60             : 
      61             : 
      62           1 : static SYSINL uintptr_t arch_syscall_invoke6(uintptr_t arg1, uintptr_t arg2,
      63             :                                              uintptr_t arg3, uintptr_t arg4,
      64             :                                              uintptr_t arg5, uintptr_t arg6,
      65             :                                              uintptr_t call_id)
      66             : {
      67             : #ifdef CONFIG_XTENSA_SYSCALL_USE_HELPER
      68             :         return xtensa_syscall_helper_args_6(arg1, arg2, arg3, arg4, arg5, arg6, call_id);
      69             : #else
      70             :         register uintptr_t a2 __asm__("%a2") = call_id;
      71             :         register uintptr_t a6 __asm__("%a6") = arg1;
      72             :         register uintptr_t a3 __asm__("%a3") = arg2;
      73             :         register uintptr_t a4 __asm__("%a4") = arg3;
      74             :         register uintptr_t a5 __asm__("%a5") = arg4;
      75             :         register uintptr_t a8 __asm__("%a8") = arg5;
      76             :         register uintptr_t a9 __asm__("%a9") = arg6;
      77             : 
      78             :         __asm__ volatile("syscall\n\t"
      79             :                          : "=r" (a2)
      80             :                          : "r" (a2), "r" (a6), "r" (a3), "r" (a4),
      81             :                            "r" (a5), "r" (a8), "r" (a9)
      82             :                          : "memory");
      83             : 
      84             :         return a2;
      85             : #endif /* CONFIG_XTENSA_SYSCALL_USE_HELPER */
      86             : }
      87             : 
      88           0 : static SYSINL uintptr_t arch_syscall_invoke5(uintptr_t arg1, uintptr_t arg2,
      89             :                                              uintptr_t arg3, uintptr_t arg4,
      90             :                                              uintptr_t arg5, uintptr_t call_id)
      91             : {
      92             : #ifdef CONFIG_XTENSA_SYSCALL_USE_HELPER
      93             :         return xtensa_syscall_helper_args_5(arg1, arg2, arg3, arg4, arg5, call_id);
      94             : #else
      95             :         register uintptr_t a2 __asm__("%a2") = call_id;
      96             :         register uintptr_t a6 __asm__("%a6") = arg1;
      97             :         register uintptr_t a3 __asm__("%a3") = arg2;
      98             :         register uintptr_t a4 __asm__("%a4") = arg3;
      99             :         register uintptr_t a5 __asm__("%a5") = arg4;
     100             :         register uintptr_t a8 __asm__("%a8") = arg5;
     101             : 
     102             :         __asm__ volatile("syscall\n\t"
     103             :                          : "=r" (a2)
     104             :                          : "r" (a2), "r" (a6), "r" (a3), "r" (a4),
     105             :                            "r" (a5), "r" (a8)
     106             :                          : "memory");
     107             : 
     108             :         return a2;
     109             : #endif /* CONFIG_XTENSA_SYSCALL_USE_HELPER */
     110             : }
     111             : 
     112           0 : static SYSINL uintptr_t arch_syscall_invoke4(uintptr_t arg1, uintptr_t arg2,
     113             :                                              uintptr_t arg3, uintptr_t arg4,
     114             :                                              uintptr_t call_id)
     115             : {
     116             : #ifdef CONFIG_XTENSA_SYSCALL_USE_HELPER
     117             :         return xtensa_syscall_helper_args_4(arg1, arg2, arg3, arg4, call_id);
     118             : #else
     119             :         register uintptr_t a2 __asm__("%a2") = call_id;
     120             :         register uintptr_t a6 __asm__("%a6") = arg1;
     121             :         register uintptr_t a3 __asm__("%a3") = arg2;
     122             :         register uintptr_t a4 __asm__("%a4") = arg3;
     123             :         register uintptr_t a5 __asm__("%a5") = arg4;
     124             : 
     125             :         __asm__ volatile("syscall\n\t"
     126             :                          : "=r" (a2)
     127             :                          : "r" (a2), "r" (a6), "r" (a3), "r" (a4),
     128             :                            "r" (a5)
     129             :                          : "memory");
     130             : 
     131             :         return a2;
     132             : #endif /* CONFIG_XTENSA_SYSCALL_USE_HELPER */
     133             : }
     134             : 
     135           0 : static inline uintptr_t arch_syscall_invoke3(uintptr_t arg1, uintptr_t arg2,
     136             :                                              uintptr_t arg3, uintptr_t call_id)
     137             : {
     138             :         register uintptr_t a2 __asm__("%a2") = call_id;
     139             :         register uintptr_t a6 __asm__("%a6") = arg1;
     140             :         register uintptr_t a3 __asm__("%a3") = arg2;
     141             :         register uintptr_t a4 __asm__("%a4") = arg3;
     142             : 
     143             :         __asm__ volatile("syscall\n\t"
     144             :                          : "=r" (a2)
     145             :                          : "r" (a2), "r" (a6), "r" (a3), "r" (a4)
     146             :                          : "memory");
     147             : 
     148             :         return a2;
     149             : }
     150             : 
     151           0 : static inline uintptr_t arch_syscall_invoke2(uintptr_t arg1, uintptr_t arg2,
     152             :                                              uintptr_t call_id)
     153             : {
     154             :         register uintptr_t a2 __asm__("%a2") = call_id;
     155             :         register uintptr_t a6 __asm__("%a6") = arg1;
     156             :         register uintptr_t a3 __asm__("%a3") = arg2;
     157             : 
     158             :         __asm__ volatile("syscall\n\t"
     159             :                          : "=r" (a2)
     160             :                          : "r" (a2), "r" (a6), "r" (a3)
     161             :                          : "memory");
     162             : 
     163             :         return a2;
     164             : }
     165             : 
     166           0 : static inline uintptr_t arch_syscall_invoke1(uintptr_t arg1, uintptr_t call_id)
     167             : {
     168             :         register uintptr_t a2 __asm__("%a2") = call_id;
     169             :         register uintptr_t a6 __asm__("%a6") = arg1;
     170             : 
     171             :         __asm__ volatile("syscall\n\t"
     172             :                          : "=r" (a2)
     173             :                          : "r" (a2), "r" (a6)
     174             :                          : "memory");
     175             : 
     176             :         return a2;
     177             : }
     178             : 
     179           0 : static inline uintptr_t arch_syscall_invoke0(uintptr_t call_id)
     180             : {
     181             :         register uintptr_t a2 __asm__("%a2") = call_id;
     182             : 
     183             :         __asm__ volatile("syscall\n\t"
     184             :                          : "=r" (a2)
     185             :                          : "r" (a2)
     186             :                          : "memory");
     187             : 
     188             :         return a2;
     189             : }
     190             : 
     191             : /*
     192             :  * There is no easy (or generic) way to figure out if a thread is runnining
     193             :  * in un-privileged mode. Reading the current ring (PS.CRING) is a privileged
     194             :  * instruction and not thread local storage is not available in xcc.
     195             :  */
     196           0 : static inline bool arch_is_user_context(void)
     197             : {
     198             : #if XCHAL_HAVE_THREADPTR
     199             :         uint32_t thread;
     200             : 
     201             :         __asm__ volatile(
     202             :                 "rur.THREADPTR %0\n\t"
     203             :                 : "=a" (thread)
     204             :         );
     205             : #ifdef CONFIG_THREAD_LOCAL_STORAGE
     206             :         extern Z_THREAD_LOCAL uint32_t is_user_mode;
     207             : 
     208             :         if (!thread) {
     209             :                 return false;
     210             :         }
     211             : 
     212             :         return is_user_mode != 0;
     213             : #else
     214             :         return !!thread;
     215             : #endif
     216             : 
     217             : #else /* XCHAL_HAVE_THREADPTR */
     218             :         extern bool xtensa_is_user_context(void);
     219             : 
     220             :         return xtensa_is_user_context();
     221             : #endif /* XCHAL_HAVE_THREADPTR */
     222             : }
     223             : 
     224             : #undef SYSINL
     225             : 
     226             : #ifdef __cplusplus
     227             : }
     228             : #endif
     229             : 
     230             : #endif /* _ASMLANGUAGE */
     231             : #endif /* CONFIG_USERSPACE */
     232             : #endif /* ZEPHYR_INCLUDE_ARCH_XTENSA_SYSCALL_H_ */

Generated by: LCOV version 1.14