sbi_domain.h 5.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187
  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_READABLE (1UL << 0)
  35. #define SBI_DOMAIN_MEMREGION_WRITEABLE (1UL << 1)
  36. #define SBI_DOMAIN_MEMREGION_EXECUTABLE (1UL << 2)
  37. #define SBI_DOMAIN_MEMREGION_MMODE (1UL << 3)
  38. #define SBI_DOMAIN_MEMREGION_ACCESS_MASK (0xfUL)
  39. #define SBI_DOMAIN_MEMREGION_MMIO (1UL << 31)
  40. unsigned long flags;
  41. };
  42. /** Maximum number of domains */
  43. #define SBI_DOMAIN_MAX_INDEX 32
  44. /** Representation of OpenSBI domain */
  45. struct sbi_domain {
  46. /**
  47. * Logical index of this domain
  48. * Note: This set by sbi_domain_finalize() in the coldboot path
  49. */
  50. u32 index;
  51. /**
  52. * HARTs assigned to this domain
  53. * Note: This set by sbi_domain_init() and sbi_domain_finalize()
  54. * in the coldboot path
  55. */
  56. struct sbi_hartmask assigned_harts;
  57. /** Name of this domain */
  58. char name[64];
  59. /** Possible HARTs in this domain */
  60. const struct sbi_hartmask *possible_harts;
  61. /** Array of memory regions terminated by a region with order zero */
  62. struct sbi_domain_memregion *regions;
  63. /** HART id of the HART booting this domain */
  64. u32 boot_hartid;
  65. /** Arg1 (or 'a1' register) of next booting stage for this domain */
  66. unsigned long next_arg1;
  67. /** Address of next booting stage for this domain */
  68. unsigned long next_addr;
  69. /** Privilege mode of next booting stage for this domain */
  70. unsigned long next_mode;
  71. /** Is domain allowed to reset the system */
  72. bool system_reset_allowed;
  73. };
  74. /** The root domain instance */
  75. extern struct sbi_domain root;
  76. /** HART id to domain table */
  77. extern struct sbi_domain *hartid_to_domain_table[];
  78. /** Get pointer to sbi_domain from HART id */
  79. #define sbi_hartid_to_domain(__hartid) \
  80. hartid_to_domain_table[__hartid]
  81. /** Get pointer to sbi_domain for current HART */
  82. #define sbi_domain_thishart_ptr() \
  83. sbi_hartid_to_domain(current_hartid())
  84. /** Index to domain table */
  85. extern struct sbi_domain *domidx_to_domain_table[];
  86. /** Get pointer to sbi_domain from index */
  87. #define sbi_index_to_domain(__index) \
  88. domidx_to_domain_table[__index]
  89. /** Iterate over each domain */
  90. #define sbi_domain_for_each(__i, __d) \
  91. for ((__i) = 0; ((__d) = sbi_index_to_domain(__i)); (__i)++)
  92. /** Iterate over each memory region of a domain */
  93. #define sbi_domain_for_each_memregion(__d, __r) \
  94. for ((__r) = (__d)->regions; (__r)->order; (__r)++)
  95. /**
  96. * Check whether given HART is assigned to specified domain
  97. * @param dom pointer to domain
  98. * @param hartid the HART ID
  99. * @return TRUE if HART is assigned to domain otherwise FALSE
  100. */
  101. bool sbi_domain_is_assigned_hart(const struct sbi_domain *dom, u32 hartid);
  102. /**
  103. * Get ulong assigned HART mask for given domain and HART base ID
  104. * @param dom pointer to domain
  105. * @param hbase the HART base ID
  106. * @return ulong possible HART mask
  107. * Note: the return ulong mask will be set to zero on failure.
  108. */
  109. ulong sbi_domain_get_assigned_hartmask(const struct sbi_domain *dom,
  110. ulong hbase);
  111. /**
  112. * Initialize a domain memory region based on it's physical
  113. * address and size.
  114. *
  115. * @param addr start physical address of memory region
  116. * @param size physical size of memory region
  117. * @param flags memory region flags
  118. * @param reg pointer to memory region being initialized
  119. */
  120. void sbi_domain_memregion_init(unsigned long addr,
  121. unsigned long size,
  122. unsigned long flags,
  123. struct sbi_domain_memregion *reg);
  124. /**
  125. * Check whether we can access specified address for given mode and
  126. * memory region flags under a domain
  127. * @param dom pointer to domain
  128. * @param addr the address to be checked
  129. * @param mode the privilege mode of access
  130. * @param access_flags bitmask of domain access types (enum sbi_domain_access)
  131. * @return TRUE if access allowed otherwise FALSE
  132. */
  133. bool sbi_domain_check_addr(const struct sbi_domain *dom,
  134. unsigned long addr, unsigned long mode,
  135. unsigned long access_flags);
  136. /** Dump domain details on the console */
  137. void sbi_domain_dump(const struct sbi_domain *dom, const char *suffix);
  138. /** Dump all domain details on the console */
  139. void sbi_domain_dump_all(const char *suffix);
  140. /**
  141. * Register a new domain
  142. * @param dom pointer to domain
  143. * @param assign_mask pointer to HART mask of HARTs assigned to the domain
  144. *
  145. * @return 0 on success and negative error code on failure
  146. */
  147. int sbi_domain_register(struct sbi_domain *dom,
  148. const struct sbi_hartmask *assign_mask);
  149. /**
  150. * Add a memory region to the root domain
  151. * @param reg pointer to the memory region to be added
  152. *
  153. * @return 0 on success and negative error code on failure
  154. */
  155. int sbi_domain_root_add_memregion(const struct sbi_domain_memregion *reg);
  156. /** Finalize domain tables and startup non-root domains */
  157. int sbi_domain_finalize(struct sbi_scratch *scratch, u32 cold_hartid);
  158. /** Initialize domains */
  159. int sbi_domain_init(struct sbi_scratch *scratch, u32 cold_hartid);
  160. #endif