1/* 2 * Code to help test the MTE gdbstubs in system mode. 3 * 4 * Copyright (c) 2024 Linaro Limited 5 * 6 * Author: Gustavo Romero <gustavo.romero@linaro.org> 7 * 8 * SPDX-License-Identifier: LGPL-2.1-or-later 9 */ 10 11#define addr x0 /* Ptr to the start of the MTE-enabled page. */ 12#define tagged_addr x1 /* 'addr' ptr with a random-generated tag added. */ 13#define tmp0 x2 /* Scratch register. */ 14#define tmp1 x3 /* Scratch register. */ 15#define tmp2 x4 /* Scratch register. */ 16#define tmp3 x5 /* Sctatch register. */ 17 18 .file "mte.S" 19 20 .text 21 .align 4 22 23 .globl main 24 .type main, @function 25 26main: 27 /* 28 * Set MAIR_EL1 (Memory Attribute Index Register). In boot.S, the 29 * attribute index for .mte_page is set to point to MAILR_EL field Attr1 30 * (AttrIndx=Attr1), so set Attr1 as Tagged Normal (MTE) to enable MTE 31 * on this page. 32 * 33 * Attr1 = 0xF0 => Tagged Normal (MTE) 34 */ 35 mrs tmp0, mair_el1 36 orr tmp0, tmp0, (0xF0 << 8) 37 msr mair_el1, tmp0 38 39 /* 40 * Set TCR_EL1 (Translation Control Registers) to ignore the top byte 41 * in the translated addresses so it can be used to keep the tags. 42 * 43 * TBI0[37] = 0b1 => Top Byte ignored and used for tagged addresses 44 */ 45 mrs tmp1, tcr_el1 46 orr tmp1, tmp1, (1 << 37) 47 msr tcr_el1, tmp1 48 49 /* 50 * Set SCTLR_EL1 (System Control Register) to enable the use of MTE 51 * insns., like stg & friends, and to enable synchronous exception in 52 * case of a tag mismatch, i.e., when the logical tag in 'tagged_addr' 53 * is different from the allocation tag related to 'addr' address. 54 * 55 * ATA[43] = 0b1 => Enable access to allocation tags at EL1 56 * TCF[41:40] = 0b01 => Tag Check Faults cause a synchronous exception 57 * 58 */ 59 mrs tmp2, sctlr_el1 60 mov tmp3, (1 << 43) | (1 << 40) 61 orr tmp2, tmp2, tmp3 62 msr sctlr_el1, tmp2 63 64 isb 65 66 /* 67 * MTE-enabled page resides at the 3rd 2MB chunk in the second 1GB 68 * block, i.e., at 0x40400000 address. See .mte_page section in boot.S 69 * and kernel.ld (where the address is effectively computed). 70 * 71 * Load .mte_page address into 'addr' register. 72 */ 73 adrp addr, mte_page 74 add addr, addr, :lo12:mte_page 75 76 /* 77 * Set GCR for random tag generation. 0xA5 is just a random value to set 78 * GCR != 0 so the tag generated by 'irg' insn. is not zero, which is 79 * more interesting for the tests than when tag is zero. 80 */ 81 mov tmp0, 0xA5 82 msr gcr_el1, tmp0 83 84 /* 85 * Generate a logical tag, add it to 'addr' address and put it into 86 * 'tagged_addr'. 87 */ 88 irg tagged_addr, addr 89 90 /* 91 * Store the generated tag to memory region pointed to by 'addr', i.e. 92 * set the allocation tag for granule at 'addr'. The tag is extracted 93 * by stg from tagged_addr pointer. 94 */ 95 stg tagged_addr, [addr] 96 97 /* 98 * Store a random value (0xdeadbeef) to tagged_addr address. This must 99 * not cause any Tag Check Fault since logical tag in tagged_addr and 100 * allocation tag associated with the memory pointed by tagged_addr are 101 * set the same, otherwise something is off and the test fails -- an 102 * exception is generated. 103 */ 104 ldr tmp1, =0xdeadbeef 105 str tmp1, [tagged_addr] 106 107 /* This label is used by GDB Python script test-mte.py. */ 108main_end: 109 ret 110