summaryrefslogtreecommitdiff
path: root/Core/EM/HddSecurity/IdeSecurityBdsCall.c
blob: 7aaf8bc25b9ba11e8271a7cd1bcc7110743d430d (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
//*************************************************************************
//*************************************************************************
//**                                                                     **
//**        (C)Copyright 1985-2014, American Megatrends, Inc.            **
//**                                                                     **
//**                       All Rights Reserved.                          **
//**                                                                     **
//**      5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093           **
//**                                                                     **
//**                       Phone: (770)-246-8600                         **
//**                                                                     **
//*************************************************************************
//*************************************************************************

//*************************************************************************
// $Header: /Alaska/SOURCE/Modules/HddSecurity/IdeSecurityBdsCall.c 2     6/09/14 9:53a Anbuprakashp $
//
// $Revision: 2 $
//
// $Date: 6/09/14 9:53a $
//
//*************************************************************************
// Revision History
// ----------------
// $Log: /Alaska/SOURCE/Modules/HddSecurity/IdeSecurityBdsCall.c $
// 
// 2     6/09/14 9:53a Anbuprakashp
// [TAG]  		EIP 172443  
// [Category]  	Improvement
// [Description]  	"RaidDriverBlockingStatus" is using
// gEfiGlobalVariableGuid that violates UEFI 2.4 spec in
// IdeSecurityBdsCall.c and Runtime attribute set of this variable need to
// be removed
// [Files]  		IdeSecurityBdsCall.c, AhciBus.c
// 
// 1     6/06/13 4:03a Rameshr
// [TAG]  		EIP106423
// [Category]  	Improvement
// [Description]  	HddPassword Support in UEFI Raid and Legacy Raid. And
// also taken care where there is no Conin Device avilable in the post
// [Files]  		IdeSecurity.cif
// IdeSecurity.sdl
// IdeSecurity.mak
// IdeSecurity.h
// IdeSecurity.c
// IdeSecuritySetup.c
// IdeSecurityBdsCall.c
// IdeSecurity.sd
// IdeSecurity.uni
// IdeSecurity.dxs
// IdeSecurity.chm
//
// 
//*************************************************************************

//<AMI_FHDR_START>
//----------------------------------------------------------------------------
//
// Name:        IdeSecurityBdsCall.c
//
// Description: This function will connect the handle's of RAID Controllers and
//  the IDE/AHCI Devices( the handle whose DiskIo was not opened by any one.)
//
//
//----------------------------------------------------------------------------
//<AMI_FHDR_END>


#include <PCI.h>
#include "Protocol\DiskIo.h"
#include <Protocol\IdeControllerInit.h>
#include <AmiDxeLib.h>
#include <Protocol\DevicePath.h>

static EFI_GUID  gAmiGlobalVariableGuid          = AMI_GLOBAL_VARIABLE_GUID;


extern EFI_STATUS GetPciHandlesByClass(
    UINT8 Class, UINT8 SubClass, UINTN *NumberOfHandles, EFI_HANDLE **HandleBuffer
);

// <AMI_PHDR_START>
//---------------------------------------------------------------------------
//
// Name: IdeConnectControllerAfterConnectEverthing
//
// Description:
//  This function will connect the handle's of RAID Controllers and the IDE/AHCI
//  Devices( the handle whose DiskIo was not opened by any one.)
//
// Input:
//  VOID
//
// Output:
//  VOID  
//
// Modified:
//
// Referrals:
//
//
// Notes:
// If Conin Devices are not Present, RAID Option ROM will not be launched 
// by CSM BlockIo as RegisterHddNotification fucntion would get control after
// connectEverything() is called from BDS. Rather it would be launched by
// ShadowAllLegacyOproms() and UEFI Boot option for RAID will not be formed as
// blockIo will not be installed by csm BlockIo driver. So Connect the RAID handle
// so that CSM BlockIo starts. And also if Password is installed the above said case
// will happen when no con in device is present.
//
// Check for any device in IDE/AHCI mode not unlocked when no ConIn Device is not present.
// If found Connecting that Device using ConnectController() after the Device is unlocked.
// as read would fail and FileSystem would not be formedOpen gEfiIdeControllerInitProtocolGuid
// which will be installed on each controller. This will be opened as
// EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER by each device handle.Connect that Handle where
// DiskIo will be installed and not opened by another driver.
//
//--------------------------------------------------------------------------- 
// <AMI_PHDR_END>

VOID IdeConnectControllerAfterConnectEverthing( ) 
{

    UINT8               Index;
    UINT8               Index1;
    UINTN               DiskIoCount;
    UINTN               Count;
    UINTN               Count1;
    EFI_HANDLE          *HandleBuffer = NULL;
    UINTN               NumHandles;
    EFI_STATUS          Status;
    EFI_OPEN_PROTOCOL_INFORMATION_ENTRY *DiskIoEntries = NULL;
    EFI_OPEN_PROTOCOL_INFORMATION_ENTRY *Entries = NULL;
    BOOLEAN             RaidDriverBlocked=FALSE;
    UINTN               VarSize=sizeof(RaidDriverBlocked);

    

    // If Conin Devices are not Present, RAID Option ROM will not be launched 
    // by CSM BlockIo as RegisterHddNotification fucntion would get control after
    // connectEverything() is called from BDS. Rather it would be launched by
    // ShadowAllLegacyOproms() and UEFI Boot option for RAID will not be formed as
    // blockIo will not be installed by csm BlockIo driver. So Connect the RAID handle
    // so that CSM BlockIo starts. And also if Password is installed the above said case
    // will happen when no con in device is present.

    Status = GetPciHandlesByClass(PCI_CL_MASS_STOR,
                                        PCI_CL_MASS_STOR_SCL_RAID,
                                        &NumHandles,
                                        &HandleBuffer
                                        );

    // Connect the handle so that CSM BlockIo Launches RAID Option Rom.
    if(!EFI_ERROR(Status)){

        Status = pRS->GetVariable( L"RaidDriverBlockingStatus",
                                   &gAmiGlobalVariableGuid,
                                   NULL,
                                   &VarSize,
                                   &RaidDriverBlocked );


        if((EFI_ERROR(Status)) || (RaidDriverBlocked == FALSE)) {
            return;
        }
        
        for(Index=0; Index<NumHandles; Index++){

            // We have blocked the Raid driver until password verification is done. 
            // Now we need to un block and connect the Raid driver after HddPassword verification is done 
            Status = pBS->OpenProtocolInformation(HandleBuffer[Index], 
                                                &gEfiDevicePathProtocolGuid, 
                                                &Entries, 
                                                &Count1
                                                );

            if(!EFI_ERROR(Status)) {
                for(Index1=0; Index1 < Count1; Index1++) { 
                    if (Entries[Index1].Attributes!=EFI_OPEN_PROTOCOL_BY_DRIVER) {
                        continue;                    
                    }

                    Status = pBS->CloseProtocol (
                                    HandleBuffer[Index],
                                    &gEfiDevicePathProtocolGuid,
                                    Entries[Index1].AgentHandle,
                                    Entries[Index1].ControllerHandle
                                    );
                }
            }

            pBS->ConnectController(HandleBuffer[Index],NULL,NULL,TRUE);
        }

    } else {

        // Check for any device in IDE/AHCI mode not unlocked when no ConIn Device is not present.
        // If found Connecting that Device using ConnectController() after the Device is unlocked.
        // Open gEfiIdeControllerInitProtocolGuid which will be installed on each controller.
        // This will be opened as EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER by each device handle.
        // Connect that Handle where DiskIo will be installed and not opened by another driver.

        Status = pBS->LocateHandleBuffer(ByProtocol,
	                    &gEfiIdeControllerInitProtocolGuid,
	                    NULL,
	                    &Count,
	                    &HandleBuffer);

    	if(!EFI_ERROR(Status)){
            for(Index=0; Index < Count; Index++) {
                Status = pBS->OpenProtocolInformation(HandleBuffer[Index], 
                                                    &gEfiIdeControllerInitProtocolGuid, 
                                                    &Entries, 
                                                    &Count1
                                                    );
                if(!EFI_ERROR(Status)) {
                    for(Index1=0; Index1 < Count1; Index1++) { 
                        if (Entries[Index1].Attributes!=EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER) {
                            continue;                    
                        }                    
                        Status = pBS->OpenProtocolInformation(Entries[Index1].ControllerHandle, 
                                                    &gEfiDiskIoProtocolGuid, 
                                                    &DiskIoEntries, 
                                                    &DiskIoCount
                                                    );		                    
                        if(!EFI_ERROR(Status)) {        
                            if( DiskIoCount == 0 ) {
                                Status = pBS->ConnectController(Entries[Index1].ControllerHandle,
                                                            NULL,
                                                            NULL,
                                                            TRUE);			
                            }
                            pBS->FreePool(DiskIoEntries);
                        }
                    }
                    pBS->FreePool(Entries);
                }
            }
    	}
    }

    if(HandleBuffer) {
        pBS->FreePool(HandleBuffer);
    }

    return;
}

//**********************************************************************
//**********************************************************************
//**                                                                  **
//**        (C)Copyright 1985-2014, American Megatrends, Inc.         **
//**                                                                  **
//**                       All Rights Reserved.                       **
//**                                                                  **
//**         5555 Oakbrook Pkwy, Suite 200, Norcross, GA 30093        **
//**                                                                  **
//**                       Phone: (770)-246-8600                      **
//**                                                                  **
//**********************************************************************
//**********************************************************************