1*b2441318SGreg Kroah-Hartman /* SPDX-License-Identifier: GPL-2.0 */ 2b5478c1bSAl Viro #ifndef _ASM_EXTABLE_H 3b5478c1bSAl Viro #define _ASM_EXTABLE_H 4b5478c1bSAl Viro 5b5478c1bSAl Viro /* 6b5478c1bSAl Viro * About the exception table: 7b5478c1bSAl Viro * 8b5478c1bSAl Viro * - insn is a 32-bit pc-relative offset from the faulting insn. 9b5478c1bSAl Viro * - nextinsn is a 16-bit offset off of the faulting instruction 10b5478c1bSAl Viro * (not off of the *next* instruction as branches are). 11b5478c1bSAl Viro * - errreg is the register in which to place -EFAULT. 12b5478c1bSAl Viro * - valreg is the final target register for the load sequence 13b5478c1bSAl Viro * and will be zeroed. 14b5478c1bSAl Viro * 15b5478c1bSAl Viro * Either errreg or valreg may be $31, in which case nothing happens. 16b5478c1bSAl Viro * 17b5478c1bSAl Viro * The exception fixup information "just so happens" to be arranged 18b5478c1bSAl Viro * as in a MEM format instruction. This lets us emit our three 19b5478c1bSAl Viro * values like so: 20b5478c1bSAl Viro * 21b5478c1bSAl Viro * lda valreg, nextinsn(errreg) 22b5478c1bSAl Viro * 23b5478c1bSAl Viro */ 24b5478c1bSAl Viro 25b5478c1bSAl Viro struct exception_table_entry 26b5478c1bSAl Viro { 27b5478c1bSAl Viro signed int insn; 28b5478c1bSAl Viro union exception_fixup { 29b5478c1bSAl Viro unsigned unit; 30b5478c1bSAl Viro struct { 31b5478c1bSAl Viro signed int nextinsn : 16; 32b5478c1bSAl Viro unsigned int errreg : 5; 33b5478c1bSAl Viro unsigned int valreg : 5; 34b5478c1bSAl Viro } bits; 35b5478c1bSAl Viro } fixup; 36b5478c1bSAl Viro }; 37b5478c1bSAl Viro 38b5478c1bSAl Viro /* Returns the new pc */ 39b5478c1bSAl Viro #define fixup_exception(map_reg, _fixup, pc) \ 40b5478c1bSAl Viro ({ \ 41b5478c1bSAl Viro if ((_fixup)->fixup.bits.valreg != 31) \ 42b5478c1bSAl Viro map_reg((_fixup)->fixup.bits.valreg) = 0; \ 43b5478c1bSAl Viro if ((_fixup)->fixup.bits.errreg != 31) \ 44b5478c1bSAl Viro map_reg((_fixup)->fixup.bits.errreg) = -EFAULT; \ 45b5478c1bSAl Viro (pc) + (_fixup)->fixup.bits.nextinsn; \ 46b5478c1bSAl Viro }) 47b5478c1bSAl Viro 48b5478c1bSAl Viro #define ARCH_HAS_RELATIVE_EXTABLE 49b5478c1bSAl Viro 50b5478c1bSAl Viro #define swap_ex_entry_fixup(a, b, tmp, delta) \ 51b5478c1bSAl Viro do { \ 52b5478c1bSAl Viro (a)->fixup.unit = (b)->fixup.unit; \ 53b5478c1bSAl Viro (b)->fixup.unit = (tmp).fixup.unit; \ 54b5478c1bSAl Viro } while (0) 55b5478c1bSAl Viro 56b5478c1bSAl Viro #endif 57