162306a36Sopenharmony_ci/* SPDX-License-Identifier: GPL-2.0 */
262306a36Sopenharmony_ci#ifndef __ASM_SH_SYSCALL_32_H
362306a36Sopenharmony_ci#define __ASM_SH_SYSCALL_32_H
462306a36Sopenharmony_ci
562306a36Sopenharmony_ci#include <uapi/linux/audit.h>
662306a36Sopenharmony_ci#include <linux/kernel.h>
762306a36Sopenharmony_ci#include <linux/sched.h>
862306a36Sopenharmony_ci#include <linux/err.h>
962306a36Sopenharmony_ci#include <asm/ptrace.h>
1062306a36Sopenharmony_ci
1162306a36Sopenharmony_ci/* The system call number is given by the user in R3 */
1262306a36Sopenharmony_cistatic inline long syscall_get_nr(struct task_struct *task,
1362306a36Sopenharmony_ci				  struct pt_regs *regs)
1462306a36Sopenharmony_ci{
1562306a36Sopenharmony_ci	return (regs->tra >= 0) ? regs->regs[3] : -1L;
1662306a36Sopenharmony_ci}
1762306a36Sopenharmony_ci
1862306a36Sopenharmony_cistatic inline void syscall_rollback(struct task_struct *task,
1962306a36Sopenharmony_ci				    struct pt_regs *regs)
2062306a36Sopenharmony_ci{
2162306a36Sopenharmony_ci	/*
2262306a36Sopenharmony_ci	 * XXX: This needs some thought. On SH we don't
2362306a36Sopenharmony_ci	 * save away the original r0 value anywhere.
2462306a36Sopenharmony_ci	 */
2562306a36Sopenharmony_ci}
2662306a36Sopenharmony_ci
2762306a36Sopenharmony_cistatic inline long syscall_get_error(struct task_struct *task,
2862306a36Sopenharmony_ci				     struct pt_regs *regs)
2962306a36Sopenharmony_ci{
3062306a36Sopenharmony_ci	return IS_ERR_VALUE(regs->regs[0]) ? regs->regs[0] : 0;
3162306a36Sopenharmony_ci}
3262306a36Sopenharmony_ci
3362306a36Sopenharmony_cistatic inline long syscall_get_return_value(struct task_struct *task,
3462306a36Sopenharmony_ci					    struct pt_regs *regs)
3562306a36Sopenharmony_ci{
3662306a36Sopenharmony_ci	return regs->regs[0];
3762306a36Sopenharmony_ci}
3862306a36Sopenharmony_ci
3962306a36Sopenharmony_cistatic inline void syscall_set_return_value(struct task_struct *task,
4062306a36Sopenharmony_ci					    struct pt_regs *regs,
4162306a36Sopenharmony_ci					    int error, long val)
4262306a36Sopenharmony_ci{
4362306a36Sopenharmony_ci	regs->regs[0] = (long) error ?: val;
4462306a36Sopenharmony_ci}
4562306a36Sopenharmony_ci
4662306a36Sopenharmony_cistatic inline void syscall_get_arguments(struct task_struct *task,
4762306a36Sopenharmony_ci					 struct pt_regs *regs,
4862306a36Sopenharmony_ci					 unsigned long *args)
4962306a36Sopenharmony_ci{
5062306a36Sopenharmony_ci
5162306a36Sopenharmony_ci	/* Argument pattern is: R4, R5, R6, R7, R0, R1 */
5262306a36Sopenharmony_ci	args[5] = regs->regs[1];
5362306a36Sopenharmony_ci	args[4] = regs->regs[0];
5462306a36Sopenharmony_ci	args[3] = regs->regs[7];
5562306a36Sopenharmony_ci	args[2] = regs->regs[6];
5662306a36Sopenharmony_ci	args[1] = regs->regs[5];
5762306a36Sopenharmony_ci	args[0] = regs->regs[4];
5862306a36Sopenharmony_ci}
5962306a36Sopenharmony_ci
6062306a36Sopenharmony_cistatic inline int syscall_get_arch(struct task_struct *task)
6162306a36Sopenharmony_ci{
6262306a36Sopenharmony_ci	int arch = AUDIT_ARCH_SH;
6362306a36Sopenharmony_ci
6462306a36Sopenharmony_ci#ifdef CONFIG_CPU_LITTLE_ENDIAN
6562306a36Sopenharmony_ci	arch |= __AUDIT_ARCH_LE;
6662306a36Sopenharmony_ci#endif
6762306a36Sopenharmony_ci	return arch;
6862306a36Sopenharmony_ci}
6962306a36Sopenharmony_ci#endif /* __ASM_SH_SYSCALL_32_H */
70