From: Ard Biesheuvel <ard.biesheuvel@linaro.org>
To: Pete Batard <pete@akeo.ie>
Cc: "edk2-devel@lists.01.org" <edk2-devel@lists.01.org>
Subject: Re: [PATCH v2 edk2-platforms 07/20] Platform/Broadcom/RPi3: Add Firmware driver
Date: Wed, 12 Dec 2018 22:17:33 +0100 [thread overview]
Message-ID: <CAKv+Gu9YmP0N-uynOJhG5ZZU07yh1q6zckhzOYgUadfpDvtyQw@mail.gmail.com> (raw)
In-Reply-To: <20181210123853.4864-8-pete@akeo.ie>
On Mon, 10 Dec 2018 at 13:39, Pete Batard <pete@akeo.ie> wrote:
>
> Contributed-under: TianoCore Contribution Agreement 1.1
> Signed-off-by: Pete Batard <pete@akeo.ie>
> ---
> Platform/Broadcom/Bcm283x/Drivers/RpiFirmwareDxe/RpiFirmwareDxe.c | 1085 ++++++++++++++++++++
> Platform/Broadcom/Bcm283x/Drivers/RpiFirmwareDxe/RpiFirmwareDxe.inf | 49 +
> Platform/Broadcom/Bcm283x/Include/Protocol/RaspberryPiFirmware.h | 131 +++
> 3 files changed, 1265 insertions(+)
>
Reviewed-by: Ard Biesheuvel <ard.biesheuvel@linaro.org>
Please move this patch forward in the series. It is depended upon by
earlier patches
> diff --git a/Platform/Broadcom/Bcm283x/Drivers/RpiFirmwareDxe/RpiFirmwareDxe.c b/Platform/Broadcom/Bcm283x/Drivers/RpiFirmwareDxe/RpiFirmwareDxe.c
> new file mode 100644
> index 000000000000..50f3ed3f1e36
> --- /dev/null
> +++ b/Platform/Broadcom/Bcm283x/Drivers/RpiFirmwareDxe/RpiFirmwareDxe.c
> @@ -0,0 +1,1085 @@
> +/** @file
> + *
> + * Copyright (c) 2017-2018, Andrei Warkentin <andrey.warkentin@gmail.com>
> + * Copyright (c) 2016, 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 <PiDxe.h>
> +
> +#include <Library/ArmLib.h>
> +#include <Library/DmaLib.h>
> +#include <Library/BaseLib.h>
> +#include <Library/BaseMemoryLib.h>
> +#include <Library/DebugLib.h>
> +#include <Library/IoLib.h>
> +#include <Library/SynchronizationLib.h>
> +#include <Library/UefiBootServicesTableLib.h>
> +#include <Library/UefiLib.h>
> +
> +#include <IndustryStandard/Bcm2836.h>
> +#include <IndustryStandard/RpiFirmware.h>
> +
> +#include <Protocol/RaspberryPiFirmware.h>
> +
> +//
> +// The number of statically allocated buffer pages
> +//
> +#define NUM_PAGES 1
> +
> +//
> +// The number of iterations to perform when waiting for the mailbox
> +// status to change
> +//
> +#define MAX_TRIES 0x100000
> +
> +STATIC VOID *mDmaBuffer;
> +STATIC VOID *mDmaBufferMapping;
> +STATIC UINTN mDmaBufferBusAddress;
> +
> +STATIC SPIN_LOCK mMailboxLock;
> +
> +STATIC
> +BOOLEAN
> +DrainMailbox (
> + VOID
> + )
> +{
> + INTN Tries;
> + UINT32 Val;
> +
> + //
> + // Get rid of stale response data in the mailbox
> + //
> + Tries = 0;
> + do {
> + Val = MmioRead32 (BCM2836_MBOX_BASE_ADDRESS + BCM2836_MBOX_STATUS_OFFSET);
> + if (Val & (1U << BCM2836_MBOX_STATUS_EMPTY)) {
> + return TRUE;
> + }
> + ArmDataSynchronizationBarrier ();
> + MmioRead32 (BCM2836_MBOX_BASE_ADDRESS + BCM2836_MBOX_READ_OFFSET);
> + } while (++Tries < MAX_TRIES);
> +
> + return FALSE;
> +}
> +
> +STATIC
> +BOOLEAN
> +MailboxWaitForStatusCleared (
> + IN UINTN StatusMask
> + )
> +{
> + INTN Tries;
> + UINT32 Val;
> +
> + //
> + // Get rid of stale response data in the mailbox
> + //
> + Tries = 0;
> + do {
> + Val = MmioRead32 (BCM2836_MBOX_BASE_ADDRESS + BCM2836_MBOX_STATUS_OFFSET);
> + if ((Val & StatusMask) == 0) {
> + return TRUE;
> + }
> + ArmDataSynchronizationBarrier ();
> + } while (++Tries < MAX_TRIES);
> +
> + return FALSE;
> +}
> +
> +STATIC
> +EFI_STATUS
> +MailboxTransaction (
> + IN UINTN Length,
> + IN UINTN Channel,
> + OUT UINT32 *Result
> + )
> +{
> + if (Channel >= BCM2836_MBOX_NUM_CHANNELS) {
> + return EFI_INVALID_PARAMETER;
> + }
> +
> + //
> + // Get rid of stale response data in the mailbox
> + //
> + if (!DrainMailbox ()) {
> + DEBUG ((DEBUG_ERROR, "%a: timeout waiting for mailbox to drain\n",
> + __FUNCTION__));
> + return EFI_TIMEOUT;
> + }
> +
> + //
> + // Wait for the 'output register full' bit to become clear
> + //
> + if (!MailboxWaitForStatusCleared (1U << BCM2836_MBOX_STATUS_FULL)) {
> + DEBUG ((DEBUG_ERROR, "%a: timeout waiting for outbox to become empty\n",
> + __FUNCTION__));
> + return EFI_TIMEOUT;
> + }
> +
> + ArmDataSynchronizationBarrier ();
> +
> + //
> + // Start the mailbox transaction
> + //
> + MmioWrite32 (BCM2836_MBOX_BASE_ADDRESS + BCM2836_MBOX_WRITE_OFFSET,
> + (UINT32)((UINTN)mDmaBufferBusAddress | Channel));
> +
> + ArmDataSynchronizationBarrier ();
> +
> + //
> + // Wait for the 'input register empty' bit to clear
> + //
> + if (!MailboxWaitForStatusCleared (1U << BCM2836_MBOX_STATUS_EMPTY)) {
> + DEBUG ((DEBUG_ERROR, "%a: timeout waiting for inbox to become full\n",
> + __FUNCTION__));
> + return EFI_TIMEOUT;
> + }
> +
> + //
> + // Read back the result
> + //
> + ArmDataSynchronizationBarrier ();
> + *Result = MmioRead32 (BCM2836_MBOX_BASE_ADDRESS + BCM2836_MBOX_READ_OFFSET);
> + ArmDataSynchronizationBarrier ();
> +
> + return EFI_SUCCESS;
> +}
> +
> +#pragma pack(1)
> +typedef struct {
> + UINT32 BufferSize;
> + UINT32 Response;
> +} RPI_FW_BUFFER_HEAD;
> +
> +typedef struct {
> + UINT32 TagId;
> + UINT32 TagSize;
> + UINT32 TagValueSize;
> +} RPI_FW_TAG_HEAD;
> +
> +typedef struct {
> + UINT32 DeviceId;
> + UINT32 PowerState;
> +} RPI_FW_POWER_STATE_TAG;
> +
> +typedef struct {
> + RPI_FW_BUFFER_HEAD BufferHead;
> + RPI_FW_TAG_HEAD TagHead;
> + RPI_FW_POWER_STATE_TAG TagBody;
> + UINT32 EndTag;
> +} RPI_FW_SET_POWER_STATE_CMD;
> +#pragma pack()
> +
> +STATIC
> +EFI_STATUS
> +EFIAPI
> +RpiFirmwareSetPowerState (
> + IN UINT32 DeviceId,
> + IN BOOLEAN PowerState,
> + IN BOOLEAN Wait
> + )
> +{
> + RPI_FW_SET_POWER_STATE_CMD *Cmd;
> + EFI_STATUS Status;
> + UINT32 Result;
> +
> + if (!AcquireSpinLockOrFail (&mMailboxLock)) {
> + DEBUG ((DEBUG_ERROR, "%a: failed to acquire spinlock\n", __FUNCTION__));
> + return EFI_DEVICE_ERROR;
> + }
> +
> + Cmd = mDmaBuffer;
> + ZeroMem (Cmd, sizeof *Cmd);
> +
> + Cmd->BufferHead.BufferSize = sizeof *Cmd;
> + Cmd->BufferHead.Response = 0;
> + Cmd->TagHead.TagId = RPI_FW_SET_POWER_STATE;
> + Cmd->TagHead.TagSize = sizeof Cmd->TagBody;
> + Cmd->TagHead.TagValueSize = 0;
> + Cmd->TagBody.DeviceId = DeviceId;
> + Cmd->TagBody.PowerState = (PowerState ? RPI_FW_POWER_STATE_ENABLE : 0) |
> + (Wait ? RPI_FW_POWER_STATE_WAIT : 0);
> + Cmd->EndTag = 0;
> +
> + Status = MailboxTransaction (Cmd->BufferHead.BufferSize, RPI_FW_MBOX_CHANNEL, &Result);
> +
> + ReleaseSpinLock (&mMailboxLock);
> +
> + if (EFI_ERROR (Status) ||
> + Cmd->BufferHead.Response != RPI_FW_RESP_SUCCESS) {
> + DEBUG ((DEBUG_ERROR,
> + "%a: mailbox transaction error: Status == %r, Response == 0x%x\n",
> + __FUNCTION__, Status, Cmd->BufferHead.Response));
> + Status = EFI_DEVICE_ERROR;
> + }
> +
> + if (!EFI_ERROR (Status) &&
> + PowerState ^ (Cmd->TagBody.PowerState & RPI_FW_POWER_STATE_ENABLE)) {
> + DEBUG ((DEBUG_ERROR, "%a: failed to %sable power for device %d\n",
> + __FUNCTION__, PowerState ? "en" : "dis", DeviceId));
> + Status = EFI_DEVICE_ERROR;
> + }
> +
> + return Status;
> +}
> +
> +#pragma pack()
> +typedef struct {
> + UINT32 Base;
> + UINT32 Size;
> +} RPI_FW_ARM_MEMORY_TAG;
> +
> +typedef struct {
> + RPI_FW_BUFFER_HEAD BufferHead;
> + RPI_FW_TAG_HEAD TagHead;
> + RPI_FW_ARM_MEMORY_TAG TagBody;
> + UINT32 EndTag;
> +} RPI_FW_GET_ARM_MEMORY_CMD;
> +#pragma pack()
> +
> +STATIC
> +EFI_STATUS
> +EFIAPI
> +RpiFirmwareGetArmMemory (
> + OUT UINT32 *Base,
> + OUT UINT32 *Size
> + )
> +{
> + RPI_FW_GET_ARM_MEMORY_CMD *Cmd;
> + EFI_STATUS Status;
> + UINT32 Result;
> +
> + if (!AcquireSpinLockOrFail (&mMailboxLock)) {
> + DEBUG ((DEBUG_ERROR, "%a: failed to acquire spinlock\n", __FUNCTION__));
> + return EFI_DEVICE_ERROR;
> + }
> +
> + Cmd = mDmaBuffer;
> + ZeroMem (Cmd, sizeof *Cmd);
> +
> + Cmd->BufferHead.BufferSize = sizeof *Cmd;
> + Cmd->BufferHead.Response = 0;
> + Cmd->TagHead.TagId = RPI_FW_GET_ARM_MEMSIZE;
> + Cmd->TagHead.TagSize = sizeof Cmd->TagBody;
> + Cmd->TagHead.TagValueSize = 0;
> + Cmd->EndTag = 0;
> +
> + Status = MailboxTransaction (Cmd->BufferHead.BufferSize, RPI_FW_MBOX_CHANNEL, &Result);
> +
> + ReleaseSpinLock (&mMailboxLock);
> +
> + if (EFI_ERROR (Status) ||
> + Cmd->BufferHead.Response != RPI_FW_RESP_SUCCESS) {
> + DEBUG ((DEBUG_ERROR,
> + "%a: mailbox transaction error: Status == %r, Response == 0x%x\n",
> + __FUNCTION__, Status, Cmd->BufferHead.Response));
> + return EFI_DEVICE_ERROR;
> + }
> +
> + *Base = Cmd->TagBody.Base;
> + *Size = Cmd->TagBody.Size;
> + return EFI_SUCCESS;
> +}
> +
> +#pragma pack()
> +typedef struct {
> + UINT8 MacAddress[6];
> + UINT32 Padding;
> +} RPI_FW_MAC_ADDR_TAG;
> +
> +typedef struct {
> + RPI_FW_BUFFER_HEAD BufferHead;
> + RPI_FW_TAG_HEAD TagHead;
> + RPI_FW_MAC_ADDR_TAG TagBody;
> + UINT32 EndTag;
> +} RPI_FW_GET_MAC_ADDR_CMD;
> +#pragma pack()
> +
> +STATIC
> +EFI_STATUS
> +EFIAPI
> +RpiFirmwareGetMacAddress (
> + OUT UINT8 MacAddress[6]
> + )
> +{
> + RPI_FW_GET_MAC_ADDR_CMD *Cmd;
> + EFI_STATUS Status;
> + UINT32 Result;
> +
> + if (!AcquireSpinLockOrFail (&mMailboxLock)) {
> + DEBUG ((DEBUG_ERROR, "%a: failed to acquire spinlock\n", __FUNCTION__));
> + return EFI_DEVICE_ERROR;
> + }
> +
> + Cmd = mDmaBuffer;
> + ZeroMem (Cmd, sizeof *Cmd);
> +
> + Cmd->BufferHead.BufferSize = sizeof *Cmd;
> + Cmd->BufferHead.Response = 0;
> + Cmd->TagHead.TagId = RPI_FW_GET_MAC_ADDRESS;
> + Cmd->TagHead.TagSize = sizeof Cmd->TagBody;
> + Cmd->TagHead.TagValueSize = 0;
> + Cmd->EndTag = 0;
> +
> + Status = MailboxTransaction (Cmd->BufferHead.BufferSize, RPI_FW_MBOX_CHANNEL, &Result);
> +
> + ReleaseSpinLock (&mMailboxLock);
> +
> + if (EFI_ERROR (Status) ||
> + Cmd->BufferHead.Response != RPI_FW_RESP_SUCCESS) {
> + DEBUG ((DEBUG_ERROR,
> + "%a: mailbox transaction error: Status == %r, Response == 0x%x\n",
> + __FUNCTION__, Status, Cmd->BufferHead.Response));
> + return EFI_DEVICE_ERROR;
> + }
> +
> + CopyMem (MacAddress, Cmd->TagBody.MacAddress, sizeof Cmd->TagBody.MacAddress);
> + return EFI_SUCCESS;
> +}
> +
> +#pragma pack()
> +typedef struct {
> + UINT64 Serial;
> +} RPI_FW_SERIAL_TAG;
> +
> +typedef struct {
> + RPI_FW_BUFFER_HEAD BufferHead;
> + RPI_FW_TAG_HEAD TagHead;
> + RPI_FW_SERIAL_TAG TagBody;
> + UINT32 EndTag;
> +} RPI_FW_GET_SERIAL_CMD;
> +#pragma pack()
> +
> +STATIC
> +EFI_STATUS
> +EFIAPI
> +RpiFirmwareGetSerial (
> + OUT UINT64 *Serial
> + )
> +{
> + RPI_FW_GET_SERIAL_CMD *Cmd;
> + EFI_STATUS Status;
> + UINT32 Result;
> +
> + if (!AcquireSpinLockOrFail (&mMailboxLock)) {
> + DEBUG ((DEBUG_ERROR, "%a: failed to acquire spinlock\n", __FUNCTION__));
> + return EFI_DEVICE_ERROR;
> + }
> +
> + Cmd = mDmaBuffer;
> + ZeroMem (Cmd, sizeof *Cmd);
> +
> + Cmd->BufferHead.BufferSize = sizeof *Cmd;
> + Cmd->BufferHead.Response = 0;
> + Cmd->TagHead.TagId = RPI_FW_GET_BOARD_SERIAL;
> + Cmd->TagHead.TagSize = sizeof Cmd->TagBody;
> + Cmd->TagHead.TagValueSize = 0;
> + Cmd->EndTag = 0;
> +
> + Status = MailboxTransaction (Cmd->BufferHead.BufferSize, RPI_FW_MBOX_CHANNEL, &Result);
> +
> + ReleaseSpinLock (&mMailboxLock);
> +
> + if (EFI_ERROR (Status) ||
> + Cmd->BufferHead.Response != RPI_FW_RESP_SUCCESS) {
> + DEBUG ((DEBUG_ERROR,
> + "%a: mailbox transaction error: Status == %r, Response == 0x%x\n",
> + __FUNCTION__, Status, Cmd->BufferHead.Response));
> + return EFI_DEVICE_ERROR;
> + }
> +
> + *Serial = Cmd->TagBody.Serial;
> + return EFI_SUCCESS;
> +}
> +
> +#pragma pack()
> +typedef struct {
> + UINT32 Model;
> +} RPI_FW_MODEL_TAG;
> +
> +typedef struct {
> + RPI_FW_BUFFER_HEAD BufferHead;
> + RPI_FW_TAG_HEAD TagHead;
> + RPI_FW_MODEL_TAG TagBody;
> + UINT32 EndTag;
> +} RPI_FW_GET_MODEL_CMD;
> +#pragma pack()
> +
> +STATIC
> +EFI_STATUS
> +EFIAPI
> +RpiFirmwareGetModel (
> + OUT UINT32 *Model
> + )
> +{
> + RPI_FW_GET_MODEL_CMD *Cmd;
> + EFI_STATUS Status;
> + UINT32 Result;
> +
> + if (!AcquireSpinLockOrFail (&mMailboxLock)) {
> + DEBUG ((DEBUG_ERROR, "%a: failed to acquire spinlock\n", __FUNCTION__));
> + return EFI_DEVICE_ERROR;
> + }
> +
> + Cmd = mDmaBuffer;
> + ZeroMem (Cmd, sizeof *Cmd);
> +
> + Cmd->BufferHead.BufferSize = sizeof *Cmd;
> + Cmd->BufferHead.Response = 0;
> + Cmd->TagHead.TagId = RPI_FW_GET_BOARD_MODEL;
> + Cmd->TagHead.TagSize = sizeof Cmd->TagBody;
> + Cmd->TagHead.TagValueSize = 0;
> + Cmd->EndTag = 0;
> +
> + Status = MailboxTransaction (Cmd->BufferHead.BufferSize, RPI_FW_MBOX_CHANNEL, &Result);
> +
> + ReleaseSpinLock (&mMailboxLock);
> +
> + if (EFI_ERROR (Status) ||
> + Cmd->BufferHead.Response != RPI_FW_RESP_SUCCESS) {
> + DEBUG ((DEBUG_ERROR,
> + "%a: mailbox transaction error: Status == %r, Response == 0x%x\n",
> + __FUNCTION__, Status, Cmd->BufferHead.Response));
> + return EFI_DEVICE_ERROR;
> + }
> +
> + *Model = Cmd->TagBody.Model;
> + return EFI_SUCCESS;
> +}
> +
> +#pragma pack()
> +typedef struct {
> + UINT32 Revision;
> +} RPI_FW_MODEL_REVISION_TAG;
> +
> +typedef struct {
> + RPI_FW_BUFFER_HEAD BufferHead;
> + RPI_FW_TAG_HEAD TagHead;
> + RPI_FW_MODEL_REVISION_TAG TagBody;
> + UINT32 EndTag;
> +} RPI_FW_GET_MODEL_REVISION_CMD;
> +#pragma pack()
> +
> +STATIC
> +EFI_STATUS
> +EFIAPI
> +RpiFirmwareGetModelRevision (
> + OUT UINT32 *Revision
> + )
> +{
> + RPI_FW_GET_MODEL_REVISION_CMD *Cmd;
> + EFI_STATUS Status;
> + UINT32 Result;
> +
> + if (!AcquireSpinLockOrFail (&mMailboxLock)) {
> + DEBUG ((DEBUG_ERROR, "%a: failed to acquire spinlock\n", __FUNCTION__));
> + return EFI_DEVICE_ERROR;
> + }
> +
> + Cmd = mDmaBuffer;
> + ZeroMem (Cmd, sizeof *Cmd);
> +
> + Cmd->BufferHead.BufferSize = sizeof *Cmd;
> + Cmd->BufferHead.Response = 0;
> + Cmd->TagHead.TagId = RPI_FW_GET_BOARD_REVISION;
> + Cmd->TagHead.TagSize = sizeof Cmd->TagBody;
> + Cmd->TagHead.TagValueSize = 0;
> + Cmd->EndTag = 0;
> +
> + Status = MailboxTransaction (Cmd->BufferHead.BufferSize, RPI_FW_MBOX_CHANNEL, &Result);
> +
> + ReleaseSpinLock (&mMailboxLock);
> +
> + if (EFI_ERROR (Status) ||
> + Cmd->BufferHead.Response != RPI_FW_RESP_SUCCESS) {
> + DEBUG ((DEBUG_ERROR,
> + "%a: mailbox transaction error: Status == %r, Response == 0x%x\n",
> + __FUNCTION__, Status, Cmd->BufferHead.Response));
> + return EFI_DEVICE_ERROR;
> + }
> +
> + *Revision = Cmd->TagBody.Revision;
> + return EFI_SUCCESS;
> +}
> +
> +#pragma pack()
> +typedef struct {
> + UINT32 Width;
> + UINT32 Height;
> +} RPI_FW_FB_SIZE_TAG;
> +
> +typedef struct {
> + RPI_FW_BUFFER_HEAD BufferHead;
> + RPI_FW_TAG_HEAD TagHead;
> + RPI_FW_FB_SIZE_TAG TagBody;
> + UINT32 EndTag;
> +} RPI_FW_GET_FB_SIZE_CMD;
> +
> +typedef struct {
> + UINT32 Depth;
> +} RPI_FW_FB_DEPTH_TAG;
> +
> +typedef struct {
> + UINT32 Pitch;
> +} RPI_FW_FB_PITCH_TAG;
> +
> +typedef struct {
> + UINT32 AlignmentBase;
> + UINT32 Size;
> +} RPI_FW_FB_ALLOC_TAG;
> +
> +typedef struct {
> + RPI_FW_BUFFER_HEAD BufferHead;
> + RPI_FW_TAG_HEAD FreeFbTag;
> + UINT32 EndTag;
> +} RPI_FW_FREE_FB_CMD;
> +
> +typedef struct {
> + RPI_FW_BUFFER_HEAD BufferHead;
> + RPI_FW_TAG_HEAD PhysSizeTag;
> + RPI_FW_FB_SIZE_TAG PhysSize;
> + RPI_FW_TAG_HEAD VirtSizeTag;
> + RPI_FW_FB_SIZE_TAG VirtSize;
> + RPI_FW_TAG_HEAD DepthTag;
> + RPI_FW_FB_DEPTH_TAG Depth;
> + RPI_FW_TAG_HEAD AllocFbTag;
> + RPI_FW_FB_ALLOC_TAG AllocFb;
> + RPI_FW_TAG_HEAD PitchTag;
> + RPI_FW_FB_PITCH_TAG Pitch;
> + UINT32 EndTag;
> +} RPI_FW_INIT_FB_CMD;
> +#pragma pack()
> +
> +STATIC
> +EFI_STATUS
> +EFIAPI
> +RpiFirmwareGetFbSize (
> + OUT UINT32 *Width,
> + OUT UINT32 *Height
> + )
> +{
> + RPI_FW_GET_FB_SIZE_CMD *Cmd;
> + EFI_STATUS Status;
> + UINT32 Result;
> +
> + if (!AcquireSpinLockOrFail (&mMailboxLock)) {
> + DEBUG ((DEBUG_ERROR, "%a: failed to acquire spinlock\n", __FUNCTION__));
> + return EFI_DEVICE_ERROR;
> + }
> +
> + Cmd = mDmaBuffer;
> + ZeroMem (Cmd, sizeof *Cmd);
> +
> + Cmd->BufferHead.BufferSize = sizeof *Cmd;
> + Cmd->BufferHead.Response = 0;
> + Cmd->TagHead.TagId = RPI_FW_GET_FB_GEOMETRY;
> + Cmd->TagHead.TagSize = sizeof Cmd->TagBody;
> + Cmd->TagHead.TagValueSize = 0;
> + Cmd->EndTag = 0;
> +
> + Status = MailboxTransaction (Cmd->BufferHead.BufferSize, RPI_FW_MBOX_CHANNEL, &Result);
> +
> + ReleaseSpinLock (&mMailboxLock);
> +
> + if (EFI_ERROR (Status) ||
> + Cmd->BufferHead.Response != RPI_FW_RESP_SUCCESS) {
> + DEBUG ((DEBUG_ERROR,
> + "%a: mailbox transaction error: Status == %r, Response == 0x%x\n",
> + __FUNCTION__, Status, Cmd->BufferHead.Response));
> + return EFI_DEVICE_ERROR;
> + }
> +
> + *Width = Cmd->TagBody.Width;
> + *Height = Cmd->TagBody.Height;
> + return EFI_SUCCESS;
> +}
> +
> +STATIC
> +EFI_STATUS
> +EFIAPI
> +RpiFirmwareFreeFb (VOID)
> +{
> + RPI_FW_FREE_FB_CMD *Cmd;
> + EFI_STATUS Status;
> + UINT32 Result;
> +
> + if (!AcquireSpinLockOrFail (&mMailboxLock)) {
> + DEBUG ((DEBUG_ERROR, "%a: failed to acquire spinlock\n", __FUNCTION__));
> + return EFI_DEVICE_ERROR;
> + }
> +
> + Cmd = mDmaBuffer;
> + ZeroMem (Cmd, sizeof *Cmd);
> +
> + Cmd->BufferHead.BufferSize = sizeof *Cmd;
> + Cmd->BufferHead.Response = 0;
> +
> + Cmd->FreeFbTag.TagId = RPI_FW_FREE_FB;
> + Cmd->FreeFbTag.TagSize = 0;
> + Cmd->FreeFbTag.TagValueSize = 0;
> + Cmd->EndTag = 0;
> +
> + Status = MailboxTransaction (Cmd->BufferHead.BufferSize, RPI_FW_MBOX_CHANNEL, &Result);
> + ReleaseSpinLock (&mMailboxLock);
> +
> + if (EFI_ERROR (Status) ||
> + Cmd->BufferHead.Response != RPI_FW_RESP_SUCCESS) {
> + DEBUG ((DEBUG_ERROR,
> + "%a: mailbox transaction error: Status == %r, Response == 0x%x\n",
> + __FUNCTION__, Status, Cmd->BufferHead.Response));
> + return EFI_DEVICE_ERROR;
> + }
> +
> + return EFI_SUCCESS;
> +}
> +
> +STATIC
> +EFI_STATUS
> +EFIAPI
> +RpiFirmwareAllocFb (
> + IN UINT32 Width,
> + IN UINT32 Height,
> + IN UINT32 Depth,
> + OUT EFI_PHYSICAL_ADDRESS *FbBase,
> + OUT UINTN *FbSize,
> + OUT UINTN *Pitch)
> +{
> + RPI_FW_INIT_FB_CMD *Cmd;
> + EFI_STATUS Status;
> + UINT32 Result;
> +
> + ASSERT (FbSize != NULL);
> + ASSERT (FbBase != NULL);
> +
> + if (!AcquireSpinLockOrFail (&mMailboxLock)) {
> + DEBUG ((DEBUG_ERROR, "%a: failed to acquire spinlock\n", __FUNCTION__));
> + return EFI_DEVICE_ERROR;
> + }
> +
> + Cmd = mDmaBuffer;
> + ZeroMem (Cmd, sizeof *Cmd);
> +
> + Cmd->BufferHead.BufferSize = sizeof *Cmd;
> + Cmd->BufferHead.Response = 0;
> +
> + Cmd->PhysSizeTag.TagId = RPI_FW_SET_FB_PGEOM;
> + Cmd->PhysSizeTag.TagSize = sizeof Cmd->PhysSize;
> + Cmd->PhysSize.Width = Width;
> + Cmd->PhysSize.Height = Height;
> + Cmd->VirtSizeTag.TagId = RPI_FW_SET_FB_VGEOM;
> + Cmd->VirtSizeTag.TagSize = sizeof Cmd->VirtSize;
> + Cmd->VirtSize.Width = Width;
> + Cmd->VirtSize.Height = Height;
> + Cmd->DepthTag.TagId = RPI_FW_SET_FB_DEPTH;
> + Cmd->DepthTag.TagSize = sizeof Cmd->Depth;
> + Cmd->Depth.Depth = Depth;
> + Cmd->AllocFbTag.TagId = RPI_FW_ALLOC_FB;
> + Cmd->AllocFbTag.TagSize = sizeof Cmd->AllocFb;
> + Cmd->AllocFb.AlignmentBase = 32;
> + Cmd->PitchTag.TagId = RPI_FW_GET_FB_LINELENGTH;
> + Cmd->PitchTag.TagSize = sizeof Cmd->Pitch;
> + Cmd->EndTag = 0;
> +
> + Status = MailboxTransaction (Cmd->BufferHead.BufferSize, RPI_FW_MBOX_CHANNEL, &Result);
> +
> + ReleaseSpinLock (&mMailboxLock);
> +
> + if (EFI_ERROR (Status) ||
> + Cmd->BufferHead.Response != RPI_FW_RESP_SUCCESS) {
> + DEBUG ((DEBUG_ERROR,
> + "%a: mailbox transaction error: Status == %r, Response == 0x%x\n",
> + __FUNCTION__, Status, Cmd->BufferHead.Response));
> + return EFI_DEVICE_ERROR;
> + }
> +
> + *Pitch = Cmd->Pitch.Pitch;
> + *FbBase = Cmd->AllocFb.AlignmentBase - BCM2836_DMA_DEVICE_OFFSET;
> + *FbSize = Cmd->AllocFb.Size;
> + return EFI_SUCCESS;
> +}
> +
> +#pragma pack()
> +typedef struct {
> + RPI_FW_BUFFER_HEAD BufferHead;
> + RPI_FW_TAG_HEAD TagHead;
> + UINT8 CommandLine[0];
> +} RPI_FW_GET_COMMAND_LINE_CMD;
> +#pragma pack()
> +
> +STATIC
> +EFI_STATUS
> +EFIAPI
> +RpiFirmwareGetCommmandLine (
> + IN UINTN BufferSize,
> + OUT CHAR8 CommandLine[]
> + )
> +{
> + RPI_FW_GET_COMMAND_LINE_CMD *Cmd;
> + EFI_STATUS Status;
> + UINT32 Result;
> +
> + if ((BufferSize % sizeof (UINT32)) != 0) {
> + DEBUG ((DEBUG_ERROR, "%a: BufferSize must be a multiple of 4\n",
> + __FUNCTION__));
> + return EFI_INVALID_PARAMETER;
> + }
> +
> + if (sizeof *Cmd + BufferSize > EFI_PAGES_TO_SIZE (NUM_PAGES)) {
> + DEBUG ((DEBUG_ERROR, "%a: BufferSize exceeds size of DMA buffer\n",
> + __FUNCTION__));
> + return EFI_OUT_OF_RESOURCES;
> + }
> +
> + if (!AcquireSpinLockOrFail (&mMailboxLock)) {
> + DEBUG ((DEBUG_ERROR, "%a: failed to acquire spinlock\n", __FUNCTION__));
> + return EFI_DEVICE_ERROR;
> + }
> +
> + Cmd = mDmaBuffer;
> + ZeroMem (Cmd, sizeof *Cmd + BufferSize + sizeof (UINT32));
> +
> + Cmd->BufferHead.BufferSize = sizeof *Cmd + BufferSize + sizeof (UINT32);
> + Cmd->BufferHead.Response = 0;
> + Cmd->TagHead.TagId = RPI_FW_GET_COMMAND_LINE;
> + Cmd->TagHead.TagSize = BufferSize;
> + Cmd->TagHead.TagValueSize = 0;
> +
> + Status = MailboxTransaction (Cmd->BufferHead.BufferSize, RPI_FW_MBOX_CHANNEL, &Result);
> +
> + ReleaseSpinLock (&mMailboxLock);
> +
> + if (EFI_ERROR (Status) ||
> + Cmd->BufferHead.Response != RPI_FW_RESP_SUCCESS) {
> + DEBUG ((DEBUG_ERROR,
> + "%a: mailbox transaction error: Status == %r, Response == 0x%x\n",
> + __FUNCTION__, Status, Cmd->BufferHead.Response));
> + return EFI_DEVICE_ERROR;
> + }
> +
> + Cmd->TagHead.TagValueSize &= ~RPI_FW_VALUE_SIZE_RESPONSE_MASK;
> + if (Cmd->TagHead.TagValueSize >= BufferSize &&
> + Cmd->CommandLine[Cmd->TagHead.TagValueSize - 1] != '\0') {
> + DEBUG ((DEBUG_ERROR, "%a: insufficient buffer size\n", __FUNCTION__));
> + return EFI_OUT_OF_RESOURCES;
> + }
> +
> + CopyMem (CommandLine, Cmd->CommandLine, Cmd->TagHead.TagValueSize);
> +
> + if (CommandLine[Cmd->TagHead.TagValueSize - 1] != '\0') {
> + //
> + // Add a NUL terminator if required.
> + //
> + CommandLine[Cmd->TagHead.TagValueSize] = '\0';
> + }
> +
> + return EFI_SUCCESS;
> +}
> +
> +#pragma pack()
> +typedef struct {
> + UINT32 ClockId;
> + UINT32 ClockRate;
> + UINT32 SkipTurbo;
> +} RPI_FW_SET_CLOCK_RATE_TAG;
> +
> +typedef struct {
> + RPI_FW_BUFFER_HEAD BufferHead;
> + RPI_FW_TAG_HEAD TagHead;
> + RPI_FW_SET_CLOCK_RATE_TAG TagBody;
> + UINT32 EndTag;
> +} RPI_FW_SET_CLOCK_RATE_CMD;
> +#pragma pack()
> +
> +STATIC
> +EFI_STATUS
> +EFIAPI
> +RpiFirmwareSetClockRate (
> + IN UINT32 ClockId,
> + IN UINT32 ClockRate
> + )
> +{
> + RPI_FW_SET_CLOCK_RATE_CMD *Cmd;
> + EFI_STATUS Status;
> + UINT32 Result;
> +
> + if (!AcquireSpinLockOrFail (&mMailboxLock)) {
> + DEBUG ((DEBUG_ERROR, "%a: failed to acquire spinlock\n", __FUNCTION__));
> + return EFI_DEVICE_ERROR;
> + }
> +
> + Cmd = mDmaBuffer;
> + ZeroMem (Cmd, sizeof *Cmd);
> +
> + Cmd->BufferHead.BufferSize = sizeof *Cmd;
> + Cmd->BufferHead.Response = 0;
> + Cmd->TagHead.TagId = RPI_FW_SET_CLOCK_RATE,
> + Cmd->TagHead.TagSize = sizeof Cmd->TagBody;
> + Cmd->TagHead.TagValueSize = 0;
> + Cmd->TagBody.ClockId = ClockId;
> + Cmd->TagBody.ClockRate = ClockRate;
> + Cmd->EndTag = 0;
> +
> + Status = MailboxTransaction (Cmd->BufferHead.BufferSize, RPI_FW_MBOX_CHANNEL, &Result);
> +
> + ReleaseSpinLock (&mMailboxLock);
> +
> + if (EFI_ERROR (Status) ||
> + Cmd->BufferHead.Response != RPI_FW_RESP_SUCCESS) {
> + DEBUG ((DEBUG_ERROR,
> + "%a: mailbox transaction error: Status == %r, Response == 0x%x\n",
> + __FUNCTION__, Status, Cmd->BufferHead.Response));
> + return EFI_DEVICE_ERROR;
> + }
> +
> + return EFI_SUCCESS;
> +}
> +
> +
> +#pragma pack()
> +typedef struct {
> + UINT32 ClockId;
> + UINT32 ClockRate;
> +} RPI_FW_CLOCK_RATE_TAG;
> +
> +typedef struct {
> + RPI_FW_BUFFER_HEAD BufferHead;
> + RPI_FW_TAG_HEAD TagHead;
> + RPI_FW_CLOCK_RATE_TAG TagBody;
> + UINT32 EndTag;
> +} RPI_FW_GET_CLOCK_RATE_CMD;
> +#pragma pack()
> +
> +STATIC
> +EFI_STATUS
> +EFIAPI
> +RpiFirmwareGetClockRate (
> + IN UINT32 ClockId,
> + IN UINT32 ClockKind,
> + OUT UINT32 *ClockRate
> + )
> +{
> + RPI_FW_GET_CLOCK_RATE_CMD *Cmd;
> + EFI_STATUS Status;
> + UINT32 Result;
> +
> + if (!AcquireSpinLockOrFail (&mMailboxLock)) {
> + DEBUG ((DEBUG_ERROR, "%a: failed to acquire spinlock\n", __FUNCTION__));
> + return EFI_DEVICE_ERROR;
> + }
> +
> + Cmd = mDmaBuffer;
> + ZeroMem (Cmd, sizeof *Cmd);
> +
> + Cmd->BufferHead.BufferSize = sizeof *Cmd;
> + Cmd->BufferHead.Response = 0;
> + Cmd->TagHead.TagId = ClockKind,
> + Cmd->TagHead.TagSize = sizeof Cmd->TagBody;
> + Cmd->TagHead.TagValueSize = 0;
> + Cmd->TagBody.ClockId = ClockId;
> + Cmd->EndTag = 0;
> +
> + Status = MailboxTransaction (Cmd->BufferHead.BufferSize, RPI_FW_MBOX_CHANNEL, &Result);
> +
> + ReleaseSpinLock (&mMailboxLock);
> +
> + if (EFI_ERROR (Status) ||
> + Cmd->BufferHead.Response != RPI_FW_RESP_SUCCESS) {
> + DEBUG ((DEBUG_ERROR,
> + "%a: mailbox transaction error: Status == %r, Response == 0x%x\n",
> + __FUNCTION__, Status, Cmd->BufferHead.Response));
> + return EFI_DEVICE_ERROR;
> + }
> +
> + *ClockRate = Cmd->TagBody.ClockRate;
> + return EFI_SUCCESS;
> +}
> +
> +STATIC
> +EFI_STATUS
> +EFIAPI
> +RpiFirmwareGetCurrentClockRate (
> + IN UINT32 ClockId,
> + OUT UINT32 *ClockRate
> + )
> +{
> + return RpiFirmwareGetClockRate(ClockId, RPI_FW_GET_CLOCK_RATE, ClockRate);
> +}
> +
> +STATIC
> +EFI_STATUS
> +EFIAPI
> +RpiFirmwareGetMaxClockRate (
> + IN UINT32 ClockId,
> + OUT UINT32 *ClockRate
> + )
> +{
> + return RpiFirmwareGetClockRate(ClockId, RPI_FW_GET_MAX_CLOCK_RATE, ClockRate);
> +}
> +
> +STATIC
> +EFI_STATUS
> +EFIAPI
> +RpiFirmwareGetMinClockRate (
> + IN UINT32 ClockId,
> + OUT UINT32 *ClockRate
> + )
> +{
> + return RpiFirmwareGetClockRate(ClockId, RPI_FW_GET_MIN_CLOCK_RATE, ClockRate);
> +}
> +
> +#pragma pack()
> +typedef struct {
> + UINT32 Pin;
> + UINT32 State;
> +} RPI_FW_SET_GPIO_TAG;
> +
> +typedef struct {
> + RPI_FW_BUFFER_HEAD BufferHead;
> + RPI_FW_TAG_HEAD TagHead;
> + RPI_FW_SET_GPIO_TAG TagBody;
> + UINT32 EndTag;
> +} RPI_FW_SET_GPIO_CMD;
> +#pragma pack()
> +
> +STATIC
> +VOID
> +RpiFirmwareLedSet (
> + IN BOOLEAN On
> + )
> +{
> + RPI_FW_SET_GPIO_CMD *Cmd;
> + EFI_STATUS Status;
> + UINT32 Result;
> +
> + if (!AcquireSpinLockOrFail (&mMailboxLock)) {
> + DEBUG ((DEBUG_ERROR, "%a: failed to acquire spinlock\n", __FUNCTION__));
> + return;
> + }
> +
> + Cmd = mDmaBuffer;
> + ZeroMem (Cmd, sizeof *Cmd);
> +
> + Cmd->BufferHead.BufferSize = sizeof *Cmd;
> + Cmd->BufferHead.Response = 0;
> + Cmd->TagHead.TagId = RPI_FW_SET_GPIO;
> + Cmd->TagHead.TagSize = sizeof Cmd->TagBody;
> + /*
> + * GPIO_PIN_2 = Activity LED
> + * GPIO_PIN_4 = HDMI Detect (Input / Active Low)
> + * GPIO_PIN_7 = Power LED (Input / Active Low)
> + *
> + * There's also a 128 pin offset.
> + */
> + Cmd->TagBody.Pin = 128 + 2;
> + Cmd->TagBody.State = On;
> + Cmd->TagHead.TagValueSize = 0;
> + Cmd->EndTag = 0;
> +
> + Status = MailboxTransaction (Cmd->BufferHead.BufferSize, RPI_FW_MBOX_CHANNEL, &Result);
> +
> + ReleaseSpinLock (&mMailboxLock);
> +
> + if (EFI_ERROR (Status) ||
> + Cmd->BufferHead.Response != RPI_FW_RESP_SUCCESS) {
> + DEBUG ((DEBUG_ERROR,
> + "%a: mailbox transaction error: Status == %r, Response == 0x%x\n",
> + __FUNCTION__, Status, Cmd->BufferHead.Response));
> + }
> +}
> +
> +STATIC RASPBERRY_PI_FIRMWARE_PROTOCOL mRpiFirmwareProtocol = {
> + RpiFirmwareSetPowerState,
> + RpiFirmwareGetMacAddress,
> + RpiFirmwareGetCommmandLine,
> + RpiFirmwareGetCurrentClockRate,
> + RpiFirmwareGetMaxClockRate,
> + RpiFirmwareGetMinClockRate,
> + RpiFirmwareSetClockRate,
> + RpiFirmwareAllocFb,
> + RpiFirmwareFreeFb,
> + RpiFirmwareGetFbSize,
> + RpiFirmwareLedSet,
> + RpiFirmwareGetSerial,
> + RpiFirmwareGetModel,
> + RpiFirmwareGetModelRevision,
> + RpiFirmwareGetArmMemory
> +};
> +
> +/**
> + Initialize the state information for the CPU Architectural Protocol
> +
> + @param ImageHandle of the loaded driver
> + @param SystemTable Pointer to the System Table
> +
> + @retval EFI_SUCCESS Protocol registered
> + @retval EFI_OUT_OF_RESOURCES Cannot allocate protocol data structure
> + @retval EFI_DEVICE_ERROR Hardware problems
> +
> +**/
> +EFI_STATUS
> +RpiFirmwareDxeInitialize (
> + IN EFI_HANDLE ImageHandle,
> + IN EFI_SYSTEM_TABLE *SystemTable
> + )
> +{
> + EFI_STATUS Status;
> + UINTN BufferSize;
> +
> + //
> + // We only need one of these
> + //
> + ASSERT_PROTOCOL_ALREADY_INSTALLED (NULL, &gRaspberryPiFirmwareProtocolGuid);
> +
> + InitializeSpinLock (&mMailboxLock);
> +
> + Status = DmaAllocateBuffer (EfiBootServicesData, NUM_PAGES, &mDmaBuffer);
> + if (EFI_ERROR (Status)) {
> + DEBUG ((DEBUG_ERROR, "%a: failed to allocate DMA buffer (Status == %r)\n",
> + __FUNCTION__));
> + return Status;
> + }
> +
> + BufferSize = EFI_PAGES_TO_SIZE (NUM_PAGES);
> + Status = DmaMap (MapOperationBusMasterCommonBuffer, mDmaBuffer, &BufferSize,
> + &mDmaBufferBusAddress, &mDmaBufferMapping);
> + if (EFI_ERROR (Status)) {
> + DEBUG ((DEBUG_ERROR, "%a: failed to map DMA buffer (Status == %r)\n",
> + __FUNCTION__));
> + goto FreeBuffer;
> + }
> +
> + //
> + // The channel index is encoded in the low bits of the bus address,
> + // so make sure these are cleared.
> + //
> + ASSERT (!(mDmaBufferBusAddress & (BCM2836_MBOX_NUM_CHANNELS - 1)));
> +
> + Status = gBS->InstallProtocolInterface (&ImageHandle,
> + &gRaspberryPiFirmwareProtocolGuid, EFI_NATIVE_INTERFACE,
> + &mRpiFirmwareProtocol);
> + if (EFI_ERROR (Status)) {
> + DEBUG ((DEBUG_ERROR,
> + "%a: failed to install RPI firmware protocol (Status == %r)\n",
> + __FUNCTION__, Status));
> + goto UnmapBuffer;
> + }
> +
> + return EFI_SUCCESS;
> +
> +UnmapBuffer:
> + DmaUnmap (mDmaBufferMapping);
> +FreeBuffer:
> + DmaFreeBuffer (NUM_PAGES, mDmaBuffer);
> +
> + return Status;
> +}
> diff --git a/Platform/Broadcom/Bcm283x/Drivers/RpiFirmwareDxe/RpiFirmwareDxe.inf b/Platform/Broadcom/Bcm283x/Drivers/RpiFirmwareDxe/RpiFirmwareDxe.inf
> new file mode 100644
> index 000000000000..2ab57bbf54f0
> --- /dev/null
> +++ b/Platform/Broadcom/Bcm283x/Drivers/RpiFirmwareDxe/RpiFirmwareDxe.inf
> @@ -0,0 +1,49 @@
> +#/** @file
> +#
> +# Copyright (c) 2017-2018, Andrei Warkentin <andrey.warkentin@gmail.com>
> +# Copyright (c) 2016, 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 = 0x00010019
> + BASE_NAME = RpiFirmwareDxe
> + FILE_GUID = 6d4628df-49a0-4b67-a325-d5af35c65745
> + MODULE_TYPE = DXE_DRIVER
> + VERSION_STRING = 1.0
> + ENTRY_POINT = RpiFirmwareDxeInitialize
> +
> +[Sources]
> + RpiFirmwareDxe.c
> +
> +[Packages]
> + ArmPkg/ArmPkg.dec
> + MdePkg/MdePkg.dec
> + EmbeddedPkg/EmbeddedPkg.dec
> + Platform/Broadcom/Bcm283x/RaspberryPiPkg.dec
> +
> +[LibraryClasses]
> + ArmLib
> + BaseLib
> + BaseMemoryLib
> + DebugLib
> + DmaLib
> + IoLib
> + SynchronizationLib
> + UefiBootServicesTableLib
> + UefiDriverEntryPoint
> + UefiLib
> +
> +[Protocols]
> + gRaspberryPiFirmwareProtocolGuid ## PRODUCES
> +
> +[Depex]
> + TRUE
> diff --git a/Platform/Broadcom/Bcm283x/Include/Protocol/RaspberryPiFirmware.h b/Platform/Broadcom/Bcm283x/Include/Protocol/RaspberryPiFirmware.h
> new file mode 100644
> index 000000000000..2a4247584641
> --- /dev/null
> +++ b/Platform/Broadcom/Bcm283x/Include/Protocol/RaspberryPiFirmware.h
> @@ -0,0 +1,131 @@
> +/** @file
> + *
> + * Copyright (c) 2016, Linaro Limited. 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 __RASPBERRY_PI_FIRMWARE_PROTOCOL_H__
> +#define __RASPBERRY_PI_FIRMWARE_PROTOCOL_H__
> +
> +#define RASPBERRY_PI_FIRMWARE_PROTOL_GUID \
> + { 0x0ACA9535, 0x7AD0, 0x4286, { 0xB0, 0x2E, 0x87, 0xFA, 0x7E, 0x2A, 0x57, 0x11 } }
> +
> +typedef
> +EFI_STATUS
> +(EFIAPI *SET_POWER_STATE) (
> + IN UINT32 DeviceId,
> + IN BOOLEAN PowerState,
> + IN BOOLEAN Wait
> + );
> +
> +typedef
> +EFI_STATUS
> +(EFIAPI *GET_MAC_ADDRESS) (
> + OUT UINT8 MacAddress[6]
> + );
> +
> +typedef
> +EFI_STATUS
> +(EFIAPI *GET_COMMAND_LINE) (
> + IN UINTN BufferSize,
> + OUT CHAR8 CommandLine[]
> + );
> +
> +typedef
> +EFI_STATUS
> +(EFIAPI *GET_CLOCK_RATE) (
> + IN UINT32 ClockId,
> + OUT UINT32 *ClockRate
> + );
> +
> +typedef
> +EFI_STATUS
> +(EFIAPI *SET_CLOCK_RATE) (
> + IN UINT32 ClockId,
> + OUT UINT32 ClockRate
> + );
> +
> +typedef
> +EFI_STATUS
> +(EFIAPI *GET_FB) (
> + IN UINT32 Width,
> + IN UINT32 Height,
> + IN UINT32 Depth,
> + OUT EFI_PHYSICAL_ADDRESS *FbBase,
> + OUT UINTN *FbSize,
> + OUT UINTN *Pitch
> + );
> +
> +typedef
> +EFI_STATUS
> +(EFIAPI *GET_FB_SIZE) (
> + OUT UINT32 *Width,
> + OUT UINT32 *Height
> + );
> +
> +typedef
> +EFI_STATUS
> +(EFIAPI *FREE_FB) (
> + VOID
> + );
> +
> +typedef
> +VOID
> +(EFIAPI *SET_LED) (
> + BOOLEAN On
> + );
> +
> +typedef
> +EFI_STATUS
> +(EFIAPI *GET_SERIAL) (
> + UINT64 *Serial
> + );
> +
> +typedef
> +EFI_STATUS
> +(EFIAPI *GET_MODEL) (
> + UINT32 *Model
> + );
> +
> +typedef
> +EFI_STATUS
> +(EFIAPI *GET_MODEL_REVISION) (
> + UINT32 *Revision
> + );
> +
> +typedef
> +EFI_STATUS
> +(EFIAPI *GET_ARM_MEM) (
> + UINT32 *Base,
> + UINT32 *Size
> + );
> +
> +typedef struct {
> + SET_POWER_STATE SetPowerState;
> + GET_MAC_ADDRESS GetMacAddress;
> + GET_COMMAND_LINE GetCommandLine;
> + GET_CLOCK_RATE GetClockRate;
> + GET_CLOCK_RATE GetMaxClockRate;
> + GET_CLOCK_RATE GetMinClockRate;
> + SET_CLOCK_RATE SetClockRate;
> + GET_FB GetFB;
> + FREE_FB FreeFB;
> + GET_FB_SIZE GetFBSize;
> + SET_LED SetLed;
> + GET_SERIAL GetSerial;
> + GET_MODEL GetModel;
> + GET_MODEL_REVISION GetModelRevision;
> + GET_ARM_MEM GetArmMem;
> +} RASPBERRY_PI_FIRMWARE_PROTOCOL;
> +
> +extern EFI_GUID gRaspberryPiFirmwareProtocolGuid;
> +
> +#endif
> --
> 2.17.0.windows.1
>
next prev parent reply other threads:[~2018-12-12 21:17 UTC|newest]
Thread overview: 48+ messages / expand[flat|nested] mbox.gz Atom feed top
2018-12-10 12:38 [PATCH v2 edk2-platforms 00/20] Platform/Broadcom: Add Raspberry Pi 3 support Pete Batard
2018-12-10 12:38 ` [PATCH v2 edk2-platforms 01/20] Platform/Broadcom/RPi3: Add Reset and Memory Init libraries Pete Batard
2018-12-12 20:43 ` Ard Biesheuvel
2018-12-13 10:48 ` Pete Batard
2018-12-10 12:38 ` [PATCH v2 edk2-platforms 02/20] Platform/Broadcom/RPi3: Add Platform library Pete Batard
2018-12-10 12:38 ` [PATCH v2 edk2-platforms 03/20] Platform/Broadcom/RPi3: Add GPIO and RTC libraries Pete Batard
2018-12-12 20:50 ` Ard Biesheuvel
2018-12-13 10:49 ` Pete Batard
2018-12-13 10:55 ` Leif Lindholm
2018-12-10 12:38 ` [PATCH v2 edk2-platforms 04/20] Platform/Broadcom/RPi3: Add ACPI Tables Pete Batard
2018-12-12 20:52 ` Ard Biesheuvel
2018-12-13 10:49 ` Pete Batard
2018-12-10 12:38 ` [PATCH v2 edk2-platforms 05/20] Platform/Broadcom/RPi3: Add Boot Manager library Pete Batard
2018-12-12 20:56 ` Ard Biesheuvel
2018-12-10 12:38 ` [PATCH v2 edk2-platforms 06/20] Platform/Broadcom/RPi3: Add Interrupt and Device Tree drivers Pete Batard
2018-12-12 21:09 ` Ard Biesheuvel
2018-12-13 10:49 ` Pete Batard
2018-12-10 12:38 ` [PATCH v2 edk2-platforms 07/20] Platform/Broadcom/RPi3: Add Firmware driver Pete Batard
2018-12-12 21:17 ` Ard Biesheuvel [this message]
2018-12-13 10:49 ` Pete Batard
2018-12-10 12:38 ` [PATCH v2 edk2-platforms 08/20] Platform/Broadcom/RPi3: Add Display driver Pete Batard
2018-12-14 15:06 ` Ard Biesheuvel
2018-12-10 12:38 ` [PATCH v2 edk2-platforms 09/20] Platform/Broadcom/RPi3: Add Graphic Console driver Pete Batard
2018-12-14 15:31 ` Ard Biesheuvel
2018-12-10 12:38 ` [PATCH v2 edk2-platforms 10/20] Platform/Broadcom/RPi3: Add Base MMC driver Pete Batard
2018-12-10 12:38 ` [PATCH v2 edk2-platforms 11/20] Platform/Broadcom/RPi3: Add Arasan " Pete Batard
2018-12-10 12:38 ` [PATCH v2 edk2-platforms 12/20] Platform/Broadcom/RPi3: Add SD Host driver Pete Batard
2018-12-10 12:38 ` [PATCH v2 edk2-platforms 13/20] Platform/Broadcom/RPi3: Add SMBIOS driver Pete Batard
2018-12-14 15:36 ` Ard Biesheuvel
2018-12-10 12:38 ` [PATCH v2 edk2-platforms 14/20] Platform/Broadcom/RPi3: Add NV Storage driver Pete Batard
2018-12-10 12:38 ` [PATCH v2 edk2-platforms 15/20] Platform/Broadcom/RPi3: Add Platform Config driver Pete Batard
2018-12-10 12:38 ` [PATCH v2 edk2-platforms 16/20] Platform/Broadcom/RPi3: Add Raspberry Pi 3 Platform Pete Batard
2018-12-14 15:39 ` Ard Biesheuvel
2018-12-14 16:21 ` Pete Batard
2018-12-10 12:38 ` [PATCH v2 edk2-platforms 17/20] Platform/Broadcom/RPi3 *NON-OSI*: Add ATF binaries Pete Batard
2018-12-10 12:38 ` [PATCH v2 edk2-platforms 18/20] Platform/Broadcom/RPi3 *NON-OSI*: Add Device Tree binaries Pete Batard
2018-12-10 12:38 ` [PATCH v2 edk2-platforms 19/20] Platform/Broadcom/RPi3 *NON-OSI*: Add USB Host driver Pete Batard
2018-12-10 12:38 ` [PATCH v2 edk2-platforms 20/20] Platform/Broadcom/RPi3 *NON-OSI*: Add Logo driver Pete Batard
2018-12-11 18:10 ` [PATCH v2 edk2-platforms 00/20] Platform/Broadcom: Add Raspberry Pi 3 support Leif Lindholm
2018-12-11 20:16 ` Pete Batard
2018-12-11 21:20 ` Ard Biesheuvel
2018-12-12 18:32 ` Leif Lindholm
2018-12-12 19:53 ` Pete Batard
2018-12-12 20:01 ` Leif Lindholm
2018-12-14 16:14 ` Philippe Mathieu-Daudé
2018-12-14 16:36 ` Leif Lindholm
2018-12-14 17:08 ` Pete Batard
2018-12-14 18:41 ` Leif Lindholm
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-list from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=CAKv+Gu9YmP0N-uynOJhG5ZZU07yh1q6zckhzOYgUadfpDvtyQw@mail.gmail.com \
--to=devel@edk2.groups.io \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox