TianoCore EDK2 master
Loading...
Searching...
No Matches
XenStore.c
Go to the documentation of this file.
1
41#include "XenStore.h"
42
43#include <Library/PrintLib.h>
44
45#include <IndustryStandard/Xen/hvm/params.h>
46
47#include "EventChannel.h"
49
50//
51// Private Data Structures
52//
53
54typedef struct {
55 CONST VOID *Data;
56 UINT32 Len;
58
59/* Register callback to watch subtree (node) in the XenStore. */
60#define XENSTORE_WATCH_SIGNATURE SIGNATURE_32 ('X','S','w','a')
62 UINT32 Signature;
63 LIST_ENTRY Link;
64
65 /* Path being watched. */
66 CHAR8 *Node;
67};
68
69#define XENSTORE_WATCH_FROM_LINK(l) \
70 CR (l, XENSTORE_WATCH, Link, XENSTORE_WATCH_SIGNATURE)
71
75#define XENSTORE_MESSAGE_SIGNATURE SIGNATURE_32 ('X', 'S', 's', 'm')
76typedef struct {
77 UINT32 Signature;
78 LIST_ENTRY Link;
79
80 struct xsd_sockmsg Header;
81
82 union {
83 /* Queued replies. */
84 struct {
85 CHAR8 *Body;
86 } Reply;
87
88 /* Queued watch events. */
89 struct {
90 XENSTORE_WATCH *Handle;
91 CONST CHAR8 **Vector;
92 UINT32 VectorSize;
93 } Watch;
94 } u;
96#define XENSTORE_MESSAGE_FROM_LINK(r) \
97 CR (r, XENSTORE_MESSAGE, Link, XENSTORE_MESSAGE_SIGNATURE)
98
102typedef struct {
108
109 XENBUS_DEVICE *Dev;
110
122
125
130
133
138
141
146 evtchn_port_t EventChannel;
147
151
152//
153// Global Data
154//
155static XENSTORE_PRIVATE xs;
156
157//
158// Private Utility Functions
159//
160
171STATIC
172UINT32
174 IN CONST CHAR8 *Strings,
175 IN UINTN Len,
176 OUT CONST CHAR8 **Dst OPTIONAL
177 )
178{
179 UINT32 Num = 0;
180 CONST CHAR8 *Ptr;
181
182 for (Ptr = Strings; Ptr < Strings + Len; Ptr += AsciiStrSize (Ptr)) {
183 if (Dst != NULL) {
184 *Dst++ = Ptr;
185 }
186
187 Num++;
188 }
189
190 return Num;
191}
192
210STATIC
211CONST CHAR8 **
213 IN CHAR8 *Strings,
214 IN UINTN Len,
215 OUT UINT32 *NumPtr
216 )
217{
218 CONST CHAR8 **Dst;
219
220 ASSERT (NumPtr != NULL);
221 ASSERT (Strings != NULL);
222
223 /* Protect against unterminated buffers. */
224 if (Len > 0) {
225 Strings[Len - 1] = '\0';
226 }
227
228 /* Count the Strings. */
229 *NumPtr = ExtractStrings (Strings, Len, NULL);
230
231 /* Transfer to one big alloc for easy freeing by the caller. */
232 Dst = AllocatePool (*NumPtr * sizeof (CHAR8 *) + Len);
233 CopyMem ((VOID *)&Dst[*NumPtr], Strings, Len);
234 FreePool (Strings);
235
236 /* Extract pointers to newly allocated array. */
237 Strings = (CHAR8 *)&Dst[*NumPtr];
238 ExtractStrings (Strings, Len, Dst);
239
240 return (Dst);
241}
242
251STATIC
254 IN CONST CHAR8 *Token
255 )
256{
257 XENSTORE_WATCH *Watch, *WantedWatch;
258 LIST_ENTRY *Entry;
259
260 WantedWatch = (VOID *)AsciiStrHexToUintn (Token);
261
262 if (IsListEmpty (&xs.RegisteredWatches)) {
263 return NULL;
264 }
265
266 for (Entry = GetFirstNode (&xs.RegisteredWatches);
267 !IsNull (&xs.RegisteredWatches, Entry);
268 Entry = GetNextNode (&xs.RegisteredWatches, Entry))
269 {
270 Watch = XENSTORE_WATCH_FROM_LINK (Entry);
271 if (Watch == WantedWatch) {
272 return Watch;
273 }
274 }
275
276 return NULL;
277}
278
279//
280// Public Utility Functions
281// API comments for these methods can be found in XenStore.h
282//
283
284CHAR8 *
286 IN CONST CHAR8 *DirectoryPath,
287 IN CONST CHAR8 *Node
288 )
289{
290 CHAR8 *Buf;
291 UINTN BufSize;
292
293 /* +1 for '/' and +1 for '\0' */
294 BufSize = AsciiStrLen (DirectoryPath) + AsciiStrLen (Node) + 2;
295 Buf = AllocatePool (BufSize);
296 ASSERT (Buf != NULL);
297
298 if (Node[0] == '\0') {
299 AsciiSPrint (Buf, BufSize, "%a", DirectoryPath);
300 } else {
301 AsciiSPrint (Buf, BufSize, "%a/%a", DirectoryPath, Node);
302 }
303
304 return Buf;
305}
306
307//
308// Low Level Communication Management
309//
310
323STATIC
324BOOLEAN
326 XENSTORE_RING_IDX Cons,
327 XENSTORE_RING_IDX Prod
328 )
329{
330 return ((Prod - Cons) <= XENSTORE_RING_SIZE);
331}
332
344STATIC
345VOID *
347 IN XENSTORE_RING_IDX Cons,
348 IN XENSTORE_RING_IDX Prod,
349 IN CHAR8 *Buffer,
350 OUT UINT32 *LenPtr
351 )
352{
353 UINT32 Len;
354
355 Len = XENSTORE_RING_SIZE - MASK_XENSTORE_IDX (Prod);
356 if ((XENSTORE_RING_SIZE - (Prod - Cons)) < Len) {
357 Len = XENSTORE_RING_SIZE - (Prod - Cons);
358 }
359
360 *LenPtr = Len;
361 return (Buffer + MASK_XENSTORE_IDX (Prod));
362}
363
375STATIC
376CONST VOID *
378 IN XENSTORE_RING_IDX Cons,
379 IN XENSTORE_RING_IDX Prod,
380 IN CONST CHAR8 *Buffer,
381 OUT UINT32 *LenPtr
382 )
383{
384 UINT32 Len;
385
386 Len = XENSTORE_RING_SIZE - MASK_XENSTORE_IDX (Cons);
387 if ((Prod - Cons) < Len) {
388 Len = Prod - Cons;
389 }
390
391 *LenPtr = Len;
392 return (Buffer + MASK_XENSTORE_IDX (Cons));
393}
394
405STATIC
408 IN EFI_EVENT Event,
409 IN UINT64 Timeout
410 )
411{
412 UINTN Index;
413 EFI_STATUS Status;
414 EFI_EVENT TimerEvent;
415 EFI_EVENT WaitList[2];
416
417 gBS->CreateEvent (EVT_TIMER, 0, NULL, NULL, &TimerEvent);
418 gBS->SetTimer (TimerEvent, TimerRelative, Timeout);
419
420 WaitList[0] = xs.EventChannelEvent;
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) {
426 return EFI_SUCCESS;
427 }
428
429 if (Index == 1) {
430 return EFI_TIMEOUT;
431 } else {
432 return EFI_SUCCESS;
433 }
434}
435
447STATIC
448XENSTORE_STATUS
450 IN CONST VOID *DataPtr,
451 IN UINT32 Len
452 )
453{
454 XENSTORE_RING_IDX Cons, Prod;
455 CONST CHAR8 *Data = (CONST CHAR8 *)DataPtr;
456
457 while (Len != 0) {
458 void *Dest;
459 UINT32 Available;
460
461 Cons = xs.XenStore->req_cons;
462 Prod = xs.XenStore->req_prod;
463 if ((Prod - Cons) == XENSTORE_RING_SIZE) {
464 /*
465 * Output ring is full. Wait for a ring event.
466 *
467 * Note that the events from both queues are combined, so being woken
468 * does not guarantee that data exist in the read ring.
469 */
470 EFI_STATUS Status;
471
472 Status = XenStoreWaitForEvent (
475 );
476 if (Status == EFI_TIMEOUT) {
477 DEBUG ((DEBUG_WARN, "XenStore Write, waiting for a ring event.\n"));
478 }
479
480 continue;
481 }
482
483 /* Verify queue sanity. */
484 if (!XenStoreCheckIndexes (Cons, Prod)) {
485 xs.XenStore->req_cons = xs.XenStore->req_prod = 0;
486 return XENSTORE_STATUS_EIO;
487 }
488
489 Dest = XenStoreGetOutputChunk (Cons, Prod, xs.XenStore->req, &Available);
490 if (Available > Len) {
491 Available = Len;
492 }
493
494 CopyMem (Dest, Data, Available);
495 Data += Available;
496 Len -= Available;
497
498 /*
499 * The store to the producer index, which indicates
500 * to the other side that new data has arrived, must
501 * be visible only after our copy of the data into the
502 * ring has completed.
503 */
504 MemoryFence ();
505 xs.XenStore->req_prod += Available;
506
507 /*
508 * The other side will see the change to req_prod at the time of the
509 * interrupt.
510 */
511 MemoryFence ();
513 }
514
515 return XENSTORE_STATUS_SUCCESS;
516}
517
529STATIC
530XENSTORE_STATUS
532 OUT VOID *DataPtr,
533 IN UINT32 Len
534 )
535{
536 XENSTORE_RING_IDX Cons, Prod;
537 CHAR8 *Data = (CHAR8 *)DataPtr;
538
539 while (Len != 0) {
540 UINT32 Available;
541 CONST CHAR8 *Src;
542
543 Cons = xs.XenStore->rsp_cons;
544 Prod = xs.XenStore->rsp_prod;
545 if (Cons == Prod) {
546 /*
547 * Nothing to read. Wait for a ring event.
548 *
549 * Note that the events from both queues are combined, so being woken
550 * does not guarantee that data exist in the read ring.
551 */
552 EFI_STATUS Status;
553
554 Status = XenStoreWaitForEvent (
557 );
558 if (Status == EFI_TIMEOUT) {
559 DEBUG ((DEBUG_WARN, "XenStore Read, waiting for a ring event.\n"));
560 }
561
562 continue;
563 }
564
565 /* Verify queue sanity. */
566 if (!XenStoreCheckIndexes (Cons, Prod)) {
567 xs.XenStore->rsp_cons = xs.XenStore->rsp_prod = 0;
568 return XENSTORE_STATUS_EIO;
569 }
570
571 Src = XenStoreGetInputChunk (Cons, Prod, xs.XenStore->rsp, &Available);
572 if (Available > Len) {
573 Available = Len;
574 }
575
576 /*
577 * Insure the data we read is related to the indexes
578 * we read above.
579 */
580 MemoryFence ();
581
582 CopyMem (Data, Src, Available);
583 Data += Available;
584 Len -= Available;
585
586 /*
587 * Insure that the producer of this ring does not see
588 * the ring space as free until after we have copied it
589 * out.
590 */
591 MemoryFence ();
592 xs.XenStore->rsp_cons += Available;
593
594 /*
595 * The producer will see the updated consumer index when the event is
596 * delivered.
597 */
598 MemoryFence ();
600 }
601
602 return XENSTORE_STATUS_SUCCESS;
603}
604
605//
606// Received Message Processing
607//
608
616STATIC
617XENSTORE_STATUS
619 VOID
620 )
621{
622 XENSTORE_MESSAGE *Message;
623 CHAR8 *Body;
624 XENSTORE_STATUS Status;
625
626 Message = AllocateZeroPool (sizeof (XENSTORE_MESSAGE));
627 Message->Signature = XENSTORE_MESSAGE_SIGNATURE;
628 Status = XenStoreReadStore (&Message->Header, sizeof (Message->Header));
629 if (Status != XENSTORE_STATUS_SUCCESS) {
630 FreePool (Message);
631 DEBUG ((DEBUG_ERROR, "XenStore: Error read store (%d)\n", Status));
632 return Status;
633 }
634
635 Body = AllocatePool (Message->Header.len + 1);
636 Status = XenStoreReadStore (Body, Message->Header.len);
637 if (Status != XENSTORE_STATUS_SUCCESS) {
638 FreePool (Body);
639 FreePool (Message);
640 DEBUG ((DEBUG_ERROR, "XenStore: Error read store (%d)\n", Status));
641 return Status;
642 }
643
644 Body[Message->Header.len] = '\0';
645
646 if (Message->Header.type == XS_WATCH_EVENT) {
647 Message->u.Watch.Vector = Split (
648 Body,
649 Message->Header.len,
650 &Message->u.Watch.VectorSize
651 );
652
654 Message->u.Watch.Handle =
655 XenStoreFindWatch (Message->u.Watch.Vector[XS_WATCH_TOKEN]);
656 DEBUG ((
657 DEBUG_INFO,
658 "XenStore: Watch event %a\n",
659 Message->u.Watch.Vector[XS_WATCH_TOKEN]
660 ));
661 if (Message->u.Watch.Handle != NULL) {
663 InsertHeadList (&xs.WatchEvents, &Message->Link);
665 } else {
666 DEBUG ((
667 DEBUG_WARN,
668 "XenStore: Watch handle %a not found\n",
669 Message->u.Watch.Vector[XS_WATCH_TOKEN]
670 ));
671 FreePool ((VOID *)Message->u.Watch.Vector);
672 FreePool (Message);
673 }
674
676 } else {
677 Message->u.Reply.Body = Body;
679 InsertTailList (&xs.ReplyList, &Message->Link);
681 }
682
683 return XENSTORE_STATUS_SUCCESS;
684}
685
686//
687// XenStore Message Request/Reply Processing
688//
689
700typedef struct {
701 XENSTORE_STATUS Status;
702 CONST CHAR8 *ErrorStr;
704
705static XenStoreErrors gXenStoreErrors[] = {
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" }
721};
722
723STATIC
724XENSTORE_STATUS
725XenStoreGetError (
726 CONST CHAR8 *ErrorStr
727 )
728{
729 UINT32 Index;
730
731 for (Index = 0; Index < ARRAY_SIZE (gXenStoreErrors); Index++) {
732 if (!AsciiStrCmp (ErrorStr, gXenStoreErrors[Index].ErrorStr)) {
733 return gXenStoreErrors[Index].Status;
734 }
735 }
736
737 DEBUG ((DEBUG_WARN, "XenStore gave unknown error %a\n", ErrorStr));
738 return XENSTORE_STATUS_EINVAL;
739}
740
748STATIC
749XENSTORE_STATUS
751 OUT enum xsd_sockmsg_type *TypePtr,
752 OUT UINT32 *LenPtr OPTIONAL,
753 OUT VOID **Result
754 )
755{
756 XENSTORE_MESSAGE *Message;
757 LIST_ENTRY *Entry;
758 CHAR8 *Body;
759
760 while (IsListEmpty (&xs.ReplyList)) {
761 XENSTORE_STATUS Status;
762 Status = XenStoreProcessMessage ();
763 if ((Status != XENSTORE_STATUS_SUCCESS) && (Status != XENSTORE_STATUS_EAGAIN)) {
764 DEBUG ((
765 DEBUG_ERROR,
766 "XenStore, error while reading the ring (%d).",
767 Status
768 ));
769 return Status;
770 }
771 }
772
774 Entry = GetFirstNode (&xs.ReplyList);
775 Message = XENSTORE_MESSAGE_FROM_LINK (Entry);
776 RemoveEntryList (Entry);
778
779 *TypePtr = Message->Header.type;
780 if (LenPtr != NULL) {
781 *LenPtr = Message->Header.len;
782 }
783
784 Body = Message->u.Reply.Body;
785
786 FreePool (Message);
787 *Result = Body;
788 return XENSTORE_STATUS_SUCCESS;
789}
790
804STATIC
805XENSTORE_STATUS
808 IN enum xsd_sockmsg_type RequestType,
809 IN CONST WRITE_REQUEST *WriteRequest,
810 IN UINT32 NumRequests,
811 OUT UINT32 *LenPtr OPTIONAL,
812 OUT VOID **ResultPtr OPTIONAL
813 )
814{
815 struct xsd_sockmsg Message;
816 void *Return = NULL;
817 UINT32 Index;
818 XENSTORE_STATUS Status;
819
820 if (Transaction == XST_NIL) {
821 Message.tx_id = 0;
822 } else {
823 Message.tx_id = Transaction->Id;
824 }
825
826 Message.req_id = 0;
827 Message.type = RequestType;
828 Message.len = 0;
829 for (Index = 0; Index < NumRequests; Index++) {
830 Message.len += WriteRequest[Index].Len;
831 }
832
833 Status = XenStoreWriteStore (&Message, sizeof (Message));
834 if (Status != XENSTORE_STATUS_SUCCESS) {
835 DEBUG ((DEBUG_ERROR, "XenStoreTalkv failed %d\n", Status));
836 goto Error;
837 }
838
839 for (Index = 0; Index < NumRequests; Index++) {
840 Status = XenStoreWriteStore (WriteRequest[Index].Data, WriteRequest[Index].Len);
841 if (Status != XENSTORE_STATUS_SUCCESS) {
842 DEBUG ((DEBUG_ERROR, "XenStoreTalkv failed %d\n", Status));
843 goto Error;
844 }
845 }
846
847 Status = XenStoreReadReply ((enum xsd_sockmsg_type *)&Message.type, LenPtr, &Return);
848
849Error:
850 if (Status != XENSTORE_STATUS_SUCCESS) {
851 return Status;
852 }
853
854 if (Message.type == XS_ERROR) {
855 Status = XenStoreGetError (Return);
856 FreePool (Return);
857 return Status;
858 }
859
860 /* Reply is either error or an echo of our request message type. */
861 ASSERT ((enum xsd_sockmsg_type)Message.type == RequestType);
862
863 if (ResultPtr) {
864 *ResultPtr = Return;
865 } else {
866 FreePool (Return);
867 }
868
869 return XENSTORE_STATUS_SUCCESS;
870}
871
888STATIC
889XENSTORE_STATUS
892 IN enum xsd_sockmsg_type RequestType,
893 IN CONST CHAR8 *Body,
894 OUT UINT32 *LenPtr OPTIONAL,
895 OUT VOID **Result OPTIONAL
896 )
897{
898 WRITE_REQUEST WriteRequest;
899
900 WriteRequest.Data = (VOID *)Body;
901 WriteRequest.Len = (UINT32)AsciiStrSize (Body);
902
903 return XenStoreTalkv (
905 RequestType,
906 &WriteRequest,
907 1,
908 LenPtr,
909 Result
910 );
911}
912
913//
914// XenStore Watch Support
915//
916
926STATIC
927XENSTORE_STATUS
929 CONST CHAR8 *Path,
930 CONST CHAR8 *Token
931 )
932{
933 WRITE_REQUEST WriteRequest[2];
934
935 WriteRequest[0].Data = (VOID *)Path;
936 WriteRequest[0].Len = (UINT32)AsciiStrSize (Path);
937 WriteRequest[1].Data = (VOID *)Token;
938 WriteRequest[1].Len = (UINT32)AsciiStrSize (Token);
939
940 return XenStoreTalkv (XST_NIL, XS_WATCH, WriteRequest, 2, NULL, NULL);
941}
942
952STATIC
953XENSTORE_STATUS
955 CONST CHAR8 *Path,
956 CONST CHAR8 *Token
957 )
958{
959 WRITE_REQUEST WriteRequest[2];
960
961 WriteRequest[0].Data = (VOID *)Path;
962 WriteRequest[0].Len = (UINT32)AsciiStrSize (Path);
963 WriteRequest[1].Data = (VOID *)Token;
964 WriteRequest[1].Len = (UINT32)AsciiStrSize (Token);
965
966 return XenStoreTalkv (XST_NIL, XS_UNWATCH, WriteRequest, 2, NULL, NULL);
967}
968
969STATIC
970XENSTORE_STATUS
971XenStoreWaitWatch (
972 VOID *Token
973 )
974{
975 XENSTORE_MESSAGE *Message;
976 LIST_ENTRY *Entry = NULL;
977 LIST_ENTRY *Last = NULL;
978 XENSTORE_STATUS Status;
979
980 while (TRUE) {
982 if (IsListEmpty (&xs.WatchEvents) ||
983 (Last == GetFirstNode (&xs.WatchEvents)))
984 {
986 Status = XenStoreProcessMessage ();
987 if ((Status != XENSTORE_STATUS_SUCCESS) && (Status != XENSTORE_STATUS_EAGAIN)) {
988 return Status;
989 }
990
991 continue;
992 }
993
994 for (Entry = GetFirstNode (&xs.WatchEvents);
995 Entry != Last && !IsNull (&xs.WatchEvents, Entry);
996 Entry = GetNextNode (&xs.WatchEvents, Entry))
997 {
998 Message = XENSTORE_MESSAGE_FROM_LINK (Entry);
999 if (Message->u.Watch.Handle == Token) {
1000 RemoveEntryList (Entry);
1002 FreePool ((VOID *)Message->u.Watch.Vector);
1003 FreePool (Message);
1004 return XENSTORE_STATUS_SUCCESS;
1005 }
1006 }
1007
1008 Last = GetFirstNode (&xs.WatchEvents);
1010 }
1011}
1012
1013VOID
1014EFIAPI
1015NotifyEventChannelCheckForEvent (
1016 IN EFI_EVENT Event,
1017 IN VOID *Context
1018 )
1019{
1020 XENSTORE_PRIVATE *xsp;
1021
1022 xsp = (XENSTORE_PRIVATE *)Context;
1023 if (TestAndClearBit (xsp->EventChannel, xsp->Dev->SharedInfo->evtchn_pending)) {
1024 gBS->SignalEvent (Event);
1025 }
1026}
1027
1033STATIC
1036 XENSTORE_PRIVATE *xsp
1037 )
1038{
1039 EFI_STATUS Status;
1040 EFI_EVENT TimerEvent;
1041 struct xenstore_domain_interface *XenStore = xsp->XenStore;
1042
1043 Status = gBS->CreateEvent (EVT_TIMER, 0, NULL, NULL, &TimerEvent);
1044 Status = gBS->SetTimer (
1045 TimerEvent,
1048 );
1049 while (XenStore->rsp_prod != XenStore->rsp_cons) {
1050 Status = gBS->CheckEvent (TimerEvent);
1051 if (!EFI_ERROR (Status)) {
1052 DEBUG ((
1053 DEBUG_WARN,
1054 "XENSTORE response ring is not quiescent "
1055 "(%08x:%08x): fixing up\n",
1056 XenStore->rsp_cons,
1057 XenStore->rsp_prod
1058 ));
1059 XenStore->rsp_cons = XenStore->rsp_prod;
1060 }
1061 }
1062
1063 gBS->CloseEvent (TimerEvent);
1064
1065 Status = gBS->CreateEvent (
1066 EVT_NOTIFY_WAIT,
1067 TPL_NOTIFY,
1068 NotifyEventChannelCheckForEvent,
1069 xsp,
1070 &xsp->EventChannelEvent
1071 );
1072 ASSERT_EFI_ERROR (Status);
1073
1074 return Status;
1075}
1076
1086 XENBUS_DEVICE *Dev
1087 )
1088{
1089 EFI_STATUS Status;
1090
1095 UINTN XenStoreGpfn;
1096
1097 xs.Dev = Dev;
1098
1099 xs.EventChannel = (evtchn_port_t)XenHypercallHvmGetParam (HVM_PARAM_STORE_EVTCHN);
1100 XenStoreGpfn = (UINTN)XenHypercallHvmGetParam (HVM_PARAM_STORE_PFN);
1101 xs.XenStore = (VOID *)(XenStoreGpfn << EFI_PAGE_SHIFT);
1102 DEBUG ((
1103 DEBUG_INFO,
1104 "XenBusInit: XenBus rings @%p, event channel %x\n",
1105 xs.XenStore,
1106 xs.EventChannel
1107 ));
1108
1112
1113 EfiInitializeLock (&xs.ReplyLock, TPL_NOTIFY);
1114 EfiInitializeLock (&xs.RegisteredWatchesLock, TPL_NOTIFY);
1115 EfiInitializeLock (&xs.WatchEventsLock, TPL_NOTIFY);
1116
1117 /* Initialize the shared memory rings to talk to xenstored */
1118 Status = XenStoreInitComms (&xs);
1119
1120 return Status;
1121}
1122
1123VOID
1125 IN XENBUS_DEVICE *Dev
1126 )
1127{
1128 //
1129 // Emptying the list RegisteredWatches, but this list should already be
1130 // empty. Every driver that is using Watches should unregister them when
1131 // it is stopped.
1132 //
1133 if (!IsListEmpty (&xs.RegisteredWatches)) {
1134 XENSTORE_WATCH *Watch;
1135 LIST_ENTRY *Entry;
1136 DEBUG ((DEBUG_WARN, "XenStore: RegisteredWatches is not empty, cleaning up..."));
1137 Entry = GetFirstNode (&xs.RegisteredWatches);
1138 while (!IsNull (&xs.RegisteredWatches, Entry)) {
1139 Watch = XENSTORE_WATCH_FROM_LINK (Entry);
1140 Entry = GetNextNode (&xs.RegisteredWatches, Entry);
1141
1143 }
1144 }
1145
1146 //
1147 // Emptying the list WatchEvents, but this list should already be empty after
1148 // having cleanup the list RegisteredWatches.
1149 //
1150 if (!IsListEmpty (&xs.WatchEvents)) {
1151 LIST_ENTRY *Entry;
1152 DEBUG ((DEBUG_WARN, "XenStore: WatchEvents is not empty, cleaning up..."));
1153 Entry = GetFirstNode (&xs.WatchEvents);
1154 while (!IsNull (&xs.WatchEvents, Entry)) {
1155 XENSTORE_MESSAGE *Message = XENSTORE_MESSAGE_FROM_LINK (Entry);
1156 Entry = GetNextNode (&xs.WatchEvents, Entry);
1157 RemoveEntryList (&Message->Link);
1158 FreePool ((VOID *)Message->u.Watch.Vector);
1159 FreePool (Message);
1160 }
1161 }
1162
1163 if (!IsListEmpty (&xs.ReplyList)) {
1164 XENSTORE_MESSAGE *Message;
1165 LIST_ENTRY *Entry;
1166 Entry = GetFirstNode (&xs.ReplyList);
1167 while (!IsNull (&xs.ReplyList, Entry)) {
1168 Message = XENSTORE_MESSAGE_FROM_LINK (Entry);
1169 Entry = GetNextNode (&xs.ReplyList, Entry);
1170 RemoveEntryList (&Message->Link);
1171 FreePool (Message->u.Reply.Body);
1172 FreePool (Message);
1173 }
1174 }
1175
1176 gBS->CloseEvent (xs.EventChannelEvent);
1177
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) {
1183 }
1184 } else {
1185 /* If the backend reads the state while we're erasing it then the
1186 * ring state will become corrupted, preventing guest frontends from
1187 * connecting. This is rare. To help diagnose the failure, we fill
1188 * the ring with XS_INVALID packets. */
1189 SetMem (xs.XenStore->req, XENSTORE_RING_SIZE, 0xff);
1190 SetMem (xs.XenStore->rsp, XENSTORE_RING_SIZE, 0xff);
1191 xs.XenStore->req_cons = xs.XenStore->req_prod = 0;
1192 xs.XenStore->rsp_cons = xs.XenStore->rsp_prod = 0;
1193 }
1194
1195 xs.XenStore = NULL;
1196}
1197
1198//
1199// Public API
1200// API comments for these methods can be found in XenStore.h
1201//
1202
1203XENSTORE_STATUS
1206 IN CONST CHAR8 *DirectoryPath,
1207 IN CONST CHAR8 *Node,
1208 OUT UINT32 *DirectoryCountPtr,
1209 OUT CONST CHAR8 ***DirectoryListPtr
1210 )
1211{
1212 CHAR8 *Path;
1213 CHAR8 *TempStr;
1214 UINT32 Len = 0;
1215 XENSTORE_STATUS Status;
1216
1217 Path = XenStoreJoin (DirectoryPath, Node);
1218 Status = XenStoreSingle (
1220 XS_DIRECTORY,
1221 Path,
1222 &Len,
1223 (VOID **)&TempStr
1224 );
1225 FreePool (Path);
1226 if (Status != XENSTORE_STATUS_SUCCESS) {
1227 return Status;
1228 }
1229
1230 *DirectoryListPtr = Split (TempStr, Len, DirectoryCountPtr);
1231
1232 return XENSTORE_STATUS_SUCCESS;
1233}
1234
1235BOOLEAN
1238 IN CONST CHAR8 *Directory,
1239 IN CONST CHAR8 *Node
1240 )
1241{
1242 CONST CHAR8 **TempStr;
1243 XENSTORE_STATUS Status;
1244 UINT32 TempNum;
1245
1246 Status = XenStoreListDirectory (
1248 Directory,
1249 Node,
1250 &TempNum,
1251 &TempStr
1252 );
1253 if (Status != XENSTORE_STATUS_SUCCESS) {
1254 return FALSE;
1255 }
1256
1257 FreePool ((VOID *)TempStr);
1258 return TRUE;
1259}
1260
1261XENSTORE_STATUS
1264 IN CONST CHAR8 *DirectoryPath,
1265 IN CONST CHAR8 *Node,
1266 OUT UINT32 *LenPtr OPTIONAL,
1267 OUT VOID **Result
1268 )
1269{
1270 CHAR8 *Path;
1271 VOID *Value;
1272 XENSTORE_STATUS Status;
1273
1274 Path = XenStoreJoin (DirectoryPath, Node);
1275 Status = XenStoreSingle (Transaction, XS_READ, Path, LenPtr, &Value);
1276 FreePool (Path);
1277 if (Status != XENSTORE_STATUS_SUCCESS) {
1278 return Status;
1279 }
1280
1281 *Result = Value;
1282 return XENSTORE_STATUS_SUCCESS;
1283}
1284
1285XENSTORE_STATUS
1288 IN CONST CHAR8 *DirectoryPath,
1289 IN CONST CHAR8 *Node,
1290 IN CONST CHAR8 *Str
1291 )
1292{
1293 CHAR8 *Path;
1294 WRITE_REQUEST WriteRequest[2];
1295 XENSTORE_STATUS Status;
1296
1297 Path = XenStoreJoin (DirectoryPath, Node);
1298
1299 WriteRequest[0].Data = (VOID *)Path;
1300 WriteRequest[0].Len = (UINT32)AsciiStrSize (Path);
1301 WriteRequest[1].Data = (VOID *)Str;
1302 WriteRequest[1].Len = (UINT32)AsciiStrLen (Str);
1303
1304 Status = XenStoreTalkv (Transaction, XS_WRITE, WriteRequest, 2, NULL, NULL);
1305 FreePool (Path);
1306
1307 return Status;
1308}
1309
1310XENSTORE_STATUS
1313 IN CONST CHAR8 *DirectoryPath,
1314 IN CONST CHAR8 *Node
1315 )
1316{
1317 CHAR8 *Path;
1318 XENSTORE_STATUS Status;
1319
1320 Path = XenStoreJoin (DirectoryPath, Node);
1321 Status = XenStoreSingle (Transaction, XS_RM, Path, NULL, NULL);
1322 FreePool (Path);
1323
1324 return Status;
1325}
1326
1327XENSTORE_STATUS
1330 )
1331{
1332 CHAR8 *IdStr;
1333 XENSTORE_STATUS Status;
1334
1335 Status = XenStoreSingle (
1336 XST_NIL,
1337 XS_TRANSACTION_START,
1338 "",
1339 NULL,
1340 (VOID **)&IdStr
1341 );
1342 if (Status == XENSTORE_STATUS_SUCCESS) {
1343 Transaction->Id = (UINT32)AsciiStrDecimalToUintn (IdStr);
1344 FreePool (IdStr);
1345 }
1346
1347 return Status;
1348}
1349
1350XENSTORE_STATUS
1353 IN BOOLEAN Abort
1354 )
1355{
1356 CHAR8 AbortStr[2];
1357
1358 AbortStr[0] = Abort ? 'F' : 'T';
1359 AbortStr[1] = '\0';
1360
1361 return XenStoreSingle (Transaction, XS_TRANSACTION_END, AbortStr, NULL, NULL);
1362}
1363
1364XENSTORE_STATUS
1365EFIAPI
1368 IN CONST CHAR8 *DirectoryPath,
1369 IN CONST CHAR8 *Node,
1370 IN CONST CHAR8 *FormatString,
1371 IN VA_LIST Marker
1372 )
1373{
1374 CHAR8 *Buf;
1375 XENSTORE_STATUS Status;
1376 UINTN BufSize;
1377 VA_LIST Marker2;
1378
1379 VA_COPY (Marker2, Marker);
1380 BufSize = SPrintLengthAsciiFormat (FormatString, Marker2) + 1;
1381 VA_END (Marker2);
1382 Buf = AllocateZeroPool (BufSize);
1383 AsciiVSPrint (Buf, BufSize, FormatString, Marker);
1384 Status = XenStoreWrite (Transaction, DirectoryPath, Node, Buf);
1385 FreePool (Buf);
1386
1387 return Status;
1388}
1389
1390XENSTORE_STATUS
1391EFIAPI
1394 IN CONST CHAR8 *DirectoryPath,
1395 IN CONST CHAR8 *Node,
1396 IN CONST CHAR8 *FormatString,
1397 ...
1398 )
1399{
1400 VA_LIST Marker;
1401 XENSTORE_STATUS Status;
1402
1403 VA_START (Marker, FormatString);
1404 Status = XenStoreVSPrint (Transaction, DirectoryPath, Node, FormatString, Marker);
1405 VA_END (Marker);
1406
1407 return Status;
1408}
1409
1410XENSTORE_STATUS
1412 IN CONST CHAR8 *DirectoryPath,
1413 IN CONST CHAR8 *Node,
1414 OUT XENSTORE_WATCH **WatchPtr
1415 )
1416{
1417 /* Pointer in ascii is the token. */
1418 CHAR8 Token[sizeof (XENSTORE_WATCH) * 2 + 1];
1419 XENSTORE_STATUS Status;
1420 XENSTORE_WATCH *Watch;
1421
1422 Watch = AllocateZeroPool (sizeof (XENSTORE_WATCH));
1423 Watch->Signature = XENSTORE_WATCH_SIGNATURE;
1424 Watch->Node = XenStoreJoin (DirectoryPath, Node);
1425
1427 InsertTailList (&xs.RegisteredWatches, &Watch->Link);
1429
1430 AsciiSPrint (Token, sizeof (Token), "%p", (VOID *)Watch);
1431 Status = XenStoreWatch (Watch->Node, Token);
1432
1433 /* Ignore errors due to multiple registration. */
1434 if (Status == XENSTORE_STATUS_EEXIST) {
1435 Status = XENSTORE_STATUS_SUCCESS;
1436 }
1437
1438 if (Status == XENSTORE_STATUS_SUCCESS) {
1439 *WatchPtr = Watch;
1440 } else {
1442 RemoveEntryList (&Watch->Link);
1444 FreePool (Watch->Node);
1445 FreePool (Watch);
1446 }
1447
1448 return Status;
1449}
1450
1451VOID
1453 IN XENSTORE_WATCH *Watch
1454 )
1455{
1456 CHAR8 Token[sizeof (Watch) * 2 + 1];
1457 LIST_ENTRY *Entry;
1458
1459 ASSERT (Watch->Signature == XENSTORE_WATCH_SIGNATURE);
1460
1461 AsciiSPrint (Token, sizeof (Token), "%p", (VOID *)Watch);
1462 if (XenStoreFindWatch (Token) == NULL) {
1463 return;
1464 }
1465
1467 RemoveEntryList (&Watch->Link);
1469
1470 XenStoreUnwatch (Watch->Node, Token);
1471
1472 /* Cancel pending watch events. */
1474 Entry = GetFirstNode (&xs.WatchEvents);
1475 while (!IsNull (&xs.WatchEvents, Entry)) {
1476 XENSTORE_MESSAGE *Message = XENSTORE_MESSAGE_FROM_LINK (Entry);
1477 Entry = GetNextNode (&xs.WatchEvents, Entry);
1478 if (Message->u.Watch.Handle == Watch) {
1479 RemoveEntryList (&Message->Link);
1480 FreePool ((VOID *)Message->u.Watch.Vector);
1481 FreePool (Message);
1482 }
1483 }
1484
1486
1487 FreePool (Watch->Node);
1488 FreePool (Watch);
1489}
1490
1491//
1492// XENBUS protocol
1493//
1494
1495XENSTORE_STATUS
1496EFIAPI
1497XenBusWaitForWatch (
1498 IN XENBUS_PROTOCOL *This,
1499 IN VOID *Token
1500 )
1501{
1502 return XenStoreWaitWatch (Token);
1503}
1504
1505XENSTORE_STATUS
1506EFIAPI
1507XenBusXenStoreRead (
1508 IN XENBUS_PROTOCOL *This,
1510 IN CONST CHAR8 *Node,
1511 OUT VOID **Value
1512 )
1513{
1514 return XenStoreRead (Transaction, This->Node, Node, NULL, Value);
1515}
1516
1517XENSTORE_STATUS
1518EFIAPI
1519XenBusXenStoreBackendRead (
1520 IN XENBUS_PROTOCOL *This,
1522 IN CONST CHAR8 *Node,
1523 OUT VOID **Value
1524 )
1525{
1526 return XenStoreRead (Transaction, This->Backend, Node, NULL, Value);
1527}
1528
1529XENSTORE_STATUS
1530EFIAPI
1531XenBusXenStoreRemove (
1532 IN XENBUS_PROTOCOL *This,
1534 IN const char *Node
1535 )
1536{
1537 return XenStoreRemove (Transaction, This->Node, Node);
1538}
1539
1540XENSTORE_STATUS
1541EFIAPI
1542XenBusXenStoreTransactionStart (
1543 IN XENBUS_PROTOCOL *This,
1545 )
1546{
1548}
1549
1550XENSTORE_STATUS
1551EFIAPI
1552XenBusXenStoreTransactionEnd (
1553 IN XENBUS_PROTOCOL *This,
1555 IN BOOLEAN Abort
1556 )
1557{
1558 return XenStoreTransactionEnd (Transaction, Abort);
1559}
1560
1561XENSTORE_STATUS
1562EFIAPI
1563XenBusXenStoreSPrint (
1564 IN XENBUS_PROTOCOL *This,
1566 IN CONST CHAR8 *DirectoryPath,
1567 IN CONST CHAR8 *Node,
1568 IN CONST CHAR8 *FormatString,
1569 ...
1570 )
1571{
1572 VA_LIST Marker;
1573 XENSTORE_STATUS Status;
1574
1575 VA_START (Marker, FormatString);
1576 Status = XenStoreVSPrint (Transaction, DirectoryPath, Node, FormatString, Marker);
1577 VA_END (Marker);
1578
1579 return Status;
1580}
1581
1582XENSTORE_STATUS
1583EFIAPI
1584XenBusRegisterWatch (
1585 IN XENBUS_PROTOCOL *This,
1586 IN CONST CHAR8 *Node,
1587 OUT VOID **Token
1588 )
1589{
1590 return XenStoreRegisterWatch (This->Node, Node, (XENSTORE_WATCH **)Token);
1591}
1592
1593XENSTORE_STATUS
1594EFIAPI
1595XenBusRegisterWatchBackend (
1596 IN XENBUS_PROTOCOL *This,
1597 IN CONST CHAR8 *Node,
1598 OUT VOID **Token
1599 )
1600{
1601 return XenStoreRegisterWatch (This->Backend, Node, (XENSTORE_WATCH **)Token);
1602}
1603
1604VOID
1605EFIAPI
1606XenBusUnregisterWatch (
1607 IN XENBUS_PROTOCOL *This,
1608 IN VOID *Token
1609 )
1610{
1612}
UINT64 UINTN
BOOLEAN EFIAPI IsNull(IN CONST LIST_ENTRY *List, IN CONST LIST_ENTRY *Node)
Definition: LinkedList.c:443
BOOLEAN EFIAPI IsListEmpty(IN CONST LIST_ENTRY *ListHead)
Definition: LinkedList.c:403
LIST_ENTRY *EFIAPI GetNextNode(IN CONST LIST_ENTRY *List, IN CONST LIST_ENTRY *Node)
Definition: LinkedList.c:333
UINTN EFIAPI AsciiStrLen(IN CONST CHAR8 *String)
Definition: String.c:641
LIST_ENTRY *EFIAPI InsertHeadList(IN OUT LIST_ENTRY *ListHead, IN OUT LIST_ENTRY *Entry)
Definition: LinkedList.c:218
LIST_ENTRY *EFIAPI GetFirstNode(IN CONST LIST_ENTRY *List)
Definition: LinkedList.c:298
INTN EFIAPI AsciiStrCmp(IN CONST CHAR8 *FirstString, IN CONST CHAR8 *SecondString)
Definition: String.c:716
VOID EFIAPI MemoryFence(VOID)
Definition: CpuBreakpoint.c:42
UINTN EFIAPI AsciiStrDecimalToUintn(IN CONST CHAR8 *String)
Definition: String.c:1006
LIST_ENTRY *EFIAPI RemoveEntryList(IN CONST LIST_ENTRY *Entry)
Definition: LinkedList.c:590
LIST_ENTRY *EFIAPI InitializeListHead(IN OUT LIST_ENTRY *ListHead)
Definition: LinkedList.c:182
UINTN EFIAPI AsciiStrHexToUintn(IN CONST CHAR8 *String)
Definition: String.c:1104
UINTN EFIAPI AsciiStrSize(IN CONST CHAR8 *String)
Definition: String.c:681
LIST_ENTRY *EFIAPI InsertTailList(IN OUT LIST_ENTRY *ListHead, IN OUT LIST_ENTRY *Entry)
Definition: LinkedList.c:259
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)
Definition: SetMemWrapper.c:38
VOID *EFIAPI AllocateZeroPool(IN UINTN AllocationSize)
VOID EFIAPI FreePool(IN VOID *Buffer)
UINT32 XenEventChannelNotify(IN XENBUS_DEVICE *Dev, IN evtchn_port_t Port)
Definition: EventChannel.c:17
UINTN EFIAPI SPrintLengthAsciiFormat(IN CONST CHAR8 *FormatString, IN VA_LIST Marker)
Definition: PrintLib.c:2117
UINTN EFIAPI AsciiVSPrint(OUT CHAR8 *StartOfBuffer, IN UINTN BufferSize, IN CONST CHAR8 *FormatString, IN VA_LIST Marker)
Definition: PrintLib.c:702
UINTN EFIAPI AsciiSPrint(OUT CHAR8 *StartOfBuffer, IN UINTN BufferSize, IN CONST CHAR8 *FormatString,...)
Definition: PrintLib.c:813
#define NULL
Definition: Base.h:319
#define CONST
Definition: Base.h:259
#define STATIC
Definition: Base.h:264
#define VA_START(Marker, Parameter)
Definition: Base.h:661
#define VA_COPY(Dest, Start)
Definition: Base.h:704
#define TRUE
Definition: Base.h:301
#define FALSE
Definition: Base.h:307
#define ARRAY_SIZE(Array)
Definition: Base.h:1393
CHAR8 * VA_LIST
Definition: Base.h:643
#define IN
Definition: Base.h:279
#define OUT
Definition: Base.h:284
#define VA_END(Marker)
Definition: Base.h:691
#define ASSERT_EFI_ERROR(StatusParameter)
Definition: DebugLib.h:462
#define DEBUG(Expression)
Definition: DebugLib.h:434
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)
Definition: SpiBus.c:231
INT32 EFIAPI TestAndClearBit(IN INT32 Bit, IN VOID *Address)
RETURN_STATUS EFI_STATUS
Definition: UefiBaseType.h:29
VOID * EFI_EVENT
Definition: UefiBaseType.h:37
#define EFI_SUCCESS
Definition: UefiBaseType.h:112
EFI_BOOT_SERVICES * gBS
#define EFI_TIMER_PERIOD_SECONDS(Seconds)
Definition: UefiLib.h:98
VOID EFIAPI EfiReleaseLock(IN EFI_LOCK *Lock)
Definition: UefiLib.c:499
#define EFI_TIMER_PERIOD_MILLISECONDS(Milliseconds)
Definition: UefiLib.h:86
VOID EFIAPI EfiAcquireLock(IN EFI_LOCK *Lock)
Definition: UefiLib.c:434
EFI_LOCK *EFIAPI EfiInitializeLock(IN OUT EFI_LOCK *Lock, IN EFI_TPL Priority)
Definition: UefiLib.c:405
@ TimerRelative
Definition: UefiSpec.h:539
UINT64 EFIAPI XenHypercallHvmGetParam(UINT32 Index)
STATIC XENSTORE_STATUS XenStoreReadReply(OUT enum xsd_sockmsg_type *TypePtr, OUT UINT32 *LenPtr OPTIONAL, OUT VOID **Result)
Definition: XenStore.c:750
STATIC XENSTORE_WATCH * XenStoreFindWatch(IN CONST CHAR8 *Token)
Definition: XenStore.c:253
STATIC VOID * XenStoreGetOutputChunk(IN XENSTORE_RING_IDX Cons, IN XENSTORE_RING_IDX Prod, IN CHAR8 *Buffer, OUT UINT32 *LenPtr)
Definition: XenStore.c:346
XENSTORE_STATUS EFIAPI XenStoreSPrint(IN CONST XENSTORE_TRANSACTION *Transaction, IN CONST CHAR8 *DirectoryPath, IN CONST CHAR8 *Node, IN CONST CHAR8 *FormatString,...)
Definition: XenStore.c:1392
XENSTORE_STATUS XenStoreRegisterWatch(IN CONST CHAR8 *DirectoryPath, IN CONST CHAR8 *Node, OUT XENSTORE_WATCH **WatchPtr)
Definition: XenStore.c:1411
XENSTORE_STATUS XenStoreRemove(IN CONST XENSTORE_TRANSACTION *Transaction, IN CONST CHAR8 *DirectoryPath, IN CONST CHAR8 *Node)
Definition: XenStore.c:1311
STATIC CONST CHAR8 ** Split(IN CHAR8 *Strings, IN UINTN Len, OUT UINT32 *NumPtr)
Definition: XenStore.c:212
STATIC EFI_STATUS XenStoreInitComms(XENSTORE_PRIVATE *xsp)
Definition: XenStore.c:1035
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)
Definition: XenStore.c:806
STATIC XENSTORE_STATUS XenStoreProcessMessage(VOID)
Definition: XenStore.c:618
#define XENSTORE_MESSAGE_SIGNATURE
Definition: XenStore.c:75
STATIC XENSTORE_STATUS XenStoreWatch(CONST CHAR8 *Path, CONST CHAR8 *Token)
Definition: XenStore.c:928
VOID XenStoreUnregisterWatch(IN XENSTORE_WATCH *Watch)
Definition: XenStore.c:1452
STATIC BOOLEAN XenStoreCheckIndexes(XENSTORE_RING_IDX Cons, XENSTORE_RING_IDX Prod)
Definition: XenStore.c:325
XENSTORE_STATUS XenStoreListDirectory(IN CONST XENSTORE_TRANSACTION *Transaction, IN CONST CHAR8 *DirectoryPath, IN CONST CHAR8 *Node, OUT UINT32 *DirectoryCountPtr, OUT CONST CHAR8 ***DirectoryListPtr)
Definition: XenStore.c:1204
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)
Definition: XenStore.c:1366
STATIC EFI_STATUS XenStoreWaitForEvent(IN EFI_EVENT Event, IN UINT64 Timeout)
Definition: XenStore.c:407
CHAR8 * XenStoreJoin(IN CONST CHAR8 *DirectoryPath, IN CONST CHAR8 *Node)
Definition: XenStore.c:285
STATIC XENSTORE_STATUS XenStoreReadStore(OUT VOID *DataPtr, IN UINT32 Len)
Definition: XenStore.c:531
STATIC XENSTORE_STATUS XenStoreWriteStore(IN CONST VOID *DataPtr, IN UINT32 Len)
Definition: XenStore.c:449
XENSTORE_STATUS XenStoreWrite(IN CONST XENSTORE_TRANSACTION *Transaction, IN CONST CHAR8 *DirectoryPath, IN CONST CHAR8 *Node, IN CONST CHAR8 *Str)
Definition: XenStore.c:1286
EFI_STATUS XenStoreInit(XENBUS_DEVICE *Dev)
Definition: XenStore.c:1085
XENSTORE_STATUS XenStoreTransactionStart(OUT XENSTORE_TRANSACTION *Transaction)
Definition: XenStore.c:1328
BOOLEAN XenStorePathExists(IN CONST XENSTORE_TRANSACTION *Transaction, IN CONST CHAR8 *Directory, IN CONST CHAR8 *Node)
Definition: XenStore.c:1236
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)
Definition: XenStore.c:890
XENSTORE_STATUS XenStoreRead(IN CONST XENSTORE_TRANSACTION *Transaction, IN CONST CHAR8 *DirectoryPath, IN CONST CHAR8 *Node, OUT UINT32 *LenPtr OPTIONAL, OUT VOID **Result)
Definition: XenStore.c:1262
XENSTORE_STATUS XenStoreTransactionEnd(IN CONST XENSTORE_TRANSACTION *Transaction, IN BOOLEAN Abort)
Definition: XenStore.c:1351
STATIC UINT32 ExtractStrings(IN CONST CHAR8 *Strings, IN UINTN Len, OUT CONST CHAR8 **Dst OPTIONAL)
Definition: XenStore.c:173
STATIC CONST VOID * XenStoreGetInputChunk(IN XENSTORE_RING_IDX Cons, IN XENSTORE_RING_IDX Prod, IN CONST CHAR8 *Buffer, OUT UINT32 *LenPtr)
Definition: XenStore.c:377
STATIC XENSTORE_STATUS XenStoreUnwatch(CONST CHAR8 *Path, CONST CHAR8 *Token)
Definition: XenStore.c:954
VOID XenStoreDeinit(IN XENBUS_DEVICE *Dev)
Definition: XenStore.c:1124
struct xenstore_domain_interface * XenStore
Definition: XenStore.c:107
EFI_EVENT EventChannelEvent
Definition: XenStore.c:149
LIST_ENTRY WatchEvents
Definition: XenStore.c:137
EFI_LOCK WatchEventsLock
Definition: XenStore.c:140
EFI_LOCK ReplyLock
Definition: XenStore.c:124
EFI_LOCK RegisteredWatchesLock
Definition: XenStore.c:132
LIST_ENTRY RegisteredWatches
Definition: XenStore.c:129
evtchn_port_t EventChannel
Definition: XenStore.c:146
LIST_ENTRY ReplyList
Definition: XenStore.c:121