45#include <IndustryStandard/Xen/hvm/params.h>
60#define XENSTORE_WATCH_SIGNATURE SIGNATURE_32 ('X','S','w','a')
69#define XENSTORE_WATCH_FROM_LINK(l) \
70 CR (l, XENSTORE_WATCH, Link, XENSTORE_WATCH_SIGNATURE)
75#define XENSTORE_MESSAGE_SIGNATURE SIGNATURE_32 ('X', 'S', 's', 'm')
96#define XENSTORE_MESSAGE_FROM_LINK(r) \
97 CR (r, XENSTORE_MESSAGE, Link, XENSTORE_MESSAGE_SIGNATURE)
182 for (Ptr = Strings; Ptr < Strings + Len; Ptr +=
AsciiStrSize (Ptr)) {
220 ASSERT (NumPtr !=
NULL);
221 ASSERT (Strings !=
NULL);
225 Strings[Len - 1] =
'\0';
233 CopyMem ((VOID *)&Dst[*NumPtr], Strings, Len);
237 Strings = (CHAR8 *)&Dst[*NumPtr];
270 Watch = XENSTORE_WATCH_FROM_LINK (Entry);
271 if (Watch == WantedWatch) {
296 ASSERT (Buf !=
NULL);
298 if (Node[0] ==
'\0') {
301 AsciiSPrint (Buf, BufSize,
"%a/%a", DirectoryPath, Node);
326 XENSTORE_RING_IDX Cons,
327 XENSTORE_RING_IDX Prod
330 return ((Prod - Cons) <= XENSTORE_RING_SIZE);
347 IN XENSTORE_RING_IDX Cons,
348 IN XENSTORE_RING_IDX Prod,
355 Len = XENSTORE_RING_SIZE - MASK_XENSTORE_IDX (Prod);
356 if ((XENSTORE_RING_SIZE - (Prod - Cons)) < Len) {
357 Len = XENSTORE_RING_SIZE - (Prod - Cons);
361 return (Buffer + MASK_XENSTORE_IDX (Prod));
378 IN XENSTORE_RING_IDX Cons,
379 IN XENSTORE_RING_IDX Prod,
386 Len = XENSTORE_RING_SIZE - MASK_XENSTORE_IDX (Cons);
387 if ((Prod - Cons) < Len) {
392 return (Buffer + MASK_XENSTORE_IDX (Cons));
417 gBS->CreateEvent (EVT_TIMER, 0,
NULL,
NULL, &TimerEvent);
421 WaitList[1] = TimerEvent;
422 Status =
gBS->WaitForEvent (2, WaitList, &Index);
423 ASSERT (Status != EFI_INVALID_PARAMETER);
424 gBS->CloseEvent (TimerEvent);
425 if (Status == EFI_UNSUPPORTED) {
454 XENSTORE_RING_IDX Cons, Prod;
463 if ((Prod - Cons) == XENSTORE_RING_SIZE) {
476 if (Status == EFI_TIMEOUT) {
477 DEBUG ((DEBUG_WARN,
"XenStore Write, waiting for a ring event.\n"));
486 return XENSTORE_STATUS_EIO;
490 if (Available > Len) {
494 CopyMem (Dest, Data, Available);
515 return XENSTORE_STATUS_SUCCESS;
536 XENSTORE_RING_IDX Cons, Prod;
537 CHAR8 *Data = (CHAR8 *)DataPtr;
558 if (Status == EFI_TIMEOUT) {
559 DEBUG ((DEBUG_WARN,
"XenStore Read, waiting for a ring event.\n"));
568 return XENSTORE_STATUS_EIO;
572 if (Available > Len) {
582 CopyMem (Data, Src, Available);
602 return XENSTORE_STATUS_SUCCESS;
624 XENSTORE_STATUS Status;
629 if (Status != XENSTORE_STATUS_SUCCESS) {
631 DEBUG ((DEBUG_ERROR,
"XenStore: Error read store (%d)\n", Status));
637 if (Status != XENSTORE_STATUS_SUCCESS) {
640 DEBUG ((DEBUG_ERROR,
"XenStore: Error read store (%d)\n", Status));
644 Body[Message->Header.len] =
'\0';
646 if (Message->Header.type == XS_WATCH_EVENT) {
647 Message->u.Watch.Vector =
Split (
650 &Message->u.Watch.VectorSize
654 Message->u.Watch.Handle =
658 "XenStore: Watch event %a\n",
659 Message->u.Watch.Vector[XS_WATCH_TOKEN]
661 if (Message->u.Watch.Handle !=
NULL) {
668 "XenStore: Watch handle %a not found\n",
669 Message->u.Watch.Vector[XS_WATCH_TOKEN]
671 FreePool ((VOID *)Message->u.Watch.Vector);
677 Message->u.Reply.Body = Body;
683 return XENSTORE_STATUS_SUCCESS;
701 XENSTORE_STATUS Status;
702 CONST CHAR8 *ErrorStr;
706 { XENSTORE_STATUS_EINVAL,
"EINVAL" },
707 { XENSTORE_STATUS_EACCES,
"EACCES" },
708 { XENSTORE_STATUS_EEXIST,
"EEXIST" },
709 { XENSTORE_STATUS_EISDIR,
"EISDIR" },
710 { XENSTORE_STATUS_ENOENT,
"ENOENT" },
711 { XENSTORE_STATUS_ENOMEM,
"ENOMEM" },
712 { XENSTORE_STATUS_ENOSPC,
"ENOSPC" },
713 { XENSTORE_STATUS_EIO,
"EIO" },
714 { XENSTORE_STATUS_ENOTEMPTY,
"ENOTEMPTY" },
715 { XENSTORE_STATUS_ENOSYS,
"ENOSYS" },
716 { XENSTORE_STATUS_EROFS,
"EROFS" },
717 { XENSTORE_STATUS_EBUSY,
"EBUSY" },
718 { XENSTORE_STATUS_EAGAIN,
"EAGAIN" },
719 { XENSTORE_STATUS_EISCONN,
"EISCONN" },
720 { XENSTORE_STATUS_E2BIG,
"E2BIG" }
726 CONST CHAR8 *ErrorStr
731 for (Index = 0; Index <
ARRAY_SIZE (gXenStoreErrors); Index++) {
732 if (!
AsciiStrCmp (ErrorStr, gXenStoreErrors[Index].ErrorStr)) {
733 return gXenStoreErrors[Index].Status;
737 DEBUG ((DEBUG_WARN,
"XenStore gave unknown error %a\n", ErrorStr));
738 return XENSTORE_STATUS_EINVAL;
751 OUT enum xsd_sockmsg_type *TypePtr,
752 OUT UINT32 *LenPtr OPTIONAL,
761 XENSTORE_STATUS Status;
763 if ((Status != XENSTORE_STATUS_SUCCESS) && (Status != XENSTORE_STATUS_EAGAIN)) {
766 "XenStore, error while reading the ring (%d).",
775 Message = XENSTORE_MESSAGE_FROM_LINK (Entry);
779 *TypePtr = Message->Header.type;
780 if (LenPtr !=
NULL) {
781 *LenPtr = Message->Header.len;
784 Body = Message->u.Reply.Body;
788 return XENSTORE_STATUS_SUCCESS;
808 IN enum xsd_sockmsg_type RequestType,
810 IN UINT32 NumRequests,
811 OUT UINT32 *LenPtr OPTIONAL,
812 OUT VOID **ResultPtr OPTIONAL
818 XENSTORE_STATUS Status;
827 Message.type = RequestType;
829 for (Index = 0; Index < NumRequests; Index++) {
830 Message.len += WriteRequest[Index].Len;
834 if (Status != XENSTORE_STATUS_SUCCESS) {
835 DEBUG ((DEBUG_ERROR,
"XenStoreTalkv failed %d\n", Status));
839 for (Index = 0; Index < NumRequests; Index++) {
841 if (Status != XENSTORE_STATUS_SUCCESS) {
842 DEBUG ((DEBUG_ERROR,
"XenStoreTalkv failed %d\n", Status));
847 Status =
XenStoreReadReply ((
enum xsd_sockmsg_type *)&Message.type, LenPtr, &Return);
850 if (Status != XENSTORE_STATUS_SUCCESS) {
854 if (Message.type == XS_ERROR) {
855 Status = XenStoreGetError (Return);
861 ASSERT ((
enum xsd_sockmsg_type)Message.type == RequestType);
869 return XENSTORE_STATUS_SUCCESS;
892 IN enum xsd_sockmsg_type RequestType,
894 OUT UINT32 *LenPtr OPTIONAL,
895 OUT VOID **Result OPTIONAL
900 WriteRequest.Data = (VOID *)Body;
935 WriteRequest[0].Data = (VOID *)Path;
937 WriteRequest[1].Data = (VOID *)Token;
961 WriteRequest[0].Data = (VOID *)Path;
963 WriteRequest[1].Data = (VOID *)Token;
978 XENSTORE_STATUS Status;
987 if ((Status != XENSTORE_STATUS_SUCCESS) && (Status != XENSTORE_STATUS_EAGAIN)) {
998 Message = XENSTORE_MESSAGE_FROM_LINK (Entry);
999 if (Message->u.Watch.Handle == Token) {
1002 FreePool ((VOID *)Message->u.Watch.Vector);
1004 return XENSTORE_STATUS_SUCCESS;
1015NotifyEventChannelCheckForEvent (
1024 gBS->SignalEvent (Event);
1043 Status =
gBS->CreateEvent (EVT_TIMER, 0,
NULL,
NULL, &TimerEvent);
1044 Status =
gBS->SetTimer (
1049 while (XenStore->rsp_prod != XenStore->rsp_cons) {
1050 Status =
gBS->CheckEvent (TimerEvent);
1051 if (!EFI_ERROR (Status)) {
1054 "XENSTORE response ring is not quiescent "
1055 "(%08x:%08x): fixing up\n",
1059 XenStore->rsp_cons = XenStore->rsp_prod;
1063 gBS->CloseEvent (TimerEvent);
1065 Status =
gBS->CreateEvent (
1068 NotifyEventChannelCheckForEvent,
1101 xs.
XenStore = (VOID *)(XenStoreGpfn << EFI_PAGE_SHIFT);
1104 "XenBusInit: XenBus rings @%p, event channel %x\n",
1136 DEBUG ((DEBUG_WARN,
"XenStore: RegisteredWatches is not empty, cleaning up..."));
1139 Watch = XENSTORE_WATCH_FROM_LINK (Entry);
1152 DEBUG ((DEBUG_WARN,
"XenStore: WatchEvents is not empty, cleaning up..."));
1158 FreePool ((VOID *)Message->u.Watch.Vector);
1168 Message = XENSTORE_MESSAGE_FROM_LINK (Entry);
1178 if (xs.
XenStore->server_features & XENSTORE_SERVER_FEATURE_RECONNECTION) {
1179 xs.
XenStore->connection = XENSTORE_RECONNECT;
1181 while (*(
volatile UINT32 *)&xs.
XenStore->connection == XENSTORE_RECONNECT) {
1206 IN CONST CHAR8 *DirectoryPath,
1208 OUT UINT32 *DirectoryCountPtr,
1209 OUT CONST CHAR8 ***DirectoryListPtr
1215 XENSTORE_STATUS Status;
1226 if (Status != XENSTORE_STATUS_SUCCESS) {
1230 *DirectoryListPtr =
Split (TempStr, Len, DirectoryCountPtr);
1232 return XENSTORE_STATUS_SUCCESS;
1242 CONST CHAR8 **TempStr;
1243 XENSTORE_STATUS Status;
1253 if (Status != XENSTORE_STATUS_SUCCESS) {
1264 IN CONST CHAR8 *DirectoryPath,
1266 OUT UINT32 *LenPtr OPTIONAL,
1272 XENSTORE_STATUS Status;
1277 if (Status != XENSTORE_STATUS_SUCCESS) {
1282 return XENSTORE_STATUS_SUCCESS;
1288 IN CONST CHAR8 *DirectoryPath,
1295 XENSTORE_STATUS Status;
1299 WriteRequest[0].Data = (VOID *)Path;
1301 WriteRequest[1].Data = (VOID *)Str;
1313 IN CONST CHAR8 *DirectoryPath,
1318 XENSTORE_STATUS Status;
1333 XENSTORE_STATUS Status;
1337 XS_TRANSACTION_START,
1342 if (Status == XENSTORE_STATUS_SUCCESS) {
1358 AbortStr[0] = Abort ?
'F' :
'T';
1368 IN CONST CHAR8 *DirectoryPath,
1375 XENSTORE_STATUS Status;
1394 IN CONST CHAR8 *DirectoryPath,
1401 XENSTORE_STATUS Status;
1412 IN CONST CHAR8 *DirectoryPath,
1419 XENSTORE_STATUS Status;
1423 Watch->Signature = XENSTORE_WATCH_SIGNATURE;
1430 AsciiSPrint (Token,
sizeof (Token),
"%p", (VOID *)Watch);
1434 if (Status == XENSTORE_STATUS_EEXIST) {
1435 Status = XENSTORE_STATUS_SUCCESS;
1438 if (Status == XENSTORE_STATUS_SUCCESS) {
1456 CHAR8 Token[
sizeof (Watch) * 2 + 1];
1459 ASSERT (Watch->Signature == XENSTORE_WATCH_SIGNATURE);
1461 AsciiSPrint (Token,
sizeof (Token),
"%p", (VOID *)Watch);
1478 if (Message->u.Watch.Handle == Watch) {
1480 FreePool ((VOID *)Message->u.Watch.Vector);
1502 return XenStoreWaitWatch (Token);
1519XenBusXenStoreBackendRead (
1531XenBusXenStoreRemove (
1542XenBusXenStoreTransactionStart (
1552XenBusXenStoreTransactionEnd (
1563XenBusXenStoreSPrint (
1566 IN CONST CHAR8 *DirectoryPath,
1573 XENSTORE_STATUS Status;
1584XenBusRegisterWatch (
1595XenBusRegisterWatchBackend (
1606XenBusUnregisterWatch (
BOOLEAN EFIAPI IsNull(IN CONST LIST_ENTRY *List, IN CONST LIST_ENTRY *Node)
BOOLEAN EFIAPI IsListEmpty(IN CONST LIST_ENTRY *ListHead)
LIST_ENTRY *EFIAPI GetNextNode(IN CONST LIST_ENTRY *List, IN CONST LIST_ENTRY *Node)
UINTN EFIAPI AsciiStrLen(IN CONST CHAR8 *String)
LIST_ENTRY *EFIAPI InsertHeadList(IN OUT LIST_ENTRY *ListHead, IN OUT LIST_ENTRY *Entry)
LIST_ENTRY *EFIAPI GetFirstNode(IN CONST LIST_ENTRY *List)
INTN EFIAPI AsciiStrCmp(IN CONST CHAR8 *FirstString, IN CONST CHAR8 *SecondString)
VOID EFIAPI MemoryFence(VOID)
UINTN EFIAPI AsciiStrDecimalToUintn(IN CONST CHAR8 *String)
LIST_ENTRY *EFIAPI RemoveEntryList(IN CONST LIST_ENTRY *Entry)
LIST_ENTRY *EFIAPI InitializeListHead(IN OUT LIST_ENTRY *ListHead)
UINTN EFIAPI AsciiStrHexToUintn(IN CONST CHAR8 *String)
UINTN EFIAPI AsciiStrSize(IN CONST CHAR8 *String)
LIST_ENTRY *EFIAPI InsertTailList(IN OUT LIST_ENTRY *ListHead, IN OUT LIST_ENTRY *Entry)
VOID *EFIAPI CopyMem(OUT VOID *DestinationBuffer, IN CONST VOID *SourceBuffer, IN UINTN Length)
VOID *EFIAPI SetMem(OUT VOID *Buffer, IN UINTN Length, IN UINT8 Value)
VOID *EFIAPI AllocateZeroPool(IN UINTN AllocationSize)
VOID EFIAPI FreePool(IN VOID *Buffer)
UINT32 XenEventChannelNotify(IN XENBUS_DEVICE *Dev, IN evtchn_port_t Port)
UINTN EFIAPI SPrintLengthAsciiFormat(IN CONST CHAR8 *FormatString, IN VA_LIST Marker)
UINTN EFIAPI AsciiVSPrint(OUT CHAR8 *StartOfBuffer, IN UINTN BufferSize, IN CONST CHAR8 *FormatString, IN VA_LIST Marker)
UINTN EFIAPI AsciiSPrint(OUT CHAR8 *StartOfBuffer, IN UINTN BufferSize, IN CONST CHAR8 *FormatString,...)
#define VA_START(Marker, Parameter)
#define VA_COPY(Dest, Start)
#define ARRAY_SIZE(Array)
#define ASSERT_EFI_ERROR(StatusParameter)
#define DEBUG(Expression)
VOID *EFIAPI AllocatePool(IN UINTN AllocationSize)
EFI_STATUS EFIAPI Transaction(IN CONST EFI_SPI_IO_PROTOCOL *This, IN EFI_SPI_TRANSACTION_TYPE TransactionType, IN BOOLEAN DebugTransaction, IN UINT32 ClockHz OPTIONAL, IN UINT32 BusWidth, IN UINT32 FrameSize, IN UINT32 WriteBytes, IN UINT8 *WriteBuffer, IN UINT32 ReadBytes, OUT UINT8 *ReadBuffer)
INT32 EFIAPI TestAndClearBit(IN INT32 Bit, IN VOID *Address)
#define EFI_TIMER_PERIOD_SECONDS(Seconds)
VOID EFIAPI EfiReleaseLock(IN EFI_LOCK *Lock)
#define EFI_TIMER_PERIOD_MILLISECONDS(Milliseconds)
VOID EFIAPI EfiAcquireLock(IN EFI_LOCK *Lock)
EFI_LOCK *EFIAPI EfiInitializeLock(IN OUT EFI_LOCK *Lock, IN EFI_TPL Priority)
UINT64 EFIAPI XenHypercallHvmGetParam(UINT32 Index)
STATIC XENSTORE_STATUS XenStoreReadReply(OUT enum xsd_sockmsg_type *TypePtr, OUT UINT32 *LenPtr OPTIONAL, OUT VOID **Result)
STATIC XENSTORE_WATCH * XenStoreFindWatch(IN CONST CHAR8 *Token)
STATIC VOID * XenStoreGetOutputChunk(IN XENSTORE_RING_IDX Cons, IN XENSTORE_RING_IDX Prod, IN CHAR8 *Buffer, OUT UINT32 *LenPtr)
XENSTORE_STATUS EFIAPI XenStoreSPrint(IN CONST XENSTORE_TRANSACTION *Transaction, IN CONST CHAR8 *DirectoryPath, IN CONST CHAR8 *Node, IN CONST CHAR8 *FormatString,...)
XENSTORE_STATUS XenStoreRegisterWatch(IN CONST CHAR8 *DirectoryPath, IN CONST CHAR8 *Node, OUT XENSTORE_WATCH **WatchPtr)
XENSTORE_STATUS XenStoreRemove(IN CONST XENSTORE_TRANSACTION *Transaction, IN CONST CHAR8 *DirectoryPath, IN CONST CHAR8 *Node)
STATIC CONST CHAR8 ** Split(IN CHAR8 *Strings, IN UINTN Len, OUT UINT32 *NumPtr)
STATIC EFI_STATUS XenStoreInitComms(XENSTORE_PRIVATE *xsp)
STATIC XENSTORE_STATUS XenStoreTalkv(IN CONST XENSTORE_TRANSACTION *Transaction, IN enum xsd_sockmsg_type RequestType, IN CONST WRITE_REQUEST *WriteRequest, IN UINT32 NumRequests, OUT UINT32 *LenPtr OPTIONAL, OUT VOID **ResultPtr OPTIONAL)
STATIC XENSTORE_STATUS XenStoreProcessMessage(VOID)
#define XENSTORE_MESSAGE_SIGNATURE
STATIC XENSTORE_STATUS XenStoreWatch(CONST CHAR8 *Path, CONST CHAR8 *Token)
VOID XenStoreUnregisterWatch(IN XENSTORE_WATCH *Watch)
STATIC BOOLEAN XenStoreCheckIndexes(XENSTORE_RING_IDX Cons, XENSTORE_RING_IDX Prod)
XENSTORE_STATUS XenStoreListDirectory(IN CONST XENSTORE_TRANSACTION *Transaction, IN CONST CHAR8 *DirectoryPath, IN CONST CHAR8 *Node, OUT UINT32 *DirectoryCountPtr, OUT CONST CHAR8 ***DirectoryListPtr)
XENSTORE_STATUS EFIAPI XenStoreVSPrint(IN CONST XENSTORE_TRANSACTION *Transaction, IN CONST CHAR8 *DirectoryPath, IN CONST CHAR8 *Node, IN CONST CHAR8 *FormatString, IN VA_LIST Marker)
STATIC EFI_STATUS XenStoreWaitForEvent(IN EFI_EVENT Event, IN UINT64 Timeout)
CHAR8 * XenStoreJoin(IN CONST CHAR8 *DirectoryPath, IN CONST CHAR8 *Node)
STATIC XENSTORE_STATUS XenStoreReadStore(OUT VOID *DataPtr, IN UINT32 Len)
STATIC XENSTORE_STATUS XenStoreWriteStore(IN CONST VOID *DataPtr, IN UINT32 Len)
XENSTORE_STATUS XenStoreWrite(IN CONST XENSTORE_TRANSACTION *Transaction, IN CONST CHAR8 *DirectoryPath, IN CONST CHAR8 *Node, IN CONST CHAR8 *Str)
EFI_STATUS XenStoreInit(XENBUS_DEVICE *Dev)
XENSTORE_STATUS XenStoreTransactionStart(OUT XENSTORE_TRANSACTION *Transaction)
BOOLEAN XenStorePathExists(IN CONST XENSTORE_TRANSACTION *Transaction, IN CONST CHAR8 *Directory, IN CONST CHAR8 *Node)
STATIC XENSTORE_STATUS XenStoreSingle(IN CONST XENSTORE_TRANSACTION *Transaction, IN enum xsd_sockmsg_type RequestType, IN CONST CHAR8 *Body, OUT UINT32 *LenPtr OPTIONAL, OUT VOID **Result OPTIONAL)
XENSTORE_STATUS XenStoreRead(IN CONST XENSTORE_TRANSACTION *Transaction, IN CONST CHAR8 *DirectoryPath, IN CONST CHAR8 *Node, OUT UINT32 *LenPtr OPTIONAL, OUT VOID **Result)
XENSTORE_STATUS XenStoreTransactionEnd(IN CONST XENSTORE_TRANSACTION *Transaction, IN BOOLEAN Abort)
STATIC UINT32 ExtractStrings(IN CONST CHAR8 *Strings, IN UINTN Len, OUT CONST CHAR8 **Dst OPTIONAL)
STATIC CONST VOID * XenStoreGetInputChunk(IN XENSTORE_RING_IDX Cons, IN XENSTORE_RING_IDX Prod, IN CONST CHAR8 *Buffer, OUT UINT32 *LenPtr)
STATIC XENSTORE_STATUS XenStoreUnwatch(CONST CHAR8 *Path, CONST CHAR8 *Token)
VOID XenStoreDeinit(IN XENBUS_DEVICE *Dev)
struct xenstore_domain_interface * XenStore
EFI_EVENT EventChannelEvent
EFI_LOCK RegisteredWatchesLock
LIST_ENTRY RegisteredWatches
evtchn_port_t EventChannel