From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received-SPF: Pass (sender SPF authorized) identity=mailfrom; client-ip=2a00:1450:400c:c09::22a; helo=mail-wm0-x22a.google.com; envelope-from=leif.lindholm@linaro.org; receiver=edk2-devel@lists.01.org Received: from mail-wm0-x22a.google.com (mail-wm0-x22a.google.com [IPv6:2a00:1450:400c:c09::22a]) (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 1DC9A20954CD3 for ; Mon, 19 Feb 2018 09:22:56 -0800 (PST) Received: by mail-wm0-x22a.google.com with SMTP id x21so16448917wmh.0 for ; Mon, 19 Feb 2018 09:28:54 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; h=date:from:to:cc:subject:message-id:references:mime-version :content-disposition:in-reply-to:user-agent; bh=W4XPhWKY5RrZYemTl8vkVPNwnLNdq8Bb0V12y2UD5QE=; b=DYHqjOlz89BKcldiGZ9yHF8fKgmGD6JmkpnsGcV5X7VHJr/b+h1HhUYIcAj83gbq4L ASnjVbaPwMuc6NrSuqWnZapfzsjlBeSQcu87J4OQF3eSXdNunCVWRUKdB4Hrd804GhNy oa4vR9hE3IKUFHBNb8Cc9fzucqeuVeceU8ezQ= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:date:from:to:cc:subject:message-id:references :mime-version:content-disposition:in-reply-to:user-agent; bh=W4XPhWKY5RrZYemTl8vkVPNwnLNdq8Bb0V12y2UD5QE=; b=fUOZh96h92ut7a0G85wvImB/Azpl0gjSRzcOBTZr+WU0CogBfNZIDQrQRnpRPFJ1u8 sMtneWNCh9SbWHUoApqqgMi7y1q8UQM2GdP+IU4UwTjQ2zsZI8Bs4hHobUXiN/ybC/WK VPlOpu5/N2S3fYSyVDWRLNv9YMfidRE5MMIqTfVaMRGruYv7dAF/663F+pY5UR06EzJK YPrqp6EcAaD3seYdBt55xvd2xwzVpTQ8yTl2/UrnmybcwnK38Dhx1xRI0QFbXNXfHU2v +ciSDYzJaMIWd9b/tkv8P8HZUbfqf160HCz/h9KTigvsabX3TBeHHKRu6Vk5zHZ1bwHn J8gw== X-Gm-Message-State: APf1xPAj1RCiMQTmQf86ImmdSohEz3zeNFvJYh0xKdUFgywTNsedOjpH b5CQCl/WGRxKVLaiqXNO7lEETQ== X-Google-Smtp-Source: AH8x2253Wt0U/nN/6vEYnoPCbTPxQjTX2rCpuKiRUi9P5KwqJC5setBZUL7idQbJHZsOHNrPTGBkyA== X-Received: by 10.28.87.20 with SMTP id l20mr11083259wmb.48.1519061331719; Mon, 19 Feb 2018 09:28:51 -0800 (PST) Received: from bivouac.eciton.net (bivouac.eciton.net. [2a00:1098:0:86:1000:23:0:2]) by smtp.gmail.com with ESMTPSA id q1sm23756070wrf.40.2018.02.19.09.28.50 (version=TLS1_2 cipher=ECDHE-RSA-CHACHA20-POLY1305 bits=256/256); Mon, 19 Feb 2018 09:28:50 -0800 (PST) Date: Mon, 19 Feb 2018 17:28:48 +0000 From: Leif Lindholm To: Ard Biesheuvel Cc: edk2-devel@lists.01.org, joakim.bech@linaro.org Message-ID: <20180219172848.gl33dx5aafy3hcp6@bivouac.eciton.net> References: <20180219094332.19853-1-ard.biesheuvel@linaro.org> MIME-Version: 1.0 In-Reply-To: <20180219094332.19853-1-ard.biesheuvel@linaro.org> User-Agent: NeoMutt/20170113 (1.7.2) 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 17:22:58 -0000 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline 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. > 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? Also, can this be different from sizeof (EFI_GUID)? > + > + if (*AlgorithmListSize < Size) { > + *AlgorithmListSize = Size; > + return EFI_BUFFER_TOO_SMALL; > + } > + > + gBS->CopyMem (AlgorithmList, &gEfiRngAlgorithmRaw, Size); You already pull in BaseMemoryLib, so could use CopyGuid? > + *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? > + 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) / Leif > + > + 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 >