serial.c 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654
  1. /*++
  2. Copyright (c) 2015 Minoca Corp. All Rights Reserved
  3. Module Name:
  4. serial.c
  5. Abstract:
  6. This module implements support for the serial device on the TI BeagleBone
  7. Black.
  8. Author:
  9. Evan Green 6-Jan-2015
  10. Environment:
  11. Firmware
  12. --*/
  13. //
  14. // ------------------------------------------------------------------- Includes
  15. //
  16. #include <uefifw.h>
  17. #include <minoca/uefi/protocol/serio.h>
  18. #include "bbonefw.h"
  19. #include <minoca/soc/am335x.h>
  20. #include "dev/omapuart.h"
  21. //
  22. // --------------------------------------------------------------------- Macros
  23. //
  24. //
  25. // This macro returns a pointer to the disk I/O data given a pointer to the
  26. // block I/O protocol instance.
  27. //
  28. #define EFI_BBONE_SERIAL_FROM_THIS(_SerialIo) \
  29. (EFI_BBONE_SERIAL_CONTEXT *)((VOID *)(_SerialIo) - \
  30. ((VOID *)(&(((EFI_BBONE_SERIAL_CONTEXT *)0)->SerialIo))))
  31. //
  32. // ---------------------------------------------------------------- Definitions
  33. //
  34. #define EFI_BBONE_SERIAL_MAGIC 0x72655342 // 'reSB'
  35. #define EFI_BBONE_DEFAULT_SERIAL_BAUD_RATE 115200
  36. //
  37. // ------------------------------------------------------ Data Type Definitions
  38. //
  39. /*++
  40. Structure Description:
  41. This structure describes the BeagleBone Black Serial I/O device context.
  42. Members:
  43. Magic - Stores the magic constand EFI_BBONE_SERIAL_MAGIC.
  44. Handle - Stores the handle to the device.
  45. DevicePath - Stores a pointer to the device path.
  46. Uart - Stores the UART context.
  47. SerialIo - Stores the Serial I/O protocol.
  48. Mode - Stores the mode information.
  49. --*/
  50. typedef struct _EFI_BBONE_SERIAL_CONTEXT {
  51. UINT32 Magic;
  52. EFI_HANDLE Handle;
  53. EFI_DEVICE_PATH_PROTOCOL *DevicePath;
  54. OMAP_UART_CONTEXT Uart;
  55. EFI_SERIAL_IO_PROTOCOL SerialIo;
  56. EFI_SERIAL_IO_MODE Mode;
  57. } EFI_BBONE_SERIAL_CONTEXT, *PEFI_BBONE_SERIAL_CONTEXT;
  58. /*++
  59. Structure Description:
  60. This structure defines the BeagleBone Black Serial I/O device path node.
  61. Members:
  62. DevicePath - Stores the standard vendor-specific device path.
  63. ControllerBase - Stores the controller base address.
  64. --*/
  65. typedef struct _EFI_BBONE_SERIAL_IO_DEVICE_PATH_NODE {
  66. VENDOR_DEVICE_PATH DevicePath;
  67. UINT32 ControllerBase;
  68. } EFI_BBONE_SERIAL_IO_DEVICE_PATH_NODE, *PEFI_BBONE_SERIAL_IO_DEVICE_PATH_NODE;
  69. /*++
  70. Structure Description:
  71. This structure defines the BeagleBone Black Serial I/O device path form.
  72. Members:
  73. Device - Stores the serial port device path node.
  74. End - Stores the end device path node.
  75. --*/
  76. typedef struct _EFI_BBONE_SERIAL_IO_DEVICE_PATH {
  77. EFI_BBONE_SERIAL_IO_DEVICE_PATH_NODE Device;
  78. EFI_DEVICE_PATH_PROTOCOL End;
  79. } PACKED EFI_BBONE_SERIAL_IO_DEVICE_PATH, *PEFI_BBONE_SERIAL_IO_DEVICE_PATH;
  80. //
  81. // ----------------------------------------------- Internal Function Prototypes
  82. //
  83. EFIAPI
  84. EFI_STATUS
  85. EfipBeagleBoneSerialReset (
  86. EFI_SERIAL_IO_PROTOCOL *This
  87. );
  88. EFIAPI
  89. EFI_STATUS
  90. EfipBeagleBoneSerialSetAttributes (
  91. EFI_SERIAL_IO_PROTOCOL *This,
  92. UINT64 BaudRate,
  93. UINT32 ReceiveFifoDepth,
  94. UINT32 Timeout,
  95. EFI_PARITY_TYPE Parity,
  96. UINT8 DataBits,
  97. EFI_STOP_BITS_TYPE StopBits
  98. );
  99. EFIAPI
  100. EFI_STATUS
  101. EfipBeagleBoneSerialSetControlBits (
  102. EFI_SERIAL_IO_PROTOCOL *This,
  103. UINT32 Control
  104. );
  105. EFIAPI
  106. EFI_STATUS
  107. EfipBeagleBoneSerialGetControlBits (
  108. EFI_SERIAL_IO_PROTOCOL *This,
  109. UINT32 *Control
  110. );
  111. EFIAPI
  112. EFI_STATUS
  113. EfipBeagleBoneSerialWrite (
  114. EFI_SERIAL_IO_PROTOCOL *This,
  115. UINTN *BufferSize,
  116. VOID *Buffer
  117. );
  118. EFIAPI
  119. EFI_STATUS
  120. EfipBeagleBoneSerialRead (
  121. EFI_SERIAL_IO_PROTOCOL *This,
  122. UINTN *BufferSize,
  123. VOID *Buffer
  124. );
  125. //
  126. // -------------------------------------------------------------------- Globals
  127. //
  128. //
  129. // Define the device path template.
  130. //
  131. EFI_BBONE_SERIAL_IO_DEVICE_PATH EfiBeagleBoneSerialIoDevicePathTemplate = {
  132. {
  133. {
  134. {
  135. HARDWARE_DEVICE_PATH,
  136. HW_VENDOR_DP,
  137. sizeof(EFI_BBONE_SERIAL_IO_DEVICE_PATH_NODE)
  138. },
  139. EFI_SERIAL_IO_PROTOCOL_GUID,
  140. },
  141. 0xFFFFFFFF
  142. },
  143. {
  144. END_DEVICE_PATH_TYPE,
  145. END_ENTIRE_DEVICE_PATH_SUBTYPE,
  146. END_DEVICE_PATH_LENGTH
  147. }
  148. };
  149. EFI_BBONE_SERIAL_CONTEXT EfiBeagleBoneSerialTemplate = {
  150. EFI_BBONE_SERIAL_MAGIC,
  151. NULL,
  152. NULL,
  153. {0},
  154. {
  155. EFI_SERIAL_IO_PROTOCOL_REVISION,
  156. EfipBeagleBoneSerialReset,
  157. EfipBeagleBoneSerialSetAttributes,
  158. EfipBeagleBoneSerialSetControlBits,
  159. EfipBeagleBoneSerialGetControlBits,
  160. EfipBeagleBoneSerialWrite,
  161. EfipBeagleBoneSerialRead,
  162. NULL
  163. },
  164. {
  165. EFI_SERIAL_INPUT_BUFFER_EMPTY,
  166. 0,
  167. 0,
  168. 0,
  169. 8,
  170. DefaultParity,
  171. DefaultStopBits
  172. }
  173. };
  174. EFI_GUID EfiSerialIoProtocolGuid = EFI_SERIAL_IO_PROTOCOL_GUID;
  175. //
  176. // ------------------------------------------------------------------ Functions
  177. //
  178. EFI_STATUS
  179. EfipBeagleBoneEnumerateSerial (
  180. VOID
  181. )
  182. /*++
  183. Routine Description:
  184. This routine enumerates the serial port on the BeagleBone Black.
  185. Arguments:
  186. None.
  187. Return Value:
  188. EFI status code.
  189. --*/
  190. {
  191. VOID *ControllerBase;
  192. PEFI_BBONE_SERIAL_CONTEXT Device;
  193. PEFI_BBONE_SERIAL_IO_DEVICE_PATH DevicePath;
  194. EFI_STATUS Status;
  195. ControllerBase = (VOID *)AM335_UART_0_BASE;
  196. //
  197. // Allocate and initialize the context structure.
  198. //
  199. Status = EfiAllocatePool(EfiBootServicesData,
  200. sizeof(EFI_BBONE_SERIAL_CONTEXT),
  201. (VOID **)&Device);
  202. if (EFI_ERROR(Status)) {
  203. return Status;
  204. }
  205. EfiCopyMem(Device,
  206. &EfiBeagleBoneSerialTemplate,
  207. sizeof(EFI_BBONE_SERIAL_CONTEXT));
  208. Device->Handle = NULL;
  209. Device->SerialIo.Mode = &(Device->Mode);
  210. Device->Uart.UartBase = ControllerBase;
  211. //
  212. // Create the device path.
  213. //
  214. Status = EfiAllocatePool(EfiBootServicesData,
  215. sizeof(EFI_BBONE_SERIAL_IO_DEVICE_PATH),
  216. (VOID **)&DevicePath);
  217. if (EFI_ERROR(Status)) {
  218. goto BeagleBoneEnumerateSerialEnd;
  219. }
  220. EfiCopyMem(DevicePath,
  221. &EfiBeagleBoneSerialIoDevicePathTemplate,
  222. sizeof(EFI_BBONE_SERIAL_IO_DEVICE_PATH));
  223. DevicePath->Device.ControllerBase = (UINT32)ControllerBase;
  224. Device->DevicePath = (EFI_DEVICE_PATH_PROTOCOL *)DevicePath;
  225. Device->Mode.BaudRate = EFI_BBONE_DEFAULT_SERIAL_BAUD_RATE;
  226. Status = EfiInstallMultipleProtocolInterfaces(&(Device->Handle),
  227. &EfiDevicePathProtocolGuid,
  228. Device->DevicePath,
  229. &EfiSerialIoProtocolGuid,
  230. &(Device->SerialIo),
  231. NULL);
  232. BeagleBoneEnumerateSerialEnd:
  233. if (EFI_ERROR(Status)) {
  234. if (Device != NULL) {
  235. if (Device->DevicePath != NULL) {
  236. EfiFreePool(DevicePath);
  237. }
  238. EfiFreePool(Device);
  239. }
  240. }
  241. return Status;
  242. }
  243. //
  244. // --------------------------------------------------------- Internal Functions
  245. //
  246. EFIAPI
  247. EFI_STATUS
  248. EfipBeagleBoneSerialReset (
  249. EFI_SERIAL_IO_PROTOCOL *This
  250. )
  251. /*++
  252. Routine Description:
  253. This routine resets the serial device.
  254. Arguments:
  255. This - Supplies a pointer to the protocol instance.
  256. Return Value:
  257. EFI_SUCCESS if the device was reset.
  258. EFI_DEVICE_ERROR if the device could not be reset.
  259. --*/
  260. {
  261. PEFI_BBONE_SERIAL_CONTEXT Device;
  262. EFI_STATUS Status;
  263. Device = EFI_BBONE_SERIAL_FROM_THIS(This);
  264. Status = EfipUartOmapComputeDivisor(Device->Mode.BaudRate,
  265. &(Device->Uart.BaudRateRegister));
  266. if (EFI_ERROR(Status)) {
  267. return Status;
  268. }
  269. Status = EfipUartOmapInitialize(&(Device->Uart));
  270. return Status;
  271. }
  272. EFIAPI
  273. EFI_STATUS
  274. EfipBeagleBoneSerialSetAttributes (
  275. EFI_SERIAL_IO_PROTOCOL *This,
  276. UINT64 BaudRate,
  277. UINT32 ReceiveFifoDepth,
  278. UINT32 Timeout,
  279. EFI_PARITY_TYPE Parity,
  280. UINT8 DataBits,
  281. EFI_STOP_BITS_TYPE StopBits
  282. )
  283. /*++
  284. Routine Description:
  285. This routine sets the baud rate, receive FIFO depth, transmit/receive
  286. timeout, parity, data bits, and stop bits on a serial device.
  287. Arguments:
  288. This - Supplies a pointer to the protocol instance.
  289. BaudRate - Supplies the desired baud rate. A value of zero will use the
  290. default interface speed.
  291. ReceiveFifoDepth - Supplies the requested depth of the receive FIFO. A
  292. value of zero uses the default FIFO size.
  293. Timeout - Supplies the timeout in microseconds for attempting to receive
  294. a single character. A timeout of zero uses the default timeout.
  295. Parity - Supplies the type of parity to use on the device.
  296. DataBits - Supplies the number of bits per byte on the serial device. A
  297. value of zero uses a default value.
  298. StopBits - Supplies the number of stop bits to use on the serial device.
  299. A value of zero uses a default value.
  300. Return Value:
  301. EFI_SUCCESS if the device was reset.
  302. EFI_DEVICE_ERROR if the device could not be reset.
  303. --*/
  304. {
  305. PEFI_BBONE_SERIAL_CONTEXT Device;
  306. Device = EFI_BBONE_SERIAL_FROM_THIS(This);
  307. if (BaudRate == 0) {
  308. BaudRate = EFI_BBONE_DEFAULT_SERIAL_BAUD_RATE;
  309. }
  310. if ((ReceiveFifoDepth != 0) ||
  311. (Timeout != 0) ||
  312. ((Parity != DefaultParity) && (Parity != NoParity)) ||
  313. ((DataBits != 0) && (DataBits != 8)) ||
  314. ((StopBits != DefaultStopBits) && (StopBits != OneStopBit))) {
  315. return EFI_UNSUPPORTED;
  316. }
  317. Device->Mode.BaudRate = BaudRate;
  318. return This->Reset(This);
  319. }
  320. EFIAPI
  321. EFI_STATUS
  322. EfipBeagleBoneSerialSetControlBits (
  323. EFI_SERIAL_IO_PROTOCOL *This,
  324. UINT32 Control
  325. )
  326. /*++
  327. Routine Description:
  328. This routine sets the control bits on a serial device.
  329. Arguments:
  330. This - Supplies a pointer to the protocol instance.
  331. Control - Supplies the control bits to set.
  332. Return Value:
  333. EFI_SUCCESS if the new control bits were set.
  334. EFI_UNSUPPORTED if the serial device does not support this operation.
  335. EFI_DEVICE_ERROR if the device is not functioning properly.
  336. --*/
  337. {
  338. return EFI_UNSUPPORTED;
  339. }
  340. EFIAPI
  341. EFI_STATUS
  342. EfipBeagleBoneSerialGetControlBits (
  343. EFI_SERIAL_IO_PROTOCOL *This,
  344. UINT32 *Control
  345. )
  346. /*++
  347. Routine Description:
  348. This routine gets the control bits on a serial device.
  349. Arguments:
  350. This - Supplies a pointer to the protocol instance.
  351. Control - Supplies a pointer where the current control bits will be
  352. returned.
  353. Return Value:
  354. EFI_SUCCESS if the new control bits were set.
  355. EFI_DEVICE_ERROR if the device is not functioning properly.
  356. --*/
  357. {
  358. PEFI_BBONE_SERIAL_CONTEXT Device;
  359. BOOLEAN ReceiveDataAvailable;
  360. EFI_STATUS Status;
  361. Device = EFI_BBONE_SERIAL_FROM_THIS(This);
  362. if (Device->Uart.BaudRateRegister == 0) {
  363. Status = This->Reset(This);
  364. if (EFI_ERROR(Status)) {
  365. return Status;
  366. }
  367. }
  368. Status = EfipUartOmapGetStatus(&(Device->Uart), &ReceiveDataAvailable);
  369. if (EFI_ERROR(Status)) {
  370. return Status;
  371. }
  372. *Control = 0;
  373. if (ReceiveDataAvailable == FALSE) {
  374. *Control |= EFI_SERIAL_INPUT_BUFFER_EMPTY;
  375. }
  376. return EFI_SUCCESS;
  377. }
  378. EFIAPI
  379. EFI_STATUS
  380. EfipBeagleBoneSerialWrite (
  381. EFI_SERIAL_IO_PROTOCOL *This,
  382. UINTN *BufferSize,
  383. VOID *Buffer
  384. )
  385. /*++
  386. Routine Description:
  387. This routine writes data to a serial device.
  388. Arguments:
  389. This - Supplies a pointer to the protocol instance.
  390. BufferSize - Supplies a pointer that on input contains the size of the
  391. buffer. On output, the number of bytes successfully written will be
  392. returned.
  393. Buffer - Supplies a pointer to the data to write.
  394. Return Value:
  395. EFI_SUCCESS if the data was written
  396. EFI_DEVICE_ERROR if the device is not functioning properly.
  397. EFI_TIMEOUT if the operation timed out before the data could be written.
  398. --*/
  399. {
  400. PEFI_BBONE_SERIAL_CONTEXT Device;
  401. UINTN Size;
  402. EFI_STATUS Status;
  403. Size = *BufferSize;
  404. *BufferSize = 0;
  405. Device = EFI_BBONE_SERIAL_FROM_THIS(This);
  406. if (Device->Uart.BaudRateRegister == 0) {
  407. Status = This->Reset(This);
  408. if (EFI_ERROR(Status)) {
  409. return Status;
  410. }
  411. }
  412. Status = EfipUartOmapTransmit(&(Device->Uart), Buffer, Size);
  413. if (EFI_ERROR(Status)) {
  414. return Status;
  415. }
  416. *BufferSize = Size;
  417. return EFI_SUCCESS;
  418. }
  419. EFIAPI
  420. EFI_STATUS
  421. EfipBeagleBoneSerialRead (
  422. EFI_SERIAL_IO_PROTOCOL *This,
  423. UINTN *BufferSize,
  424. VOID *Buffer
  425. )
  426. /*++
  427. Routine Description:
  428. This routine reads data from a serial device.
  429. Arguments:
  430. This - Supplies a pointer to the protocol instance.
  431. BufferSize - Supplies a pointer that on input contains the size of the
  432. buffer. On output, the number of bytes successfully read will be
  433. returned.
  434. Buffer - Supplies a pointer where the read data will be returned on success.
  435. Return Value:
  436. EFI_SUCCESS if the data was read.
  437. EFI_DEVICE_ERROR if the device is not functioning properly.
  438. EFI_TIMEOUT if the operation timed out before the data could be read.
  439. --*/
  440. {
  441. PEFI_BBONE_SERIAL_CONTEXT Device;
  442. EFI_STATUS Status;
  443. Device = EFI_BBONE_SERIAL_FROM_THIS(This);
  444. if (Device->Uart.BaudRateRegister == 0) {
  445. Status = This->Reset(This);
  446. if (EFI_ERROR(Status)) {
  447. return Status;
  448. }
  449. }
  450. Status = EfipUartOmapReceive(&(Device->Uart), Buffer, BufferSize);
  451. if (Status == EFI_NOT_READY) {
  452. Status = EFI_TIMEOUT;
  453. }
  454. if (EFI_ERROR(Status)) {
  455. return Status;
  456. }
  457. return EFI_SUCCESS;
  458. }