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 */ 25unsigned 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/MIPS_MAAR_VH attributes 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 */ 40static 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 /* 52 * Write the upper address & attributes (both MIPS_MAAR_VL and 53 * MIPS_MAAR_VH matter) 54 */ 55 write_c0_maari(idx << 1); 56 back_to_back_c0_hazard(); 57 write_c0_maar(((upper >> 4) & MIPS_MAAR_ADDR) | attrs); 58 back_to_back_c0_hazard(); 59#ifdef CONFIG_XPA 60 upper >>= MIPS_MAARX_ADDR_SHIFT; 61 writex_c0_maar(((upper >> 4) & MIPS_MAARX_ADDR) | MIPS_MAARX_VH); 62 back_to_back_c0_hazard(); 63#endif 64 65 /* Write the lower address & attributes */ 66 write_c0_maari((idx << 1) | 0x1); 67 back_to_back_c0_hazard(); 68 write_c0_maar((lower >> 4) | attrs); 69 back_to_back_c0_hazard(); 70#ifdef CONFIG_XPA 71 lower >>= MIPS_MAARX_ADDR_SHIFT; 72 writex_c0_maar(((lower >> 4) & MIPS_MAARX_ADDR) | MIPS_MAARX_VH); 73 back_to_back_c0_hazard(); 74#endif 75} 76 77/** 78 * maar_init() - initialise MAARs 79 * 80 * Performs initialisation of MAARs for the current CPU, making use of the 81 * platforms implementation of platform_maar_init where necessary and 82 * duplicating the setup it provides on secondary CPUs. 83 */ 84extern void maar_init(void); 85 86/** 87 * struct maar_config - MAAR configuration data 88 * @lower: The lowest address that the MAAR pair will affect. Must be 89 * aligned to a 2^16 byte boundary. 90 * @upper: The highest address that the MAAR pair will affect. Must be 91 * aligned to one byte before a 2^16 byte boundary. 92 * @attrs: The accessibility attributes to program, eg. MIPS_MAAR_S. The 93 * MIPS_MAAR_VL attribute will automatically be set. 94 * 95 * Describes the configuration of a pair of Memory Accessibility Attribute 96 * Registers - applying attributes from attrs to the range of physical 97 * addresses from lower to upper inclusive. 98 */ 99struct maar_config { 100 phys_addr_t lower; 101 phys_addr_t upper; 102 unsigned attrs; 103}; 104 105/** 106 * maar_config() - configure MAARs according to provided data 107 * @cfg: Pointer to an array of struct maar_config. 108 * @num_cfg: The number of structs in the cfg array. 109 * @num_pairs: The number of MAAR pairs present in the system. 110 * 111 * Configures as many MAARs as are present and specified in the cfg 112 * array with the values taken from the cfg array. 113 * 114 * Return: The number of MAAR pairs configured. 115 */ 116static inline unsigned maar_config(const struct maar_config *cfg, 117 unsigned num_cfg, unsigned num_pairs) 118{ 119 unsigned i; 120 121 for (i = 0; i < min(num_cfg, num_pairs); i++) 122 write_maar_pair(i, cfg[i].lower, cfg[i].upper, cfg[i].attrs); 123 124 return i; 125} 126 127#endif /* __MIPS_ASM_MIPS_MAAR_H__ */ 128