[XTENSA] Add support for configurable registers and coprocessors
The Xtensa architecture allows to define custom instructions and registers. Registers that are bound to a coprocessor are only accessible if the corresponding enable bit is set, which allows to implement a 'lazy' context switch mechanism. Other registers needs to be saved and restore at the time of the context switch or during interrupt handling. This patch adds support for these additional states: - save and restore registers that are used by the compiler upon interrupt entry and exit. - context switch additional registers unbound to any coprocessor - 'lazy' context switch of registers bound to a coprocessor - ptrace interface to provide access to additional registers - update configuration files in include/asm-xtensa/variant-fsf Signed-off-by: Chris Zankel <chris@zankel.net>
This commit is contained in:
@@ -5,81 +5,168 @@
|
||||
* License. See the file "COPYING" in the main directory of this archive
|
||||
* for more details.
|
||||
*
|
||||
* Copyright (C) 2003 - 2005 Tensilica Inc.
|
||||
* Copyright (C) 2003 - 2007 Tensilica Inc.
|
||||
*/
|
||||
|
||||
|
||||
#ifndef _XTENSA_COPROCESSOR_H
|
||||
#define _XTENSA_COPROCESSOR_H
|
||||
|
||||
#include <asm/variant/core.h>
|
||||
#include <linux/stringify.h>
|
||||
#include <asm/variant/tie.h>
|
||||
#include <asm/types.h>
|
||||
|
||||
#if !XCHAL_HAVE_CP
|
||||
#ifdef __ASSEMBLY__
|
||||
# include <asm/variant/tie-asm.h>
|
||||
|
||||
#define XTENSA_CP_EXTRA_OFFSET 0
|
||||
#define XTENSA_CP_EXTRA_ALIGN 1 /* must be a power of 2 */
|
||||
#define XTENSA_CP_EXTRA_SIZE 0
|
||||
.macro xchal_sa_start a b
|
||||
.set .Lxchal_pofs_, 0
|
||||
.set .Lxchal_ofs_, 0
|
||||
.endm
|
||||
|
||||
#else
|
||||
.macro xchal_sa_align ptr minofs maxofs ofsalign totalign
|
||||
.set .Lxchal_ofs_, .Lxchal_ofs_ + .Lxchal_pofs_ + \totalign - 1
|
||||
.set .Lxchal_ofs_, (.Lxchal_ofs_ & -\totalign) - .Lxchal_pofs_
|
||||
.endm
|
||||
|
||||
#define XTOFS(last_start,last_size,align) \
|
||||
((last_start+last_size+align-1) & -align)
|
||||
#define _SELECT ( XTHAL_SAS_TIE | XTHAL_SAS_OPT \
|
||||
| XTHAL_SAS_CC \
|
||||
| XTHAL_SAS_CALR | XTHAL_SAS_CALE | XTHAL_SAS_GLOB )
|
||||
|
||||
#define XTENSA_CP_EXTRA_OFFSET 0
|
||||
#define XTENSA_CP_EXTRA_ALIGN XCHAL_EXTRA_SA_ALIGN
|
||||
.macro save_xtregs_opt ptr clb at1 at2 at3 at4 offset
|
||||
.if XTREGS_OPT_SIZE > 0
|
||||
addi \clb, \ptr, \offset
|
||||
xchal_ncp_store \clb \at1 \at2 \at3 \at4 select=_SELECT
|
||||
.endif
|
||||
.endm
|
||||
|
||||
#define XTENSA_CPE_CP0_OFFSET \
|
||||
XTOFS(XTENSA_CP_EXTRA_OFFSET, XCHAL_EXTRA_SA_SIZE, XCHAL_CP0_SA_ALIGN)
|
||||
#define XTENSA_CPE_CP1_OFFSET \
|
||||
XTOFS(XTENSA_CPE_CP0_OFFSET, XCHAL_CP0_SA_SIZE, XCHAL_CP1_SA_ALIGN)
|
||||
#define XTENSA_CPE_CP2_OFFSET \
|
||||
XTOFS(XTENSA_CPE_CP1_OFFSET, XCHAL_CP1_SA_SIZE, XCHAL_CP2_SA_ALIGN)
|
||||
#define XTENSA_CPE_CP3_OFFSET \
|
||||
XTOFS(XTENSA_CPE_CP2_OFFSET, XCHAL_CP2_SA_SIZE, XCHAL_CP3_SA_ALIGN)
|
||||
#define XTENSA_CPE_CP4_OFFSET \
|
||||
XTOFS(XTENSA_CPE_CP3_OFFSET, XCHAL_CP3_SA_SIZE, XCHAL_CP4_SA_ALIGN)
|
||||
#define XTENSA_CPE_CP5_OFFSET \
|
||||
XTOFS(XTENSA_CPE_CP4_OFFSET, XCHAL_CP4_SA_SIZE, XCHAL_CP5_SA_ALIGN)
|
||||
#define XTENSA_CPE_CP6_OFFSET \
|
||||
XTOFS(XTENSA_CPE_CP5_OFFSET, XCHAL_CP5_SA_SIZE, XCHAL_CP6_SA_ALIGN)
|
||||
#define XTENSA_CPE_CP7_OFFSET \
|
||||
XTOFS(XTENSA_CPE_CP6_OFFSET, XCHAL_CP6_SA_SIZE, XCHAL_CP7_SA_ALIGN)
|
||||
#define XTENSA_CP_EXTRA_SIZE \
|
||||
XTOFS(XTENSA_CPE_CP7_OFFSET, XCHAL_CP7_SA_SIZE, 16)
|
||||
.macro load_xtregs_opt ptr clb at1 at2 at3 at4 offset
|
||||
.if XTREGS_OPT_SIZE > 0
|
||||
addi \clb, \ptr, \offset
|
||||
xchal_ncp_load \clb \at1 \at2 \at3 \at4 select=_SELECT
|
||||
.endif
|
||||
.endm
|
||||
#undef _SELECT
|
||||
|
||||
#define _SELECT ( XTHAL_SAS_TIE | XTHAL_SAS_OPT \
|
||||
| XTHAL_SAS_NOCC \
|
||||
| XTHAL_SAS_CALR | XTHAL_SAS_CALE | XTHAL_SAS_GLOB )
|
||||
|
||||
.macro save_xtregs_user ptr clb at1 at2 at3 at4 offset
|
||||
.if XTREGS_USER_SIZE > 0
|
||||
addi \clb, \ptr, \offset
|
||||
xchal_ncp_store \clb \at1 \at2 \at3 \at4 select=_SELECT
|
||||
.endif
|
||||
.endm
|
||||
|
||||
.macro load_xtregs_user ptr clb at1 at2 at3 at4 offset
|
||||
.if XTREGS_USER_SIZE > 0
|
||||
addi \clb, \ptr, \offset
|
||||
xchal_ncp_load \clb \at1 \at2 \at3 \at4 select=_SELECT
|
||||
.endif
|
||||
.endm
|
||||
#undef _SELECT
|
||||
|
||||
|
||||
|
||||
#endif /* __ASSEMBLY__ */
|
||||
|
||||
#if XCHAL_CP_NUM > 0
|
||||
# ifndef __ASSEMBLY__
|
||||
/*
|
||||
* Tasks that own contents of (last user) each coprocessor.
|
||||
* Entries are 0 for not-owned or non-existent coprocessors.
|
||||
* Note: The size of this structure is fixed to 8 bytes in entry.S
|
||||
* XTENSA_HAVE_COPROCESSOR(x) returns 1 if coprocessor x is configured.
|
||||
*
|
||||
* XTENSA_HAVE_IO_PORT(x) returns 1 if io-port x is configured.
|
||||
*
|
||||
*/
|
||||
typedef struct {
|
||||
struct task_struct *owner; /* owner */
|
||||
int offset; /* offset in cpextra space. */
|
||||
} coprocessor_info_t;
|
||||
# else
|
||||
# define COPROCESSOR_INFO_OWNER 0
|
||||
# define COPROCESSOR_INFO_OFFSET 4
|
||||
# define COPROCESSOR_INFO_SIZE 8
|
||||
# endif
|
||||
#endif
|
||||
#endif /* XCHAL_HAVE_CP */
|
||||
|
||||
#define XTENSA_HAVE_COPROCESSOR(x) \
|
||||
((XCHAL_CP_MASK ^ XCHAL_CP_PORT_MASK) & (1 << (x)))
|
||||
#define XTENSA_HAVE_COPROCESSORS \
|
||||
(XCHAL_CP_MASK ^ XCHAL_CP_PORT_MASK)
|
||||
#define XTENSA_HAVE_IO_PORT(x) \
|
||||
(XCHAL_CP_PORT_MASK & (1 << (x)))
|
||||
#define XTENSA_HAVE_IO_PORTS \
|
||||
XCHAL_CP_PORT_MASK
|
||||
|
||||
#ifndef __ASSEMBLY__
|
||||
# if XCHAL_CP_NUM > 0
|
||||
struct task_struct;
|
||||
extern void release_coprocessors (struct task_struct*);
|
||||
extern void save_coprocessor_registers(void*, int);
|
||||
# else
|
||||
# define release_coprocessors(task)
|
||||
# endif
|
||||
|
||||
typedef unsigned char cp_state_t[XTENSA_CP_EXTRA_SIZE]
|
||||
__attribute__ ((aligned (XTENSA_CP_EXTRA_ALIGN)));
|
||||
|
||||
#if XCHAL_HAVE_CP
|
||||
|
||||
#define RSR_CPENABLE(x) do { \
|
||||
__asm__ __volatile__("rsr %0," __stringify(CPENABLE) : "=a" (x)); \
|
||||
} while(0);
|
||||
#define WSR_CPENABLE(x) do { \
|
||||
__asm__ __volatile__("wsr %0," __stringify(CPENABLE) "; rsync" \
|
||||
:: "a" (x)); \
|
||||
} while(0);
|
||||
|
||||
#endif /* XCHAL_HAVE_CP */
|
||||
|
||||
|
||||
/*
|
||||
* Additional registers.
|
||||
* We define three types of additional registers:
|
||||
* ext: extra registers that are used by the compiler
|
||||
* cpn: optional registers that can be used by a user application
|
||||
* cpX: coprocessor registers that can only be used if the corresponding
|
||||
* CPENABLE bit is set.
|
||||
*/
|
||||
|
||||
#define XCHAL_SA_REG(list,compiler,x,type,y,name,z,align,size,...) \
|
||||
__REG ## list (compiler, type, name, size, align)
|
||||
|
||||
#define __REG0(compiler,t,name,s,a) __REG0_ ## compiler (name)
|
||||
#define __REG1(compiler,t,name,s,a) __REG1_ ## compiler (name)
|
||||
#define __REG2(c,type,...) __REG2_ ## type (__VA_ARGS__)
|
||||
|
||||
#define __REG0_0(name)
|
||||
#define __REG0_1(name) __u32 name;
|
||||
#define __REG1_0(name) __u32 name;
|
||||
#define __REG1_1(name)
|
||||
#define __REG2_0(n,s,a) __u32 name;
|
||||
#define __REG2_1(n,s,a) unsigned char n[s] __attribute__ ((aligned(a)));
|
||||
#define __REG2_2(n,s,a) unsigned char n[s] __attribute__ ((aligned(a)));
|
||||
|
||||
typedef struct { XCHAL_NCP_SA_LIST(0) } xtregs_opt_t
|
||||
__attribute__ ((aligned (XCHAL_NCP_SA_ALIGN)));
|
||||
typedef struct { XCHAL_NCP_SA_LIST(1) } xtregs_user_t
|
||||
__attribute__ ((aligned (XCHAL_NCP_SA_ALIGN)));
|
||||
|
||||
#if XTENSA_HAVE_COPROCESSORS
|
||||
|
||||
typedef struct { XCHAL_CP0_SA_LIST(2) } xtregs_cp0_t
|
||||
__attribute__ ((aligned (XCHAL_CP0_SA_ALIGN)));
|
||||
typedef struct { XCHAL_CP1_SA_LIST(2) } xtregs_cp1_t
|
||||
__attribute__ ((aligned (XCHAL_CP1_SA_ALIGN)));
|
||||
typedef struct { XCHAL_CP2_SA_LIST(2) } xtregs_cp2_t
|
||||
__attribute__ ((aligned (XCHAL_CP2_SA_ALIGN)));
|
||||
typedef struct { XCHAL_CP3_SA_LIST(2) } xtregs_cp3_t
|
||||
__attribute__ ((aligned (XCHAL_CP3_SA_ALIGN)));
|
||||
typedef struct { XCHAL_CP4_SA_LIST(2) } xtregs_cp4_t
|
||||
__attribute__ ((aligned (XCHAL_CP4_SA_ALIGN)));
|
||||
typedef struct { XCHAL_CP5_SA_LIST(2) } xtregs_cp5_t
|
||||
__attribute__ ((aligned (XCHAL_CP5_SA_ALIGN)));
|
||||
typedef struct { XCHAL_CP6_SA_LIST(2) } xtregs_cp6_t
|
||||
__attribute__ ((aligned (XCHAL_CP6_SA_ALIGN)));
|
||||
typedef struct { XCHAL_CP7_SA_LIST(2) } xtregs_cp7_t
|
||||
__attribute__ ((aligned (XCHAL_CP7_SA_ALIGN)));
|
||||
|
||||
extern struct thread_info* coprocessor_owner[XCHAL_CP_MAX];
|
||||
extern void coprocessor_save(void*, int);
|
||||
extern void coprocessor_load(void*, int);
|
||||
extern void coprocessor_flush(struct thread_info*, int);
|
||||
extern void coprocessor_restore(struct thread_info*, int);
|
||||
|
||||
extern void coprocessor_release_all(struct thread_info*);
|
||||
extern void coprocessor_flush_all(struct thread_info*);
|
||||
|
||||
static inline void coprocessor_clear_cpenable(void)
|
||||
{
|
||||
unsigned long i = 0;
|
||||
WSR_CPENABLE(i);
|
||||
}
|
||||
|
||||
#endif /* XTENSA_HAVE_COPROCESSORS */
|
||||
|
||||
#endif /* !__ASSEMBLY__ */
|
||||
|
||||
|
||||
#endif /* _XTENSA_COPROCESSOR_H */
|
||||
|
||||
@@ -173,6 +173,21 @@ extern void xtensa_elf_core_copy_regs (xtensa_gregset_t *, struct pt_regs *);
|
||||
_r->areg[12]=0; _r->areg[13]=0; _r->areg[14]=0; _r->areg[15]=0; \
|
||||
} while (0)
|
||||
|
||||
typedef struct {
|
||||
xtregs_opt_t opt;
|
||||
xtregs_user_t user;
|
||||
#if XTENSA_HAVE_COPROCESSORS
|
||||
xtregs_cp0_t cp0;
|
||||
xtregs_cp1_t cp1;
|
||||
xtregs_cp2_t cp2;
|
||||
xtregs_cp3_t cp3;
|
||||
xtregs_cp4_t cp4;
|
||||
xtregs_cp5_t cp5;
|
||||
xtregs_cp6_t cp6;
|
||||
xtregs_cp7_t cp7;
|
||||
#endif
|
||||
} elf_xtregs_t;
|
||||
|
||||
#define SET_PERSONALITY(ex, ibcs2) set_personality(PER_LINUX_32BIT)
|
||||
|
||||
struct task_struct;
|
||||
|
||||
@@ -103,10 +103,6 @@ struct thread_struct {
|
||||
unsigned long dbreaka[XCHAL_NUM_DBREAK];
|
||||
unsigned long dbreakc[XCHAL_NUM_DBREAK];
|
||||
|
||||
/* Allocate storage for extra state and coprocessor state. */
|
||||
unsigned char cp_save[XTENSA_CP_EXTRA_SIZE]
|
||||
__attribute__ ((aligned(XTENSA_CP_EXTRA_ALIGN)));
|
||||
|
||||
/* Make structure 16 bytes aligned. */
|
||||
int align[0] __attribute__ ((aligned(16)));
|
||||
};
|
||||
@@ -162,21 +158,16 @@ struct thread_struct {
|
||||
struct task_struct;
|
||||
struct mm_struct;
|
||||
|
||||
// FIXME: do we need release_thread for CP??
|
||||
/* Free all resources held by a thread. */
|
||||
#define release_thread(thread) do { } while(0)
|
||||
|
||||
// FIXME: do we need prepare_to_copy (lazy status) for CP??
|
||||
/* Prepare to copy thread state - unlazy all lazy status */
|
||||
#define prepare_to_copy(tsk) do { } while (0)
|
||||
extern void prepare_to_copy(struct task_struct*);
|
||||
|
||||
/*
|
||||
* create a kernel thread without removing it from tasklists
|
||||
*/
|
||||
/* Create a kernel thread without removing it from tasklists */
|
||||
extern int kernel_thread(int (*fn)(void *), void * arg, unsigned long flags);
|
||||
|
||||
/* Copy and release all segment info associated with a VM */
|
||||
|
||||
#define copy_segments(p, mm) do { } while(0)
|
||||
#define release_segments(mm) do { } while(0)
|
||||
#define forget_segments() do { } while (0)
|
||||
|
||||
@@ -53,33 +53,30 @@
|
||||
|
||||
/* Registers used by strace */
|
||||
|
||||
#define REG_A_BASE 0xfc000000
|
||||
#define REG_AR_BASE 0x04000000
|
||||
#define REG_PC 0x14000000
|
||||
#define REG_PS 0x080000e6
|
||||
#define REG_WB 0x08000048
|
||||
#define REG_WS 0x08000049
|
||||
#define REG_LBEG 0x08000000
|
||||
#define REG_LEND 0x08000001
|
||||
#define REG_LCOUNT 0x08000002
|
||||
#define REG_SAR 0x08000003
|
||||
#define REG_DEPC 0x080000c0
|
||||
#define REG_EXCCAUSE 0x080000e8
|
||||
#define REG_EXCVADDR 0x080000ee
|
||||
#define SYSCALL_NR 0x1
|
||||
#define REG_A_BASE 0x0000
|
||||
#define REG_AR_BASE 0x0100
|
||||
#define REG_PC 0x0020
|
||||
#define REG_PS 0x02e6
|
||||
#define REG_WB 0x0248
|
||||
#define REG_WS 0x0249
|
||||
#define REG_LBEG 0x0200
|
||||
#define REG_LEND 0x0201
|
||||
#define REG_LCOUNT 0x0202
|
||||
#define REG_SAR 0x0203
|
||||
|
||||
#define AR_REGNO_TO_A_REGNO(ar, wb) (ar - wb*4) & ~(XCHAL_NUM_AREGS - 1)
|
||||
#define SYSCALL_NR 0x00ff
|
||||
|
||||
/* Other PTRACE_ values defined in <linux/ptrace.h> using values 0-9,16,17,24 */
|
||||
|
||||
#define PTRACE_GETREGS 12
|
||||
#define PTRACE_SETREGS 13
|
||||
#define PTRACE_GETFPREGS 14
|
||||
#define PTRACE_SETFPREGS 15
|
||||
#define PTRACE_GETFPREGSIZE 18
|
||||
#define PTRACE_GETREGS 12
|
||||
#define PTRACE_SETREGS 13
|
||||
#define PTRACE_GETXTREGS 18
|
||||
#define PTRACE_SETXTREGS 19
|
||||
|
||||
#ifndef __ASSEMBLY__
|
||||
|
||||
#ifdef __KERNEL__
|
||||
|
||||
/*
|
||||
* This struct defines the way the registers are stored on the
|
||||
* kernel stack during a system call or other kernel entry.
|
||||
@@ -102,6 +99,9 @@ struct pt_regs {
|
||||
unsigned long icountlevel; /* 60 */
|
||||
int reserved[1]; /* 64 */
|
||||
|
||||
/* Additional configurable registers that are used by the compiler. */
|
||||
xtregs_opt_t xtregs_opt;
|
||||
|
||||
/* Make sure the areg field is 16 bytes aligned. */
|
||||
int align[0] __attribute__ ((aligned(16)));
|
||||
|
||||
@@ -111,8 +111,6 @@ struct pt_regs {
|
||||
unsigned long areg[16]; /* 128 (64) */
|
||||
};
|
||||
|
||||
#ifdef __KERNEL__
|
||||
|
||||
#include <asm/variant/core.h>
|
||||
|
||||
# define task_pt_regs(tsk) ((struct pt_regs*) \
|
||||
|
||||
@@ -100,7 +100,14 @@
|
||||
#define EXCCAUSE_DTLB_SIZE_RESTRICTION 27
|
||||
#define EXCCAUSE_LOAD_CACHE_ATTRIBUTE 28
|
||||
#define EXCCAUSE_STORE_CACHE_ATTRIBUTE 29
|
||||
#define EXCCAUSE_FLOATING_POINT 40
|
||||
#define EXCCAUSE_COPROCESSOR0_DISABLED 32
|
||||
#define EXCCAUSE_COPROCESSOR1_DISABLED 33
|
||||
#define EXCCAUSE_COPROCESSOR2_DISABLED 34
|
||||
#define EXCCAUSE_COPROCESSOR3_DISABLED 35
|
||||
#define EXCCAUSE_COPROCESSOR4_DISABLED 36
|
||||
#define EXCCAUSE_COPROCESSOR5_DISABLED 37
|
||||
#define EXCCAUSE_COPROCESSOR6_DISABLED 38
|
||||
#define EXCCAUSE_COPROCESSOR7_DISABLED 39
|
||||
|
||||
/* PS register fields. */
|
||||
|
||||
|
||||
@@ -22,6 +22,7 @@ struct sigcontext {
|
||||
unsigned long sc_acclo;
|
||||
unsigned long sc_acchi;
|
||||
unsigned long sc_a[16];
|
||||
void *sc_xtregs;
|
||||
};
|
||||
|
||||
#endif /* _XTENSA_SIGCONTEXT_H */
|
||||
|
||||
@@ -46,42 +46,6 @@ static inline int irqs_disabled(void)
|
||||
return flags & 0xf;
|
||||
}
|
||||
|
||||
#define RSR_CPENABLE(x) do { \
|
||||
__asm__ __volatile__("rsr %0," __stringify(CPENABLE) : "=a" (x)); \
|
||||
} while(0);
|
||||
#define WSR_CPENABLE(x) do { \
|
||||
__asm__ __volatile__("wsr %0," __stringify(CPENABLE)";rsync" \
|
||||
:: "a" (x));} while(0);
|
||||
|
||||
#define clear_cpenable() __clear_cpenable()
|
||||
|
||||
static inline void __clear_cpenable(void)
|
||||
{
|
||||
#if XCHAL_HAVE_CP
|
||||
unsigned long i = 0;
|
||||
WSR_CPENABLE(i);
|
||||
#endif
|
||||
}
|
||||
|
||||
static inline void enable_coprocessor(int i)
|
||||
{
|
||||
#if XCHAL_HAVE_CP
|
||||
int cp;
|
||||
RSR_CPENABLE(cp);
|
||||
cp |= 1 << i;
|
||||
WSR_CPENABLE(cp);
|
||||
#endif
|
||||
}
|
||||
|
||||
static inline void disable_coprocessor(int i)
|
||||
{
|
||||
#if XCHAL_HAVE_CP
|
||||
int cp;
|
||||
RSR_CPENABLE(cp);
|
||||
cp &= ~(1 << i);
|
||||
WSR_CPENABLE(cp);
|
||||
#endif
|
||||
}
|
||||
|
||||
#define smp_read_barrier_depends() do { } while(0)
|
||||
#define read_barrier_depends() do { } while(0)
|
||||
@@ -111,7 +75,6 @@ extern void *_switch_to(void *last, void *next);
|
||||
|
||||
#define switch_to(prev,next,last) \
|
||||
do { \
|
||||
clear_cpenable(); \
|
||||
(last) = _switch_to(prev, next); \
|
||||
} while(0)
|
||||
|
||||
@@ -244,7 +207,7 @@ static inline void spill_registers(void)
|
||||
"wsr a13," __stringify(SAR) "\n\t"
|
||||
"wsr a14," __stringify(PS) "\n\t"
|
||||
:: "a" (&a0), "a" (&ps)
|
||||
: "a2", "a3", "a12", "a13", "a14", "a15", "memory");
|
||||
: "a2", "a3", "a4", "a7", "a11", "a12", "a13", "a14", "a15", "memory");
|
||||
}
|
||||
|
||||
#define arch_align_stack(x) (x)
|
||||
|
||||
@@ -27,6 +27,21 @@
|
||||
|
||||
#ifndef __ASSEMBLY__
|
||||
|
||||
#if XTENSA_HAVE_COPROCESSORS
|
||||
|
||||
typedef struct xtregs_coprocessor {
|
||||
xtregs_cp0_t cp0;
|
||||
xtregs_cp1_t cp1;
|
||||
xtregs_cp2_t cp2;
|
||||
xtregs_cp3_t cp3;
|
||||
xtregs_cp4_t cp4;
|
||||
xtregs_cp5_t cp5;
|
||||
xtregs_cp6_t cp6;
|
||||
xtregs_cp7_t cp7;
|
||||
} xtregs_coprocessor_t;
|
||||
|
||||
#endif
|
||||
|
||||
struct thread_info {
|
||||
struct task_struct *task; /* main task structure */
|
||||
struct exec_domain *exec_domain; /* execution domain */
|
||||
@@ -38,7 +53,13 @@ struct thread_info {
|
||||
mm_segment_t addr_limit; /* thread address space */
|
||||
struct restart_block restart_block;
|
||||
|
||||
unsigned long cpenable;
|
||||
|
||||
/* Allocate storage for extra user states and coprocessor states. */
|
||||
#if XTENSA_HAVE_COPROCESSORS
|
||||
xtregs_coprocessor_t xtregs_cp;
|
||||
#endif
|
||||
xtregs_user_t xtregs_user;
|
||||
};
|
||||
|
||||
#else /* !__ASSEMBLY__ */
|
||||
|
||||
70
include/asm-xtensa/variant-fsf/tie-asm.h
Normal file
70
include/asm-xtensa/variant-fsf/tie-asm.h
Normal file
@@ -0,0 +1,70 @@
|
||||
/*
|
||||
* This header file contains assembly-language definitions (assembly
|
||||
* macros, etc.) for this specific Xtensa processor's TIE extensions
|
||||
* and options. It is customized to this Xtensa processor configuration.
|
||||
*
|
||||
* This file is subject to the terms and conditions of the GNU General Public
|
||||
* License. See the file "COPYING" in the main directory of this archive
|
||||
* for more details.
|
||||
*
|
||||
* Copyright (C) 1999-2008 Tensilica Inc.
|
||||
*/
|
||||
|
||||
#ifndef _XTENSA_CORE_TIE_ASM_H
|
||||
#define _XTENSA_CORE_TIE_ASM_H
|
||||
|
||||
/* Selection parameter values for save-area save/restore macros: */
|
||||
/* Option vs. TIE: */
|
||||
#define XTHAL_SAS_TIE 0x0001 /* custom extension or coprocessor */
|
||||
#define XTHAL_SAS_OPT 0x0002 /* optional (and not a coprocessor) */
|
||||
/* Whether used automatically by compiler: */
|
||||
#define XTHAL_SAS_NOCC 0x0004 /* not used by compiler w/o special opts/code */
|
||||
#define XTHAL_SAS_CC 0x0008 /* used by compiler without special opts/code */
|
||||
/* ABI handling across function calls: */
|
||||
#define XTHAL_SAS_CALR 0x0010 /* caller-saved */
|
||||
#define XTHAL_SAS_CALE 0x0020 /* callee-saved */
|
||||
#define XTHAL_SAS_GLOB 0x0040 /* global across function calls (in thread) */
|
||||
/* Misc */
|
||||
#define XTHAL_SAS_ALL 0xFFFF /* include all default NCP contents */
|
||||
|
||||
|
||||
|
||||
/* Macro to save all non-coprocessor (extra) custom TIE and optional state
|
||||
* (not including zero-overhead loop registers).
|
||||
* Save area ptr (clobbered): ptr (1 byte aligned)
|
||||
* Scratch regs (clobbered): at1..at4 (only first XCHAL_NCP_NUM_ATMPS needed)
|
||||
*/
|
||||
.macro xchal_ncp_store ptr at1 at2 at3 at4 continue=0 ofs=-1 select=XTHAL_SAS_ALL
|
||||
xchal_sa_start \continue, \ofs
|
||||
.ifeq (XTHAL_SAS_OPT | XTHAL_SAS_CC | XTHAL_SAS_GLOB) & ~\select
|
||||
xchal_sa_align \ptr, 0, 1024-4, 4, 4
|
||||
rur \at1, THREADPTR // threadptr option
|
||||
s32i \at1, \ptr, .Lxchal_ofs_ + 0
|
||||
.set .Lxchal_ofs_, .Lxchal_ofs_ + 4
|
||||
.endif
|
||||
.endm // xchal_ncp_store
|
||||
|
||||
/* Macro to save all non-coprocessor (extra) custom TIE and optional state
|
||||
* (not including zero-overhead loop registers).
|
||||
* Save area ptr (clobbered): ptr (1 byte aligned)
|
||||
* Scratch regs (clobbered): at1..at4 (only first XCHAL_NCP_NUM_ATMPS needed)
|
||||
*/
|
||||
.macro xchal_ncp_load ptr at1 at2 at3 at4 continue=0 ofs=-1 select=XTHAL_SAS_ALL
|
||||
xchal_sa_start \continue, \ofs
|
||||
.ifeq (XTHAL_SAS_OPT | XTHAL_SAS_CC | XTHAL_SAS_GLOB) & ~\select
|
||||
xchal_sa_align \ptr, 0, 1024-4, 4, 4
|
||||
l32i \at1, \ptr, .Lxchal_ofs_ + 0
|
||||
wur \at1, THREADPTR // threadptr option
|
||||
.set .Lxchal_ofs_, .Lxchal_ofs_ + 4
|
||||
.endif
|
||||
.endm // xchal_ncp_load
|
||||
|
||||
|
||||
|
||||
#define XCHAL_NCP_NUM_ATMPS 1
|
||||
|
||||
|
||||
#define XCHAL_SA_NUM_ATMPS 1
|
||||
|
||||
#endif /*_XTENSA_CORE_TIE_ASM_H*/
|
||||
|
||||
@@ -1,22 +1,77 @@
|
||||
/*
|
||||
* Xtensa processor core configuration information.
|
||||
* This header file describes this specific Xtensa processor's TIE extensions
|
||||
* that extend basic Xtensa core functionality. It is customized to this
|
||||
* Xtensa processor configuration.
|
||||
*
|
||||
* This file is subject to the terms and conditions of the GNU General Public
|
||||
* License. See the file "COPYING" in the main directory of this archive
|
||||
* for more details.
|
||||
*
|
||||
* Copyright (C) 1999-2006 Tensilica Inc.
|
||||
* Copyright (C) 1999-2007 Tensilica Inc.
|
||||
*/
|
||||
|
||||
#ifndef XTENSA_TIE_H
|
||||
#define XTENSA_TIE_H
|
||||
|
||||
/*----------------------------------------------------------------------
|
||||
COPROCESSORS and EXTRA STATE
|
||||
----------------------------------------------------------------------*/
|
||||
#ifndef _XTENSA_CORE_TIE_H
|
||||
#define _XTENSA_CORE_TIE_H
|
||||
|
||||
#define XCHAL_CP_NUM 0 /* number of coprocessors */
|
||||
#define XCHAL_CP_MASK 0x00
|
||||
#define XCHAL_CP_MAX 0 /* max CP ID + 1 (0 if none) */
|
||||
#define XCHAL_CP_MASK 0x00 /* bitmask of all CPs by ID */
|
||||
#define XCHAL_CP_PORT_MASK 0x00 /* bitmask of only port CPs */
|
||||
|
||||
#endif /*XTENSA_CONFIG_TIE_H*/
|
||||
/* Basic parameters of each coprocessor: */
|
||||
#define XCHAL_CP7_NAME "XTIOP"
|
||||
#define XCHAL_CP7_IDENT XTIOP
|
||||
#define XCHAL_CP7_SA_SIZE 0 /* size of state save area */
|
||||
#define XCHAL_CP7_SA_ALIGN 1 /* min alignment of save area */
|
||||
#define XCHAL_CP_ID_XTIOP 7 /* coprocessor ID (0..7) */
|
||||
|
||||
/* Filler info for unassigned coprocessors, to simplify arrays etc: */
|
||||
#define XCHAL_NCP_SA_SIZE 0
|
||||
#define XCHAL_NCP_SA_ALIGN 1
|
||||
#define XCHAL_CP0_SA_SIZE 0
|
||||
#define XCHAL_CP0_SA_ALIGN 1
|
||||
#define XCHAL_CP1_SA_SIZE 0
|
||||
#define XCHAL_CP1_SA_ALIGN 1
|
||||
#define XCHAL_CP2_SA_SIZE 0
|
||||
#define XCHAL_CP2_SA_ALIGN 1
|
||||
#define XCHAL_CP3_SA_SIZE 0
|
||||
#define XCHAL_CP3_SA_ALIGN 1
|
||||
#define XCHAL_CP4_SA_SIZE 0
|
||||
#define XCHAL_CP4_SA_ALIGN 1
|
||||
#define XCHAL_CP5_SA_SIZE 0
|
||||
#define XCHAL_CP5_SA_ALIGN 1
|
||||
#define XCHAL_CP6_SA_SIZE 0
|
||||
#define XCHAL_CP6_SA_ALIGN 1
|
||||
|
||||
/* Save area for non-coprocessor optional and custom (TIE) state: */
|
||||
#define XCHAL_NCP_SA_SIZE 0
|
||||
#define XCHAL_NCP_SA_ALIGN 1
|
||||
|
||||
/* Total save area for optional and custom state (NCP + CPn): */
|
||||
#define XCHAL_TOTAL_SA_SIZE 0 /* with 16-byte align padding */
|
||||
#define XCHAL_TOTAL_SA_ALIGN 1 /* actual minimum alignment */
|
||||
|
||||
#define XCHAL_NCP_SA_NUM 0
|
||||
#define XCHAL_NCP_SA_LIST(s)
|
||||
#define XCHAL_CP0_SA_NUM 0
|
||||
#define XCHAL_CP0_SA_LIST(s)
|
||||
#define XCHAL_CP1_SA_NUM 0
|
||||
#define XCHAL_CP1_SA_LIST(s)
|
||||
#define XCHAL_CP2_SA_NUM 0
|
||||
#define XCHAL_CP2_SA_LIST(s)
|
||||
#define XCHAL_CP3_SA_NUM 0
|
||||
#define XCHAL_CP3_SA_LIST(s)
|
||||
#define XCHAL_CP4_SA_NUM 0
|
||||
#define XCHAL_CP4_SA_LIST(s)
|
||||
#define XCHAL_CP5_SA_NUM 0
|
||||
#define XCHAL_CP5_SA_LIST(s)
|
||||
#define XCHAL_CP6_SA_NUM 0
|
||||
#define XCHAL_CP6_SA_LIST(s)
|
||||
#define XCHAL_CP7_SA_NUM 0
|
||||
#define XCHAL_CP7_SA_LIST(s)
|
||||
|
||||
/* Byte length of instruction from its first nibble (op0 field), per FLIX. */
|
||||
#define XCHAL_OP0_FORMAT_LENGTHS 3,3,3,3,3,3,3,3,2,2,2,2,2,2,3,3
|
||||
|
||||
#endif /*_XTENSA_CORE_TIE_H*/
|
||||
|
||||
|
||||
Reference in New Issue
Block a user