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