1*4882a593Smuzhiyun/* SPDX-License-Identifier: GPL-2.0 */ 2*4882a593Smuzhiyun/* 3*4882a593Smuzhiyun * The ARM LDRD and Thumb LDRSB instructions use bit 20/11 (ARM/Thumb) 4*4882a593Smuzhiyun * differently than every other instruction, so it is set to 0 (write) 5*4882a593Smuzhiyun * even though the instructions are read instructions. This means that 6*4882a593Smuzhiyun * during an abort the instructions will be treated as a write and the 7*4882a593Smuzhiyun * handler will raise a signal from unwriteable locations if they 8*4882a593Smuzhiyun * fault. We have to specifically check for these instructions 9*4882a593Smuzhiyun * from the abort handlers to treat them properly. 10*4882a593Smuzhiyun * 11*4882a593Smuzhiyun */ 12*4882a593Smuzhiyun 13*4882a593Smuzhiyun .macro do_thumb_abort, fsr, pc, psr, tmp 14*4882a593Smuzhiyun tst \psr, #PSR_T_BIT 15*4882a593Smuzhiyun beq not_thumb 16*4882a593Smuzhiyun ldrh \tmp, [\pc] @ Read aborted Thumb instruction 17*4882a593Smuzhiyun uaccess_disable ip @ disable userspace access 18*4882a593Smuzhiyun and \tmp, \tmp, # 0xfe00 @ Mask opcode field 19*4882a593Smuzhiyun cmp \tmp, # 0x5600 @ Is it ldrsb? 20*4882a593Smuzhiyun orreq \tmp, \tmp, #1 << 11 @ Set L-bit if yes 21*4882a593Smuzhiyun tst \tmp, #1 << 11 @ L = 0 -> write 22*4882a593Smuzhiyun orreq \fsr, \fsr, #1 << 11 @ yes. 23*4882a593Smuzhiyun b do_DataAbort 24*4882a593Smuzhiyunnot_thumb: 25*4882a593Smuzhiyun .endm 26*4882a593Smuzhiyun 27*4882a593Smuzhiyun/* 28*4882a593Smuzhiyun * We check for the following instruction encoding for LDRD. 29*4882a593Smuzhiyun * 30*4882a593Smuzhiyun * [27:25] == 000 31*4882a593Smuzhiyun * [7:4] == 1101 32*4882a593Smuzhiyun * [20] == 0 33*4882a593Smuzhiyun */ 34*4882a593Smuzhiyun .macro teq_ldrd, tmp, insn 35*4882a593Smuzhiyun mov \tmp, #0x0e100000 36*4882a593Smuzhiyun orr \tmp, #0x000000f0 37*4882a593Smuzhiyun and \tmp, \insn, \tmp 38*4882a593Smuzhiyun teq \tmp, #0x000000d0 39*4882a593Smuzhiyun .endm 40