debug.c 5.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293
  1. /*++
  2. Copyright (c) 2014 Minoca Corp. All Rights Reserved
  3. Module Name:
  4. debug.c
  5. Abstract:
  6. This module implements debug UART support for BIOS platforms.
  7. Author:
  8. Evan Green 26-Feb-2014
  9. Environment:
  10. Firmware
  11. --*/
  12. //
  13. // ------------------------------------------------------------------- Includes
  14. //
  15. #include <uefifw.h>
  16. #include <dev/ns16550.h>
  17. //
  18. // --------------------------------------------------------------------- Macros
  19. //
  20. //
  21. // ---------------------------------------------------------------- Definitions
  22. //
  23. //
  24. // Define the hard-coded debug serial port.
  25. //
  26. #define EFI_BIOS_DEBUG_SERIAL_PORT 1
  27. //
  28. // Define the number of serial ports that exist in a PC.
  29. //
  30. #define SERIAL_PORT_COUNT 4
  31. //
  32. // Define the bits for the PC UART Line Status register.
  33. //
  34. #define PC_UART_LINE_STATUS_DATA_READY 0x01
  35. #define PC_UART_LINE_STATUS_TRANSMIT_EMPTY 0x20
  36. #define PC_UART_LINE_STATUS_ERRORS 0x8E
  37. //
  38. // Define the base baud rate for the PC UART. This corresponds to a divisor of
  39. // 1.
  40. //
  41. #define PC_UART_BASE_BAUD 115200
  42. //
  43. // ------------------------------------------------------ Data Type Definitions
  44. //
  45. /*++
  46. Structure Description:
  47. This structure defines a baud rate for the PC UART.
  48. Members:
  49. BaudRate - Stores the baud rate.
  50. Divisor - Stores the divisor to set for this baud rate.
  51. --*/
  52. typedef struct _BAUD_RATE {
  53. UINT32 BaudRate;
  54. UINT16 Divisor;
  55. } BAUD_RATE, *PBAUD_RATE;
  56. typedef enum _COM_REGISTER {
  57. ComDataBuffer = 0,
  58. ComDivisorLow = 0,
  59. ComInterruptEnable = 1,
  60. ComDivisorHigh = 1,
  61. ComInterruptStatus = 2,
  62. ComFifoControl = 2,
  63. ComLineControl = 3,
  64. ComModemControl = 4,
  65. ComLineStatus = 5,
  66. ComModemStatus = 6,
  67. ComScratch = 7
  68. } COM_REGISTER, *PCOM_REGISTER;
  69. //
  70. // ----------------------------------------------- Internal Function Prototypes
  71. //
  72. //
  73. // -------------------------------------------------------------------- Globals
  74. //
  75. NS16550_CONTEXT EfiPcDebugUart;
  76. UINT16 EfiPcSerialIoPortBase[SERIAL_PORT_COUNT] = {
  77. 0x3F8,
  78. 0x2F8,
  79. 0x3E8,
  80. 0x2E8
  81. };
  82. //
  83. // ------------------------------------------------------------------ Functions
  84. //
  85. EFI_STATUS
  86. EfiPlatformDebugDeviceReset (
  87. UINT32 BaudRate
  88. )
  89. /*++
  90. Routine Description:
  91. This routine attempts to initialize the serial UART used for debugging.
  92. Arguments:
  93. BaudRate - Supplies the desired baud rate.
  94. Return Value:
  95. EFI_SUCCESS on success.
  96. EFI_DEVICE_ERROR if a device error occurred while resetting the device.
  97. EFI_UNSUPPORTED if the given baud rate cannot be achieved.
  98. --*/
  99. {
  100. UINT16 PortBase;
  101. EFI_STATUS Status;
  102. Status = EfipNs16550ComputeDivisor(PC_UART_BASE_BAUD,
  103. BaudRate,
  104. &(EfiPcDebugUart.BaudRateDivisor));
  105. if (EFI_ERROR(Status)) {
  106. return Status;
  107. }
  108. PortBase = EfiPcSerialIoPortBase[EFI_BIOS_DEBUG_SERIAL_PORT - 1];
  109. EfiPcDebugUart.MemoryBase = NULL;
  110. EfiPcDebugUart.IoBase = PortBase;
  111. EfiPcDebugUart.RegisterOffset = 0;
  112. EfiPcDebugUart.RegisterShift = 0;
  113. EfiPcDebugUart.Flags = NS16550_FLAG_64_BYTE_FIFO;
  114. return EfipNs16550Initialize(&EfiPcDebugUart);
  115. }
  116. EFI_STATUS
  117. EfiPlatformDebugDeviceTransmit (
  118. VOID *Data,
  119. UINTN Size
  120. )
  121. /*++
  122. Routine Description:
  123. This routine transmits data from the host out through the debug device.
  124. Arguments:
  125. Data - Supplies a pointer to the data to write.
  126. Size - Supplies the size to write, in bytes.
  127. Return Value:
  128. EFI_SUCCESS on success.
  129. EFI_DEVICE_ERROR if a device error occurred.
  130. --*/
  131. {
  132. return EfipNs16550Transmit(&EfiPcDebugUart, Data, Size);
  133. }
  134. EFI_STATUS
  135. EfiPlatformDebugDeviceReceive (
  136. VOID *Data,
  137. UINTN *Size
  138. )
  139. /*++
  140. Routine Description:
  141. This routine receives incoming data from the debug device.
  142. Arguments:
  143. Data - Supplies a pointer where the read data will be returned on success.
  144. Size - Supplies a pointer that on input contains the size of the receive
  145. buffer. On output, returns the number of bytes read.
  146. Return Value:
  147. EFI_SUCCESS on success.
  148. EFI_NOT_READY if there was no data to be read at the current time.
  149. EFI_DEVICE_ERROR if a device error occurred.
  150. --*/
  151. {
  152. return EfipNs16550Receive(&EfiPcDebugUart, Data, Size);
  153. }
  154. EFI_STATUS
  155. EfiPlatformDebugDeviceGetStatus (
  156. BOOLEAN *ReceiveDataAvailable
  157. )
  158. /*++
  159. Routine Description:
  160. This routine returns the current device status.
  161. Arguments:
  162. ReceiveDataAvailable - Supplies a pointer where a boolean will be returned
  163. indicating whether or not receive data is available.
  164. Return Value:
  165. EFI_SUCCESS on success.
  166. EFI_DEVICE_ERROR if a device error occurred.
  167. --*/
  168. {
  169. return EfipNs16550GetStatus(&EfiPcDebugUart, ReceiveDataAvailable);
  170. }
  171. VOID
  172. EfiPlatformDebugDeviceDisconnect (
  173. VOID
  174. )
  175. /*++
  176. Routine Description:
  177. This routine disconnects a device, taking it offline.
  178. Arguments:
  179. None.
  180. Return Value:
  181. None.
  182. --*/
  183. {
  184. return;
  185. }
  186. //
  187. // --------------------------------------------------------- Internal Functions
  188. //