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
9*0cc3a351SSean Christopherson #ifndef __ASSEMBLER__
107ee966e9SAndrew Jones #include <asm/ptrace.h>
11957b6055SAndrew Jones #include <asm/esr.h>
1292fca209SWei Huang #include <asm/sysreg.h>
13a5875fd4SAndrew Jones #include <asm/barrier.h>
147ee966e9SAndrew Jones
157ee966e9SAndrew Jones enum vector {
167ee966e9SAndrew Jones EL1T_SYNC,
177ee966e9SAndrew Jones EL1T_IRQ,
187ee966e9SAndrew Jones EL1T_FIQ,
197ee966e9SAndrew Jones EL1T_ERROR,
207ee966e9SAndrew Jones EL1H_SYNC,
217ee966e9SAndrew Jones EL1H_IRQ,
227ee966e9SAndrew Jones EL1H_FIQ,
237ee966e9SAndrew Jones EL1H_ERROR,
247ee966e9SAndrew Jones EL0_SYNC_64,
257ee966e9SAndrew Jones EL0_IRQ_64,
267ee966e9SAndrew Jones EL0_FIQ_64,
277ee966e9SAndrew Jones EL0_ERROR_64,
287ee966e9SAndrew Jones EL0_SYNC_32,
297ee966e9SAndrew Jones EL0_IRQ_32,
307ee966e9SAndrew Jones EL0_FIQ_32,
317ee966e9SAndrew Jones EL0_ERROR_32,
327ee966e9SAndrew Jones VECTOR_MAX,
337ee966e9SAndrew Jones };
347ee966e9SAndrew Jones
357ee966e9SAndrew Jones #define EC_MAX 64
367ee966e9SAndrew Jones
377ee966e9SAndrew Jones typedef void (*vector_fn)(enum vector v, struct pt_regs *regs,
387ee966e9SAndrew Jones unsigned int esr);
397ee966e9SAndrew Jones typedef void (*exception_fn)(struct pt_regs *regs, unsigned int esr);
409ae19a63SAndrew Jones typedef void (*irq_handler_fn)(struct pt_regs *regs);
417ee966e9SAndrew Jones extern void install_vector_handler(enum vector v, vector_fn fn);
427ee966e9SAndrew Jones extern void install_exception_handler(enum vector v, unsigned int ec,
437ee966e9SAndrew Jones exception_fn fn);
449ae19a63SAndrew Jones extern void install_irq_handler(enum vector v, irq_handler_fn fn);
459ae19a63SAndrew Jones extern void default_vector_sync_handler(enum vector v, struct pt_regs *regs,
469ae19a63SAndrew Jones unsigned int esr);
479ae19a63SAndrew Jones extern void default_vector_irq_handler(enum vector v, struct pt_regs *regs,
48a4049322SAndrew Jones unsigned int esr);
49ad14f089SAndrew Jones extern void vector_handlers_default_init(vector_fn *handlers);
507ee966e9SAndrew Jones
517ee966e9SAndrew Jones extern void show_regs(struct pt_regs *regs);
52db328a24SAndrew Jones extern bool get_far(unsigned int esr, unsigned long *far);
537ee966e9SAndrew Jones
current_level(void)547ee966e9SAndrew Jones static inline unsigned long current_level(void)
557ee966e9SAndrew Jones {
567ee966e9SAndrew Jones unsigned long el;
577ee966e9SAndrew Jones asm volatile("mrs %0, CurrentEL" : "=r" (el));
587ee966e9SAndrew Jones return el & 0xc;
597ee966e9SAndrew Jones }
607ee966e9SAndrew Jones
local_irq_enable(void)61990e5425SAndrew Jones static inline void local_irq_enable(void)
62990e5425SAndrew Jones {
63990e5425SAndrew Jones asm volatile("msr daifclr, #2" : : : "memory");
64990e5425SAndrew Jones }
65990e5425SAndrew Jones
local_irq_disable(void)66990e5425SAndrew Jones static inline void local_irq_disable(void)
67990e5425SAndrew Jones {
68990e5425SAndrew Jones asm volatile("msr daifset, #2" : : : "memory");
69990e5425SAndrew Jones }
70990e5425SAndrew Jones
get_mpidr(void)71da905c9dSAndrew Jones static inline uint64_t get_mpidr(void)
7292fca209SWei Huang {
7392fca209SWei Huang return read_sysreg(mpidr_el1);
74f6d10793SAndrew Jones }
75f6d10793SAndrew Jones
76d9729025SAndrew Jones #define MPIDR_HWID_BITMASK 0xff00ffffff
77d9729025SAndrew Jones extern int mpidr_to_cpu(uint64_t mpidr);
78d9729025SAndrew Jones
79d9729025SAndrew Jones #define MPIDR_LEVEL_SHIFT(level) \
80d9729025SAndrew Jones (((1 << level) >> 1) << 3)
81d9729025SAndrew Jones #define MPIDR_AFFINITY_LEVEL(mpidr, level) \
82d9729025SAndrew Jones ((mpidr >> MPIDR_LEVEL_SHIFT(level)) & 0xff)
83f6d10793SAndrew Jones
847ee966e9SAndrew Jones extern void start_usr(void (*func)(void *arg), void *arg, unsigned long sp_usr);
85f6d10793SAndrew Jones extern bool is_user(void);
860917dc65SNikos Nikoleris extern bool __mmu_enabled(void);
877ee966e9SAndrew Jones
get_cntvct(void)88a5875fd4SAndrew Jones static inline u64 get_cntvct(void)
89a5875fd4SAndrew Jones {
90a5875fd4SAndrew Jones isb();
91a5875fd4SAndrew Jones return read_sysreg(cntvct_el0);
92a5875fd4SAndrew Jones }
93a5875fd4SAndrew Jones
get_cntfrq(void)94a5875fd4SAndrew Jones static inline u32 get_cntfrq(void)
95a5875fd4SAndrew Jones {
96a5875fd4SAndrew Jones return read_sysreg(cntfrq_el0);
97a5875fd4SAndrew Jones }
98a5875fd4SAndrew Jones
get_ctr(void)99410b3bf0SAlexandru Elisei static inline u64 get_ctr(void)
100410b3bf0SAlexandru Elisei {
101410b3bf0SAlexandru Elisei return read_sysreg(ctr_el0);
102410b3bf0SAlexandru Elisei }
103410b3bf0SAlexandru Elisei
get_id_aa64mmfr0_el1(void)104c67363eeSNikos Nikoleris static inline unsigned long get_id_aa64mmfr0_el1(void)
105c67363eeSNikos Nikoleris {
106c67363eeSNikos Nikoleris return read_sysreg(id_aa64mmfr0_el1);
107c67363eeSNikos Nikoleris }
108c67363eeSNikos Nikoleris
109c67363eeSNikos Nikoleris #define ID_AA64MMFR0_TGRAN4_SHIFT 28
110c67363eeSNikos Nikoleris #define ID_AA64MMFR0_TGRAN64_SHIFT 24
111c67363eeSNikos Nikoleris #define ID_AA64MMFR0_TGRAN16_SHIFT 20
112c67363eeSNikos Nikoleris
113dc0a3a76SAndrew Jones #define ID_AA64MMFR0_TGRAN4_SUPPORTED(r) \
114dc0a3a76SAndrew Jones ({ \
115dc0a3a76SAndrew Jones u64 __v = ((r) >> ID_AA64MMFR0_TGRAN4_SHIFT) & 0xf; \
116dc0a3a76SAndrew Jones (__v) == 0 || (__v) == 1; \
117dc0a3a76SAndrew Jones })
118dc0a3a76SAndrew Jones
119dc0a3a76SAndrew Jones #define ID_AA64MMFR0_TGRAN64_SUPPORTED(r) \
120dc0a3a76SAndrew Jones ({ \
121dc0a3a76SAndrew Jones u64 __v = ((r) >> ID_AA64MMFR0_TGRAN64_SHIFT) & 0xf; \
122dc0a3a76SAndrew Jones (__v) == 0; \
123dc0a3a76SAndrew Jones })
124dc0a3a76SAndrew Jones
125dc0a3a76SAndrew Jones #define ID_AA64MMFR0_TGRAN16_SUPPORTED(r) \
126dc0a3a76SAndrew Jones ({ \
127dc0a3a76SAndrew Jones u64 __v = ((r) >> ID_AA64MMFR0_TGRAN16_SHIFT) & 0xf; \
128dc0a3a76SAndrew Jones (__v) == 1 || (__v) == 2; \
129dc0a3a76SAndrew Jones })
130c67363eeSNikos Nikoleris
system_supports_granule(size_t granule)131c67363eeSNikos Nikoleris static inline bool system_supports_granule(size_t granule)
132c67363eeSNikos Nikoleris {
133dc0a3a76SAndrew Jones u64 mmfr0 = get_id_aa64mmfr0_el1();
134c67363eeSNikos Nikoleris
135dc0a3a76SAndrew Jones if (granule == SZ_4K)
136dc0a3a76SAndrew Jones return ID_AA64MMFR0_TGRAN4_SUPPORTED(mmfr0);
137dc0a3a76SAndrew Jones
138dc0a3a76SAndrew Jones if (granule == SZ_16K)
139dc0a3a76SAndrew Jones return ID_AA64MMFR0_TGRAN16_SUPPORTED(mmfr0);
140dc0a3a76SAndrew Jones
141c67363eeSNikos Nikoleris assert(granule == SZ_64K);
142dc0a3a76SAndrew Jones return ID_AA64MMFR0_TGRAN64_SUPPORTED(mmfr0);
143c67363eeSNikos Nikoleris }
144c67363eeSNikos Nikoleris
get_id_aa64pfr0_el1(void)145d47d370cSSubhasish Ghosh static inline unsigned long get_id_aa64pfr0_el1(void)
146d47d370cSSubhasish Ghosh {
147d47d370cSSubhasish Ghosh return read_sysreg(id_aa64pfr0_el1);
148d47d370cSSubhasish Ghosh }
149d47d370cSSubhasish Ghosh
150d47d370cSSubhasish Ghosh #define ID_AA64PFR0_EL1_SVE_SHIFT 32
151d47d370cSSubhasish Ghosh
system_supports_sve(void)152d47d370cSSubhasish Ghosh static inline bool system_supports_sve(void)
153d47d370cSSubhasish Ghosh {
154d47d370cSSubhasish Ghosh return ((get_id_aa64pfr0_el1() >> ID_AA64PFR0_EL1_SVE_SHIFT) & 0xf) != 0;
155d47d370cSSubhasish Ghosh }
156d47d370cSSubhasish Ghosh
sve_vl(void)1570ed2cdf3SSuzuki K Poulose static inline unsigned long sve_vl(void)
158d47d370cSSubhasish Ghosh {
1590ed2cdf3SSuzuki K Poulose unsigned long vl;
160d47d370cSSubhasish Ghosh
161d47d370cSSubhasish Ghosh asm volatile(".arch_extension sve\n"
1620ed2cdf3SSuzuki K Poulose "rdvl %x0, #8"
163d47d370cSSubhasish Ghosh : "=r" (vl));
164d47d370cSSubhasish Ghosh
165d47d370cSSubhasish Ghosh return vl;
166d47d370cSSubhasish Ghosh }
167d47d370cSSubhasish Ghosh
168d47d370cSSubhasish Ghosh
system_supports_rndr(void)169d47d370cSSubhasish Ghosh static inline bool system_supports_rndr(void)
170d47d370cSSubhasish Ghosh {
171d47d370cSSubhasish Ghosh u64 id_aa64isar0_el1 = read_sysreg(ID_AA64ISAR0_EL1);
172d47d370cSSubhasish Ghosh
173d47d370cSSubhasish Ghosh return ((id_aa64isar0_el1 >> ID_AA64ISAR0_EL1_RNDR_SHIFT) & 0xf) != 0;
174d47d370cSSubhasish Ghosh }
175d47d370cSSubhasish Ghosh
176*0cc3a351SSean Christopherson #endif /* !__ASSEMBLER__ */
1777ee966e9SAndrew Jones #endif /* _ASMARM64_PROCESSOR_H_ */
178