memmap.c 6.2 KB

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