From nobody Wed May 1 13:20:12 2024 Delivered-To: importer@patchew.org Authentication-Results: mx.zohomail.com; dkim=fail; spf=none (zoho.com: 198.145.21.10 is neither permitted nor denied by domain of lists.01.org) smtp.mailfrom=edk2-devel-bounces@lists.01.org; dmarc=fail(p=none dis=none) header.from=linaro.org Return-Path: Received: from ml01.01.org (ml01.01.org [198.145.21.10]) by mx.zohomail.com with SMTPS id 1519033430120106.65958104235949; Mon, 19 Feb 2018 01:43:50 -0800 (PST) Received: from [127.0.0.1] (localhost [IPv6:::1]) by ml01.01.org (Postfix) with ESMTP id 4CB44223230DF; Mon, 19 Feb 2018 01:37:51 -0800 (PST) Received: from mail-wr0-x22f.google.com (mail-wr0-x22f.google.com [IPv6:2a00:1450:400c:c0c::22f]) (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 602E3223230C7 for ; Mon, 19 Feb 2018 01:37:49 -0800 (PST) Received: by mail-wr0-x22f.google.com with SMTP id s5so8935237wra.0 for ; Mon, 19 Feb 2018 01:43:46 -0800 (PST) Received: from localhost.localdomain ([154.145.114.50]) by smtp.gmail.com with ESMTPSA id d17sm19853399wre.76.2018.02.19.01.43.41 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Mon, 19 Feb 2018 01:43:42 -0800 (PST) X-Original-To: edk2-devel@lists.01.org Received-SPF: none (zoho.com: 198.145.21.10 is neither permitted nor denied by domain of lists.01.org) client-ip=198.145.21.10; envelope-from=edk2-devel-bounces@lists.01.org; helo=ml01.01.org; Received-SPF: Pass (sender SPF authorized) identity=mailfrom; client-ip=2a00:1450:400c:c0c::22f; helo=mail-wr0-x22f.google.com; envelope-from=ard.biesheuvel@linaro.org; receiver=edk2-devel@lists.01.org DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; h=from:to:cc:subject:date:message-id; bh=TKeCzu2Z7OURrjyWFiNDgblTdvd6FKKLIheby2TBfok=; b=MHrDLlvWHPXnNXFdvWkqXwnRqyQyMErwxO4vMZsfAqmSi0zKJ8aMsVGYKGOpVqNcKT XkgaxkqDWBXUCxwnxhnSdWlUD4mLcfuMC9EOOqWByCg24/5ME6KMZ08zWkYxkPToF09H MMN0wzIJz2Z5CIJObnl+QiIpkCwYgySW9EpLA= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id; bh=TKeCzu2Z7OURrjyWFiNDgblTdvd6FKKLIheby2TBfok=; b=s6y0+x+pyqz/SVzFwAt33l22ucrMdi02AUHNl2C/xRjtev66nOB1PuW4r0Y3pQEa8b gkamFp2c8dHFTOTs5SYPpDas8f02epihY/KY/83EO1R0tsVuZQYidNnbCImswR3LdhN1 du3ScFbBBJQHuXXgCu0VSRnEMYw6Coe2SAK6qQWvAeMyYbL24o0GY/zsd5397baQPcOm dtXCtSOGTjmWQrI71+Mfef3EsWNf4HvaOX1INuPTZ4E13xxVZ5TkeAnHdhjx/mWmOy9K 1uRXGLsYu0ub5yFqPKtTttBnL1SlsxjpiU7bqUcWC87JhVjydIYHh0WP/nOWhLm4arRZ kzOg== X-Gm-Message-State: APf1xPAXKCsiFfk/FAFcZ4biOolCiPnrp2O0pyF5c4cCJDJsTc/3vFi6 JK+DGpiGJt7eSmd2J9wktKAZ+vTiF5w= X-Google-Smtp-Source: AH8x225Rs1Vlmdimk6NpPcGkAvBeaOADlVHR/GeZ+R/DoB3ip+nfe1rKdnkqZFjuWJl1fgog2NmrVg== X-Received: by 10.223.176.13 with SMTP id f13mr13224244wra.231.1519033423448; Mon, 19 Feb 2018 01:43:43 -0800 (PST) From: Ard Biesheuvel To: edk2-devel@lists.01.org Date: Mon, 19 Feb 2018 09:43:32 +0000 Message-Id: <20180219094332.19853-1-ard.biesheuvel@linaro.org> X-Mailer: git-send-email 2.11.0 Subject: [edk2] [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: , Cc: joakim.bech@linaro.org, leif.lindholm@linaro.org, Ard Biesheuvel MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Errors-To: edk2-devel-bounces@lists.01.org Sender: "edk2-devel" X-ZohoMail-DKIM: fail (Header signature does not verify) X-ZohoMail: RDKM_2 RSF_4 Z_629925259 SPT_0 Content-Type: text/plain; charset="utf-8" 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. 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/AtSha204= a/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 B= SD 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 IM= PLIED. +# +## + +[Defines] + DEC_SPECIFICATION =3D 0x0001001A + PACKAGE_NAME =3D AtSha204a + PACKAGE_GUID =3D 86085a5b-355b-4e72-92ab-fc3e1d71c9ad + PACKAGE_VERSION =3D 0.1 + +[Guids] + gAtSha204aI2cDeviceGuid =3D { 0x52e9b64b, 0x4ec1, 0x4bd6, { 0x9e, 0x1c, = 0x6d, 0xac, 0xef, 0x35, 0x18, 0x21 } } diff --git a/Silicon/Atmel/AtSha204a/AtSha204aDriver.c b/Silicon/Atmel/AtSh= a204a/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 licens= e 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 IMP= LIED. + +**/ + +#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 inst= ance. + @param[in,out] AlgorithmListSize On input, the size in bytes of Algorit= hmList + On output with a return code of EFI_SU= CCESS, + 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 l= ist. + @param[out] AlgorithmList A caller-allocated memory buffer fille= d by + the driver with one EFI_RNG_ALGORITHM + element for each supported RNG algorit= hm. + The list must not change across multip= le + 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 inco= rrect. + @retval EFI_BUFFER_TOO_SMALL The buffer RNGAlgorithmList is too sma= ll 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 =3D sizeof gEfiRngAlgorithmRaw; + + if (*AlgorithmListSize < Size) { + *AlgorithmListSize =3D Size; + return EFI_BUFFER_TOO_SMALL; + } + + gBS->CopyMem (AlgorithmList, &gEfiRngAlgorithmRaw, Size); + *AlgorithmListSize =3D 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 instan= ce. + @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 availabl= e to + satisfy the length requested by + RNGValueLength. + @retval EFI_INVALID_PARAMETER RNGValue is NULL or RNGValueLength is ze= ro. + +**/ +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; + UINTN Retries; + + if (Algorithm !=3D NULL && !CompareGuid (Algorithm, &gEfiRngAlgorithmRaw= )) { + return EFI_UNSUPPORTED; + } + + AtSha204a =3D ATSHA204A_DEV_FROM_THIS (This); + + Req.OperationCount =3D 1; + Req.Operation.Flags =3D 0; + + Cmd.Command =3D ATSHA204A_COMMAND; + Cmd.Count =3D sizeof (Cmd) - 1; + Cmd.Opcode =3D ATSHA204A_OPCODE_RANDOM; + Cmd.Param1 =3D 0; + Cmd.Param2 =3D 0; + Cmd.Crc =3D OPCODE_COMMAND_PACKET_CRC; + + Resp.OperationCount =3D 1; + Resp.Operation.Flags =3D I2C_FLAG_READ; + Resp.Operation.LengthInBytes =3D sizeof (Res); + Resp.Operation.Buffer =3D (VOID *)&Res; + + Retries =3D 0; + while (ValueLength > 0) { + // + // The AtSha204a will go back to sleep right in the middle of a transa= ction + // 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 0x= 0. + // + Req.Operation.LengthInBytes =3D 0; + Status =3D 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 =3D sizeof (Cmd); + Req.Operation.Buffer =3D (VOID *)&Cmd; + Status =3D AtSha204a->I2cIo->QueueRequest (AtSha204a->I2cIo, 0, NULL, + (VOID *)&Req, NULL); + if (EFI_ERROR (Status)) { + if (++Retries <=3D MAX_RETRIES) { + continue; + } + DEBUG ((DEBUG_ERROR, "%a: I2C request transfer failed, Status =3D=3D= %r\n", + __FUNCTION__, Status)); + return EFI_DEVICE_ERROR; + } + + gBS->Stall (50 * 1000); // 50 ms max execution time for RANDOM opcode + + Status =3D AtSha204a->I2cIo->QueueRequest (AtSha204a->I2cIo, 0, NULL, + (VOID *)&Resp, NULL); + if (EFI_ERROR (Status)) { + if (++Retries <=3D MAX_RETRIES) { + continue; + } + DEBUG ((DEBUG_ERROR, "%a: I2C response transfer failed, Status =3D= =3D %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 <=3D 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_SI= ZE)); + if (ValueLength < ATSHA204A_OUTPUT_SIZE) { + break; + } + + Value +=3D ATSHA204A_OUTPUT_SIZE; + ValueLength -=3D ATSHA204A_OUTPUT_SIZE; + Retries =3D 0; + } + return EFI_SUCCESS; +} + +EFI_STATUS +AtSha204aInit ( + IN EFI_HANDLE DriverBindingHandle, + IN EFI_HANDLE ControllerHandle + ) +{ + EFI_STATUS Status; + ATSHA204A_DEV *AtSha204a; + + Status =3D gBS->AllocatePool (EfiBootServicesData, sizeof (ATSHA204A_DEV= ), + (VOID **) &AtSha204a); + if (EFI_ERROR (Status)) { + return EFI_OUT_OF_RESOURCES; + } + + AtSha204a->Signature =3D ATSHA204A_DEV_SIGNATURE; + AtSha204a->Rng.GetInfo =3D AtSha240aGetInfo; + AtSha204a->Rng.GetRNG =3D AtSha240aGetRNG; + + // + // Open I2C I/O Protocol + // + Status =3D gBS->OpenProtocol (ControllerHandle, + &gEfiI2cIoProtocolGuid, + (VOID **)&AtSha204a->I2cIo, + DriverBindingHandle, + ControllerHandle, + EFI_OPEN_PROTOCOL_BY_DRIVER); + if (EFI_ERROR (Status)) { + goto ErrorFreeDev; + } + + Status =3D gBS->InstallProtocolInterface (&ControllerHandle, + &gEfiRngProtocolGuid, + EFI_NATIVE_INTERFACE, + &AtSha204a->Rng); + if (EFI_ERROR (Status)) { + DEBUG ((DEBUG_ERROR, + "Failed to install RNG protocol interface (Status =3D=3D %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 =3D gBS->HandleProtocol (ControllerHandle, + &gEfiRngProtocolGuid, + (VOID **)&Rng); + ASSERT_EFI_ERROR (Status); + if (EFI_ERROR (Status)) { + return Status; + } + + AtSha204a =3D ATSHA204A_DEV_FROM_THIS (Rng); + + Status =3D gBS->UninstallProtocolInterface (ControllerHandle, + &gEfiRngProtocolGuid, + Rng); + ASSERT_EFI_ERROR (Status); + if (EFI_ERROR (Status)) { + return Status; + } + + Status =3D 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/AtSh= a204a/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 licens= e 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 IMP= LIED. + +**/ + +#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/AtSha= 204a/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 B= SD +# License which accompanies this distribution. The full text of the licen= se 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 IM= PLIED. +# +## + +[Defines] + INF_VERSION =3D 0x0001001A + BASE_NAME =3D AtSha204aDxe + FILE_GUID =3D 8b8f683b-f376-4ba0-b8d7-b4bbd30319cc + MODULE_TYPE =3D UEFI_DRIVER + VERSION_STRING =3D 1.0 + ENTRY_POINT =3D EntryPoint + UNLOAD_IMAGE =3D UnloadImage + +# +# VALID_ARCHITECTURES =3D 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/AtSha2= 04a/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 BS= D License + which accompanies this distribution. The full text of the license may b= e 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 IMP= LIED. + +**/ + +#include "AtSha204aDriver.h" + +STATIC EFI_UNICODE_STRING_TABLE mAtSha204aDriverNameTable[] =3D { + { + "en", + (CHAR16 *)L"AtSha204a RNG I2C driver" + }, + { } +}; + +STATIC EFI_UNICODE_STRING_TABLE mAtSha204aControllerNameTable[] =3D { + { + "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 o= f 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 speci= fied + 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_PROTO= COL 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 calle= r 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 for= mat. + + @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 specifie= d by + This and the language specified by Languag= e 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 supp= ort + 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 control= ler + that is being managed by a driver. + + This function retrieves the user readable name of the controller specifi= ed 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 specif= ied by + Language, then a pointer to the controller name is returned in Controlle= rName, + and EFI_SUCCESS is returned. If the driver specified by This is not cur= rently + 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 retu= rned. + + @param This[in] A pointer to the EFI_COMPONENT_NAME2_PROTO= COL 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 retr= ieve + the name of. This is an optional paramete= r that + may be NULL. It will be NULL for device + drivers. It will also be NULL for a bus d= rivers + 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 calle= r 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 specifie= d 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 a= nd + ChildHandle in the language specified by + Language from the point of view of the dri= ver + specified by This. + + @retval EFI_SUCCESS The Unicode string for the user readable n= ame 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 va= lid + 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 curren= tly + managing the controller specified by + ControllerHandle and ChildHandle. + + @retval EFI_UNSUPPORTED The driver specified by This does not supp= ort + the language specified by Language. + +**/ +STATIC +EFI_STATUS +EFIAPI +AtSha204aGetControllerName ( + IN EFI_COMPONENT_NAME2_PROTOCOL *This, + IN EFI_HANDLE ControllerHandle, + IN EFI_HANDLE ChildHandle O= PTIONAL, + IN CHAR8 *Language, + OUT CHAR16 **ControllerName + ) +{ + if (ChildHandle !=3D NULL) { + return EFI_UNSUPPORTED; + } + + return LookupUnicodeString2 (Language, + This->SupportedLanguages, + mAtSha204aControllerNameTable, + ControllerName, + FALSE); +} + +// +// EFI Component Name 2 Protocol +// +EFI_COMPONENT_NAME2_PROTOCOL gAtSha204aDriverComponentName2 =3D { + AtSha204aGetDriverName, + AtSha204aGetControllerName, + "en" +}; diff --git a/Silicon/Atmel/AtSha204a/DriverBinding.c b/Silicon/Atmel/AtSha2= 04a/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 licens= e 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 IMP= LIED. + +**/ + +#include + +#include "AtSha204aDriver.h" + +/** + Tests to see if this driver supports a given controller. + + @param This[in] A pointer to the EFI_DRIVER_BINDING_PRO= TOCOL + 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 ControllerHandl= e is + already being managed by the driver spe= cified + by This. + @retval EFI_UNSUPPORTED The device specified by ControllerHandl= e is + not supported by the driver specified b= y 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 =3D 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 =3D EFI_SUCCESS; + } else { + Status =3D 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_PRO= TOCOL + instance. + @param[in] ControllerHandle The handle of the device to start. This + handle must support a protocol interfac= e that + supplies an I/O abstraction to the driv= er. + @param[in] RemainingDevicePath The remaining portion of the device pat= h. + (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_PROTOC= OL + instance. + @param[in] ControllerHandle A handle to the device being stopped. The = handle + must support a bus specific I/O protocol f= or 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 d= evice + 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 =3D { + 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 norm= ally. + @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 =3D EfiLibInstallDriverBindingComponentName2 ( + ImageHandle, SystemTable, &gI2cHwrngDriverBinding, ImageHandl= e, + 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 =3D 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 =3D 0; Index < HandleCount; Index++) { + Status =3D gBS->DisconnectController (HandleBuffer[Index], + gImageHandle, + NULL); + } + + // + // Free the handle array + // + gBS->FreePool (HandleBuffer); + + // + // Uninstall protocols installed by the driver in its entrypoint + // + Status =3D gBS->UninstallMultipleProtocolInterfaces (ImageHandle, + &gEfiDriverBindingProtocolGuid, + &gI2cHwrngDriverBinding, + NULL + ); + + return EFI_SUCCESS; +} --=20 2.11.0 _______________________________________________ edk2-devel mailing list edk2-devel@lists.01.org https://lists.01.org/mailman/listinfo/edk2-devel