linux/arch/blackfin/include/asm/syscall.h
<<
>>
Prefs
   1/*
   2 * Magic syscall break down functions
   3 *
   4 * Copyright 2010 Analog Devices Inc.
   5 *
   6 * Licensed under the GPL-2 or later.
   7 */
   8
   9#ifndef __ASM_BLACKFIN_SYSCALL_H__
  10#define __ASM_BLACKFIN_SYSCALL_H__
  11
  12/*
  13 * Blackfin syscalls are simple:
  14 *      enter:
  15 *              p0: syscall number
  16 *              r{0,1,2,3,4,5}: syscall args 0,1,2,3,4,5
  17 *      exit:
  18 *              r0: return/error value
  19 */
  20
  21#include <linux/err.h>
  22#include <linux/sched.h>
  23#include <asm/ptrace.h>
  24
  25static inline long
  26syscall_get_nr(struct task_struct *task, struct pt_regs *regs)
  27{
  28        return regs->p0;
  29}
  30
  31static inline void
  32syscall_rollback(struct task_struct *task, struct pt_regs *regs)
  33{
  34        regs->p0 = regs->orig_p0;
  35}
  36
  37static inline long
  38syscall_get_error(struct task_struct *task, struct pt_regs *regs)
  39{
  40        return IS_ERR_VALUE(regs->r0) ? regs->r0 : 0;
  41}
  42
  43static inline long
  44syscall_get_return_value(struct task_struct *task, struct pt_regs *regs)
  45{
  46        return regs->r0;
  47}
  48
  49static inline void
  50syscall_set_return_value(struct task_struct *task, struct pt_regs *regs,
  51                         int error, long val)
  52{
  53        regs->r0 = error ? -error : val;
  54}
  55
  56/**
  57 *      syscall_get_arguments()
  58 *      @task:   unused
  59 *      @regs:   the register layout to extract syscall arguments from
  60 *      @i:      first syscall argument to extract
  61 *      @n:      number of syscall arguments to extract
  62 *      @args:   array to return the syscall arguments in
  63 *
  64 * args[0] gets i'th argument, args[n - 1] gets the i+n-1'th argument
  65 */
  66static inline void
  67syscall_get_arguments(struct task_struct *task, struct pt_regs *regs,
  68                      unsigned int i, unsigned int n, unsigned long *args)
  69{
  70        /*
  71         * Assume the ptrace layout doesn't change -- r5 is first in memory,
  72         * then r4, ..., then r0.  So we simply reverse the ptrace register
  73         * array in memory to store into the args array.
  74         */
  75        long *aregs = &regs->r0 - i;
  76
  77        BUG_ON(i > 5 || i + n > 6);
  78
  79        while (n--)
  80                *args++ = *aregs--;
  81}
  82
  83/* See syscall_get_arguments() comments */
  84static inline void
  85syscall_set_arguments(struct task_struct *task, struct pt_regs *regs,
  86                      unsigned int i, unsigned int n, const unsigned long *args)
  87{
  88        long *aregs = &regs->r0 - i;
  89
  90        BUG_ON(i > 5 || i + n > 6);
  91
  92        while (n--)
  93                *aregs-- = *args++;
  94}
  95
  96#endif
  97