xref: /kvm-unit-tests/lib/arm64/asm/processor.h (revision 957b60551601b80bf5822f826518c2c38466e226)
17ee966e9SAndrew Jones #ifndef _ASMARM64_PROCESSOR_H_
27ee966e9SAndrew Jones #define _ASMARM64_PROCESSOR_H_
37ee966e9SAndrew Jones /*
47ee966e9SAndrew Jones  * Copyright (C) 2014, Red Hat Inc, Andrew Jones <drjones@redhat.com>
57ee966e9SAndrew Jones  *
67ee966e9SAndrew Jones  * This work is licensed under the terms of the GNU LGPL, version 2.
77ee966e9SAndrew Jones  */
8db328a24SAndrew Jones 
9db328a24SAndrew Jones /* System Control Register (SCTLR_EL1) bits */
10db328a24SAndrew Jones #define SCTLR_EL1_EE	(1 << 25)
11db328a24SAndrew Jones #define SCTLR_EL1_WXN	(1 << 19)
12db328a24SAndrew Jones #define SCTLR_EL1_I	(1 << 12)
13db328a24SAndrew Jones #define SCTLR_EL1_SA0	(1 << 4)
14db328a24SAndrew Jones #define SCTLR_EL1_SA	(1 << 3)
15db328a24SAndrew Jones #define SCTLR_EL1_C	(1 << 2)
16db328a24SAndrew Jones #define SCTLR_EL1_A	(1 << 1)
17db328a24SAndrew Jones #define SCTLR_EL1_M	(1 << 0)
18db328a24SAndrew Jones 
19db328a24SAndrew Jones #ifndef __ASSEMBLY__
207ee966e9SAndrew Jones #include <asm/ptrace.h>
21*957b6055SAndrew Jones #include <asm/esr.h>
227ee966e9SAndrew Jones 
237ee966e9SAndrew Jones enum vector {
247ee966e9SAndrew Jones 	EL1T_SYNC,
257ee966e9SAndrew Jones 	EL1T_IRQ,
267ee966e9SAndrew Jones 	EL1T_FIQ,
277ee966e9SAndrew Jones 	EL1T_ERROR,
287ee966e9SAndrew Jones 	EL1H_SYNC,
297ee966e9SAndrew Jones 	EL1H_IRQ,
307ee966e9SAndrew Jones 	EL1H_FIQ,
317ee966e9SAndrew Jones 	EL1H_ERROR,
327ee966e9SAndrew Jones 	EL0_SYNC_64,
337ee966e9SAndrew Jones 	EL0_IRQ_64,
347ee966e9SAndrew Jones 	EL0_FIQ_64,
357ee966e9SAndrew Jones 	EL0_ERROR_64,
367ee966e9SAndrew Jones 	EL0_SYNC_32,
377ee966e9SAndrew Jones 	EL0_IRQ_32,
387ee966e9SAndrew Jones 	EL0_FIQ_32,
397ee966e9SAndrew Jones 	EL0_ERROR_32,
407ee966e9SAndrew Jones 	VECTOR_MAX,
417ee966e9SAndrew Jones };
427ee966e9SAndrew Jones 
437ee966e9SAndrew Jones #define EC_MAX 64
447ee966e9SAndrew Jones 
457ee966e9SAndrew Jones typedef void (*vector_fn)(enum vector v, struct pt_regs *regs,
467ee966e9SAndrew Jones 			  unsigned int esr);
477ee966e9SAndrew Jones typedef void (*exception_fn)(struct pt_regs *regs, unsigned int esr);
489ae19a63SAndrew Jones typedef void (*irq_handler_fn)(struct pt_regs *regs);
497ee966e9SAndrew Jones extern void install_vector_handler(enum vector v, vector_fn fn);
507ee966e9SAndrew Jones extern void install_exception_handler(enum vector v, unsigned int ec,
517ee966e9SAndrew Jones 				      exception_fn fn);
529ae19a63SAndrew Jones extern void install_irq_handler(enum vector v, irq_handler_fn fn);
539ae19a63SAndrew Jones extern void default_vector_sync_handler(enum vector v, struct pt_regs *regs,
549ae19a63SAndrew Jones 					unsigned int esr);
559ae19a63SAndrew Jones extern void default_vector_irq_handler(enum vector v, struct pt_regs *regs,
56a4049322SAndrew Jones 				       unsigned int esr);
57ad14f089SAndrew Jones extern void vector_handlers_default_init(vector_fn *handlers);
587ee966e9SAndrew Jones 
597ee966e9SAndrew Jones extern void show_regs(struct pt_regs *regs);
60db328a24SAndrew Jones extern bool get_far(unsigned int esr, unsigned long *far);
617ee966e9SAndrew Jones 
627ee966e9SAndrew Jones static inline unsigned long current_level(void)
637ee966e9SAndrew Jones {
647ee966e9SAndrew Jones 	unsigned long el;
657ee966e9SAndrew Jones 	asm volatile("mrs %0, CurrentEL" : "=r" (el));
667ee966e9SAndrew Jones 	return el & 0xc;
677ee966e9SAndrew Jones }
687ee966e9SAndrew Jones 
69f6d10793SAndrew Jones #define DEFINE_GET_SYSREG32(reg)				\
70f6d10793SAndrew Jones static inline unsigned int get_##reg(void)			\
71f6d10793SAndrew Jones {								\
72f6d10793SAndrew Jones 	unsigned int reg;					\
73f6d10793SAndrew Jones 	asm volatile("mrs %0, " #reg "_el1" : "=r" (reg));	\
74f6d10793SAndrew Jones 	return reg;						\
75f6d10793SAndrew Jones }
76f6d10793SAndrew Jones DEFINE_GET_SYSREG32(mpidr)
77f6d10793SAndrew Jones 
78f6d10793SAndrew Jones /* Only support Aff0 for now, gicv2 only */
79f6d10793SAndrew Jones #define mpidr_to_cpu(mpidr) ((int)((mpidr) & 0xff))
80f6d10793SAndrew Jones 
817ee966e9SAndrew Jones extern void start_usr(void (*func)(void *arg), void *arg, unsigned long sp_usr);
82f6d10793SAndrew Jones extern bool is_user(void);
837ee966e9SAndrew Jones 
84db328a24SAndrew Jones #endif /* !__ASSEMBLY__ */
857ee966e9SAndrew Jones #endif /* _ASMARM64_PROCESSOR_H_ */
86