Lines Matching +full:rx +full:- +full:sched +full:- +full:sp

1 // SPDX-License-Identifier: GPL-2.0-only
6 * Modifications for ARM processor (c) 1995-2001 Russell King
8 * - Adapted from gdb/sim/arm/thumbemu.c -- Thumb instruction emulation.
14 #include <linux/sched/debug.h>
20 #include <linux/sched/signal.h>
32 * 32-bit misaligned trap handler (c) 1998 San Mehat (CCC) -July 1998
52 #define LDSTHD_I_BIT(i) (i & (1 << 22)) /* double/half-word immed */
72 /* Thumb-2 32 bit format per ARMv7 DDI0406A A6.3, either f800h,e800h,f800h */
107 * CPUs since we spin re-faulting the instruction without in safe_usermode()
158 return -EFAULT; in alignment_proc_write()
160 ai_usermode = safe_usermode(mode - '0', true); in alignment_proc_write()
330 offset.un = -offset.un; in do_alignment_finish_ldst()
336 regs->uregs[RN_BITS(instr)] = addr; in do_alignment_finish_ldst()
353 /* signed half-word? */ in do_alignment_ldrhstrh()
357 regs->uregs[rd] = val; in do_alignment_ldrhstrh()
359 put16_unaligned_check(regs->uregs[rd], addr); in do_alignment_ldrhstrh()
371 /* signed half-word? */ in do_alignment_ldrhstrh()
375 regs->uregs[rd] = val; in do_alignment_ldrhstrh()
378 put16t_unaligned_check(regs->uregs[rd], addr); in do_alignment_ldrhstrh()
396 /* ARMv7 Thumb-2 32-bit LDRD/STRD */ in do_alignment_ldrdstrd()
414 regs->uregs[rd] = val; in do_alignment_ldrdstrd()
416 regs->uregs[rd2] = val; in do_alignment_ldrdstrd()
418 put32_unaligned_check(regs->uregs[rd], addr); in do_alignment_ldrdstrd()
419 put32_unaligned_check(regs->uregs[rd2], addr + 4); in do_alignment_ldrdstrd()
434 regs->uregs[rd] = val; in do_alignment_ldrdstrd()
435 regs->uregs[rd2] = val2; in do_alignment_ldrdstrd()
438 put32t_unaligned_check(regs->uregs[rd], addr); in do_alignment_ldrdstrd()
439 put32t_unaligned_check(regs->uregs[rd2], addr + 4); in do_alignment_ldrdstrd()
463 regs->uregs[rd] = val; in do_alignment_ldrstr()
465 put32_unaligned_check(regs->uregs[rd], addr); in do_alignment_ldrstr()
474 regs->uregs[rd] = val; in do_alignment_ldrstr()
477 put32t_unaligned_check(regs->uregs[rd], addr); in do_alignment_ldrstr()
492 * ------ increasing address ----->
493 * | | r0 | r1 | ... | rx | |
509 regs->ARM_pc += correction; in do_alignment_ldmstm()
517 newaddr = eaddr = regs->uregs[rn]; in do_alignment_ldmstm()
520 nr_regs = -nr_regs; in do_alignment_ldmstm()
537 * This is a "hint" - we already have eaddr worked out by the in do_alignment_ldmstm()
556 regs->uregs[rd] = val; in do_alignment_ldmstm()
558 put32t_unaligned_check(regs->uregs[rd], eaddr); in do_alignment_ldmstm()
569 regs->uregs[rd] = val; in do_alignment_ldmstm()
571 put32_unaligned_check(regs->uregs[rd], eaddr); in do_alignment_ldmstm()
577 regs->uregs[rn] = newaddr; in do_alignment_ldmstm()
579 regs->ARM_pc -= correction; in do_alignment_ldmstm()
583 regs->ARM_pc -= correction; in do_alignment_ldmstm()
587 pr_err("Alignment trap: not handling ldm with s-bit set\n"); in do_alignment_ldmstm()
601 * 2. If for some reason we're passed an non-ld/st Thumb instruction to
619 ((tinstr & (1<<12)) << (22-12)) | /* fixup */ in thumb2arm()
621 ((tinstr & (7<<0)) << (12-0)) | /* Rd */ in thumb2arm()
622 ((tinstr & (7<<3)) << (16-3)) | /* Rn */ in thumb2arm()
624 (6 - ((tinstr & (1<<12)) ? 0 : 2))); in thumb2arm()
629 ((tinstr & (7<<0)) << (12-0)) | /* Rd */ in thumb2arm()
630 ((tinstr & (7<<3)) << (16-3)) | /* Rn */ in thumb2arm()
631 ((tinstr & (7<<6)) >> (6-1)) | /* immed_5[2:0] */ in thumb2arm()
632 ((tinstr & (3<<9)) >> (9-8)); /* immed_5[4:3] */ in thumb2arm()
649 ((tinstr & (7<<0)) << (12-0)) | /* Rd */ in thumb2arm()
650 ((tinstr & (7<<3)) << (16-3)) | /* Rn */ in thumb2arm()
651 ((tinstr & (7<<6)) >> (6-0)); /* Rm */ in thumb2arm()
657 * loading 32-bit memory data via PC relative in thumb2arm()
662 ((tinstr & (7<<8)) << (12-8)) | /* Rd */ in thumb2arm()
663 ((tinstr & 255) << (2-0)); /* immed_8 */ in thumb2arm()
670 ((tinstr & (7<<8)) << (12-8)) | /* Rd */ in thumb2arm()
689 0xe92d0000, /* STMDB sp!,{registers} */ in thumb2arm()
690 0xe92d4000, /* STMDB sp!,{registers,lr} */ in thumb2arm()
691 0xe8bd0000, /* LDMIA sp!,{registers} */ in thumb2arm()
692 0xe8bd8000 /* LDMIA sp!,{registers,pc} */ in thumb2arm()
705 * Convert Thumb-2 32 bit LDM, STM, LDRD, STRD to equivalent instruction
709 * @pinstr: original Thumb-2 instruction; returns new handlable instruction
738 0xe92d0000, /* STMDB sp!,{registers} */ in do_alignment_t32_to_handler()
739 0xe8bd0000, /* LDMIA sp!,{registers} */ in do_alignment_t32_to_handler()
752 poffset->un = (tinst2 & 0xff) << 2; in do_alignment_t32_to_handler()
824 /* Thumb-2 32-bit */ in do_alignment()
851 regs->ARM_pc += isize; in do_alignment()
858 offset.un = regs->uregs[RM_BITS(instr)]; in do_alignment()
880 offset.un = regs->uregs[RM_BITS(instr)]; in do_alignment()
901 if (regs->ARM_cpsr & PSR_C_BIT) in do_alignment()
905 offset.un << (32 - shiftval); in do_alignment()
912 case 0x08000000: /* ldm or stm, or thumb-2 32bit instruction */ in do_alignment()
931 regs->ARM_pc -= isize; in do_alignment()
939 regs->ARM_cpsr = it_advance(regs->ARM_cpsr); in do_alignment()
947 * We got a fault - fix it up, or die. in do_alignment()
971 "Address=0x%08lx FSR 0x%03x\n", current->comm, in do_alignment()
988 * the alignment trap won't be re-enabled in that case as it in do_alignment()
992 * entry-common.S) and disable the alignment trap only if in do_alignment()
1024 return -ENOMEM; in alignment_init()