syscall.h 2.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105
  1. /*
  2. * Copyright (C) 2008-2009 Red Hat, Inc. All rights reserved.
  3. * Copyright 2010 Tilera Corporation. All Rights Reserved.
  4. * Copyright 2015 Regents of the University of California, Berkeley
  5. *
  6. * This program is free software; you can redistribute it and/or
  7. * modify it under the terms of the GNU General Public License
  8. * as published by the Free Software Foundation, version 2.
  9. *
  10. * This program is distributed in the hope that it will be useful,
  11. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  12. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  13. * GNU General Public License for more details.
  14. *
  15. * See asm-generic/syscall.h for descriptions of what we must do here.
  16. */
  17. #ifndef _ASM_RISCV_SYSCALL_H
  18. #define _ASM_RISCV_SYSCALL_H
  19. #include <linux/sched.h>
  20. #include <linux/err.h>
  21. /* The array of function pointers for syscalls. */
  22. extern void *sys_call_table[];
  23. /*
  24. * Only the low 32 bits of orig_r0 are meaningful, so we return int.
  25. * This importantly ignores the high bits on 64-bit, so comparisons
  26. * sign-extend the low 32 bits.
  27. */
  28. static inline int syscall_get_nr(struct task_struct *task,
  29. struct pt_regs *regs)
  30. {
  31. return regs->a7;
  32. }
  33. static inline void syscall_set_nr(struct task_struct *task,
  34. struct pt_regs *regs,
  35. int sysno)
  36. {
  37. regs->a7 = sysno;
  38. }
  39. static inline void syscall_rollback(struct task_struct *task,
  40. struct pt_regs *regs)
  41. {
  42. regs->a0 = regs->orig_a0;
  43. }
  44. static inline long syscall_get_error(struct task_struct *task,
  45. struct pt_regs *regs)
  46. {
  47. unsigned long error = regs->a0;
  48. return IS_ERR_VALUE(error) ? error : 0;
  49. }
  50. static inline long syscall_get_return_value(struct task_struct *task,
  51. struct pt_regs *regs)
  52. {
  53. return regs->a0;
  54. }
  55. static inline void syscall_set_return_value(struct task_struct *task,
  56. struct pt_regs *regs,
  57. int error, long val)
  58. {
  59. regs->a0 = (long) error ?: val;
  60. }
  61. static inline void syscall_get_arguments(struct task_struct *task,
  62. struct pt_regs *regs,
  63. unsigned int i, unsigned int n,
  64. unsigned long *args)
  65. {
  66. BUG_ON(i + n > 6);
  67. if (i == 0) {
  68. args[0] = regs->orig_a0;
  69. args++;
  70. n--;
  71. } else {
  72. i--;
  73. }
  74. memcpy(args, &regs->a1 + i, n * sizeof(args[0]));
  75. }
  76. static inline void syscall_set_arguments(struct task_struct *task,
  77. struct pt_regs *regs,
  78. unsigned int i, unsigned int n,
  79. const unsigned long *args)
  80. {
  81. BUG_ON(i + n > 6);
  82. if (i == 0) {
  83. regs->orig_a0 = args[0];
  84. args++;
  85. n--;
  86. } else {
  87. i--;
  88. }
  89. memcpy(&regs->a1 + i, args, n * sizeof(regs->a1));
  90. }
  91. #endif /* _ASM_RISCV_SYSCALL_H */