13a72e3ebSJaroslaw Pelczar/*
23a72e3ebSJaroslaw Pelczar * Copyright 2018, Jaroslaw Pelczar <jarek@jpelczar.com>
33a72e3ebSJaroslaw Pelczar * Distributed under the terms of the MIT License.
43a72e3ebSJaroslaw Pelczar */
53a72e3ebSJaroslaw Pelczar#ifndef _KERNEL_ARCH_ARM64_ARCH_CPU_H_
63a72e3ebSJaroslaw Pelczar#define _KERNEL_ARCH_ARM64_ARCH_CPU_H_
73a72e3ebSJaroslaw Pelczar
83a72e3ebSJaroslaw Pelczar
93a72e3ebSJaroslaw Pelczar#define CPU_MAX_CACHE_LEVEL 	8
103a72e3ebSJaroslaw Pelczar#define CACHE_LINE_SIZE 		64
113a72e3ebSJaroslaw Pelczar
123a72e3ebSJaroslaw Pelczar#define set_ac()
133a72e3ebSJaroslaw Pelczar#define clear_ac()
143a72e3ebSJaroslaw Pelczar
151761cb8eSJaroslaw Pelczar#include <kernel/arch/arm64/arm_registers.h>
163a72e3ebSJaroslaw Pelczar
173a72e3ebSJaroslaw Pelczar#ifndef _ASSEMBLER
183a72e3ebSJaroslaw Pelczar
193a72e3ebSJaroslaw Pelczar#include <arch/arm64/arch_thread_types.h>
203a72e3ebSJaroslaw Pelczar#include <kernel.h>
213a72e3ebSJaroslaw Pelczar
223a72e3ebSJaroslaw Pelczar#define arm64_sev()  		__asm__ __volatile__("sev" : : : "memory")
233a72e3ebSJaroslaw Pelczar#define arm64_wfe()  		__asm__ __volatile__("wfe" : : : "memory")
243a72e3ebSJaroslaw Pelczar#define arm64_dsb()  		__asm__ __volatile__("dsb" : : : "memory")
253a72e3ebSJaroslaw Pelczar#define arm64_dmb()  		__asm__ __volatile__("dmb" : : : "memory")
263a72e3ebSJaroslaw Pelczar#define arm64_isb()  		__asm__ __volatile__("isb" : : : "memory")
273a72e3ebSJaroslaw Pelczar#define arm64_nop()  		__asm__ __volatile__("nop" : : : "memory")
283a72e3ebSJaroslaw Pelczar#define arm64_yield() 	__asm__ __volatile__("yield" : : : "memory")
293a72e3ebSJaroslaw Pelczar
303a72e3ebSJaroslaw Pelczar/* Extract CPU affinity levels 0-3 */
313a72e3ebSJaroslaw Pelczar#define	CPU_AFF0(mpidr)	(u_int)(((mpidr) >> 0) & 0xff)
323a72e3ebSJaroslaw Pelczar#define	CPU_AFF1(mpidr)	(u_int)(((mpidr) >> 8) & 0xff)
333a72e3ebSJaroslaw Pelczar#define	CPU_AFF2(mpidr)	(u_int)(((mpidr) >> 16) & 0xff)
343a72e3ebSJaroslaw Pelczar#define	CPU_AFF3(mpidr)	(u_int)(((mpidr) >> 32) & 0xff)
353a72e3ebSJaroslaw Pelczar#define	CPU_AFF0_MASK	0xffUL
363a72e3ebSJaroslaw Pelczar#define	CPU_AFF1_MASK	0xff00UL
373a72e3ebSJaroslaw Pelczar#define	CPU_AFF2_MASK	0xff0000UL
383a72e3ebSJaroslaw Pelczar#define	CPU_AFF3_MASK	0xff00000000UL
393a72e3ebSJaroslaw Pelczar#define	CPU_AFF_MASK	(CPU_AFF0_MASK | CPU_AFF1_MASK | \
403a72e3ebSJaroslaw Pelczar    CPU_AFF2_MASK| CPU_AFF3_MASK)	/* Mask affinity fields in MPIDR_EL1 */
413a72e3ebSJaroslaw Pelczar
423a72e3ebSJaroslaw Pelczar
433a72e3ebSJaroslaw Pelczar#define	CPU_IMPL_ARM		0x41
443a72e3ebSJaroslaw Pelczar#define	CPU_IMPL_BROADCOM	0x42
453a72e3ebSJaroslaw Pelczar#define	CPU_IMPL_CAVIUM		0x43
463a72e3ebSJaroslaw Pelczar#define	CPU_IMPL_DEC		0x44
473a72e3ebSJaroslaw Pelczar#define	CPU_IMPL_INFINEON	0x49
483a72e3ebSJaroslaw Pelczar#define	CPU_IMPL_FREESCALE	0x4D
493a72e3ebSJaroslaw Pelczar#define	CPU_IMPL_NVIDIA		0x4E
503a72e3ebSJaroslaw Pelczar#define	CPU_IMPL_APM		0x50
513a72e3ebSJaroslaw Pelczar#define	CPU_IMPL_QUALCOMM	0x51
523a72e3ebSJaroslaw Pelczar#define	CPU_IMPL_MARVELL	0x56
533a72e3ebSJaroslaw Pelczar#define	CPU_IMPL_INTEL		0x69
543a72e3ebSJaroslaw Pelczar
553a72e3ebSJaroslaw Pelczar#define	CPU_PART_THUNDER	0x0A1
563a72e3ebSJaroslaw Pelczar#define	CPU_PART_FOUNDATION	0xD00
573a72e3ebSJaroslaw Pelczar#define	CPU_PART_CORTEX_A35	0xD04
583a72e3ebSJaroslaw Pelczar#define	CPU_PART_CORTEX_A53	0xD03
593a72e3ebSJaroslaw Pelczar#define	CPU_PART_CORTEX_A55	0xD05
603a72e3ebSJaroslaw Pelczar#define	CPU_PART_CORTEX_A57	0xD07
613a72e3ebSJaroslaw Pelczar#define	CPU_PART_CORTEX_A72	0xD08
623a72e3ebSJaroslaw Pelczar#define	CPU_PART_CORTEX_A73	0xD09
633a72e3ebSJaroslaw Pelczar#define	CPU_PART_CORTEX_A75	0xD0A
643a72e3ebSJaroslaw Pelczar
653a72e3ebSJaroslaw Pelczar#define	CPU_REV_THUNDER_1_0	0x00
663a72e3ebSJaroslaw Pelczar#define	CPU_REV_THUNDER_1_1	0x01
673a72e3ebSJaroslaw Pelczar
683a72e3ebSJaroslaw Pelczar#define	CPU_IMPL(midr)	(((midr) >> 24) & 0xff)
693a72e3ebSJaroslaw Pelczar#define	CPU_PART(midr)	(((midr) >> 4) & 0xfff)
703a72e3ebSJaroslaw Pelczar#define	CPU_VAR(midr)	(((midr) >> 20) & 0xf)
713a72e3ebSJaroslaw Pelczar#define	CPU_REV(midr)	(((midr) >> 0) & 0xf)
723a72e3ebSJaroslaw Pelczar
733a72e3ebSJaroslaw Pelczar#define	CPU_IMPL_TO_MIDR(val)	(((val) & 0xff) << 24)
743a72e3ebSJaroslaw Pelczar#define	CPU_PART_TO_MIDR(val)	(((val) & 0xfff) << 4)
753a72e3ebSJaroslaw Pelczar#define	CPU_VAR_TO_MIDR(val)	(((val) & 0xf) << 20)
763a72e3ebSJaroslaw Pelczar#define	CPU_REV_TO_MIDR(val)	(((val) & 0xf) << 0)
773a72e3ebSJaroslaw Pelczar
783a72e3ebSJaroslaw Pelczar#define	CPU_IMPL_MASK	(0xff << 24)
793a72e3ebSJaroslaw Pelczar#define	CPU_PART_MASK	(0xfff << 4)
803a72e3ebSJaroslaw Pelczar#define	CPU_VAR_MASK	(0xf << 20)
813a72e3ebSJaroslaw Pelczar#define	CPU_REV_MASK	(0xf << 0)
823a72e3ebSJaroslaw Pelczar
833a72e3ebSJaroslaw Pelczar#define	CPU_ID_RAW(impl, part, var, rev)		\
843a72e3ebSJaroslaw Pelczar    (CPU_IMPL_TO_MIDR((impl)) |				\
853a72e3ebSJaroslaw Pelczar    CPU_PART_TO_MIDR((part)) | CPU_VAR_TO_MIDR((var)) |	\
863a72e3ebSJaroslaw Pelczar    CPU_REV_TO_MIDR((rev)))
873a72e3ebSJaroslaw Pelczar
883a72e3ebSJaroslaw Pelczar#define	CPU_MATCH(mask, impl, part, var, rev)		\
893a72e3ebSJaroslaw Pelczar    (((mask) & PCPU_GET(midr)) ==			\
903a72e3ebSJaroslaw Pelczar    ((mask) & CPU_ID_RAW((impl), (part), (var), (rev))))
913a72e3ebSJaroslaw Pelczar
923a72e3ebSJaroslaw Pelczar#define	CPU_MATCH_RAW(mask, devid)			\
933a72e3ebSJaroslaw Pelczar    (((mask) & PCPU_GET(midr)) == ((mask) & (devid)))
943a72e3ebSJaroslaw Pelczar
953a72e3ebSJaroslaw Pelczarstatic inline uint64 arm64_get_cyclecount(void)
963a72e3ebSJaroslaw Pelczar{
973a72e3ebSJaroslaw Pelczar	return READ_SPECIALREG(cntvct_el0);
983a72e3ebSJaroslaw Pelczar}
993a72e3ebSJaroslaw Pelczar
1003a72e3ebSJaroslaw Pelczar#define	ADDRESS_TRANSLATE_FUNC(stage)					\
1013a72e3ebSJaroslaw Pelczarstatic inline uint64									\
1023a72e3ebSJaroslaw Pelczararm64_address_translate_ ##stage (uint64 addr)		\
1033a72e3ebSJaroslaw Pelczar{														\
1043a72e3ebSJaroslaw Pelczar	uint64 ret;											\
1053a72e3ebSJaroslaw Pelczar														\
1063a72e3ebSJaroslaw Pelczar	__asm __volatile(									\
1071761cb8eSJaroslaw Pelczar	    "at " __ARMREG_STRING(stage) ", %1 \n"					\
1083a72e3ebSJaroslaw Pelczar	    "mrs %0, par_el1" : "=r"(ret) : "r"(addr));		\
1093a72e3ebSJaroslaw Pelczar														\
1103a72e3ebSJaroslaw Pelczar	return (ret);										\
1113a72e3ebSJaroslaw Pelczar}
1123a72e3ebSJaroslaw Pelczar
1133a72e3ebSJaroslaw PelczarADDRESS_TRANSLATE_FUNC(s1e0r)
1143a72e3ebSJaroslaw PelczarADDRESS_TRANSLATE_FUNC(s1e0w)
1153a72e3ebSJaroslaw PelczarADDRESS_TRANSLATE_FUNC(s1e1r)
1163a72e3ebSJaroslaw PelczarADDRESS_TRANSLATE_FUNC(s1e1w)
1173a72e3ebSJaroslaw Pelczar
1183a72e3ebSJaroslaw Pelczar/* raw exception frames */
1193a72e3ebSJaroslaw Pelczarstruct iframe {
1203a72e3ebSJaroslaw Pelczar	uint64			sp;
1213a72e3ebSJaroslaw Pelczar	uint64			lr;
1223a72e3ebSJaroslaw Pelczar	uint64			elr;
1233a72e3ebSJaroslaw Pelczar	uint32			spsr;
1243a72e3ebSJaroslaw Pelczar	uint32			esr;
1253a72e3ebSJaroslaw Pelczar	uint64			x[30];
1263a72e3ebSJaroslaw Pelczar};
1273a72e3ebSJaroslaw Pelczar
1281761cb8eSJaroslaw Pelczar#ifdef __cplusplus
1293a72e3ebSJaroslaw Pelczarnamespace BKernel {
1303a72e3ebSJaroslaw Pelczar	struct Thread;
1313a72e3ebSJaroslaw Pelczar}  // namespace BKernel
1323a72e3ebSJaroslaw Pelczar
1333a72e3ebSJaroslaw Pelczartypedef struct arch_cpu_info {
1343a72e3ebSJaroslaw Pelczar	uint32						mpidr;
1353a72e3ebSJaroslaw Pelczar	BKernel::Thread*			last_vfp_user;
1363a72e3ebSJaroslaw Pelczar} arch_cpu_info;
1371761cb8eSJaroslaw Pelczar#endif
1383a72e3ebSJaroslaw Pelczar
1393a72e3ebSJaroslaw Pelczar#ifdef __cplusplus
1403a72e3ebSJaroslaw Pelczarextern "C" {
1413a72e3ebSJaroslaw Pelczar#endif
1423a72e3ebSJaroslaw Pelczar
1433a72e3ebSJaroslaw Pelczarstatic inline void arch_cpu_pause(void)
1443a72e3ebSJaroslaw Pelczar{
1453a72e3ebSJaroslaw Pelczar	arm64_yield();
1463a72e3ebSJaroslaw Pelczar}
1473a72e3ebSJaroslaw Pelczar
1483a72e3ebSJaroslaw Pelczarstatic inline void arch_cpu_idle(void)
1493a72e3ebSJaroslaw Pelczar{
1503a72e3ebSJaroslaw Pelczar	arm64_yield();
1513a72e3ebSJaroslaw Pelczar}
1523a72e3ebSJaroslaw Pelczar
1533a72e3ebSJaroslaw Pelczar#ifdef __cplusplus
1543a72e3ebSJaroslaw Pelczar}
1553a72e3ebSJaroslaw Pelczar#endif
1563a72e3ebSJaroslaw Pelczar
1573a72e3ebSJaroslaw Pelczar#endif
1583a72e3ebSJaroslaw Pelczar
1593a72e3ebSJaroslaw Pelczar
1603a72e3ebSJaroslaw Pelczar#endif /* _KERNEL_ARCH_ARM64_ARCH_CPU_H_ */
161