14baa9922SRussell King /* 24baa9922SRussell King * arch/arm/include/asm/proc-fns.h 34baa9922SRussell King * 44baa9922SRussell King * Copyright (C) 1997-1999 Russell King 54baa9922SRussell King * Copyright (C) 2000 Deep Blue Solutions Ltd 64baa9922SRussell King * 74baa9922SRussell King * This program is free software; you can redistribute it and/or modify 84baa9922SRussell King * it under the terms of the GNU General Public License version 2 as 94baa9922SRussell King * published by the Free Software Foundation. 104baa9922SRussell King */ 114baa9922SRussell King #ifndef __ASM_PROCFNS_H 124baa9922SRussell King #define __ASM_PROCFNS_H 134baa9922SRussell King 144baa9922SRussell King #ifdef __KERNEL__ 154baa9922SRussell King 16753790e7SRussell King #include <asm/glue-proc.h> 17753790e7SRussell King #include <asm/page.h> 184baa9922SRussell King 194baa9922SRussell King #ifndef __ASSEMBLY__ 204baa9922SRussell King 21753790e7SRussell King struct mm_struct; 22753790e7SRussell King 23753790e7SRussell King /* 24753790e7SRussell King * Don't change this structure - ASM code relies on it. 25753790e7SRussell King */ 26e209950fSRussell King struct processor { 27753790e7SRussell King /* MISC 28753790e7SRussell King * get data abort address/flags 29753790e7SRussell King */ 30753790e7SRussell King void (*_data_abort)(unsigned long pc); 31753790e7SRussell King /* 32753790e7SRussell King * Retrieve prefetch fault address 33753790e7SRussell King */ 34753790e7SRussell King unsigned long (*_prefetch_abort)(unsigned long lr); 35753790e7SRussell King /* 36753790e7SRussell King * Set up any processor specifics 37753790e7SRussell King */ 38753790e7SRussell King void (*_proc_init)(void); 39753790e7SRussell King /* 409d3a0492SRussell King * Check for processor bugs 419d3a0492SRussell King */ 429d3a0492SRussell King void (*check_bugs)(void); 439d3a0492SRussell King /* 44753790e7SRussell King * Disable any processor specifics 45753790e7SRussell King */ 46753790e7SRussell King void (*_proc_fin)(void); 47753790e7SRussell King /* 48753790e7SRussell King * Special stuff for a reset 49753790e7SRussell King */ 509da5ac23SRussell King void (*reset)(unsigned long addr, bool hvc) __attribute__((noreturn)); 51753790e7SRussell King /* 52753790e7SRussell King * Idle the processor 53753790e7SRussell King */ 54753790e7SRussell King int (*_do_idle)(void); 55753790e7SRussell King /* 56753790e7SRussell King * Processor architecture specific 57753790e7SRussell King */ 58753790e7SRussell King /* 59753790e7SRussell King * clean a virtual address range from the 60753790e7SRussell King * D-cache without flushing the cache. 61753790e7SRussell King */ 62753790e7SRussell King void (*dcache_clean_area)(void *addr, int size); 63753790e7SRussell King 64753790e7SRussell King /* 65753790e7SRussell King * Set the page table 66753790e7SRussell King */ 6713f659b0SCyril Chemparathy void (*switch_mm)(phys_addr_t pgd_phys, struct mm_struct *mm); 68753790e7SRussell King /* 69753790e7SRussell King * Set a possibly extended PTE. Non-extended PTEs should 70753790e7SRussell King * ignore 'ext'. 71753790e7SRussell King */ 72da028779SCatalin Marinas #ifdef CONFIG_ARM_LPAE 73da028779SCatalin Marinas void (*set_pte_ext)(pte_t *ptep, pte_t pte); 74da028779SCatalin Marinas #else 75753790e7SRussell King void (*set_pte_ext)(pte_t *ptep, pte_t pte, unsigned int ext); 76da028779SCatalin Marinas #endif 77f6b0fa02SRussell King 78f6b0fa02SRussell King /* Suspend/resume */ 79f6b0fa02SRussell King unsigned int suspend_size; 80f6b0fa02SRussell King void (*do_suspend)(void *); 81f6b0fa02SRussell King void (*do_resume)(void *); 82e209950fSRussell King }; 83753790e7SRussell King 844baa9922SRussell King #ifndef MULTI_CPU 85e209950fSRussell King static inline void init_proc_vtable(const struct processor *p) 86e209950fSRussell King { 87e209950fSRussell King } 88e209950fSRussell King 89753790e7SRussell King extern void cpu_proc_init(void); 90753790e7SRussell King extern void cpu_proc_fin(void); 91753790e7SRussell King extern int cpu_do_idle(void); 92753790e7SRussell King extern void cpu_dcache_clean_area(void *, int); 9313f659b0SCyril Chemparathy extern void cpu_do_switch_mm(phys_addr_t pgd_phys, struct mm_struct *mm); 94da028779SCatalin Marinas #ifdef CONFIG_ARM_LPAE 95da028779SCatalin Marinas extern void cpu_set_pte_ext(pte_t *ptep, pte_t pte); 96da028779SCatalin Marinas #else 97753790e7SRussell King extern void cpu_set_pte_ext(pte_t *ptep, pte_t pte, unsigned int ext); 98da028779SCatalin Marinas #endif 999da5ac23SRussell King extern void cpu_reset(unsigned long addr, bool hvc) __attribute__((noreturn)); 100abda1bd5SRussell King 101abda1bd5SRussell King /* These three are private to arch/arm/kernel/suspend.c */ 102abda1bd5SRussell King extern void cpu_do_suspend(void *); 103abda1bd5SRussell King extern void cpu_do_resume(void *); 1044baa9922SRussell King #else 105abda1bd5SRussell King 106e209950fSRussell King extern struct processor processor; 107e209950fSRussell King #define PROC_VTABLE(f) processor.f 108e209950fSRussell King #define PROC_TABLE(f) processor.f 109e209950fSRussell King static inline void init_proc_vtable(const struct processor *p) 110e209950fSRussell King { 111e209950fSRussell King processor = *p; 112e209950fSRussell King } 113e209950fSRussell King 114e209950fSRussell King #define cpu_proc_init PROC_VTABLE(_proc_init) 115e209950fSRussell King #define cpu_check_bugs PROC_VTABLE(check_bugs) 116e209950fSRussell King #define cpu_proc_fin PROC_VTABLE(_proc_fin) 117e209950fSRussell King #define cpu_reset PROC_VTABLE(reset) 118e209950fSRussell King #define cpu_do_idle PROC_VTABLE(_do_idle) 119e209950fSRussell King #define cpu_dcache_clean_area PROC_TABLE(dcache_clean_area) 120e209950fSRussell King #define cpu_set_pte_ext PROC_TABLE(set_pte_ext) 121e209950fSRussell King #define cpu_do_switch_mm PROC_VTABLE(switch_mm) 122e209950fSRussell King 123e209950fSRussell King /* These two are private to arch/arm/kernel/suspend.c */ 124e209950fSRussell King #define cpu_do_suspend PROC_VTABLE(do_suspend) 125e209950fSRussell King #define cpu_do_resume PROC_VTABLE(do_resume) 1264baa9922SRussell King #endif 1274baa9922SRussell King 128f6b0fa02SRussell King extern void cpu_resume(void); 129f6b0fa02SRussell King 1304baa9922SRussell King #include <asm/memory.h> 1314baa9922SRussell King 1324baa9922SRussell King #ifdef CONFIG_MMU 1334baa9922SRussell King 1344baa9922SRussell King #define cpu_switch_mm(pgd,mm) cpu_do_switch_mm(virt_to_phys(pgd),mm) 1354baa9922SRussell King 136da028779SCatalin Marinas #ifdef CONFIG_ARM_LPAE 1371fc84ae8SCyril Chemparathy 1381fc84ae8SCyril Chemparathy #define cpu_get_ttbr(nr) \ 1391fc84ae8SCyril Chemparathy ({ \ 1401fc84ae8SCyril Chemparathy u64 ttbr; \ 1411fc84ae8SCyril Chemparathy __asm__("mrrc p15, " #nr ", %Q0, %R0, c2" \ 1421fc84ae8SCyril Chemparathy : "=r" (ttbr)); \ 1431fc84ae8SCyril Chemparathy ttbr; \ 1441fc84ae8SCyril Chemparathy }) 1451fc84ae8SCyril Chemparathy 146da028779SCatalin Marinas #define cpu_get_pgd() \ 147da028779SCatalin Marinas ({ \ 1481fc84ae8SCyril Chemparathy u64 pg = cpu_get_ttbr(0); \ 149da028779SCatalin Marinas pg &= ~(PTRS_PER_PGD*sizeof(pgd_t)-1); \ 150da028779SCatalin Marinas (pgd_t *)phys_to_virt(pg); \ 151da028779SCatalin Marinas }) 152da028779SCatalin Marinas #else 1534baa9922SRussell King #define cpu_get_pgd() \ 1544baa9922SRussell King ({ \ 1554baa9922SRussell King unsigned long pg; \ 1564baa9922SRussell King __asm__("mrc p15, 0, %0, c2, c0, 0" \ 1574baa9922SRussell King : "=r" (pg) : : "cc"); \ 1584baa9922SRussell King pg &= ~0x3fff; \ 1594baa9922SRussell King (pgd_t *)phys_to_virt(pg); \ 1604baa9922SRussell King }) 161da028779SCatalin Marinas #endif 1624baa9922SRussell King 16302ed1c7bSWill Deacon #else /*!CONFIG_MMU */ 16402ed1c7bSWill Deacon 16502ed1c7bSWill Deacon #define cpu_switch_mm(pgd,mm) { } 16602ed1c7bSWill Deacon 1674baa9922SRussell King #endif 1684baa9922SRussell King 1694baa9922SRussell King #endif /* __ASSEMBLY__ */ 1704baa9922SRussell King #endif /* __KERNEL__ */ 1714baa9922SRussell King #endif /* __ASM_PROCFNS_H */ 172