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 19410b3bf0SAlexandru Elisei #define CTR_DMINLINE_SHIFT 16 20410b3bf0SAlexandru Elisei #define CTR_DMINLINE_MASK (0xf << 16) 21410b3bf0SAlexandru Elisei #define CTR_DMINLINE(x) \ 22410b3bf0SAlexandru Elisei (((x) & CTR_DMINLINE_MASK) >> CTR_DMINLINE_SHIFT) 23410b3bf0SAlexandru Elisei 24db328a24SAndrew Jones #ifndef __ASSEMBLY__ 257ee966e9SAndrew Jones #include <asm/ptrace.h> 26957b6055SAndrew Jones #include <asm/esr.h> 2792fca209SWei Huang #include <asm/sysreg.h> 28a5875fd4SAndrew Jones #include <asm/barrier.h> 297ee966e9SAndrew Jones 307ee966e9SAndrew Jones enum vector { 317ee966e9SAndrew Jones EL1T_SYNC, 327ee966e9SAndrew Jones EL1T_IRQ, 337ee966e9SAndrew Jones EL1T_FIQ, 347ee966e9SAndrew Jones EL1T_ERROR, 357ee966e9SAndrew Jones EL1H_SYNC, 367ee966e9SAndrew Jones EL1H_IRQ, 377ee966e9SAndrew Jones EL1H_FIQ, 387ee966e9SAndrew Jones EL1H_ERROR, 397ee966e9SAndrew Jones EL0_SYNC_64, 407ee966e9SAndrew Jones EL0_IRQ_64, 417ee966e9SAndrew Jones EL0_FIQ_64, 427ee966e9SAndrew Jones EL0_ERROR_64, 437ee966e9SAndrew Jones EL0_SYNC_32, 447ee966e9SAndrew Jones EL0_IRQ_32, 457ee966e9SAndrew Jones EL0_FIQ_32, 467ee966e9SAndrew Jones EL0_ERROR_32, 477ee966e9SAndrew Jones VECTOR_MAX, 487ee966e9SAndrew Jones }; 497ee966e9SAndrew Jones 507ee966e9SAndrew Jones #define EC_MAX 64 517ee966e9SAndrew Jones 527ee966e9SAndrew Jones typedef void (*vector_fn)(enum vector v, struct pt_regs *regs, 537ee966e9SAndrew Jones unsigned int esr); 547ee966e9SAndrew Jones typedef void (*exception_fn)(struct pt_regs *regs, unsigned int esr); 559ae19a63SAndrew Jones typedef void (*irq_handler_fn)(struct pt_regs *regs); 567ee966e9SAndrew Jones extern void install_vector_handler(enum vector v, vector_fn fn); 577ee966e9SAndrew Jones extern void install_exception_handler(enum vector v, unsigned int ec, 587ee966e9SAndrew Jones exception_fn fn); 599ae19a63SAndrew Jones extern void install_irq_handler(enum vector v, irq_handler_fn fn); 609ae19a63SAndrew Jones extern void default_vector_sync_handler(enum vector v, struct pt_regs *regs, 619ae19a63SAndrew Jones unsigned int esr); 629ae19a63SAndrew Jones extern void default_vector_irq_handler(enum vector v, struct pt_regs *regs, 63a4049322SAndrew Jones unsigned int esr); 64ad14f089SAndrew Jones extern void vector_handlers_default_init(vector_fn *handlers); 657ee966e9SAndrew Jones 667ee966e9SAndrew Jones extern void show_regs(struct pt_regs *regs); 67db328a24SAndrew Jones extern bool get_far(unsigned int esr, unsigned long *far); 687ee966e9SAndrew Jones 697ee966e9SAndrew Jones static inline unsigned long current_level(void) 707ee966e9SAndrew Jones { 717ee966e9SAndrew Jones unsigned long el; 727ee966e9SAndrew Jones asm volatile("mrs %0, CurrentEL" : "=r" (el)); 737ee966e9SAndrew Jones return el & 0xc; 747ee966e9SAndrew Jones } 757ee966e9SAndrew Jones 76990e5425SAndrew Jones static inline void local_irq_enable(void) 77990e5425SAndrew Jones { 78990e5425SAndrew Jones asm volatile("msr daifclr, #2" : : : "memory"); 79990e5425SAndrew Jones } 80990e5425SAndrew Jones 81990e5425SAndrew Jones static inline void local_irq_disable(void) 82990e5425SAndrew Jones { 83990e5425SAndrew Jones asm volatile("msr daifset, #2" : : : "memory"); 84990e5425SAndrew Jones } 85990e5425SAndrew Jones 86da905c9dSAndrew Jones static inline uint64_t get_mpidr(void) 8792fca209SWei Huang { 8892fca209SWei Huang return read_sysreg(mpidr_el1); 89f6d10793SAndrew Jones } 90f6d10793SAndrew Jones 91d9729025SAndrew Jones #define MPIDR_HWID_BITMASK 0xff00ffffff 92d9729025SAndrew Jones extern int mpidr_to_cpu(uint64_t mpidr); 93d9729025SAndrew Jones 94d9729025SAndrew Jones #define MPIDR_LEVEL_SHIFT(level) \ 95d9729025SAndrew Jones (((1 << level) >> 1) << 3) 96d9729025SAndrew Jones #define MPIDR_AFFINITY_LEVEL(mpidr, level) \ 97d9729025SAndrew Jones ((mpidr >> MPIDR_LEVEL_SHIFT(level)) & 0xff) 98f6d10793SAndrew Jones 997ee966e9SAndrew Jones extern void start_usr(void (*func)(void *arg), void *arg, unsigned long sp_usr); 100f6d10793SAndrew Jones extern bool is_user(void); 101*0917dc65SNikos Nikoleris extern bool __mmu_enabled(void); 1027ee966e9SAndrew Jones 103a5875fd4SAndrew Jones static inline u64 get_cntvct(void) 104a5875fd4SAndrew Jones { 105a5875fd4SAndrew Jones isb(); 106a5875fd4SAndrew Jones return read_sysreg(cntvct_el0); 107a5875fd4SAndrew Jones } 108a5875fd4SAndrew Jones 109a5875fd4SAndrew Jones static inline u32 get_cntfrq(void) 110a5875fd4SAndrew Jones { 111a5875fd4SAndrew Jones return read_sysreg(cntfrq_el0); 112a5875fd4SAndrew Jones } 113a5875fd4SAndrew Jones 114410b3bf0SAlexandru Elisei static inline u64 get_ctr(void) 115410b3bf0SAlexandru Elisei { 116410b3bf0SAlexandru Elisei return read_sysreg(ctr_el0); 117410b3bf0SAlexandru Elisei } 118410b3bf0SAlexandru Elisei 119956e3800SAndrew Jones extern unsigned long dcache_line_size; 120410b3bf0SAlexandru Elisei 121c67363eeSNikos Nikoleris static inline unsigned long get_id_aa64mmfr0_el1(void) 122c67363eeSNikos Nikoleris { 123c67363eeSNikos Nikoleris return read_sysreg(id_aa64mmfr0_el1); 124c67363eeSNikos Nikoleris } 125c67363eeSNikos Nikoleris 126c67363eeSNikos Nikoleris #define ID_AA64MMFR0_TGRAN4_SHIFT 28 127c67363eeSNikos Nikoleris #define ID_AA64MMFR0_TGRAN64_SHIFT 24 128c67363eeSNikos Nikoleris #define ID_AA64MMFR0_TGRAN16_SHIFT 20 129c67363eeSNikos Nikoleris 130c67363eeSNikos Nikoleris #define ID_AA64MMFR0_TGRAN4_SUPPORTED 0x0 131c67363eeSNikos Nikoleris #define ID_AA64MMFR0_TGRAN64_SUPPORTED 0x0 132c67363eeSNikos Nikoleris #define ID_AA64MMFR0_TGRAN16_SUPPORTED 0x1 133c67363eeSNikos Nikoleris 134c67363eeSNikos Nikoleris static inline bool system_supports_granule(size_t granule) 135c67363eeSNikos Nikoleris { 136c67363eeSNikos Nikoleris u32 shift; 137c67363eeSNikos Nikoleris u32 val; 138c67363eeSNikos Nikoleris u64 mmfr0; 139c67363eeSNikos Nikoleris 140c67363eeSNikos Nikoleris if (granule == SZ_4K) { 141c67363eeSNikos Nikoleris shift = ID_AA64MMFR0_TGRAN4_SHIFT; 142c67363eeSNikos Nikoleris val = ID_AA64MMFR0_TGRAN4_SUPPORTED; 143c67363eeSNikos Nikoleris } else if (granule == SZ_16K) { 144c67363eeSNikos Nikoleris shift = ID_AA64MMFR0_TGRAN16_SHIFT; 145c67363eeSNikos Nikoleris val = ID_AA64MMFR0_TGRAN16_SUPPORTED; 146c67363eeSNikos Nikoleris } else { 147c67363eeSNikos Nikoleris assert(granule == SZ_64K); 148c67363eeSNikos Nikoleris shift = ID_AA64MMFR0_TGRAN64_SHIFT; 149c67363eeSNikos Nikoleris val = ID_AA64MMFR0_TGRAN64_SUPPORTED; 150c67363eeSNikos Nikoleris } 151c67363eeSNikos Nikoleris 152c67363eeSNikos Nikoleris mmfr0 = get_id_aa64mmfr0_el1(); 153c67363eeSNikos Nikoleris 154c67363eeSNikos Nikoleris return ((mmfr0 >> shift) & 0xf) == val; 155c67363eeSNikos Nikoleris } 156c67363eeSNikos Nikoleris 157db328a24SAndrew Jones #endif /* !__ASSEMBLY__ */ 1587ee966e9SAndrew Jones #endif /* _ASMARM64_PROCESSOR_H_ */ 159