These are implementations of SerialPortLib using SBI console services.
- BaseSerialPortLibRiscVSbiLib is appropriate for SEC/PEI (XIP)
environments
- BaseSerialPortLibRiscVSbiLibRam is appropriate for PrePI/DXE
environments
Tested with:
- Qemu RiscVVirt (non-DBCN case, backed by UART)
- TinyEMU + RiscVVirt (non-DBCN case, HTIF)
- TinyEMU + RiscVVirt (DBCN case, HTIF)
Cc: Daniel Schaefer <git@danielschaefer.me>
Cc: Sunil V L <sunilvl@ventanamicro.com>
Cc: Michael D Kinney <michael.d.kinney@intel.com>
Cc: Liming Gao <gaoliming@byosoft.com.cn>
Cc: Zhiguang Liu <zhiguang.liu@intel.com>
Signed-off-by: Andrei Warkentin <andrei.warkentin@intel.com>
Acked-by: Gerd Hoffmann <kraxel@redhat.com>
Reviewed-by: Michael D Kinney <michael.d.kinney@intel.com>
--- /dev/null
+/** @file\r
+ Serial Port Library backed by SBI console.\r
+\r
+ Meant for SEC and PEI (XIP) environments.\r
+\r
+ Due to limitations of SBI console interface and XIP environments\r
+ (on use of globals), this library instance does not implement reading\r
+ and polling the serial port. See BaseSerialPortLibRiscVSbiLibRam.c for\r
+ the full-featured variant meant for PrePi and DXE environments.\r
+\r
+ Copyright (c) 2023, Intel Corporation. All rights reserved.<BR>\r
+ SPDX-License-Identifier: BSD-2-Clause-Patent\r
+\r
+**/\r
+\r
+#include "Common.h"\r
+\r
+/**\r
+ Initialize the serial device hardware.\r
+\r
+ If no initialization is required, then return RETURN_SUCCESS.\r
+ If the serial device was successfully initialized, then return RETURN_SUCCESS.\r
+ If the serial device could not be initialized, then return RETURN_DEVICE_ERROR.\r
+\r
+ @retval RETURN_SUCCESS The serial device was initialized.\r
+ @retval RETURN_DEVICE_ERROR The serial device could not be initialized.\r
+\r
+**/\r
+RETURN_STATUS\r
+EFIAPI\r
+SerialPortInitialize (\r
+ VOID\r
+ )\r
+{\r
+ return RETURN_SUCCESS;\r
+}\r
+\r
+/**\r
+ Write data from buffer to serial device.\r
+\r
+ Writes NumberOfBytes data bytes from Buffer to the serial device.\r
+ The number of bytes actually written to the serial device is returned.\r
+ If the return value is less than NumberOfBytes, then the write operation failed.\r
+ If NumberOfBytes is zero, then return 0.\r
+\r
+ @param Buffer The pointer to the data buffer to be written.\r
+ @param NumberOfBytes The number of bytes to written to the serial device.\r
+\r
+ @retval 0 NumberOfBytes is 0.\r
+ @retval >0 The number of bytes written to the serial device.\r
+ If this value is less than NumberOfBytes, then the write operation failed.\r
+\r
+**/\r
+UINTN\r
+EFIAPI\r
+SerialPortWrite (\r
+ IN UINT8 *Buffer,\r
+ IN UINTN NumberOfBytes\r
+ )\r
+{\r
+ if (NumberOfBytes == 0) {\r
+ return 0;\r
+ }\r
+\r
+ if (SbiImplementsDbcn ()) {\r
+ return SbiDbcnWrite (Buffer, NumberOfBytes);\r
+ }\r
+\r
+ if (SbiImplementsLegacyPutchar ()) {\r
+ return SbiLegacyPutchar (Buffer, NumberOfBytes);\r
+ }\r
+\r
+ /*\r
+ * Neither DBCN or legacy extension were present.\r
+ */\r
+ return 0;\r
+}\r
+\r
+/**\r
+ Read data from serial device and save the datas in buffer.\r
+\r
+ Reads NumberOfBytes data bytes from a serial device into the buffer\r
+ specified by Buffer. The number of bytes actually read is returned.\r
+ If the return value is less than NumberOfBytes, then the rest operation failed.\r
+ If NumberOfBytes is zero, then return 0.\r
+\r
+ @param Buffer The pointer to the data buffer to store the data read from the serial device.\r
+ @param NumberOfBytes The number of bytes which will be read.\r
+\r
+ @retval 0 Read data failed; No data is to be read.\r
+ @retval >0 The actual number of bytes read from serial device.\r
+\r
+**/\r
+UINTN\r
+EFIAPI\r
+SerialPortRead (\r
+ OUT UINT8 *Buffer,\r
+ IN UINTN NumberOfBytes\r
+ )\r
+{\r
+ return 0;\r
+}\r
+\r
+/**\r
+ Polls a serial device to see if there is any data waiting to be read.\r
+\r
+ Polls a serial device to see if there is any data waiting to be read.\r
+ If there is data waiting to be read from the serial device, then TRUE is returned.\r
+ If there is no data waiting to be read from the serial device, then FALSE is returned.\r
+\r
+ @retval TRUE Data is waiting to be read from the serial device.\r
+ @retval FALSE There is no data waiting to be read from the serial device.\r
+\r
+**/\r
+BOOLEAN\r
+EFIAPI\r
+SerialPortPoll (\r
+ VOID\r
+ )\r
+{\r
+ return FALSE;\r
+}\r
+\r
+/**\r
+ Sets the control bits on a serial device.\r
+\r
+ @param Control Sets the bits of Control that are settable.\r
+\r
+ @retval RETURN_SUCCESS The new control bits were set on the serial device.\r
+ @retval RETURN_UNSUPPORTED The serial device does not support this operation.\r
+ @retval RETURN_DEVICE_ERROR The serial device is not functioning correctly.\r
+\r
+**/\r
+RETURN_STATUS\r
+EFIAPI\r
+SerialPortSetControl (\r
+ IN UINT32 Control\r
+ )\r
+{\r
+ return RETURN_SUCCESS;\r
+}\r
+\r
+/**\r
+ Retrieve the status of the control bits on a serial device.\r
+\r
+ @param Control A pointer to return the current control signals from the serial device.\r
+\r
+ @retval RETURN_SUCCESS The control bits were read from the serial device.\r
+ @retval RETURN_UNSUPPORTED The serial device does not support this operation.\r
+ @retval RETURN_DEVICE_ERROR The serial device is not functioning correctly.\r
+\r
+**/\r
+RETURN_STATUS\r
+EFIAPI\r
+SerialPortGetControl (\r
+ OUT UINT32 *Control\r
+ )\r
+{\r
+ *Control = 0;\r
+ return RETURN_SUCCESS;\r
+}\r
+\r
+/**\r
+ Sets the baud rate, receive FIFO depth, transmit/receice time out, parity,\r
+ data bits, and stop bits on a serial device.\r
+\r
+ @param BaudRate The requested baud rate. A BaudRate value of 0 will use the\r
+ device's default interface speed.\r
+ On output, the value actually set.\r
+ @param ReveiveFifoDepth The requested depth of the FIFO on the receive side of the\r
+ serial interface. A ReceiveFifoDepth value of 0 will use\r
+ the device's default FIFO depth.\r
+ On output, the value actually set.\r
+ @param Timeout The requested time out for a single character in microseconds.\r
+ This timeout applies to both the transmit and receive side of the\r
+ interface. A Timeout value of 0 will use the device's default time\r
+ out value.\r
+ On output, the value actually set.\r
+ @param Parity The type of parity to use on this serial device. A Parity value of\r
+ DefaultParity will use the device's default parity value.\r
+ On output, the value actually set.\r
+ @param DataBits The number of data bits to use on the serial device. A DataBits\r
+ vaule of 0 will use the device's default data bit setting.\r
+ On output, the value actually set.\r
+ @param StopBits The number of stop bits to use on this serial device. A StopBits\r
+ value of DefaultStopBits will use the device's default number of\r
+ stop bits.\r
+ On output, the value actually set.\r
+\r
+ @retval RETURN_SUCCESS The new attributes were set on the serial device.\r
+ @retval RETURN_UNSUPPORTED The serial device does not support this operation.\r
+ @retval RETURN_INVALID_PARAMETER One or more of the attributes has an unsupported value.\r
+ @retval RETURN_DEVICE_ERROR The serial device is not functioning correctly.\r
+\r
+**/\r
+RETURN_STATUS\r
+EFIAPI\r
+SerialPortSetAttributes (\r
+ IN OUT UINT64 *BaudRate,\r
+ IN OUT UINT32 *ReceiveFifoDepth,\r
+ IN OUT UINT32 *Timeout,\r
+ IN OUT EFI_PARITY_TYPE *Parity,\r
+ IN OUT UINT8 *DataBits,\r
+ IN OUT EFI_STOP_BITS_TYPE *StopBits\r
+ )\r
+{\r
+ return RETURN_SUCCESS;\r
+}\r
--- /dev/null
+## @file\r
+# Serial Port Library backed by SBI console.\r
+#\r
+# Meant for SEC and PEI (XIP) environments.\r
+#\r
+# Due to limitations of SBI console interface and XIP environments\r
+# (on use of globals), this library instance does not implement reading\r
+# and polling the serial port. See PrePiDxeSerialPortLibRiscVSbiRam.inf\r
+# for the full-featured variant meant for PrePi and DXE environments.\r
+#\r
+# Copyright (c) 2023, Intel Corporation. All rights reserved.<BR>\r
+#\r
+# SPDX-License-Identifier: BSD-2-Clause-Patent\r
+#\r
+#\r
+##\r
+\r
+[Defines]\r
+ INF_VERSION = 0x0001001B\r
+ BASE_NAME = BaseSerialPortLibRiscVSbiLib\r
+ MODULE_UNI_FILE = BaseSerialPortLibRiscVSbiLib.uni\r
+ FILE_GUID = 639fad38-4bfd-4eb9-9f09-e97c7947d480\r
+ MODULE_TYPE = BASE\r
+ VERSION_STRING = 1.0\r
+ LIBRARY_CLASS = SerialPortLib | SEC PEI_CORE PEIM\r
+\r
+\r
+#\r
+# VALID_ARCHITECTURES = RISCV64\r
+#\r
+\r
+[Sources]\r
+ BaseSerialPortLibRiscVSbiLib.c\r
+ Common.c\r
+ Common.h\r
+\r
+[Packages]\r
+ MdePkg/MdePkg.dec\r
+\r
+[LibraryClasses]\r
+ RiscVSbiLib\r
--- /dev/null
+// /** @file\r
+// Serial Port Library backed by SBI console.\r
+//\r
+// Serial Port Library backed by SBI console.\r
+//\r
+// Copyright (c) 2023, Intel Corporation. All rights reserved.<BR>\r
+//\r
+// SPDX-License-Identifier: BSD-2-Clause-Patent\r
+//\r
+// **/\r
+\r
+\r
+#string STR_MODULE_ABSTRACT #language en-US "Serial Port Library backed by SBI console"\r
+\r
+#string STR_MODULE_DESCRIPTION #language en-US "Serial Port Library backed by SBI console."\r
+\r
--- /dev/null
+/** @file\r
+ Serial Port Library backed by SBI console.\r
+\r
+ Meant for PrePi and DXE environments (where globals are allowed). See\r
+ BaseSerialPortLibRiscVSbiLib.c for a reduced variant appropriate for\r
+ SEC and PEI (XIP) environments.\r
+\r
+ Copyright (c) 2023, Intel Corporation. All rights reserved.<BR>\r
+ SPDX-License-Identifier: BSD-2-Clause-Patent\r
+\r
+**/\r
+\r
+#include <Base.h>\r
+#include <Library/SerialPortLib.h>\r
+#include <Library/BaseRiscVSbiLib.h>\r
+#include "Common.h"\r
+\r
+STATIC BOOLEAN mHaveDbcn = FALSE;\r
+STATIC BOOLEAN mHaveLegacyPutchar = FALSE;\r
+STATIC BOOLEAN mHaveLegacyGetchar = FALSE;\r
+STATIC INT64 mLastGetChar = -1;\r
+\r
+/**\r
+ Return whether the legacy console getchar extension is implemented.\r
+\r
+ @retval TRUE Extension is implemented.\r
+ @retval FALSE Extension is not implemented.\r
+\r
+**/\r
+STATIC\r
+BOOLEAN\r
+SbiImplementsLegacyGetchar (\r
+ VOID\r
+ )\r
+{\r
+ SBI_RET Ret;\r
+\r
+ Ret = SbiCall (SBI_EXT_BASE, SBI_EXT_BASE_PROBE_EXT, 1, SBI_EXT_0_1_CONSOLE_GETCHAR);\r
+ if ((TranslateError (Ret.Error) == EFI_SUCCESS) &&\r
+ (Ret.Value != 0))\r
+ {\r
+ return TRUE;\r
+ }\r
+\r
+ return FALSE;\r
+}\r
+\r
+/**\r
+ Initialize the serial device hardware.\r
+\r
+ If no initialization is required, then return RETURN_SUCCESS.\r
+ If the serial device was successfully initialized, then return RETURN_SUCCESS.\r
+ If the serial device could not be initialized, then return RETURN_DEVICE_ERROR.\r
+\r
+ @retval RETURN_SUCCESS The serial device was initialized.\r
+ @retval RETURN_DEVICE_ERROR The serial device could not be initialized.\r
+\r
+**/\r
+RETURN_STATUS\r
+EFIAPI\r
+SerialPortInitialize (\r
+ VOID\r
+ )\r
+{\r
+ if (SbiImplementsDbcn ()) {\r
+ mHaveDbcn = TRUE;\r
+ return RETURN_SUCCESS;\r
+ }\r
+\r
+ if (SbiImplementsLegacyPutchar ()) {\r
+ mHaveLegacyPutchar = TRUE;\r
+ }\r
+\r
+ if (SbiImplementsLegacyGetchar ()) {\r
+ mHaveLegacyGetchar = TRUE;\r
+ }\r
+\r
+ return (mHaveLegacyGetchar && mHaveLegacyPutchar) ?\r
+ RETURN_SUCCESS :\r
+ RETURN_DEVICE_ERROR;\r
+}\r
+\r
+/**\r
+ Write data from buffer to serial device.\r
+\r
+ Writes NumberOfBytes data bytes from Buffer to the serial device.\r
+ The number of bytes actually written to the serial device is returned.\r
+ If the return value is less than NumberOfBytes, then the write operation failed.\r
+ If NumberOfBytes is zero, then return 0.\r
+\r
+ @param Buffer The pointer to the data buffer to be written.\r
+ @param NumberOfBytes The number of bytes to written to the serial device.\r
+\r
+ @retval 0 NumberOfBytes is 0.\r
+ @retval >0 The number of bytes written to the serial device.\r
+ If this value is less than NumberOfBytes, then the write operation failed.\r
+\r
+**/\r
+UINTN\r
+EFIAPI\r
+SerialPortWrite (\r
+ IN UINT8 *Buffer,\r
+ IN UINTN NumberOfBytes\r
+ )\r
+{\r
+ if (NumberOfBytes == 0) {\r
+ return 0;\r
+ }\r
+\r
+ if (mHaveDbcn) {\r
+ return SbiDbcnWrite (Buffer, NumberOfBytes);\r
+ } else if (mHaveLegacyPutchar) {\r
+ return SbiLegacyPutchar (Buffer, NumberOfBytes);\r
+ }\r
+\r
+ /*\r
+ * Neither DBCN or legacy extension were present.\r
+ */\r
+ return 0;\r
+}\r
+\r
+/**\r
+ Read data from serial device and save the datas in buffer.\r
+\r
+ Reads NumberOfBytes data bytes from a serial device into the buffer\r
+ specified by Buffer. The number of bytes actually read is returned.\r
+ If the return value is less than NumberOfBytes, then the rest operation failed.\r
+ If NumberOfBytes is zero, then return 0.\r
+\r
+ @param Buffer The pointer to the data buffer to store the data read from the serial device.\r
+ @param NumberOfBytes The number of bytes which will be read.\r
+\r
+ @retval 0 Read data failed; No data is to be read.\r
+ @retval >0 The actual number of bytes read from serial device.\r
+\r
+**/\r
+UINTN\r
+EFIAPI\r
+SerialPortRead (\r
+ OUT UINT8 *Buffer,\r
+ IN UINTN NumberOfBytes\r
+ )\r
+{\r
+ UINTN Index;\r
+\r
+ Index = 0;\r
+ while ((Index < NumberOfBytes) && SerialPortPoll ()) {\r
+ Buffer[Index++] = (UINT8)mLastGetChar;\r
+ mLastGetChar = -1;\r
+ }\r
+\r
+ return Index;\r
+}\r
+\r
+/**\r
+ Polls a serial device to see if there is any data waiting to be read.\r
+\r
+ Polls a serial device to see if there is any data waiting to be read.\r
+ If there is data waiting to be read from the serial device, then TRUE is returned.\r
+ If there is no data waiting to be read from the serial device, then FALSE is returned.\r
+\r
+ @retval TRUE Data is waiting to be read from the serial device.\r
+ @retval FALSE There is no data waiting to be read from the serial device.\r
+\r
+**/\r
+BOOLEAN\r
+EFIAPI\r
+SerialPortPoll (\r
+ VOID\r
+ )\r
+{\r
+ /*\r
+ * Careful. OpenSBI with HTIF console will return -1 followed by -2\r
+ * if there is no character received. So just check for values >= 0.\r
+ */\r
+\r
+ if (mLastGetChar >= 0) {\r
+ return TRUE;\r
+ }\r
+\r
+ if (mHaveDbcn) {\r
+ UINT8 Buffer;\r
+ SBI_RET Ret;\r
+\r
+ Ret = SbiCall (\r
+ SBI_EXT_DBCN,\r
+ SBI_EXT_DBCN_READ,\r
+ 3,\r
+ 1,\r
+ ((UINTN)&Buffer),\r
+ 0\r
+ );\r
+ if ((TranslateError (Ret.Error) == EFI_SUCCESS) &&\r
+ (Ret.Value == 1))\r
+ {\r
+ mLastGetChar = Buffer;\r
+ }\r
+ } else if (mHaveLegacyGetchar) {\r
+ mLastGetChar = (INT64)SbiCall (SBI_EXT_0_1_CONSOLE_GETCHAR, 0, 0).Error;\r
+ }\r
+\r
+ return mLastGetChar >= 0;\r
+}\r
+\r
+/**\r
+ Sets the control bits on a serial device.\r
+\r
+ @param Control Sets the bits of Control that are settable.\r
+\r
+ @retval RETURN_SUCCESS The new control bits were set on the serial device.\r
+ @retval RETURN_UNSUPPORTED The serial device does not support this operation.\r
+ @retval RETURN_DEVICE_ERROR The serial device is not functioning correctly.\r
+\r
+**/\r
+RETURN_STATUS\r
+EFIAPI\r
+SerialPortSetControl (\r
+ IN UINT32 Control\r
+ )\r
+{\r
+ return RETURN_SUCCESS;\r
+}\r
+\r
+/**\r
+ Retrieve the status of the control bits on a serial device.\r
+\r
+ @param Control A pointer to return the current control signals from the serial device.\r
+\r
+ @retval RETURN_SUCCESS The control bits were read from the serial device.\r
+ @retval RETURN_UNSUPPORTED The serial device does not support this operation.\r
+ @retval RETURN_DEVICE_ERROR The serial device is not functioning correctly.\r
+\r
+**/\r
+RETURN_STATUS\r
+EFIAPI\r
+SerialPortGetControl (\r
+ OUT UINT32 *Control\r
+ )\r
+{\r
+ *Control = 0;\r
+ return RETURN_SUCCESS;\r
+}\r
+\r
+/**\r
+ Sets the baud rate, receive FIFO depth, transmit/receice time out, parity,\r
+ data bits, and stop bits on a serial device.\r
+\r
+ @param BaudRate The requested baud rate. A BaudRate value of 0 will use the\r
+ device's default interface speed.\r
+ On output, the value actually set.\r
+ @param ReveiveFifoDepth The requested depth of the FIFO on the receive side of the\r
+ serial interface. A ReceiveFifoDepth value of 0 will use\r
+ the device's default FIFO depth.\r
+ On output, the value actually set.\r
+ @param Timeout The requested time out for a single character in microseconds.\r
+ This timeout applies to both the transmit and receive side of the\r
+ interface. A Timeout value of 0 will use the device's default time\r
+ out value.\r
+ On output, the value actually set.\r
+ @param Parity The type of parity to use on this serial device. A Parity value of\r
+ DefaultParity will use the device's default parity value.\r
+ On output, the value actually set.\r
+ @param DataBits The number of data bits to use on the serial device. A DataBits\r
+ vaule of 0 will use the device's default data bit setting.\r
+ On output, the value actually set.\r
+ @param StopBits The number of stop bits to use on this serial device. A StopBits\r
+ value of DefaultStopBits will use the device's default number of\r
+ stop bits.\r
+ On output, the value actually set.\r
+\r
+ @retval RETURN_SUCCESS The new attributes were set on the serial device.\r
+ @retval RETURN_UNSUPPORTED The serial device does not support this operation.\r
+ @retval RETURN_INVALID_PARAMETER One or more of the attributes has an unsupported value.\r
+ @retval RETURN_DEVICE_ERROR The serial device is not functioning correctly.\r
+\r
+**/\r
+RETURN_STATUS\r
+EFIAPI\r
+SerialPortSetAttributes (\r
+ IN OUT UINT64 *BaudRate,\r
+ IN OUT UINT32 *ReceiveFifoDepth,\r
+ IN OUT UINT32 *Timeout,\r
+ IN OUT EFI_PARITY_TYPE *Parity,\r
+ IN OUT UINT8 *DataBits,\r
+ IN OUT EFI_STOP_BITS_TYPE *StopBits\r
+ )\r
+{\r
+ return RETURN_SUCCESS;\r
+}\r
--- /dev/null
+## @file\r
+# Serial Port Library backed by SBI console.\r
+#\r
+# Meant for PrePi and DXE environments (where globals are allowed). See\r
+# BaseSerialPortLibRiscVSbiLib.inf for a reduced variant appropriate\r
+# for SEC and PEI (XIP) environments.\r
+#\r
+# Copyright (c) 2023, Intel Corporation. All rights reserved.<BR>\r
+#\r
+# SPDX-License-Identifier: BSD-2-Clause-Patent\r
+#\r
+#\r
+##\r
+\r
+[Defines]\r
+ INF_VERSION = 0x0001001B\r
+ BASE_NAME = BaseSerialPortLibRiscVSbiLibRam\r
+ MODULE_UNI_FILE = BaseSerialPortLibRiscVSbiLib.uni\r
+ FILE_GUID = 872af743-ab56-45b4-a065-602567f4820c\r
+ MODULE_TYPE = BASE\r
+ VERSION_STRING = 1.0\r
+ LIBRARY_CLASS = SerialPortLib | SEC DXE_CORE DXE_DRIVER DXE_RUNTIME_DRIVER UEFI_DRIVER UEFI_APPLICATION\r
+\r
+\r
+#\r
+# VALID_ARCHITECTURES = RISCV64\r
+#\r
+\r
+[Sources]\r
+ BaseSerialPortLibRiscVSbiLibRam.c\r
+ Common.c\r
+ Common.h\r
+\r
+[Packages]\r
+ MdePkg/MdePkg.dec\r
+\r
+[LibraryClasses]\r
+ RiscVSbiLib\r
--- /dev/null
+/** @file\r
+ Serial Port Library backed by SBI console.\r
+\r
+ Common functionality shared by PrePiDxeSerialPortLibRiscVSbi and\r
+ PrePiDxeSerialPortLibRiscVSbiRam implementations.\r
+\r
+ Copyright (c) 2023, Intel Corporation. All rights reserved.<BR>\r
+ SPDX-License-Identifier: BSD-2-Clause-Patent\r
+\r
+**/\r
+\r
+#include "Common.h"\r
+\r
+/**\r
+ Return whether the DBCN extension is implemented.\r
+\r
+ @retval TRUE Extension is implemented.\r
+ @retval FALSE Extension is not implemented.\r
+\r
+**/\r
+BOOLEAN\r
+SbiImplementsDbcn (\r
+ VOID\r
+ )\r
+{\r
+ SBI_RET Ret;\r
+\r
+ Ret = SbiCall (SBI_EXT_BASE, SBI_EXT_BASE_PROBE_EXT, 1, SBI_EXT_DBCN);\r
+ if ((TranslateError (Ret.Error) == EFI_SUCCESS) &&\r
+ (Ret.Value != 0))\r
+ {\r
+ return TRUE;\r
+ }\r
+\r
+ return FALSE;\r
+}\r
+\r
+/**\r
+ Return whether the legacy console putchar extension is implemented.\r
+\r
+ @retval TRUE Extension is implemented.\r
+ @retval FALSE Extension is not implemented.\r
+\r
+**/\r
+BOOLEAN\r
+SbiImplementsLegacyPutchar (\r
+ VOID\r
+ )\r
+{\r
+ SBI_RET Ret;\r
+\r
+ Ret = SbiCall (SBI_EXT_BASE, SBI_EXT_BASE_PROBE_EXT, 1, SBI_EXT_0_1_CONSOLE_PUTCHAR);\r
+ if ((TranslateError (Ret.Error) == EFI_SUCCESS) &&\r
+ (Ret.Value != 0))\r
+ {\r
+ return TRUE;\r
+ }\r
+\r
+ return FALSE;\r
+}\r
+\r
+/**\r
+ Write data from buffer to console via SBI legacy putchar extension.\r
+\r
+ The number of bytes actually written to the SBI console is returned.\r
+ If the return value is less than NumberOfBytes, then the write operation failed.\r
+\r
+ @param Buffer The pointer to the data buffer to be written.\r
+ @param NumberOfBytes The number of bytes to written to the serial device.\r
+\r
+ @retval >=0 The number of bytes written to the serial device.\r
+ If this value is less than NumberOfBytes, then the\r
+ write operation failed.\r
+\r
+**/\r
+UINTN\r
+SbiLegacyPutchar (\r
+ IN UINT8 *Buffer,\r
+ IN UINTN NumberOfBytes\r
+ )\r
+{\r
+ SBI_RET Ret;\r
+ UINTN Index;\r
+\r
+ for (Index = 0; Index < NumberOfBytes; Index++) {\r
+ Ret = SbiCall (SBI_EXT_0_1_CONSOLE_PUTCHAR, 0, 1, Buffer[Index]);\r
+ if ((INT64)Ret.Error < 0) {\r
+ break;\r
+ }\r
+ }\r
+\r
+ return Index;\r
+}\r
+\r
+/**\r
+ Write data from buffer to console via SBI DBCN.\r
+\r
+ The number of bytes actually written to the SBI console is returned.\r
+ If the return value is less than NumberOfBytes, then the write operation failed.\r
+\r
+ @param Buffer The pointer to the data buffer to be written.\r
+ @param NumberOfBytes The number of bytes to written to the serial device.\r
+\r
+ @retval >=0 The number of bytes written to the serial device.\r
+ If this value is less than NumberOfBytes, then the\r
+ write operation failed.\r
+\r
+**/\r
+UINTN\r
+SbiDbcnWrite (\r
+ IN UINT8 *Buffer,\r
+ IN UINTN NumberOfBytes\r
+ )\r
+{\r
+ SBI_RET Ret;\r
+\r
+ Ret = SbiCall (\r
+ SBI_EXT_DBCN,\r
+ SBI_EXT_DBCN_WRITE,\r
+ 3,\r
+ NumberOfBytes,\r
+ ((UINTN)Buffer),\r
+ 0\r
+ );\r
+\r
+ /*\r
+ * May do partial writes. Don't bother decoding\r
+ * Ret.Error as we're only interested in number of\r
+ * bytes written to console.\r
+ */\r
+ return Ret.Value;\r
+}\r
--- /dev/null
+/** @file\r
+ Serial Port Library backed by SBI console.\r
+\r
+ Common functionality shared by PrePiDxeSerialPortLibRiscVSbi and\r
+ PrePiDxeSerialPortLibRiscVSbiRam implementations.\r
+\r
+ Copyright (c) 2023, Intel Corporation. All rights reserved.<BR>\r
+ SPDX-License-Identifier: BSD-2-Clause-Patent\r
+\r
+**/\r
+\r
+#ifndef SERIAL_PORT_SBI_COMMON_H_\r
+#define SERIAL_PORT_SBI_COMMON_H_\r
+\r
+#include <Base.h>\r
+#include <Library/SerialPortLib.h>\r
+#include <Library/BaseRiscVSbiLib.h>\r
+\r
+BOOLEAN\r
+SbiImplementsDbcn (\r
+ VOID\r
+ );\r
+\r
+BOOLEAN\r
+SbiImplementsLegacyPutchar (\r
+ VOID\r
+ );\r
+\r
+UINTN\r
+SbiLegacyPutchar (\r
+ IN UINT8 *Buffer,\r
+ IN UINTN NumberOfBytes\r
+ );\r
+\r
+UINTN\r
+SbiDbcnWrite (\r
+ IN UINT8 *Buffer,\r
+ IN UINTN NumberOfBytes\r
+ );\r
+\r
+#endif /* SERIAL_PORT_SBI_COMMON_H_ */\r
\r
[Components.RISCV64]\r
MdePkg/Library/BaseRiscVSbiLib/BaseRiscVSbiLib.inf\r
+ MdePkg/Library/BaseSerialPortLibRiscVSbiLib/BaseSerialPortLibRiscVSbiLib.inf\r
+ MdePkg/Library/BaseSerialPortLibRiscVSbiLib/BaseSerialPortLibRiscVSbiLibRam.inf\r
\r
[BuildOptions]\r