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 * Disable any processor specifics 41 */ 42 void (*_proc_fin)(void); 43 /* 44 * Special stuff for a reset 45 */ 46 void (*reset)(unsigned long addr) __attribute__((noreturn)); 47 /* 48 * Idle the processor 49 */ 50 int (*_do_idle)(void); 51 /* 52 * Processor architecture specific 53 */ 54 /* 55 * clean a virtual address range from the 56 * D-cache without flushing the cache. 57 */ 58 void (*dcache_clean_area)(void *addr, int size); 59 60 /* 61 * Set the page table 62 */ 63 void (*switch_mm)(phys_addr_t pgd_phys, struct mm_struct *mm); 64 /* 65 * Set a possibly extended PTE. Non-extended PTEs should 66 * ignore 'ext'. 67 */ 68 #ifdef CONFIG_ARM_LPAE 69 void (*set_pte_ext)(pte_t *ptep, pte_t pte); 70 #else 71 void (*set_pte_ext)(pte_t *ptep, pte_t pte, unsigned int ext); 72 #endif 73 74 /* Suspend/resume */ 75 unsigned int suspend_size; 76 void (*do_suspend)(void *); 77 void (*do_resume)(void *); 78 } processor; 79 80 #ifndef MULTI_CPU 81 extern void cpu_proc_init(void); 82 extern void cpu_proc_fin(void); 83 extern int cpu_do_idle(void); 84 extern void cpu_dcache_clean_area(void *, int); 85 extern void cpu_do_switch_mm(phys_addr_t pgd_phys, struct mm_struct *mm); 86 #ifdef CONFIG_ARM_LPAE 87 extern void cpu_set_pte_ext(pte_t *ptep, pte_t pte); 88 #else 89 extern void cpu_set_pte_ext(pte_t *ptep, pte_t pte, unsigned int ext); 90 #endif 91 extern void cpu_reset(unsigned long addr) __attribute__((noreturn)); 92 93 /* These three are private to arch/arm/kernel/suspend.c */ 94 extern void cpu_do_suspend(void *); 95 extern void cpu_do_resume(void *); 96 #else 97 #define cpu_proc_init processor._proc_init 98 #define cpu_proc_fin processor._proc_fin 99 #define cpu_reset processor.reset 100 #define cpu_do_idle processor._do_idle 101 #define cpu_dcache_clean_area processor.dcache_clean_area 102 #define cpu_set_pte_ext processor.set_pte_ext 103 #define cpu_do_switch_mm processor.switch_mm 104 105 /* These three are private to arch/arm/kernel/suspend.c */ 106 #define cpu_do_suspend processor.do_suspend 107 #define cpu_do_resume processor.do_resume 108 #endif 109 110 extern void cpu_resume(void); 111 112 #include <asm/memory.h> 113 114 #ifdef CONFIG_MMU 115 116 #define cpu_switch_mm(pgd,mm) cpu_do_switch_mm(virt_to_phys(pgd),mm) 117 118 #ifdef CONFIG_ARM_LPAE 119 120 #define cpu_get_ttbr(nr) \ 121 ({ \ 122 u64 ttbr; \ 123 __asm__("mrrc p15, " #nr ", %Q0, %R0, c2" \ 124 : "=r" (ttbr)); \ 125 ttbr; \ 126 }) 127 128 #define cpu_set_ttbr(nr, val) \ 129 do { \ 130 u64 ttbr = val; \ 131 __asm__("mcrr p15, " #nr ", %Q0, %R0, c2" \ 132 : : "r" (ttbr)); \ 133 } while (0) 134 135 #define cpu_get_pgd() \ 136 ({ \ 137 u64 pg = cpu_get_ttbr(0); \ 138 pg &= ~(PTRS_PER_PGD*sizeof(pgd_t)-1); \ 139 (pgd_t *)phys_to_virt(pg); \ 140 }) 141 #else 142 #define cpu_get_pgd() \ 143 ({ \ 144 unsigned long pg; \ 145 __asm__("mrc p15, 0, %0, c2, c0, 0" \ 146 : "=r" (pg) : : "cc"); \ 147 pg &= ~0x3fff; \ 148 (pgd_t *)phys_to_virt(pg); \ 149 }) 150 #endif 151 152 #else /*!CONFIG_MMU */ 153 154 #define cpu_switch_mm(pgd,mm) { } 155 156 #endif 157 158 #endif /* __ASSEMBLY__ */ 159 #endif /* __KERNEL__ */ 160 #endif /* __ASM_PROCFNS_H */ 161