2 Xen console SerialPortLib instance
4 Copyright (c) 2015, Linaro Ltd. All rights reserved.<BR>
6 This program and the accompanying materials
7 are licensed and made available under the terms and conditions of the BSD License
8 which accompanies this distribution. The full text of the license may be found at
9 http://opensource.org/licenses/bsd-license.php
11 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
12 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
17 #include <Uefi/UefiBaseType.h>
19 #include <Library/BaseLib.h>
20 #include <Library/SerialPortLib.h>
21 #include <Library/XenHypercallLib.h>
23 #include <IndustryStandard/Xen/io/console.h>
24 #include <IndustryStandard/Xen/hvm/params.h>
25 #include <IndustryStandard/Xen/event_channel.h>
28 // The code below expects these global variables to be mutable, even in the case
29 // that we have been incorporated into SEC or PEIM phase modules (which is
30 // allowed by our INF description). While this is a dangerous assumption to make
31 // in general, it is actually fine for the Xen domU (guest) environment that
32 // this module is intended for, as UEFI always executes from DRAM in that case.
34 STATIC evtchn_send_t mXenConsoleEventChain
;
35 STATIC
struct xencons_interface
*mXenConsoleInterface
;
39 SerialPortInitialize (
43 if (! XenHypercallIsAvailable ()) {
44 return RETURN_NOT_FOUND
;
47 if (!mXenConsoleInterface
) {
48 mXenConsoleEventChain
.port
= (UINT32
)XenHypercallHvmGetParam (HVM_PARAM_CONSOLE_EVTCHN
);
49 mXenConsoleInterface
= (struct xencons_interface
*)(UINTN
)
50 (XenHypercallHvmGetParam (HVM_PARAM_CONSOLE_PFN
) << EFI_PAGE_SHIFT
);
53 // No point in ASSERT'ing here as we won't be seeing the output
56 return RETURN_SUCCESS
;
60 Write data to serial device.
62 @param Buffer Point of data buffer which need to be written.
63 @param NumberOfBytes Number of output bytes which are cached in Buffer.
65 @retval 0 Write data failed.
66 @retval !0 Actual number of bytes written to serial device.
73 IN UINTN NumberOfBytes
76 XENCONS_RING_IDX Consumer
, Producer
;
79 if (!mXenConsoleInterface
) {
83 Consumer
= mXenConsoleInterface
->out_cons
;
84 Producer
= mXenConsoleInterface
->out_prod
;
89 while (Sent
< NumberOfBytes
&& ((Producer
- Consumer
) < sizeof (mXenConsoleInterface
->out
)))
90 mXenConsoleInterface
->out
[MASK_XENCONS_IDX(Producer
++, mXenConsoleInterface
->out
)] = Buffer
[Sent
++];
94 mXenConsoleInterface
->out_prod
= Producer
;
97 XenHypercallEventChannelOp (EVTCHNOP_send
, &mXenConsoleEventChain
);
104 Read data from serial device and save the data in buffer.
106 @param Buffer Point of data buffer which need to be written.
107 @param NumberOfBytes Size of Buffer[].
109 @retval 0 Read data failed.
110 @retval !0 Actual number of bytes read from serial device.
117 IN UINTN NumberOfBytes
120 XENCONS_RING_IDX Consumer
, Producer
;
123 if (!mXenConsoleInterface
) {
127 Consumer
= mXenConsoleInterface
->in_cons
;
128 Producer
= mXenConsoleInterface
->in_prod
;
133 while (Received
< NumberOfBytes
&& Consumer
< Producer
)
134 Buffer
[Received
++] = mXenConsoleInterface
->in
[MASK_XENCONS_IDX(Consumer
++, mXenConsoleInterface
->in
)];
138 mXenConsoleInterface
->in_cons
= Consumer
;
140 XenHypercallEventChannelOp (EVTCHNOP_send
, &mXenConsoleEventChain
);
146 Check to see if any data is available to be read from the debug device.
148 @retval TRUE At least one byte of data is available to be read
149 @retval FALSE No data is available to be read
158 return mXenConsoleInterface
&&
159 mXenConsoleInterface
->in_cons
!= mXenConsoleInterface
->in_prod
;