2019-06-04 10:11:33 +02:00
/* SPDX-License-Identifier: GPL-2.0-only */
2005-04-16 15:20:36 -07:00
/*
2008-08-02 10:55:55 +01:00
* arch / arm / include / asm / proc - fns . h
2005-04-16 15:20:36 -07:00
*
* Copyright ( C ) 1997 - 1999 Russell King
* Copyright ( C ) 2000 Deep Blue Solutions Ltd
*/
# ifndef __ASM_PROCFNS_H
# define __ASM_PROCFNS_H
# ifdef __KERNEL__
2011-02-06 15:32:24 +00:00
# include <asm/glue-proc.h>
# include <asm/page.h>
2005-04-16 15:20:36 -07:00
2011-02-06 15:32:24 +00:00
# ifndef __ASSEMBLY__
struct mm_struct ;
2005-04-16 15:20:36 -07:00
/*
2011-02-06 15:32:24 +00:00
* Don ' t change this structure - ASM code relies on it .
2005-04-16 15:20:36 -07:00
*/
2018-07-19 12:17:38 +01:00
struct processor {
2011-02-06 15:32:24 +00:00
/* MISC
* get data abort address / flags
*/
void ( * _data_abort ) ( unsigned long pc ) ;
/*
* Retrieve prefetch fault address
*/
unsigned long ( * _prefetch_abort ) ( unsigned long lr ) ;
/*
* Set up any processor specifics
*/
void ( * _proc_init ) ( void ) ;
2018-05-10 13:07:29 +01:00
/*
* Check for processor bugs
*/
void ( * check_bugs ) ( void ) ;
2011-02-06 15:32:24 +00:00
/*
* Disable any processor specifics
*/
void ( * _proc_fin ) ( void ) ;
/*
* Special stuff for a reset
*/
2017-04-03 19:37:46 +01:00
void ( * reset ) ( unsigned long addr , bool hvc ) __attribute__ ( ( noreturn ) ) ;
2011-02-06 15:32:24 +00:00
/*
* Idle the processor
*/
int ( * _do_idle ) ( void ) ;
/*
* Processor architecture specific
*/
/*
* clean a virtual address range from the
* D - cache without flushing the cache .
*/
void ( * dcache_clean_area ) ( void * addr , int size ) ;
/*
* Set the page table
*/
2012-07-16 15:37:06 -04:00
void ( * switch_mm ) ( phys_addr_t pgd_phys , struct mm_struct * mm ) ;
2011-02-06 15:32:24 +00:00
/*
* Set a possibly extended PTE . Non - extended PTEs should
* ignore ' ext ' .
*/
2011-11-22 17:30:29 +00:00
# ifdef CONFIG_ARM_LPAE
void ( * set_pte_ext ) ( pte_t * ptep , pte_t pte ) ;
# else
2011-02-06 15:32:24 +00:00
void ( * set_pte_ext ) ( pte_t * ptep , pte_t pte , unsigned int ext ) ;
2011-11-22 17:30:29 +00:00
# endif
2011-02-06 15:48:39 +00:00
/* Suspend/resume */
unsigned int suspend_size ;
void ( * do_suspend ) ( void * ) ;
void ( * do_resume ) ( void * ) ;
2018-07-19 12:17:38 +01:00
} ;
2005-04-16 15:20:36 -07:00
# ifndef MULTI_CPU
2018-07-19 12:17:38 +01:00
static inline void init_proc_vtable ( const struct processor * p )
{
}
2011-02-06 15:32:24 +00:00
extern void cpu_proc_init ( void ) ;
extern void cpu_proc_fin ( void ) ;
extern int cpu_do_idle ( void ) ;
extern void cpu_dcache_clean_area ( void * , int ) ;
2012-07-16 15:37:06 -04:00
extern void cpu_do_switch_mm ( phys_addr_t pgd_phys , struct mm_struct * mm ) ;
2011-11-22 17:30:29 +00:00
# ifdef CONFIG_ARM_LPAE
extern void cpu_set_pte_ext ( pte_t * ptep , pte_t pte ) ;
# else
2011-02-06 15:32:24 +00:00
extern void cpu_set_pte_ext ( pte_t * ptep , pte_t pte , unsigned int ext ) ;
2011-11-22 17:30:29 +00:00
# endif
2017-04-03 19:37:46 +01:00
extern void cpu_reset ( unsigned long addr , bool hvc ) __attribute__ ( ( noreturn ) ) ;
2011-09-01 11:52:33 +01:00
/* These three are private to arch/arm/kernel/suspend.c */
extern void cpu_do_suspend ( void * ) ;
extern void cpu_do_resume ( void * ) ;
2005-04-16 15:20:36 -07:00
# else
2011-09-01 11:52:33 +01:00
2018-07-19 12:17:38 +01:00
extern struct processor processor ;
2018-07-19 12:21:31 +01:00
# if defined(CONFIG_BIG_LITTLE) && defined(CONFIG_HARDEN_BRANCH_PREDICTOR)
# include <linux/smp.h>
/*
* This can ' t be a per - cpu variable because we need to access it before
* per - cpu has been initialised . We have a couple of functions that are
* called in a pre - emptible context , and so can ' t use smp_processor_id ( )
* there , hence PROC_TABLE ( ) . We insist in init_proc_vtable ( ) that the
* function pointers for these are identical across all CPUs .
*/
extern struct processor * cpu_vtable [ ] ;
# define PROC_VTABLE(f) cpu_vtable[smp_processor_id()]->f
# define PROC_TABLE(f) cpu_vtable[0]->f
static inline void init_proc_vtable ( const struct processor * p )
{
unsigned int cpu = smp_processor_id ( ) ;
* cpu_vtable [ cpu ] = * p ;
WARN_ON_ONCE ( cpu_vtable [ cpu ] - > dcache_clean_area ! =
cpu_vtable [ 0 ] - > dcache_clean_area ) ;
WARN_ON_ONCE ( cpu_vtable [ cpu ] - > set_pte_ext ! =
cpu_vtable [ 0 ] - > set_pte_ext ) ;
}
# else
2018-07-19 12:17:38 +01:00
# define PROC_VTABLE(f) processor.f
# define PROC_TABLE(f) processor.f
static inline void init_proc_vtable ( const struct processor * p )
{
processor = * p ;
}
2018-07-19 12:21:31 +01:00
# endif
2018-07-19 12:17:38 +01:00
# define cpu_proc_init PROC_VTABLE(_proc_init)
# define cpu_check_bugs PROC_VTABLE(check_bugs)
# define cpu_proc_fin PROC_VTABLE(_proc_fin)
# define cpu_reset PROC_VTABLE(reset)
# define cpu_do_idle PROC_VTABLE(_do_idle)
# define cpu_dcache_clean_area PROC_TABLE(dcache_clean_area)
# define cpu_set_pte_ext PROC_TABLE(set_pte_ext)
# define cpu_do_switch_mm PROC_VTABLE(switch_mm)
/* These two are private to arch/arm/kernel/suspend.c */
# define cpu_do_suspend PROC_VTABLE(do_suspend)
# define cpu_do_resume PROC_VTABLE(do_resume)
2005-04-16 15:20:36 -07:00
# endif
2011-02-06 15:48:39 +00:00
extern void cpu_resume ( void ) ;
2005-04-16 15:20:36 -07:00
# include <asm/memory.h>
2006-06-20 20:46:52 +01:00
# ifdef CONFIG_MMU
2005-04-16 15:20:36 -07:00
# define cpu_switch_mm(pgd,mm) cpu_do_switch_mm(virt_to_phys(pgd),mm)
2011-11-22 17:30:29 +00:00
# ifdef CONFIG_ARM_LPAE
2012-07-16 17:20:17 -04:00
# define cpu_get_ttbr(nr) \
( { \
u64 ttbr ; \
__asm__ ( " mrrc p15, " # nr " , %Q0, %R0, c2 " \
: " =r " ( ttbr ) ) ; \
ttbr ; \
} )
2011-11-22 17:30:29 +00:00
# define cpu_get_pgd() \
( { \
2012-07-16 17:20:17 -04:00
u64 pg = cpu_get_ttbr ( 0 ) ; \
2011-11-22 17:30:29 +00:00
pg & = ~ ( PTRS_PER_PGD * sizeof ( pgd_t ) - 1 ) ; \
( pgd_t * ) phys_to_virt ( pg ) ; \
} )
# else
2005-04-16 15:20:36 -07:00
# define cpu_get_pgd() \
( { \
unsigned long pg ; \
__asm__ ( " mrc p15, 0, %0, c2, c0, 0 " \
: " =r " ( pg ) : : " cc " ) ; \
pg & = ~ 0x3fff ; \
( pgd_t * ) phys_to_virt ( pg ) ; \
} )
2011-11-22 17:30:29 +00:00
# endif
2005-04-16 15:20:36 -07:00
2012-02-28 14:26:42 +00:00
# else /*!CONFIG_MMU */
# define cpu_switch_mm(pgd,mm) { }
2006-06-20 20:46:52 +01:00
# endif
2005-04-16 15:20:36 -07:00
# endif /* __ASSEMBLY__ */
# endif /* __KERNEL__ */
# endif /* __ASM_PROCFNS_H */