1 #ifndef _ASMARM64_PROCESSOR_H_ 2 #define _ASMARM64_PROCESSOR_H_ 3 /* 4 * Copyright (C) 2014, Red Hat Inc, Andrew Jones <drjones@redhat.com> 5 * 6 * This work is licensed under the terms of the GNU LGPL, version 2. 7 */ 8 9 #ifndef __ASSEMBLY__ 10 #include <asm/ptrace.h> 11 #include <asm/esr.h> 12 #include <asm/sysreg.h> 13 #include <asm/barrier.h> 14 15 enum vector { 16 EL1T_SYNC, 17 EL1T_IRQ, 18 EL1T_FIQ, 19 EL1T_ERROR, 20 EL1H_SYNC, 21 EL1H_IRQ, 22 EL1H_FIQ, 23 EL1H_ERROR, 24 EL0_SYNC_64, 25 EL0_IRQ_64, 26 EL0_FIQ_64, 27 EL0_ERROR_64, 28 EL0_SYNC_32, 29 EL0_IRQ_32, 30 EL0_FIQ_32, 31 EL0_ERROR_32, 32 VECTOR_MAX, 33 }; 34 35 #define EC_MAX 64 36 37 typedef void (*vector_fn)(enum vector v, struct pt_regs *regs, 38 unsigned int esr); 39 typedef void (*exception_fn)(struct pt_regs *regs, unsigned int esr); 40 typedef void (*irq_handler_fn)(struct pt_regs *regs); 41 extern void install_vector_handler(enum vector v, vector_fn fn); 42 extern void install_exception_handler(enum vector v, unsigned int ec, 43 exception_fn fn); 44 extern void install_irq_handler(enum vector v, irq_handler_fn fn); 45 extern void default_vector_sync_handler(enum vector v, struct pt_regs *regs, 46 unsigned int esr); 47 extern void default_vector_irq_handler(enum vector v, struct pt_regs *regs, 48 unsigned int esr); 49 extern void vector_handlers_default_init(vector_fn *handlers); 50 51 extern void show_regs(struct pt_regs *regs); 52 extern bool get_far(unsigned int esr, unsigned long *far); 53 54 static inline unsigned long current_level(void) 55 { 56 unsigned long el; 57 asm volatile("mrs %0, CurrentEL" : "=r" (el)); 58 return el & 0xc; 59 } 60 61 static inline void local_irq_enable(void) 62 { 63 asm volatile("msr daifclr, #2" : : : "memory"); 64 } 65 66 static inline void local_irq_disable(void) 67 { 68 asm volatile("msr daifset, #2" : : : "memory"); 69 } 70 71 static inline uint64_t get_mpidr(void) 72 { 73 return read_sysreg(mpidr_el1); 74 } 75 76 #define MPIDR_HWID_BITMASK 0xff00ffffff 77 extern int mpidr_to_cpu(uint64_t mpidr); 78 79 #define MPIDR_LEVEL_SHIFT(level) \ 80 (((1 << level) >> 1) << 3) 81 #define MPIDR_AFFINITY_LEVEL(mpidr, level) \ 82 ((mpidr >> MPIDR_LEVEL_SHIFT(level)) & 0xff) 83 84 extern void start_usr(void (*func)(void *arg), void *arg, unsigned long sp_usr); 85 extern bool is_user(void); 86 extern bool __mmu_enabled(void); 87 88 static inline u64 get_cntvct(void) 89 { 90 isb(); 91 return read_sysreg(cntvct_el0); 92 } 93 94 static inline u32 get_cntfrq(void) 95 { 96 return read_sysreg(cntfrq_el0); 97 } 98 99 static inline u64 get_ctr(void) 100 { 101 return read_sysreg(ctr_el0); 102 } 103 104 static inline unsigned long get_id_aa64mmfr0_el1(void) 105 { 106 return read_sysreg(id_aa64mmfr0_el1); 107 } 108 109 #define ID_AA64MMFR0_TGRAN4_SHIFT 28 110 #define ID_AA64MMFR0_TGRAN64_SHIFT 24 111 #define ID_AA64MMFR0_TGRAN16_SHIFT 20 112 113 #define ID_AA64MMFR0_TGRAN4_SUPPORTED 0x0 114 #define ID_AA64MMFR0_TGRAN64_SUPPORTED 0x0 115 #define ID_AA64MMFR0_TGRAN16_SUPPORTED 0x1 116 117 static inline bool system_supports_granule(size_t granule) 118 { 119 u32 shift; 120 u32 val; 121 u64 mmfr0; 122 123 if (granule == SZ_4K) { 124 shift = ID_AA64MMFR0_TGRAN4_SHIFT; 125 val = ID_AA64MMFR0_TGRAN4_SUPPORTED; 126 } else if (granule == SZ_16K) { 127 shift = ID_AA64MMFR0_TGRAN16_SHIFT; 128 val = ID_AA64MMFR0_TGRAN16_SUPPORTED; 129 } else { 130 assert(granule == SZ_64K); 131 shift = ID_AA64MMFR0_TGRAN64_SHIFT; 132 val = ID_AA64MMFR0_TGRAN64_SUPPORTED; 133 } 134 135 mmfr0 = get_id_aa64mmfr0_el1(); 136 137 return ((mmfr0 >> shift) & 0xf) == val; 138 } 139 140 #endif /* !__ASSEMBLY__ */ 141 #endif /* _ASMARM64_PROCESSOR_H_ */ 142