xref: /kvm-unit-tests/lib/arm64/asm/processor.h (revision d9729025989690ae4e02c6b84eac881849dd186a)
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>
21957b6055SAndrew Jones #include <asm/esr.h>
2292fca209SWei Huang #include <asm/sysreg.h>
237ee966e9SAndrew Jones 
247ee966e9SAndrew Jones enum vector {
257ee966e9SAndrew Jones 	EL1T_SYNC,
267ee966e9SAndrew Jones 	EL1T_IRQ,
277ee966e9SAndrew Jones 	EL1T_FIQ,
287ee966e9SAndrew Jones 	EL1T_ERROR,
297ee966e9SAndrew Jones 	EL1H_SYNC,
307ee966e9SAndrew Jones 	EL1H_IRQ,
317ee966e9SAndrew Jones 	EL1H_FIQ,
327ee966e9SAndrew Jones 	EL1H_ERROR,
337ee966e9SAndrew Jones 	EL0_SYNC_64,
347ee966e9SAndrew Jones 	EL0_IRQ_64,
357ee966e9SAndrew Jones 	EL0_FIQ_64,
367ee966e9SAndrew Jones 	EL0_ERROR_64,
377ee966e9SAndrew Jones 	EL0_SYNC_32,
387ee966e9SAndrew Jones 	EL0_IRQ_32,
397ee966e9SAndrew Jones 	EL0_FIQ_32,
407ee966e9SAndrew Jones 	EL0_ERROR_32,
417ee966e9SAndrew Jones 	VECTOR_MAX,
427ee966e9SAndrew Jones };
437ee966e9SAndrew Jones 
447ee966e9SAndrew Jones #define EC_MAX 64
457ee966e9SAndrew Jones 
467ee966e9SAndrew Jones typedef void (*vector_fn)(enum vector v, struct pt_regs *regs,
477ee966e9SAndrew Jones 			  unsigned int esr);
487ee966e9SAndrew Jones typedef void (*exception_fn)(struct pt_regs *regs, unsigned int esr);
499ae19a63SAndrew Jones typedef void (*irq_handler_fn)(struct pt_regs *regs);
507ee966e9SAndrew Jones extern void install_vector_handler(enum vector v, vector_fn fn);
517ee966e9SAndrew Jones extern void install_exception_handler(enum vector v, unsigned int ec,
527ee966e9SAndrew Jones 				      exception_fn fn);
539ae19a63SAndrew Jones extern void install_irq_handler(enum vector v, irq_handler_fn fn);
549ae19a63SAndrew Jones extern void default_vector_sync_handler(enum vector v, struct pt_regs *regs,
559ae19a63SAndrew Jones 					unsigned int esr);
569ae19a63SAndrew Jones extern void default_vector_irq_handler(enum vector v, struct pt_regs *regs,
57a4049322SAndrew Jones 				       unsigned int esr);
58ad14f089SAndrew Jones extern void vector_handlers_default_init(vector_fn *handlers);
597ee966e9SAndrew Jones 
607ee966e9SAndrew Jones extern void show_regs(struct pt_regs *regs);
61db328a24SAndrew Jones extern bool get_far(unsigned int esr, unsigned long *far);
627ee966e9SAndrew Jones 
637ee966e9SAndrew Jones static inline unsigned long current_level(void)
647ee966e9SAndrew Jones {
657ee966e9SAndrew Jones 	unsigned long el;
667ee966e9SAndrew Jones 	asm volatile("mrs %0, CurrentEL" : "=r" (el));
677ee966e9SAndrew Jones 	return el & 0xc;
687ee966e9SAndrew Jones }
697ee966e9SAndrew Jones 
7092fca209SWei Huang static inline unsigned int get_mpidr(void)
7192fca209SWei Huang {
7292fca209SWei Huang 	return read_sysreg(mpidr_el1);
73f6d10793SAndrew Jones }
74f6d10793SAndrew Jones 
75*d9729025SAndrew Jones #define MPIDR_HWID_BITMASK 0xff00ffffff
76*d9729025SAndrew Jones extern int mpidr_to_cpu(uint64_t mpidr);
77*d9729025SAndrew Jones 
78*d9729025SAndrew Jones #define MPIDR_LEVEL_SHIFT(level) \
79*d9729025SAndrew Jones 	(((1 << level) >> 1) << 3)
80*d9729025SAndrew Jones #define MPIDR_AFFINITY_LEVEL(mpidr, level) \
81*d9729025SAndrew Jones 	((mpidr >> MPIDR_LEVEL_SHIFT(level)) & 0xff)
82f6d10793SAndrew Jones 
837ee966e9SAndrew Jones extern void start_usr(void (*func)(void *arg), void *arg, unsigned long sp_usr);
84f6d10793SAndrew Jones extern bool is_user(void);
857ee966e9SAndrew Jones 
86db328a24SAndrew Jones #endif /* !__ASSEMBLY__ */
877ee966e9SAndrew Jones #endif /* _ASMARM64_PROCESSOR_H_ */
88