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