18c2ecf20Sopenharmony_ci/* SPDX-License-Identifier: GPL-2.0 */
28c2ecf20Sopenharmony_ci/* Copyright (C) 2020 ARM Limited */
38c2ecf20Sopenharmony_ci
48c2ecf20Sopenharmony_ci#include "mte_def.h"
58c2ecf20Sopenharmony_ci
68c2ecf20Sopenharmony_ci#define ENTRY(name) \
78c2ecf20Sopenharmony_ci	.globl name ;\
88c2ecf20Sopenharmony_ci	.p2align 2;\
98c2ecf20Sopenharmony_ci	.type name, @function ;\
108c2ecf20Sopenharmony_ciname:
118c2ecf20Sopenharmony_ci
128c2ecf20Sopenharmony_ci#define ENDPROC(name) \
138c2ecf20Sopenharmony_ci	.size name, .-name ;
148c2ecf20Sopenharmony_ci
158c2ecf20Sopenharmony_ci	.text
168c2ecf20Sopenharmony_ci/*
178c2ecf20Sopenharmony_ci * mte_insert_random_tag: Insert random tag and might be same as the source tag if
188c2ecf20Sopenharmony_ci *			  the source pointer has it.
198c2ecf20Sopenharmony_ci * Input:
208c2ecf20Sopenharmony_ci *		x0 - source pointer with a tag/no-tag
218c2ecf20Sopenharmony_ci * Return:
228c2ecf20Sopenharmony_ci *		x0 - pointer with random tag
238c2ecf20Sopenharmony_ci */
248c2ecf20Sopenharmony_ciENTRY(mte_insert_random_tag)
258c2ecf20Sopenharmony_ci	irg	x0, x0, xzr
268c2ecf20Sopenharmony_ci	ret
278c2ecf20Sopenharmony_ciENDPROC(mte_insert_random_tag)
288c2ecf20Sopenharmony_ci
298c2ecf20Sopenharmony_ci/*
308c2ecf20Sopenharmony_ci * mte_insert_new_tag: Insert new tag and different from the source tag if
318c2ecf20Sopenharmony_ci *		       source pointer has it.
328c2ecf20Sopenharmony_ci * Input:
338c2ecf20Sopenharmony_ci *		x0 - source pointer with a tag/no-tag
348c2ecf20Sopenharmony_ci * Return:
358c2ecf20Sopenharmony_ci *		x0 - pointer with random tag
368c2ecf20Sopenharmony_ci */
378c2ecf20Sopenharmony_ciENTRY(mte_insert_new_tag)
388c2ecf20Sopenharmony_ci	gmi	x1, x0, xzr
398c2ecf20Sopenharmony_ci	irg	x0, x0, x1
408c2ecf20Sopenharmony_ci	ret
418c2ecf20Sopenharmony_ciENDPROC(mte_insert_new_tag)
428c2ecf20Sopenharmony_ci
438c2ecf20Sopenharmony_ci/*
448c2ecf20Sopenharmony_ci * mte_get_tag_address: Get the tag from given address.
458c2ecf20Sopenharmony_ci * Input:
468c2ecf20Sopenharmony_ci *		x0 - source pointer
478c2ecf20Sopenharmony_ci * Return:
488c2ecf20Sopenharmony_ci *		x0 - pointer with appended tag
498c2ecf20Sopenharmony_ci */
508c2ecf20Sopenharmony_ciENTRY(mte_get_tag_address)
518c2ecf20Sopenharmony_ci	ldg	x0, [x0]
528c2ecf20Sopenharmony_ci	ret
538c2ecf20Sopenharmony_ciENDPROC(mte_get_tag_address)
548c2ecf20Sopenharmony_ci
558c2ecf20Sopenharmony_ci/*
568c2ecf20Sopenharmony_ci * mte_set_tag_address_range: Set the tag range from the given address
578c2ecf20Sopenharmony_ci * Input:
588c2ecf20Sopenharmony_ci *		x0 - source pointer with tag data
598c2ecf20Sopenharmony_ci *		x1 - range
608c2ecf20Sopenharmony_ci * Return:
618c2ecf20Sopenharmony_ci *		none
628c2ecf20Sopenharmony_ci */
638c2ecf20Sopenharmony_ciENTRY(mte_set_tag_address_range)
648c2ecf20Sopenharmony_ci	cbz	x1, 2f
658c2ecf20Sopenharmony_ci1:
668c2ecf20Sopenharmony_ci	stg	x0, [x0, #0x0]
678c2ecf20Sopenharmony_ci	add	x0, x0, #MT_GRANULE_SIZE
688c2ecf20Sopenharmony_ci	sub	x1, x1, #MT_GRANULE_SIZE
698c2ecf20Sopenharmony_ci	cbnz	x1, 1b
708c2ecf20Sopenharmony_ci2:
718c2ecf20Sopenharmony_ci	ret
728c2ecf20Sopenharmony_ciENDPROC(mte_set_tag_address_range)
738c2ecf20Sopenharmony_ci
748c2ecf20Sopenharmony_ci/*
758c2ecf20Sopenharmony_ci * mt_clear_tag_address_range: Clear the tag range from the given address
768c2ecf20Sopenharmony_ci * Input:
778c2ecf20Sopenharmony_ci *		x0 - source pointer with tag data
788c2ecf20Sopenharmony_ci *		x1 - range
798c2ecf20Sopenharmony_ci * Return:
808c2ecf20Sopenharmony_ci *		none
818c2ecf20Sopenharmony_ci */
828c2ecf20Sopenharmony_ciENTRY(mte_clear_tag_address_range)
838c2ecf20Sopenharmony_ci	cbz	x1, 2f
848c2ecf20Sopenharmony_ci1:
858c2ecf20Sopenharmony_ci	stzg	x0, [x0, #0x0]
868c2ecf20Sopenharmony_ci	add	x0, x0, #MT_GRANULE_SIZE
878c2ecf20Sopenharmony_ci	sub	x1, x1, #MT_GRANULE_SIZE
888c2ecf20Sopenharmony_ci	cbnz	x1, 1b
898c2ecf20Sopenharmony_ci2:
908c2ecf20Sopenharmony_ci	ret
918c2ecf20Sopenharmony_ciENDPROC(mte_clear_tag_address_range)
928c2ecf20Sopenharmony_ci
938c2ecf20Sopenharmony_ci/*
948c2ecf20Sopenharmony_ci * mte_enable_pstate_tco: Enable PSTATE.TCO (tag check override) field
958c2ecf20Sopenharmony_ci * Input:
968c2ecf20Sopenharmony_ci *		none
978c2ecf20Sopenharmony_ci * Return:
988c2ecf20Sopenharmony_ci *		none
998c2ecf20Sopenharmony_ci */
1008c2ecf20Sopenharmony_ciENTRY(mte_enable_pstate_tco)
1018c2ecf20Sopenharmony_ci	msr	tco, #MT_PSTATE_TCO_EN
1028c2ecf20Sopenharmony_ci	ret
1038c2ecf20Sopenharmony_ciENDPROC(mte_enable_pstate_tco)
1048c2ecf20Sopenharmony_ci
1058c2ecf20Sopenharmony_ci/*
1068c2ecf20Sopenharmony_ci * mte_disable_pstate_tco: Disable PSTATE.TCO (tag check override) field
1078c2ecf20Sopenharmony_ci * Input:
1088c2ecf20Sopenharmony_ci *		none
1098c2ecf20Sopenharmony_ci * Return:
1108c2ecf20Sopenharmony_ci *		none
1118c2ecf20Sopenharmony_ci */
1128c2ecf20Sopenharmony_ciENTRY(mte_disable_pstate_tco)
1138c2ecf20Sopenharmony_ci	msr	tco, #MT_PSTATE_TCO_DIS
1148c2ecf20Sopenharmony_ci	ret
1158c2ecf20Sopenharmony_ciENDPROC(mte_disable_pstate_tco)
1168c2ecf20Sopenharmony_ci
1178c2ecf20Sopenharmony_ci/*
1188c2ecf20Sopenharmony_ci * mte_get_pstate_tco: Get PSTATE.TCO (tag check override) field
1198c2ecf20Sopenharmony_ci * Input:
1208c2ecf20Sopenharmony_ci *		none
1218c2ecf20Sopenharmony_ci * Return:
1228c2ecf20Sopenharmony_ci *		x0
1238c2ecf20Sopenharmony_ci */
1248c2ecf20Sopenharmony_ciENTRY(mte_get_pstate_tco)
1258c2ecf20Sopenharmony_ci	mrs	x0, tco
1268c2ecf20Sopenharmony_ci	ubfx	x0, x0, #MT_PSTATE_TCO_SHIFT, #1
1278c2ecf20Sopenharmony_ci	ret
1288c2ecf20Sopenharmony_ciENDPROC(mte_get_pstate_tco)
129