memmap.c 6.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274
  1. /*++
  2. Copyright (c) 2014 Minoca Corp.
  3. This file is licensed under the terms of the GNU General Public License
  4. version 3. Alternative licensing terms are available. Contact
  5. info@minocacorp.com for details. See the LICENSE file at the root of this
  6. project for complete licensing information.
  7. Module Name:
  8. memmap.c
  9. Abstract:
  10. This module implements support for acquiring the initial memory map on a
  11. BCM2709 SoC.
  12. Author:
  13. Chris Stevens 21-Dec-2014
  14. Environment:
  15. Firmware
  16. --*/
  17. //
  18. // ------------------------------------------------------------------- Includes
  19. //
  20. #include <uefifw.h>
  21. #include <dev/bcm2709.h>
  22. //
  23. // ---------------------------------------------------------------- Definitions
  24. //
  25. #define BCM2709_MEMORY_MAP_SIZE \
  26. (sizeof(EfiBcm2709MemoryMap) / sizeof(EfiBcm2709MemoryMap[0]))
  27. #define BCM2709_MEMORY_MAP_SCRATCH_BUFFER_SIZE \
  28. sizeof(BCM2709_MAILBOX_GET_MEMORY_REGIONS) + BCM2709_MAILBOX_DATA_ALIGNMENT
  29. //
  30. // ------------------------------------------------------ Data Type Definitions
  31. //
  32. /*++
  33. Structure Description:
  34. This structure defines the data necessary to get the system's memory
  35. regions.
  36. Members:
  37. Header - Stores a header that defines the total size of the messages being
  38. sent to and received from the mailbox.
  39. ArmMemoryRegion - Stores a request to get the ARM core's memory region.
  40. VideoMemoryRegion - Store a request to get the video core's memory region.
  41. EndTag - Stores the tag to denote the end of the mailbox message.
  42. --*/
  43. typedef struct _BCM2709_MAILBOX_GET_MEMORY_REGIONS {
  44. BCM2709_MAILBOX_HEADER Header;
  45. BCM2709_MAILBOX_MEMORY_REGION ArmMemoryRegion;
  46. BCM2709_MAILBOX_MEMORY_REGION VideoMemoryRegion;
  47. UINT32 EndTag;
  48. } BCM2709_MAILBOX_GET_MEMORY_REGIONS, *PBCM2709_MAILBOX_GET_MEMORY_REGIONS;
  49. //
  50. // ----------------------------------------------- Internal Function Prototypes
  51. //
  52. //
  53. // -------------------------------------------------------------------- Globals
  54. //
  55. //
  56. // Define the initial memory map.
  57. //
  58. EFI_MEMORY_DESCRIPTOR EfiBcm2709MemoryMap[] = {
  59. {
  60. EfiConventionalMemory,
  61. 0,
  62. 0,
  63. 0,
  64. 0,
  65. 0
  66. },
  67. {
  68. EfiMemoryMappedIO,
  69. 0,
  70. 0,
  71. 0,
  72. 0,
  73. 0
  74. },
  75. {
  76. EfiRuntimeServicesData,
  77. 0,
  78. BCM2709_PRM_OFFSET,
  79. 0,
  80. EFI_SIZE_TO_PAGES(BCM2709_PRM_SIZE),
  81. EFI_MEMORY_UC | EFI_MEMORY_RUNTIME
  82. },
  83. };
  84. //
  85. // Define a template for the call to query the memory regions.
  86. //
  87. BCM2709_MAILBOX_GET_MEMORY_REGIONS EfiBcm2709GetMemoryRegionsTemplate = {
  88. {
  89. sizeof(BCM2709_MAILBOX_GET_MEMORY_REGIONS),
  90. 0
  91. },
  92. {
  93. {
  94. BCM2709_MAILBOX_TAG_GET_ARM_CORE_MEMORY,
  95. sizeof(UINT32) + sizeof(UINT32),
  96. 0
  97. },
  98. 0,
  99. 0
  100. },
  101. {
  102. {
  103. BCM2709_MAILBOX_TAG_GET_VIDEO_CORE_MEMORY,
  104. sizeof(UINT32) + sizeof(UINT32),
  105. 0
  106. },
  107. 0,
  108. 0
  109. },
  110. 0
  111. };
  112. //
  113. // ------------------------------------------------------------------ Functions
  114. //
  115. EFI_STATUS
  116. EfipBcm2709GetInitialMemoryMap (
  117. EFI_MEMORY_DESCRIPTOR **Map,
  118. UINTN *MapSize
  119. )
  120. /*++
  121. Routine Description:
  122. This routine returns the initial platform memory map to the EFI core. The
  123. core maintains this memory map. The memory map returned does not need to
  124. take into account the firmware image itself or stack, the EFI core will
  125. reserve those regions automatically.
  126. Arguments:
  127. Map - Supplies a pointer where the array of memory descriptors constituting
  128. the initial memory map is returned on success. The EFI core will make
  129. a copy of these descriptors, so they can be in read-only or
  130. temporary memory.
  131. MapSize - Supplies a pointer where the number of elements in the initial
  132. memory map will be returned on success.
  133. Return Value:
  134. EFI status code.
  135. --*/
  136. {
  137. UINT8 Buffer[BCM2709_MEMORY_MAP_SCRATCH_BUFFER_SIZE];
  138. UINT32 ExpectedLength;
  139. UINT32 Length;
  140. PBCM2709_MAILBOX_GET_MEMORY_REGIONS MemoryRegions;
  141. EFI_STATUS Status;
  142. //
  143. // The BCM2709 device library must be initialized in order to get the
  144. // memory map.
  145. //
  146. if (EfiBcm2709Initialized == FALSE) {
  147. return EFI_NOT_READY;
  148. }
  149. MemoryRegions = ALIGN_POINTER(Buffer, BCM2709_MAILBOX_DATA_ALIGNMENT);
  150. EfiCopyMem(MemoryRegions,
  151. &EfiBcm2709GetMemoryRegionsTemplate,
  152. sizeof(BCM2709_MAILBOX_GET_MEMORY_REGIONS));
  153. //
  154. // Request and validate the memory regions.
  155. //
  156. Status = EfipBcm2709MailboxSendCommand(
  157. BCM2709_MAILBOX_PROPERTIES_CHANNEL,
  158. MemoryRegions,
  159. sizeof(BCM2709_MAILBOX_GET_MEMORY_REGIONS),
  160. FALSE);
  161. if (EFI_ERROR(Status)) {
  162. return Status;
  163. }
  164. Length = MemoryRegions->ArmMemoryRegion.TagHeader.Length;
  165. ExpectedLength = sizeof(BCM2709_MAILBOX_MEMORY_REGION) -
  166. sizeof(BCM2709_MAILBOX_TAG);
  167. if (BCM2709_MAILBOX_CHECK_TAG_LENGTH(Length, ExpectedLength) == FALSE) {
  168. Status = EFI_DEVICE_ERROR;
  169. return Status;
  170. }
  171. Length = MemoryRegions->VideoMemoryRegion.TagHeader.Length;
  172. ExpectedLength = sizeof(BCM2709_MAILBOX_MEMORY_REGION) -
  173. sizeof(BCM2709_MAILBOX_TAG);
  174. if (BCM2709_MAILBOX_CHECK_TAG_LENGTH(Length, ExpectedLength) == FALSE) {
  175. Status = EFI_DEVICE_ERROR;
  176. return Status;
  177. }
  178. //
  179. // Fill out the memory map based on the two regions returned by the
  180. // firmware.
  181. //
  182. EfiBcm2709MemoryMap[0].PhysicalStart =
  183. MemoryRegions->ArmMemoryRegion.BaseAddress;
  184. EfiBcm2709MemoryMap[0].NumberOfPages =
  185. MemoryRegions->ArmMemoryRegion.Size / EFI_PAGE_SIZE;
  186. EfiBcm2709MemoryMap[1].PhysicalStart =
  187. MemoryRegions->VideoMemoryRegion.BaseAddress;
  188. EfiBcm2709MemoryMap[1].NumberOfPages =
  189. MemoryRegions->VideoMemoryRegion.Size / EFI_PAGE_SIZE;
  190. //
  191. // Patch up the PRM base as only the offset from the BCM2709 base address
  192. // was stored in the global array.
  193. //
  194. EfiBcm2709MemoryMap[2].PhysicalStart = (UINTN)BCM2709_PRM_BASE;
  195. *Map = EfiBcm2709MemoryMap;
  196. *MapSize = BCM2709_MEMORY_MAP_SIZE;
  197. return EFI_SUCCESS;
  198. }
  199. //
  200. // --------------------------------------------------------- Internal Functions
  201. //