-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Add metag system call and gateway page interfaces. The metag architecture port uses the generic system call numbers from asm-generic/unistd.h, as well as a user gateway page mapped at 0x6ffff000 which contains fast atomic primitives (depending on SMP) and a fast method of accessing TLS data. System calls use the SWITCH instruction with the immediate 0x440001 to signal a system call. Signed-off-by: James Hogan <james.hogan@imgtec.com>
- Loading branch information
James Hogan
committed
Mar 2, 2013
1 parent
5698c50
commit 26025bb
Showing
8 changed files
with
508 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,11 @@ | ||
#ifndef __METAG_MMAN_H__ | ||
#define __METAG_MMAN_H__ | ||
|
||
#include <uapi/asm/mman.h> | ||
|
||
#ifndef __ASSEMBLY__ | ||
#define arch_mmap_check metag_mmap_check | ||
int metag_mmap_check(unsigned long addr, unsigned long len, | ||
unsigned long flags); | ||
#endif | ||
#endif /* __METAG_MMAN_H__ */ |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,104 @@ | ||
/* | ||
* Access to user system call parameters and results | ||
* | ||
* Copyright (C) 2008 Imagination Technologies Ltd. | ||
* | ||
* This copyrighted material is made available to anyone wishing to use, | ||
* modify, copy, or redistribute it subject to the terms and conditions | ||
* of the GNU General Public License v.2. | ||
* | ||
* See asm-generic/syscall.h for descriptions of what we must do here. | ||
*/ | ||
|
||
#ifndef _ASM_METAG_SYSCALL_H | ||
#define _ASM_METAG_SYSCALL_H | ||
|
||
#include <linux/sched.h> | ||
#include <linux/err.h> | ||
#include <linux/uaccess.h> | ||
|
||
#include <asm/switch.h> | ||
|
||
static inline long syscall_get_nr(struct task_struct *task, | ||
struct pt_regs *regs) | ||
{ | ||
unsigned long insn; | ||
|
||
/* | ||
* FIXME there's no way to find out how we got here other than to | ||
* examine the memory at the PC to see if it is a syscall | ||
* SWITCH instruction. | ||
*/ | ||
if (get_user(insn, (unsigned long *)(regs->ctx.CurrPC - 4))) | ||
return -1; | ||
|
||
if (insn == __METAG_SW_ENCODING(SYS)) | ||
return regs->ctx.DX[0].U1; | ||
else | ||
return -1L; | ||
} | ||
|
||
static inline void syscall_rollback(struct task_struct *task, | ||
struct pt_regs *regs) | ||
{ | ||
/* do nothing */ | ||
} | ||
|
||
static inline long syscall_get_error(struct task_struct *task, | ||
struct pt_regs *regs) | ||
{ | ||
unsigned long error = regs->ctx.DX[0].U0; | ||
return IS_ERR_VALUE(error) ? error : 0; | ||
} | ||
|
||
static inline long syscall_get_return_value(struct task_struct *task, | ||
struct pt_regs *regs) | ||
{ | ||
return regs->ctx.DX[0].U0; | ||
} | ||
|
||
static inline void syscall_set_return_value(struct task_struct *task, | ||
struct pt_regs *regs, | ||
int error, long val) | ||
{ | ||
regs->ctx.DX[0].U0 = (long) error ?: val; | ||
} | ||
|
||
static inline void syscall_get_arguments(struct task_struct *task, | ||
struct pt_regs *regs, | ||
unsigned int i, unsigned int n, | ||
unsigned long *args) | ||
{ | ||
unsigned int reg, j; | ||
BUG_ON(i + n > 6); | ||
|
||
for (j = i, reg = 6 - i; j < (i + n); j++, reg--) { | ||
if (reg % 2) | ||
args[j] = regs->ctx.DX[(reg + 1) / 2].U0; | ||
else | ||
args[j] = regs->ctx.DX[reg / 2].U1; | ||
} | ||
} | ||
|
||
static inline void syscall_set_arguments(struct task_struct *task, | ||
struct pt_regs *regs, | ||
unsigned int i, unsigned int n, | ||
const unsigned long *args) | ||
{ | ||
unsigned int reg; | ||
BUG_ON(i + n > 6); | ||
|
||
for (reg = 6 - i; i < (i + n); i++, reg--) { | ||
if (reg % 2) | ||
regs->ctx.DX[(reg + 1) / 2].U0 = args[i]; | ||
else | ||
regs->ctx.DX[reg / 2].U1 = args[i]; | ||
} | ||
} | ||
|
||
#define NR_syscalls __NR_syscalls | ||
|
||
/* generic syscall table */ | ||
extern const void *sys_call_table[]; | ||
|
||
#endif /* _ASM_METAG_SYSCALL_H */ |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,39 @@ | ||
#ifndef _ASM_METAG_SYSCALLS_H | ||
#define _ASM_METAG_SYSCALLS_H | ||
|
||
#include <linux/compiler.h> | ||
#include <linux/linkage.h> | ||
#include <linux/types.h> | ||
#include <linux/signal.h> | ||
|
||
/* kernel/signal.c */ | ||
#define sys_rt_sigreturn sys_rt_sigreturn | ||
asmlinkage long sys_rt_sigreturn(void); | ||
|
||
#include <asm-generic/syscalls.h> | ||
|
||
/* kernel/sys_metag.c */ | ||
asmlinkage int sys_metag_setglobalbit(char __user *, int); | ||
asmlinkage void sys_metag_set_fpu_flags(unsigned int); | ||
asmlinkage int sys_metag_set_tls(void __user *); | ||
asmlinkage void *sys_metag_get_tls(void); | ||
|
||
asmlinkage long sys_truncate64_metag(const char __user *, unsigned long, | ||
unsigned long); | ||
asmlinkage long sys_ftruncate64_metag(unsigned int, unsigned long, | ||
unsigned long); | ||
asmlinkage long sys_fadvise64_64_metag(int, unsigned long, unsigned long, | ||
unsigned long, unsigned long, int); | ||
asmlinkage long sys_readahead_metag(int, unsigned long, unsigned long, size_t); | ||
asmlinkage ssize_t sys_pread64_metag(unsigned long, char __user *, size_t, | ||
unsigned long, unsigned long); | ||
asmlinkage ssize_t sys_pwrite64_metag(unsigned long, char __user *, size_t, | ||
unsigned long, unsigned long); | ||
asmlinkage long sys_sync_file_range_metag(int, unsigned long, unsigned long, | ||
unsigned long, unsigned long, | ||
unsigned int); | ||
|
||
int do_work_pending(struct pt_regs *regs, unsigned int thread_flags, | ||
int syscall); | ||
|
||
#endif /* _ASM_METAG_SYSCALLS_H */ |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,12 @@ | ||
/* | ||
* Copyright (C) 2012 Imagination Technologies Ltd. | ||
* | ||
* This program is free software; you can redistribute it and/or modify | ||
* it under the terms of the GNU General Public License as published by | ||
* the Free Software Foundation; either version 2 of the License, or | ||
* (at your option) any later version. | ||
*/ | ||
|
||
#include <uapi/asm/unistd.h> | ||
|
||
#define __ARCH_WANT_SYS_CLONE |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,44 @@ | ||
/* | ||
* Copyright (C) 2010 Imagination Technologies | ||
*/ | ||
|
||
#ifndef __ASM_METAG_USER_GATEWAY_H | ||
#define __ASM_METAG_USER_GATEWAY_H | ||
|
||
#include <asm/page.h> | ||
|
||
/* Page of kernel code accessible to userspace. */ | ||
#define USER_GATEWAY_PAGE 0x6ffff000 | ||
/* Offset of TLS pointer array in gateway page. */ | ||
#define USER_GATEWAY_TLS 0x100 | ||
|
||
#ifndef __ASSEMBLY__ | ||
|
||
extern char __user_gateway_start; | ||
extern char __user_gateway_end; | ||
|
||
/* Kernel mapping of the gateway page. */ | ||
extern void *gateway_page; | ||
|
||
static inline void set_gateway_tls(void __user *tls_ptr) | ||
{ | ||
void **gateway_tls = (void **)(gateway_page + USER_GATEWAY_TLS + | ||
hard_processor_id() * 4); | ||
|
||
*gateway_tls = (__force void *)tls_ptr; | ||
#ifdef CONFIG_METAG_META12 | ||
/* Avoid cache aliases on virtually tagged cache. */ | ||
__builtin_dcache_flush((void *)USER_GATEWAY_PAGE + USER_GATEWAY_TLS + | ||
hard_processor_id() * sizeof(void *)); | ||
#endif | ||
} | ||
|
||
extern int __kuser_get_tls(void); | ||
extern char *__kuser_get_tls_end[]; | ||
|
||
extern int __kuser_cmpxchg(int, int, unsigned long *); | ||
extern char *__kuser_cmpxchg_end[]; | ||
|
||
#endif | ||
|
||
#endif |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,21 @@ | ||
/* | ||
* Copyright (C) 2012 Imagination Technologies Ltd. | ||
* | ||
* This program is free software; you can redistribute it and/or modify | ||
* it under the terms of the GNU General Public License as published by | ||
* the Free Software Foundation; either version 2 of the License, or | ||
* (at your option) any later version. | ||
*/ | ||
|
||
/* Use the standard ABI for syscalls. */ | ||
#include <asm-generic/unistd.h> | ||
|
||
/* metag-specific syscalls. */ | ||
#define __NR_metag_setglobalbit (__NR_arch_specific_syscall + 1) | ||
__SYSCALL(__NR_metag_setglobalbit, sys_metag_setglobalbit) | ||
#define __NR_metag_set_fpu_flags (__NR_arch_specific_syscall + 2) | ||
__SYSCALL(__NR_metag_set_fpu_flags, sys_metag_set_fpu_flags) | ||
#define __NR_metag_set_tls (__NR_arch_specific_syscall + 3) | ||
__SYSCALL(__NR_metag_set_tls, sys_metag_set_tls) | ||
#define __NR_metag_get_tls (__NR_arch_specific_syscall + 4) | ||
__SYSCALL(__NR_metag_get_tls, sys_metag_get_tls) |
Oops, something went wrong.