maar.h 4.2 KB

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