// Copyright 2016 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_MISC_DRIVERS_TPM_TPM_H_
#define SRC_DEVICES_MISC_DRIVERS_TPM_TPM_H_

#include <lib/zircon-internal/thread_annotations.h>
#include <stddef.h>
#include <stdint.h>
#include <zircon/types.h>

#include <ddk/device.h>

#if __cplusplus

#include <memory>

#include <ddktl/device.h>
#include <ddktl/protocol/empty-protocol.h>
#include <fbl/mutex.h>

namespace tpm {

typedef uint8_t Locality;

// Abstraction over the hardware access mechanism.  The communication protocol
// relies on accessing certain hardware registers which have the same contents
// regardless of access mechanism.
class HardwareInterface {
 public:
  virtual ~HardwareInterface() {}

  // Return ZX_OK if the device represented by this interface is valid under
  // the interface's constraints.  This may perform IO to determine the
  // answer, and will be called before the device is made visible to the rest
  // of the system.
  virtual zx_status_t Validate() { return ZX_OK; }

  // Read/write the ACCESS register for the given locality
  virtual zx_status_t ReadAccess(Locality loc, uint8_t* access) = 0;
  virtual zx_status_t WriteAccess(Locality loc, uint8_t access) = 0;

  // Read/write the STS register for the given locality
  virtual zx_status_t ReadStatus(Locality loc, uint32_t* sts) = 0;
  virtual zx_status_t WriteStatus(Locality loc, uint32_t sts) = 0;

  // Read the DID_VID register, if present
  virtual zx_status_t ReadDidVid(uint16_t* vid, uint16_t* did) = 0;

  // Read/write from the DATA_FIFO register.  It is up to the caller to respect the
  // protocol's burstCount.
  virtual zx_status_t ReadDataFifo(Locality loc, uint8_t* buf, size_t len) = 0;
  virtual zx_status_t WriteDataFifo(Locality loc, const uint8_t* buf, size_t len) = 0;
};

class Device;
using DeviceType = ddk::Device<Device, ddk::UnbindableNew, ddk::Suspendable>;

class Device : public DeviceType, public ddk::EmptyProtocol<ZX_PROTOCOL_TPM> {
 public:
  Device(zx_device_t* parent, std::unique_ptr<HardwareInterface> iface);
  ~Device();

  static zx_status_t Create(void* ctx, zx_device_t* parent, std::unique_ptr<Device>* out);
  static zx_status_t CreateAndBind(void* ctx, zx_device_t* parent);
  static bool RunUnitTests(void* ctx, zx_device_t* parent, zx_handle_t channel);

  // Send the given command packet to the TPM and wait for a response.
  // |actual| is the number of bytes written into |resp|.
  zx_status_t ExecuteCmd(Locality loc, const uint8_t* cmd, size_t len, uint8_t* resp,
                         size_t max_len, size_t* actual);

  // Execute the GetRandom TPM command.
  zx_status_t GetRandom(void* buf, uint16_t count, size_t* actual);

  // DDK methods
  void DdkRelease();
  void DdkUnbindNew(ddk::UnbindTxn txn);
  void DdkSuspend(ddk::SuspendTxn txn);

  zx_status_t Init();
  zx_status_t Suspend(uint8_t requested_state, bool wakeup_enabled, uint8_t suspend_reason,
                      uint8_t* out_state);

 private:
  // Register this instance with devmgr and launch the deferred
  // initialization.
  zx_status_t Bind();

  // Deferred initialization of the device via a thread.  Once complete, this
  // marks the device as visible.
  static zx_status_t InitThread(void* device) {
    return reinterpret_cast<Device*>(device)->InitThread();
  }
  zx_status_t InitThread();

  // Send the given command packet to the TPM and wait for a response.
  // |actual| is the number of bytes written into |resp|.
  zx_status_t ExecuteCmdLocked(Locality loc, const uint8_t* cmd, size_t len, uint8_t* resp,
                               size_t max_len, size_t* actual) TA_REQ(lock_);

  // Request use of the given locality
  zx_status_t RequestLocalityLocked(Locality loc) TA_REQ(lock_);
  // Wait for access to the requested locality
  zx_status_t WaitForLocalityLocked(Locality loc) TA_REQ(lock_);
  // Release the given locality
  zx_status_t ReleaseLocalityLocked(Locality loc) TA_REQ(lock_);

  // Perform the transmit half of a command
  zx_status_t SendCmdLocked(Locality loc, const uint8_t* cmd, size_t len) TA_REQ(lock_);
  // Perform the receive half of a command.  |actual| will contain the total number of bytes in
  // the response, may be less than max_len.
  zx_status_t RecvRespLocked(Locality loc, uint8_t* resp, size_t max_len, size_t* actual)
      TA_REQ(lock_);

  // Issue a TPM_CC_SHUTDOWN with the given type
  zx_status_t ShutdownLocked(uint16_t type) TA_REQ(lock_);

  fbl::Mutex lock_;
  const std::unique_ptr<HardwareInterface> iface_;
};

enum tpm_result {
  TPM_SUCCESS = 0x0,
  TPM_BAD_PARAMETER = 0x3,
  TPM_DEACTIVATED = 0x6,
  TPM_DISABLED = 0x7,
  TPM_DISABLED_CMD = 0x8,
  TPM_FAIL = 0x9,
  TPM_BAD_ORDINAL = 0xa,
  TPM_RETRY = 0x800,
};

}  // namespace tpm

#endif  // __cplusplus

#endif  // SRC_DEVICES_MISC_DRIVERS_TPM_TPM_H_
