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
