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