162306a36Sopenharmony_ci/* SPDX-License-Identifier: GPL-2.0 */
262306a36Sopenharmony_ci/* Copyright (C) 2020 ARM Limited */
362306a36Sopenharmony_ci
462306a36Sopenharmony_ci#include "mte_def.h"
562306a36Sopenharmony_ci
662306a36Sopenharmony_ci.arch	armv8.5-a+memtag
762306a36Sopenharmony_ci
862306a36Sopenharmony_ci#define ENTRY(name) \
962306a36Sopenharmony_ci	.globl name ;\
1062306a36Sopenharmony_ci	.p2align 2;\
1162306a36Sopenharmony_ci	.type name, @function ;\
1262306a36Sopenharmony_ciname:
1362306a36Sopenharmony_ci
1462306a36Sopenharmony_ci#define ENDPROC(name) \
1562306a36Sopenharmony_ci	.size name, .-name ;
1662306a36Sopenharmony_ci
1762306a36Sopenharmony_ci	.text
1862306a36Sopenharmony_ci/*
1962306a36Sopenharmony_ci * mte_insert_random_tag: Insert random tag and might be same as the source tag if
2062306a36Sopenharmony_ci *			  the source pointer has it.
2162306a36Sopenharmony_ci * Input:
2262306a36Sopenharmony_ci *		x0 - source pointer with a tag/no-tag
2362306a36Sopenharmony_ci * Return:
2462306a36Sopenharmony_ci *		x0 - pointer with random tag
2562306a36Sopenharmony_ci */
2662306a36Sopenharmony_ciENTRY(mte_insert_random_tag)
2762306a36Sopenharmony_ci	irg	x0, x0, xzr
2862306a36Sopenharmony_ci	ret
2962306a36Sopenharmony_ciENDPROC(mte_insert_random_tag)
3062306a36Sopenharmony_ci
3162306a36Sopenharmony_ci/*
3262306a36Sopenharmony_ci * mte_insert_new_tag: Insert new tag and different from the source tag if
3362306a36Sopenharmony_ci *		       source pointer has it.
3462306a36Sopenharmony_ci * Input:
3562306a36Sopenharmony_ci *		x0 - source pointer with a tag/no-tag
3662306a36Sopenharmony_ci * Return:
3762306a36Sopenharmony_ci *		x0 - pointer with random tag
3862306a36Sopenharmony_ci */
3962306a36Sopenharmony_ciENTRY(mte_insert_new_tag)
4062306a36Sopenharmony_ci	gmi	x1, x0, xzr
4162306a36Sopenharmony_ci	irg	x0, x0, x1
4262306a36Sopenharmony_ci	ret
4362306a36Sopenharmony_ciENDPROC(mte_insert_new_tag)
4462306a36Sopenharmony_ci
4562306a36Sopenharmony_ci/*
4662306a36Sopenharmony_ci * mte_get_tag_address: Get the tag from given address.
4762306a36Sopenharmony_ci * Input:
4862306a36Sopenharmony_ci *		x0 - source pointer
4962306a36Sopenharmony_ci * Return:
5062306a36Sopenharmony_ci *		x0 - pointer with appended tag
5162306a36Sopenharmony_ci */
5262306a36Sopenharmony_ciENTRY(mte_get_tag_address)
5362306a36Sopenharmony_ci	ldg	x0, [x0]
5462306a36Sopenharmony_ci	ret
5562306a36Sopenharmony_ciENDPROC(mte_get_tag_address)
5662306a36Sopenharmony_ci
5762306a36Sopenharmony_ci/*
5862306a36Sopenharmony_ci * mte_set_tag_address_range: Set the tag range from the given address
5962306a36Sopenharmony_ci * Input:
6062306a36Sopenharmony_ci *		x0 - source pointer with tag data
6162306a36Sopenharmony_ci *		x1 - range
6262306a36Sopenharmony_ci * Return:
6362306a36Sopenharmony_ci *		none
6462306a36Sopenharmony_ci */
6562306a36Sopenharmony_ciENTRY(mte_set_tag_address_range)
6662306a36Sopenharmony_ci	cbz	x1, 2f
6762306a36Sopenharmony_ci1:
6862306a36Sopenharmony_ci	stg	x0, [x0, #0x0]
6962306a36Sopenharmony_ci	add	x0, x0, #MT_GRANULE_SIZE
7062306a36Sopenharmony_ci	sub	x1, x1, #MT_GRANULE_SIZE
7162306a36Sopenharmony_ci	cbnz	x1, 1b
7262306a36Sopenharmony_ci2:
7362306a36Sopenharmony_ci	ret
7462306a36Sopenharmony_ciENDPROC(mte_set_tag_address_range)
7562306a36Sopenharmony_ci
7662306a36Sopenharmony_ci/*
7762306a36Sopenharmony_ci * mt_clear_tag_address_range: Clear the tag range from the given address
7862306a36Sopenharmony_ci * Input:
7962306a36Sopenharmony_ci *		x0 - source pointer with tag data
8062306a36Sopenharmony_ci *		x1 - range
8162306a36Sopenharmony_ci * Return:
8262306a36Sopenharmony_ci *		none
8362306a36Sopenharmony_ci */
8462306a36Sopenharmony_ciENTRY(mte_clear_tag_address_range)
8562306a36Sopenharmony_ci	cbz	x1, 2f
8662306a36Sopenharmony_ci1:
8762306a36Sopenharmony_ci	stzg	x0, [x0, #0x0]
8862306a36Sopenharmony_ci	add	x0, x0, #MT_GRANULE_SIZE
8962306a36Sopenharmony_ci	sub	x1, x1, #MT_GRANULE_SIZE
9062306a36Sopenharmony_ci	cbnz	x1, 1b
9162306a36Sopenharmony_ci2:
9262306a36Sopenharmony_ci	ret
9362306a36Sopenharmony_ciENDPROC(mte_clear_tag_address_range)
9462306a36Sopenharmony_ci
9562306a36Sopenharmony_ci/*
9662306a36Sopenharmony_ci * mte_enable_pstate_tco: Enable PSTATE.TCO (tag check override) field
9762306a36Sopenharmony_ci * Input:
9862306a36Sopenharmony_ci *		none
9962306a36Sopenharmony_ci * Return:
10062306a36Sopenharmony_ci *		none
10162306a36Sopenharmony_ci */
10262306a36Sopenharmony_ciENTRY(mte_enable_pstate_tco)
10362306a36Sopenharmony_ci	msr	tco, #MT_PSTATE_TCO_EN
10462306a36Sopenharmony_ci	ret
10562306a36Sopenharmony_ciENDPROC(mte_enable_pstate_tco)
10662306a36Sopenharmony_ci
10762306a36Sopenharmony_ci/*
10862306a36Sopenharmony_ci * mte_disable_pstate_tco: Disable PSTATE.TCO (tag check override) field
10962306a36Sopenharmony_ci * Input:
11062306a36Sopenharmony_ci *		none
11162306a36Sopenharmony_ci * Return:
11262306a36Sopenharmony_ci *		none
11362306a36Sopenharmony_ci */
11462306a36Sopenharmony_ciENTRY(mte_disable_pstate_tco)
11562306a36Sopenharmony_ci	msr	tco, #MT_PSTATE_TCO_DIS
11662306a36Sopenharmony_ci	ret
11762306a36Sopenharmony_ciENDPROC(mte_disable_pstate_tco)
11862306a36Sopenharmony_ci
11962306a36Sopenharmony_ci/*
12062306a36Sopenharmony_ci * mte_get_pstate_tco: Get PSTATE.TCO (tag check override) field
12162306a36Sopenharmony_ci * Input:
12262306a36Sopenharmony_ci *		none
12362306a36Sopenharmony_ci * Return:
12462306a36Sopenharmony_ci *		x0
12562306a36Sopenharmony_ci */
12662306a36Sopenharmony_ciENTRY(mte_get_pstate_tco)
12762306a36Sopenharmony_ci	mrs	x0, tco
12862306a36Sopenharmony_ci	ubfx	x0, x0, #MT_PSTATE_TCO_SHIFT, #1
12962306a36Sopenharmony_ci	ret
13062306a36Sopenharmony_ciENDPROC(mte_get_pstate_tco)
131