18c2ecf20Sopenharmony_ci/* SPDX-License-Identifier: GPL-2.0 */
28c2ecf20Sopenharmony_ci#ifndef __ASM_SH_SYSCALL_32_H
38c2ecf20Sopenharmony_ci#define __ASM_SH_SYSCALL_32_H
48c2ecf20Sopenharmony_ci
58c2ecf20Sopenharmony_ci#include <uapi/linux/audit.h>
68c2ecf20Sopenharmony_ci#include <linux/kernel.h>
78c2ecf20Sopenharmony_ci#include <linux/sched.h>
88c2ecf20Sopenharmony_ci#include <linux/err.h>
98c2ecf20Sopenharmony_ci#include <asm/ptrace.h>
108c2ecf20Sopenharmony_ci
118c2ecf20Sopenharmony_ci/* The system call number is given by the user in R3 */
128c2ecf20Sopenharmony_cistatic inline long syscall_get_nr(struct task_struct *task,
138c2ecf20Sopenharmony_ci				  struct pt_regs *regs)
148c2ecf20Sopenharmony_ci{
158c2ecf20Sopenharmony_ci	return (regs->tra >= 0) ? regs->regs[3] : -1L;
168c2ecf20Sopenharmony_ci}
178c2ecf20Sopenharmony_ci
188c2ecf20Sopenharmony_cistatic inline void syscall_rollback(struct task_struct *task,
198c2ecf20Sopenharmony_ci				    struct pt_regs *regs)
208c2ecf20Sopenharmony_ci{
218c2ecf20Sopenharmony_ci	/*
228c2ecf20Sopenharmony_ci	 * XXX: This needs some thought. On SH we don't
238c2ecf20Sopenharmony_ci	 * save away the original r0 value anywhere.
248c2ecf20Sopenharmony_ci	 */
258c2ecf20Sopenharmony_ci}
268c2ecf20Sopenharmony_ci
278c2ecf20Sopenharmony_cistatic inline long syscall_get_error(struct task_struct *task,
288c2ecf20Sopenharmony_ci				     struct pt_regs *regs)
298c2ecf20Sopenharmony_ci{
308c2ecf20Sopenharmony_ci	return IS_ERR_VALUE(regs->regs[0]) ? regs->regs[0] : 0;
318c2ecf20Sopenharmony_ci}
328c2ecf20Sopenharmony_ci
338c2ecf20Sopenharmony_cistatic inline long syscall_get_return_value(struct task_struct *task,
348c2ecf20Sopenharmony_ci					    struct pt_regs *regs)
358c2ecf20Sopenharmony_ci{
368c2ecf20Sopenharmony_ci	return regs->regs[0];
378c2ecf20Sopenharmony_ci}
388c2ecf20Sopenharmony_ci
398c2ecf20Sopenharmony_cistatic inline void syscall_set_return_value(struct task_struct *task,
408c2ecf20Sopenharmony_ci					    struct pt_regs *regs,
418c2ecf20Sopenharmony_ci					    int error, long val)
428c2ecf20Sopenharmony_ci{
438c2ecf20Sopenharmony_ci	regs->regs[0] = (long) error ?: val;
448c2ecf20Sopenharmony_ci}
458c2ecf20Sopenharmony_ci
468c2ecf20Sopenharmony_cistatic inline void syscall_get_arguments(struct task_struct *task,
478c2ecf20Sopenharmony_ci					 struct pt_regs *regs,
488c2ecf20Sopenharmony_ci					 unsigned long *args)
498c2ecf20Sopenharmony_ci{
508c2ecf20Sopenharmony_ci
518c2ecf20Sopenharmony_ci	/* Argument pattern is: R4, R5, R6, R7, R0, R1 */
528c2ecf20Sopenharmony_ci	args[5] = regs->regs[1];
538c2ecf20Sopenharmony_ci	args[4] = regs->regs[0];
548c2ecf20Sopenharmony_ci	args[3] = regs->regs[7];
558c2ecf20Sopenharmony_ci	args[2] = regs->regs[6];
568c2ecf20Sopenharmony_ci	args[1] = regs->regs[5];
578c2ecf20Sopenharmony_ci	args[0] = regs->regs[4];
588c2ecf20Sopenharmony_ci}
598c2ecf20Sopenharmony_ci
608c2ecf20Sopenharmony_cistatic inline void syscall_set_arguments(struct task_struct *task,
618c2ecf20Sopenharmony_ci					 struct pt_regs *regs,
628c2ecf20Sopenharmony_ci					 const unsigned long *args)
638c2ecf20Sopenharmony_ci{
648c2ecf20Sopenharmony_ci	regs->regs[1] = args[5];
658c2ecf20Sopenharmony_ci	regs->regs[0] = args[4];
668c2ecf20Sopenharmony_ci	regs->regs[7] = args[3];
678c2ecf20Sopenharmony_ci	regs->regs[6] = args[2];
688c2ecf20Sopenharmony_ci	regs->regs[5] = args[1];
698c2ecf20Sopenharmony_ci	regs->regs[4] = args[0];
708c2ecf20Sopenharmony_ci}
718c2ecf20Sopenharmony_ci
728c2ecf20Sopenharmony_cistatic inline int syscall_get_arch(struct task_struct *task)
738c2ecf20Sopenharmony_ci{
748c2ecf20Sopenharmony_ci	int arch = AUDIT_ARCH_SH;
758c2ecf20Sopenharmony_ci
768c2ecf20Sopenharmony_ci#ifdef CONFIG_CPU_LITTLE_ENDIAN
778c2ecf20Sopenharmony_ci	arch |= __AUDIT_ARCH_LE;
788c2ecf20Sopenharmony_ci#endif
798c2ecf20Sopenharmony_ci	return arch;
808c2ecf20Sopenharmony_ci}
818c2ecf20Sopenharmony_ci#endif /* __ASM_SH_SYSCALL_32_H */
82