blob: 1a5a8f766c47ab6f63571adb6dbd7a4ab221b3b7 [file] [log] [blame]
// Copyright 2019 The Fuchsia Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef SRC_DEVICES_SECUREMEM_DRIVERS_AML_SECUREMEM_DEVICE_H_
#define SRC_DEVICES_SECUREMEM_DRIVERS_AML_SECUREMEM_DEVICE_H_
#include <fidl/fuchsia.hardware.securemem/cpp/wire.h>
#include <fidl/fuchsia.hardware.sysmem/cpp/wire.h>
#include <fidl/fuchsia.hardware.tee/cpp/wire.h>
#include <fuchsia/hardware/platform/device/c/banjo.h>
#include <fuchsia/hardware/platform/device/cpp/banjo.h>
#include <lib/async_patterns/cpp/dispatcher_bound.h>
#include <lib/async_patterns/cpp/receiver.h>
#include <lib/device-protocol/pdev-fidl.h>
#include <lib/fpromise/result.h>
#include <lib/zx/bti.h>
#include <zircon/types.h>
#include <optional>
#include <ddktl/device.h>
#include <ddktl/protocol/empty-protocol.h>
#include "sysmem-secure-mem-server.h"
namespace amlogic_secure_mem {
static constexpr const char* kDeviceName = "aml-securemem";
class AmlogicSecureMemDevice;
using AmlogicSecureMemDeviceBase =
ddk::Device<AmlogicSecureMemDevice, ddk::Messageable<fuchsia_hardware_securemem::Device>::Mixin,
ddk::Suspendable>;
class AmlogicSecureMemDevice : public AmlogicSecureMemDeviceBase,
public ddk::EmptyProtocol<ZX_PROTOCOL_SECURE_MEM> {
public:
static zx_status_t Create(void* ctx, zx_device_t* parent);
zx_status_t Bind();
void DdkSuspend(ddk::SuspendTxn txn);
void DdkRelease() { delete this; }
// LLCPP interface implementations
void GetSecureMemoryPhysicalAddress(
GetSecureMemoryPhysicalAddressRequestView request,
GetSecureMemoryPhysicalAddressCompleter::Sync& completer) override;
fpromise::result<zx_paddr_t, zx_status_t> GetSecureMemoryPhysicalAddress(zx::vmo secure_mem);
private:
explicit AmlogicSecureMemDevice(zx_device_t* device);
zx_status_t CreateAndServeSysmemTee();
void SysmemSecureMemServerOnUnbound(bool is_success);
// The dispatcher that this |AmlogicSecureMemDevice| lives on.
fdf_dispatcher_t* const fdf_dispatcher_;
ddk::PDevFidl pdev_proto_client_;
fidl::WireSyncClient<fuchsia_hardware_sysmem::Sysmem> sysmem_;
fidl::WireSyncClient<fuchsia_hardware_tee::DeviceConnector> tee_proto_client_;
// Note: |bti_| must be backed by a dummy IOMMU so that the physical address will be stable every
// time a secure memory VMO is passed to be pinned.
zx::bti bti_;
// By destroying/shutting down the loop after the |DispatcherBound|, we know that we won't
// trigger a synchronous call to any method calls queued via the normally-async
// |sysmem_secure_mem_server_| below, nor any synchronous call to the
// |SysmemSecureMemServer| constructor, nor any synchronous call to the
// |SysmemSecureMemServer| destructor.
async::Loop sysmem_secure_mem_server_loop_{&kAsyncLoopConfigNeverAttachToThread};
// |sysmem_secure_mem_server_| lives on |sysmem_secure_mem_server_loop_|.
// This shields the fdf dispatcher away from blocking TEE calls.
async_patterns::DispatcherBound<SysmemSecureMemServer> sysmem_secure_mem_server_{
sysmem_secure_mem_server_loop_.dispatcher()};
bool is_suspend_mexec_ = false;
std::optional<ddk::SuspendTxn> suspend_txn_;
// Used to receive messages from |SysmemSecureMemServer|, e.g. the server has stopped.
async_patterns::Receiver<AmlogicSecureMemDevice> receiver_;
};
} // namespace amlogic_secure_mem
#endif // SRC_DEVICES_SECUREMEM_DRIVERS_AML_SECUREMEM_DEVICE_H_