blob: 587863f37b39e4ac5f84b0e5ade8f3b6902c7222 [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 <fuchsia/hardware/securemem/llcpp/fidl.h>
#include <lib/fit/result.h>
#include <lib/zx/bti.h>
#include <threads.h>
#include <zircon/types.h>
#include <optional>
#include <ddk/protocol/platform/device.h>
#include <ddk/protocol/sysmem.h>
#include <ddktl/device.h>
#include <ddktl/protocol/empty-protocol.h>
#include <ddktl/protocol/platform/device.h>
#include <ddktl/protocol/sysmem.h>
#include <ddktl/protocol/tee.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, ddk::Suspendable>;
class AmlogicSecureMemDevice : public AmlogicSecureMemDeviceBase,
public ::llcpp::fuchsia::hardware::securemem::Device::Interface,
public ddk::EmptyProtocol<ZX_PROTOCOL_SECURE_MEM> {
public:
static zx_status_t Create(void* ctx, zx_device_t* device);
zx_status_t Bind();
zx_status_t DdkOpen(zx_device_t** out_dev, uint32_t flags);
zx_status_t DdkMessage(fidl_msg_t* msg, fidl_txn_t* parent);
void DdkSuspend(ddk::SuspendTxn txn);
void DdkRelease() { delete this; }
// LLCPP interface implementations
void GetSecureMemoryPhysicalAddress(
zx::vmo secure_mem, GetSecureMemoryPhysicalAddressCompleter::Sync completer) override;
fit::result<zx_paddr_t, zx_status_t> GetSecureMemoryPhysicalAddress(zx::vmo secure_mem);
private:
explicit AmlogicSecureMemDevice(zx_device_t* device) : AmlogicSecureMemDeviceBase(device) {}
zx_status_t CreateAndServeSysmemTee();
thrd_t ddk_dispatcher_thread_ = {};
ddk::PDevProtocolClient pdev_proto_client_;
ddk::SysmemProtocolClient sysmem_proto_client_;
ddk::TeeProtocolClient 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_;
// Created by ddk_dispatcher_thead_. Ownership transferred to sysmem_secure_mem_server_thread_ by
// successful BindAsync(). We use a separate thread because llcpp doesn't provide any way to
// force unbind other than dispatcher shutdown (client channel closing doesn't count). Since we
// can't shutdown the devhost's main dispatcher, we use a separate dispatcher and shutdown that
// dispatcher when we want to unbind.
//
// TODO(dustingreen): llcpp should provide a way to force unbind without shutdown of the whole
// dispatcher.
std::optional<SysmemSecureMemServer> sysmem_secure_mem_server_;
thrd_t sysmem_secure_mem_server_thread_ = {};
bool is_suspend_mexec_ = false;
// Last on purpose.
ClosureQueue ddk_loop_closure_queue_;
};
} // namespace amlogic_secure_mem
#endif // SRC_DEVICES_SECUREMEM_DRIVERS_AML_SECUREMEM_DEVICE_H_