18c2ecf20Sopenharmony_ci/* SPDX-License-Identifier: GPL-2.0-only */
28c2ecf20Sopenharmony_ci/*
38c2ecf20Sopenharmony_ci *  arch/arm/include/asm/domain.h
48c2ecf20Sopenharmony_ci *
58c2ecf20Sopenharmony_ci *  Copyright (C) 1999 Russell King.
68c2ecf20Sopenharmony_ci */
78c2ecf20Sopenharmony_ci#ifndef __ASM_PROC_DOMAIN_H
88c2ecf20Sopenharmony_ci#define __ASM_PROC_DOMAIN_H
98c2ecf20Sopenharmony_ci
108c2ecf20Sopenharmony_ci#ifndef __ASSEMBLY__
118c2ecf20Sopenharmony_ci#include <asm/barrier.h>
128c2ecf20Sopenharmony_ci#include <asm/thread_info.h>
138c2ecf20Sopenharmony_ci#endif
148c2ecf20Sopenharmony_ci
158c2ecf20Sopenharmony_ci/*
168c2ecf20Sopenharmony_ci * Domain numbers
178c2ecf20Sopenharmony_ci *
188c2ecf20Sopenharmony_ci *  DOMAIN_IO     - domain 2 includes all IO only
198c2ecf20Sopenharmony_ci *  DOMAIN_USER   - domain 1 includes all user memory only
208c2ecf20Sopenharmony_ci *  DOMAIN_KERNEL - domain 0 includes all kernel memory only
218c2ecf20Sopenharmony_ci *
228c2ecf20Sopenharmony_ci * The domain numbering depends on whether we support 36 physical
238c2ecf20Sopenharmony_ci * address for I/O or not.  Addresses above the 32 bit boundary can
248c2ecf20Sopenharmony_ci * only be mapped using supersections and supersections can only
258c2ecf20Sopenharmony_ci * be set for domain 0.  We could just default to DOMAIN_IO as zero,
268c2ecf20Sopenharmony_ci * but there may be systems with supersection support and no 36-bit
278c2ecf20Sopenharmony_ci * addressing.  In such cases, we want to map system memory with
288c2ecf20Sopenharmony_ci * supersections to reduce TLB misses and footprint.
298c2ecf20Sopenharmony_ci *
308c2ecf20Sopenharmony_ci * 36-bit addressing and supersections are only available on
318c2ecf20Sopenharmony_ci * CPUs based on ARMv6+ or the Intel XSC3 core.
328c2ecf20Sopenharmony_ci */
338c2ecf20Sopenharmony_ci#ifndef CONFIG_IO_36
348c2ecf20Sopenharmony_ci#define DOMAIN_KERNEL	0
358c2ecf20Sopenharmony_ci#define DOMAIN_USER	1
368c2ecf20Sopenharmony_ci#define DOMAIN_IO	2
378c2ecf20Sopenharmony_ci#else
388c2ecf20Sopenharmony_ci#define DOMAIN_KERNEL	2
398c2ecf20Sopenharmony_ci#define DOMAIN_USER	1
408c2ecf20Sopenharmony_ci#define DOMAIN_IO	0
418c2ecf20Sopenharmony_ci#endif
428c2ecf20Sopenharmony_ci#define DOMAIN_VECTORS	3
438c2ecf20Sopenharmony_ci
448c2ecf20Sopenharmony_ci/*
458c2ecf20Sopenharmony_ci * Domain types
468c2ecf20Sopenharmony_ci */
478c2ecf20Sopenharmony_ci#define DOMAIN_NOACCESS	0
488c2ecf20Sopenharmony_ci#define DOMAIN_CLIENT	1
498c2ecf20Sopenharmony_ci#ifdef CONFIG_CPU_USE_DOMAINS
508c2ecf20Sopenharmony_ci#define DOMAIN_MANAGER	3
518c2ecf20Sopenharmony_ci#else
528c2ecf20Sopenharmony_ci#define DOMAIN_MANAGER	1
538c2ecf20Sopenharmony_ci#endif
548c2ecf20Sopenharmony_ci
558c2ecf20Sopenharmony_ci#define domain_mask(dom)	((3) << (2 * (dom)))
568c2ecf20Sopenharmony_ci#define domain_val(dom,type)	((type) << (2 * (dom)))
578c2ecf20Sopenharmony_ci
588c2ecf20Sopenharmony_ci#ifdef CONFIG_CPU_SW_DOMAIN_PAN
598c2ecf20Sopenharmony_ci#define DACR_INIT \
608c2ecf20Sopenharmony_ci	(domain_val(DOMAIN_USER, DOMAIN_NOACCESS) | \
618c2ecf20Sopenharmony_ci	 domain_val(DOMAIN_KERNEL, DOMAIN_MANAGER) | \
628c2ecf20Sopenharmony_ci	 domain_val(DOMAIN_IO, DOMAIN_CLIENT) | \
638c2ecf20Sopenharmony_ci	 domain_val(DOMAIN_VECTORS, DOMAIN_CLIENT))
648c2ecf20Sopenharmony_ci#else
658c2ecf20Sopenharmony_ci#define DACR_INIT \
668c2ecf20Sopenharmony_ci	(domain_val(DOMAIN_USER, DOMAIN_CLIENT) | \
678c2ecf20Sopenharmony_ci	 domain_val(DOMAIN_KERNEL, DOMAIN_MANAGER) | \
688c2ecf20Sopenharmony_ci	 domain_val(DOMAIN_IO, DOMAIN_CLIENT) | \
698c2ecf20Sopenharmony_ci	 domain_val(DOMAIN_VECTORS, DOMAIN_CLIENT))
708c2ecf20Sopenharmony_ci#endif
718c2ecf20Sopenharmony_ci
728c2ecf20Sopenharmony_ci#define __DACR_DEFAULT \
738c2ecf20Sopenharmony_ci	domain_val(DOMAIN_KERNEL, DOMAIN_CLIENT) | \
748c2ecf20Sopenharmony_ci	domain_val(DOMAIN_IO, DOMAIN_CLIENT) | \
758c2ecf20Sopenharmony_ci	domain_val(DOMAIN_VECTORS, DOMAIN_CLIENT)
768c2ecf20Sopenharmony_ci
778c2ecf20Sopenharmony_ci#define DACR_UACCESS_DISABLE	\
788c2ecf20Sopenharmony_ci	(__DACR_DEFAULT | domain_val(DOMAIN_USER, DOMAIN_NOACCESS))
798c2ecf20Sopenharmony_ci#define DACR_UACCESS_ENABLE	\
808c2ecf20Sopenharmony_ci	(__DACR_DEFAULT | domain_val(DOMAIN_USER, DOMAIN_CLIENT))
818c2ecf20Sopenharmony_ci
828c2ecf20Sopenharmony_ci#ifndef __ASSEMBLY__
838c2ecf20Sopenharmony_ci
848c2ecf20Sopenharmony_ci#ifdef CONFIG_CPU_CP15_MMU
858c2ecf20Sopenharmony_cistatic __always_inline unsigned int get_domain(void)
868c2ecf20Sopenharmony_ci{
878c2ecf20Sopenharmony_ci	unsigned int domain;
888c2ecf20Sopenharmony_ci
898c2ecf20Sopenharmony_ci	asm(
908c2ecf20Sopenharmony_ci	"mrc	p15, 0, %0, c3, c0	@ get domain"
918c2ecf20Sopenharmony_ci	 : "=r" (domain)
928c2ecf20Sopenharmony_ci	 : "m" (current_thread_info()->cpu_domain));
938c2ecf20Sopenharmony_ci
948c2ecf20Sopenharmony_ci	return domain;
958c2ecf20Sopenharmony_ci}
968c2ecf20Sopenharmony_ci
978c2ecf20Sopenharmony_cistatic __always_inline void set_domain(unsigned int val)
988c2ecf20Sopenharmony_ci{
998c2ecf20Sopenharmony_ci	asm volatile(
1008c2ecf20Sopenharmony_ci	"mcr	p15, 0, %0, c3, c0	@ set domain"
1018c2ecf20Sopenharmony_ci	  : : "r" (val) : "memory");
1028c2ecf20Sopenharmony_ci	isb();
1038c2ecf20Sopenharmony_ci}
1048c2ecf20Sopenharmony_ci#else
1058c2ecf20Sopenharmony_cistatic __always_inline unsigned int get_domain(void)
1068c2ecf20Sopenharmony_ci{
1078c2ecf20Sopenharmony_ci	return 0;
1088c2ecf20Sopenharmony_ci}
1098c2ecf20Sopenharmony_ci
1108c2ecf20Sopenharmony_cistatic __always_inline void set_domain(unsigned int val)
1118c2ecf20Sopenharmony_ci{
1128c2ecf20Sopenharmony_ci}
1138c2ecf20Sopenharmony_ci#endif
1148c2ecf20Sopenharmony_ci
1158c2ecf20Sopenharmony_ci#ifdef CONFIG_CPU_USE_DOMAINS
1168c2ecf20Sopenharmony_ci#define modify_domain(dom,type)					\
1178c2ecf20Sopenharmony_ci	do {							\
1188c2ecf20Sopenharmony_ci		unsigned int domain = get_domain();		\
1198c2ecf20Sopenharmony_ci		domain &= ~domain_mask(dom);			\
1208c2ecf20Sopenharmony_ci		domain = domain | domain_val(dom, type);	\
1218c2ecf20Sopenharmony_ci		set_domain(domain);				\
1228c2ecf20Sopenharmony_ci	} while (0)
1238c2ecf20Sopenharmony_ci
1248c2ecf20Sopenharmony_ci#else
1258c2ecf20Sopenharmony_cistatic inline void modify_domain(unsigned dom, unsigned type)	{ }
1268c2ecf20Sopenharmony_ci#endif
1278c2ecf20Sopenharmony_ci
1288c2ecf20Sopenharmony_ci/*
1298c2ecf20Sopenharmony_ci * Generate the T (user) versions of the LDR/STR and related
1308c2ecf20Sopenharmony_ci * instructions (inline assembly)
1318c2ecf20Sopenharmony_ci */
1328c2ecf20Sopenharmony_ci#ifdef CONFIG_CPU_USE_DOMAINS
1338c2ecf20Sopenharmony_ci#define TUSER(instr)		TUSERCOND(instr, )
1348c2ecf20Sopenharmony_ci#define TUSERCOND(instr, cond)	#instr "t" #cond
1358c2ecf20Sopenharmony_ci#else
1368c2ecf20Sopenharmony_ci#define TUSER(instr)		TUSERCOND(instr, )
1378c2ecf20Sopenharmony_ci#define TUSERCOND(instr, cond)	#instr #cond
1388c2ecf20Sopenharmony_ci#endif
1398c2ecf20Sopenharmony_ci
1408c2ecf20Sopenharmony_ci#else /* __ASSEMBLY__ */
1418c2ecf20Sopenharmony_ci
1428c2ecf20Sopenharmony_ci/*
1438c2ecf20Sopenharmony_ci * Generate the T (user) versions of the LDR/STR and related
1448c2ecf20Sopenharmony_ci * instructions
1458c2ecf20Sopenharmony_ci */
1468c2ecf20Sopenharmony_ci#ifdef CONFIG_CPU_USE_DOMAINS
1478c2ecf20Sopenharmony_ci#define TUSER(instr)	instr ## t
1488c2ecf20Sopenharmony_ci#else
1498c2ecf20Sopenharmony_ci#define TUSER(instr)	instr
1508c2ecf20Sopenharmony_ci#endif
1518c2ecf20Sopenharmony_ci
1528c2ecf20Sopenharmony_ci#endif /* __ASSEMBLY__ */
1538c2ecf20Sopenharmony_ci
1548c2ecf20Sopenharmony_ci#endif /* !__ASM_PROC_DOMAIN_H */
155