]> xenbits.xensource.com Git - ovmf.git/commitdiff
MdePkg: add SBI-based SerialPortLib for RISC-V
authorAndrei Warkentin <andrei.warkentin@intel.com>
Tue, 28 Feb 2023 23:32:03 +0000 (17:32 -0600)
committermergify[bot] <37929162+mergify[bot]@users.noreply.github.com>
Wed, 17 May 2023 23:47:20 +0000 (23:47 +0000)
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>
MdePkg/Library/BaseSerialPortLibRiscVSbiLib/BaseSerialPortLibRiscVSbiLib.c [new file with mode: 0644]
MdePkg/Library/BaseSerialPortLibRiscVSbiLib/BaseSerialPortLibRiscVSbiLib.inf [new file with mode: 0644]
MdePkg/Library/BaseSerialPortLibRiscVSbiLib/BaseSerialPortLibRiscVSbiLib.uni [new file with mode: 0644]
MdePkg/Library/BaseSerialPortLibRiscVSbiLib/BaseSerialPortLibRiscVSbiLibRam.c [new file with mode: 0644]
MdePkg/Library/BaseSerialPortLibRiscVSbiLib/BaseSerialPortLibRiscVSbiLibRam.inf [new file with mode: 0644]
MdePkg/Library/BaseSerialPortLibRiscVSbiLib/Common.c [new file with mode: 0644]
MdePkg/Library/BaseSerialPortLibRiscVSbiLib/Common.h [new file with mode: 0644]
MdePkg/MdePkg.dsc

diff --git a/MdePkg/Library/BaseSerialPortLibRiscVSbiLib/BaseSerialPortLibRiscVSbiLib.c b/MdePkg/Library/BaseSerialPortLibRiscVSbiLib/BaseSerialPortLibRiscVSbiLib.c
new file mode 100644 (file)
index 0000000..f4f2959
--- /dev/null
@@ -0,0 +1,208 @@
+/** @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
diff --git a/MdePkg/Library/BaseSerialPortLibRiscVSbiLib/BaseSerialPortLibRiscVSbiLib.inf b/MdePkg/Library/BaseSerialPortLibRiscVSbiLib/BaseSerialPortLibRiscVSbiLib.inf
new file mode 100644 (file)
index 0000000..2340ac6
--- /dev/null
@@ -0,0 +1,41 @@
+## @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
diff --git a/MdePkg/Library/BaseSerialPortLibRiscVSbiLib/BaseSerialPortLibRiscVSbiLib.uni b/MdePkg/Library/BaseSerialPortLibRiscVSbiLib/BaseSerialPortLibRiscVSbiLib.uni
new file mode 100644 (file)
index 0000000..7b22caa
--- /dev/null
@@ -0,0 +1,16 @@
+// /** @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
diff --git a/MdePkg/Library/BaseSerialPortLibRiscVSbiLib/BaseSerialPortLibRiscVSbiLibRam.c b/MdePkg/Library/BaseSerialPortLibRiscVSbiLib/BaseSerialPortLibRiscVSbiLibRam.c
new file mode 100644 (file)
index 0000000..fafba87
--- /dev/null
@@ -0,0 +1,289 @@
+/** @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
diff --git a/MdePkg/Library/BaseSerialPortLibRiscVSbiLib/BaseSerialPortLibRiscVSbiLibRam.inf b/MdePkg/Library/BaseSerialPortLibRiscVSbiLib/BaseSerialPortLibRiscVSbiLibRam.inf
new file mode 100644 (file)
index 0000000..d09573c
--- /dev/null
@@ -0,0 +1,38 @@
+## @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
diff --git a/MdePkg/Library/BaseSerialPortLibRiscVSbiLib/Common.c b/MdePkg/Library/BaseSerialPortLibRiscVSbiLib/Common.c
new file mode 100644 (file)
index 0000000..4926ac6
--- /dev/null
@@ -0,0 +1,132 @@
+/** @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
diff --git a/MdePkg/Library/BaseSerialPortLibRiscVSbiLib/Common.h b/MdePkg/Library/BaseSerialPortLibRiscVSbiLib/Common.h
new file mode 100644 (file)
index 0000000..98c1a5d
--- /dev/null
@@ -0,0 +1,41 @@
+/** @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
index c850970b23cab804a0a1c7d7c53474d3c006145e..3abd1a1e2310f8c50ba4112078dfec2ce872d77f 100644 (file)
 \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