TianoCore EDK2 master
Loading...
Searching...
No Matches
ArmVirtQemuMonitorPeiLib.c
Go to the documentation of this file.
1
12#include <Base.h>
13
14#include <Library/ArmHvcLib.h>
16#include <Library/ArmSmcLib.h>
17#include <Library/BaseLib.h>
18#include <Library/DebugLib.h>
19#include <Library/FdtLib.h>
20
21typedef enum {
22 SmcccConduitUnknown,
23 SmcccConduitSmc,
24 SmcccConduitHvc,
25} SMCCC_CONDUIT;
26
33SMCCC_CONDUIT
35 VOID
36 )
37{
38 VOID *DeviceTreeBase;
39 INT32 Node, Prev;
40 INT32 Len;
41 CONST FDT_PROPERTY *Compatible;
42 CONST CHAR8 *CompatibleItem;
43 CONST FDT_PROPERTY *Prop;
44
45 DeviceTreeBase = (VOID *)(UINTN)PcdGet64 (PcdDeviceTreeInitialBaseAddress);
46 ASSERT (FdtCheckHeader (DeviceTreeBase) == 0);
47
48 //
49 // Enumerate all FDT nodes looking for the PSCI node and capture the conduit
50 //
51 for (Prev = 0; ; Prev = Node) {
52 Node = FdtNextNode (DeviceTreeBase, Prev, NULL);
53 if (Node < 0) {
54 break;
55 }
56
57 Compatible = FdtGetProperty (DeviceTreeBase, Node, "compatible", &Len);
58 if (Compatible == NULL) {
59 continue;
60 }
61
62 //
63 // Iterate over the NULL-separated items in the compatible string
64 //
65 for (CompatibleItem = Compatible->Data; CompatibleItem < Compatible->Data + Len;
66 CompatibleItem += 1 + AsciiStrLen (CompatibleItem))
67 {
68 if (AsciiStrCmp (CompatibleItem, "arm,psci-0.2") != 0) {
69 continue;
70 }
71
72 Prop = FdtGetProperty (DeviceTreeBase, Node, "method", NULL);
73 if (Prop == NULL) {
74 DEBUG ((
75 DEBUG_ERROR,
76 "%a: Missing PSCI method property\n",
77 __func__
78 ));
79
80 return SmcccConduitUnknown;
81 }
82
83 if (AsciiStrnCmp (Prop->Data, "hvc", 3) == 0) {
84 return SmcccConduitHvc;
85 } else if (AsciiStrnCmp (Prop->Data, "smc", 3) == 0) {
86 return SmcccConduitSmc;
87 } else {
88 DEBUG ((
89 DEBUG_ERROR,
90 "%a: Unknown PSCI method \"%a\"\n",
91 __func__,
92 Prop
93 ));
94
95 return SmcccConduitUnknown;
96 }
97 }
98 }
99
100 return SmcccConduitUnknown;
101}
102
110VOID
111EFIAPI
114 )
115{
116 switch (DiscoverSmcccConduit ()) {
117 case SmcccConduitHvc:
118 ArmCallHvc ((ARM_HVC_ARGS *)Args);
119 break;
120
121 case SmcccConduitSmc:
122 ArmCallSmc ((ARM_SMC_ARGS *)Args);
123 break;
124
125 default:
126 ASSERT (FALSE);
127 }
128}
UINT64 UINTN
VOID ArmCallHvc(IN OUT ARM_HVC_ARGS *Args)
Definition: ArmHvcLibNull.c:23
VOID ArmCallSmc(IN OUT ARM_SMC_ARGS *Args)
Definition: ArmSmcLibNull.c:14
VOID EFIAPI ArmMonitorCall(IN OUT ARM_MONITOR_ARGS *Args)
STATIC SMCCC_CONDUIT DiscoverSmcccConduit(VOID)
UINTN EFIAPI AsciiStrLen(IN CONST CHAR8 *String)
Definition: String.c:641
INTN EFIAPI AsciiStrCmp(IN CONST CHAR8 *FirstString, IN CONST CHAR8 *SecondString)
Definition: String.c:716
INTN EFIAPI AsciiStrnCmp(IN CONST CHAR8 *FirstString, IN CONST CHAR8 *SecondString, IN UINTN Length)
Definition: String.c:872
CONST FDT_PROPERTY *EFIAPI FdtGetProperty(IN CONST VOID *Fdt, IN INT32 NodeOffset, IN CONST CHAR8 *Name, IN INT32 *Length)
Definition: FdtLib.c:446
INT32 EFIAPI FdtNextNode(IN CONST VOID *Fdt, IN INT32 Offset, IN INT32 *Depth)
Definition: FdtLib.c:220
INT32 EFIAPI FdtCheckHeader(IN CONST VOID *Fdt)
Definition: FdtLib.c:125
#define NULL
Definition: Base.h:319
#define CONST
Definition: Base.h:259
#define STATIC
Definition: Base.h:264
#define FALSE
Definition: Base.h:307
#define IN
Definition: Base.h:279
#define OUT
Definition: Base.h:284
#define DEBUG(Expression)
Definition: DebugLib.h:434
#define PcdGet64(TokenName)
Definition: PcdLib.h:375