summaryrefslogtreecommitdiff
path: root/Silicon/Atmel
diff options
context:
space:
mode:
Diffstat (limited to 'Silicon/Atmel')
-rw-r--r--Silicon/Atmel/AtSha204a/AtSha204a.dec22
-rw-r--r--Silicon/Atmel/AtSha204a/AtSha204aDriver.c309
-rw-r--r--Silicon/Atmel/AtSha204a/AtSha204aDriver.h81
-rw-r--r--Silicon/Atmel/AtSha204a/AtSha204aDxe.inf52
-rw-r--r--Silicon/Atmel/AtSha204a/ComponentName.c186
-rw-r--r--Silicon/Atmel/AtSha204a/DriverBinding.c242
6 files changed, 892 insertions, 0 deletions
diff --git a/Silicon/Atmel/AtSha204a/AtSha204a.dec b/Silicon/Atmel/AtSha204a/AtSha204a.dec
new file mode 100644
index 0000000000..f1fdea5984
--- /dev/null
+++ b/Silicon/Atmel/AtSha204a/AtSha204a.dec
@@ -0,0 +1,22 @@
+## @file
+#
+# Copyright (c) 2018, Linaro Ltd. All rights reserved.
+#
+# 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.
+#
+##
+
+[Defines]
+ DEC_SPECIFICATION = 0x0001001A
+ PACKAGE_NAME = AtSha204a
+ PACKAGE_GUID = 86085a5b-355b-4e72-92ab-fc3e1d71c9ad
+ PACKAGE_VERSION = 0.1
+
+[Guids]
+ gAtSha204aI2cDeviceGuid = { 0x52e9b64b, 0x4ec1, 0x4bd6, { 0x9e, 0x1c, 0x6d, 0xac, 0xef, 0x35, 0x18, 0x21 } }
diff --git a/Silicon/Atmel/AtSha204a/AtSha204aDriver.c b/Silicon/Atmel/AtSha204a/AtSha204aDriver.c
new file mode 100644
index 0000000000..5db2de21a7
--- /dev/null
+++ b/Silicon/Atmel/AtSha204a/AtSha204aDriver.c
@@ -0,0 +1,309 @@
+/** @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 "AtSha204aDriver.h"
+
+#include <Library/BaseMemoryLib.h>
+#include <Library/DebugLib.h>
+#include <Library/MemoryAllocationLib.h>
+
+#define MAX_RETRIES 5
+
+// Don't bother calculating the CRC for the immutable RANDOM opcode packet
+#define OPCODE_COMMAND_PACKET_CRC 0xcd24
+
+/**
+ Returns information about the random number generation implementation.
+
+ @param[in] This A pointer to the EFI_RNG_PROTOCOL instance.
+ @param[in,out] AlgorithmListSize On input, the size in bytes of AlgorithmList
+ On output with a return code of EFI_SUCCESS,
+ the size in bytes of the data returned in
+ AlgorithmList. On output with a return
+ code of EFI_BUFFER_TOO_SMALL, the size of
+ AlgorithmList required to obtain the list.
+ @param[out] AlgorithmList A caller-allocated memory buffer filled by
+ the driver with one EFI_RNG_ALGORITHM
+ element for each supported RNG algorithm.
+ The list must not change across multiple
+ calls to the same driver. The first
+ algorithm in the list is the default
+ algorithm for the driver.
+
+ @retval EFI_SUCCESS The RNG algorithm list was returned
+ successfully.
+ @retval EFI_UNSUPPORTED The services is not supported by this driver
+ @retval EFI_DEVICE_ERROR The list of algorithms could not be
+ retrieved due to a hardware or firmware
+ error.
+ @retval EFI_INVALID_PARAMETER One or more of the parameters are incorrect.
+ @retval EFI_BUFFER_TOO_SMALL The buffer RNGAlgorithmList is too small to
+ hold the result.
+
+**/
+STATIC
+EFI_STATUS
+EFIAPI
+AtSha240aGetInfo (
+ IN EFI_RNG_PROTOCOL *This,
+ IN OUT UINTN *AlgorithmListSize,
+ OUT EFI_RNG_ALGORITHM *AlgorithmList
+)
+{
+ UINTN Size;
+
+ //
+ // We only implement the raw algorithm
+ //
+ Size = sizeof (EFI_GUID);
+
+ if (*AlgorithmListSize < Size) {
+ *AlgorithmListSize = Size;
+ return EFI_BUFFER_TOO_SMALL;
+ }
+
+ CopyGuid (AlgorithmList, &gEfiRngAlgorithmRaw);
+ *AlgorithmListSize = Size;
+
+ return EFI_SUCCESS;
+}
+
+
+/**
+ Produces and returns an RNG value using either the default or specified RNG
+ algorithm.
+
+ @param[in] This A pointer to the EFI_RNG_PROTOCOL instance.
+ @param[in] Algorithm A pointer to the EFI_RNG_ALGORITHM that
+ identifies the RNG algorithm to use. May be
+ NULL in which case the function will use its
+ default RNG algorithm.
+ @param[in] ValueLength The length in bytes of the memory buffer
+ pointed to by RNGValue. The driver shall
+ return exactly this numbers of bytes.
+ @param[out] Value A caller-allocated memory buffer filled by the
+ driver with the resulting RNG value.
+
+ @retval EFI_SUCCESS The RNG value was returned successfully.
+ @retval EFI_UNSUPPORTED The algorithm specified by RNGAlgorithm is not
+ supported by this driver.
+ @retval EFI_DEVICE_ERROR An RNG value could not be retrieved due to a
+ hardware or firmware error.
+ @retval EFI_NOT_READY There is not enough random data available to
+ satisfy the length requested by
+ RNGValueLength.
+ @retval EFI_INVALID_PARAMETER RNGValue is NULL or RNGValueLength is zero.
+
+**/
+STATIC
+EFI_STATUS
+EFIAPI
+AtSha240aGetRNG (
+ IN EFI_RNG_PROTOCOL *This,
+ IN EFI_RNG_ALGORITHM *Algorithm OPTIONAL,
+ IN UINTN ValueLength,
+ OUT UINT8 *Value
+)
+{
+ EFI_STATUS Status;
+ ATSHA204A_DEV *AtSha204a;
+ ATSHA204A_I2C_RNG_COMMAND Command;
+ ATSHA204A_I2C_RNG_RESULT Result;
+ I2C_RNG_REQUEST Request;
+ I2C_RNG_REQUEST Response;
+ UINTN Retries;
+
+ if (Algorithm != NULL && !CompareGuid (Algorithm, &gEfiRngAlgorithmRaw)) {
+ return EFI_UNSUPPORTED;
+ }
+
+ AtSha204a = ATSHA204A_DEV_FROM_THIS (This);
+
+ Request.OperationCount = 1;
+ Request.Operation.Flags = 0;
+
+ Command.Command = ATSHA204A_COMMAND;
+ Command.Count = sizeof (Command) - 1;
+ Command.Opcode = ATSHA204A_OPCODE_RANDOM;
+ Command.Param1 = 0;
+ Command.Param2 = 0;
+ Command.Crc = OPCODE_COMMAND_PACKET_CRC;
+
+ Response.OperationCount = 1;
+ Response.Operation.Flags = I2C_FLAG_READ;
+ Response.Operation.LengthInBytes = sizeof (Result);
+ Response.Operation.Buffer = (VOID *)&Result;
+
+ Retries = 0;
+ while (ValueLength > 0) {
+ //
+ // The AtSha204a will go back to sleep right in the middle of a transaction
+ // if it does not complete in ~1.3 seconds. So send the wake sequence for
+ // each iteration, which consists of a dummy write to slave address 0x0.
+ //
+ Request.Operation.LengthInBytes = 0;
+ Status = AtSha204a->I2cIo->QueueRequest (AtSha204a->I2cIo, 1, NULL,
+ (VOID *)&Request, NULL);
+ DEBUG ((DEBUG_INFO, "%a: wake AtSha204a: I2cIo->QueueRequest() - %r\n",
+ __FUNCTION__, Status));
+
+ gBS->Stall (2500); // wait 2.5 ms for wake to complete
+
+ Request.Operation.LengthInBytes = sizeof (Command);
+ Request.Operation.Buffer = (VOID *)&Command;
+ Status = AtSha204a->I2cIo->QueueRequest (AtSha204a->I2cIo, 0, NULL,
+ (VOID *)&Request, NULL);
+ if (EFI_ERROR (Status)) {
+ if (++Retries <= MAX_RETRIES) {
+ continue;
+ }
+ DEBUG ((DEBUG_ERROR, "%a: I2C request transfer failed, Status == %r\n",
+ __FUNCTION__, Status));
+ return EFI_DEVICE_ERROR;
+ }
+
+ gBS->Stall (50 * 1000); // 50 ms max execution time for RANDOM opcode
+
+ Status = AtSha204a->I2cIo->QueueRequest (AtSha204a->I2cIo, 0, NULL,
+ (VOID *)&Response, NULL);
+ if (EFI_ERROR (Status)) {
+ if (++Retries <= MAX_RETRIES) {
+ continue;
+ }
+ DEBUG ((DEBUG_ERROR, "%a: I2C response transfer failed, Status == %r\n",
+ __FUNCTION__, Status));
+ return EFI_DEVICE_ERROR;
+ }
+
+ if (Result.Count < sizeof (Result)) {
+ //
+ // Incomplete packet received, most likely due to an error. Retry.
+ //
+ if (++Retries <= MAX_RETRIES) {
+ continue;
+ }
+ DEBUG ((DEBUG_WARN, "%a: incomplete packet received\n", __FUNCTION__));
+ return EFI_DEVICE_ERROR;
+ }
+
+ gBS->CopyMem (Value, Result.Result, MIN (ValueLength,
+ ATSHA204A_OUTPUT_SIZE));
+ if (ValueLength < ATSHA204A_OUTPUT_SIZE) {
+ break;
+ }
+
+ Value += ATSHA204A_OUTPUT_SIZE;
+ ValueLength -= ATSHA204A_OUTPUT_SIZE;
+ Retries = 0;
+ }
+ return EFI_SUCCESS;
+}
+
+EFI_STATUS
+AtSha204aInit (
+ IN EFI_HANDLE DriverBindingHandle,
+ IN EFI_HANDLE ControllerHandle
+ )
+{
+ EFI_STATUS Status;
+ ATSHA204A_DEV *AtSha204a;
+
+ Status = gBS->AllocatePool (EfiBootServicesData, sizeof (ATSHA204A_DEV),
+ (VOID **) &AtSha204a);
+ if (EFI_ERROR (Status)) {
+ return EFI_OUT_OF_RESOURCES;
+ }
+
+ AtSha204a->Signature = ATSHA204A_DEV_SIGNATURE;
+ AtSha204a->Rng.GetInfo = AtSha240aGetInfo;
+ AtSha204a->Rng.GetRNG = AtSha240aGetRNG;
+
+ //
+ // Open I2C I/O Protocol
+ //
+ Status = gBS->OpenProtocol (ControllerHandle,
+ &gEfiI2cIoProtocolGuid,
+ (VOID **)&AtSha204a->I2cIo,
+ DriverBindingHandle,
+ ControllerHandle,
+ EFI_OPEN_PROTOCOL_BY_DRIVER);
+ if (EFI_ERROR (Status)) {
+ goto ErrorFreeDev;
+ }
+
+ Status = gBS->InstallProtocolInterface (&ControllerHandle,
+ &gEfiRngProtocolGuid,
+ EFI_NATIVE_INTERFACE,
+ &AtSha204a->Rng);
+ if (EFI_ERROR (Status)) {
+ DEBUG ((DEBUG_ERROR,
+ "Failed to install RNG protocol interface (Status == %r)\n",
+ Status));
+ goto ErrorCloseProtocol;
+ }
+
+ return EFI_SUCCESS;
+
+ErrorCloseProtocol:
+ gBS->CloseProtocol (ControllerHandle, &gEfiI2cIoProtocolGuid,
+ DriverBindingHandle, ControllerHandle);
+
+ErrorFreeDev:
+ gBS->FreePool (AtSha204a);
+
+ return Status;
+}
+
+EFI_STATUS
+AtSha204aRelease (
+ IN EFI_HANDLE DriverBindingHandle,
+ IN EFI_HANDLE ControllerHandle
+ )
+{
+ EFI_RNG_PROTOCOL *Rng;
+ ATSHA204A_DEV *AtSha204a;
+ EFI_STATUS Status;
+
+ Status = gBS->HandleProtocol (ControllerHandle,
+ &gEfiRngProtocolGuid,
+ (VOID **)&Rng);
+ ASSERT_EFI_ERROR (Status);
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ AtSha204a = ATSHA204A_DEV_FROM_THIS (Rng);
+
+ Status = gBS->UninstallProtocolInterface (ControllerHandle,
+ &gEfiRngProtocolGuid,
+ Rng);
+ ASSERT_EFI_ERROR (Status);
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ Status = gBS->CloseProtocol (ControllerHandle,
+ &gEfiI2cIoProtocolGuid,
+ DriverBindingHandle,
+ ControllerHandle);
+ ASSERT_EFI_ERROR (Status);
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ gBS->FreePool (AtSha204a);
+
+ return EFI_SUCCESS;
+}
diff --git a/Silicon/Atmel/AtSha204a/AtSha204aDriver.h b/Silicon/Atmel/AtSha204a/AtSha204aDriver.h
new file mode 100644
index 0000000000..315a450d34
--- /dev/null
+++ b/Silicon/Atmel/AtSha204a/AtSha204aDriver.h
@@ -0,0 +1,81 @@
+/** @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.
+
+**/
+
+#ifndef _ATSHA204A_I2C_HWRNG_DRIVER_H_
+#define _ATSHA204A_I2C_HWRNG_DRIVER_H_
+
+#include <Uefi.h>
+#include <Library/BaseMemoryLib.h>
+#include <Library/DebugLib.h>
+#include <Library/UefiBootServicesTableLib.h>
+#include <Library/UefiLib.h>
+
+#include <Protocol/Rng.h>
+#include <Protocol/I2cIo.h>
+
+#define ATSHA204A_OUTPUT_SIZE 32
+
+#define ATSHA204A_DEV_SIGNATURE SIGNATURE_32('a','t','s','h')
+
+typedef struct {
+ UINT32 Signature;
+ EFI_I2C_IO_PROTOCOL *I2cIo;
+ EFI_RNG_PROTOCOL Rng;
+} ATSHA204A_DEV;
+
+#define ATSHA204A_DEV_FROM_THIS(a) \
+ CR(a, ATSHA204A_DEV, Rng, ATSHA204A_DEV_SIGNATURE)
+
+#pragma pack(1)
+typedef struct {
+ UINT8 Command;
+ UINT8 Count;
+ UINT8 Opcode;
+ UINT8 Param1;
+ UINT16 Param2;
+ UINT16 Crc;
+} ATSHA204A_I2C_RNG_COMMAND;
+
+typedef struct {
+ UINT8 Count;
+ UINT8 Result[ATSHA204A_OUTPUT_SIZE];
+ UINT16 Crc;
+} ATSHA204A_I2C_RNG_RESULT;
+#pragma pack()
+
+typedef struct {
+ UINTN OperationCount;
+ EFI_I2C_OPERATION Operation;
+} I2C_RNG_REQUEST;
+
+#define ATSHA204A_COMMAND 0x3
+
+#define ATSHA204A_OPCODE_RANDOM 0x1b
+
+extern EFI_COMPONENT_NAME2_PROTOCOL gAtSha204aDriverComponentName2;
+
+EFI_STATUS
+AtSha204aInit (
+ IN EFI_HANDLE DriverBindingHandle,
+ IN EFI_HANDLE ControllerHandle
+ );
+
+EFI_STATUS
+AtSha204aRelease (
+ IN EFI_HANDLE DriverBindingHandle,
+ IN EFI_HANDLE ControllerHandle
+ );
+
+#endif // _ATSHA204A_I2C_HWRNG_DRIVER_H_
diff --git a/Silicon/Atmel/AtSha204a/AtSha204aDxe.inf b/Silicon/Atmel/AtSha204a/AtSha204aDxe.inf
new file mode 100644
index 0000000000..fe90cc5381
--- /dev/null
+++ b/Silicon/Atmel/AtSha204a/AtSha204aDxe.inf
@@ -0,0 +1,52 @@
+## @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.
+#
+##
+
+[Defines]
+ INF_VERSION = 0x0001001A
+ BASE_NAME = AtSha204aDxe
+ FILE_GUID = 8b8f683b-f376-4ba0-b8d7-b4bbd30319cc
+ MODULE_TYPE = UEFI_DRIVER
+ VERSION_STRING = 1.0
+ ENTRY_POINT = EntryPoint
+ UNLOAD_IMAGE = UnloadImage
+
+#
+# VALID_ARCHITECTURES = AARCH64 ARM EBC IA32 IPF X64
+#
+
+[Sources]
+ AtSha204aDriver.c
+ AtSha204aDriver.h
+ ComponentName.c
+ DriverBinding.c
+
+[Packages]
+ MdePkg/MdePkg.dec
+ Silicon/Atmel/AtSha204a/AtSha204a.dec
+
+[LibraryClasses]
+ BaseMemoryLib
+ DebugLib
+ UefiBootServicesTableLib
+ UefiDriverEntryPoint
+ UefiLib
+
+[Protocols]
+ gEfiRngProtocolGuid # PROTOCOL BY_START
+ gEfiI2cIoProtocolGuid # PROTOCOL TO_START
+
+[Guids]
+ gAtSha204aI2cDeviceGuid
+ gEfiRngAlgorithmRaw
diff --git a/Silicon/Atmel/AtSha204a/ComponentName.c b/Silicon/Atmel/AtSha204a/ComponentName.c
new file mode 100644
index 0000000000..9893e7c4c2
--- /dev/null
+++ b/Silicon/Atmel/AtSha204a/ComponentName.c
@@ -0,0 +1,186 @@
+/** @file
+ UEFI Component Name(2) protocol implementation for AtSha204a driver.
+
+ Copyright (c) 2018, Linaro Ltd. All rights reserved.
+
+ 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 "AtSha204aDriver.h"
+
+STATIC EFI_UNICODE_STRING_TABLE mAtSha204aDriverNameTable[] = {
+ {
+ "en",
+ (CHAR16 *)L"AtSha204a RNG I2C driver"
+ },
+ { }
+};
+
+STATIC EFI_UNICODE_STRING_TABLE mAtSha204aControllerNameTable[] = {
+ {
+ "en",
+ (CHAR16 *)L"AtSha204a Random Number Generator (I2C)"
+ },
+ { }
+};
+
+/**
+ Retrieves a Unicode string that is the user readable name of the driver.
+
+ This function retrieves the user readable name of a driver in the form of a
+ Unicode string. If the driver specified by This has a user readable name in
+ the language specified by Language, then a pointer to the driver name is
+ returned in DriverName, and EFI_SUCCESS is returned. If the driver specified
+ by This does not support the language specified by Language,
+ then EFI_UNSUPPORTED is returned.
+
+ @param This[in] A pointer to the EFI_COMPONENT_NAME2_PROTOCOL or
+ EFI_COMPONENT_NAME_PROTOCOL instance.
+
+ @param Language[in] A pointer to a Null-terminated ASCII string
+ array indicating the language. This is the
+ language of the driver name that the caller is
+ requesting, and it must match one of the
+ languages specified in SupportedLanguages. The
+ number of languages supported by a driver is up
+ to the driver writer. Language is specified
+ in RFC 4646 or ISO 639-2 language code format.
+
+ @param DriverName[out] A pointer to the Unicode string to return.
+ This Unicode string is the name of the
+ driver specified by This in the language
+ specified by Language.
+
+ @retval EFI_SUCCESS The Unicode string for the Driver specified by
+ This and the language specified by Language was
+ returned in DriverName.
+
+ @retval EFI_INVALID_PARAMETER Language is NULL.
+
+ @retval EFI_INVALID_PARAMETER DriverName is NULL.
+
+ @retval EFI_UNSUPPORTED The driver specified by This does not support
+ the language specified by Language.
+
+**/
+STATIC
+EFI_STATUS
+EFIAPI
+AtSha204aGetDriverName (
+ IN EFI_COMPONENT_NAME2_PROTOCOL *This,
+ IN CHAR8 *Language,
+ OUT CHAR16 **DriverName
+ )
+{
+ return LookupUnicodeString2 (Language,
+ This->SupportedLanguages,
+ mAtSha204aDriverNameTable,
+ DriverName,
+ FALSE);
+}
+
+/**
+ Retrieves a Unicode string that is the user readable name of the controller
+ that is being managed by a driver.
+
+ This function retrieves the user readable name of the controller specified by
+ ControllerHandle and ChildHandle in the form of a Unicode string. If the
+ driver specified by This has a user readable name in the language specified by
+ Language, then a pointer to the controller name is returned in ControllerName,
+ and EFI_SUCCESS is returned. If the driver specified by This is not currently
+ managing the controller specified by ControllerHandle and ChildHandle,
+ then EFI_UNSUPPORTED is returned. If the driver specified by This does not
+ support the language specified by Language, then EFI_UNSUPPORTED is returned.
+
+ @param This[in] A pointer to the EFI_COMPONENT_NAME2_PROTOCOL or
+ EFI_COMPONENT_NAME_PROTOCOL instance.
+
+ @param ControllerHandle[in] The handle of a controller that the driver
+ specified by This is managing. This handle
+ specifies the controller whose name is to be
+ returned.
+
+ @param ChildHandle[in] The handle of the child controller to retrieve
+ the name of. This is an optional parameter that
+ may be NULL. It will be NULL for device
+ drivers. It will also be NULL for a bus drivers
+ that wish to retrieve the name of the bus
+ controller. It will not be NULL for a bus
+ driver that wishes to retrieve the name of a
+ child controller.
+
+ @param Language[in] A pointer to a Null-terminated ASCII string
+ array indicating the language. This is the
+ language of the driver name that the caller is
+ requesting, and it must match one of the
+ languages specified in SupportedLanguages. The
+ number of languages supported by a driver is up
+ to the driver writer. Language is specified in
+ RFC 4646 or ISO 639-2 language code format.
+
+ @param ControllerName[out] A pointer to the Unicode string to return.
+ This Unicode string is the name of the
+ controller specified by ControllerHandle and
+ ChildHandle in the language specified by
+ Language from the point of view of the driver
+ specified by This.
+
+ @retval EFI_SUCCESS The Unicode string for the user readable name in
+ the language specified by Language for the
+ driver specified by This was returned in
+ DriverName.
+
+ @retval EFI_INVALID_PARAMETER ControllerHandle is NULL.
+
+ @retval EFI_INVALID_PARAMETER ChildHandle is not NULL and it is not a valid
+ EFI_HANDLE.
+
+ @retval EFI_INVALID_PARAMETER Language is NULL.
+
+ @retval EFI_INVALID_PARAMETER ControllerName is NULL.
+
+ @retval EFI_UNSUPPORTED The driver specified by This is not currently
+ managing the controller specified by
+ ControllerHandle and ChildHandle.
+
+ @retval EFI_UNSUPPORTED The driver specified by This does not support
+ the language specified by Language.
+
+**/
+STATIC
+EFI_STATUS
+EFIAPI
+AtSha204aGetControllerName (
+ IN EFI_COMPONENT_NAME2_PROTOCOL *This,
+ IN EFI_HANDLE ControllerHandle,
+ IN EFI_HANDLE ChildHandle OPTIONAL,
+ IN CHAR8 *Language,
+ OUT CHAR16 **ControllerName
+ )
+{
+ if (ChildHandle != NULL) {
+ return EFI_UNSUPPORTED;
+ }
+
+ return LookupUnicodeString2 (Language,
+ This->SupportedLanguages,
+ mAtSha204aControllerNameTable,
+ ControllerName,
+ FALSE);
+}
+
+//
+// EFI Component Name 2 Protocol
+//
+EFI_COMPONENT_NAME2_PROTOCOL gAtSha204aDriverComponentName2 = {
+ AtSha204aGetDriverName,
+ AtSha204aGetControllerName,
+ "en"
+};
diff --git a/Silicon/Atmel/AtSha204a/DriverBinding.c b/Silicon/Atmel/AtSha204a/DriverBinding.c
new file mode 100644
index 0000000000..17e61f96e8
--- /dev/null
+++ b/Silicon/Atmel/AtSha204a/DriverBinding.c
@@ -0,0 +1,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;
+}