From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received-SPF: Pass (sender SPF authorized) identity=mailfrom; client-ip=2607:f8b0:4001:c0b::235; helo=mail-it0-x235.google.com; envelope-from=ard.biesheuvel@linaro.org; receiver=edk2-devel@lists.01.org Received: from mail-it0-x235.google.com (mail-it0-x235.google.com [IPv6:2607:f8b0:4001:c0b::235]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by ml01.01.org (Postfix) with ESMTPS id 91CF220954CDD for ; Mon, 19 Feb 2018 10:13:58 -0800 (PST) Received: by mail-it0-x235.google.com with SMTP id p204so10004176itc.4 for ; Mon, 19 Feb 2018 10:19:55 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; h=mime-version:in-reply-to:references:from:date:message-id:subject:to :cc; bh=OI9r+vOELuavweLlN0nGB/zn8jeGz/w/8Htm9Eg62FQ=; b=J7TiI1cxv6WrLCInqUxodpFeM+d52LSIG8xfPSgac6PemRiWZ7Gfk9XBcvhQ9h0hac dC08wATIeGgwKqYs01XZuQYMnLtRVu1NMhWKymAQfnk6xM82X2kNlNOJdUdthuMy4Dnm kgED3cZVCeuTUjOj5/tEx266FHDuMCszHJNQQ= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:mime-version:in-reply-to:references:from:date :message-id:subject:to:cc; bh=OI9r+vOELuavweLlN0nGB/zn8jeGz/w/8Htm9Eg62FQ=; b=C3NaeOnbTfTfWtxBZb6fJYts0FalHPr0ZFSuBAKkgOCSwcDaUee21jmhWfmxQgbFPW JFgCM/XwZ3JcqomYBSMxsyuPJtLU7Xutn/HmGqEM5qJ3i9tV1wr1IFflS18X+JqyPi0N zVuWOgSk0Ih8Eq9Lq+BNMLdbDH9ZDm89bRvV2Fim4VXN1EZE2L2bFpzBrlvkoB49Pxfl nxZapzr/daA7hU59G/KNEUhtQjpyL//lb3f8MTBCL3sH/BqcXmPQpvAaFK+Nxtruulik gFnHEwIYsPpdWbfC+wAP1GOig8+eUPTj/w2eXUnlsliH2Yp0WeHEiKhjvrII42V6xMgE oU+A== X-Gm-Message-State: APf1xPAZOZqW6adw8+lhFD5/suhuseBmxmLUHiqH2kbG7psm105z/p6S x9GCa/JbEIBR9zCXbGzwX7WEN9R9wbKeriiPRIXjZw== X-Google-Smtp-Source: AH8x224RbC6ceP0bK7XWFOT0rjsjDegq00p4zA8c5l644BPYchgxyUFTGQJ9OWQSroOoAAMYgE4/yBehzd9Gggbdt+k= X-Received: by 10.36.252.65 with SMTP id b62mr9096754ith.50.1519064393958; Mon, 19 Feb 2018 10:19:53 -0800 (PST) MIME-Version: 1.0 Received: by 10.107.138.209 with HTTP; Mon, 19 Feb 2018 10:19:53 -0800 (PST) In-Reply-To: <20180219172848.gl33dx5aafy3hcp6@bivouac.eciton.net> References: <20180219094332.19853-1-ard.biesheuvel@linaro.org> <20180219172848.gl33dx5aafy3hcp6@bivouac.eciton.net> From: Ard Biesheuvel Date: Mon, 19 Feb 2018 18:19:53 +0000 Message-ID: To: Leif Lindholm Cc: "edk2-devel@lists.01.org" , Joakim Bech Subject: Re: [PATCH] Silicon/Atmel: add support for AtSha204a RNG X-BeenThere: edk2-devel@lists.01.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: EDK II Development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Mon, 19 Feb 2018 18:13:59 -0000 Content-Type: text/plain; charset="UTF-8" On 19 February 2018 at 17:28, Leif Lindholm wrote: > On Mon, Feb 19, 2018 at 09:43:32AM +0000, Ard Biesheuvel wrote: >> This adds support for using the random number generator in the Atmel >> AtSha204a over I2C. Other functionality of the chip is currently >> unsupported. >> >> Note that the the I2C support in this device essentially violates the >> protocol layering, by requiring that the device is woken up by driving >> SDA low for a certain amount of time, which is something that cannot be >> expressed in terms of an I2C packet sent to the device's slave address. >> Instead, the slave address 0x0 is added to the device's address array, >> and the wake is sent by sending a dummy write to address 0x0, and >> ignoring the subsequent error. This requires the I2C bus to be clocked >> at 100 kHz. > > As long as the violation is down to the component rather than its > integration onto the mezzanine board, I see no problem with this. > OK >> Contributed-under: TianoCore Contribution Agreement 1.1 >> Signed-off-by: Ard Biesheuvel >> --- >> Silicon/Atmel/AtSha204a/AtSha204a.dec | 22 ++ >> Silicon/Atmel/AtSha204a/AtSha204aDriver.c | 308 ++++++++++++++++++++ >> Silicon/Atmel/AtSha204a/AtSha204aDriver.h | 81 +++++ >> Silicon/Atmel/AtSha204a/AtSha204aDxe.inf | 52 ++++ >> Silicon/Atmel/AtSha204a/ComponentName.c | 186 ++++++++++++ >> Silicon/Atmel/AtSha204a/DriverBinding.c | 242 +++++++++++++++ >> 6 files changed, 891 insertions(+) >> >> diff --git a/Silicon/Atmel/AtSha204a/AtSha204a.dec b/Silicon/Atmel/AtSha204a/AtSha204a.dec >> new file mode 100644 >> index 000000000000..f1fdea59843d >> --- /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 000000000000..25329086592a >> --- /dev/null >> +++ b/Silicon/Atmel/AtSha204a/AtSha204aDriver.c >> @@ -0,0 +1,308 @@ >> +/** @file >> + Device driver for the Atmel ATSHA204A random number generator. >> + >> + 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" >> + >> +#include >> +#include >> +#include >> + >> +#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 gEfiRngAlgorithmRaw; > > Use parantheses for sizeof? OK > Also, can this be different from sizeof (EFI_GUID)? > Nope >> + >> + if (*AlgorithmListSize < Size) { >> + *AlgorithmListSize = Size; >> + return EFI_BUFFER_TOO_SMALL; >> + } >> + >> + gBS->CopyMem (AlgorithmList, &gEfiRngAlgorithmRaw, Size); > > You already pull in BaseMemoryLib, so could use CopyGuid? > OK >> + *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 Cmd; >> + ATSHA204A_I2C_RNG_RESULT Res; >> + I2C_RNG_REQUEST Req; >> + I2C_RNG_REQUEST Resp; > > Since I just gave Marcin a hard time over non-approved abbreviations, > I should probably flag these too... Would you mind terribly turning > them into Command, Result, Request, Response? > No that is fine. >> + UINTN Retries; >> + >> + if (Algorithm != NULL && !CompareGuid (Algorithm, &gEfiRngAlgorithmRaw)) { >> + return EFI_UNSUPPORTED; >> + } >> + >> + AtSha204a = ATSHA204A_DEV_FROM_THIS (This); >> + >> + Req.OperationCount = 1; >> + Req.Operation.Flags = 0; >> + >> + Cmd.Command = ATSHA204A_COMMAND; >> + Cmd.Count = sizeof (Cmd) - 1; >> + Cmd.Opcode = ATSHA204A_OPCODE_RANDOM; >> + Cmd.Param1 = 0; >> + Cmd.Param2 = 0; >> + Cmd.Crc = OPCODE_COMMAND_PACKET_CRC; >> + >> + Resp.OperationCount = 1; >> + Resp.Operation.Flags = I2C_FLAG_READ; >> + Resp.Operation.LengthInBytes = sizeof (Res); >> + Resp.Operation.Buffer = (VOID *)&Res; >> + >> + 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. >> + // >> + Req.Operation.LengthInBytes = 0; >> + Status = AtSha204a->I2cIo->QueueRequest (AtSha204a->I2cIo, 1, NULL, >> + (VOID *)&Req, NULL); >> + DEBUG ((DEBUG_INFO, "%a: wake AtSha204a: I2cIo->QueueRequest() - %r\n", >> + __FUNCTION__, Status)); >> + >> + gBS->Stall (2500); // wait 2.5 ms for wake to complete >> + >> + Req.Operation.LengthInBytes = sizeof (Cmd); >> + Req.Operation.Buffer = (VOID *)&Cmd; >> + Status = AtSha204a->I2cIo->QueueRequest (AtSha204a->I2cIo, 0, NULL, >> + (VOID *)&Req, 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 > > Is there no way of polling for response complete? > 50ms per iteration?? :( (or, well, 52.5 in total) > Typical execution time is 11 ms, but it is rare for this routine to iterate more than once in the first place, so I tried to keep it simple. (The typical use case of a raw RNG is to seed a DRBG, which typically takes 32 bytes of seed, which is exactly the output size of a single invocation) I don't mind changing it, though, if you feel strongly about this. -- Ard. >> + >> + Status = AtSha204a->I2cIo->QueueRequest (AtSha204a->I2cIo, 0, NULL, >> + (VOID *)&Resp, 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 (Res.Count < sizeof (Res)) { >> + // >> + // 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, Res.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 000000000000..315a450d34f2 >> --- /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.
>> + >> + 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 >> +#include >> +#include >> +#include >> +#include >> + >> +#include >> +#include >> + >> +#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 000000000000..fe90cc538114 >> --- /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.
>> +# >> +# 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 000000000000..9893e7c4c2bf >> --- /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 000000000000..17e61f96e8c5 >> --- /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.
>> + >> + 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 >> + >> +#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; >> +} >> -- >> 2.11.0 >>