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