/* Reads NumberOfBytes data bytes from a serial device into the buffer specified by Buffer. The number of bytes actually read is returned. If Buffer is NULL, then ASSERT(). If NumberOfBytes is zero, then return 0. */
UINTN EFIAPI SerialPortRead(OUT UINT8 *Buffer, IN UINTN NumberOfBytes)
/* Reads NumberOfBytes data bytes from a serial device into the buffer specified by Buffer. The number of bytes actually read is returned. If Buffer is NULL, then ASSERT(). If NumberOfBytes is zero, then return 0. */
UINTN EFIAPI SerialPortRead(OUT UINT8 *Buffer, IN UINTN NumberOfBytes)
{
  XENCONS_RING_IDX  Consumer, Producer;
  UINTN             Received;
  ASSERT (Buffer != NULL);
  if (NumberOfBytes == 0) {
    return 0;
  }
  if (!mXenConsoleInterface) {
    return 0;
  }
  Consumer = mXenConsoleInterface->in_cons;
  Producer = mXenConsoleInterface->in_prod;
  MemoryFence ();
  Received = 0;
  while (Received < NumberOfBytes && Consumer < Producer) {
    Buffer[Received++] = mXenConsoleInterface->in[MASK_XENCONS_IDX (Consumer++, mXenConsoleInterface->in)];
  }
  MemoryFence ();
  mXenConsoleInterface->in_cons = Consumer;
  XenHypercallEventChannelOp (EVTCHNOP_send, &mXenConsoleEventChain);
  return Received;
}