Linux 2.6.13-rc4
[linux-2.6/next.git] / arch / xtensa / kernel / coprocessor.S
blob356192a4d39d07c42966188a73c299cbb32e7ebc
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  */
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  */
27 #include <linux/config.h>
28 #include <linux/linkage.h>
29 #include <asm/processor.h>
31 #if XCHAL_HAVE_CP
33 #define CP_LAST ((XCHAL_CP_MAX - 1) * COPROCESSOR_INFO_SIZE)
35 ENTRY(release_coprocessors)
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
45 1:      /* Check if task is coprocessor owner of coprocessor[i]. */
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
53         /* Found an entry: Clear entry CPENABLE bit to disable CP. */
55         rsr     a5, CPENABLE
56         s32i    a6, a4, COPROCESSOR_INFO_OWNER
57         xor     a5, a3, a5
58         wsr     a5, CPENABLE
60         bnez    a3, 1b
62 1:      wsr     a7, PS
63         rsync
64         retw
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
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
94 #endif
96 ENTRY(save_coprocessor_extra)
97         entry   sp, 16
98         xchal_extra_store_funcbody
99         retw
101 ENTRY(restore_coprocessor_extra)
102         entry   sp, 16
103         xchal_extra_load_funcbody
104         retw
106 ENTRY(save_coprocessor_registers)
107         entry   sp, 16
108         xchal_cpi_store_funcbody
109         retw
111 ENTRY(restore_coprocessor_registers)
112         entry   sp, 16
113         xchal_cpi_load_funcbody
114         retw
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:
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)
132  *  For this table, we only care about the <libdbnum>, <offset> and <size>
133  *  fields.
134  */
136 /*  Map all XCHAL CONTENTS macros to the reg_entry asm macro defined below:  */
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 ;
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 */
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 */
169  * Register info tables.
170  */
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
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: