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