xref: /linux/arch/xtensa/kernel/coprocessor.S (revision 87c2ce3b9305b9b723faeedf6e32ef703ec9b33a)
1/*
2 * arch/xtensa/kernel/coprocessor.S
3 *
4 * Xtensa processor configuration-specific table of coprocessor and
5 * other custom register layout information.
6 *
7 * This file is subject to the terms and conditions of the GNU General Public
8 * License.  See the file "COPYING" in the main directory of this archive
9 * for more details.
10 *
11 * Copyright (C) 2003 - 2005 Tensilica Inc.
12 *
13 * Marc Gauthier <marc@tensilica.com> <marc@alumni.uwaterloo.ca>
14 */
15
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
27#include <linux/config.h>
28#include <linux/linkage.h>
29#include <asm/processor.h>
30
31#if XCHAL_HAVE_CP
32
33#define CP_LAST ((XCHAL_CP_MAX - 1) * COPROCESSOR_INFO_SIZE)
34
35ENTRY(release_coprocessors)
36
37	entry	a1, 16
38						# a2: task
39	movi	a3, 1 << XCHAL_CP_MAX 		# a3: coprocessor-bit
40	movi	a4, coprocessor_info+CP_LAST	# a4: owner-table
41						# a5: tmp
42	movi	a6, 0				# a6: 0
43	rsil	a7, LOCKLEVEL			# a7: PS
44
451:	/* Check if task is coprocessor owner of coprocessor[i]. */
46
47	l32i	a5, a4, COPROCESSOR_INFO_OWNER
48	srli	a3, a3, 1
49	beqz	a3, 1f
50	addi	a4, a4, -8
51	beq	a2, a5, 1b
52
53	/* Found an entry: Clear entry CPENABLE bit to disable CP. */
54
55	rsr	a5, CPENABLE
56	s32i	a6, a4, COPROCESSOR_INFO_OWNER
57	xor	a5, a3, a5
58	wsr	a5, CPENABLE
59
60	bnez	a3, 1b
61
621:	wsr	a7, PS
63	rsync
64	retw
65
66
67ENTRY(disable_coprocessor)
68	entry	sp, 16
69	rsil	a7, LOCKLEVEL
70	rsr	a3, CPENABLE
71	movi	a4, 1
72	ssl	a2
73	sll	a4, a4
74	and	a4, a3, a4
75	xor	a3, a3, a4
76	wsr	a3, CPENABLE
77	wsr	a7, PS
78	rsync
79	retw
80
81ENTRY(enable_coprocessor)
82	entry	sp, 16
83	rsil	a7, LOCKLEVEL
84	rsr	a3, CPENABLE
85	movi	a4, 1
86	ssl	a2
87	sll	a4, a4
88	or	a3, a3, a4
89	wsr	a3, CPENABLE
90	wsr	a7, PS
91	rsync
92	retw
93
94#endif
95
96ENTRY(save_coprocessor_extra)
97	entry	sp, 16
98	xchal_extra_store_funcbody
99	retw
100
101ENTRY(restore_coprocessor_extra)
102	entry	sp, 16
103	xchal_extra_load_funcbody
104	retw
105
106ENTRY(save_coprocessor_registers)
107	entry	sp, 16
108	xchal_cpi_store_funcbody
109	retw
110
111ENTRY(restore_coprocessor_registers)
112	entry	sp, 16
113	xchal_cpi_load_funcbody
114	retw
115
116
117/*
118 *  The Xtensa compile-time HAL (core.h) XCHAL_*_SA_CONTENTS_LIBDB macros
119 *  describe the contents of coprocessor & extra save areas in terms of
120 *  undefined CONTENTS_LIBDB_{SREG,UREG,REGF} macros.  We define these
121 *  latter macros here; they expand into a table of the format we want.
122 *  The general format is:
123 *
124 *	CONTENTS_LIBDB_SREG(libdbnum, offset, size, align, rsv1, name, sregnum,
125 *			    bitmask, rsv2, rsv3)
126 *	CONTENTS_LIBDB_UREG(libdbnum, offset, size, align, rsv1, name, uregnum,
127 *			    bitmask, rsv2, rsv3)
128 *	CONTENTS_LIBDB_REGF(libdbnum, offset, size, align, rsv1, name, index,
129 *			    numentries, contentsize, regname_base,
130 *			    regfile_name, rsv2, rsv3)
131 *
132 *  For this table, we only care about the <libdbnum>, <offset> and <size>
133 *  fields.
134 */
135
136/*  Map all XCHAL CONTENTS macros to the reg_entry asm macro defined below:  */
137
138#define CONTENTS_LIBDB_SREG(libdbnum,offset,size,align,rsv1,name,sregnum,     \
139			    bitmask, rsv2, rsv3)			      \
140		reg_entry libdbnum, offset, size ;
141#define CONTENTS_LIBDB_UREG(libdbnum,offset,size,align,rsv1,name,uregnum,     \
142			    bitmask, rsv2, rsv3)			      \
143		reg_entry libdbnum, offset, size ;
144#define CONTENTS_LIBDB_REGF(libdbnum, offset, size, align, rsv1, name, index, \
145			    numentries, contentsize, regname_base,	      \
146			    regfile_name, rsv2, rsv3)			      \
147		reg_entry libdbnum, offset, size ;
148
149/* A single table entry: */
150	.macro	reg_entry	libdbnum, offset, size
151	 .ifne	(__last_offset-(__last_group_offset+\offset))
152	  /* padding entry */
153	  .word	(0xFC000000+__last_offset-(__last_group_offset+\offset))
154	 .endif
155	 .word	\libdbnum				/* actual entry */
156	 .set	__last_offset, __last_group_offset+\offset+\size
157	.endm	/* reg_entry */
158
159
160/* Table entry that marks the beginning of a group (coprocessor or "extra"): */
161	.macro	reg_group	cpnum, num_entries, align
162	 .set	__last_group_offset, (__last_offset + \align- 1) & -\align
163	 .ifne	\num_entries
164	  .word	0xFD000000+(\cpnum<<16)+\num_entries
165	 .endif
166	.endm	/* reg_group */
167
168/*
169 * Register info tables.
170 */
171
172	.section .rodata, "a"
173	.globl	_xtensa_reginfo_tables
174	.globl	_xtensa_reginfo_table_size
175	.align	4
176_xtensa_reginfo_table_size:
177	.word	_xtensa_reginfo_table_end - _xtensa_reginfo_tables
178
179_xtensa_reginfo_tables:
180	.set	__last_offset, 0
181	reg_group 0xFF, XCHAL_EXTRA_SA_CONTENTS_LIBDB_NUM, XCHAL_EXTRA_SA_ALIGN
182	XCHAL_EXTRA_SA_CONTENTS_LIBDB
183	reg_group 0, XCHAL_CP0_SA_CONTENTS_LIBDB_NUM, XCHAL_CP0_SA_ALIGN
184	XCHAL_CP0_SA_CONTENTS_LIBDB
185	reg_group 1, XCHAL_CP1_SA_CONTENTS_LIBDB_NUM, XCHAL_CP1_SA_ALIGN
186	XCHAL_CP1_SA_CONTENTS_LIBDB
187	reg_group 2, XCHAL_CP2_SA_CONTENTS_LIBDB_NUM, XCHAL_CP2_SA_ALIGN
188	XCHAL_CP2_SA_CONTENTS_LIBDB
189	reg_group 3, XCHAL_CP3_SA_CONTENTS_LIBDB_NUM, XCHAL_CP3_SA_ALIGN
190	XCHAL_CP3_SA_CONTENTS_LIBDB
191	reg_group 4, XCHAL_CP4_SA_CONTENTS_LIBDB_NUM, XCHAL_CP4_SA_ALIGN
192	XCHAL_CP4_SA_CONTENTS_LIBDB
193	reg_group 5, XCHAL_CP5_SA_CONTENTS_LIBDB_NUM, XCHAL_CP5_SA_ALIGN
194	XCHAL_CP5_SA_CONTENTS_LIBDB
195	reg_group 6, XCHAL_CP6_SA_CONTENTS_LIBDB_NUM, XCHAL_CP6_SA_ALIGN
196	XCHAL_CP6_SA_CONTENTS_LIBDB
197	reg_group 7, XCHAL_CP7_SA_CONTENTS_LIBDB_NUM, XCHAL_CP7_SA_ALIGN
198	XCHAL_CP7_SA_CONTENTS_LIBDB
199	.word	0xFC000000	/* invalid register number,marks end of table*/
200_xtensa_reginfo_table_end:
201
202