main.c 5.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307
  1. /*++
  2. Copyright (c) 2014 Minoca Corp. All Rights Reserved
  3. Module Name:
  4. main.c
  5. Abstract:
  6. This module implements the entry point for the UEFI firmware running on top
  7. of the TI BeagleBone Black.
  8. Author:
  9. Evan Green 19-Dec-2014
  10. Environment:
  11. Firmware
  12. --*/
  13. //
  14. // ------------------------------------------------------------------- Includes
  15. //
  16. #include <uefifw.h>
  17. #include <minoca/soc/am335x.h>
  18. #include "bbonefw.h"
  19. //
  20. // ---------------------------------------------------------------- Definitions
  21. //
  22. #define FIRMWARE_IMAGE_NAME "bbonefw.elf"
  23. //
  24. // ------------------------------------------------------ Data Type Definitions
  25. //
  26. //
  27. // ----------------------------------------------- Internal Function Prototypes
  28. //
  29. VOID
  30. EfipBeagleBoneBlackSetMacAddresses (
  31. VOID
  32. );
  33. //
  34. // -------------------------------------------------------------------- Globals
  35. //
  36. //
  37. // Variables defined in the linker script that mark the start and end of the
  38. // image.
  39. //
  40. extern INT8 _end;
  41. extern INT8 __executable_start;
  42. //
  43. // Store a boolean used for debugging that disables the watchdog timer.
  44. //
  45. BOOLEAN EfiDisableWatchdog = FALSE;
  46. //
  47. // Store the boot device type.
  48. //
  49. UINT32 EfiBootDeviceCode;
  50. //
  51. // ------------------------------------------------------------------ Functions
  52. //
  53. VOID
  54. EfiBeagleBoneMain (
  55. VOID *TopOfStack,
  56. UINTN StackSize,
  57. UINT32 BootDevice
  58. )
  59. /*++
  60. Routine Description:
  61. This routine is the C entry point for the firmware.
  62. Arguments:
  63. TopOfStack - Supplies the top of the stack that has been set up for the
  64. loader.
  65. StackSize - Supplies the total size of the stack set up for the loader, in
  66. bytes.
  67. BootDevice - Supplies the boot device code. See AM335_ROM_DEVICE_*
  68. definitions.
  69. Return Value:
  70. This routine does not return.
  71. --*/
  72. {
  73. UINTN FirmwareSize;
  74. //
  75. // Initialize UEFI enough to get into the debugger.
  76. //
  77. EfipBeagleBoneBlackSetLeds(4);
  78. FirmwareSize = (UINTN)&_end - (UINTN)&__executable_start;
  79. EfiBootDeviceCode = BootDevice;
  80. EfiCoreMain((VOID *)-1,
  81. &__executable_start,
  82. FirmwareSize,
  83. FIRMWARE_IMAGE_NAME,
  84. TopOfStack - StackSize,
  85. StackSize);
  86. return;
  87. }
  88. EFI_STATUS
  89. EfiPlatformInitialize (
  90. UINT32 Phase
  91. )
  92. /*++
  93. Routine Description:
  94. This routine performs platform-specific firmware initialization.
  95. Arguments:
  96. Phase - Supplies the iteration number this routine is being called on.
  97. Phase zero occurs very early, just after the debugger comes up.
  98. Phase one occurs a bit later, after timer and interrupt services are
  99. initialized. Phase two happens right before boot, after all platform
  100. devices have been enumerated.
  101. Return Value:
  102. EFI status code.
  103. --*/
  104. {
  105. EFI_STATUS Status;
  106. if (Phase == 0) {
  107. if (EfiDisableWatchdog != FALSE) {
  108. EfiPlatformSetWatchdogTimer(0, 0, 0, NULL);
  109. }
  110. EfipAm335InitializePowerAndClocks();
  111. EfipBeagleBoneBlackInitializeRtc();
  112. } else if (Phase == 1) {
  113. Status = EfipBeagleBoneCreateSmbiosTables();
  114. if (EFI_ERROR(Status)) {
  115. return Status;
  116. }
  117. }
  118. return EFI_SUCCESS;
  119. }
  120. EFI_STATUS
  121. EfiPlatformEnumerateDevices (
  122. VOID
  123. )
  124. /*++
  125. Routine Description:
  126. This routine enumerates and connects any builtin devices the platform
  127. contains.
  128. Arguments:
  129. None.
  130. Return Value:
  131. EFI status code.
  132. --*/
  133. {
  134. EFI_STATUS Status;
  135. EfipBeagleBoneBlackEnumerateVideo();
  136. EfipBeagleBoneBlackSetMacAddresses();
  137. Status = EfipBeagleBoneEnumerateStorage();
  138. if (EFI_ERROR(Status)) {
  139. return Status;
  140. }
  141. EfipBeagleBoneEnumerateSerial();
  142. Status = EfipEnumerateRamDisks();
  143. if (EFI_ERROR(Status)) {
  144. return Status;
  145. }
  146. return EFI_SUCCESS;
  147. }
  148. VOID
  149. EfipBeagleBoneBlackSetLeds (
  150. UINT32 Leds
  151. )
  152. /*++
  153. Routine Description:
  154. This routine sets the LEDs to a new value.
  155. Arguments:
  156. Leds - Supplies the four bits containing whether to set the LEDs high or
  157. low.
  158. Return Value:
  159. None.
  160. --*/
  161. {
  162. UINT32 Value;
  163. Value = (Leds & 0x0F) << 21;
  164. EfiWriteRegister32((VOID *)(AM335_GPIO_1_BASE + AM335_GPIO_SET_DATA_OUT),
  165. Value);
  166. Value = (~Leds & 0x0F) << 21;
  167. EfiWriteRegister32((VOID *)(AM335_GPIO_1_BASE + AM335_GPIO_CLEAR_DATA_OUT),
  168. Value);
  169. return;
  170. }
  171. //
  172. // --------------------------------------------------------- Internal Functions
  173. //
  174. VOID
  175. EfipBeagleBoneBlackSetMacAddresses (
  176. VOID
  177. )
  178. /*++
  179. Routine Description:
  180. This routine sets the MAC addresses in the CPSW based on the data in the
  181. SOC Control region.
  182. Arguments:
  183. None.
  184. Return Value:
  185. None.
  186. --*/
  187. {
  188. VOID *CpswPort;
  189. VOID *SocControl;
  190. UINT32 Value;
  191. CpswPort = (VOID *)AM335_CPSW_PORT_REGISTERS;
  192. SocControl = (VOID *)AM335_SOC_CONTROL_REGISTERS;
  193. //
  194. // The SOC ID region stores unique MAC addresses for the two external
  195. // ethernet ports. Copy those values over to the ethernet controller so the
  196. // OS can discover them.
  197. //
  198. Value = EfiReadRegister32(SocControl + AM335_SOC_CONTROL_MAC_ID0_LOW);
  199. EfiWriteRegister32(CpswPort + AM335_CPSW_PORT1_SOURCE_ADDRESS_LOW, Value);
  200. Value = EfiReadRegister32(SocControl + AM335_SOC_CONTROL_MAC_ID0_HIGH);
  201. EfiWriteRegister32(CpswPort + AM335_CPSW_PORT1_SOURCE_ADDRESS_HIGH, Value);
  202. Value = EfiReadRegister32(SocControl + AM335_SOC_CONTROL_MAC_ID1_LOW);
  203. EfiWriteRegister32(CpswPort + AM335_CPSW_PORT2_SOURCE_ADDRESS_LOW, Value);
  204. Value = EfiReadRegister32(SocControl + AM335_SOC_CONTROL_MAC_ID1_HIGH);
  205. EfiWriteRegister32(CpswPort + AM335_CPSW_PORT2_SOURCE_ADDRESS_HIGH, Value);
  206. return;
  207. }