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
|
/** @file
Device driver for the Atmel ATSHA204A random number generator.
Copyright (c) 2018, Linaro Ltd. All rights reserved.<BR>
This program and the accompanying materials
are licensed and made available under the terms and conditions of the BSD
License which accompanies this distribution. The full text of the license may
be found at http://opensource.org/licenses/bsd-license.php.
THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
**/
#include <Library/UefiDriverEntryPoint.h>
#include "AtSha204aDriver.h"
/**
Tests to see if this driver supports a given controller.
@param This[in] A pointer to the EFI_DRIVER_BINDING_PROTOCOL
instance.
@param ControllerHandle[in] The handle of the controller to test.
@param RemainingDevicePath[in] The remaining device path.
(Ignored - this is not a bus driver.)
@retval EFI_SUCCESS The driver supports this controller.
@retval EFI_ALREADY_STARTED The device specified by ControllerHandle is
already being managed by the driver specified
by This.
@retval EFI_UNSUPPORTED The device specified by ControllerHandle is
not supported by the driver specified by This.
**/
EFI_STATUS
EFIAPI
I2cHwrngDriverBindingSupported (
IN EFI_DRIVER_BINDING_PROTOCOL *This,
IN EFI_HANDLE ControllerHandle,
IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath
)
{
EFI_I2C_IO_PROTOCOL *I2cIo;
EFI_STATUS Status;
//
// Connect to the I2C stack
//
Status = gBS->OpenProtocol (ControllerHandle,
&gEfiI2cIoProtocolGuid,
(VOID **) &I2cIo,
This->DriverBindingHandle,
ControllerHandle,
EFI_OPEN_PROTOCOL_BY_DRIVER);
if (EFI_ERROR (Status)) {
return Status;
}
if (CompareGuid (I2cIo->DeviceGuid, &gAtSha204aI2cDeviceGuid)) {
DEBUG ((DEBUG_INIT | DEBUG_INFO, "Detected AtSha204a RNG device\n"));
Status = EFI_SUCCESS;
} else {
Status = EFI_UNSUPPORTED;
}
//
// Clean up.
//
gBS->CloseProtocol (ControllerHandle,
&gEfiI2cIoProtocolGuid,
This->DriverBindingHandle,
ControllerHandle);
return Status;
}
/**
Starts a device controller or a bus controller.
@param[in] This A pointer to the EFI_DRIVER_BINDING_PROTOCOL
instance.
@param[in] ControllerHandle The handle of the device to start. This
handle must support a protocol interface that
supplies an I/O abstraction to the driver.
@param[in] RemainingDevicePath The remaining portion of the device path.
(Ignored - this is not a bus driver.)
@retval EFI_SUCCESS The device was started.
@retval EFI_DEVICE_ERROR The device could not be started due to a
device error.
@retval EFI_OUT_OF_RESOURCES The request could not be completed due to a
lack of resources.
**/
EFI_STATUS
EFIAPI
I2cHwrngDriverBindingStart (
IN EFI_DRIVER_BINDING_PROTOCOL *This,
IN EFI_HANDLE ControllerHandle,
IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath OPTIONAL
)
{
return AtSha204aInit (This->DriverBindingHandle, ControllerHandle);
}
/**
Stops a device controller or a bus controller.
@param[in] This A pointer to the EFI_DRIVER_BINDING_PROTOCOL
instance.
@param[in] ControllerHandle A handle to the device being stopped. The handle
must support a bus specific I/O protocol for the
driver to use to stop the device.
@param[in] NumberOfChildren The number of child device handles in
ChildHandleBuffer.
@param[in] ChildHandleBuffer An array of child handles to be freed. May be
NULL if NumberOfChildren is 0.
@retval EFI_SUCCESS The device was stopped.
@retval EFI_DEVICE_ERROR The device could not be stopped due to a device
error.
**/
EFI_STATUS
EFIAPI
I2cHwrngDriverBindingStop (
IN EFI_DRIVER_BINDING_PROTOCOL *This,
IN EFI_HANDLE ControllerHandle,
IN UINTN NumberOfChildren,
IN EFI_HANDLE *ChildHandleBuffer OPTIONAL
)
{
return AtSha204aRelease (This->DriverBindingHandle, ControllerHandle);
}
STATIC
EFI_DRIVER_BINDING_PROTOCOL gI2cHwrngDriverBinding = {
I2cHwrngDriverBindingSupported,
I2cHwrngDriverBindingStart,
I2cHwrngDriverBindingStop,
0xa,
NULL,
NULL
};
/**
The entry point of AtSha204a UEFI Driver.
@param ImageHandle The image handle of the UEFI Driver.
@param SystemTable A pointer to the EFI System Table.
@retval EFI_SUCCESS The Driver or UEFI Driver exited normally.
@retval EFI_INCOMPATIBLE_VERSION _gUefiDriverRevision is greater than
SystemTable->Hdr.Revision.
**/
EFI_STATUS
EFIAPI
EntryPoint (
IN EFI_HANDLE ImageHandle,
IN EFI_SYSTEM_TABLE *SystemTable
)
{
EFI_STATUS Status;
//
// Add the driver to the list of drivers
//
Status = EfiLibInstallDriverBindingComponentName2 (
ImageHandle, SystemTable, &gI2cHwrngDriverBinding, ImageHandle,
NULL, &gAtSha204aDriverComponentName2);
ASSERT_EFI_ERROR (Status);
DEBUG ((DEBUG_INIT | DEBUG_INFO, "*** Installed AtSha204a driver! ***\n"));
return EFI_SUCCESS;
}
/**
Unload function for the AtSha204a Driver.
@param ImageHandle[in] The allocated handle for the EFI image
@retval EFI_SUCCESS The driver was unloaded successfully
@retval EFI_INVALID_PARAMETER ImageHandle is not a valid image handle.
**/
EFI_STATUS
EFIAPI
UnloadImage (
IN EFI_HANDLE ImageHandle
)
{
EFI_STATUS Status;
EFI_HANDLE *HandleBuffer;
UINTN HandleCount;
UINTN Index;
//
// Retrieve all I2C I/O handles in the handle database
//
Status = gBS->LocateHandleBuffer (ByProtocol,
&gEfiI2cIoProtocolGuid,
NULL,
&HandleCount,
&HandleBuffer);
if (EFI_ERROR (Status)) {
return Status;
}
//
// Disconnect the driver from the handles in the handle database
//
for (Index = 0; Index < HandleCount; Index++) {
Status = gBS->DisconnectController (HandleBuffer[Index],
gImageHandle,
NULL);
}
//
// Free the handle array
//
gBS->FreePool (HandleBuffer);
//
// Uninstall protocols installed by the driver in its entrypoint
//
Status = gBS->UninstallMultipleProtocolInterfaces (ImageHandle,
&gEfiDriverBindingProtocolGuid,
&gI2cHwrngDriverBinding,
NULL
);
return EFI_SUCCESS;
}
|