serial.c 5.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297
  1. /*++
  2. Copyright (c) 2014 Minoca Corp. All Rights Reserved
  3. Module Name:
  4. serial.c
  5. Abstract:
  6. This module implements basic serial support for the first stage loader.
  7. Author:
  8. Evan Green 18-Dec-2014
  9. Environment:
  10. Firmware
  11. --*/
  12. //
  13. // ------------------------------------------------------------------- Includes
  14. //
  15. #include <uefifw.h>
  16. #include "init.h"
  17. #include "util.h"
  18. //
  19. // --------------------------------------------------------------------- Macros
  20. //
  21. #define AM335_WRITE_UART(_Register, _Value) \
  22. AM3_WRITE32(AM335_UART_0_BASE + (_Register), (_Value))
  23. #define AM335_READ_UART(_Register) \
  24. AM3_READ32(AM335_UART_0_BASE + (_Register))
  25. //
  26. // ---------------------------------------------------------------- Definitions
  27. //
  28. #define STAGE1_SERIAL_CLOCK_HZ 48000000
  29. #define STAGE1_SERIAL_BAUD_RATE 115200
  30. //
  31. // ------------------------------------------------------ Data Type Definitions
  32. //
  33. //
  34. // ----------------------------------------------- Internal Function Prototypes
  35. //
  36. //
  37. // -------------------------------------------------------------------- Globals
  38. //
  39. //
  40. // ------------------------------------------------------------------ Functions
  41. //
  42. VOID
  43. EfipAm335EnableUart (
  44. VOID
  45. )
  46. /*++
  47. Routine Description:
  48. This routine performs rudimentary initialization so that UART0 can be used
  49. as a debug console.
  50. Arguments:
  51. None.
  52. Return Value:
  53. None.
  54. --*/
  55. {
  56. UINT32 Divisor;
  57. UINT32 Register;
  58. UINT32 Value;
  59. //
  60. // Set the pad configuration for UART0.
  61. //
  62. Register = AM335_SOC_CONTROL_REGISTERS + AM335_PAD_UART_RXD(0);
  63. Value = AM335_SOC_CONTROL_UART0_RXD_PULLUP |
  64. AM335_SOC_CONTROL_UART0_RXD_RX_ACTIVE;
  65. AM3_WRITE32(Register, Value);
  66. Register = AM335_SOC_CONTROL_REGISTERS + AM335_PAD_UART_TXD(0);
  67. Value = AM335_SOC_CONTROL_UART0_TXD_PULLUP;
  68. AM3_WRITE32(Register, Value);
  69. //
  70. // Reset the UART module.
  71. //
  72. Value = AM335_READ_UART(AM335_UART_SYSTEM_CONTROL);
  73. Value |= AM335_UART_SYSTEM_CONTROL_RESET;
  74. AM335_WRITE_UART(AM335_UART_SYSTEM_CONTROL, Value);
  75. do {
  76. Value = AM335_READ_UART(AM335_UART_SYSTEM_STATUS);
  77. } while ((Value & AM335_UART_SYSTEM_STATUS_RESET_DONE) == 0);
  78. //
  79. // Configure the UART.
  80. //
  81. Divisor = STAGE1_SERIAL_CLOCK_HZ / 16 / STAGE1_SERIAL_BAUD_RATE;
  82. AM335_WRITE_UART(AM335_UART_IER, 0x00);
  83. AM335_WRITE_UART(AM335_UART_MDR1, 0x07);
  84. AM335_WRITE_UART(AM335_UART_LCR, 0x83);
  85. AM335_WRITE_UART(AM335_UART_DLL, (UINT8)Divisor);
  86. AM335_WRITE_UART(AM335_UART_DLM, (UINT8)(Divisor >> 8));
  87. AM335_WRITE_UART(AM335_UART_LCR, 0x03);
  88. AM335_WRITE_UART(AM335_UART_MCR, 0x03);
  89. AM335_WRITE_UART(AM335_UART_FCR, 0x07);
  90. AM335_WRITE_UART(AM335_UART_MDR1, 0x00);
  91. return;
  92. }
  93. VOID
  94. EfipSerialPrintBuffer32 (
  95. CHAR8 *Title,
  96. VOID *Buffer,
  97. UINT32 Size
  98. )
  99. /*++
  100. Routine Description:
  101. This routine prints a buffer of 32-bit hex integers.
  102. Arguments:
  103. Title - Supplies an optional pointer to a string to title the buffer.
  104. Buffer - Supplies the buffer to print.
  105. Size - Supplies the size of the buffer. This is assumed to be divisible by
  106. 4.
  107. Return Value:
  108. None.
  109. --*/
  110. {
  111. UINT32 *Buffer32;
  112. UINTN Index;
  113. if (Title != NULL) {
  114. EfipSerialPrintString(Title);
  115. }
  116. Buffer32 = Buffer;
  117. for (Index = 0; Index < (Size >> 2); Index += 1) {
  118. if ((Index & 0x7) == 0) {
  119. EfipSerialPrintString("\r\n");
  120. }
  121. EfipSerialPrintHexInteger(Buffer32[Index]);
  122. EfipSerialPrintString(" ");
  123. }
  124. EfipSerialPrintString("\r\n");
  125. return;
  126. }
  127. VOID
  128. EfipSerialPrintString (
  129. CHAR8 *String
  130. )
  131. /*++
  132. Routine Description:
  133. This routine prints a string to the serial console.
  134. Arguments:
  135. String - Supplies a pointer to the string to send.
  136. Return Value:
  137. None.
  138. --*/
  139. {
  140. while (*String != '\0') {
  141. if (*String == '\n') {
  142. EfipSerialPutCharacter('\r');
  143. }
  144. EfipSerialPutCharacter(*String);
  145. String += 1;
  146. }
  147. return;
  148. }
  149. VOID
  150. EfipSerialPrintHexInteger (
  151. UINT32 Value
  152. )
  153. /*++
  154. Routine Description:
  155. This routine prints a hex integer to the console.
  156. Arguments:
  157. Value - Supplies the value to print.
  158. Return Value:
  159. None.
  160. --*/
  161. {
  162. UINT32 Digit;
  163. UINTN Index;
  164. for (Index = 0; Index < 8; Index += 1) {
  165. Digit = ((Value & 0xF0000000) >> 28) & 0x0000000F;
  166. if (Digit >= 0xA) {
  167. EfipSerialPutCharacter(Digit - 0xA + 'A');
  168. } else {
  169. EfipSerialPutCharacter(Digit + '0');
  170. }
  171. Value = Value << 4;
  172. }
  173. return;
  174. }
  175. VOID
  176. EfipSerialPutCharacter (
  177. CHAR8 Character
  178. )
  179. /*++
  180. Routine Description:
  181. This routine prints a character to the serial console.
  182. Arguments:
  183. Character - Supplies the character to send.
  184. Return Value:
  185. None.
  186. --*/
  187. {
  188. while (TRUE) {
  189. if ((AM335_READ_UART(AM335_UART_LSR) & 0x20) != 0) {
  190. break;
  191. }
  192. }
  193. AM335_WRITE_UART(AM335_UART_THR, Character);
  194. return;
  195. }
  196. //
  197. // --------------------------------------------------------- Internal Functions
  198. //