Back to home page

OSCL-LXR

 
 

    


0001 /* SPDX-License-Identifier: GPL-2.0-or-later */
0002 /*
0003  * Copyright (C) 2014 Imagination Technologies
0004  * Author: Paul Burton <paul.burton@mips.com>
0005  */
0006 
0007 #ifndef __MIPS_ASM_MIPS_MAAR_H__
0008 #define __MIPS_ASM_MIPS_MAAR_H__
0009 
0010 #include <asm/hazards.h>
0011 #include <asm/mipsregs.h>
0012 
0013 /**
0014  * platform_maar_init() - perform platform-level MAAR configuration
0015  * @num_pairs:  The number of MAAR pairs present in the system.
0016  *
0017  * Platforms should implement this function such that it configures as many
0018  * MAAR pairs as required, from 0 up to the maximum of num_pairs-1, and returns
0019  * the number that were used. Any further MAARs will be configured to be
0020  * invalid. The default implementation of this function will simply indicate
0021  * that it has configured 0 MAAR pairs.
0022  *
0023  * Return:  The number of MAAR pairs configured.
0024  */
0025 unsigned platform_maar_init(unsigned num_pairs);
0026 
0027 /**
0028  * write_maar_pair() - write to a pair of MAARs
0029  * @idx:    The index of the pair (ie. use MAARs idx*2 & (idx*2)+1).
0030  * @lower:  The lowest address that the MAAR pair will affect. Must be
0031  *      aligned to a 2^16 byte boundary.
0032  * @upper:  The highest address that the MAAR pair will affect. Must be
0033  *      aligned to one byte before a 2^16 byte boundary.
0034  * @attrs:  The accessibility attributes to program, eg. MIPS_MAAR_S. The
0035  *      MIPS_MAAR_VL/MIPS_MAAR_VH attributes will automatically be set.
0036  *
0037  * Program the pair of MAAR registers specified by idx to apply the attributes
0038  * specified by attrs to the range of addresses from lower to higher.
0039  */
0040 static inline void write_maar_pair(unsigned idx, phys_addr_t lower,
0041                    phys_addr_t upper, unsigned attrs)
0042 {
0043     /* Addresses begin at bit 16, but are shifted right 4 bits */
0044     BUG_ON(lower & (0xffff | ~(MIPS_MAAR_ADDR << 4)));
0045     BUG_ON(((upper & 0xffff) != 0xffff)
0046         || ((upper & ~0xffffull) & ~(MIPS_MAAR_ADDR << 4)));
0047 
0048     /* Automatically set MIPS_MAAR_VL */
0049     attrs |= MIPS_MAAR_VL;
0050 
0051     /*
0052      * Write the upper address & attributes (both MIPS_MAAR_VL and
0053      * MIPS_MAAR_VH matter)
0054      */
0055     write_c0_maari(idx << 1);
0056     back_to_back_c0_hazard();
0057     write_c0_maar(((upper >> 4) & MIPS_MAAR_ADDR) | attrs);
0058     back_to_back_c0_hazard();
0059 #ifdef CONFIG_XPA
0060     upper >>= MIPS_MAARX_ADDR_SHIFT;
0061     writex_c0_maar(((upper >> 4) & MIPS_MAARX_ADDR) | MIPS_MAARX_VH);
0062     back_to_back_c0_hazard();
0063 #endif
0064 
0065     /* Write the lower address & attributes */
0066     write_c0_maari((idx << 1) | 0x1);
0067     back_to_back_c0_hazard();
0068     write_c0_maar((lower >> 4) | attrs);
0069     back_to_back_c0_hazard();
0070 #ifdef CONFIG_XPA
0071     lower >>= MIPS_MAARX_ADDR_SHIFT;
0072     writex_c0_maar(((lower >> 4) & MIPS_MAARX_ADDR) | MIPS_MAARX_VH);
0073     back_to_back_c0_hazard();
0074 #endif
0075 }
0076 
0077 /**
0078  * maar_init() - initialise MAARs
0079  *
0080  * Performs initialisation of MAARs for the current CPU, making use of the
0081  * platforms implementation of platform_maar_init where necessary and
0082  * duplicating the setup it provides on secondary CPUs.
0083  */
0084 extern void maar_init(void);
0085 
0086 /**
0087  * struct maar_config - MAAR configuration data
0088  * @lower:  The lowest address that the MAAR pair will affect. Must be
0089  *      aligned to a 2^16 byte boundary.
0090  * @upper:  The highest address that the MAAR pair will affect. Must be
0091  *      aligned to one byte before a 2^16 byte boundary.
0092  * @attrs:  The accessibility attributes to program, eg. MIPS_MAAR_S. The
0093  *      MIPS_MAAR_VL attribute will automatically be set.
0094  *
0095  * Describes the configuration of a pair of Memory Accessibility Attribute
0096  * Registers - applying attributes from attrs to the range of physical
0097  * addresses from lower to upper inclusive.
0098  */
0099 struct maar_config {
0100     phys_addr_t lower;
0101     phys_addr_t upper;
0102     unsigned attrs;
0103 };
0104 
0105 /**
0106  * maar_config() - configure MAARs according to provided data
0107  * @cfg:    Pointer to an array of struct maar_config.
0108  * @num_cfg:    The number of structs in the cfg array.
0109  * @num_pairs:  The number of MAAR pairs present in the system.
0110  *
0111  * Configures as many MAARs as are present and specified in the cfg
0112  * array with the values taken from the cfg array.
0113  *
0114  * Return:  The number of MAAR pairs configured.
0115  */
0116 static inline unsigned maar_config(const struct maar_config *cfg,
0117                    unsigned num_cfg, unsigned num_pairs)
0118 {
0119     unsigned i;
0120 
0121     for (i = 0; i < min(num_cfg, num_pairs); i++)
0122         write_maar_pair(i, cfg[i].lower, cfg[i].upper, cfg[i].attrs);
0123 
0124     return i;
0125 }
0126 
0127 #endif /* __MIPS_ASM_MIPS_MAAR_H__ */