This fixes a particularly nasty interaction between TerminalDxe
and XenConsoleSerialPortLib where the latter may write fewer
bytes than it was passed in its ->Write() function, which is
interpreted by TerminalDxe as a failure condition, causing the
its driver binding to fail, which in turn causes other drivers
(the Intel BDS under ArmPlatformPkg) to fail due to a missing
console pipe.

While one would assume that throttling of the output is the
responsibility of the console/terminal layer, in this case we
can work around it by notifying the hypervisor of the partial
write, and looping until it makes some more room for us.

Contributed-under: TianoCore Contribution Agreement 1.0
Signed-off-by: Ard Biesheuvel <[email protected]>
---
 .../XenConsoleSerialPortLib.c                      | 24 ++++++++++++----------
 1 file changed, 13 insertions(+), 11 deletions(-)

diff --git a/OvmfPkg/Library/XenConsoleSerialPortLib/XenConsoleSerialPortLib.c 
b/OvmfPkg/Library/XenConsoleSerialPortLib/XenConsoleSerialPortLib.c
index 467cb27a30c4..9bb2016c2f32 100644
--- a/OvmfPkg/Library/XenConsoleSerialPortLib/XenConsoleSerialPortLib.c
+++ b/OvmfPkg/Library/XenConsoleSerialPortLib/XenConsoleSerialPortLib.c
@@ -80,22 +80,24 @@ SerialPortWrite (
     return 0;
   }
 
-  Consumer = mXenConsoleInterface->out_cons;
-  Producer = mXenConsoleInterface->out_prod;
+  Sent = 0;
+  do {
+    Consumer = mXenConsoleInterface->out_cons;
+    Producer = mXenConsoleInterface->out_prod;
 
-  MemoryFence ();
+    MemoryFence ();
 
-  Sent = 0;
-  while (Sent < NumberOfBytes && ((Producer - Consumer) < sizeof 
(mXenConsoleInterface->out)))
-    mXenConsoleInterface->out[MASK_XENCONS_IDX(Producer++, 
mXenConsoleInterface->out)] = Buffer[Sent++];
+    while (Sent < NumberOfBytes && ((Producer - Consumer) < sizeof 
(mXenConsoleInterface->out)))
+      mXenConsoleInterface->out[MASK_XENCONS_IDX(Producer++, 
mXenConsoleInterface->out)] = Buffer[Sent++];
 
-  MemoryFence ();
+    MemoryFence ();
 
-  mXenConsoleInterface->out_prod = Producer;
+    mXenConsoleInterface->out_prod = Producer;
 
-  if (Sent > 0) {
-    XenHypercallEventChannelOp (EVTCHNOP_send, &mXenConsoleEventChain);
-  }
+    if (Sent > 0) {
+      XenHypercallEventChannelOp (EVTCHNOP_send, &mXenConsoleEventChain);
+    }
+  } while (Sent < NumberOfBytes);
 
   return Sent;
 }
-- 
1.8.3.2


------------------------------------------------------------------------------
Dive into the World of Parallel Programming The Go Parallel Website, sponsored
by Intel and developed in partnership with Slashdot Media, is your hub for all
things parallel software development, from weekly thought leadership blogs to
news, videos, case studies, tutorials and more. Take a look and join the 
conversation now. http://goparallel.sourceforge.net/
_______________________________________________
edk2-devel mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/edk2-devel

Reply via email to