2014-07-14 10:32:15 +01:00
/*
* Copyright ( C ) 2014 Imagination Technologies
* Author : Paul Burton < paul . burton @ imgtec . com >
*
* This program is free software ; you can redistribute it and / or modify it
* under the terms of the GNU General Public License as published by the
* Free Software Foundation ; either version 2 of the License , or ( at your
* option ) any later version .
*/
# ifndef __MIPS_ASM_MIPS_MAAR_H__
# define __MIPS_ASM_MIPS_MAAR_H__
# include <asm/hazards.h>
# include <asm/mipsregs.h>
/**
* platform_maar_init ( ) - perform platform - level MAAR configuration
* @ num_pairs : The number of MAAR pairs present in the system .
*
* Platforms should implement this function such that it configures as many
* MAAR pairs as required , from 0 up to the maximum of num_pairs - 1 , and returns
* the number that were used . Any further MAARs will be configured to be
* invalid . The default implementation of this function will simply indicate
* that it has configured 0 MAAR pairs .
*
* Return : The number of MAAR pairs configured .
*/
2015-07-12 18:11:04 -05:00
unsigned platform_maar_init ( unsigned num_pairs ) ;
2014-07-14 10:32:15 +01:00
/**
* write_maar_pair ( ) - write to a pair of MAARs
* @ idx : The index of the pair ( ie . use MAARs idx * 2 & ( idx * 2 ) + 1 ) .
* @ lower : The lowest address that the MAAR pair will affect . Must be
* aligned to a 2 ^ 16 byte boundary .
* @ upper : The highest address that the MAAR pair will affect . Must be
* aligned to one byte before a 2 ^ 16 byte boundary .
* @ attrs : The accessibility attributes to program , eg . MIPS_MAAR_S . The
* MIPS_MAAR_V attribute will automatically be set .
*
* Program the pair of MAAR registers specified by idx to apply the attributes
* specified by attrs to the range of addresses from lower to higher .
*/
static inline void write_maar_pair ( unsigned idx , phys_addr_t lower ,
phys_addr_t upper , unsigned attrs )
{
/* Addresses begin at bit 16, but are shifted right 4 bits */
BUG_ON ( lower & ( 0xffff | ~ ( MIPS_MAAR_ADDR < < 4 ) ) ) ;
BUG_ON ( ( ( upper & 0xffff ) ! = 0xffff )
| | ( ( upper & ~ 0xffffull ) & ~ ( MIPS_MAAR_ADDR < < 4 ) ) ) ;
/* Automatically set MIPS_MAAR_V */
attrs | = MIPS_MAAR_V ;
/* Write the upper address & attributes (only MIPS_MAAR_V matters) */
write_c0_maari ( idx < < 1 ) ;
back_to_back_c0_hazard ( ) ;
write_c0_maar ( ( ( upper > > 4 ) & MIPS_MAAR_ADDR ) | attrs ) ;
back_to_back_c0_hazard ( ) ;
/* Write the lower address & attributes */
write_c0_maari ( ( idx < < 1 ) | 0x1 ) ;
back_to_back_c0_hazard ( ) ;
write_c0_maar ( ( lower > > 4 ) | attrs ) ;
back_to_back_c0_hazard ( ) ;
}
/**
* struct maar_config - MAAR configuration data
* @ lower : The lowest address that the MAAR pair will affect . Must be
* aligned to a 2 ^ 16 byte boundary .
* @ upper : The highest address that the MAAR pair will affect . Must be
* aligned to one byte before a 2 ^ 16 byte boundary .
* @ attrs : The accessibility attributes to program , eg . MIPS_MAAR_S . The
* MIPS_MAAR_V attribute will automatically be set .
*
* Describes the configuration of a pair of Memory Accessibility Attribute
* Registers - applying attributes from attrs to the range of physical
* addresses from lower to upper inclusive .
*/
struct maar_config {
phys_addr_t lower ;
phys_addr_t upper ;
unsigned attrs ;
} ;
/**
* maar_config ( ) - configure MAARs according to provided data
* @ cfg : Pointer to an array of struct maar_config .
* @ num_cfg : The number of structs in the cfg array .
* @ num_pairs : The number of MAAR pairs present in the system .
*
* Configures as many MAARs as are present and specified in the cfg
* array with the values taken from the cfg array .
*
* Return : The number of MAAR pairs configured .
*/
static inline unsigned maar_config ( const struct maar_config * cfg ,
unsigned num_cfg , unsigned num_pairs )
{
unsigned i ;
for ( i = 0 ; i < min ( num_cfg , num_pairs ) ; i + + )
write_maar_pair ( i , cfg [ i ] . lower , cfg [ i ] . upper , cfg [ i ] . attrs ) ;
return i ;
}
# endif /* __MIPS_ASM_MIPS_MAAR_H__ */