1/* 2 * Copyright 2010 Tilera Corporation. All Rights Reserved. 3 * 4 * This program is free software; you can redistribute it and/or 5 * modify it under the terms of the GNU General Public License 6 * as published by the Free Software Foundation, version 2. 7 * 8 * This program is distributed in the hope that it will be useful, but 9 * WITHOUT ANY WARRANTY; without even the implied warranty of 10 * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, GOOD TITLE or 11 * NON INFRINGEMENT. See the GNU General Public License for 12 * more details. 13 * 14 * This file contains various random system calls that 15 * have a non-standard calling sequence on the Linux/TILE 16 * platform. 17 */ 18 19#include <linux/errno.h> 20#include <linux/sched.h> 21#include <linux/mm.h> 22#include <linux/smp.h> 23#include <linux/syscalls.h> 24#include <linux/mman.h> 25#include <linux/file.h> 26#include <linux/mempolicy.h> 27#include <linux/binfmts.h> 28#include <linux/fs.h> 29#include <linux/compat.h> 30#include <linux/uaccess.h> 31#include <linux/signal.h> 32#include <asm/syscalls.h> 33#include <asm/pgtable.h> 34#include <asm/homecache.h> 35#include <asm/cachectl.h> 36#include <arch/chip.h> 37 38SYSCALL_DEFINE3(cacheflush, unsigned long, addr, unsigned long, len, 39 unsigned long, flags) 40{ 41 /* DCACHE is not particularly effective if not bound to one cpu. */ 42 if (flags & DCACHE) 43 homecache_evict(cpumask_of(raw_smp_processor_id())); 44 45 if (flags & ICACHE) 46 flush_remote(0, HV_FLUSH_EVICT_L1I, mm_cpumask(current->mm), 47 0, 0, 0, NULL, NULL, 0); 48 return 0; 49} 50 51/* 52 * Syscalls that pass 64-bit values on 32-bit systems normally 53 * pass them as (low,high) word packed into the immediately adjacent 54 * registers. If the low word naturally falls on an even register, 55 * our ABI makes it work correctly; if not, we adjust it here. 56 * Handling it here means we don't have to fix uclibc AND glibc AND 57 * any other standard libcs we want to support. 58 */ 59 60#if !defined(__tilegx__) || defined(CONFIG_COMPAT) 61 62ssize_t sys32_readahead(int fd, u32 offset_lo, u32 offset_hi, u32 count) 63{ 64 return sys_readahead(fd, ((loff_t)offset_hi << 32) | offset_lo, count); 65} 66 67int sys32_fadvise64_64(int fd, u32 offset_lo, u32 offset_hi, 68 u32 len_lo, u32 len_hi, int advice) 69{ 70 return sys_fadvise64_64(fd, ((loff_t)offset_hi << 32) | offset_lo, 71 ((loff_t)len_hi << 32) | len_lo, advice); 72} 73 74#endif /* 32-bit syscall wrappers */ 75 76/* Note: used by the compat code even in 64-bit Linux. */ 77SYSCALL_DEFINE6(mmap2, unsigned long, addr, unsigned long, len, 78 unsigned long, prot, unsigned long, flags, 79 unsigned long, fd, unsigned long, off_4k) 80{ 81#define PAGE_ADJUST (PAGE_SHIFT - 12) 82 if (off_4k & ((1 << PAGE_ADJUST) - 1)) 83 return -EINVAL; 84 return sys_mmap_pgoff(addr, len, prot, flags, fd, 85 off_4k >> PAGE_ADJUST); 86} 87 88#ifdef __tilegx__ 89SYSCALL_DEFINE6(mmap, unsigned long, addr, unsigned long, len, 90 unsigned long, prot, unsigned long, flags, 91 unsigned long, fd, off_t, offset) 92{ 93 if (offset & ((1 << PAGE_SHIFT) - 1)) 94 return -EINVAL; 95 return sys_mmap_pgoff(addr, len, prot, flags, fd, 96 offset >> PAGE_SHIFT); 97} 98#endif 99 100 101/* Provide the actual syscall number to call mapping. */ 102#undef __SYSCALL 103#define __SYSCALL(nr, call) [nr] = (call), 104 105#ifndef __tilegx__ 106/* See comments at the top of the file. */ 107#define sys_fadvise64_64 sys32_fadvise64_64 108#define sys_readahead sys32_readahead 109#endif 110 111/* Call the assembly trampolines where necessary. */ 112#undef sys_rt_sigreturn 113#define sys_rt_sigreturn _sys_rt_sigreturn 114#define sys_clone _sys_clone 115 116/* 117 * Note that we can't include <linux/unistd.h> here since the header 118 * guard will defeat us; <asm/unistd.h> checks for __SYSCALL as well. 119 */ 120void *sys_call_table[__NR_syscalls] = { 121 [0 ... __NR_syscalls-1] = sys_ni_syscall, 122#include <asm/unistd.h> 123}; 124