main.c 5.9 KB

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