]> git.proxmox.com Git - mirror_edk2.git/blob - ArmPkg/Drivers/ArmScmiDxe/ScmiDxe.c
ArmPkg: Replace BSD License with BSD+Patent License
[mirror_edk2.git] / ArmPkg / Drivers / ArmScmiDxe / ScmiDxe.c
1 /** @file
2
3 Copyright (c) 2017-2018, Arm Limited. All rights reserved.
4
5 SPDX-License-Identifier: BSD-2-Clause-Patent
6
7 System Control and Management Interface V1.0
8 http://infocenter.arm.com/help/topic/com.arm.doc.den0056a/
9 DEN0056A_System_Control_and_Management_Interface.pdf
10 **/
11
12 #include <Base.h>
13 #include <Library/DebugLib.h>
14 #include <Library/MemoryAllocationLib.h>
15 #include <Library/UefiBootServicesTableLib.h>
16 #include <Protocol/ArmScmiBaseProtocol.h>
17 #include <Protocol/ArmScmiClockProtocol.h>
18 #include <Protocol/ArmScmiPerformanceProtocol.h>
19
20 #include "ArmScmiBaseProtocolPrivate.h"
21 #include "ArmScmiClockProtocolPrivate.h"
22 #include "ArmScmiPerformanceProtocolPrivate.h"
23 #include "ScmiDxe.h"
24 #include "ScmiPrivate.h"
25
26 STATIC CONST SCMI_PROTOCOL_ENTRY Protocols[] = {
27 { SCMI_PROTOCOL_ID_BASE, ScmiBaseProtocolInit },
28 { SCMI_PROTOCOL_ID_PERFORMANCE, ScmiPerformanceProtocolInit },
29 { SCMI_PROTOCOL_ID_CLOCK, ScmiClockProtocolInit }
30 };
31
32 /** ARM SCMI driver entry point function.
33
34 This function installs the SCMI Base protocol and a list of other
35 protocols is queried using the Base protocol. If protocol is supported,
36 driver will call each protocol init function to install the protocol on
37 the ImageHandle.
38
39 @param[in] ImageHandle Handle to this EFI Image which will be used to
40 install Base, Clock and Performance protocols.
41 @param[in] SystemTable A pointer to boot time system table.
42
43 @retval EFI_SUCCESS Driver initalized successfully.
44 @retval EFI_UNSUPPORTED If SCMI base protocol version is not supported.
45 @retval !(EFI_SUCCESS) Other errors.
46 **/
47 EFI_STATUS
48 EFIAPI
49 ArmScmiDxeEntryPoint (
50 IN EFI_HANDLE ImageHandle,
51 IN EFI_SYSTEM_TABLE *SystemTable
52 )
53 {
54 EFI_STATUS Status;
55 SCMI_BASE_PROTOCOL *BaseProtocol;
56 UINT32 Version;
57 UINT32 Index;
58 UINT32 NumProtocols;
59 UINT32 ProtocolIndex;
60 UINT8 *SupportedList;
61 UINT32 SupportedListSize;
62
63 // Every SCMI implementation must implement the base protocol.
64 ASSERT (Protocols[0].Id == SCMI_PROTOCOL_ID_BASE);
65
66 Status = ScmiBaseProtocolInit (&ImageHandle);
67 if (EFI_ERROR (Status)) {
68 ASSERT (FALSE);
69 return Status;
70 }
71
72 Status = gBS->LocateProtocol (
73 &gArmScmiBaseProtocolGuid,
74 NULL,
75 (VOID**)&BaseProtocol
76 );
77 if (EFI_ERROR (Status)) {
78 ASSERT (FALSE);
79 return Status;
80 }
81
82 // Get SCMI Base protocol version.
83 Status = BaseProtocol->GetVersion (BaseProtocol, &Version);
84 if (EFI_ERROR (Status)) {
85 ASSERT (FALSE);
86 return Status;
87 }
88
89 if (Version != BASE_PROTOCOL_VERSION) {
90 ASSERT (FALSE);
91 return EFI_UNSUPPORTED;
92 }
93
94 // Apart from Base protocol, SCMI may implement various other protocols,
95 // query total protocols implemented by the SCP firmware.
96 NumProtocols = 0;
97 Status = BaseProtocol->GetTotalProtocols (BaseProtocol, &NumProtocols);
98 if (EFI_ERROR (Status)) {
99 ASSERT (FALSE);
100 return Status;
101 }
102
103 ASSERT (NumProtocols != 0);
104
105 SupportedListSize = (NumProtocols * sizeof (*SupportedList));
106
107 Status = gBS->AllocatePool (
108 EfiBootServicesData,
109 SupportedListSize,
110 (VOID**)&SupportedList
111 );
112 if (EFI_ERROR (Status)) {
113 ASSERT (FALSE);
114 return Status;
115 }
116
117 // Get the list of protocols supported by SCP firmware on the platform.
118 Status = BaseProtocol->DiscoverListProtocols (
119 BaseProtocol,
120 &SupportedListSize,
121 SupportedList
122 );
123 if (EFI_ERROR (Status)) {
124 gBS->FreePool (SupportedList);
125 ASSERT (FALSE);
126 return Status;
127 }
128
129 // Install supported protocol on ImageHandle.
130 for (ProtocolIndex = 1; ProtocolIndex < ARRAY_SIZE (Protocols);
131 ProtocolIndex++) {
132 for (Index = 0; Index < NumProtocols; Index++) {
133 if (Protocols[ProtocolIndex].Id == SupportedList[Index]) {
134 Status = Protocols[ProtocolIndex].InitFn (&ImageHandle);
135 if (EFI_ERROR (Status)) {
136 ASSERT_EFI_ERROR (Status);
137 return Status;
138 }
139 break;
140 }
141 }
142 }
143
144 gBS->FreePool (SupportedList);
145
146 return EFI_SUCCESS;
147 }