1 /* 2 * arch/arm/include/asm/proc-fns.h 3 * 4 * Copyright (C) 1997-1999 Russell King 5 * Copyright (C) 2000 Deep Blue Solutions Ltd 6 * 7 * This program is free software; you can redistribute it and/or modify 8 * it under the terms of the GNU General Public License version 2 as 9 * published by the Free Software Foundation. 10 */ 11 #ifndef __ASM_PROCFNS_H 12 #define __ASM_PROCFNS_H 13 14 #ifdef __KERNEL__ 15 16 #include <asm/glue-proc.h> 17 #include <asm/page.h> 18 19 #ifndef __ASSEMBLY__ 20 21 struct mm_struct; 22 23 /* 24 * Don't change this structure - ASM code relies on it. 25 */ 26 extern struct processor { 27 /* MISC 28 * get data abort address/flags 29 */ 30 void (*_data_abort)(unsigned long pc); 31 /* 32 * Retrieve prefetch fault address 33 */ 34 unsigned long (*_prefetch_abort)(unsigned long lr); 35 /* 36 * Set up any processor specifics 37 */ 38 void (*_proc_init)(void); 39 /* 40 * Check for processor bugs 41 */ 42 void (*check_bugs)(void); 43 /* 44 * Disable any processor specifics 45 */ 46 void (*_proc_fin)(void); 47 /* 48 * Special stuff for a reset 49 */ 50 void (*reset)(unsigned long addr, bool hvc) __attribute__((noreturn)); 51 /* 52 * Idle the processor 53 */ 54 int (*_do_idle)(void); 55 /* 56 * Processor architecture specific 57 */ 58 /* 59 * clean a virtual address range from the 60 * D-cache without flushing the cache. 61 */ 62 void (*dcache_clean_area)(void *addr, int size); 63 64 /* 65 * Set the page table 66 */ 67 void (*switch_mm)(phys_addr_t pgd_phys, struct mm_struct *mm); 68 /* 69 * Set a possibly extended PTE. Non-extended PTEs should 70 * ignore 'ext'. 71 */ 72 #ifdef CONFIG_ARM_LPAE 73 void (*set_pte_ext)(pte_t *ptep, pte_t pte); 74 #else 75 void (*set_pte_ext)(pte_t *ptep, pte_t pte, unsigned int ext); 76 #endif 77 78 /* Suspend/resume */ 79 unsigned int suspend_size; 80 void (*do_suspend)(void *); 81 void (*do_resume)(void *); 82 } processor; 83 84 #ifndef MULTI_CPU 85 extern void cpu_proc_init(void); 86 extern void cpu_proc_fin(void); 87 extern int cpu_do_idle(void); 88 extern void cpu_dcache_clean_area(void *, int); 89 extern void cpu_do_switch_mm(phys_addr_t pgd_phys, struct mm_struct *mm); 90 #ifdef CONFIG_ARM_LPAE 91 extern void cpu_set_pte_ext(pte_t *ptep, pte_t pte); 92 #else 93 extern void cpu_set_pte_ext(pte_t *ptep, pte_t pte, unsigned int ext); 94 #endif 95 extern void cpu_reset(unsigned long addr, bool hvc) __attribute__((noreturn)); 96 97 /* These three are private to arch/arm/kernel/suspend.c */ 98 extern void cpu_do_suspend(void *); 99 extern void cpu_do_resume(void *); 100 #else 101 #define cpu_proc_init processor._proc_init 102 #define cpu_proc_fin processor._proc_fin 103 #define cpu_reset processor.reset 104 #define cpu_do_idle processor._do_idle 105 #define cpu_dcache_clean_area processor.dcache_clean_area 106 #define cpu_set_pte_ext processor.set_pte_ext 107 #define cpu_do_switch_mm processor.switch_mm 108 109 /* These three are private to arch/arm/kernel/suspend.c */ 110 #define cpu_do_suspend processor.do_suspend 111 #define cpu_do_resume processor.do_resume 112 #endif 113 114 extern void cpu_resume(void); 115 116 #include <asm/memory.h> 117 118 #ifdef CONFIG_MMU 119 120 #define cpu_switch_mm(pgd,mm) cpu_do_switch_mm(virt_to_phys(pgd),mm) 121 122 #ifdef CONFIG_ARM_LPAE 123 124 #define cpu_get_ttbr(nr) \ 125 ({ \ 126 u64 ttbr; \ 127 __asm__("mrrc p15, " #nr ", %Q0, %R0, c2" \ 128 : "=r" (ttbr)); \ 129 ttbr; \ 130 }) 131 132 #define cpu_get_pgd() \ 133 ({ \ 134 u64 pg = cpu_get_ttbr(0); \ 135 pg &= ~(PTRS_PER_PGD*sizeof(pgd_t)-1); \ 136 (pgd_t *)phys_to_virt(pg); \ 137 }) 138 #else 139 #define cpu_get_pgd() \ 140 ({ \ 141 unsigned long pg; \ 142 __asm__("mrc p15, 0, %0, c2, c0, 0" \ 143 : "=r" (pg) : : "cc"); \ 144 pg &= ~0x3fff; \ 145 (pgd_t *)phys_to_virt(pg); \ 146 }) 147 #endif 148 149 #else /*!CONFIG_MMU */ 150 151 #define cpu_switch_mm(pgd,mm) { } 152 153 #endif 154 155 #endif /* __ASSEMBLY__ */ 156 #endif /* __KERNEL__ */ 157 #endif /* __ASM_PROCFNS_H */ 158