sbi_domain.h 8.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262
  1. /*
  2. * SPDX-License-Identifier: BSD-2-Clause
  3. *
  4. * Copyright (c) 2020 Western Digital Corporation or its affiliates.
  5. *
  6. * Authors:
  7. * Anup Patel <anup.patel@wdc.com>
  8. */
  9. #ifndef __SBI_DOMAIN_H__
  10. #define __SBI_DOMAIN_H__
  11. #include <sbi/sbi_types.h>
  12. #include <sbi/sbi_hartmask.h>
  13. struct sbi_scratch;
  14. /** Domain access types */
  15. enum sbi_domain_access {
  16. SBI_DOMAIN_READ = (1UL << 0),
  17. SBI_DOMAIN_WRITE = (1UL << 1),
  18. SBI_DOMAIN_EXECUTE = (1UL << 2),
  19. SBI_DOMAIN_MMIO = (1UL << 3)
  20. };
  21. /** Representation of OpenSBI domain memory region */
  22. struct sbi_domain_memregion {
  23. /**
  24. * Size of memory region as power of 2
  25. * It has to be minimum 3 and maximum __riscv_xlen
  26. */
  27. unsigned long order;
  28. /**
  29. * Base address of memory region
  30. * It must be 2^order aligned address
  31. */
  32. unsigned long base;
  33. /** Flags representing memory region attributes */
  34. #define SBI_DOMAIN_MEMREGION_M_READABLE (1UL << 0)
  35. #define SBI_DOMAIN_MEMREGION_M_WRITABLE (1UL << 1)
  36. #define SBI_DOMAIN_MEMREGION_M_EXECUTABLE (1UL << 2)
  37. #define SBI_DOMAIN_MEMREGION_SU_READABLE (1UL << 3)
  38. #define SBI_DOMAIN_MEMREGION_SU_WRITABLE (1UL << 4)
  39. #define SBI_DOMAIN_MEMREGION_SU_EXECUTABLE (1UL << 5)
  40. /** Bit to control if permissions are enforced on all modes */
  41. #define SBI_DOMAIN_MEMREGION_ENF_PERMISSIONS (1UL << 6)
  42. #define SBI_DOMAIN_MEMREGION_M_RWX \
  43. (SBI_DOMAIN_MEMREGION_M_READABLE | \
  44. SBI_DOMAIN_MEMREGION_M_WRITABLE | \
  45. SBI_DOMAIN_MEMREGION_M_EXECUTABLE)
  46. #define SBI_DOMAIN_MEMREGION_SU_RWX \
  47. (SBI_DOMAIN_MEMREGION_SU_READABLE | \
  48. SBI_DOMAIN_MEMREGION_SU_WRITABLE | \
  49. SBI_DOMAIN_MEMREGION_SU_EXECUTABLE)
  50. /* Unrestricted M-mode accesses but enfoced on SU-mode */
  51. #define SBI_DOMAIN_MEMREGION_READABLE \
  52. (SBI_DOMAIN_MEMREGION_SU_READABLE | \
  53. SBI_DOMAIN_MEMREGION_M_RWX)
  54. #define SBI_DOMAIN_MEMREGION_WRITEABLE \
  55. (SBI_DOMAIN_MEMREGION_SU_WRITABLE | \
  56. SBI_DOMAIN_MEMREGION_M_RWX)
  57. #define SBI_DOMAIN_MEMREGION_EXECUTABLE \
  58. (SBI_DOMAIN_MEMREGION_SU_EXECUTABLE | \
  59. SBI_DOMAIN_MEMREGION_M_RWX)
  60. /* Enforced accesses across all modes */
  61. #define SBI_DOMAIN_MEMREGION_ENF_READABLE \
  62. (SBI_DOMAIN_MEMREGION_SU_READABLE | \
  63. SBI_DOMAIN_MEMREGION_M_READABLE)
  64. #define SBI_DOMAIN_MEMREGION_ENF_WRITABLE \
  65. (SBI_DOMAIN_MEMREGION_SU_WRITABLE | \
  66. SBI_DOMAIN_MEMREGION_M_WRITABLE)
  67. #define SBI_DOMAIN_MEMREGION_ENF_EXECUTABLE \
  68. (SBI_DOMAIN_MEMREGION_SU_EXECUTABLE | \
  69. SBI_DOMAIN_MEMREGION_M_EXECUTABLE)
  70. #define SBI_DOMAIN_MEMREGION_ACCESS_MASK (0x3fUL)
  71. #define SBI_DOMAIN_MEMREGION_M_ACCESS_MASK (0x7UL)
  72. #define SBI_DOMAIN_MEMREGION_SU_ACCESS_MASK (0x38UL)
  73. #define SBI_DOMAIN_MEMREGION_SU_ACCESS_SHIFT (3)
  74. #define SBI_DOMAIN_MEMREGION_MMIO (1UL << 31)
  75. unsigned long flags;
  76. };
  77. /** Maximum number of domains */
  78. #define SBI_DOMAIN_MAX_INDEX 32
  79. /** Representation of OpenSBI domain */
  80. struct sbi_domain {
  81. /**
  82. * Logical index of this domain
  83. * Note: This set by sbi_domain_finalize() in the coldboot path
  84. */
  85. u32 index;
  86. /**
  87. * HARTs assigned to this domain
  88. * Note: This set by sbi_domain_init() and sbi_domain_finalize()
  89. * in the coldboot path
  90. */
  91. struct sbi_hartmask assigned_harts;
  92. /** Name of this domain */
  93. char name[64];
  94. /** Possible HARTs in this domain */
  95. const struct sbi_hartmask *possible_harts;
  96. /** Array of memory regions terminated by a region with order zero */
  97. struct sbi_domain_memregion *regions;
  98. /** HART id of the HART booting this domain */
  99. u32 boot_hartid;
  100. /** Arg1 (or 'a1' register) of next booting stage for this domain */
  101. unsigned long next_arg1;
  102. /** Address of next booting stage for this domain */
  103. unsigned long next_addr;
  104. /** Privilege mode of next booting stage for this domain */
  105. unsigned long next_mode;
  106. /** Is domain allowed to reset the system */
  107. bool system_reset_allowed;
  108. /** Is domain allowed to suspend the system */
  109. bool system_suspend_allowed;
  110. };
  111. /** The root domain instance */
  112. extern struct sbi_domain root;
  113. /** HART id to domain table */
  114. extern struct sbi_domain *hartid_to_domain_table[];
  115. /** Get pointer to sbi_domain from HART id */
  116. #define sbi_hartid_to_domain(__hartid) \
  117. hartid_to_domain_table[__hartid]
  118. /** Get pointer to sbi_domain for current HART */
  119. #define sbi_domain_thishart_ptr() \
  120. sbi_hartid_to_domain(current_hartid())
  121. /** Index to domain table */
  122. extern struct sbi_domain *domidx_to_domain_table[];
  123. /** Get pointer to sbi_domain from index */
  124. #define sbi_index_to_domain(__index) \
  125. domidx_to_domain_table[__index]
  126. /** Iterate over each domain */
  127. #define sbi_domain_for_each(__i, __d) \
  128. for ((__i) = 0; ((__d) = sbi_index_to_domain(__i)); (__i)++)
  129. /** Iterate over each memory region of a domain */
  130. #define sbi_domain_for_each_memregion(__d, __r) \
  131. for ((__r) = (__d)->regions; (__r)->order; (__r)++)
  132. /**
  133. * Check whether given HART is assigned to specified domain
  134. * @param dom pointer to domain
  135. * @param hartid the HART ID
  136. * @return true if HART is assigned to domain otherwise false
  137. */
  138. bool sbi_domain_is_assigned_hart(const struct sbi_domain *dom, u32 hartid);
  139. /**
  140. * Get ulong assigned HART mask for given domain and HART base ID
  141. * @param dom pointer to domain
  142. * @param hbase the HART base ID
  143. * @return ulong possible HART mask
  144. * Note: the return ulong mask will be set to zero on failure.
  145. */
  146. ulong sbi_domain_get_assigned_hartmask(const struct sbi_domain *dom,
  147. ulong hbase);
  148. /**
  149. * Initialize a domain memory region based on it's physical
  150. * address and size.
  151. *
  152. * @param addr start physical address of memory region
  153. * @param size physical size of memory region
  154. * @param flags memory region flags
  155. * @param reg pointer to memory region being initialized
  156. */
  157. void sbi_domain_memregion_init(unsigned long addr,
  158. unsigned long size,
  159. unsigned long flags,
  160. struct sbi_domain_memregion *reg);
  161. /**
  162. * Check whether we can access specified address for given mode and
  163. * memory region flags under a domain
  164. * @param dom pointer to domain
  165. * @param addr the address to be checked
  166. * @param mode the privilege mode of access
  167. * @param access_flags bitmask of domain access types (enum sbi_domain_access)
  168. * @return true if access allowed otherwise false
  169. */
  170. bool sbi_domain_check_addr(const struct sbi_domain *dom,
  171. unsigned long addr, unsigned long mode,
  172. unsigned long access_flags);
  173. /**
  174. * Check whether we can access specified address range for given mode and
  175. * memory region flags under a domain
  176. * @param dom pointer to domain
  177. * @param addr the start of the address range to be checked
  178. * @param size the size of the address range to be checked
  179. * @param mode the privilege mode of access
  180. * @param access_flags bitmask of domain access types (enum sbi_domain_access)
  181. * @return TRUE if access allowed otherwise FALSE
  182. */
  183. bool sbi_domain_check_addr_range(const struct sbi_domain *dom,
  184. unsigned long addr, unsigned long size,
  185. unsigned long mode,
  186. unsigned long access_flags);
  187. /** Dump domain details on the console */
  188. void sbi_domain_dump(const struct sbi_domain *dom, const char *suffix);
  189. /** Dump all domain details on the console */
  190. void sbi_domain_dump_all(const char *suffix);
  191. /**
  192. * Register a new domain
  193. * @param dom pointer to domain
  194. * @param assign_mask pointer to HART mask of HARTs assigned to the domain
  195. *
  196. * @return 0 on success and negative error code on failure
  197. */
  198. int sbi_domain_register(struct sbi_domain *dom,
  199. const struct sbi_hartmask *assign_mask);
  200. /**
  201. * Add a memory region to the root domain
  202. * @param reg pointer to the memory region to be added
  203. *
  204. * @return 0 on success
  205. * @return SBI_EALREADY if memory region conflicts with the existing one
  206. * @return SBI_EINVAL otherwise
  207. */
  208. int sbi_domain_root_add_memregion(const struct sbi_domain_memregion *reg);
  209. /**
  210. * Add a memory range with its flags to the root domain
  211. * @param addr start physical address of memory range
  212. * @param size physical size of memory range
  213. * @param align alignment of memory region
  214. * @param region_flags memory range flags
  215. *
  216. * @return 0 on success
  217. * @return SBI_EALREADY if memory region conflicts with the existing one
  218. * @return SBI_EINVAL otherwise
  219. */
  220. int sbi_domain_root_add_memrange(unsigned long addr, unsigned long size,
  221. unsigned long align, unsigned long region_flags);
  222. /** Finalize domain tables and startup non-root domains */
  223. int sbi_domain_finalize(struct sbi_scratch *scratch, u32 cold_hartid);
  224. /** Initialize domains */
  225. int sbi_domain_init(struct sbi_scratch *scratch, u32 cold_hartid);
  226. #endif