// 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.

#include "device.h"

#include <lib/async/default.h>
#include <zircon/errors.h>
#include <zircon/syscalls/object.h>

#include <array>
#include <cinttypes>
#include <memory>

#include <ddk/debug.h>
#include <ddk/platform-defs.h>
#include <ddktl/fidl.h>
#include <ddktl/protocol/composite.h>
#include <ddktl/protocol/platform/device.h>
#include <ddktl/protocol/sysmem.h>

#include "log.h"
#include "src/devices/securemem/drivers/aml-securemem/aml-securemem-bind.h"

namespace amlogic_secure_mem {

zx_status_t AmlogicSecureMemDevice::Create(void* ctx, zx_device_t* parent) {
  std::unique_ptr<AmlogicSecureMemDevice> sec_mem(new AmlogicSecureMemDevice(parent));

  zx_status_t status = sec_mem->Bind();
  if (status == ZX_OK) {
    // devmgr should now own the lifetime
    __UNUSED auto ptr = sec_mem.release();
  }

  return status;
}

zx_status_t AmlogicSecureMemDevice::Bind() {
  ddk_dispatcher_thread_ = thrd_current();
  ddk_loop_closure_queue_.SetDispatcher(async_get_default_dispatcher(), ddk_dispatcher_thread_);

  zx_status_t status = ZX_OK;

  ddk::CompositeProtocolClient composite(parent());
  if (!composite.is_valid()) {
    LOG(ERROR, "Unable to get composite protocol");
    return status;
  }

  status = ddk::PDevProtocolClient::CreateFromComposite(
      composite, "ddk.protocol.platform.device.PDev", &pdev_proto_client_);
  if (status != ZX_OK) {
    LOG(ERROR, "Unable to get pdev protocol - status: %d", status);
    return status;
  }

  status =
      ddk::SysmemProtocolClient::CreateFromComposite(composite, "sysmem", &sysmem_proto_client_);
  if (status != ZX_OK) {
    LOG(ERROR, "Unable to get sysmem protocol - status: %d", status);
    return status;
  }

  status = ddk::TeeProtocolClient::CreateFromComposite(composite, "tee", &tee_proto_client_);
  if (status != ZX_OK) {
    LOG(ERROR, "ddk::TeeProtocolClient::CreateFromDevice() failed - status: %d", status);
    return status;
  }

  // See note on the constraints of |bti_| in the header.
  constexpr uint32_t kBtiIndex = 0;
  status = pdev_proto_client_.GetBti(kBtiIndex, &bti_);
  if (status != ZX_OK) {
    LOG(ERROR, "Unable to get bti handle - status: %d", status);
    return status;
  }

  status = CreateAndServeSysmemTee();
  if (status != ZX_OK) {
    LOG(ERROR, "CreateAndServeSysmemTee() failed - status: %d", status);
    return status;
  }

  status = DdkAdd(kDeviceName);
  if (status != ZX_OK) {
    LOG(ERROR, "Failed to add device");
    return status;
  }

  return status;
}

zx_status_t AmlogicSecureMemDevice::DdkMessage(fidl_incoming_msg_t* msg, fidl_txn_t* txn) {
  DdkTransaction transaction(txn);
  llcpp::fuchsia::hardware::securemem::Device::Dispatch(this, msg, &transaction);
  return transaction.Status();
}

// TODO(fxbug.dev/36888): Determine if we only ever use mexec to reboot from zedboot into a
// netboot(ed) image. Iff so, we could avoid some complexity here by not loading aml-securemem in
// zedboot, and not handling suspend(mexec) here, and not having UnregisterSecureMem().
void AmlogicSecureMemDevice::DdkSuspend(ddk::SuspendTxn txn) {
  LOG(DEBUG, "aml-securemem: begin DdkSuspend() - Suspend Reason: %d", txn.suspend_reason());

  if ((txn.suspend_reason() & DEVICE_MASK_SUSPEND_REASON) != DEVICE_SUSPEND_REASON_MEXEC) {
    // When a driver doesn't set a suspend function, the default impl returns
    // ZX_OK.
    txn.Reply(ZX_OK, txn.requested_state());
    return;
  }

  // Sysmem loads first (by design, to maximize chance of getting contiguous
  // memory), and aml-securemem depends on sysmem.  This means aml-securemem
  // will suspend before sysmem, so we have aml-securemem clean up secure memory
  // during its suspend (instead of sysmem trying to call aml-securemem after
  // aml-securemem has already suspended).
  ZX_DEBUG_ASSERT((txn.suspend_reason() & DEVICE_MASK_SUSPEND_REASON) ==
                  DEVICE_SUSPEND_REASON_MEXEC);

  if (sysmem_secure_mem_server_) {
    is_suspend_mexec_ = true;

    // We'd like this to be able to suspend async, but instead since DdkSuspend() is a sync call, we
    // have to pump the ddk_loop_closure_queue_ below (so far).
    sysmem_secure_mem_server_->StopAsync();

    // TODO(dustingreen): If DdkSuspend() becomes async, consider not running closures directly
    // here.  Or, if llcpp server binding permits unbind by an owner of the binding without
    // requiring the whole dispatcher to shutdown, consider not running closures directly here.
    while (sysmem_secure_mem_server_) {
      ddk_loop_closure_queue_.RunOneHere();
    }
  }

  LOG(DEBUG, "aml-securemem: end DdkSuspend()");
  txn.Reply(ZX_OK, txn.requested_state());
}

void AmlogicSecureMemDevice::GetSecureMemoryPhysicalAddress(
    zx::vmo secure_mem, GetSecureMemoryPhysicalAddressCompleter::Sync& completer) {
  auto result = GetSecureMemoryPhysicalAddress(std::move(secure_mem));
  if (result.is_error()) {
    completer.Reply(result.error(), static_cast<zx_paddr_t>(0));
  }

  completer.Reply(ZX_OK, result.value());
}

fit::result<zx_paddr_t, zx_status_t> AmlogicSecureMemDevice::GetSecureMemoryPhysicalAddress(
    zx::vmo secure_mem) {
  ZX_DEBUG_ASSERT(secure_mem.is_valid());
  ZX_ASSERT(bti_.is_valid());

  // Validate that the VMO handle passed meets additional constraints.
  zx_info_vmo_t secure_mem_info;
  zx_status_t status = secure_mem.get_info(ZX_INFO_VMO, reinterpret_cast<void*>(&secure_mem_info),
                                           sizeof(secure_mem_info), nullptr, nullptr);
  if (status != ZX_OK) {
    LOG(ERROR, "Failed to get VMO info - status: %d", status);
    return fit::error(status);
  }

  // Only allow pinning on VMOs that are contiguous.
  if ((secure_mem_info.flags & ZX_INFO_VMO_CONTIGUOUS) != ZX_INFO_VMO_CONTIGUOUS) {
    LOG(ERROR, "Received non-contiguous VMO type to pin");
    return fit::error(ZX_ERR_WRONG_TYPE);
  }

  // Pin the VMO to get the physical address.
  zx_paddr_t paddr;
  zx::pmt pmt;
  status = bti_.pin(ZX_BTI_CONTIGUOUS | ZX_BTI_PERM_READ, secure_mem, 0 /* offset */,
                    secure_mem_info.size_bytes, &paddr, 1u, &pmt);
  if (status != ZX_OK) {
    LOG(ERROR, "Failed to pin memory - status: %d", status);
    return fit::error(status);
  }

  // Unpinning the PMT should never fail
  status = pmt.unpin();
  ZX_DEBUG_ASSERT(status == ZX_OK);

  return fit::ok(paddr);
}

zx_status_t AmlogicSecureMemDevice::CreateAndServeSysmemTee() {
  ZX_DEBUG_ASSERT(tee_proto_client_.is_valid());
  zx::channel tee_device_client;
  zx::channel tee_device_server;
  zx_status_t status = zx::channel::create(0, &tee_device_client, &tee_device_server);
  if (status != ZX_OK) {
    LOG(ERROR, "optee: failed to create fuchsia.tee.Device channels - status: %d", status);
    return status;
  }
  constexpr zx_handle_t kNoServiceProvider = ZX_HANDLE_INVALID;
  status = tee_proto_client_.Connect(std::move(tee_device_server), zx::channel(kNoServiceProvider));
  if (status != ZX_OK) {
    LOG(ERROR, "optee: tee_client_.Connect() failed - status: %d", status);
    return status;
  }
  sysmem_secure_mem_server_.emplace(ddk_dispatcher_thread_, std::move(tee_device_client));
  zx::channel sysmem_secure_mem_client;
  zx::channel sysmem_secure_mem_server;
  status = zx::channel::create(0, &sysmem_secure_mem_client, &sysmem_secure_mem_server);
  if (status != ZX_OK) {
    LOG(ERROR, "failed to create sysmem tee channels - status: %d", status);
    return status;
  }
  status = sysmem_secure_mem_server_->BindAsync(
      std::move(sysmem_secure_mem_server), &sysmem_secure_mem_server_thread_,
      [this](bool is_success) {
        ZX_DEBUG_ASSERT(thrd_current() == sysmem_secure_mem_server_thread_);
        ddk_loop_closure_queue_.Enqueue([this, is_success] {
          ZX_DEBUG_ASSERT(thrd_current() == ddk_dispatcher_thread_);
          // Else the current lambda wouldn't be running.
          ZX_DEBUG_ASSERT(sysmem_secure_mem_server_);
          if (!is_success) {
            // This unexpected loss of connection to sysmem should never happen.  Complain if it
            // does happen.
            //
            // TODO(dustingreen): Determine if there's a way to cause the aml-securemem's devhost
            // to get re-started cleanly.  Currently this is leaving the overall device in a state
            // where DRM playback will likely be impossible (we should never get here).
            //
            // We may or may not see this message, depending on whether the sysmem failure causes a
            // hard reboot first.
            LOG(ERROR, "fuchsia::sysmem::Tee channel close !is_success - DRM playback will fail");
          } else {
            // If is_success, that means the sysmem_secure_mem_server_ is being shut down
            // intentionally before any channel close.  So far, we only do this for suspend(mexec).
            // In this case, tell sysmem that all is well, before the
            // sysmem_secure_mem_server_.reset() below causes the channel to close (which sysmem
            // would otherwise intentionally interpret as justifying a hard reboot).
            ZX_DEBUG_ASSERT(is_suspend_mexec_);
            LOG(DEBUG, "calling sysmem_proto_client_.UnregisterSecureMem()...");
            zx_status_t status = sysmem_proto_client_.UnregisterSecureMem();
            LOG(DEBUG, "sysmem_proto_client_.UnregisterSecureMem() returned");
            if (status != ZX_OK) {
              // Ignore this failure here, but sysmem may panic if sysmem sees
              // sysmem_secure_mem_server_ channel close without seeing UnregisterSecureMem() first.
              LOG(ERROR,
                  "sysmem_proto_client_.UnregisterSecureMem() failed (ignoring here) - status: %d",
                  status);
            }
          }

          // Regardless of whether this is due to DdkSuspend() or unexpected channel closure, we
          // won't be serving the fuchsia::sysmem::Tee channel any more. The ~SysmemSecureMemServer
          // is designed to be called on the DDK thread.
          //
          // If DdkSuspend() is presently running, this lets it continue.
          sysmem_secure_mem_server_.reset();
          LOG(DEBUG, "Done serving fuchsia::sysmem::Tee");
          // TODO(dustingreen): If DdkSuspend() were async, we could potentially finish the suspend
          // here instead of pumping ddk_loop_closure_queue_ until !sysmem_secure_mem_server_.
          // Similar for an async DdkUnbind() (assuming that ever needs to be handled in this
          // driver).
        });
      });
  if (status != ZX_OK) {
    LOG(ERROR, "sysmem_secure_mem_server_->BindAsync() failed - status: %d", status);
    // When BindAsync() fails, we don't call StopAsync().
    sysmem_secure_mem_server_.reset();
    return status;
  }

  // Tell sysmem about the fidl::sysmem::Tee channel that sysmem will use (async) to configure
  // secure memory ranges.  Sysmem won't fidl call back during this banjo call.
  LOG(DEBUG, "calling sysmem_proto_client_.RegisterSecureMem()...");
  status = sysmem_proto_client_.RegisterSecureMem(std::move(sysmem_secure_mem_client));
  if (status != ZX_OK) {
    // In this case sysmem_secure_mem_server_ will get cleaned up when the channel close is noticed
    // soon.
    LOG(ERROR, "optee: Failed to RegisterSecureMem()");
    return status;
  }
  return ZX_OK;
}

static constexpr zx_driver_ops_t driver_ops = []() {
  zx_driver_ops_t ops = {};
  ops.version = DRIVER_OPS_VERSION;
  ops.bind = AmlogicSecureMemDevice::Create;
  return ops;
}();

}  // namespace amlogic_secure_mem

ZIRCON_DRIVER(amlogic_secure_mem, amlogic_secure_mem::driver_ops, "zircon", "0.1");
