linux/arch/frv/include/asm/syscall.h
<<
>>
Prefs
   1/* syscall parameter access functions
   2 *
   3 * Copyright (C) 2009 Red Hat, Inc. All Rights Reserved.
   4 * Written by David Howells (dhowells@redhat.com)
   5 *
   6 * This program is free software; you can redistribute it and/or
   7 * modify it under the terms of the GNU General Public Licence
   8 * as published by the Free Software Foundation; either version
   9 * 2 of the Licence, or (at your option) any later version.
  10 */
  11
  12#ifndef _ASM_SYSCALL_H
  13#define _ASM_SYSCALL_H
  14
  15#include <linux/err.h>
  16#include <asm/ptrace.h>
  17
  18/*
  19 * Get the system call number or -1
  20 */
  21static inline long syscall_get_nr(struct task_struct *task,
  22                                  struct pt_regs *regs)
  23{
  24        return regs->syscallno;
  25}
  26
  27/*
  28 * Restore the clobbered GR8 register
  29 * (1st syscall arg was overwritten with syscall return or error)
  30 */
  31static inline void syscall_rollback(struct task_struct *task,
  32                                    struct pt_regs *regs)
  33{
  34        regs->gr8 = regs->orig_gr8;
  35}
  36
  37/*
  38 * See if the syscall return value is an error, returning it if it is and 0 if
  39 * not
  40 */
  41static inline long syscall_get_error(struct task_struct *task,
  42                                     struct pt_regs *regs)
  43{
  44        return IS_ERR_VALUE(regs->gr8) ? regs->gr8 : 0;
  45}
  46
  47/*
  48 * Get the syscall return value
  49 */
  50static inline long syscall_get_return_value(struct task_struct *task,
  51                                            struct pt_regs *regs)
  52{
  53        return regs->gr8;
  54}
  55
  56/*
  57 * Set the syscall return value
  58 */
  59static inline void syscall_set_return_value(struct task_struct *task,
  60                                            struct pt_regs *regs,
  61                                            int error, long val)
  62{
  63        if (error)
  64                regs->gr8 = -error;
  65        else
  66                regs->gr8 = val;
  67}
  68
  69/*
  70 * Retrieve the system call arguments
  71 */
  72static inline void syscall_get_arguments(struct task_struct *task,
  73                                         struct pt_regs *regs,
  74                                         unsigned int i, unsigned int n,
  75                                         unsigned long *args)
  76{
  77        /*
  78         * Do this simply for now. If we need to start supporting
  79         * fetching arguments from arbitrary indices, this will need some
  80         * extra logic. Presently there are no in-tree users that depend
  81         * on this behaviour.
  82         */
  83        BUG_ON(i);
  84
  85        /* Argument pattern is: GR8, GR9, GR10, GR11, GR12, GR13 */
  86        switch (n) {
  87        case 6: args[5] = regs->gr13;
  88        case 5: args[4] = regs->gr12;
  89        case 4: args[3] = regs->gr11;
  90        case 3: args[2] = regs->gr10;
  91        case 2: args[1] = regs->gr9;
  92        case 1: args[0] = regs->gr8;
  93                break;
  94        default:
  95                BUG();
  96        }
  97}
  98
  99/*
 100 * Alter the system call arguments
 101 */
 102static inline void syscall_set_arguments(struct task_struct *task,
 103                                         struct pt_regs *regs,
 104                                         unsigned int i, unsigned int n,
 105                                         const unsigned long *args)
 106{
 107        /* Same note as above applies */
 108        BUG_ON(i);
 109
 110        switch (n) {
 111        case 6: regs->gr13 = args[5];
 112        case 5: regs->gr12 = args[4];
 113        case 4: regs->gr11 = args[3];
 114        case 3: regs->gr10 = args[2];
 115        case 2: regs->gr9  = args[1];
 116        case 1: regs->gr8  = args[0];
 117                break;
 118        default:
 119                BUG();
 120        }
 121}
 122
 123#endif /* _ASM_SYSCALL_H */
 124