Merge branch 'for-linus' of master.kernel.org:/pub/scm/linux/kernel/git/roland/infiniband
[linux-2.6] / 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
94 ENTRY(save_coprocessor_extra)
95         entry   sp, 16
96         xchal_extra_store_funcbody
97         retw
98
99 ENTRY(restore_coprocessor_extra)
100         entry   sp, 16
101         xchal_extra_load_funcbody
102         retw
103
104 ENTRY(save_coprocessor_registers)
105         entry   sp, 16
106         xchal_cpi_store_funcbody
107         retw
108
109 ENTRY(restore_coprocessor_registers)
110         entry   sp, 16
111         xchal_cpi_load_funcbody
112         retw
113
114
115 /*
116  *  The Xtensa compile-time HAL (core.h) XCHAL_*_SA_CONTENTS_LIBDB macros
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  *
122  *      CONTENTS_LIBDB_SREG(libdbnum, offset, size, align, rsv1, name, sregnum,
123  *                          bitmask, rsv2, rsv3)
124  *      CONTENTS_LIBDB_UREG(libdbnum, offset, size, align, rsv1, name, uregnum,
125  *                          bitmask, rsv2, rsv3)
126  *      CONTENTS_LIBDB_REGF(libdbnum, offset, size, align, rsv1, name, index,
127  *                          numentries, contentsize, regname_base,
128  *                          regfile_name, rsv2, rsv3)
129  *
130  *  For this table, we only care about the <libdbnum>, <offset> and <size>
131  *  fields.
132  */
133
134 /*  Map all XCHAL CONTENTS macros to the reg_entry asm macro defined below:  */
135
136 #define CONTENTS_LIBDB_SREG(libdbnum,offset,size,align,rsv1,name,sregnum,     \
137                             bitmask, rsv2, rsv3)                              \
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
166 /*
167  * Register info tables.
168  */
169
170         .section .rodata, "a"
171         .globl  _xtensa_reginfo_tables
172         .globl  _xtensa_reginfo_table_size
173         .align  4
174 _xtensa_reginfo_table_size:
175         .word   _xtensa_reginfo_table_end - _xtensa_reginfo_tables
176
177 _xtensa_reginfo_tables:
178         .set    __last_offset, 0
179         reg_group 0xFF, XCHAL_EXTRA_SA_CONTENTS_LIBDB_NUM, XCHAL_EXTRA_SA_ALIGN
180         XCHAL_EXTRA_SA_CONTENTS_LIBDB
181         reg_group 0, XCHAL_CP0_SA_CONTENTS_LIBDB_NUM, XCHAL_CP0_SA_ALIGN
182         XCHAL_CP0_SA_CONTENTS_LIBDB
183         reg_group 1, XCHAL_CP1_SA_CONTENTS_LIBDB_NUM, XCHAL_CP1_SA_ALIGN
184         XCHAL_CP1_SA_CONTENTS_LIBDB
185         reg_group 2, XCHAL_CP2_SA_CONTENTS_LIBDB_NUM, XCHAL_CP2_SA_ALIGN
186         XCHAL_CP2_SA_CONTENTS_LIBDB
187         reg_group 3, XCHAL_CP3_SA_CONTENTS_LIBDB_NUM, XCHAL_CP3_SA_ALIGN
188         XCHAL_CP3_SA_CONTENTS_LIBDB
189         reg_group 4, XCHAL_CP4_SA_CONTENTS_LIBDB_NUM, XCHAL_CP4_SA_ALIGN
190         XCHAL_CP4_SA_CONTENTS_LIBDB
191         reg_group 5, XCHAL_CP5_SA_CONTENTS_LIBDB_NUM, XCHAL_CP5_SA_ALIGN
192         XCHAL_CP5_SA_CONTENTS_LIBDB
193         reg_group 6, XCHAL_CP6_SA_CONTENTS_LIBDB_NUM, XCHAL_CP6_SA_ALIGN
194         XCHAL_CP6_SA_CONTENTS_LIBDB
195         reg_group 7, XCHAL_CP7_SA_CONTENTS_LIBDB_NUM, XCHAL_CP7_SA_ALIGN
196         XCHAL_CP7_SA_CONTENTS_LIBDB
197         .word   0xFC000000      /* invalid register number,marks end of table*/
198 _xtensa_reginfo_table_end:
199 #endif
200