]> git.proxmox.com Git - mirror_edk2.git/commitdiff
Ovmf/Xen: add Xen PV console SerialPortLib driver
authorArd Biesheuvel <ard.biesheuvel@linaro.org>
Sat, 28 Feb 2015 20:33:45 +0000 (20:33 +0000)
committerlersek <lersek@Edk2>
Sat, 28 Feb 2015 20:33:45 +0000 (20:33 +0000)
This implements a SerialPortLib instance that wires up to the
PV console ring used by domU guests. Also imports the required
upstream Xen io/console.h header.

Contributed-under: TianoCore Contribution Agreement 1.0
Reviewed-by: Stefano Stabellini <stefano.stabellini@eu.citrix.com>
Acked-by: Laszlo Ersek <lersek@redhat.com>
Signed-off-by: Ard Biesheuvel <ard.biesheuvel@linaro.org>
Signed-off-by: Laszlo Ersek <lersek@redhat.com>
git-svn-id: https://svn.code.sf.net/p/edk2/code/trunk/edk2@16976 6f19259b-4bc3-4df7-8a09-765794883524

OvmfPkg/Include/IndustryStandard/Xen/io/console.h [new file with mode: 0644]
OvmfPkg/Library/XenConsoleSerialPortLib/XenConsoleSerialPortLib.c [new file with mode: 0644]
OvmfPkg/Library/XenConsoleSerialPortLib/XenConsoleSerialPortLib.inf [new file with mode: 0644]

diff --git a/OvmfPkg/Include/IndustryStandard/Xen/io/console.h b/OvmfPkg/Include/IndustryStandard/Xen/io/console.h
new file mode 100644 (file)
index 0000000..f1caa97
--- /dev/null
@@ -0,0 +1,51 @@
+/******************************************************************************\r
+ * console.h\r
+ *\r
+ * Console I/O interface for Xen guest OSes.\r
+ *\r
+ * Permission is hereby granted, free of charge, to any person obtaining a copy\r
+ * of this software and associated documentation files (the "Software"), to\r
+ * deal in the Software without restriction, including without limitation the\r
+ * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or\r
+ * sell copies of the Software, and to permit persons to whom the Software is\r
+ * furnished to do so, subject to the following conditions:\r
+ *\r
+ * The above copyright notice and this permission notice shall be included in\r
+ * all copies or substantial portions of the Software.\r
+ *\r
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\r
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\r
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\r
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\r
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING\r
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\r
+ * DEALINGS IN THE SOFTWARE.\r
+ *\r
+ * Copyright (c) 2005, Keir Fraser\r
+ */\r
+\r
+#ifndef __XEN_PUBLIC_IO_CONSOLE_H__\r
+#define __XEN_PUBLIC_IO_CONSOLE_H__\r
+\r
+typedef UINT32 XENCONS_RING_IDX;\r
+\r
+#define MASK_XENCONS_IDX(idx, ring) ((idx) & (sizeof(ring)-1))\r
+\r
+struct xencons_interface {\r
+    char in[1024];\r
+    char out[2048];\r
+    XENCONS_RING_IDX in_cons, in_prod;\r
+    XENCONS_RING_IDX out_cons, out_prod;\r
+};\r
+\r
+#endif /* __XEN_PUBLIC_IO_CONSOLE_H__ */\r
+\r
+/*\r
+ * Local variables:\r
+ * mode: C\r
+ * c-file-style: "BSD"\r
+ * c-basic-offset: 4\r
+ * tab-width: 4\r
+ * indent-tabs-mode: nil\r
+ * End:\r
+ */\r
diff --git a/OvmfPkg/Library/XenConsoleSerialPortLib/XenConsoleSerialPortLib.c b/OvmfPkg/Library/XenConsoleSerialPortLib/XenConsoleSerialPortLib.c
new file mode 100644 (file)
index 0000000..9802235
--- /dev/null
@@ -0,0 +1,156 @@
+/** @file\r
+  Xen console SerialPortLib instance\r
+\r
+  Copyright (c) 2015, Linaro Ltd. All rights reserved.<BR>\r
+\r
+  This program and the accompanying materials\r
+  are licensed and made available under the terms and conditions of the BSD License\r
+  which accompanies this distribution.  The full text of the license may be found at\r
+  http://opensource.org/licenses/bsd-license.php\r
+\r
+  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
+  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
+\r
+**/\r
+\r
+#include <Base.h>\r
+#include <Uefi/UefiBaseType.h>\r
+\r
+#include <Library/BaseLib.h>\r
+#include <Library/SerialPortLib.h>\r
+#include <Library/XenHypercallLib.h>\r
+\r
+#include <IndustryStandard/Xen/io/console.h>\r
+#include <IndustryStandard/Xen/hvm/params.h>\r
+#include <IndustryStandard/Xen/event_channel.h>\r
+\r
+//\r
+// The code below expects these global variables to be mutable, even in the case\r
+// that we have been incorporated into SEC or PEIM phase modules (which is\r
+// allowed by our INF description). While this is a dangerous assumption to make\r
+// in general, it is actually fine for the Xen domU (guest) environment that\r
+// this module is intended for, as UEFI always executes from DRAM in that case.\r
+//\r
+STATIC evtchn_send_t              mXenConsoleEventChain;\r
+STATIC struct xencons_interface   *mXenConsoleInterface;\r
+\r
+RETURN_STATUS\r
+EFIAPI\r
+SerialPortInitialize (\r
+  VOID\r
+  )\r
+{\r
+  if (!mXenConsoleInterface) {\r
+    mXenConsoleEventChain.port = (UINT32)XenHypercallHvmGetParam (HVM_PARAM_CONSOLE_EVTCHN);\r
+    mXenConsoleInterface = (struct xencons_interface *)(UINTN)\r
+      (XenHypercallHvmGetParam (HVM_PARAM_CONSOLE_PFN) << EFI_PAGE_SHIFT);\r
+\r
+    //\r
+    // No point in ASSERT'ing here as we won't be seeing the output\r
+    //\r
+  }\r
+  return RETURN_SUCCESS;\r
+}\r
+\r
+/**\r
+  Write data to serial device.\r
+\r
+  @param  Buffer           Point of data buffer which need to be written.\r
+  @param  NumberOfBytes    Number of output bytes which are cached in Buffer.\r
+\r
+  @retval 0                Write data failed.\r
+  @retval !0               Actual number of bytes written to serial device.\r
+\r
+**/\r
+UINTN\r
+EFIAPI\r
+SerialPortWrite (\r
+  IN UINT8     *Buffer,\r
+  IN UINTN     NumberOfBytes\r
+  )\r
+{\r
+  XENCONS_RING_IDX  Consumer, Producer;\r
+  UINTN             Sent;\r
+\r
+  if (!mXenConsoleInterface) {\r
+    return 0;\r
+  }\r
+\r
+  Consumer = mXenConsoleInterface->out_cons;\r
+  Producer = mXenConsoleInterface->out_prod;\r
+\r
+  MemoryFence ();\r
+\r
+  Sent = 0;\r
+  while (Sent < NumberOfBytes && ((Producer - Consumer) < sizeof (mXenConsoleInterface->out)))\r
+    mXenConsoleInterface->out[MASK_XENCONS_IDX(Producer++, mXenConsoleInterface->out)] = Buffer[Sent++];\r
+\r
+  MemoryFence ();\r
+\r
+  mXenConsoleInterface->out_prod = Producer;\r
+\r
+  if (Sent > 0) {\r
+    XenHypercallEventChannelOp (EVTCHNOP_send, &mXenConsoleEventChain);\r
+  }\r
+\r
+  return Sent;\r
+}\r
+\r
+/**\r
+  Read data from serial device and save the data in buffer.\r
+\r
+  @param  Buffer           Point of data buffer which need to be written.\r
+  @param  NumberOfBytes    Size of Buffer[].\r
+\r
+  @retval 0                Read data failed.\r
+  @retval !0               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
+  XENCONS_RING_IDX  Consumer, Producer;\r
+  UINTN             Received;\r
+\r
+  if (!mXenConsoleInterface) {\r
+    return 0;\r
+  }\r
+\r
+  Consumer = mXenConsoleInterface->in_cons;\r
+  Producer = mXenConsoleInterface->in_prod;\r
+\r
+  MemoryFence ();\r
+\r
+  Received = 0;\r
+  while (Received < NumberOfBytes && Consumer < Producer)\r
+     Buffer[Received++] = mXenConsoleInterface->in[MASK_XENCONS_IDX(Consumer++, mXenConsoleInterface->in)];\r
+\r
+  MemoryFence ();\r
+\r
+  mXenConsoleInterface->in_cons = Consumer;\r
+\r
+  XenHypercallEventChannelOp (EVTCHNOP_send, &mXenConsoleEventChain);\r
+\r
+  return Received;\r
+}\r
+\r
+/**\r
+  Check to see if any data is available to be read from the debug device.\r
+\r
+  @retval TRUE       At least one byte of data is available to be read\r
+  @retval FALSE      No data is available to be read\r
+\r
+**/\r
+BOOLEAN\r
+EFIAPI\r
+SerialPortPoll (\r
+  VOID\r
+  )\r
+{\r
+  return mXenConsoleInterface &&\r
+    mXenConsoleInterface->in_cons != mXenConsoleInterface->in_prod;\r
+}\r
diff --git a/OvmfPkg/Library/XenConsoleSerialPortLib/XenConsoleSerialPortLib.inf b/OvmfPkg/Library/XenConsoleSerialPortLib/XenConsoleSerialPortLib.inf
new file mode 100644 (file)
index 0000000..8a74115
--- /dev/null
@@ -0,0 +1,35 @@
+#/** @file\r
+#\r
+#  Component description file for XenConsoleSerialPortLib module\r
+#\r
+#  Copyright (c) 2015, Linaro Ltd. All rights reserved.<BR>\r
+#\r
+#  This program and the accompanying materials\r
+#  are licensed and made available under the terms and conditions of the BSD License\r
+#  which accompanies this distribution.  The full text of the license may be found at\r
+#  http://opensource.org/licenses/bsd-license.php\r
+#\r
+#  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
+#  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
+#\r
+#**/\r
+\r
+[Defines]\r
+  INF_VERSION                    = 0x00010005\r
+  BASE_NAME                      = XenConsoleSerialPortLib\r
+  FILE_GUID                      = 401406DD-BCAC-4B91-9F4E-72A7FEBE4762\r
+  MODULE_TYPE                    = BASE\r
+  VERSION_STRING                 = 1.0\r
+  LIBRARY_CLASS                  = SerialPortLib\r
+  CONSTRUCTOR                    = SerialPortInitialize\r
+\r
+[Sources.common]\r
+  XenConsoleSerialPortLib.c\r
+\r
+[LibraryClasses]\r
+  BaseLib\r
+  XenHypercallLib\r
+\r
+[Packages]\r
+  MdePkg/MdePkg.dec\r
+  OvmfPkg/OvmfPkg.dec\r