[PATCH] xtensa: Architecture support for Tensilica Xtensa Part 3
[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/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
35 ENTRY(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
45 1:      /* 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
62 1:      wsr     a7, PS
63         rsync
64         retw
65
66
67 ENTRY(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
81 ENTRY(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
96 ENTRY(save_coprocessor_extra)
97         entry   sp, 16
98         xchal_extra_store_funcbody
99         retw
100
101 ENTRY(restore_coprocessor_extra)
102         entry   sp, 16
103         xchal_extra_load_funcbody
104         retw
105
106 ENTRY(save_coprocessor_registers)
107         entry   sp, 16
108         xchal_cpi_store_funcbody
109         retw
110
111 ENTRY(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