0001
0002
0003
0004
0005
0006
0007
0008 #ifndef __ASM_PROCFNS_H
0009 #define __ASM_PROCFNS_H
0010
0011 #ifdef __KERNEL__
0012
0013 #include <asm/glue-proc.h>
0014 #include <asm/page.h>
0015
0016 #ifndef __ASSEMBLY__
0017
0018 struct mm_struct;
0019
0020
0021
0022
0023 struct processor {
0024
0025
0026
0027 void (*_data_abort)(unsigned long pc);
0028
0029
0030
0031 unsigned long (*_prefetch_abort)(unsigned long lr);
0032
0033
0034
0035 void (*_proc_init)(void);
0036
0037
0038
0039 void (*check_bugs)(void);
0040
0041
0042
0043 void (*_proc_fin)(void);
0044
0045
0046
0047 void (*reset)(unsigned long addr, bool hvc) __attribute__((noreturn));
0048
0049
0050
0051 int (*_do_idle)(void);
0052
0053
0054
0055
0056
0057
0058
0059 void (*dcache_clean_area)(void *addr, int size);
0060
0061
0062
0063
0064 void (*switch_mm)(phys_addr_t pgd_phys, struct mm_struct *mm);
0065
0066
0067
0068
0069 #ifdef CONFIG_ARM_LPAE
0070 void (*set_pte_ext)(pte_t *ptep, pte_t pte);
0071 #else
0072 void (*set_pte_ext)(pte_t *ptep, pte_t pte, unsigned int ext);
0073 #endif
0074
0075
0076 unsigned int suspend_size;
0077 void (*do_suspend)(void *);
0078 void (*do_resume)(void *);
0079 };
0080
0081 #ifndef MULTI_CPU
0082 static inline void init_proc_vtable(const struct processor *p)
0083 {
0084 }
0085
0086 extern void cpu_proc_init(void);
0087 extern void cpu_proc_fin(void);
0088 extern int cpu_do_idle(void);
0089 extern void cpu_dcache_clean_area(void *, int);
0090 extern void cpu_do_switch_mm(phys_addr_t pgd_phys, struct mm_struct *mm);
0091 #ifdef CONFIG_ARM_LPAE
0092 extern void cpu_set_pte_ext(pte_t *ptep, pte_t pte);
0093 #else
0094 extern void cpu_set_pte_ext(pte_t *ptep, pte_t pte, unsigned int ext);
0095 #endif
0096 extern void cpu_reset(unsigned long addr, bool hvc) __attribute__((noreturn));
0097
0098
0099 extern void cpu_do_suspend(void *);
0100 extern void cpu_do_resume(void *);
0101 #else
0102
0103 extern struct processor processor;
0104 #if defined(CONFIG_BIG_LITTLE) && defined(CONFIG_HARDEN_BRANCH_PREDICTOR)
0105 #include <linux/smp.h>
0106
0107
0108
0109
0110
0111
0112
0113 extern struct processor *cpu_vtable[];
0114 #define PROC_VTABLE(f) cpu_vtable[smp_processor_id()]->f
0115 #define PROC_TABLE(f) cpu_vtable[0]->f
0116 static inline void init_proc_vtable(const struct processor *p)
0117 {
0118 unsigned int cpu = smp_processor_id();
0119 *cpu_vtable[cpu] = *p;
0120 WARN_ON_ONCE(cpu_vtable[cpu]->dcache_clean_area !=
0121 cpu_vtable[0]->dcache_clean_area);
0122 WARN_ON_ONCE(cpu_vtable[cpu]->set_pte_ext !=
0123 cpu_vtable[0]->set_pte_ext);
0124 }
0125 #else
0126 #define PROC_VTABLE(f) processor.f
0127 #define PROC_TABLE(f) processor.f
0128 static inline void init_proc_vtable(const struct processor *p)
0129 {
0130 processor = *p;
0131 }
0132 #endif
0133
0134 #define cpu_proc_init PROC_VTABLE(_proc_init)
0135 #define cpu_check_bugs PROC_VTABLE(check_bugs)
0136 #define cpu_proc_fin PROC_VTABLE(_proc_fin)
0137 #define cpu_reset PROC_VTABLE(reset)
0138 #define cpu_do_idle PROC_VTABLE(_do_idle)
0139 #define cpu_dcache_clean_area PROC_TABLE(dcache_clean_area)
0140 #define cpu_set_pte_ext PROC_TABLE(set_pte_ext)
0141 #define cpu_do_switch_mm PROC_VTABLE(switch_mm)
0142
0143
0144 #define cpu_do_suspend PROC_VTABLE(do_suspend)
0145 #define cpu_do_resume PROC_VTABLE(do_resume)
0146 #endif
0147
0148 extern void cpu_resume(void);
0149
0150 #include <asm/memory.h>
0151
0152 #ifdef CONFIG_MMU
0153
0154 #define cpu_switch_mm(pgd,mm) cpu_do_switch_mm(virt_to_phys(pgd),mm)
0155
0156 #ifdef CONFIG_ARM_LPAE
0157
0158 #define cpu_get_ttbr(nr) \
0159 ({ \
0160 u64 ttbr; \
0161 __asm__("mrrc p15, " #nr ", %Q0, %R0, c2" \
0162 : "=r" (ttbr)); \
0163 ttbr; \
0164 })
0165
0166 #define cpu_get_pgd() \
0167 ({ \
0168 u64 pg = cpu_get_ttbr(0); \
0169 pg &= ~(PTRS_PER_PGD*sizeof(pgd_t)-1); \
0170 (pgd_t *)phys_to_virt(pg); \
0171 })
0172 #else
0173 #define cpu_get_pgd() \
0174 ({ \
0175 unsigned long pg; \
0176 __asm__("mrc p15, 0, %0, c2, c0, 0" \
0177 : "=r" (pg) : : "cc"); \
0178 pg &= ~0x3fff; \
0179 (pgd_t *)phys_to_virt(pg); \
0180 })
0181 #endif
0182
0183 #else
0184
0185 #define cpu_switch_mm(pgd,mm) { }
0186
0187 #endif
0188
0189 #endif
0190 #endif
0191 #endif