aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--arch/xtensa/Makefile2
-rw-r--r--arch/xtensa/boot/boot-elf/Makefile9
-rw-r--r--arch/xtensa/boot/boot-elf/boot.lds.S (renamed from arch/xtensa/boot/boot-elf/boot.ld)4
-rw-r--r--arch/xtensa/boot/boot-redboot/Makefile2
-rw-r--r--arch/xtensa/boot/boot-redboot/boot.ld2
-rw-r--r--arch/xtensa/kernel/asm-offsets.c17
-rw-r--r--arch/xtensa/kernel/coprocessor.S443
-rw-r--r--arch/xtensa/kernel/entry.S355
-rw-r--r--arch/xtensa/kernel/module.c2
-rw-r--r--arch/xtensa/kernel/process.c306
-rw-r--r--arch/xtensa/kernel/ptrace.c351
-rw-r--r--arch/xtensa/kernel/setup.c5
-rw-r--r--arch/xtensa/kernel/signal.c89
-rw-r--r--arch/xtensa/kernel/traps.c20
-rw-r--r--arch/xtensa/kernel/vmlinux.lds.S6
-rw-r--r--arch/xtensa/mm/cache.c7
-rw-r--r--arch/xtensa/mm/init.c2
-rw-r--r--arch/xtensa/mm/misc.S2
-rw-r--r--arch/xtensa/platforms/iss/Makefile (renamed from arch/xtensa/platform-iss/Makefile)0
-rw-r--r--arch/xtensa/platforms/iss/console.c (renamed from arch/xtensa/platform-iss/console.c)1
-rw-r--r--arch/xtensa/platforms/iss/io.c (renamed from arch/xtensa/platform-iss/io.c)0
-rw-r--r--arch/xtensa/platforms/iss/network.c (renamed from arch/xtensa/platform-iss/network.c)2
-rw-r--r--arch/xtensa/platforms/iss/setup.c (renamed from arch/xtensa/platform-iss/setup.c)0
-rw-r--r--include/asm-xtensa/cacheflush.h2
-rw-r--r--include/asm-xtensa/coprocessor.h214
-rw-r--r--include/asm-xtensa/elf.h110
-rw-r--r--include/asm-xtensa/module.h4
-rw-r--r--include/asm-xtensa/pgalloc.h2
-rw-r--r--include/asm-xtensa/pgtable.h8
-rw-r--r--include/asm-xtensa/processor.h13
-rw-r--r--include/asm-xtensa/ptrace.h44
-rw-r--r--include/asm-xtensa/regs.h9
-rw-r--r--include/asm-xtensa/sigcontext.h4
-rw-r--r--include/asm-xtensa/stat.h36
-rw-r--r--include/asm-xtensa/system.h39
-rw-r--r--include/asm-xtensa/thread_info.h21
-rw-r--r--include/asm-xtensa/timex.h8
-rw-r--r--include/asm-xtensa/uaccess.h99
-rw-r--r--include/asm-xtensa/variant-fsf/tie-asm.h70
-rw-r--r--include/asm-xtensa/variant-fsf/tie.h75
40 files changed, 1205 insertions, 1180 deletions
diff --git a/arch/xtensa/Makefile b/arch/xtensa/Makefile
index 56685a883347..4bd1e14c6b90 100644
--- a/arch/xtensa/Makefile
+++ b/arch/xtensa/Makefile
@@ -59,7 +59,7 @@ LIBGCC := $(shell $(CC) $(KBUILD_CFLAGS) -print-libgcc-file-name)
59head-y := arch/xtensa/kernel/head.o 59head-y := arch/xtensa/kernel/head.o
60core-y += arch/xtensa/kernel/ arch/xtensa/mm/ 60core-y += arch/xtensa/kernel/ arch/xtensa/mm/
61ifneq ($(PLATFORM),) 61ifneq ($(PLATFORM),)
62core-y += arch/xtensa/platform-$(PLATFORM)/ 62core-y += arch/xtensa/platforms/$(PLATFORM)/
63endif 63endif
64libs-y += arch/xtensa/lib/ $(LIBGCC) 64libs-y += arch/xtensa/lib/ $(LIBGCC)
65 65
diff --git a/arch/xtensa/boot/boot-elf/Makefile b/arch/xtensa/boot/boot-elf/Makefile
index 734db7f76583..08e8814f8c71 100644
--- a/arch/xtensa/boot/boot-elf/Makefile
+++ b/arch/xtensa/boot/boot-elf/Makefile
@@ -14,25 +14,26 @@ OBJCOPY_ARGS := -O elf32-xtensa-le
14endif 14endif
15 15
16export OBJCOPY_ARGS 16export OBJCOPY_ARGS
17export CPPFLAGS_boot.lds += -P -C
17 18
18boot-y := bootstrap.o 19boot-y := bootstrap.o
19 20
20OBJS := $(addprefix $(obj)/,$(boot-y)) 21OBJS := $(addprefix $(obj)/,$(boot-y))
21 22
22Image: vmlinux $(OBJS) 23Image: vmlinux $(OBJS) arch/$(ARCH)/boot/boot-elf/boot.lds
23 $(OBJCOPY) --strip-all -R .comment -R .xt.insn -O binary \ 24 $(OBJCOPY) --strip-all -R .comment -R .note.gnu.build-id -O binary \
24 vmlinux vmlinux.tmp 25 vmlinux vmlinux.tmp
25 $(OBJCOPY) $(OBJCOPY_ARGS) -R .comment \ 26 $(OBJCOPY) $(OBJCOPY_ARGS) -R .comment \
26 --add-section image=vmlinux.tmp \ 27 --add-section image=vmlinux.tmp \
27 --set-section-flags image=contents,alloc,load,load,data \ 28 --set-section-flags image=contents,alloc,load,load,data \
28 $(OBJS) $@.tmp 29 $(OBJS) $@.tmp
29 $(LD) $(LDFLAGS) $(LDFLAGS_vmlinux) \ 30 $(LD) $(LDFLAGS) $(LDFLAGS_vmlinux) \
30 -T $(srctree)/arch/$(ARCH)/boot/boot-elf/boot.ld \ 31 -T arch/$(ARCH)/boot/boot-elf/boot.lds \
31 -o arch/$(ARCH)/boot/$@.elf $@.tmp 32 -o arch/$(ARCH)/boot/$@.elf $@.tmp
32 rm -f $@.tmp vmlinux.tmp 33 rm -f $@.tmp vmlinux.tmp
33 34
34Image.initrd: vmlinux $(OBJS) 35Image.initrd: vmlinux $(OBJS)
35 $(OBJCOPY) --strip-all -R .comment -R .xt.insn -O binary \ 36 $(OBJCOPY) --strip-all -R .comment -R .note.gnu.build-id -O binary \
36 --add-section .initrd=arch/$(ARCH)/boot/ramdisk \ 37 --add-section .initrd=arch/$(ARCH)/boot/ramdisk \
37 --set-section-flags .initrd=contents,alloc,load,load,data \ 38 --set-section-flags .initrd=contents,alloc,load,load,data \
38 vmlinux vmlinux.tmp 39 vmlinux vmlinux.tmp
diff --git a/arch/xtensa/boot/boot-elf/boot.ld b/arch/xtensa/boot/boot-elf/boot.lds.S
index 4ab06a0a7a6b..849dfcafd518 100644
--- a/arch/xtensa/boot/boot-elf/boot.ld
+++ b/arch/xtensa/boot/boot-elf/boot.lds.S
@@ -1,4 +1,6 @@
1#include <asm/variant/core.h>
1OUTPUT_ARCH(xtensa) 2OUTPUT_ARCH(xtensa)
3ENTRY(_ResetVector)
2 4
3SECTIONS 5SECTIONS
4{ 6{
@@ -61,7 +63,7 @@ SECTIONS
61 _end = .; 63 _end = .;
62 _param_start = .; 64 _param_start = .;
63 65
64 .ResetVector.text 0xfe000020 : 66 .ResetVector.text XCHAL_RESET_VECTOR_VADDR :
65 { 67 {
66 *(.ResetVector.text) 68 *(.ResetVector.text)
67 } 69 }
diff --git a/arch/xtensa/boot/boot-redboot/Makefile b/arch/xtensa/boot/boot-redboot/Makefile
index 74d15d08077b..872029b84435 100644
--- a/arch/xtensa/boot/boot-redboot/Makefile
+++ b/arch/xtensa/boot/boot-redboot/Makefile
@@ -22,7 +22,7 @@ LIBS := arch/xtensa/boot/lib/lib.a arch/xtensa/lib/lib.a
22LIBGCC := $(shell $(CC) $(KBUILD_CFLAGS) -print-libgcc-file-name) 22LIBGCC := $(shell $(CC) $(KBUILD_CFLAGS) -print-libgcc-file-name)
23 23
24zImage: vmlinux $(OBJS) $(LIBS) 24zImage: vmlinux $(OBJS) $(LIBS)
25 $(OBJCOPY) --strip-all -R .comment -R .xt.insn -O binary \ 25 $(OBJCOPY) --strip-all -R .comment -R .note.gnu.build-id -O binary \
26 vmlinux vmlinux.tmp 26 vmlinux vmlinux.tmp
27 gzip -vf9 vmlinux.tmp 27 gzip -vf9 vmlinux.tmp
28 $(OBJCOPY) $(OBJCOPY_ARGS) -R .comment \ 28 $(OBJCOPY) $(OBJCOPY_ARGS) -R .comment \
diff --git a/arch/xtensa/boot/boot-redboot/boot.ld b/arch/xtensa/boot/boot-redboot/boot.ld
index 65b726410e8a..774db20d11f7 100644
--- a/arch/xtensa/boot/boot-redboot/boot.ld
+++ b/arch/xtensa/boot/boot-redboot/boot.ld
@@ -2,7 +2,7 @@ OUTPUT_ARCH(xtensa)
2 2
3SECTIONS 3SECTIONS
4{ 4{
5 .start 0xD0200000 : { *(.start) } 5 .start 0xD1000000 : { *(.start) }
6 6
7 .text : 7 .text :
8 { 8 {
diff --git a/arch/xtensa/kernel/asm-offsets.c b/arch/xtensa/kernel/asm-offsets.c
index d5ffe7b6443e..ef63adadf7f4 100644
--- a/arch/xtensa/kernel/asm-offsets.c
+++ b/arch/xtensa/kernel/asm-offsets.c
@@ -21,7 +21,6 @@
21#include <linux/mm.h> 21#include <linux/mm.h>
22 22
23#include <asm/ptrace.h> 23#include <asm/ptrace.h>
24#include <asm/processor.h>
25#include <asm/uaccess.h> 24#include <asm/uaccess.h>
26 25
27#define DEFINE(sym, val) asm volatile("\n->" #sym " %0 " #val : : "i" (val)) 26#define DEFINE(sym, val) asm volatile("\n->" #sym " %0 " #val : : "i" (val))
@@ -64,6 +63,8 @@ int main(void)
64 DEFINE(PT_SIZE, sizeof(struct pt_regs)); 63 DEFINE(PT_SIZE, sizeof(struct pt_regs));
65 DEFINE(PT_AREG_END, offsetof (struct pt_regs, areg[XCHAL_NUM_AREGS])); 64 DEFINE(PT_AREG_END, offsetof (struct pt_regs, areg[XCHAL_NUM_AREGS]));
66 DEFINE(PT_USER_SIZE, offsetof(struct pt_regs, areg[XCHAL_NUM_AREGS])); 65 DEFINE(PT_USER_SIZE, offsetof(struct pt_regs, areg[XCHAL_NUM_AREGS]));
66 DEFINE(PT_XTREGS_OPT, offsetof(struct pt_regs, xtregs_opt));
67 DEFINE(XTREGS_OPT_SIZE, sizeof(xtregs_opt_t));
67 68
68 /* struct task_struct */ 69 /* struct task_struct */
69 DEFINE(TASK_PTRACE, offsetof (struct task_struct, ptrace)); 70 DEFINE(TASK_PTRACE, offsetof (struct task_struct, ptrace));
@@ -77,7 +78,19 @@ int main(void)
77 /* struct thread_info (offset from start_struct) */ 78 /* struct thread_info (offset from start_struct) */
78 DEFINE(THREAD_RA, offsetof (struct task_struct, thread.ra)); 79 DEFINE(THREAD_RA, offsetof (struct task_struct, thread.ra));
79 DEFINE(THREAD_SP, offsetof (struct task_struct, thread.sp)); 80 DEFINE(THREAD_SP, offsetof (struct task_struct, thread.sp));
80 DEFINE(THREAD_CP_SAVE, offsetof (struct task_struct, thread.cp_save)); 81 DEFINE(THREAD_CPENABLE, offsetof (struct thread_info, cpenable));
82#if XTENSA_HAVE_COPROCESSORS
83 DEFINE(THREAD_XTREGS_CP0, offsetof (struct thread_info, xtregs_cp));
84 DEFINE(THREAD_XTREGS_CP1, offsetof (struct thread_info, xtregs_cp));
85 DEFINE(THREAD_XTREGS_CP2, offsetof (struct thread_info, xtregs_cp));
86 DEFINE(THREAD_XTREGS_CP3, offsetof (struct thread_info, xtregs_cp));
87 DEFINE(THREAD_XTREGS_CP4, offsetof (struct thread_info, xtregs_cp));
88 DEFINE(THREAD_XTREGS_CP5, offsetof (struct thread_info, xtregs_cp));
89 DEFINE(THREAD_XTREGS_CP6, offsetof (struct thread_info, xtregs_cp));
90 DEFINE(THREAD_XTREGS_CP7, offsetof (struct thread_info, xtregs_cp));
91#endif
92 DEFINE(THREAD_XTREGS_USER, offsetof (struct thread_info, xtregs_user));
93 DEFINE(XTREGS_USER_SIZE, sizeof(xtregs_user_t));
81 DEFINE(THREAD_CURRENT_DS, offsetof (struct task_struct, thread.current_ds)); 94 DEFINE(THREAD_CURRENT_DS, offsetof (struct task_struct, thread.current_ds));
82 95
83 /* struct mm_struct */ 96 /* struct mm_struct */
diff --git a/arch/xtensa/kernel/coprocessor.S b/arch/xtensa/kernel/coprocessor.S
index 01bcb9fcfcbd..2bc1e145c0a4 100644
--- a/arch/xtensa/kernel/coprocessor.S
+++ b/arch/xtensa/kernel/coprocessor.S
@@ -8,193 +8,328 @@
8 * License. See the file "COPYING" in the main directory of this archive 8 * License. See the file "COPYING" in the main directory of this archive
9 * for more details. 9 * for more details.
10 * 10 *
11 * Copyright (C) 2003 - 2005 Tensilica Inc. 11 * Copyright (C) 2003 - 2007 Tensilica Inc.
12 *
13 * Marc Gauthier <marc@tensilica.com> <marc@alumni.uwaterloo.ca>
14 */ 12 */
15 13
16/*
17 * This module contains a table that describes the layout of the various
18 * custom registers and states associated with each coprocessor, as well
19 * as those not associated with any coprocessor ("extra state").
20 * This table is included with core dumps and is available via the ptrace
21 * interface, allowing the layout of such register/state information to
22 * be modified in the kernel without affecting the debugger. Each
23 * register or state is identified using a 32-bit "libdb target number"
24 * assigned when the Xtensa processor is generated.
25 */
26 14
27#include <linux/linkage.h> 15#include <linux/linkage.h>
16#include <asm/asm-offsets.h>
28#include <asm/processor.h> 17#include <asm/processor.h>
18#include <asm/coprocessor.h>
19#include <asm/thread_info.h>
20#include <asm/uaccess.h>
21#include <asm/unistd.h>
22#include <asm/ptrace.h>
23#include <asm/current.h>
24#include <asm/pgtable.h>
25#include <asm/page.h>
26#include <asm/signal.h>
27#include <asm/tlbflush.h>
29 28
30#if XCHAL_HAVE_CP 29/*
30 * Entry condition:
31 *
32 * a0: trashed, original value saved on stack (PT_AREG0)
33 * a1: a1
34 * a2: new stack pointer, original in DEPC
35 * a3: dispatch table
36 * depc: a2, original value saved on stack (PT_DEPC)
37 * excsave_1: a3
38 *
39 * PT_DEPC >= VALID_DOUBLE_EXCEPTION_ADDRESS: double exception, DEPC
40 * < VALID_DOUBLE_EXCEPTION_ADDRESS: regular exception
41 */
31 42
32#define CP_LAST ((XCHAL_CP_MAX - 1) * COPROCESSOR_INFO_SIZE) 43/* IO protection is currently unsupported. */
33 44
34ENTRY(release_coprocessors) 45ENTRY(fast_io_protect)
46 wsr a0, EXCSAVE_1
47 movi a0, unrecoverable_exception
48 callx0 a0
35 49
36 entry a1, 16 50#if XTENSA_HAVE_COPROCESSORS
37 # a2: task
38 movi a3, 1 << XCHAL_CP_MAX # a3: coprocessor-bit
39 movi a4, coprocessor_info+CP_LAST # a4: owner-table
40 # a5: tmp
41 movi a6, 0 # a6: 0
42 rsil a7, LOCKLEVEL # a7: PS
43 51
441: /* Check if task is coprocessor owner of coprocessor[i]. */ 52/*
53 * Macros for lazy context switch.
54 */
45 55
46 l32i a5, a4, COPROCESSOR_INFO_OWNER 56#define SAVE_CP_REGS(x) \
47 srli a3, a3, 1 57 .align 4; \
48 beqz a3, 1f 58 .Lsave_cp_regs_cp##x: \
49 addi a4, a4, -8 59 .if XTENSA_HAVE_COPROCESSOR(x); \
50 beq a2, a5, 1b 60 xchal_cp##x##_store a2 a4 a5 a6 a7; \
61 .endif; \
62 jx a0
51 63
52 /* Found an entry: Clear entry CPENABLE bit to disable CP. */ 64#define SAVE_CP_REGS_TAB(x) \
65 .if XTENSA_HAVE_COPROCESSOR(x); \
66 .long .Lsave_cp_regs_cp##x - .Lsave_cp_regs_jump_table; \
67 .else; \
68 .long 0; \
69 .endif; \
70 .long THREAD_XTREGS_CP##x
53 71
54 rsr a5, CPENABLE
55 s32i a6, a4, COPROCESSOR_INFO_OWNER
56 xor a5, a3, a5
57 wsr a5, CPENABLE
58 72
59 bnez a3, 1b 73#define LOAD_CP_REGS(x) \
74 .align 4; \
75 .Lload_cp_regs_cp##x: \
76 .if XTENSA_HAVE_COPROCESSOR(x); \
77 xchal_cp##x##_load a2 a4 a5 a6 a7; \
78 .endif; \
79 jx a0
60 80
611: wsr a7, PS 81#define LOAD_CP_REGS_TAB(x) \
62 rsync 82 .if XTENSA_HAVE_COPROCESSOR(x); \
63 retw 83 .long .Lload_cp_regs_cp##x - .Lload_cp_regs_jump_table; \
84 .else; \
85 .long 0; \
86 .endif; \
87 .long THREAD_XTREGS_CP##x
64 88
89 SAVE_CP_REGS(0)
90 SAVE_CP_REGS(1)
91 SAVE_CP_REGS(2)
92 SAVE_CP_REGS(3)
93 SAVE_CP_REGS(4)
94 SAVE_CP_REGS(5)
95 SAVE_CP_REGS(6)
96 SAVE_CP_REGS(7)
65 97
66ENTRY(disable_coprocessor) 98 LOAD_CP_REGS(0)
67 entry sp, 16 99 LOAD_CP_REGS(1)
68 rsil a7, LOCKLEVEL 100 LOAD_CP_REGS(2)
69 rsr a3, CPENABLE 101 LOAD_CP_REGS(3)
70 movi a4, 1 102 LOAD_CP_REGS(4)
71 ssl a2 103 LOAD_CP_REGS(5)
72 sll a4, a4 104 LOAD_CP_REGS(6)
73 and a4, a3, a4 105 LOAD_CP_REGS(7)
74 xor a3, a3, a4
75 wsr a3, CPENABLE
76 wsr a7, PS
77 rsync
78 retw
79 106
80ENTRY(enable_coprocessor) 107 .align 4
81 entry sp, 16 108.Lsave_cp_regs_jump_table:
82 rsil a7, LOCKLEVEL 109 SAVE_CP_REGS_TAB(0)
83 rsr a3, CPENABLE 110 SAVE_CP_REGS_TAB(1)
84 movi a4, 1 111 SAVE_CP_REGS_TAB(2)
85 ssl a2 112 SAVE_CP_REGS_TAB(3)
86 sll a4, a4 113 SAVE_CP_REGS_TAB(4)
87 or a3, a3, a4 114 SAVE_CP_REGS_TAB(5)
88 wsr a3, CPENABLE 115 SAVE_CP_REGS_TAB(6)
89 wsr a7, PS 116 SAVE_CP_REGS_TAB(7)
90 rsync
91 retw
92 117
118.Lload_cp_regs_jump_table:
119 LOAD_CP_REGS_TAB(0)
120 LOAD_CP_REGS_TAB(1)
121 LOAD_CP_REGS_TAB(2)
122 LOAD_CP_REGS_TAB(3)
123 LOAD_CP_REGS_TAB(4)
124 LOAD_CP_REGS_TAB(5)
125 LOAD_CP_REGS_TAB(6)
126 LOAD_CP_REGS_TAB(7)
93 127
94ENTRY(save_coprocessor_extra) 128/*
95 entry sp, 16 129 * coprocessor_save(buffer, index)
96 xchal_extra_store_funcbody 130 * a2 a3
97 retw 131 * coprocessor_load(buffer, index)
132 * a2 a3
133 *
134 * Save or load coprocessor registers for coprocessor 'index'.
135 * The register values are saved to or loaded from them 'buffer' address.
136 *
137 * Note that these functions don't update the coprocessor_owner information!
138 *
139 */
98 140
99ENTRY(restore_coprocessor_extra) 141ENTRY(coprocessor_save)
100 entry sp, 16 142 entry a1, 32
101 xchal_extra_load_funcbody 143 s32i a0, a1, 0
144 movi a0, .Lsave_cp_regs_jump_table
145 addx8 a3, a3, a0
146 l32i a3, a3, 0
147 beqz a3, 1f
148 add a0, a0, a3
149 callx0 a0
1501: l32i a0, a1, 0
102 retw 151 retw
103 152
104ENTRY(save_coprocessor_registers) 153ENTRY(coprocessor_load)
105 entry sp, 16 154 entry a1, 32
106 xchal_cpi_store_funcbody 155 s32i a0, a1, 0
156 movi a0, .Lload_cp_regs_jump_table
157 addx4 a3, a3, a0
158 l32i a3, a3, 0
159 beqz a3, 1f
160 add a0, a0, a3
161 callx0 a0
1621: l32i a0, a1, 0
107 retw 163 retw
108 164
109ENTRY(restore_coprocessor_registers) 165/*
110 entry sp, 16 166 * coprocessor_flush(struct task_info*, index)
111 xchal_cpi_load_funcbody 167 * a2 a3
168 * coprocessor_restore(struct task_info*, index)
169 * a2 a3
170 *
171 * Save or load coprocessor registers for coprocessor 'index'.
172 * The register values are saved to or loaded from the coprocessor area
173 * inside the task_info structure.
174 *
175 * Note that these functions don't update the coprocessor_owner information!
176 *
177 */
178
179
180ENTRY(coprocessor_flush)
181 entry a1, 32
182 s32i a0, a1, 0
183 movi a0, .Lsave_cp_regs_jump_table
184 addx8 a3, a3, a0
185 l32i a4, a3, 4
186 l32i a3, a3, 0
187 add a2, a2, a4
188 beqz a3, 1f
189 add a0, a0, a3
190 callx0 a0
1911: l32i a0, a1, 0
112 retw 192 retw
113 193
194ENTRY(coprocessor_restore)
195 entry a1, 32
196 s32i a0, a1, 0
197 movi a0, .Lload_cp_regs_jump_table
198 addx4 a3, a3, a0
199 l32i a4, a3, 4
200 l32i a3, a3, 0
201 add a2, a2, a4
202 beqz a3, 1f
203 add a0, a0, a3
204 callx0 a0
2051: l32i a0, a1, 0
206 retw
114 207
115/* 208/*
116 * The Xtensa compile-time HAL (core.h) XCHAL_*_SA_CONTENTS_LIBDB macros 209 * Entry condition:
117 * describe the contents of coprocessor & extra save areas in terms of
118 * undefined CONTENTS_LIBDB_{SREG,UREG,REGF} macros. We define these
119 * latter macros here; they expand into a table of the format we want.
120 * The general format is:
121 * 210 *
122 * CONTENTS_LIBDB_SREG(libdbnum, offset, size, align, rsv1, name, sregnum, 211 * a0: trashed, original value saved on stack (PT_AREG0)
123 * bitmask, rsv2, rsv3) 212 * a1: a1
124 * CONTENTS_LIBDB_UREG(libdbnum, offset, size, align, rsv1, name, uregnum, 213 * a2: new stack pointer, original in DEPC
125 * bitmask, rsv2, rsv3) 214 * a3: dispatch table
126 * CONTENTS_LIBDB_REGF(libdbnum, offset, size, align, rsv1, name, index, 215 * depc: a2, original value saved on stack (PT_DEPC)
127 * numentries, contentsize, regname_base, 216 * excsave_1: a3
128 * regfile_name, rsv2, rsv3)
129 * 217 *
130 * For this table, we only care about the <libdbnum>, <offset> and <size> 218 * PT_DEPC >= VALID_DOUBLE_EXCEPTION_ADDRESS: double exception, DEPC
131 * fields. 219 * < VALID_DOUBLE_EXCEPTION_ADDRESS: regular exception
132 */ 220 */
133 221
134/* Map all XCHAL CONTENTS macros to the reg_entry asm macro defined below: */ 222ENTRY(fast_coprocessor_double)
135 223 wsr a0, EXCSAVE_1
136#define CONTENTS_LIBDB_SREG(libdbnum,offset,size,align,rsv1,name,sregnum, \ 224 movi a0, unrecoverable_exception
137 bitmask, rsv2, rsv3) \ 225 callx0 a0
138 reg_entry libdbnum, offset, size ;
139#define CONTENTS_LIBDB_UREG(libdbnum,offset,size,align,rsv1,name,uregnum, \
140 bitmask, rsv2, rsv3) \
141 reg_entry libdbnum, offset, size ;
142#define CONTENTS_LIBDB_REGF(libdbnum, offset, size, align, rsv1, name, index, \
143 numentries, contentsize, regname_base, \
144 regfile_name, rsv2, rsv3) \
145 reg_entry libdbnum, offset, size ;
146
147/* A single table entry: */
148 .macro reg_entry libdbnum, offset, size
149 .ifne (__last_offset-(__last_group_offset+\offset))
150 /* padding entry */
151 .word (0xFC000000+__last_offset-(__last_group_offset+\offset))
152 .endif
153 .word \libdbnum /* actual entry */
154 .set __last_offset, __last_group_offset+\offset+\size
155 .endm /* reg_entry */
156
157
158/* Table entry that marks the beginning of a group (coprocessor or "extra"): */
159 .macro reg_group cpnum, num_entries, align
160 .set __last_group_offset, (__last_offset + \align- 1) & -\align
161 .ifne \num_entries
162 .word 0xFD000000+(\cpnum<<16)+\num_entries
163 .endif
164 .endm /* reg_group */
165 226
166/*
167 * Register info tables.
168 */
169 227
170 .section .rodata, "a" 228ENTRY(fast_coprocessor)
171 .globl _xtensa_reginfo_tables 229
172 .globl _xtensa_reginfo_table_size 230 /* Save remaining registers a1-a3 and SAR */
173 .align 4 231
174_xtensa_reginfo_table_size: 232 xsr a3, EXCSAVE_1
175 .word _xtensa_reginfo_table_end - _xtensa_reginfo_tables 233 s32i a3, a2, PT_AREG3
176 234 rsr a3, SAR
177_xtensa_reginfo_tables: 235 s32i a1, a2, PT_AREG1
178 .set __last_offset, 0 236 s32i a3, a2, PT_SAR
179 reg_group 0xFF, XCHAL_EXTRA_SA_CONTENTS_LIBDB_NUM, XCHAL_EXTRA_SA_ALIGN 237 mov a1, a2
180 XCHAL_EXTRA_SA_CONTENTS_LIBDB 238 rsr a2, DEPC
181 reg_group 0, XCHAL_CP0_SA_CONTENTS_LIBDB_NUM, XCHAL_CP0_SA_ALIGN 239 s32i a2, a1, PT_AREG2
182 XCHAL_CP0_SA_CONTENTS_LIBDB 240
183 reg_group 1, XCHAL_CP1_SA_CONTENTS_LIBDB_NUM, XCHAL_CP1_SA_ALIGN 241 /*
184 XCHAL_CP1_SA_CONTENTS_LIBDB 242 * The hal macros require up to 4 temporary registers. We use a3..a6.
185 reg_group 2, XCHAL_CP2_SA_CONTENTS_LIBDB_NUM, XCHAL_CP2_SA_ALIGN 243 */
186 XCHAL_CP2_SA_CONTENTS_LIBDB 244
187 reg_group 3, XCHAL_CP3_SA_CONTENTS_LIBDB_NUM, XCHAL_CP3_SA_ALIGN 245 s32i a4, a1, PT_AREG4
188 XCHAL_CP3_SA_CONTENTS_LIBDB 246 s32i a5, a1, PT_AREG5
189 reg_group 4, XCHAL_CP4_SA_CONTENTS_LIBDB_NUM, XCHAL_CP4_SA_ALIGN 247 s32i a6, a1, PT_AREG6
190 XCHAL_CP4_SA_CONTENTS_LIBDB 248
191 reg_group 5, XCHAL_CP5_SA_CONTENTS_LIBDB_NUM, XCHAL_CP5_SA_ALIGN 249 /* Find coprocessor number. Subtract first CP EXCCAUSE from EXCCAUSE */
192 XCHAL_CP5_SA_CONTENTS_LIBDB 250
193 reg_group 6, XCHAL_CP6_SA_CONTENTS_LIBDB_NUM, XCHAL_CP6_SA_ALIGN 251 rsr a3, EXCCAUSE
194 XCHAL_CP6_SA_CONTENTS_LIBDB 252 addi a3, a3, -EXCCAUSE_COPROCESSOR0_DISABLED
195 reg_group 7, XCHAL_CP7_SA_CONTENTS_LIBDB_NUM, XCHAL_CP7_SA_ALIGN 253
196 XCHAL_CP7_SA_CONTENTS_LIBDB 254 /* Set corresponding CPENABLE bit -> (sar:cp-index, a3: 1<<cp-index)*/
197 .word 0xFC000000 /* invalid register number,marks end of table*/ 255
198_xtensa_reginfo_table_end: 256 ssl a3 # SAR: 32 - coprocessor_number
199#endif 257 movi a2, 1
258 rsr a0, CPENABLE
259 sll a2, a2
260 or a0, a0, a2
261 wsr a0, CPENABLE
262 rsync
263
264 /* Retrieve previous owner. (a3 still holds CP number) */
265
266 movi a0, coprocessor_owner # list of owners
267 addx4 a0, a3, a0 # entry for CP
268 l32i a4, a0, 0
269
270 beqz a4, 1f # skip 'save' if no previous owner
271
272 /* Disable coprocessor for previous owner. (a2 = 1 << CP number) */
273
274 l32i a5, a4, THREAD_CPENABLE
275 xor a5, a5, a2 # (1 << cp-id) still in a2
276 s32i a5, a4, THREAD_CPENABLE
277
278 /*
279 * Get context save area and 'call' save routine.
280 * (a4 still holds previous owner (thread_info), a3 CP number)
281 */
282
283 movi a5, .Lsave_cp_regs_jump_table
284 movi a0, 2f # a0: 'return' address
285 addx8 a3, a3, a5 # a3: coprocessor number
286 l32i a2, a3, 4 # a2: xtregs offset
287 l32i a3, a3, 0 # a3: jump offset
288 add a2, a2, a4
289 add a4, a3, a5 # a4: address of save routine
290 jx a4
291
292 /* Note that only a0 and a1 were preserved. */
293
2942: rsr a3, EXCCAUSE
295 addi a3, a3, -EXCCAUSE_COPROCESSOR0_DISABLED
296 movi a0, coprocessor_owner
297 addx4 a0, a3, a0
298
299 /* Set new 'owner' (a0 points to the CP owner, a3 contains the CP nr) */
300
3011: GET_THREAD_INFO (a4, a1)
302 s32i a4, a0, 0
303
304 /* Get context save area and 'call' load routine. */
305
306 movi a5, .Lload_cp_regs_jump_table
307 movi a0, 1f
308 addx8 a3, a3, a5
309 l32i a2, a3, 4 # a2: xtregs offset
310 l32i a3, a3, 0 # a3: jump offset
311 add a2, a2, a4
312 add a4, a3, a5
313 jx a4
314
315 /* Restore all registers and return from exception handler. */
316
3171: l32i a6, a1, PT_AREG6
318 l32i a5, a1, PT_AREG5
319 l32i a4, a1, PT_AREG4
320
321 l32i a0, a1, PT_SAR
322 l32i a3, a1, PT_AREG3
323 l32i a2, a1, PT_AREG2
324 wsr a0, SAR
325 l32i a0, a1, PT_AREG0
326 l32i a1, a1, PT_AREG1
327
328 rfe
329
330 .data
331ENTRY(coprocessor_owner)
332 .fill XCHAL_CP_MAX, 4, 0
333
334#endif /* XTENSA_HAVE_COPROCESSORS */
200 335
diff --git a/arch/xtensa/kernel/entry.S b/arch/xtensa/kernel/entry.S
index 91a689eca43d..dfd35dcc1cb5 100644
--- a/arch/xtensa/kernel/entry.S
+++ b/arch/xtensa/kernel/entry.S
@@ -25,10 +25,10 @@
25#include <asm/page.h> 25#include <asm/page.h>
26#include <asm/signal.h> 26#include <asm/signal.h>
27#include <asm/tlbflush.h> 27#include <asm/tlbflush.h>
28#include <asm/variant/tie-asm.h>
28 29
29/* Unimplemented features. */ 30/* Unimplemented features. */
30 31
31#undef SIGNAL_HANDLING_IN_DOUBLE_EXCEPTION
32#undef KERNEL_STACK_OVERFLOW_CHECK 32#undef KERNEL_STACK_OVERFLOW_CHECK
33#undef PREEMPTIBLE_KERNEL 33#undef PREEMPTIBLE_KERNEL
34#undef ALLOCA_EXCEPTION_IN_IRAM 34#undef ALLOCA_EXCEPTION_IN_IRAM
@@ -214,19 +214,7 @@ _user_exception:
214 214
215 /* We are back to the original stack pointer (a1) */ 215 /* We are back to the original stack pointer (a1) */
216 216
2172: 2172: /* Now, jump to the common exception handler. */
218#if XCHAL_EXTRA_SA_SIZE
219
220 /* For user exceptions, save the extra state into the user's TCB.
221 * Note: We must assume that xchal_extra_store_funcbody destroys a2..a15
222 */
223
224 GET_CURRENT(a2,a1)
225 addi a2, a2, THREAD_CP_SAVE
226 xchal_extra_store_funcbody
227#endif
228
229 /* Now, jump to the common exception handler. */
230 218
231 j common_exception 219 j common_exception
232 220
@@ -382,6 +370,10 @@ common_exception:
382 s32i a2, a1, PT_LBEG 370 s32i a2, a1, PT_LBEG
383 s32i a3, a1, PT_LEND 371 s32i a3, a1, PT_LEND
384 372
373 /* Save optional registers. */
374
375 save_xtregs_opt a1 a2 a4 a5 a6 a7 PT_XTREGS_OPT
376
385 /* Go to second-level dispatcher. Set up parameters to pass to the 377 /* Go to second-level dispatcher. Set up parameters to pass to the
386 * exception handler and call the exception handler. 378 * exception handler and call the exception handler.
387 */ 379 */
@@ -403,74 +395,49 @@ common_exception_return:
403 /* Jump if we are returning from kernel exceptions. */ 395 /* Jump if we are returning from kernel exceptions. */
404 396
4051: l32i a3, a1, PT_PS 3971: l32i a3, a1, PT_PS
406 _bbsi.l a3, PS_UM_BIT, 2f 398 _bbci.l a3, PS_UM_BIT, 4f
407 j kernel_exception_exit
408 399
409 /* Specific to a user exception exit: 400 /* Specific to a user exception exit:
410 * We need to check some flags for signal handling and rescheduling, 401 * We need to check some flags for signal handling and rescheduling,
411 * and have to restore WB and WS, extra states, and all registers 402 * and have to restore WB and WS, extra states, and all registers
412 * in the register file that were in use in the user task. 403 * in the register file that were in use in the user task.
413 */ 404 * Note that we don't disable interrupts here.
414
4152: wsr a3, PS /* disable interrupts */
416
417 /* Check for signals (keep interrupts disabled while we read TI_FLAGS)
418 * Note: PS.INTLEVEL = 0, PS.EXCM = 1
419 */ 405 */
420 406
421 GET_THREAD_INFO(a2,a1) 407 GET_THREAD_INFO(a2,a1)
422 l32i a4, a2, TI_FLAGS 408 l32i a4, a2, TI_FLAGS
423 409
424 /* Enable interrupts again.
425 * Note: When we get here, we certainly have handled any interrupts.
426 * (Hint: There is only one user exception frame on stack)
427 */
428
429 movi a3, 1 << PS_WOE_BIT
430
431 _bbsi.l a4, TIF_NEED_RESCHED, 3f 410 _bbsi.l a4, TIF_NEED_RESCHED, 3f
432 _bbci.l a4, TIF_SIGPENDING, 4f 411 _bbci.l a4, TIF_SIGPENDING, 4f
433 412
434#ifndef SIGNAL_HANDLING_IN_DOUBLE_EXCEPTION
435 l32i a4, a1, PT_DEPC 413 l32i a4, a1, PT_DEPC
436 bgeui a4, VALID_DOUBLE_EXCEPTION_ADDRESS, 4f 414 bgeui a4, VALID_DOUBLE_EXCEPTION_ADDRESS, 4f
437#endif
438 415
439 /* Reenable interrupts and call do_signal() */ 416 /* Call do_signal() */
440 417
441 wsr a3, PS
442 movi a4, do_signal # int do_signal(struct pt_regs*, sigset_t*) 418 movi a4, do_signal # int do_signal(struct pt_regs*, sigset_t*)
443 mov a6, a1 419 mov a6, a1
444 movi a7, 0 420 movi a7, 0
445 callx4 a4 421 callx4 a4
446 j 1b 422 j 1b
447 423
4483: /* Reenable interrupts and reschedule */ 4243: /* Reschedule */
449 425
450 wsr a3, PS
451 movi a4, schedule # void schedule (void) 426 movi a4, schedule # void schedule (void)
452 callx4 a4 427 callx4 a4
453 j 1b 428 j 1b
454 429
455 /* Restore the state of the task and return from the exception. */ 4304: /* Restore optional registers. */
456
4574: /* a2 holds GET_CURRENT(a2,a1) */
458
459#if XCHAL_EXTRA_SA_SIZE
460 431
461 /* For user exceptions, restore the extra state from the user's TCB. */ 432 load_xtregs_opt a1 a2 a4 a5 a6 a7 PT_XTREGS_OPT
462 433
463 /* Note: a2 still contains GET_CURRENT(a2,a1) */ 434 wsr a3, PS /* disable interrupts */
464 addi a2, a2, THREAD_CP_SAVE
465 xchal_extra_load_funcbody
466 435
467 /* We must assume that xchal_extra_store_funcbody destroys 436 _bbci.l a3, PS_UM_BIT, kernel_exception_exit
468 * registers a2..a15. FIXME, this list can eventually be
469 * reduced once real register requirements of the macro are
470 * finalized. */
471 437
472#endif /* XCHAL_EXTRA_SA_SIZE */ 438user_exception_exit:
473 439
440 /* Restore the state of the task and return from the exception. */
474 441
475 /* Switch to the user thread WINDOWBASE. Save SP temporarily in DEPC */ 442 /* Switch to the user thread WINDOWBASE. Save SP temporarily in DEPC */
476 443
@@ -536,10 +503,6 @@ common_exception_return:
536 503
537kernel_exception_exit: 504kernel_exception_exit:
538 505
539 /* Disable interrupts (a3 holds PT_PS) */
540
541 wsr a3, PS
542
543#ifdef PREEMPTIBLE_KERNEL 506#ifdef PREEMPTIBLE_KERNEL
544 507
545#ifdef CONFIG_PREEMPT 508#ifdef CONFIG_PREEMPT
@@ -618,6 +581,8 @@ kernel_exception_exit:
618 581
619common_exception_exit: 582common_exception_exit:
620 583
584 /* Restore address registers. */
585
621 _bbsi.l a2, 1, 1f 586 _bbsi.l a2, 1, 1f
622 l32i a4, a1, PT_AREG4 587 l32i a4, a1, PT_AREG4
623 l32i a5, a1, PT_AREG5 588 l32i a5, a1, PT_AREG5
@@ -1150,7 +1115,6 @@ CATCH
1150 * excsave_1: a3 1115 * excsave_1: a3
1151 * 1116 *
1152 * Note: We assume the stack pointer is EXC_TABLE_KSTK in the fixup handler. 1117 * Note: We assume the stack pointer is EXC_TABLE_KSTK in the fixup handler.
1153 * Note: We don't need to save a2 in depc (return value)
1154 */ 1118 */
1155 1119
1156ENTRY(fast_syscall_spill_registers) 1120ENTRY(fast_syscall_spill_registers)
@@ -1166,29 +1130,31 @@ ENTRY(fast_syscall_spill_registers)
1166 1130
1167 rsr a0, SAR 1131 rsr a0, SAR
1168 xsr a3, EXCSAVE_1 # restore a3 and excsave_1 1132 xsr a3, EXCSAVE_1 # restore a3 and excsave_1
1169 s32i a0, a2, PT_AREG4 # store SAR to PT_AREG4
1170 s32i a3, a2, PT_AREG3 1133 s32i a3, a2, PT_AREG3
1134 s32i a4, a2, PT_AREG4
1135 s32i a0, a2, PT_AREG5 # store SAR to PT_AREG5
1171 1136
1172 /* The spill routine might clobber a7, a11, and a15. */ 1137 /* The spill routine might clobber a7, a11, and a15. */
1173 1138
1174 s32i a7, a2, PT_AREG5 1139 s32i a7, a2, PT_AREG7
1175 s32i a11, a2, PT_AREG6 1140 s32i a11, a2, PT_AREG11
1176 s32i a15, a2, PT_AREG7 1141 s32i a15, a2, PT_AREG15
1177 1142
1178 call0 _spill_registers # destroys a3, DEPC, and SAR 1143 call0 _spill_registers # destroys a3, a4, and SAR
1179 1144
1180 /* Advance PC, restore registers and SAR, and return from exception. */ 1145 /* Advance PC, restore registers and SAR, and return from exception. */
1181 1146
1182 l32i a3, a2, PT_AREG4 1147 l32i a3, a2, PT_AREG5
1148 l32i a4, a2, PT_AREG4
1183 l32i a0, a2, PT_AREG0 1149 l32i a0, a2, PT_AREG0
1184 wsr a3, SAR 1150 wsr a3, SAR
1185 l32i a3, a2, PT_AREG3 1151 l32i a3, a2, PT_AREG3
1186 1152
1187 /* Restore clobbered registers. */ 1153 /* Restore clobbered registers. */
1188 1154
1189 l32i a7, a2, PT_AREG5 1155 l32i a7, a2, PT_AREG7
1190 l32i a11, a2, PT_AREG6 1156 l32i a11, a2, PT_AREG11
1191 l32i a15, a2, PT_AREG7 1157 l32i a15, a2, PT_AREG15
1192 1158
1193 movi a2, 0 1159 movi a2, 0
1194 rfe 1160 rfe
@@ -1247,16 +1213,6 @@ fast_syscall_spill_registers_fixup:
1247 * Note: This frame might be the same as above. 1213 * Note: This frame might be the same as above.
1248 */ 1214 */
1249 1215
1250#ifdef SIGNAL_HANDLING_IN_DOUBLE_EXCEPTION
1251 /* Restore registers we precautiously saved.
1252 * We have the value of the 'right' a3
1253 */
1254
1255 l32i a7, a2, PT_AREG5
1256 l32i a11, a2, PT_AREG6
1257 l32i a15, a2, PT_AREG7
1258#endif
1259
1260 /* Setup stack pointer. */ 1216 /* Setup stack pointer. */
1261 1217
1262 addi a2, a2, -PT_USER_SIZE 1218 addi a2, a2, -PT_USER_SIZE
@@ -1271,9 +1227,9 @@ fast_syscall_spill_registers_fixup:
1271 1227
1272 movi a3, exc_table 1228 movi a3, exc_table
1273 rsr a0, EXCCAUSE 1229 rsr a0, EXCCAUSE
1274 addx4 a0, a0, a3 # find entry in table 1230 addx4 a0, a0, a3 # find entry in table
1275 l32i a0, a0, EXC_TABLE_FAST_USER # load handler 1231 l32i a0, a0, EXC_TABLE_FAST_USER # load handler
1276 jx a0 1232 jx a0
1277 1233
1278fast_syscall_spill_registers_fixup_return: 1234fast_syscall_spill_registers_fixup_return:
1279 1235
@@ -1290,14 +1246,6 @@ fast_syscall_spill_registers_fixup_return:
1290 s32i a2, a3, EXC_TABLE_PARAM 1246 s32i a2, a3, EXC_TABLE_PARAM
1291 l32i a2, a3, EXC_TABLE_KSTK 1247 l32i a2, a3, EXC_TABLE_KSTK
1292 1248
1293#ifdef SIGNAL_HANDLING_IN_DOUBLE_EXCEPTION
1294 /* Save registers again that might be clobbered. */
1295
1296 s32i a7, a2, PT_AREG5
1297 s32i a11, a2, PT_AREG6
1298 s32i a15, a2, PT_AREG7
1299#endif
1300
1301 /* Load WB at the time the exception occurred. */ 1249 /* Load WB at the time the exception occurred. */
1302 1250
1303 rsr a3, SAR # WB is still in SAR 1251 rsr a3, SAR # WB is still in SAR
@@ -1319,7 +1267,7 @@ fast_syscall_spill_registers_fixup_return:
1319 * This is not a real function. The following conditions must be met: 1267 * This is not a real function. The following conditions must be met:
1320 * 1268 *
1321 * - must be called with call0. 1269 * - must be called with call0.
1322 * - uses DEPC, a3 and SAR. 1270 * - uses a3, a4 and SAR.
1323 * - the last 'valid' register of each frame are clobbered. 1271 * - the last 'valid' register of each frame are clobbered.
1324 * - the caller must have registered a fixup handler 1272 * - the caller must have registered a fixup handler
1325 * (or be inside a critical section) 1273 * (or be inside a critical section)
@@ -1331,41 +1279,39 @@ ENTRY(_spill_registers)
1331 /* 1279 /*
1332 * Rotate ws so that the current windowbase is at bit 0. 1280 * Rotate ws so that the current windowbase is at bit 0.
1333 * Assume ws = xxxwww1yy (www1 current window frame). 1281 * Assume ws = xxxwww1yy (www1 current window frame).
1334 * Rotate ws right so that a2 = yyxxxwww1. 1282 * Rotate ws right so that a4 = yyxxxwww1.
1335 */ 1283 */
1336 1284
1337 wsr a2, DEPC # preserve a2 1285 rsr a4, WINDOWBASE
1338 rsr a2, WINDOWBASE 1286 rsr a3, WINDOWSTART # a3 = xxxwww1yy
1339 rsr a3, WINDOWSTART 1287 ssr a4 # holds WB
1340 ssr a2 # holds WB 1288 slli a4, a3, WSBITS
1341 slli a2, a3, WSBITS 1289 or a3, a3, a4 # a3 = xxxwww1yyxxxwww1yy
1342 or a3, a3, a2 # a2 = xxxwww1yyxxxwww1yy 1290 srl a3, a3 # a3 = 00xxxwww1yyxxxwww1
1343 srl a3, a3
1344 1291
1345 /* We are done if there are no more than the current register frame. */ 1292 /* We are done if there are no more than the current register frame. */
1346 1293
1347 extui a3, a3, 1, WSBITS-2 # a3 = 0yyxxxwww 1294 extui a3, a3, 1, WSBITS-1 # a3 = 0yyxxxwww
1348 movi a2, (1 << (WSBITS-1)) 1295 movi a4, (1 << (WSBITS-1))
1349 _beqz a3, .Lnospill # only one active frame? jump 1296 _beqz a3, .Lnospill # only one active frame? jump
1350 1297
1351 /* We want 1 at the top, so that we return to the current windowbase */ 1298 /* We want 1 at the top, so that we return to the current windowbase */
1352 1299
1353 or a3, a3, a2 # 1yyxxxwww 1300 or a3, a3, a4 # 1yyxxxwww
1354 1301
1355 /* Skip empty frames - get 'oldest' WINDOWSTART-bit. */ 1302 /* Skip empty frames - get 'oldest' WINDOWSTART-bit. */
1356 1303
1357 wsr a3, WINDOWSTART # save shifted windowstart 1304 wsr a3, WINDOWSTART # save shifted windowstart
1358 neg a2, a3 1305 neg a4, a3
1359 and a3, a2, a3 # first bit set from right: 000010000 1306 and a3, a4, a3 # first bit set from right: 000010000
1360 1307
1361 ffs_ws a2, a3 # a2: shifts to skip empty frames 1308 ffs_ws a4, a3 # a4: shifts to skip empty frames
1362 movi a3, WSBITS 1309 movi a3, WSBITS
1363 sub a2, a3, a2 # WSBITS-a2:number of 0-bits from right 1310 sub a4, a3, a4 # WSBITS-a4:number of 0-bits from right
1364 ssr a2 # save in SAR for later. 1311 ssr a4 # save in SAR for later.
1365 1312
1366 rsr a3, WINDOWBASE 1313 rsr a3, WINDOWBASE
1367 add a3, a3, a2 1314 add a3, a3, a4
1368 rsr a2, DEPC # restore a2
1369 wsr a3, WINDOWBASE 1315 wsr a3, WINDOWBASE
1370 rsync 1316 rsync
1371 1317
@@ -1394,6 +1340,9 @@ ENTRY(_spill_registers)
1394 l32e a4, a1, -16 1340 l32e a4, a1, -16
1395 j .Lc12c 1341 j .Lc12c
1396 1342
1343.Lnospill:
1344 ret
1345
1397.Lloop: _bbsi.l a3, 1, .Lc4 1346.Lloop: _bbsi.l a3, 1, .Lc4
1398 _bbci.l a3, 2, .Lc12 1347 _bbci.l a3, 2, .Lc12
1399 1348
@@ -1419,9 +1368,7 @@ ENTRY(_spill_registers)
1419 movi a3, 1 1368 movi a3, 1
1420 sll a3, a3 1369 sll a3, a3
1421 wsr a3, WINDOWSTART 1370 wsr a3, WINDOWSTART
1422 1371 ret
1423.Lnospill:
1424 jx a0
1425 1372
1426.Lc4: s32e a4, a9, -16 1373.Lc4: s32e a4, a9, -16
1427 s32e a5, a9, -12 1374 s32e a5, a9, -12
@@ -1830,154 +1777,6 @@ ENTRY(fast_store_prohibited)
18301: j _user_exception 17771: j _user_exception
1831 1778
1832 1779
1833#if XCHAL_EXTRA_SA_SIZE
1834
1835#warning fast_coprocessor untested
1836
1837/*
1838 * Entry condition:
1839 *
1840 * a0: trashed, original value saved on stack (PT_AREG0)
1841 * a1: a1
1842 * a2: new stack pointer, original in DEPC
1843 * a3: dispatch table
1844 * depc: a2, original value saved on stack (PT_DEPC)
1845 * excsave_1: a3
1846 *
1847 * PT_DEPC >= VALID_DOUBLE_EXCEPTION_ADDRESS: double exception, DEPC
1848 * < VALID_DOUBLE_EXCEPTION_ADDRESS: regular exception
1849 */
1850
1851ENTRY(fast_coprocessor_double)
1852 wsr a0, EXCSAVE_1
1853 movi a0, unrecoverable_exception
1854 callx0 a0
1855
1856ENTRY(fast_coprocessor)
1857
1858 /* Fatal if we are in a double exception. */
1859
1860 l32i a0, a2, PT_DEPC
1861 _bgeui a0, VALID_DOUBLE_EXCEPTION_ADDRESS, fast_coprocessor_double
1862
1863 /* Save some registers a1, a3, a4, SAR */
1864
1865 xsr a3, EXCSAVE_1
1866 s32i a3, a2, PT_AREG3
1867 rsr a3, SAR
1868 s32i a4, a2, PT_AREG4
1869 s32i a1, a2, PT_AREG1
1870 s32i a5, a1, PT_AREG5
1871 s32i a3, a2, PT_SAR
1872 mov a1, a2
1873
1874 /* Currently, the HAL macros only guarantee saving a0 and a1.
1875 * These can and will be refined in the future, but for now,
1876 * just save the remaining registers of a2...a15.
1877 */
1878 s32i a6, a1, PT_AREG6
1879 s32i a7, a1, PT_AREG7
1880 s32i a8, a1, PT_AREG8
1881 s32i a9, a1, PT_AREG9
1882 s32i a10, a1, PT_AREG10
1883 s32i a11, a1, PT_AREG11
1884 s32i a12, a1, PT_AREG12
1885 s32i a13, a1, PT_AREG13
1886 s32i a14, a1, PT_AREG14
1887 s32i a15, a1, PT_AREG15
1888
1889 /* Find coprocessor number. Subtract first CP EXCCAUSE from EXCCAUSE */
1890
1891 rsr a0, EXCCAUSE
1892 addi a3, a0, -XCHAL_EXCCAUSE_COPROCESSOR0_DISABLED
1893
1894 /* Set corresponding CPENABLE bit */
1895
1896 movi a4, 1
1897 ssl a3 # SAR: 32 - coprocessor_number
1898 rsr a5, CPENABLE
1899 sll a4, a4
1900 or a4, a5, a4
1901 wsr a4, CPENABLE
1902 rsync
1903 movi a5, coprocessor_info # list of owner and offset into cp_save
1904 addx8 a0, a4, a5 # entry for CP
1905
1906 bne a4, a5, .Lload # bit wasn't set before, cp not in use
1907
1908 /* Now compare the current task with the owner of the coprocessor.
1909 * If they are the same, there is no reason to save or restore any
1910 * coprocessor state. Having already enabled the coprocessor,
1911 * branch ahead to return.
1912 */
1913 GET_CURRENT(a5,a1)
1914 l32i a4, a0, COPROCESSOR_INFO_OWNER # a4: current owner for this CP
1915 beq a4, a5, .Ldone
1916
1917 /* Find location to dump current coprocessor state:
1918 * task_struct->task_cp_save_offset + coprocessor_offset[coprocessor]
1919 *
1920 * Note: a0 pointer to the entry in the coprocessor owner table,
1921 * a3 coprocessor number,
1922 * a4 current owner of coprocessor.
1923 */
1924 l32i a5, a0, COPROCESSOR_INFO_OFFSET
1925 addi a2, a4, THREAD_CP_SAVE
1926 add a2, a2, a5
1927
1928 /* Store current coprocessor states. (a5 still has CP number) */
1929
1930 xchal_cpi_store_funcbody
1931
1932 /* The macro might have destroyed a3 (coprocessor number), but
1933 * SAR still has 32 - coprocessor_number!
1934 */
1935 movi a3, 32
1936 rsr a4, SAR
1937 sub a3, a3, a4
1938
1939.Lload: /* A new task now owns the corpocessors. Save its TCB pointer into
1940 * the coprocessor owner table.
1941 *
1942 * Note: a0 pointer to the entry in the coprocessor owner table,
1943 * a3 coprocessor number.
1944 */
1945 GET_CURRENT(a4,a1)
1946 s32i a4, a0, 0
1947
1948 /* Find location from where to restore the current coprocessor state.*/
1949
1950 l32i a5, a0, COPROCESSOR_INFO_OFFSET
1951 addi a2, a4, THREAD_CP_SAVE
1952 add a2, a2, a4
1953
1954 xchal_cpi_load_funcbody
1955
1956 /* We must assume that the xchal_cpi_store_funcbody macro destroyed
1957 * registers a2..a15.
1958 */
1959
1960.Ldone: l32i a15, a1, PT_AREG15
1961 l32i a14, a1, PT_AREG14
1962 l32i a13, a1, PT_AREG13
1963 l32i a12, a1, PT_AREG12
1964 l32i a11, a1, PT_AREG11
1965 l32i a10, a1, PT_AREG10
1966 l32i a9, a1, PT_AREG9
1967 l32i a8, a1, PT_AREG8
1968 l32i a7, a1, PT_AREG7
1969 l32i a6, a1, PT_AREG6
1970 l32i a5, a1, PT_AREG5
1971 l32i a4, a1, PT_AREG4
1972 l32i a3, a1, PT_AREG3
1973 l32i a2, a1, PT_AREG2
1974 l32i a0, a1, PT_AREG0
1975 l32i a1, a1, PT_AREG1
1976
1977 rfe
1978
1979#endif /* XCHAL_EXTRA_SA_SIZE */
1980
1981/* 1780/*
1982 * System Calls. 1781 * System Calls.
1983 * 1782 *
@@ -2086,20 +1885,36 @@ ENTRY(_switch_to)
2086 1885
2087 entry a1, 16 1886 entry a1, 16
2088 1887
2089 mov a4, a3 # preserve a3 1888 mov a12, a2 # preserve 'prev' (a2)
1889 mov a13, a3 # and 'next' (a3)
1890
1891 l32i a4, a2, TASK_THREAD_INFO
1892 l32i a5, a3, TASK_THREAD_INFO
1893
1894 save_xtregs_user a4 a6 a8 a9 a10 a11 THREAD_XTREGS_USER
2090 1895
2091 s32i a0, a2, THREAD_RA # save return address 1896 s32i a0, a12, THREAD_RA # save return address
2092 s32i a1, a2, THREAD_SP # save stack pointer 1897 s32i a1, a12, THREAD_SP # save stack pointer
2093 1898
2094 /* Disable ints while we manipulate the stack pointer; spill regs. */ 1899 /* Disable ints while we manipulate the stack pointer. */
2095 1900
2096 movi a5, (1 << PS_EXCM_BIT) | LOCKLEVEL 1901 movi a14, (1 << PS_EXCM_BIT) | LOCKLEVEL
2097 xsr a5, PS 1902 xsr a14, PS
2098 rsr a3, EXCSAVE_1 1903 rsr a3, EXCSAVE_1
2099 rsync 1904 rsync
2100 s32i a3, a3, EXC_TABLE_FIXUP /* enter critical section */ 1905 s32i a3, a3, EXC_TABLE_FIXUP /* enter critical section */
2101 1906
2102 call0 _spill_registers 1907 /* Switch CPENABLE */
1908
1909#if (XTENSA_HAVE_COPROCESSORS || XTENSA_HAVE_IO_PORTS)
1910 l32i a3, a5, THREAD_CPENABLE
1911 xsr a3, CPENABLE
1912 s32i a3, a4, THREAD_CPENABLE
1913#endif
1914
1915 /* Flush register file. */
1916
1917 call0 _spill_registers # destroys a3, a4, and SAR
2103 1918
2104 /* Set kernel stack (and leave critical section) 1919 /* Set kernel stack (and leave critical section)
2105 * Note: It's save to set it here. The stack will not be overwritten 1920 * Note: It's save to set it here. The stack will not be overwritten
@@ -2107,19 +1922,21 @@ ENTRY(_switch_to)
2107 * we return from kernel space. 1922 * we return from kernel space.
2108 */ 1923 */
2109 1924
2110 l32i a0, a4, TASK_THREAD_INFO
2111 rsr a3, EXCSAVE_1 # exc_table 1925 rsr a3, EXCSAVE_1 # exc_table
2112 movi a1, 0 1926 movi a6, 0
2113 addi a0, a0, PT_REGS_OFFSET 1927 addi a7, a5, PT_REGS_OFFSET
2114 s32i a1, a3, EXC_TABLE_FIXUP 1928 s32i a6, a3, EXC_TABLE_FIXUP
2115 s32i a0, a3, EXC_TABLE_KSTK 1929 s32i a7, a3, EXC_TABLE_KSTK
2116 1930
2117 /* restore context of the task that 'next' addresses */ 1931 /* restore context of the task that 'next' addresses */
2118 1932
2119 l32i a0, a4, THREAD_RA /* restore return address */ 1933 l32i a0, a13, THREAD_RA # restore return address
2120 l32i a1, a4, THREAD_SP /* restore stack pointer */ 1934 l32i a1, a13, THREAD_SP # restore stack pointer
1935
1936 load_xtregs_user a5 a6 a8 a9 a10 a11 THREAD_XTREGS_USER
2121 1937
2122 wsr a5, PS 1938 wsr a14, PS
1939 mov a2, a12 # return 'prev'
2123 rsync 1940 rsync
2124 1941
2125 retw 1942 retw
diff --git a/arch/xtensa/kernel/module.c b/arch/xtensa/kernel/module.c
index ddf14dcf2ad9..3981a466c779 100644
--- a/arch/xtensa/kernel/module.c
+++ b/arch/xtensa/kernel/module.c
@@ -28,7 +28,7 @@ void *module_alloc(unsigned long size)
28{ 28{
29 if (size == 0) 29 if (size == 0)
30 return NULL; 30 return NULL;
31 return vmalloc(size); 31 return vmalloc_exec(size);
32} 32}
33 33
34void module_free(struct module *mod, void *module_region) 34void module_free(struct module *mod, void *module_region)
diff --git a/arch/xtensa/kernel/process.c b/arch/xtensa/kernel/process.c
index f53d7bd9dfb2..9185597eb6a0 100644
--- a/arch/xtensa/kernel/process.c
+++ b/arch/xtensa/kernel/process.c
@@ -52,6 +52,55 @@ void (*pm_power_off)(void) = NULL;
52EXPORT_SYMBOL(pm_power_off); 52EXPORT_SYMBOL(pm_power_off);
53 53
54 54
55#if XTENSA_HAVE_COPROCESSORS
56
57void coprocessor_release_all(struct thread_info *ti)
58{
59 unsigned long cpenable;
60 int i;
61
62 /* Make sure we don't switch tasks during this operation. */
63
64 preempt_disable();
65
66 /* Walk through all cp owners and release it for the requested one. */
67
68 cpenable = ti->cpenable;
69
70 for (i = 0; i < XCHAL_CP_MAX; i++) {
71 if (coprocessor_owner[i] == ti) {
72 coprocessor_owner[i] = 0;
73 cpenable &= ~(1 << i);
74 }
75 }
76
77 ti->cpenable = cpenable;
78 coprocessor_clear_cpenable();
79
80 preempt_enable();
81}
82
83void coprocessor_flush_all(struct thread_info *ti)
84{
85 unsigned long cpenable;
86 int i;
87
88 preempt_disable();
89
90 cpenable = ti->cpenable;
91
92 for (i = 0; i < XCHAL_CP_MAX; i++) {
93 if ((cpenable & 1) != 0 && coprocessor_owner[i] == ti)
94 coprocessor_flush(ti, i);
95 cpenable >>= 1;
96 }
97
98 preempt_enable();
99}
100
101#endif
102
103
55/* 104/*
56 * Powermanagement idle function, if any is provided by the platform. 105 * Powermanagement idle function, if any is provided by the platform.
57 */ 106 */
@@ -71,15 +120,36 @@ void cpu_idle(void)
71} 120}
72 121
73/* 122/*
74 * Free current thread data structures etc.. 123 * This is called when the thread calls exit().
75 */ 124 */
76
77void exit_thread(void) 125void exit_thread(void)
78{ 126{
127#if XTENSA_HAVE_COPROCESSORS
128 coprocessor_release_all(current_thread_info());
129#endif
79} 130}
80 131
132/*
133 * Flush thread state. This is called when a thread does an execve()
134 * Note that we flush coprocessor registers for the case execve fails.
135 */
81void flush_thread(void) 136void flush_thread(void)
82{ 137{
138#if XTENSA_HAVE_COPROCESSORS
139 struct thread_info *ti = current_thread_info();
140 coprocessor_flush_all(ti);
141 coprocessor_release_all(ti);
142#endif
143}
144
145/*
146 * This is called before the thread is copied.
147 */
148void prepare_to_copy(struct task_struct *tsk)
149{
150#if XTENSA_HAVE_COPROCESSORS
151 coprocessor_flush_all(task_thread_info(tsk));
152#endif
83} 153}
84 154
85/* 155/*
@@ -107,6 +177,7 @@ int copy_thread(int nr, unsigned long clone_flags, unsigned long usp,
107 struct task_struct * p, struct pt_regs * regs) 177 struct task_struct * p, struct pt_regs * regs)
108{ 178{
109 struct pt_regs *childregs; 179 struct pt_regs *childregs;
180 struct thread_info *ti;
110 unsigned long tos; 181 unsigned long tos;
111 int user_mode = user_mode(regs); 182 int user_mode = user_mode(regs);
112 183
@@ -128,13 +199,14 @@ int copy_thread(int nr, unsigned long clone_flags, unsigned long usp,
128 p->set_child_tid = p->clear_child_tid = NULL; 199 p->set_child_tid = p->clear_child_tid = NULL;
129 p->thread.ra = MAKE_RA_FOR_CALL((unsigned long)ret_from_fork, 0x1); 200 p->thread.ra = MAKE_RA_FOR_CALL((unsigned long)ret_from_fork, 0x1);
130 p->thread.sp = (unsigned long)childregs; 201 p->thread.sp = (unsigned long)childregs;
202
131 if (user_mode(regs)) { 203 if (user_mode(regs)) {
132 204
133 int len = childregs->wmask & ~0xf; 205 int len = childregs->wmask & ~0xf;
134 childregs->areg[1] = usp; 206 childregs->areg[1] = usp;
135 memcpy(&childregs->areg[XCHAL_NUM_AREGS - len/4], 207 memcpy(&childregs->areg[XCHAL_NUM_AREGS - len/4],
136 &regs->areg[XCHAL_NUM_AREGS - len/4], len); 208 &regs->areg[XCHAL_NUM_AREGS - len/4], len);
137 209// FIXME: we need to set THREADPTR in thread_info...
138 if (clone_flags & CLONE_SETTLS) 210 if (clone_flags & CLONE_SETTLS)
139 childregs->areg[2] = childregs->areg[6]; 211 childregs->areg[2] = childregs->areg[6];
140 212
@@ -142,6 +214,12 @@ int copy_thread(int nr, unsigned long clone_flags, unsigned long usp,
142 /* In kernel space, we start a new thread with a new stack. */ 214 /* In kernel space, we start a new thread with a new stack. */
143 childregs->wmask = 1; 215 childregs->wmask = 1;
144 } 216 }
217
218#if (XTENSA_HAVE_COPROCESSORS || XTENSA_HAVE_IO_PORTS)
219 ti = task_thread_info(p);
220 ti->cpenable = 0;
221#endif
222
145 return 0; 223 return 0;
146} 224}
147 225
@@ -179,10 +257,6 @@ unsigned long get_wchan(struct task_struct *p)
179} 257}
180 258
181/* 259/*
182 * do_copy_regs() gathers information from 'struct pt_regs' and
183 * 'current->thread.areg[]' to fill in the xtensa_gregset_t
184 * structure.
185 *
186 * xtensa_gregset_t and 'struct pt_regs' are vastly different formats 260 * xtensa_gregset_t and 'struct pt_regs' are vastly different formats
187 * of processor registers. Besides different ordering, 261 * of processor registers. Besides different ordering,
188 * xtensa_gregset_t contains non-live register information that 262 * xtensa_gregset_t contains non-live register information that
@@ -191,18 +265,19 @@ unsigned long get_wchan(struct task_struct *p)
191 * 265 *
192 */ 266 */
193 267
194void do_copy_regs (xtensa_gregset_t *elfregs, struct pt_regs *regs, 268void xtensa_elf_core_copy_regs (xtensa_gregset_t *elfregs, struct pt_regs *regs)
195 struct task_struct *tsk)
196{ 269{
197 int i, n, wb_offset; 270 unsigned long wb, ws, wm;
271 int live, last;
198 272
199 elfregs->xchal_config_id0 = XCHAL_HW_CONFIGID0; 273 wb = regs->windowbase;
200 elfregs->xchal_config_id1 = XCHAL_HW_CONFIGID1; 274 ws = regs->windowstart;
275 wm = regs->wmask;
276 ws = ((ws >> wb) | (ws << (WSBITS - wb))) & ((1 << WSBITS) - 1);
201 277
202 __asm__ __volatile__ ("rsr %0, 176\n" : "=a" (i)); 278 /* Don't leak any random bits. */
203 elfregs->cpux = i; 279
204 __asm__ __volatile__ ("rsr %0, 208\n" : "=a" (i)); 280 memset(elfregs, 0, sizeof (elfregs));
205 elfregs->cpuy = i;
206 281
207 /* Note: PS.EXCM is not set while user task is running; its 282 /* Note: PS.EXCM is not set while user task is running; its
208 * being set in regs->ps is for exception handling convenience. 283 * being set in regs->ps is for exception handling convenience.
@@ -210,204 +285,22 @@ void do_copy_regs (xtensa_gregset_t *elfregs, struct pt_regs *regs,
210 285
211 elfregs->pc = regs->pc; 286 elfregs->pc = regs->pc;
212 elfregs->ps = (regs->ps & ~(1 << PS_EXCM_BIT)); 287 elfregs->ps = (regs->ps & ~(1 << PS_EXCM_BIT));
213 elfregs->exccause = regs->exccause;
214 elfregs->excvaddr = regs->excvaddr;
215 elfregs->windowbase = regs->windowbase;
216 elfregs->windowstart = regs->windowstart;
217 elfregs->lbeg = regs->lbeg; 288 elfregs->lbeg = regs->lbeg;
218 elfregs->lend = regs->lend; 289 elfregs->lend = regs->lend;
219 elfregs->lcount = regs->lcount; 290 elfregs->lcount = regs->lcount;
220 elfregs->sar = regs->sar; 291 elfregs->sar = regs->sar;
221 elfregs->syscall = regs->syscall; 292 elfregs->windowstart = ws;
222
223 /* Copy register file.
224 * The layout looks like this:
225 *
226 * | a0 ... a15 | Z ... Z | arX ... arY |
227 * current window unused saved frames
228 */
229
230 memset (elfregs->ar, 0, sizeof(elfregs->ar));
231 293
232 wb_offset = regs->windowbase * 4; 294 live = (wm & 2) ? 4 : (wm & 4) ? 8 : (wm & 8) ? 12 : 16;
233 n = (regs->wmask&1)? 4 : (regs->wmask&2)? 8 : (regs->wmask&4)? 12 : 16; 295 last = XCHAL_NUM_AREGS - (wm >> 4) * 4;
234 296 memcpy(elfregs->a, regs->areg, live * 4);
235 for (i = 0; i < n; i++) 297 memcpy(elfregs->a + last, regs->areg + last, (wm >> 4) * 16);
236 elfregs->ar[(wb_offset + i) % XCHAL_NUM_AREGS] = regs->areg[i];
237
238 n = (regs->wmask >> 4) * 4;
239
240 for (i = XCHAL_NUM_AREGS - n; n > 0; i++, n--)
241 elfregs->ar[(wb_offset + i) % XCHAL_NUM_AREGS] = regs->areg[i];
242} 298}
243 299
244void xtensa_elf_core_copy_regs (xtensa_gregset_t *elfregs, struct pt_regs *regs) 300int dump_fpu(void)
245{ 301{
246 do_copy_regs ((xtensa_gregset_t *)elfregs, regs, current);
247}
248
249
250/* The inverse of do_copy_regs(). No error or sanity checking. */
251
252void do_restore_regs (xtensa_gregset_t *elfregs, struct pt_regs *regs,
253 struct task_struct *tsk)
254{
255 int i, n, wb_offset;
256
257 /* Note: PS.EXCM is not set while user task is running; it
258 * needs to be set in regs->ps is for exception handling convenience.
259 */
260
261 regs->pc = elfregs->pc;
262 regs->ps = (elfregs->ps | (1 << PS_EXCM_BIT));
263 regs->exccause = elfregs->exccause;
264 regs->excvaddr = elfregs->excvaddr;
265 regs->windowbase = elfregs->windowbase;
266 regs->windowstart = elfregs->windowstart;
267 regs->lbeg = elfregs->lbeg;
268 regs->lend = elfregs->lend;
269 regs->lcount = elfregs->lcount;
270 regs->sar = elfregs->sar;
271 regs->syscall = elfregs->syscall;
272
273 /* Clear everything. */
274
275 memset (regs->areg, 0, sizeof(regs->areg));
276
277 /* Copy regs from live window frame. */
278
279 wb_offset = regs->windowbase * 4;
280 n = (regs->wmask&1)? 4 : (regs->wmask&2)? 8 : (regs->wmask&4)? 12 : 16;
281
282 for (i = 0; i < n; i++)
283 regs->areg[(wb_offset+i) % XCHAL_NUM_AREGS] = elfregs->ar[i];
284
285 n = (regs->wmask >> 4) * 4;
286
287 for (i = XCHAL_NUM_AREGS - n; n > 0; i++, n--)
288 regs->areg[(wb_offset+i) % XCHAL_NUM_AREGS] = elfregs->ar[i];
289}
290
291/*
292 * do_save_fpregs() gathers information from 'struct pt_regs' and
293 * 'current->thread' to fill in the elf_fpregset_t structure.
294 *
295 * Core files and ptrace use elf_fpregset_t.
296 */
297
298void do_save_fpregs (elf_fpregset_t *fpregs, struct pt_regs *regs,
299 struct task_struct *tsk)
300{
301#if XCHAL_HAVE_CP
302
303 extern unsigned char _xtensa_reginfo_tables[];
304 extern unsigned _xtensa_reginfo_table_size;
305 int i;
306 unsigned long flags;
307
308 /* Before dumping coprocessor state from memory,
309 * ensure any live coprocessor contents for this
310 * task are first saved to memory:
311 */
312 local_irq_save(flags);
313
314 for (i = 0; i < XCHAL_CP_MAX; i++) {
315 if (tsk == coprocessor_info[i].owner) {
316 enable_coprocessor(i);
317 save_coprocessor_registers(
318 tsk->thread.cp_save+coprocessor_info[i].offset,i);
319 disable_coprocessor(i);
320 }
321 }
322
323 local_irq_restore(flags);
324
325 /* Now dump coprocessor & extra state: */
326 memcpy((unsigned char*)fpregs,
327 _xtensa_reginfo_tables, _xtensa_reginfo_table_size);
328 memcpy((unsigned char*)fpregs + _xtensa_reginfo_table_size,
329 tsk->thread.cp_save, XTENSA_CP_EXTRA_SIZE);
330#endif
331}
332
333/*
334 * The inverse of do_save_fpregs().
335 * Copies coprocessor and extra state from fpregs into regs and tsk->thread.
336 * Returns 0 on success, non-zero if layout doesn't match.
337 */
338
339int do_restore_fpregs (elf_fpregset_t *fpregs, struct pt_regs *regs,
340 struct task_struct *tsk)
341{
342#if XCHAL_HAVE_CP
343
344 extern unsigned char _xtensa_reginfo_tables[];
345 extern unsigned _xtensa_reginfo_table_size;
346 int i;
347 unsigned long flags;
348
349 /* Make sure save area layouts match.
350 * FIXME: in the future we could allow restoring from
351 * a different layout of the same registers, by comparing
352 * fpregs' table with _xtensa_reginfo_tables and matching
353 * entries and copying registers one at a time.
354 * Not too sure yet whether that's very useful.
355 */
356
357 if( memcmp((unsigned char*)fpregs,
358 _xtensa_reginfo_tables, _xtensa_reginfo_table_size) ) {
359 return -1;
360 }
361
362 /* Before restoring coprocessor state from memory,
363 * ensure any live coprocessor contents for this
364 * task are first invalidated.
365 */
366
367 local_irq_save(flags);
368
369 for (i = 0; i < XCHAL_CP_MAX; i++) {
370 if (tsk == coprocessor_info[i].owner) {
371 enable_coprocessor(i);
372 save_coprocessor_registers(
373 tsk->thread.cp_save+coprocessor_info[i].offset,i);
374 coprocessor_info[i].owner = 0;
375 disable_coprocessor(i);
376 }
377 }
378
379 local_irq_restore(flags);
380
381 /* Now restore coprocessor & extra state: */
382
383 memcpy(tsk->thread.cp_save,
384 (unsigned char*)fpregs + _xtensa_reginfo_table_size,
385 XTENSA_CP_EXTRA_SIZE);
386#endif
387 return 0; 302 return 0;
388} 303}
389/*
390 * Fill in the CP structure for a core dump for a particular task.
391 */
392
393int
394dump_task_fpu(struct pt_regs *regs, struct task_struct *task, elf_fpregset_t *r)
395{
396 return 0; /* no coprocessors active on this processor */
397}
398
399/*
400 * Fill in the CP structure for a core dump.
401 * This includes any FPU coprocessor.
402 * Here, we dump all coprocessors, and other ("extra") custom state.
403 *
404 * This function is called by elf_core_dump() in fs/binfmt_elf.c
405 * (in which case 'regs' comes from calls to do_coredump, see signals.c).
406 */
407int dump_fpu(struct pt_regs *regs, elf_fpregset_t *r)
408{
409 return dump_task_fpu(regs, current, r);
410}
411 304
412asmlinkage 305asmlinkage
413long xtensa_clone(unsigned long clone_flags, unsigned long newsp, 306long xtensa_clone(unsigned long clone_flags, unsigned long newsp,
@@ -421,8 +314,8 @@ long xtensa_clone(unsigned long clone_flags, unsigned long newsp,
421} 314}
422 315
423/* 316/*
424 * * xtensa_execve() executes a new program. 317 * xtensa_execve() executes a new program.
425 * */ 318 */
426 319
427asmlinkage 320asmlinkage
428long xtensa_execve(char __user *name, char __user * __user *argv, 321long xtensa_execve(char __user *name, char __user * __user *argv,
@@ -437,7 +330,6 @@ long xtensa_execve(char __user *name, char __user * __user *argv,
437 error = PTR_ERR(filename); 330 error = PTR_ERR(filename);
438 if (IS_ERR(filename)) 331 if (IS_ERR(filename))
439 goto out; 332 goto out;
440 // FIXME: release coprocessor??
441 error = do_execve(filename, argv, envp, regs); 333 error = do_execve(filename, argv, envp, regs);
442 if (error == 0) { 334 if (error == 0) {
443 task_lock(current); 335 task_lock(current);
diff --git a/arch/xtensa/kernel/ptrace.c b/arch/xtensa/kernel/ptrace.c
index 5533c7850d53..9486882ef0af 100644
--- a/arch/xtensa/kernel/ptrace.c
+++ b/arch/xtensa/kernel/ptrace.c
@@ -4,7 +4,7 @@
4 * License. See the file "COPYING" in the main directory of this archive 4 * License. See the file "COPYING" in the main directory of this archive
5 * for more details. 5 * for more details.
6 * 6 *
7 * Copyright (C) 2001 - 2005 Tensilica Inc. 7 * Copyright (C) 2001 - 2007 Tensilica Inc.
8 * 8 *
9 * Joe Taylor <joe@tensilica.com, joetylr@yahoo.com> 9 * Joe Taylor <joe@tensilica.com, joetylr@yahoo.com>
10 * Chris Zankel <chris@zankel.net> 10 * Chris Zankel <chris@zankel.net>
@@ -28,14 +28,10 @@
28#include <asm/uaccess.h> 28#include <asm/uaccess.h>
29#include <asm/ptrace.h> 29#include <asm/ptrace.h>
30#include <asm/elf.h> 30#include <asm/elf.h>
31 31#include <asm/coprocessor.h>
32#define TEST_KERNEL // verify kernel operations FIXME: remove
33
34 32
35/* 33/*
36 * Called by kernel/ptrace.c when detaching.. 34 * Called by kernel/ptrace.c when detaching to disable single stepping.
37 *
38 * Make sure single step bits etc are not set.
39 */ 35 */
40 36
41void ptrace_disable(struct task_struct *child) 37void ptrace_disable(struct task_struct *child)
@@ -43,136 +39,237 @@ void ptrace_disable(struct task_struct *child)
43 /* Nothing to do.. */ 39 /* Nothing to do.. */
44} 40}
45 41
46long arch_ptrace(struct task_struct *child, long request, long addr, long data) 42int ptrace_getregs(struct task_struct *child, void __user *uregs)
47{ 43{
48 int ret = -EPERM; 44 struct pt_regs *regs = task_pt_regs(child);
45 xtensa_gregset_t __user *gregset = uregs;
46 unsigned long wm = regs->wmask;
47 unsigned long wb = regs->windowbase;
48 int live, i;
49
50 if (!access_ok(VERIFY_WRITE, uregs, sizeof(xtensa_gregset_t)))
51 return -EIO;
52
53 __put_user(regs->pc, &gregset->pc);
54 __put_user(regs->ps & ~(1 << PS_EXCM_BIT), &gregset->ps);
55 __put_user(regs->lbeg, &gregset->lbeg);
56 __put_user(regs->lend, &gregset->lend);
57 __put_user(regs->lcount, &gregset->lcount);
58 __put_user(regs->windowstart, &gregset->windowstart);
59 __put_user(regs->windowbase, &gregset->windowbase);
60
61 live = (wm & 2) ? 4 : (wm & 4) ? 8 : (wm & 8) ? 12 : 16;
62
63 for (i = 0; i < live; i++)
64 __put_user(regs->areg[i],gregset->a+((wb*4+i)%XCHAL_NUM_AREGS));
65 for (i = XCHAL_NUM_AREGS - (wm >> 4) * 4; i < XCHAL_NUM_AREGS; i++)
66 __put_user(regs->areg[i],gregset->a+((wb*4+i)%XCHAL_NUM_AREGS));
67
68 return 0;
69}
49 70
50 switch (request) { 71int ptrace_setregs(struct task_struct *child, void __user *uregs)
51 case PTRACE_PEEKTEXT: /* read word at location addr. */ 72{
52 case PTRACE_PEEKDATA: 73 struct pt_regs *regs = task_pt_regs(child);
53 ret = generic_ptrace_peekdata(child, addr, data); 74 xtensa_gregset_t *gregset = uregs;
54 goto out; 75 const unsigned long ps_mask = PS_CALLINC_MASK | PS_OWB_MASK;
76 unsigned long ps;
77 unsigned long wb;
55 78
56 /* Read the word at location addr in the USER area. */ 79 if (!access_ok(VERIFY_WRITE, uregs, sizeof(xtensa_gregset_t)))
80 return -EIO;
57 81
58 case PTRACE_PEEKUSR: 82 __get_user(regs->pc, &gregset->pc);
59 { 83 __get_user(ps, &gregset->ps);
60 struct pt_regs *regs; 84 __get_user(regs->lbeg, &gregset->lbeg);
61 unsigned long tmp; 85 __get_user(regs->lend, &gregset->lend);
86 __get_user(regs->lcount, &gregset->lcount);
87 __get_user(regs->windowstart, &gregset->windowstart);
88 __get_user(wb, &gregset->windowbase);
89
90 regs->ps = (regs->ps & ~ps_mask) | (ps & ps_mask) | (1 << PS_EXCM_BIT);
91
92 if (wb >= XCHAL_NUM_AREGS / 4)
93 return -EFAULT;
94
95 regs->windowbase = wb;
96
97 if (wb != 0 && __copy_from_user(regs->areg + XCHAL_NUM_AREGS - wb * 4,
98 gregset->a, wb * 16))
99 return -EFAULT;
100
101 if (__copy_from_user(regs->areg, gregset->a + wb*4, (WSBITS-wb) * 16))
102 return -EFAULT;
103
104 return 0;
105}
106
107
108int ptrace_getxregs(struct task_struct *child, void __user *uregs)
109{
110 struct pt_regs *regs = task_pt_regs(child);
111 struct thread_info *ti = task_thread_info(child);
112 elf_xtregs_t __user *xtregs = uregs;
113 int ret = 0;
114
115 if (!access_ok(VERIFY_WRITE, uregs, sizeof(elf_xtregs_t)))
116 return -EIO;
117
118#if XTENSA_HAVE_COPROCESSORS
119 /* Flush all coprocessor registers to memory. */
120 coprocessor_flush_all(ti);
121 ret |= __copy_to_user(&xtregs->cp0, &ti->xtregs_cp,
122 sizeof(xtregs_coprocessor_t));
123#endif
124 ret |= __copy_to_user(&xtregs->opt, &regs->xtregs_opt,
125 sizeof(xtregs->opt));
126 ret |= __copy_to_user(&xtregs->user,&ti->xtregs_user,
127 sizeof(xtregs->user));
128
129 return ret ? -EFAULT : 0;
130}
131
132int ptrace_setxregs(struct task_struct *child, void __user *uregs)
133{
134 struct thread_info *ti = task_thread_info(child);
135 struct pt_regs *regs = task_pt_regs(child);
136 elf_xtregs_t *xtregs = uregs;
137 int ret = 0;
138
139#if XTENSA_HAVE_COPROCESSORS
140 /* Flush all coprocessors before we overwrite them. */
141 coprocessor_flush_all(ti);
142 coprocessor_release_all(ti);
143
144 ret |= __copy_from_user(&ti->xtregs_cp, &xtregs->cp0,
145 sizeof(xtregs_coprocessor_t));
146#endif
147 ret |= __copy_from_user(&regs->xtregs_opt, &xtregs->opt,
148 sizeof(xtregs->opt));
149 ret |= __copy_from_user(&ti->xtregs_user, &xtregs->user,
150 sizeof(xtregs->user));
151
152 return ret ? -EFAULT : 0;
153}
154
155int ptrace_peekusr(struct task_struct *child, long regno, long __user *ret)
156{
157 struct pt_regs *regs;
158 unsigned long tmp;
62 159
63 regs = task_pt_regs(child); 160 regs = task_pt_regs(child);
64 tmp = 0; /* Default return value. */ 161 tmp = 0; /* Default return value. */
65 162
66 switch(addr) { 163 switch(regno) {
67 164
68 case REG_AR_BASE ... REG_AR_BASE + XCHAL_NUM_AREGS - 1: 165 case REG_AR_BASE ... REG_AR_BASE + XCHAL_NUM_AREGS - 1:
69 { 166 tmp = regs->areg[regno - REG_AR_BASE];
70 int ar = addr - REG_AR_BASE - regs->windowbase * 4;
71 ar &= (XCHAL_NUM_AREGS - 1);
72 if (ar < 16 && ar + (regs->wmask >> 4) * 4 >= 0)
73 tmp = regs->areg[ar];
74 else
75 ret = -EIO;
76 break; 167 break;
77 } 168
78 case REG_A_BASE ... REG_A_BASE + 15: 169 case REG_A_BASE ... REG_A_BASE + 15:
79 tmp = regs->areg[addr - REG_A_BASE]; 170 tmp = regs->areg[regno - REG_A_BASE];
80 break; 171 break;
172
81 case REG_PC: 173 case REG_PC:
82 tmp = regs->pc; 174 tmp = regs->pc;
83 break; 175 break;
176
84 case REG_PS: 177 case REG_PS:
85 /* Note: PS.EXCM is not set while user task is running; 178 /* Note: PS.EXCM is not set while user task is running;
86 * its being set in regs is for exception handling 179 * its being set in regs is for exception handling
87 * convenience. */ 180 * convenience. */
88 tmp = (regs->ps & ~(1 << PS_EXCM_BIT)); 181 tmp = (regs->ps & ~(1 << PS_EXCM_BIT));
89 break; 182 break;
183
90 case REG_WB: 184 case REG_WB:
91 tmp = regs->windowbase; 185 break; /* tmp = 0 */
92 break; 186
93 case REG_WS: 187 case REG_WS:
94 tmp = regs->windowstart; 188 {
189 unsigned long wb = regs->windowbase;
190 unsigned long ws = regs->windowstart;
191 tmp = ((ws>>wb) | (ws<<(WSBITS-wb))) & ((1<<WSBITS)-1);
95 break; 192 break;
193 }
96 case REG_LBEG: 194 case REG_LBEG:
97 tmp = regs->lbeg; 195 tmp = regs->lbeg;
98 break; 196 break;
197
99 case REG_LEND: 198 case REG_LEND:
100 tmp = regs->lend; 199 tmp = regs->lend;
101 break; 200 break;
201
102 case REG_LCOUNT: 202 case REG_LCOUNT:
103 tmp = regs->lcount; 203 tmp = regs->lcount;
104 break; 204 break;
205
105 case REG_SAR: 206 case REG_SAR:
106 tmp = regs->sar; 207 tmp = regs->sar;
107 break; 208 break;
108 case REG_DEPC: 209
109 tmp = regs->depc;
110 break;
111 case REG_EXCCAUSE:
112 tmp = regs->exccause;
113 break;
114 case REG_EXCVADDR:
115 tmp = regs->excvaddr;
116 break;
117 case SYSCALL_NR: 210 case SYSCALL_NR:
118 tmp = regs->syscall; 211 tmp = regs->syscall;
119 break; 212 break;
120 default:
121 tmp = 0;
122 ret = -EIO;
123 goto out;
124 }
125 ret = put_user(tmp, (unsigned long *) data);
126 goto out;
127 }
128 213
129 case PTRACE_POKETEXT: /* write the word at location addr. */ 214 default:
130 case PTRACE_POKEDATA: 215 return -EIO;
131 ret = generic_ptrace_pokedata(child, addr, data); 216 }
132 goto out; 217 return put_user(tmp, ret);
218}
133 219
134 case PTRACE_POKEUSR: 220int ptrace_pokeusr(struct task_struct *child, long regno, long val)
135 { 221{
136 struct pt_regs *regs; 222 struct pt_regs *regs;
137 regs = task_pt_regs(child); 223 regs = task_pt_regs(child);
138 224
139 switch (addr) { 225 switch (regno) {
140 case REG_AR_BASE ... REG_AR_BASE + XCHAL_NUM_AREGS - 1: 226 case REG_AR_BASE ... REG_AR_BASE + XCHAL_NUM_AREGS - 1:
141 { 227 regs->areg[regno - REG_AR_BASE] = val;
142 int ar = addr - REG_AR_BASE - regs->windowbase * 4;
143 if (ar < 16 && ar + (regs->wmask >> 4) * 4 >= 0)
144 regs->areg[ar & (XCHAL_NUM_AREGS - 1)] = data;
145 else
146 ret = -EIO;
147 break; 228 break;
148 } 229
149 case REG_A_BASE ... REG_A_BASE + 15: 230 case REG_A_BASE ... REG_A_BASE + 15:
150 regs->areg[addr - REG_A_BASE] = data; 231 regs->areg[regno - REG_A_BASE] = val;
151 break; 232 break;
233
152 case REG_PC: 234 case REG_PC:
153 regs->pc = data; 235 regs->pc = val;
154 break; 236 break;
237
155 case SYSCALL_NR: 238 case SYSCALL_NR:
156 regs->syscall = data; 239 regs->syscall = val;
157 break;
158#ifdef TEST_KERNEL
159 case REG_WB:
160 regs->windowbase = data;
161 break;
162 case REG_WS:
163 regs->windowstart = data;
164 break; 240 break;
165#endif
166 241
167 default: 242 default:
168 /* The rest are not allowed. */ 243 return -EIO;
169 ret = -EIO; 244 }
170 break; 245 return 0;
171 } 246}
247
248long arch_ptrace(struct task_struct *child, long request, long addr, long data)
249{
250 int ret = -EPERM;
251
252 switch (request) {
253 case PTRACE_PEEKTEXT: /* read word at location addr. */
254 case PTRACE_PEEKDATA:
255 ret = generic_ptrace_peekdata(child, addr, data);
256 break;
257
258 case PTRACE_PEEKUSR: /* read register specified by addr. */
259 ret = ptrace_peekusr(child, addr, (void __user *) data);
260 break;
261
262 case PTRACE_POKETEXT: /* write the word at location addr. */
263 case PTRACE_POKEDATA:
264 ret = generic_ptrace_pokedata(child, addr, data);
265 break;
266
267 case PTRACE_POKEUSR: /* write register specified by addr. */
268 ret = ptrace_pokeusr(child, addr, data);
172 break; 269 break;
173 }
174 270
175 /* continue and stop at next (return from) syscall */ 271 /* continue and stop at next (return from) syscall */
272
176 case PTRACE_SYSCALL: 273 case PTRACE_SYSCALL:
177 case PTRACE_CONT: /* restart after signal. */ 274 case PTRACE_CONT: /* restart after signal. */
178 { 275 {
@@ -217,98 +314,26 @@ long arch_ptrace(struct task_struct *child, long request, long addr, long data)
217 break; 314 break;
218 315
219 case PTRACE_GETREGS: 316 case PTRACE_GETREGS:
220 { 317 ret = ptrace_getregs(child, (void __user *) data);
221 /* 'data' points to user memory in which to write.
222 * Mainly due to the non-live register values, we
223 * reformat the register values into something more
224 * standard. For convenience, we use the handy
225 * elf_gregset_t format. */
226
227 xtensa_gregset_t format;
228 struct pt_regs *regs = task_pt_regs(child);
229
230 do_copy_regs (&format, regs, child);
231
232 /* Now, copy to user space nice and easy... */
233 ret = 0;
234 if (copy_to_user((void *)data, &format, sizeof(elf_gregset_t)))
235 ret = -EFAULT;
236 break; 318 break;
237 }
238 319
239 case PTRACE_SETREGS: 320 case PTRACE_SETREGS:
240 { 321 ret = ptrace_setregs(child, (void __user *) data);
241 /* 'data' points to user memory that contains the new
242 * values in the elf_gregset_t format. */
243
244 xtensa_gregset_t format;
245 struct pt_regs *regs = task_pt_regs(child);
246
247 if (copy_from_user(&format,(void *)data,sizeof(elf_gregset_t))){
248 ret = -EFAULT;
249 break;
250 }
251
252 /* FIXME: Perhaps we want some sanity checks on
253 * these user-space values? See ARM version. Are
254 * debuggers a security concern? */
255
256 do_restore_regs (&format, regs, child);
257
258 ret = 0;
259 break;
260 }
261
262 case PTRACE_GETFPREGS:
263 {
264 /* 'data' points to user memory in which to write.
265 * For convenience, we use the handy
266 * elf_fpregset_t format. */
267
268 elf_fpregset_t fpregs;
269 struct pt_regs *regs = task_pt_regs(child);
270
271 do_save_fpregs (&fpregs, regs, child);
272
273 /* Now, copy to user space nice and easy... */
274 ret = 0;
275 if (copy_to_user((void *)data, &fpregs, sizeof(elf_fpregset_t)))
276 ret = -EFAULT;
277
278 break; 322 break;
279 }
280
281 case PTRACE_SETFPREGS:
282 {
283 /* 'data' points to user memory that contains the new
284 * values in the elf_fpregset_t format.
285 */
286 elf_fpregset_t fpregs;
287 struct pt_regs *regs = task_pt_regs(child);
288 323
289 ret = 0; 324 case PTRACE_GETXTREGS:
290 if (copy_from_user(&fpregs, (void *)data, sizeof(elf_fpregset_t))) { 325 ret = ptrace_getxregs(child, (void __user *) data);
291 ret = -EFAULT;
292 break;
293 }
294
295 if (do_restore_fpregs (&fpregs, regs, child))
296 ret = -EIO;
297 break; 326 break;
298 }
299 327
300 case PTRACE_GETFPREGSIZE: 328 case PTRACE_SETXTREGS:
301 /* 'data' points to 'unsigned long' set to the size 329 ret = ptrace_setxregs(child, (void __user *) data);
302 * of elf_fpregset_t
303 */
304 ret = put_user(sizeof(elf_fpregset_t), (unsigned long *) data);
305 break; 330 break;
306 331
307 default: 332 default:
308 ret = ptrace_request(child, request, addr, data); 333 ret = ptrace_request(child, request, addr, data);
309 goto out; 334 break;
310 } 335 }
311 out: 336
312 return ret; 337 return ret;
313} 338}
314 339
diff --git a/arch/xtensa/kernel/setup.c b/arch/xtensa/kernel/setup.c
index b80f2cb1b4fb..5e6d75c9f92b 100644
--- a/arch/xtensa/kernel/setup.c
+++ b/arch/xtensa/kernel/setup.c
@@ -60,11 +60,6 @@ struct ide_ops *ide_ops;
60extern struct rtc_ops no_rtc_ops; 60extern struct rtc_ops no_rtc_ops;
61struct rtc_ops *rtc_ops; 61struct rtc_ops *rtc_ops;
62 62
63#ifdef CONFIG_PC_KEYB
64extern struct kbd_ops no_kbd_ops;
65struct kbd_ops *kbd_ops;
66#endif
67
68#ifdef CONFIG_BLK_DEV_INITRD 63#ifdef CONFIG_BLK_DEV_INITRD
69extern void *initrd_start; 64extern void *initrd_start;
70extern void *initrd_end; 65extern void *initrd_end;
diff --git a/arch/xtensa/kernel/signal.c b/arch/xtensa/kernel/signal.c
index 033aae0336d2..f2220b5bdce6 100644
--- a/arch/xtensa/kernel/signal.c
+++ b/arch/xtensa/kernel/signal.c
@@ -35,13 +35,17 @@ asmlinkage int do_signal(struct pt_regs *regs, sigset_t *oldset);
35 35
36extern struct task_struct *coproc_owners[]; 36extern struct task_struct *coproc_owners[];
37 37
38extern void release_all_cp (struct task_struct *);
39
40struct rt_sigframe 38struct rt_sigframe
41{ 39{
42 struct siginfo info; 40 struct siginfo info;
43 struct ucontext uc; 41 struct ucontext uc;
44 cp_state_t cpstate; 42 struct {
43 xtregs_opt_t opt;
44 xtregs_user_t user;
45#if XTENSA_HAVE_COPROCESSORS
46 xtregs_coprocessor_t cp;
47#endif
48 } xtregs;
45 unsigned char retcode[6]; 49 unsigned char retcode[6];
46 unsigned int window[4]; 50 unsigned int window[4];
47}; 51};
@@ -49,8 +53,6 @@ struct rt_sigframe
49/* 53/*
50 * Flush register windows stored in pt_regs to stack. 54 * Flush register windows stored in pt_regs to stack.
51 * Returns 1 for errors. 55 * Returns 1 for errors.
52 *
53 * Note that windowbase, windowstart, and wmask are not updated!
54 */ 56 */
55 57
56int 58int
@@ -116,6 +118,9 @@ flush_window_regs_user(struct pt_regs *regs)
116 base += inc; 118 base += inc;
117 } 119 }
118 120
121 regs->wmask = 1;
122 regs->windowstart = 1 << wb;
123
119 return 0; 124 return 0;
120 125
121errout: 126errout:
@@ -131,9 +136,10 @@ errout:
131 */ 136 */
132 137
133static int 138static int
134setup_sigcontext(struct sigcontext __user *sc, cp_state_t *cpstate, 139setup_sigcontext(struct rt_sigframe __user *frame, struct pt_regs *regs)
135 struct pt_regs *regs, unsigned long mask)
136{ 140{
141 struct sigcontext __user *sc = &frame->uc.uc_mcontext;
142 struct thread_info *ti = current_thread_info();
137 int err = 0; 143 int err = 0;
138 144
139#define COPY(x) err |= __put_user(regs->x, &sc->sc_##x) 145#define COPY(x) err |= __put_user(regs->x, &sc->sc_##x)
@@ -147,23 +153,32 @@ setup_sigcontext(struct sigcontext __user *sc, cp_state_t *cpstate,
147 153
148 err |= flush_window_regs_user(regs); 154 err |= flush_window_regs_user(regs);
149 err |= __copy_to_user (sc->sc_a, regs->areg, 16 * 4); 155 err |= __copy_to_user (sc->sc_a, regs->areg, 16 * 4);
156 err |= __put_user(0, &sc->sc_xtregs);
150 157
151 // err |= __copy_to_user (sc->sc_a, regs->areg, XCHAL_NUM_AREGS * 4) 158 if (err)
159 return err;
152 160
153#if XCHAL_HAVE_CP 161#if XTENSA_HAVE_COPROCESSORS
154# error Coprocessors unsupported 162 coprocessor_flush_all(ti);
155 err |= save_cpextra(cpstate); 163 coprocessor_release_all(ti);
156 err |= __put_user(err ? NULL : cpstate, &sc->sc_cpstate); 164 err |= __copy_to_user(&frame->xtregs.cp, &ti->xtregs_cp,
165 sizeof (frame->xtregs.cp));
157#endif 166#endif
158 /* non-iBCS2 extensions.. */ 167 err |= __copy_to_user(&frame->xtregs.opt, &regs->xtregs_opt,
159 err |= __put_user(mask, &sc->oldmask); 168 sizeof (xtregs_opt_t));
169 err |= __copy_to_user(&frame->xtregs.user, &ti->xtregs_user,
170 sizeof (xtregs_user_t));
171
172 err |= __put_user(err ? NULL : &frame->xtregs, &sc->sc_xtregs);
160 173
161 return err; 174 return err;
162} 175}
163 176
164static int 177static int
165restore_sigcontext(struct pt_regs *regs, struct sigcontext __user *sc) 178restore_sigcontext(struct pt_regs *regs, struct rt_sigframe __user *frame)
166{ 179{
180 struct sigcontext __user *sc = &frame->uc.uc_mcontext;
181 struct thread_info *ti = current_thread_info();
167 unsigned int err = 0; 182 unsigned int err = 0;
168 unsigned long ps; 183 unsigned long ps;
169 184
@@ -181,6 +196,8 @@ restore_sigcontext(struct pt_regs *regs, struct sigcontext __user *sc)
181 regs->windowbase = 0; 196 regs->windowbase = 0;
182 regs->windowstart = 1; 197 regs->windowstart = 1;
183 198
199 regs->syscall = -1; /* disable syscall checks */
200
184 /* For PS, restore only PS.CALLINC. 201 /* For PS, restore only PS.CALLINC.
185 * Assume that all other bits are either the same as for the signal 202 * Assume that all other bits are either the same as for the signal
186 * handler, or the user mode value doesn't matter (e.g. PS.OWB). 203 * handler, or the user mode value doesn't matter (e.g. PS.OWB).
@@ -196,8 +213,9 @@ restore_sigcontext(struct pt_regs *regs, struct sigcontext __user *sc)
196 213
197 err |= __copy_from_user(regs->areg, sc->sc_a, 16 * 4); 214 err |= __copy_from_user(regs->areg, sc->sc_a, 16 * 4);
198 215
199#if XCHAL_HAVE_CP 216 if (err)
200# error Coprocessors unsupported 217 return err;
218
201 /* The signal handler may have used coprocessors in which 219 /* The signal handler may have used coprocessors in which
202 * case they are still enabled. We disable them to force a 220 * case they are still enabled. We disable them to force a
203 * reloading of the original task's CP state by the lazy 221 * reloading of the original task's CP state by the lazy
@@ -205,20 +223,20 @@ restore_sigcontext(struct pt_regs *regs, struct sigcontext __user *sc)
205 * Also, we essentially discard any coprocessor state that the 223 * Also, we essentially discard any coprocessor state that the
206 * signal handler created. */ 224 * signal handler created. */
207 225
208 if (!err) { 226#if XTENSA_HAVE_COPROCESSORS
209 struct task_struct *tsk = current; 227 coprocessor_release_all(ti);
210 release_all_cp(tsk); 228 err |= __copy_from_user(&ti->xtregs_cp, &frame->xtregs.cp,
211 err |= __copy_from_user(tsk->thread.cpextra, sc->sc_cpstate, 229 sizeof (frame->xtregs.cp));
212 XTENSA_CP_EXTRA_SIZE);
213 }
214#endif 230#endif
231 err |= __copy_from_user(&ti->xtregs_user, &frame->xtregs.user,
232 sizeof (xtregs_user_t));
233 err |= __copy_from_user(&regs->xtregs_opt, &frame->xtregs.opt,
234 sizeof (xtregs_opt_t));
215 235
216 regs->syscall = -1; /* disable syscall checks */
217 return err; 236 return err;
218} 237}
219 238
220 239
221
222/* 240/*
223 * Do a signal return; undo the signal stack. 241 * Do a signal return; undo the signal stack.
224 */ 242 */
@@ -247,7 +265,7 @@ asmlinkage long xtensa_rt_sigreturn(long a0, long a1, long a2, long a3,
247 recalc_sigpending(); 265 recalc_sigpending();
248 spin_unlock_irq(&current->sighand->siglock); 266 spin_unlock_irq(&current->sighand->siglock);
249 267
250 if (restore_sigcontext(regs, &frame->uc.uc_mcontext)) 268 if (restore_sigcontext(regs, frame))
251 goto badframe; 269 goto badframe;
252 270
253 ret = regs->areg[2]; 271 ret = regs->areg[2];
@@ -360,18 +378,22 @@ static void setup_frame(int sig, struct k_sigaction *ka, siginfo_t *info,
360 err |= __put_user(sas_ss_flags(regs->areg[1]), 378 err |= __put_user(sas_ss_flags(regs->areg[1]),
361 &frame->uc.uc_stack.ss_flags); 379 &frame->uc.uc_stack.ss_flags);
362 err |= __put_user(current->sas_ss_size, &frame->uc.uc_stack.ss_size); 380 err |= __put_user(current->sas_ss_size, &frame->uc.uc_stack.ss_size);
363 err |= setup_sigcontext(&frame->uc.uc_mcontext, &frame->cpstate, 381 err |= setup_sigcontext(frame, regs);
364 regs, set->sig[0]);
365 err |= __copy_to_user(&frame->uc.uc_sigmask, set, sizeof(*set)); 382 err |= __copy_to_user(&frame->uc.uc_sigmask, set, sizeof(*set));
366 383
367 /* Create sys_rt_sigreturn syscall in stack frame */ 384 if (ka->sa.sa_flags & SA_RESTORER) {
385 ra = (unsigned long)ka->sa.sa_restorer;
386 } else {
368 387
369 err |= gen_return_code(frame->retcode); 388 /* Create sys_rt_sigreturn syscall in stack frame */
370 389
371 if (err) { 390 err |= gen_return_code(frame->retcode);
372 goto give_sigsegv; 391
392 if (err) {
393 goto give_sigsegv;
394 }
395 ra = (unsigned long) frame->retcode;
373 } 396 }
374
375 397
376 /* 398 /*
377 * Create signal handler execution context. 399 * Create signal handler execution context.
@@ -385,7 +407,6 @@ static void setup_frame(int sig, struct k_sigaction *ka, siginfo_t *info,
385 /* Set up a stack frame for a call4 407 /* Set up a stack frame for a call4
386 * Note: PS.CALLINC is set to one by start_thread 408 * Note: PS.CALLINC is set to one by start_thread
387 */ 409 */
388 ra = (unsigned long) frame->retcode;
389 regs->areg[4] = (((unsigned long) ra) & 0x3fffffff) | 0x40000000; 410 regs->areg[4] = (((unsigned long) ra) & 0x3fffffff) | 0x40000000;
390 regs->areg[6] = (unsigned long) signal; 411 regs->areg[6] = (unsigned long) signal;
391 regs->areg[7] = (unsigned long) &frame->info; 412 regs->areg[7] = (unsigned long) &frame->info;
diff --git a/arch/xtensa/kernel/traps.c b/arch/xtensa/kernel/traps.c
index 397bcd6ad08d..c7a021d9f696 100644
--- a/arch/xtensa/kernel/traps.c
+++ b/arch/xtensa/kernel/traps.c
@@ -118,28 +118,28 @@ static dispatch_init_table_t __initdata dispatch_init_table[] = {
118{ EXCCAUSE_STORE_CACHE_ATTRIBUTE, 0, do_page_fault }, 118{ EXCCAUSE_STORE_CACHE_ATTRIBUTE, 0, do_page_fault },
119{ EXCCAUSE_LOAD_CACHE_ATTRIBUTE, 0, do_page_fault }, 119{ EXCCAUSE_LOAD_CACHE_ATTRIBUTE, 0, do_page_fault },
120/* XCCHAL_EXCCAUSE_FLOATING_POINT unhandled */ 120/* XCCHAL_EXCCAUSE_FLOATING_POINT unhandled */
121#if (XCHAL_CP_MASK & 1) 121#if XTENSA_HAVE_COPROCESSOR(0)
122COPROCESSOR(0), 122COPROCESSOR(0),
123#endif 123#endif
124#if (XCHAL_CP_MASK & 2) 124#if XTENSA_HAVE_COPROCESSOR(1)
125COPROCESSOR(1), 125COPROCESSOR(1),
126#endif 126#endif
127#if (XCHAL_CP_MASK & 4) 127#if XTENSA_HAVE_COPROCESSOR(2)
128COPROCESSOR(2), 128COPROCESSOR(2),
129#endif 129#endif
130#if (XCHAL_CP_MASK & 8) 130#if XTENSA_HAVE_COPROCESSOR(3)
131COPROCESSOR(3), 131COPROCESSOR(3),
132#endif 132#endif
133#if (XCHAL_CP_MASK & 16) 133#if XTENSA_HAVE_COPROCESSOR(4)
134COPROCESSOR(4), 134COPROCESSOR(4),
135#endif 135#endif
136#if (XCHAL_CP_MASK & 32) 136#if XTENSA_HAVE_COPROCESSOR(5)
137COPROCESSOR(5), 137COPROCESSOR(5),
138#endif 138#endif
139#if (XCHAL_CP_MASK & 64) 139#if XTENSA_HAVE_COPROCESSOR(6)
140COPROCESSOR(6), 140COPROCESSOR(6),
141#endif 141#endif
142#if (XCHAL_CP_MASK & 128) 142#if XTENSA_HAVE_COPROCESSOR(7)
143COPROCESSOR(7), 143COPROCESSOR(7),
144#endif 144#endif
145{ EXCCAUSE_MAPPED_DEBUG, 0, do_debug }, 145{ EXCCAUSE_MAPPED_DEBUG, 0, do_debug },
@@ -349,9 +349,7 @@ void show_regs(struct pt_regs * regs)
349 349
350 wmask = regs->wmask & ~1; 350 wmask = regs->wmask & ~1;
351 351
352 for (i = 0; i < 32; i++) { 352 for (i = 0; i < 16; i++) {
353 if (wmask & (1 << (i / 4)))
354 break;
355 if ((i % 8) == 0) 353 if ((i % 8) == 0)
356 printk ("\n" KERN_INFO "a%02d: ", i); 354 printk ("\n" KERN_INFO "a%02d: ", i);
357 printk("%08lx ", regs->areg[i]); 355 printk("%08lx ", regs->areg[i]);
diff --git a/arch/xtensa/kernel/vmlinux.lds.S b/arch/xtensa/kernel/vmlinux.lds.S
index 7d0f55a4982d..51f4fb6f16f9 100644
--- a/arch/xtensa/kernel/vmlinux.lds.S
+++ b/arch/xtensa/kernel/vmlinux.lds.S
@@ -136,7 +136,9 @@ SECTIONS
136 __init_begin = .; 136 __init_begin = .;
137 .init.text : { 137 .init.text : {
138 _sinittext = .; 138 _sinittext = .;
139 *(.init.literal) INIT_TEXT 139 *(.init.literal) *(.cpuinit.literal)
140 *(.devinit.literal) *(.meminit.literal)
141 INIT_TEXT
140 _einittext = .; 142 _einittext = .;
141 } 143 }
142 144
@@ -161,6 +163,8 @@ SECTIONS
161 .DoubleExceptionVector.literal); 163 .DoubleExceptionVector.literal);
162 RELOCATE_ENTRY(_DoubleExceptionVector_text, 164 RELOCATE_ENTRY(_DoubleExceptionVector_text,
163 .DoubleExceptionVector.text); 165 .DoubleExceptionVector.text);
166 RELOCATE_ENTRY(_DebugInterruptVector_text,
167 .DebugInterruptVector.text);
164 168
165 __boot_reloc_table_end = ABSOLUTE(.) ; 169 __boot_reloc_table_end = ABSOLUTE(.) ;
166 } 170 }
diff --git a/arch/xtensa/mm/cache.c b/arch/xtensa/mm/cache.c
index 9a1fa9478ae7..3ba990c67676 100644
--- a/arch/xtensa/mm/cache.c
+++ b/arch/xtensa/mm/cache.c
@@ -25,7 +25,6 @@
25#include <linux/swap.h> 25#include <linux/swap.h>
26#include <linux/pagemap.h> 26#include <linux/pagemap.h>
27 27
28#include <asm/pgtable.h>
29#include <asm/bootparam.h> 28#include <asm/bootparam.h>
30#include <asm/mmu_context.h> 29#include <asm/mmu_context.h>
31#include <asm/tlb.h> 30#include <asm/tlb.h>
@@ -181,9 +180,9 @@ update_mmu_cache(struct vm_area_struct * vma, unsigned long addr, pte_t pte)
181#else 180#else
182 if (!PageReserved(page) && !test_bit(PG_arch_1, &page->flags) 181 if (!PageReserved(page) && !test_bit(PG_arch_1, &page->flags)
183 && (vma->vm_flags & VM_EXEC) != 0) { 182 && (vma->vm_flags & VM_EXEC) != 0) {
184 unsigned long vaddr = addr & PAGE_MASK; 183 unsigned long paddr = (unsigned long) page_address(page);
185 __flush_dcache_page(vaddr); 184 __flush_dcache_page(paddr);
186 __invalidate_icache_page(vaddr); 185 __invalidate_icache_page(paddr);
187 set_bit(PG_arch_1, &page->flags); 186 set_bit(PG_arch_1, &page->flags);
188 } 187 }
189#endif 188#endif
diff --git a/arch/xtensa/mm/init.c b/arch/xtensa/mm/init.c
index b3086f34a8e7..81d0560eaea2 100644
--- a/arch/xtensa/mm/init.c
+++ b/arch/xtensa/mm/init.c
@@ -309,7 +309,7 @@ void show_mem(void)
309 309
310struct kmem_cache *pgtable_cache __read_mostly; 310struct kmem_cache *pgtable_cache __read_mostly;
311 311
312static void pgd_ctor(void *addr, struct kmem_cache *cache, unsigned long flags) 312static void pgd_ctor(struct kmem_cache *cache, void* addr)
313{ 313{
314 pte_t* ptep = (pte_t*)addr; 314 pte_t* ptep = (pte_t*)addr;
315 int i; 315 int i;
diff --git a/arch/xtensa/mm/misc.S b/arch/xtensa/mm/misc.S
index e1f880368e32..c885664211d1 100644
--- a/arch/xtensa/mm/misc.S
+++ b/arch/xtensa/mm/misc.S
@@ -295,7 +295,7 @@ ENTRY(__tlbtemp_mapping_itlb)
295ENTRY(__invalidate_icache_page_alias) 295ENTRY(__invalidate_icache_page_alias)
296 entry sp, 16 296 entry sp, 16
297 297
298 addi a6, a3, (PAGE_KERNEL | _PAGE_HW_WRITE) 298 addi a6, a3, (PAGE_KERNEL_EXEC | _PAGE_HW_WRITE)
299 mov a4, a2 299 mov a4, a2
300 witlb a6, a2 300 witlb a6, a2
301 isync 301 isync
diff --git a/arch/xtensa/platform-iss/Makefile b/arch/xtensa/platforms/iss/Makefile
index af96e314d71f..af96e314d71f 100644
--- a/arch/xtensa/platform-iss/Makefile
+++ b/arch/xtensa/platforms/iss/Makefile
diff --git a/arch/xtensa/platform-iss/console.c b/arch/xtensa/platforms/iss/console.c
index 854677d0c3f6..9141e3690731 100644
--- a/arch/xtensa/platform-iss/console.c
+++ b/arch/xtensa/platforms/iss/console.c
@@ -43,6 +43,7 @@ static DEFINE_SPINLOCK(timer_lock);
43 43
44int errno; 44int errno;
45 45
46static int __simc (int a, int b, int c, int d, int e, int f) __attribute__((__noinline__));
46static int __simc (int a, int b, int c, int d, int e, int f) 47static int __simc (int a, int b, int c, int d, int e, int f)
47{ 48{
48 int ret; 49 int ret;
diff --git a/arch/xtensa/platform-iss/io.c b/arch/xtensa/platforms/iss/io.c
index 5b161a5cb65f..5b161a5cb65f 100644
--- a/arch/xtensa/platform-iss/io.c
+++ b/arch/xtensa/platforms/iss/io.c
diff --git a/arch/xtensa/platform-iss/network.c b/arch/xtensa/platforms/iss/network.c
index f21b9b0899a8..a2e252217428 100644
--- a/arch/xtensa/platform-iss/network.c
+++ b/arch/xtensa/platforms/iss/network.c
@@ -31,7 +31,6 @@
31#include <linux/bootmem.h> 31#include <linux/bootmem.h>
32#include <linux/ethtool.h> 32#include <linux/ethtool.h>
33#include <linux/rtnetlink.h> 33#include <linux/rtnetlink.h>
34#include <linux/timer.h>
35#include <linux/platform_device.h> 34#include <linux/platform_device.h>
36 35
37#include <asm/platform/simcall.h> 36#include <asm/platform/simcall.h>
@@ -108,6 +107,7 @@ struct iss_net_private {
108 107
109static int errno; 108static int errno;
110 109
110static int __simc (int a, int b, int c, int d, int e, int f) __attribute__((__noinline__));
111static int __simc (int a, int b, int c, int d, int e, int f) 111static int __simc (int a, int b, int c, int d, int e, int f)
112{ 112{
113 int ret; 113 int ret;
diff --git a/arch/xtensa/platform-iss/setup.c b/arch/xtensa/platforms/iss/setup.c
index f60c8cf6dfbe..f60c8cf6dfbe 100644
--- a/arch/xtensa/platform-iss/setup.c
+++ b/arch/xtensa/platforms/iss/setup.c
diff --git a/include/asm-xtensa/cacheflush.h b/include/asm-xtensa/cacheflush.h
index b773c57e75a5..94c4c53a099e 100644
--- a/include/asm-xtensa/cacheflush.h
+++ b/include/asm-xtensa/cacheflush.h
@@ -70,6 +70,8 @@ extern void __flush_invalidate_dcache_page_alias(unsigned long, unsigned long);
70#endif 70#endif
71#if (ICACHE_WAY_SIZE > PAGE_SIZE) 71#if (ICACHE_WAY_SIZE > PAGE_SIZE)
72extern void __invalidate_icache_page_alias(unsigned long, unsigned long); 72extern void __invalidate_icache_page_alias(unsigned long, unsigned long);
73#else
74# define __invalidate_icache_page_alias(v,p) do { } while(0)
73#endif 75#endif
74 76
75/* 77/*
diff --git a/include/asm-xtensa/coprocessor.h b/include/asm-xtensa/coprocessor.h
index aa2121034558..1cbcf9001a41 100644
--- a/include/asm-xtensa/coprocessor.h
+++ b/include/asm-xtensa/coprocessor.h
@@ -5,81 +5,173 @@
5 * License. See the file "COPYING" in the main directory of this archive 5 * License. See the file "COPYING" in the main directory of this archive
6 * for more details. 6 * for more details.
7 * 7 *
8 * Copyright (C) 2003 - 2005 Tensilica Inc. 8 * Copyright (C) 2003 - 2007 Tensilica Inc.
9 */ 9 */
10 10
11
11#ifndef _XTENSA_COPROCESSOR_H 12#ifndef _XTENSA_COPROCESSOR_H
12#define _XTENSA_COPROCESSOR_H 13#define _XTENSA_COPROCESSOR_H
13 14
14#include <asm/variant/core.h> 15#include <linux/stringify.h>
15#include <asm/variant/tie.h> 16#include <asm/variant/tie.h>
17#include <asm/types.h>
18
19#ifdef __ASSEMBLY__
20# include <asm/variant/tie-asm.h>
21
22.macro xchal_sa_start a b
23 .set .Lxchal_pofs_, 0
24 .set .Lxchal_ofs_, 0
25.endm
26
27.macro xchal_sa_align ptr minofs maxofs ofsalign totalign
28 .set .Lxchal_ofs_, .Lxchal_ofs_ + .Lxchal_pofs_ + \totalign - 1
29 .set .Lxchal_ofs_, (.Lxchal_ofs_ & -\totalign) - .Lxchal_pofs_
30.endm
31
32#define _SELECT ( XTHAL_SAS_TIE | XTHAL_SAS_OPT \
33 | XTHAL_SAS_CC \
34 | XTHAL_SAS_CALR | XTHAL_SAS_CALE )
35
36.macro save_xtregs_opt ptr clb at1 at2 at3 at4 offset
37 .if XTREGS_OPT_SIZE > 0
38 addi \clb, \ptr, \offset
39 xchal_ncp_store \clb \at1 \at2 \at3 \at4 select=_SELECT
40 .endif
41.endm
42
43.macro load_xtregs_opt ptr clb at1 at2 at3 at4 offset
44 .if XTREGS_OPT_SIZE > 0
45 addi \clb, \ptr, \offset
46 xchal_ncp_load \clb \at1 \at2 \at3 \at4 select=_SELECT
47 .endif
48.endm
49#undef _SELECT
50
51#define _SELECT ( XTHAL_SAS_TIE | XTHAL_SAS_OPT \
52 | XTHAL_SAS_NOCC \
53 | XTHAL_SAS_CALR | XTHAL_SAS_CALE | XTHAL_SAS_GLOB )
54
55.macro save_xtregs_user ptr clb at1 at2 at3 at4 offset
56 .if XTREGS_USER_SIZE > 0
57 addi \clb, \ptr, \offset
58 xchal_ncp_store \clb \at1 \at2 \at3 \at4 select=_SELECT
59 .endif
60.endm
61
62.macro load_xtregs_user ptr clb at1 at2 at3 at4 offset
63 .if XTREGS_USER_SIZE > 0
64 addi \clb, \ptr, \offset
65 xchal_ncp_load \clb \at1 \at2 \at3 \at4 select=_SELECT
66 .endif
67.endm
68#undef _SELECT
69
70
71
72#endif /* __ASSEMBLY__ */
16 73
17#if !XCHAL_HAVE_CP
18
19#define XTENSA_CP_EXTRA_OFFSET 0
20#define XTENSA_CP_EXTRA_ALIGN 1 /* must be a power of 2 */
21#define XTENSA_CP_EXTRA_SIZE 0
22
23#else
24
25#define XTOFS(last_start,last_size,align) \
26 ((last_start+last_size+align-1) & -align)
27
28#define XTENSA_CP_EXTRA_OFFSET 0
29#define XTENSA_CP_EXTRA_ALIGN XCHAL_EXTRA_SA_ALIGN
30
31#define XTENSA_CPE_CP0_OFFSET \
32 XTOFS(XTENSA_CP_EXTRA_OFFSET, XCHAL_EXTRA_SA_SIZE, XCHAL_CP0_SA_ALIGN)
33#define XTENSA_CPE_CP1_OFFSET \
34 XTOFS(XTENSA_CPE_CP0_OFFSET, XCHAL_CP0_SA_SIZE, XCHAL_CP1_SA_ALIGN)
35#define XTENSA_CPE_CP2_OFFSET \
36 XTOFS(XTENSA_CPE_CP1_OFFSET, XCHAL_CP1_SA_SIZE, XCHAL_CP2_SA_ALIGN)
37#define XTENSA_CPE_CP3_OFFSET \
38 XTOFS(XTENSA_CPE_CP2_OFFSET, XCHAL_CP2_SA_SIZE, XCHAL_CP3_SA_ALIGN)
39#define XTENSA_CPE_CP4_OFFSET \
40 XTOFS(XTENSA_CPE_CP3_OFFSET, XCHAL_CP3_SA_SIZE, XCHAL_CP4_SA_ALIGN)
41#define XTENSA_CPE_CP5_OFFSET \
42 XTOFS(XTENSA_CPE_CP4_OFFSET, XCHAL_CP4_SA_SIZE, XCHAL_CP5_SA_ALIGN)
43#define XTENSA_CPE_CP6_OFFSET \
44 XTOFS(XTENSA_CPE_CP5_OFFSET, XCHAL_CP5_SA_SIZE, XCHAL_CP6_SA_ALIGN)
45#define XTENSA_CPE_CP7_OFFSET \
46 XTOFS(XTENSA_CPE_CP6_OFFSET, XCHAL_CP6_SA_SIZE, XCHAL_CP7_SA_ALIGN)
47#define XTENSA_CP_EXTRA_SIZE \
48 XTOFS(XTENSA_CPE_CP7_OFFSET, XCHAL_CP7_SA_SIZE, 16)
49
50#if XCHAL_CP_NUM > 0
51# ifndef __ASSEMBLY__
52/* 74/*
53 * Tasks that own contents of (last user) each coprocessor. 75 * XTENSA_HAVE_COPROCESSOR(x) returns 1 if coprocessor x is configured.
54 * Entries are 0 for not-owned or non-existent coprocessors. 76 *
55 * Note: The size of this structure is fixed to 8 bytes in entry.S 77 * XTENSA_HAVE_IO_PORT(x) returns 1 if io-port x is configured.
78 *
56 */ 79 */
57typedef struct {
58 struct task_struct *owner; /* owner */
59 int offset; /* offset in cpextra space. */
60} coprocessor_info_t;
61# else
62# define COPROCESSOR_INFO_OWNER 0
63# define COPROCESSOR_INFO_OFFSET 4
64# define COPROCESSOR_INFO_SIZE 8
65# endif
66#endif
67#endif /* XCHAL_HAVE_CP */
68 80
81#define XTENSA_HAVE_COPROCESSOR(x) \
82 ((XCHAL_CP_MASK ^ XCHAL_CP_PORT_MASK) & (1 << (x)))
83#define XTENSA_HAVE_COPROCESSORS \
84 (XCHAL_CP_MASK ^ XCHAL_CP_PORT_MASK)
85#define XTENSA_HAVE_IO_PORT(x) \
86 (XCHAL_CP_PORT_MASK & (1 << (x)))
87#define XTENSA_HAVE_IO_PORTS \
88 XCHAL_CP_PORT_MASK
69 89
70#ifndef __ASSEMBLY__ 90#ifndef __ASSEMBLY__
71# if XCHAL_CP_NUM > 0
72struct task_struct;
73extern void release_coprocessors (struct task_struct*);
74extern void save_coprocessor_registers(void*, int);
75# else
76# define release_coprocessors(task)
77# endif
78 91
79typedef unsigned char cp_state_t[XTENSA_CP_EXTRA_SIZE]
80 __attribute__ ((aligned (XTENSA_CP_EXTRA_ALIGN)));
81 92
82#endif /* !__ASSEMBLY__ */ 93#if XCHAL_HAVE_CP
94
95#define RSR_CPENABLE(x) do { \
96 __asm__ __volatile__("rsr %0," __stringify(CPENABLE) : "=a" (x)); \
97 } while(0);
98#define WSR_CPENABLE(x) do { \
99 __asm__ __volatile__("wsr %0," __stringify(CPENABLE) "; rsync" \
100 :: "a" (x)); \
101 } while(0);
83 102
103#endif /* XCHAL_HAVE_CP */
84 104
105
106/*
107 * Additional registers.
108 * We define three types of additional registers:
109 * ext: extra registers that are used by the compiler
110 * cpn: optional registers that can be used by a user application
111 * cpX: coprocessor registers that can only be used if the corresponding
112 * CPENABLE bit is set.
113 */
114
115#define XCHAL_SA_REG(list,cc,abi,type,y,name,z,align,size,...) \
116 __REG ## list (cc, abi, type, name, size, align)
117
118#define __REG0(cc,abi,t,name,s,a) __REG0_ ## cc (abi,name)
119#define __REG1(cc,abi,t,name,s,a) __REG1_ ## cc (name)
120#define __REG2(cc,abi,type,...) __REG2_ ## type (__VA_ARGS__)
121
122#define __REG0_0(abi,name)
123#define __REG0_1(abi,name) __REG0_1 ## abi (name)
124#define __REG0_10(name) __u32 name;
125#define __REG0_11(name) __u32 name;
126#define __REG0_12(name)
127
128#define __REG1_0(name) __u32 name;
129#define __REG1_1(name)
130
131#define __REG2_0(n,s,a) __u32 name;
132#define __REG2_1(n,s,a) unsigned char n[s] __attribute__ ((aligned(a)));
133#define __REG2_2(n,s,a) unsigned char n[s] __attribute__ ((aligned(a)));
134
135typedef struct { XCHAL_NCP_SA_LIST(0) } xtregs_opt_t
136 __attribute__ ((aligned (XCHAL_NCP_SA_ALIGN)));
137typedef struct { XCHAL_NCP_SA_LIST(1) } xtregs_user_t
138 __attribute__ ((aligned (XCHAL_NCP_SA_ALIGN)));
139
140#if XTENSA_HAVE_COPROCESSORS
141
142typedef struct { XCHAL_CP0_SA_LIST(2) } xtregs_cp0_t
143 __attribute__ ((aligned (XCHAL_CP0_SA_ALIGN)));
144typedef struct { XCHAL_CP1_SA_LIST(2) } xtregs_cp1_t
145 __attribute__ ((aligned (XCHAL_CP1_SA_ALIGN)));
146typedef struct { XCHAL_CP2_SA_LIST(2) } xtregs_cp2_t
147 __attribute__ ((aligned (XCHAL_CP2_SA_ALIGN)));
148typedef struct { XCHAL_CP3_SA_LIST(2) } xtregs_cp3_t
149 __attribute__ ((aligned (XCHAL_CP3_SA_ALIGN)));
150typedef struct { XCHAL_CP4_SA_LIST(2) } xtregs_cp4_t
151 __attribute__ ((aligned (XCHAL_CP4_SA_ALIGN)));
152typedef struct { XCHAL_CP5_SA_LIST(2) } xtregs_cp5_t
153 __attribute__ ((aligned (XCHAL_CP5_SA_ALIGN)));
154typedef struct { XCHAL_CP6_SA_LIST(2) } xtregs_cp6_t
155 __attribute__ ((aligned (XCHAL_CP6_SA_ALIGN)));
156typedef struct { XCHAL_CP7_SA_LIST(2) } xtregs_cp7_t
157 __attribute__ ((aligned (XCHAL_CP7_SA_ALIGN)));
158
159extern struct thread_info* coprocessor_owner[XCHAL_CP_MAX];
160extern void coprocessor_save(void*, int);
161extern void coprocessor_load(void*, int);
162extern void coprocessor_flush(struct thread_info*, int);
163extern void coprocessor_restore(struct thread_info*, int);
164
165extern void coprocessor_release_all(struct thread_info*);
166extern void coprocessor_flush_all(struct thread_info*);
167
168static inline void coprocessor_clear_cpenable(void)
169{
170 unsigned long i = 0;
171 WSR_CPENABLE(i);
172}
173
174#endif /* XTENSA_HAVE_COPROCESSORS */
175
176#endif /* !__ASSEMBLY__ */
85#endif /* _XTENSA_COPROCESSOR_H */ 177#endif /* _XTENSA_COPROCESSOR_H */
diff --git a/include/asm-xtensa/elf.h b/include/asm-xtensa/elf.h
index 467384542502..ca6e5101a2cb 100644
--- a/include/asm-xtensa/elf.h
+++ b/include/asm-xtensa/elf.h
@@ -72,115 +72,32 @@
72 72
73/* ELF register definitions. This is needed for core dump support. */ 73/* ELF register definitions. This is needed for core dump support. */
74 74
75/*
76 * elf_gregset_t contains the application-level state in the following order:
77 * Processor info: config_version, cpuxy
78 * Processor state: pc, ps, exccause, excvaddr, wb, ws,
79 * lbeg, lend, lcount, sar
80 * GP regs: ar0 - arXX
81 */
82
83typedef unsigned long elf_greg_t; 75typedef unsigned long elf_greg_t;
84 76
85typedef struct { 77typedef struct {
86 elf_greg_t xchal_config_id0;
87 elf_greg_t xchal_config_id1;
88 elf_greg_t cpux;
89 elf_greg_t cpuy;
90 elf_greg_t pc; 78 elf_greg_t pc;
91 elf_greg_t ps; 79 elf_greg_t ps;
92 elf_greg_t exccause;
93 elf_greg_t excvaddr;
94 elf_greg_t windowbase;
95 elf_greg_t windowstart;
96 elf_greg_t lbeg; 80 elf_greg_t lbeg;
97 elf_greg_t lend; 81 elf_greg_t lend;
98 elf_greg_t lcount; 82 elf_greg_t lcount;
99 elf_greg_t sar; 83 elf_greg_t sar;
100 elf_greg_t syscall; 84 elf_greg_t windowstart;
101 elf_greg_t ar[64]; 85 elf_greg_t windowbase;
86 elf_greg_t reserved[8+48];
87 elf_greg_t a[64];
102} xtensa_gregset_t; 88} xtensa_gregset_t;
103 89
104#define ELF_NGREG (sizeof(xtensa_gregset_t) / sizeof(elf_greg_t)) 90#define ELF_NGREG (sizeof(xtensa_gregset_t) / sizeof(elf_greg_t))
105 91
106typedef elf_greg_t elf_gregset_t[ELF_NGREG]; 92typedef elf_greg_t elf_gregset_t[ELF_NGREG];
107 93
108/* 94#define ELF_NFPREG 18
109 * Compute the size of the coprocessor and extra state layout (register info)
110 * table (in bytes).
111 * This is actually the maximum size of the table, as opposed to the size,
112 * which is available from the _xtensa_reginfo_table_size global variable.
113 *
114 * (See also arch/xtensa/kernel/coprocessor.S)
115 *
116 */
117
118#ifndef XCHAL_EXTRA_SA_CONTENTS_LIBDB_NUM
119# define XTENSA_CPE_LTABLE_SIZE 0
120#else
121# define XTENSA_CPE_SEGMENT(num) (num ? (1+num) : 0)
122# define XTENSA_CPE_LTABLE_ENTRIES \
123 ( XTENSA_CPE_SEGMENT(XCHAL_EXTRA_SA_CONTENTS_LIBDB_NUM) \
124 + XTENSA_CPE_SEGMENT(XCHAL_CP0_SA_CONTENTS_LIBDB_NUM) \
125 + XTENSA_CPE_SEGMENT(XCHAL_CP1_SA_CONTENTS_LIBDB_NUM) \
126 + XTENSA_CPE_SEGMENT(XCHAL_CP2_SA_CONTENTS_LIBDB_NUM) \
127 + XTENSA_CPE_SEGMENT(XCHAL_CP3_SA_CONTENTS_LIBDB_NUM) \
128 + XTENSA_CPE_SEGMENT(XCHAL_CP4_SA_CONTENTS_LIBDB_NUM) \
129 + XTENSA_CPE_SEGMENT(XCHAL_CP5_SA_CONTENTS_LIBDB_NUM) \
130 + XTENSA_CPE_SEGMENT(XCHAL_CP6_SA_CONTENTS_LIBDB_NUM) \
131 + XTENSA_CPE_SEGMENT(XCHAL_CP7_SA_CONTENTS_LIBDB_NUM) \
132 + 1 /* final entry */ \
133 )
134# define XTENSA_CPE_LTABLE_SIZE (XTENSA_CPE_LTABLE_ENTRIES * 8)
135#endif
136
137
138/*
139 * Instantiations of the elf_fpregset_t type contain, in most
140 * architectures, the floating point (FPU) register set.
141 * For Xtensa, this type is extended to contain all custom state,
142 * ie. coprocessor and "extra" (non-coprocessor) state (including,
143 * for example, TIE-defined states and register files; as well
144 * as other optional processor state).
145 * This includes FPU state if a floating-point coprocessor happens
146 * to have been configured within the Xtensa processor.
147 *
148 * TOTAL_FPREGS_SIZE is the required size (without rounding)
149 * of elf_fpregset_t. It provides space for the following:
150 *
151 * a) 32-bit mask of active coprocessors for this task (similar
152 * to CPENABLE in single-threaded Xtensa processor systems)
153 *
154 * b) table describing the layout of custom states (ie. of
155 * individual registers, etc) within the save areas
156 *
157 * c) save areas for each coprocessor and for non-coprocessor
158 * ("extra") state
159 *
160 * Note that save areas may require up to 16-byte alignment when
161 * accessed by save/restore sequences. We do not need to ensure
162 * such alignment in an elf_fpregset_t structure because custom
163 * state is not directly loaded/stored into it; rather, save area
164 * contents are copied to elf_fpregset_t from the active save areas
165 * (see 'struct task_struct' definition in processor.h for that)
166 * using memcpy(). But we do allow space for such alignment,
167 * to allow optimizations of layout and copying.
168 */
169#if 0
170#define TOTAL_FPREGS_SIZE \
171 (4 + XTENSA_CPE_LTABLE_SIZE + XTENSA_CP_EXTRA_SIZE)
172#define ELF_NFPREG \
173 ((TOTAL_FPREGS_SIZE + sizeof(elf_fpreg_t) - 1) / sizeof(elf_fpreg_t))
174#else
175#define TOTAL_FPREGS_SIZE 0
176#define ELF_NFPREG 0
177#endif
178 95
179typedef unsigned int elf_fpreg_t; 96typedef unsigned int elf_fpreg_t;
180typedef elf_fpreg_t elf_fpregset_t[ELF_NFPREG]; 97typedef elf_fpreg_t elf_fpregset_t[ELF_NFPREG];
181 98
182#define ELF_CORE_COPY_REGS(_eregs, _pregs) \ 99#define ELF_CORE_COPY_REGS(_eregs, _pregs) \
183 xtensa_elf_core_copy_regs (&_eregs, _pregs); 100 xtensa_elf_core_copy_regs ((xtensa_gregset_t*)&(_eregs), _pregs);
184 101
185extern void xtensa_elf_core_copy_regs (xtensa_gregset_t *, struct pt_regs *); 102extern void xtensa_elf_core_copy_regs (xtensa_gregset_t *, struct pt_regs *);
186 103
@@ -257,6 +174,21 @@ extern void xtensa_elf_core_copy_regs (xtensa_gregset_t *, struct pt_regs *);
257 _r->areg[12]=0; _r->areg[13]=0; _r->areg[14]=0; _r->areg[15]=0; \ 174 _r->areg[12]=0; _r->areg[13]=0; _r->areg[14]=0; _r->areg[15]=0; \
258 } while (0) 175 } while (0)
259 176
177typedef struct {
178 xtregs_opt_t opt;
179 xtregs_user_t user;
180#if XTENSA_HAVE_COPROCESSORS
181 xtregs_cp0_t cp0;
182 xtregs_cp1_t cp1;
183 xtregs_cp2_t cp2;
184 xtregs_cp3_t cp3;
185 xtregs_cp4_t cp4;
186 xtregs_cp5_t cp5;
187 xtregs_cp6_t cp6;
188 xtregs_cp7_t cp7;
189#endif
190} elf_xtregs_t;
191
260#define SET_PERSONALITY(ex, ibcs2) set_personality(PER_LINUX_32BIT) 192#define SET_PERSONALITY(ex, ibcs2) set_personality(PER_LINUX_32BIT)
261 193
262struct task_struct; 194struct task_struct;
diff --git a/include/asm-xtensa/module.h b/include/asm-xtensa/module.h
index ffb25bfdf6a1..d9b34bee4d42 100644
--- a/include/asm-xtensa/module.h
+++ b/include/asm-xtensa/module.h
@@ -15,9 +15,11 @@
15 15
16struct mod_arch_specific 16struct mod_arch_specific
17{ 17{
18 /* Module support is not completely implemented. */ 18 /* No special elements, yet. */
19}; 19};
20 20
21#define MODULE_ARCH_VERMAGIC "xtensa-" __stringify(XCHAL_CORE_ID) " "
22
21#define Elf_Shdr Elf32_Shdr 23#define Elf_Shdr Elf32_Shdr
22#define Elf_Sym Elf32_Sym 24#define Elf_Sym Elf32_Sym
23#define Elf_Ehdr Elf32_Ehdr 25#define Elf_Ehdr Elf32_Ehdr
diff --git a/include/asm-xtensa/pgalloc.h b/include/asm-xtensa/pgalloc.h
index 8d1544eb461e..4f4a7987eded 100644
--- a/include/asm-xtensa/pgalloc.h
+++ b/include/asm-xtensa/pgalloc.h
@@ -47,7 +47,7 @@ static inline pte_t *pte_alloc_one_kernel(struct mm_struct *mm,
47 return kmem_cache_alloc(pgtable_cache, GFP_KERNEL|__GFP_REPEAT); 47 return kmem_cache_alloc(pgtable_cache, GFP_KERNEL|__GFP_REPEAT);
48} 48}
49 49
50static inline pte_token_t pte_alloc_one(struct mm_struct *mm, 50static inline pgtable_t pte_alloc_one(struct mm_struct *mm,
51 unsigned long addr) 51 unsigned long addr)
52{ 52{
53 struct page *page; 53 struct page *page;
diff --git a/include/asm-xtensa/pgtable.h b/include/asm-xtensa/pgtable.h
index c0fcc1c9660c..c8b024a48b4d 100644
--- a/include/asm-xtensa/pgtable.h
+++ b/include/asm-xtensa/pgtable.h
@@ -66,11 +66,9 @@
66 */ 66 */
67 67
68#define VMALLOC_START 0xC0000000 68#define VMALLOC_START 0xC0000000
69#define VMALLOC_END 0xC6FEFFFF 69#define VMALLOC_END 0xC7FEFFFF
70#define TLBTEMP_BASE_1 0xC6FF0000 70#define TLBTEMP_BASE_1 0xC7FF0000
71#define TLBTEMP_BASE_2 0xC6FF8000 71#define TLBTEMP_BASE_2 0xC7FF8000
72#define MODULE_START 0xC7000000
73#define MODULE_END 0xC7FFFFFF
74 72
75/* 73/*
76 * Xtensa Linux config PTE layout (when present): 74 * Xtensa Linux config PTE layout (when present):
diff --git a/include/asm-xtensa/processor.h b/include/asm-xtensa/processor.h
index 96408f436624..4918a4e96d42 100644
--- a/include/asm-xtensa/processor.h
+++ b/include/asm-xtensa/processor.h
@@ -103,10 +103,6 @@ struct thread_struct {
103 unsigned long dbreaka[XCHAL_NUM_DBREAK]; 103 unsigned long dbreaka[XCHAL_NUM_DBREAK];
104 unsigned long dbreakc[XCHAL_NUM_DBREAK]; 104 unsigned long dbreakc[XCHAL_NUM_DBREAK];
105 105
106 /* Allocate storage for extra state and coprocessor state. */
107 unsigned char cp_save[XTENSA_CP_EXTRA_SIZE]
108 __attribute__ ((aligned(XTENSA_CP_EXTRA_ALIGN)));
109
110 /* Make structure 16 bytes aligned. */ 106 /* Make structure 16 bytes aligned. */
111 int align[0] __attribute__ ((aligned(16))); 107 int align[0] __attribute__ ((aligned(16)));
112}; 108};
@@ -162,21 +158,16 @@ struct thread_struct {
162struct task_struct; 158struct task_struct;
163struct mm_struct; 159struct mm_struct;
164 160
165// FIXME: do we need release_thread for CP??
166/* Free all resources held by a thread. */ 161/* Free all resources held by a thread. */
167#define release_thread(thread) do { } while(0) 162#define release_thread(thread) do { } while(0)
168 163
169// FIXME: do we need prepare_to_copy (lazy status) for CP??
170/* Prepare to copy thread state - unlazy all lazy status */ 164/* Prepare to copy thread state - unlazy all lazy status */
171#define prepare_to_copy(tsk) do { } while (0) 165extern void prepare_to_copy(struct task_struct*);
172 166
173/* 167/* Create a kernel thread without removing it from tasklists */
174 * create a kernel thread without removing it from tasklists
175 */
176extern int kernel_thread(int (*fn)(void *), void * arg, unsigned long flags); 168extern int kernel_thread(int (*fn)(void *), void * arg, unsigned long flags);
177 169
178/* Copy and release all segment info associated with a VM */ 170/* Copy and release all segment info associated with a VM */
179
180#define copy_segments(p, mm) do { } while(0) 171#define copy_segments(p, mm) do { } while(0)
181#define release_segments(mm) do { } while(0) 172#define release_segments(mm) do { } while(0)
182#define forget_segments() do { } while (0) 173#define forget_segments() do { } while (0)
diff --git a/include/asm-xtensa/ptrace.h b/include/asm-xtensa/ptrace.h
index 77ff02d307bb..422c73e26937 100644
--- a/include/asm-xtensa/ptrace.h
+++ b/include/asm-xtensa/ptrace.h
@@ -53,33 +53,30 @@
53 53
54/* Registers used by strace */ 54/* Registers used by strace */
55 55
56#define REG_A_BASE 0xfc000000 56#define REG_A_BASE 0x0000
57#define REG_AR_BASE 0x04000000 57#define REG_AR_BASE 0x0100
58#define REG_PC 0x14000000 58#define REG_PC 0x0020
59#define REG_PS 0x080000e6 59#define REG_PS 0x02e6
60#define REG_WB 0x08000048 60#define REG_WB 0x0248
61#define REG_WS 0x08000049 61#define REG_WS 0x0249
62#define REG_LBEG 0x08000000 62#define REG_LBEG 0x0200
63#define REG_LEND 0x08000001 63#define REG_LEND 0x0201
64#define REG_LCOUNT 0x08000002 64#define REG_LCOUNT 0x0202
65#define REG_SAR 0x08000003 65#define REG_SAR 0x0203
66#define REG_DEPC 0x080000c0 66
67#define REG_EXCCAUSE 0x080000e8 67#define SYSCALL_NR 0x00ff
68#define REG_EXCVADDR 0x080000ee
69#define SYSCALL_NR 0x1
70
71#define AR_REGNO_TO_A_REGNO(ar, wb) (ar - wb*4) & ~(XCHAL_NUM_AREGS - 1)
72 68
73/* Other PTRACE_ values defined in <linux/ptrace.h> using values 0-9,16,17,24 */ 69/* Other PTRACE_ values defined in <linux/ptrace.h> using values 0-9,16,17,24 */
74 70
75#define PTRACE_GETREGS 12 71#define PTRACE_GETREGS 12
76#define PTRACE_SETREGS 13 72#define PTRACE_SETREGS 13
77#define PTRACE_GETFPREGS 14 73#define PTRACE_GETXTREGS 18
78#define PTRACE_SETFPREGS 15 74#define PTRACE_SETXTREGS 19
79#define PTRACE_GETFPREGSIZE 18
80 75
81#ifndef __ASSEMBLY__ 76#ifndef __ASSEMBLY__
82 77
78#ifdef __KERNEL__
79
83/* 80/*
84 * This struct defines the way the registers are stored on the 81 * This struct defines the way the registers are stored on the
85 * kernel stack during a system call or other kernel entry. 82 * kernel stack during a system call or other kernel entry.
@@ -102,6 +99,9 @@ struct pt_regs {
102 unsigned long icountlevel; /* 60 */ 99 unsigned long icountlevel; /* 60 */
103 int reserved[1]; /* 64 */ 100 int reserved[1]; /* 64 */
104 101
102 /* Additional configurable registers that are used by the compiler. */
103 xtregs_opt_t xtregs_opt;
104
105 /* Make sure the areg field is 16 bytes aligned. */ 105 /* Make sure the areg field is 16 bytes aligned. */
106 int align[0] __attribute__ ((aligned(16))); 106 int align[0] __attribute__ ((aligned(16)));
107 107
@@ -111,8 +111,6 @@ struct pt_regs {
111 unsigned long areg[16]; /* 128 (64) */ 111 unsigned long areg[16]; /* 128 (64) */
112}; 112};
113 113
114#ifdef __KERNEL__
115
116#include <asm/variant/core.h> 114#include <asm/variant/core.h>
117 115
118# define task_pt_regs(tsk) ((struct pt_regs*) \ 116# define task_pt_regs(tsk) ((struct pt_regs*) \
diff --git a/include/asm-xtensa/regs.h b/include/asm-xtensa/regs.h
index c913d259faaa..d4baed246928 100644
--- a/include/asm-xtensa/regs.h
+++ b/include/asm-xtensa/regs.h
@@ -100,7 +100,14 @@
100#define EXCCAUSE_DTLB_SIZE_RESTRICTION 27 100#define EXCCAUSE_DTLB_SIZE_RESTRICTION 27
101#define EXCCAUSE_LOAD_CACHE_ATTRIBUTE 28 101#define EXCCAUSE_LOAD_CACHE_ATTRIBUTE 28
102#define EXCCAUSE_STORE_CACHE_ATTRIBUTE 29 102#define EXCCAUSE_STORE_CACHE_ATTRIBUTE 29
103#define EXCCAUSE_FLOATING_POINT 40 103#define EXCCAUSE_COPROCESSOR0_DISABLED 32
104#define EXCCAUSE_COPROCESSOR1_DISABLED 33
105#define EXCCAUSE_COPROCESSOR2_DISABLED 34
106#define EXCCAUSE_COPROCESSOR3_DISABLED 35
107#define EXCCAUSE_COPROCESSOR4_DISABLED 36
108#define EXCCAUSE_COPROCESSOR5_DISABLED 37
109#define EXCCAUSE_COPROCESSOR6_DISABLED 38
110#define EXCCAUSE_COPROCESSOR7_DISABLED 39
104 111
105/* PS register fields. */ 112/* PS register fields. */
106 113
diff --git a/include/asm-xtensa/sigcontext.h b/include/asm-xtensa/sigcontext.h
index e3381cee5059..03383af8c3b7 100644
--- a/include/asm-xtensa/sigcontext.h
+++ b/include/asm-xtensa/sigcontext.h
@@ -13,9 +13,6 @@
13 13
14 14
15struct sigcontext { 15struct sigcontext {
16 unsigned long oldmask;
17
18 /* CPU registers */
19 unsigned long sc_pc; 16 unsigned long sc_pc;
20 unsigned long sc_ps; 17 unsigned long sc_ps;
21 unsigned long sc_lbeg; 18 unsigned long sc_lbeg;
@@ -25,6 +22,7 @@ struct sigcontext {
25 unsigned long sc_acclo; 22 unsigned long sc_acclo;
26 unsigned long sc_acchi; 23 unsigned long sc_acchi;
27 unsigned long sc_a[16]; 24 unsigned long sc_a[16];
25 void *sc_xtregs;
28}; 26};
29 27
30#endif /* _XTENSA_SIGCONTEXT_H */ 28#endif /* _XTENSA_SIGCONTEXT_H */
diff --git a/include/asm-xtensa/stat.h b/include/asm-xtensa/stat.h
index 149f4bce092f..c4992038cee0 100644
--- a/include/asm-xtensa/stat.h
+++ b/include/asm-xtensa/stat.h
@@ -5,25 +5,23 @@
5 * License. See the file "COPYING" in the main directory of this archive 5 * License. See the file "COPYING" in the main directory of this archive
6 * for more details. 6 * for more details.
7 * 7 *
8 * Copyright (C) 2001 - 2005 Tensilica Inc. 8 * Copyright (C) 2001 - 2007 Tensilica Inc.
9 */ 9 */
10 10
11#ifndef _XTENSA_STAT_H 11#ifndef _XTENSA_STAT_H
12#define _XTENSA_STAT_H 12#define _XTENSA_STAT_H
13 13
14#include <linux/types.h>
15
16#define STAT_HAVE_NSEC 1 14#define STAT_HAVE_NSEC 1
17 15
18struct stat { 16struct stat {
19 unsigned long st_dev; 17 unsigned long st_dev;
20 ino_t st_ino; 18 unsigned long st_ino;
21 mode_t st_mode; 19 unsigned int st_mode;
22 nlink_t st_nlink; 20 unsigned int st_nlink;
23 uid_t st_uid; 21 unsigned int st_uid;
24 gid_t st_gid; 22 unsigned int st_gid;
25 unsigned int st_rdev; 23 unsigned long st_rdev;
26 off_t st_size; 24 long st_size;
27 unsigned long st_blksize; 25 unsigned long st_blksize;
28 unsigned long st_blocks; 26 unsigned long st_blocks;
29 unsigned long st_atime; 27 unsigned long st_atime;
@@ -36,8 +34,6 @@ struct stat {
36 unsigned long __unused5; 34 unsigned long __unused5;
37}; 35};
38 36
39/* This matches struct stat64 in glibc-2.3 */
40
41struct stat64 { 37struct stat64 {
42 unsigned long long st_dev; /* Device */ 38 unsigned long long st_dev; /* Device */
43 unsigned long long st_ino; /* File serial number */ 39 unsigned long long st_ino; /* File serial number */
@@ -47,20 +43,14 @@ struct stat64 {
47 unsigned int st_gid; /* Group ID of the file's group. */ 43 unsigned int st_gid; /* Group ID of the file's group. */
48 unsigned long long st_rdev; /* Device number, if device. */ 44 unsigned long long st_rdev; /* Device number, if device. */
49 long long st_size; /* Size of file, in bytes. */ 45 long long st_size; /* Size of file, in bytes. */
50 long st_blksize; /* Optimal block size for I/O. */ 46 unsigned long st_blksize; /* Optimal block size for I/O. */
51 unsigned long __unused2; 47 unsigned long __unused2;
52#ifdef __XTENSA_EB__ 48 unsigned long long st_blocks; /* Number 512-byte blocks allocated. */
53 unsigned long __unused3; 49 unsigned long st_atime; /* Time of last access. */
54 long st_blocks; /* Number 512-byte blocks allocated. */
55#else
56 long st_blocks; /* Number 512-byte blocks allocated. */
57 unsigned long __unused3;
58#endif
59 long st_atime; /* Time of last access. */
60 unsigned long st_atime_nsec; 50 unsigned long st_atime_nsec;
61 long st_mtime; /* Time of last modification. */ 51 unsigned long st_mtime; /* Time of last modification. */
62 unsigned long st_mtime_nsec; 52 unsigned long st_mtime_nsec;
63 long st_ctime; /* Time of last status change. */ 53 unsigned long st_ctime; /* Time of last status change. */
64 unsigned long st_ctime_nsec; 54 unsigned long st_ctime_nsec;
65 unsigned long __unused4; 55 unsigned long __unused4;
66 unsigned long __unused5; 56 unsigned long __unused5;
diff --git a/include/asm-xtensa/system.h b/include/asm-xtensa/system.h
index e0cb9116d8ab..62b1e8f3c13c 100644
--- a/include/asm-xtensa/system.h
+++ b/include/asm-xtensa/system.h
@@ -46,42 +46,6 @@ static inline int irqs_disabled(void)
46 return flags & 0xf; 46 return flags & 0xf;
47} 47}
48 48
49#define RSR_CPENABLE(x) do { \
50 __asm__ __volatile__("rsr %0," __stringify(CPENABLE) : "=a" (x)); \
51 } while(0);
52#define WSR_CPENABLE(x) do { \
53 __asm__ __volatile__("wsr %0," __stringify(CPENABLE)";rsync" \
54 :: "a" (x));} while(0);
55
56#define clear_cpenable() __clear_cpenable()
57
58static inline void __clear_cpenable(void)
59{
60#if XCHAL_HAVE_CP
61 unsigned long i = 0;
62 WSR_CPENABLE(i);
63#endif
64}
65
66static inline void enable_coprocessor(int i)
67{
68#if XCHAL_HAVE_CP
69 int cp;
70 RSR_CPENABLE(cp);
71 cp |= 1 << i;
72 WSR_CPENABLE(cp);
73#endif
74}
75
76static inline void disable_coprocessor(int i)
77{
78#if XCHAL_HAVE_CP
79 int cp;
80 RSR_CPENABLE(cp);
81 cp &= ~(1 << i);
82 WSR_CPENABLE(cp);
83#endif
84}
85 49
86#define smp_read_barrier_depends() do { } while(0) 50#define smp_read_barrier_depends() do { } while(0)
87#define read_barrier_depends() do { } while(0) 51#define read_barrier_depends() do { } while(0)
@@ -111,7 +75,6 @@ extern void *_switch_to(void *last, void *next);
111 75
112#define switch_to(prev,next,last) \ 76#define switch_to(prev,next,last) \
113do { \ 77do { \
114 clear_cpenable(); \
115 (last) = _switch_to(prev, next); \ 78 (last) = _switch_to(prev, next); \
116} while(0) 79} while(0)
117 80
@@ -244,7 +207,7 @@ static inline void spill_registers(void)
244 "wsr a13," __stringify(SAR) "\n\t" 207 "wsr a13," __stringify(SAR) "\n\t"
245 "wsr a14," __stringify(PS) "\n\t" 208 "wsr a14," __stringify(PS) "\n\t"
246 :: "a" (&a0), "a" (&ps) 209 :: "a" (&a0), "a" (&ps)
247 : "a2", "a3", "a12", "a13", "a14", "a15", "memory"); 210 : "a2", "a3", "a4", "a7", "a11", "a12", "a13", "a14", "a15", "memory");
248} 211}
249 212
250#define arch_align_stack(x) (x) 213#define arch_align_stack(x) (x)
diff --git a/include/asm-xtensa/thread_info.h b/include/asm-xtensa/thread_info.h
index 52c958285bcb..a2c640682ed9 100644
--- a/include/asm-xtensa/thread_info.h
+++ b/include/asm-xtensa/thread_info.h
@@ -27,6 +27,21 @@
27 27
28#ifndef __ASSEMBLY__ 28#ifndef __ASSEMBLY__
29 29
30#if XTENSA_HAVE_COPROCESSORS
31
32typedef struct xtregs_coprocessor {
33 xtregs_cp0_t cp0;
34 xtregs_cp1_t cp1;
35 xtregs_cp2_t cp2;
36 xtregs_cp3_t cp3;
37 xtregs_cp4_t cp4;
38 xtregs_cp5_t cp5;
39 xtregs_cp6_t cp6;
40 xtregs_cp7_t cp7;
41} xtregs_coprocessor_t;
42
43#endif
44
30struct thread_info { 45struct thread_info {
31 struct task_struct *task; /* main task structure */ 46 struct task_struct *task; /* main task structure */
32 struct exec_domain *exec_domain; /* execution domain */ 47 struct exec_domain *exec_domain; /* execution domain */
@@ -38,7 +53,13 @@ struct thread_info {
38 mm_segment_t addr_limit; /* thread address space */ 53 mm_segment_t addr_limit; /* thread address space */
39 struct restart_block restart_block; 54 struct restart_block restart_block;
40 55
56 unsigned long cpenable;
41 57
58 /* Allocate storage for extra user states and coprocessor states. */
59#if XTENSA_HAVE_COPROCESSORS
60 xtregs_coprocessor_t xtregs_cp;
61#endif
62 xtregs_user_t xtregs_user;
42}; 63};
43 64
44#else /* !__ASSEMBLY__ */ 65#else /* !__ASSEMBLY__ */
diff --git a/include/asm-xtensa/timex.h b/include/asm-xtensa/timex.h
index a5fca59fba9e..b83a8181d448 100644
--- a/include/asm-xtensa/timex.h
+++ b/include/asm-xtensa/timex.h
@@ -63,10 +63,10 @@ extern cycles_t cacheflush_time;
63 * Register access. 63 * Register access.
64 */ 64 */
65 65
66#define WSR_CCOUNT(r) __asm__("wsr %0,"__stringify(CCOUNT) :: "a" (r)) 66#define WSR_CCOUNT(r) asm volatile ("wsr %0,"__stringify(CCOUNT) :: "a" (r))
67#define RSR_CCOUNT(r) __asm__("rsr %0,"__stringify(CCOUNT) : "=a" (r)) 67#define RSR_CCOUNT(r) asm volatile ("rsr %0,"__stringify(CCOUNT) : "=a" (r))
68#define WSR_CCOMPARE(x,r) __asm__("wsr %0,"__stringify(CCOMPARE)"+"__stringify(x) :: "a"(r)) 68#define WSR_CCOMPARE(x,r) asm volatile ("wsr %0,"__stringify(CCOMPARE)"+"__stringify(x) :: "a"(r))
69#define RSR_CCOMPARE(x,r) __asm__("rsr %0,"__stringify(CCOMPARE)"+"__stringify(x) : "=a"(r)) 69#define RSR_CCOMPARE(x,r) asm volatile ("rsr %0,"__stringify(CCOMPARE)"+"__stringify(x) : "=a"(r))
70 70
71static inline unsigned long get_ccount (void) 71static inline unsigned long get_ccount (void)
72{ 72{
diff --git a/include/asm-xtensa/uaccess.h b/include/asm-xtensa/uaccess.h
index d6352da05b10..b8528426ab1f 100644
--- a/include/asm-xtensa/uaccess.h
+++ b/include/asm-xtensa/uaccess.h
@@ -26,6 +26,7 @@
26#include <asm/current.h> 26#include <asm/current.h>
27#include <asm/asm-offsets.h> 27#include <asm/asm-offsets.h>
28#include <asm/processor.h> 28#include <asm/processor.h>
29#include <asm/types.h>
29 30
30/* 31/*
31 * These assembly macros mirror the C macros that follow below. They 32 * These assembly macros mirror the C macros that follow below. They
@@ -118,7 +119,7 @@
118 * <at> destroyed (actually, (TASK_SIZE + 1 - size)) 119 * <at> destroyed (actually, (TASK_SIZE + 1 - size))
119 */ 120 */
120 .macro user_ok aa, as, at, error 121 .macro user_ok aa, as, at, error
121 movi \at, (TASK_SIZE+1) 122 movi \at, __XTENSA_UL_CONST(TASK_SIZE)
122 bgeu \as, \at, \error 123 bgeu \as, \at, \error
123 sub \at, \at, \as 124 sub \at, \at, \as
124 bgeu \aa, \at, \error 125 bgeu \aa, \at, \error
@@ -226,20 +227,21 @@ extern long __put_user_bad(void);
226 __pu_err; \ 227 __pu_err; \
227}) 228})
228 229
229#define __put_user_size(x,ptr,size,retval) \ 230#define __put_user_size(x,ptr,size,retval) \
230do { \ 231do { \
231 retval = 0; \ 232 int __cb; \
232 switch (size) { \ 233 retval = 0; \
233 case 1: __put_user_asm(x,ptr,retval,1,"s8i"); break; \ 234 switch (size) { \
234 case 2: __put_user_asm(x,ptr,retval,2,"s16i"); break; \ 235 case 1: __put_user_asm(x,ptr,retval,1,"s8i",__cb); break; \
235 case 4: __put_user_asm(x,ptr,retval,4,"s32i"); break; \ 236 case 2: __put_user_asm(x,ptr,retval,2,"s16i",__cb); break; \
236 case 8: { \ 237 case 4: __put_user_asm(x,ptr,retval,4,"s32i",__cb); break; \
237 __typeof__(*ptr) __v64 = x; \ 238 case 8: { \
238 retval = __copy_to_user(ptr,&__v64,8); \ 239 __typeof__(*ptr) __v64 = x; \
239 break; \ 240 retval = __copy_to_user(ptr,&__v64,8); \
240 } \ 241 break; \
241 default: __put_user_bad(); \ 242 } \
242 } \ 243 default: __put_user_bad(); \
244 } \
243} while (0) 245} while (0)
244 246
245 247
@@ -267,14 +269,14 @@ do { \
267#define __check_align_1 "" 269#define __check_align_1 ""
268 270
269#define __check_align_2 \ 271#define __check_align_2 \
270 " _bbci.l %2, 0, 1f \n" \ 272 " _bbci.l %3, 0, 1f \n" \
271 " movi %0, %3 \n" \ 273 " movi %0, %4 \n" \
272 " _j 2f \n" 274 " _j 2f \n"
273 275
274#define __check_align_4 \ 276#define __check_align_4 \
275 " _bbsi.l %2, 0, 0f \n" \ 277 " _bbsi.l %3, 0, 0f \n" \
276 " _bbci.l %2, 1, 1f \n" \ 278 " _bbci.l %3, 1, 1f \n" \
277 "0: movi %0, %3 \n" \ 279 "0: movi %0, %4 \n" \
278 " _j 2f \n" 280 " _j 2f \n"
279 281
280 282
@@ -286,24 +288,24 @@ do { \
286 * WARNING: If you modify this macro at all, verify that the 288 * WARNING: If you modify this macro at all, verify that the
287 * __check_align_* macros still work. 289 * __check_align_* macros still work.
288 */ 290 */
289#define __put_user_asm(x, addr, err, align, insn) \ 291#define __put_user_asm(x, addr, err, align, insn, cb) \
290 __asm__ __volatile__( \ 292 __asm__ __volatile__( \
291 __check_align_##align \ 293 __check_align_##align \
292 "1: "insn" %1, %2, 0 \n" \ 294 "1: "insn" %2, %3, 0 \n" \
293 "2: \n" \ 295 "2: \n" \
294 " .section .fixup,\"ax\" \n" \ 296 " .section .fixup,\"ax\" \n" \
295 " .align 4 \n" \ 297 " .align 4 \n" \
296 "4: \n" \ 298 "4: \n" \
297 " .long 2b \n" \ 299 " .long 2b \n" \
298 "5: \n" \ 300 "5: \n" \
299 " l32r %2, 4b \n" \ 301 " l32r %1, 4b \n" \
300 " movi %0, %3 \n" \ 302 " movi %0, %4 \n" \
301 " jx %2 \n" \ 303 " jx %1 \n" \
302 " .previous \n" \ 304 " .previous \n" \
303 " .section __ex_table,\"a\" \n" \ 305 " .section __ex_table,\"a\" \n" \
304 " .long 1b, 5b \n" \ 306 " .long 1b, 5b \n" \
305 " .previous" \ 307 " .previous" \
306 :"=r" (err) \ 308 :"=r" (err), "=r" (cb) \
307 :"r" ((int)(x)), "r" (addr), "i" (-EFAULT), "0" (err)) 309 :"r" ((int)(x)), "r" (addr), "i" (-EFAULT), "0" (err))
308 310
309#define __get_user_nocheck(x,ptr,size) \ 311#define __get_user_nocheck(x,ptr,size) \
@@ -328,11 +330,12 @@ extern long __get_user_bad(void);
328 330
329#define __get_user_size(x,ptr,size,retval) \ 331#define __get_user_size(x,ptr,size,retval) \
330do { \ 332do { \
333 int __cb; \
331 retval = 0; \ 334 retval = 0; \
332 switch (size) { \ 335 switch (size) { \
333 case 1: __get_user_asm(x,ptr,retval,1,"l8ui"); break; \ 336 case 1: __get_user_asm(x,ptr,retval,1,"l8ui",__cb); break; \
334 case 2: __get_user_asm(x,ptr,retval,2,"l16ui"); break; \ 337 case 2: __get_user_asm(x,ptr,retval,2,"l16ui",__cb); break; \
335 case 4: __get_user_asm(x,ptr,retval,4,"l32i"); break; \ 338 case 4: __get_user_asm(x,ptr,retval,4,"l32i",__cb); break; \
336 case 8: retval = __copy_from_user(&x,ptr,8); break; \ 339 case 8: retval = __copy_from_user(&x,ptr,8); break; \
337 default: (x) = __get_user_bad(); \ 340 default: (x) = __get_user_bad(); \
338 } \ 341 } \
@@ -343,25 +346,25 @@ do { \
343 * WARNING: If you modify this macro at all, verify that the 346 * WARNING: If you modify this macro at all, verify that the
344 * __check_align_* macros still work. 347 * __check_align_* macros still work.
345 */ 348 */
346#define __get_user_asm(x, addr, err, align, insn) \ 349#define __get_user_asm(x, addr, err, align, insn, cb) \
347 __asm__ __volatile__( \ 350 __asm__ __volatile__( \
348 __check_align_##align \ 351 __check_align_##align \
349 "1: "insn" %1, %2, 0 \n" \ 352 "1: "insn" %2, %3, 0 \n" \
350 "2: \n" \ 353 "2: \n" \
351 " .section .fixup,\"ax\" \n" \ 354 " .section .fixup,\"ax\" \n" \
352 " .align 4 \n" \ 355 " .align 4 \n" \
353 "4: \n" \ 356 "4: \n" \
354 " .long 2b \n" \ 357 " .long 2b \n" \
355 "5: \n" \ 358 "5: \n" \
356 " l32r %2, 4b \n" \ 359 " l32r %1, 4b \n" \
357 " movi %1, 0 \n" \ 360 " movi %2, 0 \n" \
358 " movi %0, %3 \n" \ 361 " movi %0, %4 \n" \
359 " jx %2 \n" \ 362 " jx %1 \n" \
360 " .previous \n" \ 363 " .previous \n" \
361 " .section __ex_table,\"a\" \n" \ 364 " .section __ex_table,\"a\" \n" \
362 " .long 1b, 5b \n" \ 365 " .long 1b, 5b \n" \
363 " .previous" \ 366 " .previous" \
364 :"=r" (err), "=r" (x) \ 367 :"=r" (err), "=r" (cb), "=r" (x) \
365 :"r" (addr), "i" (-EFAULT), "0" (err)) 368 :"r" (addr), "i" (-EFAULT), "0" (err))
366 369
367 370
diff --git a/include/asm-xtensa/variant-fsf/tie-asm.h b/include/asm-xtensa/variant-fsf/tie-asm.h
new file mode 100644
index 000000000000..68a73bf4ffc5
--- /dev/null
+++ b/include/asm-xtensa/variant-fsf/tie-asm.h
@@ -0,0 +1,70 @@
1/*
2 * This header file contains assembly-language definitions (assembly
3 * macros, etc.) for this specific Xtensa processor's TIE extensions
4 * and options. It is customized to this Xtensa processor configuration.
5 *
6 * This file is subject to the terms and conditions of the GNU General Public
7 * License. See the file "COPYING" in the main directory of this archive
8 * for more details.
9 *
10 * Copyright (C) 1999-2008 Tensilica Inc.
11 */
12
13#ifndef _XTENSA_CORE_TIE_ASM_H
14#define _XTENSA_CORE_TIE_ASM_H
15
16/* Selection parameter values for save-area save/restore macros: */
17/* Option vs. TIE: */
18#define XTHAL_SAS_TIE 0x0001 /* custom extension or coprocessor */
19#define XTHAL_SAS_OPT 0x0002 /* optional (and not a coprocessor) */
20/* Whether used automatically by compiler: */
21#define XTHAL_SAS_NOCC 0x0004 /* not used by compiler w/o special opts/code */
22#define XTHAL_SAS_CC 0x0008 /* used by compiler without special opts/code */
23/* ABI handling across function calls: */
24#define XTHAL_SAS_CALR 0x0010 /* caller-saved */
25#define XTHAL_SAS_CALE 0x0020 /* callee-saved */
26#define XTHAL_SAS_GLOB 0x0040 /* global across function calls (in thread) */
27/* Misc */
28#define XTHAL_SAS_ALL 0xFFFF /* include all default NCP contents */
29
30
31
32/* Macro to save all non-coprocessor (extra) custom TIE and optional state
33 * (not including zero-overhead loop registers).
34 * Save area ptr (clobbered): ptr (1 byte aligned)
35 * Scratch regs (clobbered): at1..at4 (only first XCHAL_NCP_NUM_ATMPS needed)
36 */
37 .macro xchal_ncp_store ptr at1 at2 at3 at4 continue=0 ofs=-1 select=XTHAL_SAS_ALL
38 xchal_sa_start \continue, \ofs
39 .ifeq (XTHAL_SAS_OPT | XTHAL_SAS_CC | XTHAL_SAS_GLOB) & ~\select
40 xchal_sa_align \ptr, 0, 1024-4, 4, 4
41 rur \at1, THREADPTR // threadptr option
42 s32i \at1, \ptr, .Lxchal_ofs_ + 0
43 .set .Lxchal_ofs_, .Lxchal_ofs_ + 4
44 .endif
45 .endm // xchal_ncp_store
46
47/* Macro to save all non-coprocessor (extra) custom TIE and optional state
48 * (not including zero-overhead loop registers).
49 * Save area ptr (clobbered): ptr (1 byte aligned)
50 * Scratch regs (clobbered): at1..at4 (only first XCHAL_NCP_NUM_ATMPS needed)
51 */
52 .macro xchal_ncp_load ptr at1 at2 at3 at4 continue=0 ofs=-1 select=XTHAL_SAS_ALL
53 xchal_sa_start \continue, \ofs
54 .ifeq (XTHAL_SAS_OPT | XTHAL_SAS_CC | XTHAL_SAS_GLOB) & ~\select
55 xchal_sa_align \ptr, 0, 1024-4, 4, 4
56 l32i \at1, \ptr, .Lxchal_ofs_ + 0
57 wur \at1, THREADPTR // threadptr option
58 .set .Lxchal_ofs_, .Lxchal_ofs_ + 4
59 .endif
60 .endm // xchal_ncp_load
61
62
63
64#define XCHAL_NCP_NUM_ATMPS 1
65
66
67#define XCHAL_SA_NUM_ATMPS 1
68
69#endif /*_XTENSA_CORE_TIE_ASM_H*/
70
diff --git a/include/asm-xtensa/variant-fsf/tie.h b/include/asm-xtensa/variant-fsf/tie.h
index a73c71664918..bf4020116df5 100644
--- a/include/asm-xtensa/variant-fsf/tie.h
+++ b/include/asm-xtensa/variant-fsf/tie.h
@@ -1,22 +1,77 @@
1/* 1/*
2 * Xtensa processor core configuration information. 2 * This header file describes this specific Xtensa processor's TIE extensions
3 * that extend basic Xtensa core functionality. It is customized to this
4 * Xtensa processor configuration.
3 * 5 *
4 * This file is subject to the terms and conditions of the GNU General Public 6 * This file is subject to the terms and conditions of the GNU General Public
5 * License. See the file "COPYING" in the main directory of this archive 7 * License. See the file "COPYING" in the main directory of this archive
6 * for more details. 8 * for more details.
7 * 9 *
8 * Copyright (C) 1999-2006 Tensilica Inc. 10 * Copyright (C) 1999-2007 Tensilica Inc.
9 */ 11 */
10 12
11#ifndef XTENSA_TIE_H 13#ifndef _XTENSA_CORE_TIE_H
12#define XTENSA_TIE_H 14#define _XTENSA_CORE_TIE_H
13
14/*----------------------------------------------------------------------
15 COPROCESSORS and EXTRA STATE
16 ----------------------------------------------------------------------*/
17 15
18#define XCHAL_CP_NUM 0 /* number of coprocessors */ 16#define XCHAL_CP_NUM 0 /* number of coprocessors */
19#define XCHAL_CP_MASK 0x00 17#define XCHAL_CP_MAX 0 /* max CP ID + 1 (0 if none) */
18#define XCHAL_CP_MASK 0x00 /* bitmask of all CPs by ID */
19#define XCHAL_CP_PORT_MASK 0x00 /* bitmask of only port CPs */
20
21/* Basic parameters of each coprocessor: */
22#define XCHAL_CP7_NAME "XTIOP"
23#define XCHAL_CP7_IDENT XTIOP
24#define XCHAL_CP7_SA_SIZE 0 /* size of state save area */
25#define XCHAL_CP7_SA_ALIGN 1 /* min alignment of save area */
26#define XCHAL_CP_ID_XTIOP 7 /* coprocessor ID (0..7) */
27
28/* Filler info for unassigned coprocessors, to simplify arrays etc: */
29#define XCHAL_NCP_SA_SIZE 0
30#define XCHAL_NCP_SA_ALIGN 1
31#define XCHAL_CP0_SA_SIZE 0
32#define XCHAL_CP0_SA_ALIGN 1
33#define XCHAL_CP1_SA_SIZE 0
34#define XCHAL_CP1_SA_ALIGN 1
35#define XCHAL_CP2_SA_SIZE 0
36#define XCHAL_CP2_SA_ALIGN 1
37#define XCHAL_CP3_SA_SIZE 0
38#define XCHAL_CP3_SA_ALIGN 1
39#define XCHAL_CP4_SA_SIZE 0
40#define XCHAL_CP4_SA_ALIGN 1
41#define XCHAL_CP5_SA_SIZE 0
42#define XCHAL_CP5_SA_ALIGN 1
43#define XCHAL_CP6_SA_SIZE 0
44#define XCHAL_CP6_SA_ALIGN 1
45
46/* Save area for non-coprocessor optional and custom (TIE) state: */
47#define XCHAL_NCP_SA_SIZE 0
48#define XCHAL_NCP_SA_ALIGN 1
49
50/* Total save area for optional and custom state (NCP + CPn): */
51#define XCHAL_TOTAL_SA_SIZE 0 /* with 16-byte align padding */
52#define XCHAL_TOTAL_SA_ALIGN 1 /* actual minimum alignment */
53
54#define XCHAL_NCP_SA_NUM 0
55#define XCHAL_NCP_SA_LIST(s)
56#define XCHAL_CP0_SA_NUM 0
57#define XCHAL_CP0_SA_LIST(s)
58#define XCHAL_CP1_SA_NUM 0
59#define XCHAL_CP1_SA_LIST(s)
60#define XCHAL_CP2_SA_NUM 0
61#define XCHAL_CP2_SA_LIST(s)
62#define XCHAL_CP3_SA_NUM 0
63#define XCHAL_CP3_SA_LIST(s)
64#define XCHAL_CP4_SA_NUM 0
65#define XCHAL_CP4_SA_LIST(s)
66#define XCHAL_CP5_SA_NUM 0
67#define XCHAL_CP5_SA_LIST(s)
68#define XCHAL_CP6_SA_NUM 0
69#define XCHAL_CP6_SA_LIST(s)
70#define XCHAL_CP7_SA_NUM 0
71#define XCHAL_CP7_SA_LIST(s)
72
73/* Byte length of instruction from its first nibble (op0 field), per FLIX. */
74#define XCHAL_OP0_FORMAT_LENGTHS 3,3,3,3,3,3,3,3,2,2,2,2,2,2,3,3
20 75
21#endif /*XTENSA_CONFIG_TIE_H*/ 76#endif /*_XTENSA_CORE_TIE_H*/
22 77