1/* 2 * Test ARMv6-M UNDEFINED 32-bit instructions 3 * 4 * Copyright 2018 Red Hat Inc. 5 * 6 * This work is licensed under the terms of the GNU GPL, version 2 7 * or later. See the COPYING file in the top-level directory. 8 */ 9 10/* 11 * Test that UNDEFINED 32-bit instructions fault as expected. This is an 12 * interesting test because ARMv6-M shares code with its more fully-featured 13 * siblings and it's necessary to verify that its limited instruction set is 14 * emulated correctly. 15 * 16 * The emulator must be invoked with -semihosting so that the test case can 17 * terminate with exit code 0 on success or 1 on failure. 18 * 19 * Failures can be debugged with -d in_asm,int,exec,cpu and the 20 * gdbstub (-S -s). 21 */ 22 23.syntax unified 24.cpu cortex-m0 25.thumb 26 27/* 28 * Memory map 29 */ 30#define SRAM_BASE 0x20000000 31#define SRAM_SIZE (16 * 1024) 32 33/* 34 * Semihosting interface on ARM T32 35 * See "Semihosting for AArch32 and AArch64 Version 2.0 Documentation" by ARM 36 */ 37#define semihosting_call bkpt 0xab 38#define SYS_EXIT 0x18 39 40vector_table: 41 .word SRAM_BASE + SRAM_SIZE /* 0. SP_main */ 42 .word exc_reset_thumb /* 1. Reset */ 43 .word 0 /* 2. NMI */ 44 .word exc_hard_fault_thumb /* 3. HardFault */ 45 .rept 7 46 .word 0 /* 4-10. Reserved */ 47 .endr 48 .word 0 /* 11. SVCall */ 49 .word 0 /* 12. Reserved */ 50 .word 0 /* 13. Reserved */ 51 .word 0 /* 14. PendSV */ 52 .word 0 /* 15. SysTick */ 53 .rept 32 54 .word 0 /* 16-47. External Interrupts */ 55 .endr 56 57exc_reset: 58.equ exc_reset_thumb, exc_reset + 1 59.global exc_reset_thumb 60 /* The following 32-bit UNDEFINED instructions are tested by executing 61 * them. The HardFault exception handler should execute and return to 62 * the next test case. If no exception is raised the test fails. 63 */ 64 65 /* Table A5-9 32-bit Thumb encoding */ 66 .short 0b1110100000000000 67 .short 0b0000000000000000 68 b not_reached 69 .short 0b1110100000000000 70 .short 0b1000000000000000 71 b not_reached 72 .short 0b1111100000000000 73 .short 0b0000000000000000 74 b not_reached 75 .short 0b1111100000000000 76 .short 0b1000000000000000 77 b not_reached 78 .short 0b1111000000000000 79 .short 0b0000000000000000 80 b not_reached 81 82 /* Table A5-10 Branch and miscellaneous control instructions */ 83 .short 0b1111011111110000 84 .short 0b1010000000000000 85 b not_reached 86 87 /* The following are valid 32-bit instructions that must not raise a 88 * HardFault. 89 */ 90 91 /* B4.2.3 Move to Special Register (moves to IPSR are ignored) */ 92 msr ipsr, r0 93 b 1f 94 b not_reached 951: 96 /* B4.2.2 Move from Special Register */ 97 mrs r0, ipsr 98 b 1f 99 b not_reached 1001: 101 /* A6.7.13 Branch with Link (immediate) */ 102 bl 1f 1031: 104 b 1f 105 b not_reached 1061: 107 /* A6.7.21 Data Memory Barrier */ 108 dmb 109 b 1f 110 b not_reached 1111: 112 /* A6.7.22 Data Synchronization Barrier */ 113 dsb 114 b 1f 115 b not_reached 1161: 117 /* A6.7.24 Instruction Memory Barrier */ 118 isb 119 b 1f 120 b not_reached 1211: 122 123 /* Success! */ 124 movs r0, 1 125 b exit 126 127not_reached: /* Failure :( */ 128 movs r0, 0 129 b exit 130 131/* When a HardFault occurs, return to pc+6 (test cases are 3 halfwords long) */ 132exc_hard_fault: 133.equ exc_hard_fault_thumb, exc_hard_fault + 1 134.global exc_hard_fault_thumb 135 ldr r0, [sp, 0x18] 136 adds r0, 6 137 str r0, [sp, 0x18] 138 bx lr 139 140/* 141 * exit: Terminate emulator 142 * @r0: 0 - failure, 1 - success 143 */ 144exit: 145 movs r1, 0 146 cmp r0, 1 147 bne 1f 148 ldr r1, ADP_Stopped_ApplicationExit 1491: 150 movs r0, SYS_EXIT 151 semihosting_call 152.align 2 153ADP_Stopped_ApplicationExit: 154 .word 0x20026 155