1 /* SPDX-License-Identifier: GPL-2.0-or-later */ 2 /* 3 * Copyright (C) 2014 Imagination Technologies 4 * Author: Paul Burton <paul.burton@mips.com> 5 */ 6 7 #ifndef __MIPS_ASM_MIPS_MAAR_H__ 8 #define __MIPS_ASM_MIPS_MAAR_H__ 9 10 #include <asm/hazards.h> 11 #include <asm/mipsregs.h> 12 13 /** 14 * platform_maar_init() - perform platform-level MAAR configuration 15 * @num_pairs: The number of MAAR pairs present in the system. 16 * 17 * Platforms should implement this function such that it configures as many 18 * MAAR pairs as required, from 0 up to the maximum of num_pairs-1, and returns 19 * the number that were used. Any further MAARs will be configured to be 20 * invalid. The default implementation of this function will simply indicate 21 * that it has configured 0 MAAR pairs. 22 * 23 * Return: The number of MAAR pairs configured. 24 */ 25 unsigned platform_maar_init(unsigned num_pairs); 26 27 /** 28 * write_maar_pair() - write to a pair of MAARs 29 * @idx: The index of the pair (ie. use MAARs idx*2 & (idx*2)+1). 30 * @lower: The lowest address that the MAAR pair will affect. Must be 31 * aligned to a 2^16 byte boundary. 32 * @upper: The highest address that the MAAR pair will affect. Must be 33 * aligned to one byte before a 2^16 byte boundary. 34 * @attrs: The accessibility attributes to program, eg. MIPS_MAAR_S. The 35 * MIPS_MAAR_VL attribute will automatically be set. 36 * 37 * Program the pair of MAAR registers specified by idx to apply the attributes 38 * specified by attrs to the range of addresses from lower to higher. 39 */ 40 static inline void write_maar_pair(unsigned idx, phys_addr_t lower, 41 phys_addr_t upper, unsigned attrs) 42 { 43 /* Addresses begin at bit 16, but are shifted right 4 bits */ 44 BUG_ON(lower & (0xffff | ~(MIPS_MAAR_ADDR << 4))); 45 BUG_ON(((upper & 0xffff) != 0xffff) 46 || ((upper & ~0xffffull) & ~(MIPS_MAAR_ADDR << 4))); 47 48 /* Automatically set MIPS_MAAR_VL */ 49 attrs |= MIPS_MAAR_VL; 50 51 /* Write the upper address & attributes (only MIPS_MAAR_VL matters) */ 52 write_c0_maari(idx << 1); 53 back_to_back_c0_hazard(); 54 write_c0_maar(((upper >> 4) & MIPS_MAAR_ADDR) | attrs); 55 back_to_back_c0_hazard(); 56 57 /* Write the lower address & attributes */ 58 write_c0_maari((idx << 1) | 0x1); 59 back_to_back_c0_hazard(); 60 write_c0_maar((lower >> 4) | attrs); 61 back_to_back_c0_hazard(); 62 } 63 64 /** 65 * maar_init() - initialise MAARs 66 * 67 * Performs initialisation of MAARs for the current CPU, making use of the 68 * platforms implementation of platform_maar_init where necessary and 69 * duplicating the setup it provides on secondary CPUs. 70 */ 71 extern void maar_init(void); 72 73 /** 74 * struct maar_config - MAAR configuration data 75 * @lower: The lowest address that the MAAR pair will affect. Must be 76 * aligned to a 2^16 byte boundary. 77 * @upper: The highest address that the MAAR pair will affect. Must be 78 * aligned to one byte before a 2^16 byte boundary. 79 * @attrs: The accessibility attributes to program, eg. MIPS_MAAR_S. The 80 * MIPS_MAAR_VL attribute will automatically be set. 81 * 82 * Describes the configuration of a pair of Memory Accessibility Attribute 83 * Registers - applying attributes from attrs to the range of physical 84 * addresses from lower to upper inclusive. 85 */ 86 struct maar_config { 87 phys_addr_t lower; 88 phys_addr_t upper; 89 unsigned attrs; 90 }; 91 92 /** 93 * maar_config() - configure MAARs according to provided data 94 * @cfg: Pointer to an array of struct maar_config. 95 * @num_cfg: The number of structs in the cfg array. 96 * @num_pairs: The number of MAAR pairs present in the system. 97 * 98 * Configures as many MAARs as are present and specified in the cfg 99 * array with the values taken from the cfg array. 100 * 101 * Return: The number of MAAR pairs configured. 102 */ 103 static inline unsigned maar_config(const struct maar_config *cfg, 104 unsigned num_cfg, unsigned num_pairs) 105 { 106 unsigned i; 107 108 for (i = 0; i < min(num_cfg, num_pairs); i++) 109 write_maar_pair(i, cfg[i].lower, cfg[i].upper, cfg[i].attrs); 110 111 return i; 112 } 113 114 #endif /* __MIPS_ASM_MIPS_MAAR_H__ */ 115