/*
 * Copyright 2024 Google LLC
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#ifndef MPACT_CHERIOT__CHERIOT_REGISTER_H_
#define MPACT_CHERIOT__CHERIOT_REGISTER_H_

// This file contains the definition of the Capability class used to implement
// the CHERI RiscV IoT capability.

#include <cstdint>
#include <string>
#include <utility>

#include "absl/status/status.h"
#include "absl/strings/string_view.h"
#include "mpact/sim/generic/register.h"

// This file defines the CHERI RiscV 64 bit capability register for use in
// a unified register file as described in CHERIoT.

namespace mpact {
namespace sim {
namespace cheriot {

class CheriotState;

class CheriotRegister : public generic::Register<uint32_t> {
 public:
  // Set of permission bits in uncompressed view.
  enum PermissionBits : uint32_t {
    kPermitNone = 0,
    kPermitGlobal = 1 << 0,
    kPermitLoadGlobal = 1 << 1,
    kPermitStore = 1 << 2,
    kPermitLoadMutable = 1 << 3,
    kPermitStoreLocalCapability = 1 << 4,
    kPermitLoad = 1 << 5,
    kPermitLoadStoreCapability = 1 << 6,
    kPermitAccessSystemRegisters = 1 << 7,
    kPermitExecute = 1 << 8,
    kPermitUnseal = 1 << 9,
    kPermitSeal = 1 << 10,
    kUserPerm0 = 1 << 11,
    kPermitMask = (1 << 12) - 1,
  };
  // In the compressed representation of the capability, the permission bits
  // are stored in one of the below compressed formats.
  enum PermissionFormats : uint32_t {
    kMemoryCapReadWrite,
    kMemoryCapReadOnly,
    kMemoryCapWriteOnly,
    kMemoryDataOnly,
    kExecutable,
    kSealing,
  };
  // Special object types.
  enum ObjectType : uint32_t {
    kUnsealed = 0,
    kSentry = 1,
    kInterruptDisablingSentry = 2,
    kInterruptEnablingSentry = 3,
    kInterruptDisablingReturnSentry = 4,
    kInterruptEnablingReturnSentry = 5,
    kSealedExecutable6 = 6,
    kSealedExecutable7 = 7,
    kReserved8 = 8,
    // 9-15 are sealed non-executable capabilities.
  };

  static constexpr uint32_t kNullCapability = 0;
  static constexpr unsigned kCapabilitySizeInBytes = 8;
  static constexpr unsigned kGranuleShift = 3;

  // Value type of this register class.
  using ValueType = uint32_t;

  // {msb, lsb} pairs of fields in the compressed capability.
  // Bit layout:
  // |3|3    2|2   2|2   1|1       |         |
  // |1|0    5|4   2|1   8|7      9|8       0|
  //  R  perm  otype  exp   base       top
  //
  static constexpr int kBase[2] = {8, 0};
  static constexpr int kTop[2] = {17, 9};
  static constexpr int kExponent[2] = {21, 18};
  static constexpr int kObjectType[2] = {24, 22};
  static constexpr int kPermissions[2] = {30, 25};
  static constexpr int kReserved[2] = {31, 31};

  // Constructor. Default constructors and assignment are disabled.
  CheriotRegister(generic::ArchState *state, absl::string_view name);
  CheriotRegister() = delete;
  CheriotRegister(const CheriotRegister &) = delete;
  CheriotRegister &operator=(const CheriotRegister &) = delete;

  // These functions set the capability register to a known state, either the
  // null capability, or one of the three root capabilities. All capabilities
  // have to be derived from a root capability.
  void ResetNull();
  void ResetMemoryRoot();
  void ResetExecuteRoot();
  void ResetSealingRoot();
  // Return true if the capability register has the given permission.
  bool HasPermission(uint32_t permission_bits) const {
    return (permissions() & permission_bits) != 0;
  }
  // Clears the capability as a null capability, but does not change the
  // address.
  void Clear();
  // Removes one or more permission from the current capability.
  void ClearPermissions(uint32_t permission_bits);
  // Clear the tag - invalidates the capability.
  void ClearTag();
  // Compute the bounds.
  std::pair<uint32_t, uint64_t> ComputeBounds();
  // Get the compressed representation of the capability.
  uint32_t Compress() const;
  // Expand the compressed capability representation.
  void Expand(uint32_t address, uint32_t compressed, bool tag);
  // If the address is out of range, invalidate the tag.
  void Validate();
  // Return true if the current capability is valid, i.e., tag is true and
  // the address is in range.
  bool IsValid() const;
  // Is representable.
  bool IsRepresentable() const;
  // Seal (unseal) the current capability based on permissions and address field
  // in source. Returns ok status if the operation is successful.
  absl::Status Seal(const CheriotRegister &source, uint32_t obj_type);
  absl::Status Unseal(const CheriotRegister &source, uint32_t obj_type);
  // Returns true if the capability is sealed, i.e., that the object type is set
  // to a valid, non-reserved object type.
  bool IsSealed() const;
  // Returns true if the capability is unsealed, i.e., that the object type is
  // zero.
  bool IsUnsealed() const;
  // Returns true if the capability is a sentry.
  bool IsSentry() const;
  // Returns true if the capability is a backward sentry.
  bool IsBackwardSentry() const;
  // Clears the tag.
  void Invalidate() { set_tag(false); }
  // Set bounds, return true if they're precise, i.e., that the base and length
  // do not have to be rounded, false otherwise.
  bool SetBounds(uint32_t req_base, uint64_t req_length);
  // Return true if the address is in bounds of the capability.
  bool IsInBounds(uint32_t cap_address, uint32_t size) const {
    return (cap_address >= base()) &&
           (top() >= (uint64_t)cap_address + (uint64_t)size);
  }
  // Copy fields from other capability register.
  void CopyFrom(const CheriotRegister &other);
  // Equal operator.
  bool operator==(const CheriotRegister &other) const;
  bool IsMemoryEqual(const CheriotRegister &other) const;
  // Text representation.
  std::string AsString() const;
  // Update address with change to base and top as needed.
  void SetAddress(uint32_t address);
  // Accessors.
  bool tag() const { return is_null_ ? false : tag_; }
  void set_tag(bool tag) { tag_ = tag; }

  uint32_t address() const { return data_buffer()->Get<uint32_t>(0); }
  void set_address(uint32_t address) {
    data_buffer()->Set<uint32_t>(0, address);
    Validate();
  }

  uint64_t top() const { return is_null_ ? address() & ~0x1ffULL : top_; }
  uint32_t base() const { return is_null_ ? address() & ~0x1ffULL : base_; }
  uint64_t length() const {
    // Length is only 33 bits, so mask off the value.
    return is_null_ ? 0 : (top_ - base_) & 0x1'ffff'ffffULL;
  }
  uint32_t exponent() const { return is_null_ ? 0 : exponent_; }
  uint32_t permissions() const { return is_null_ ? 0 : permissions_; }
  void set_permissions(uint32_t permissions) { permissions_ = permissions; }

  uint32_t object_type() const { return is_null_ ? 0 : object_type_; }
  void set_object_type(uint32_t object_type) {
    object_type_ = object_type & 0xf;
  }

  uint32_t reserved() const { return is_null_ ? 0 : reserved_; }
  void set_reserved(uint32_t reserved) { reserved_ = reserved & 0x1; }

  bool is_null() const { return is_null_; }
  void set_is_null() { is_null_ = true; }

 private:
  // These are the capabilities in each compressed capability permission format
  // that are writable.
  static constexpr uint32_t kWritableCapabilites[] = {
      /* kMemoryCapReadWrite */ kPermitGlobal | kPermitStoreLocalCapability |
          kPermitLoadMutable | kPermitLoadGlobal,
      /* kMemoryCapReadOnly */ kPermitGlobal | kPermitLoadMutable |
          kPermitLoadGlobal,
      /* kMemoryCapWriteOnly */ kPermitGlobal,
      /* kMemoryDataOnly */ kPermitGlobal | kPermitLoad | kPermitStore,
      /* kExecutable */ kPermitGlobal | kPermitAccessSystemRegisters |
          kPermitLoadMutable | kPermitLoadGlobal,
      /* kSealing */ kPermitGlobal | kUserPerm0 | kPermitSeal | kPermitUnseal,
  };

  // The different compressed capability permission formats have different sets
  // of implied capabilities.
  static constexpr uint32_t kImpliedCapabilities[] = {
      /* kMemoryCapReadWrite */ kPermitLoad | kPermitLoadStoreCapability |
          kPermitStore,
      /* kMemoryCapReadOnly */ kPermitLoad | kPermitLoadStoreCapability,
      /* kMemoryCapWriteOnly */ kPermitStore | kPermitLoadStoreCapability,
      /* kMemoryDataOnly */ 0,
      /* kExecutable */ kPermitExecute | kPermitLoad |
          kPermitLoadStoreCapability,
      /* kSealing */ 0,
  };

  // Decoding table for compressed permission formats.
  static constexpr PermissionFormats kPermissionFormat[] = {
      /* 00000 */ kSealing,
      /* 00001 */ kSealing,
      /* 00010 */ kSealing,
      /* 00011 */ kSealing,
      /* 00100 */ kSealing,
      /* 00101 */ kSealing,
      /* 00110 */ kSealing,
      /* 00111 */ kSealing,
      /* 01000 */ kExecutable,
      /* 01001 */ kExecutable,
      /* 01010 */ kExecutable,
      /* 01011 */ kExecutable,
      /* 01100 */ kExecutable,
      /* 01101 */ kExecutable,
      /* 01110 */ kExecutable,
      /* 01111 */ kExecutable,
      /* 10000 */ kMemoryCapWriteOnly,
      /* 10001 */ kMemoryDataOnly,
      /* 10010 */ kMemoryDataOnly,
      /* 10011 */ kMemoryDataOnly,
      /* 10100 */ kMemoryCapReadOnly,
      /* 10101 */ kMemoryCapReadOnly,
      /* 10110 */ kMemoryCapReadOnly,
      /* 10111 */ kMemoryCapReadOnly,
      /* 11000 */ kMemoryCapReadWrite,
      /* 11001 */ kMemoryCapReadWrite,
      /* 11010 */ kMemoryCapReadWrite,
      /* 11011 */ kMemoryCapReadWrite,
      /* 11100 */ kMemoryCapReadWrite,
      /* 11101 */ kMemoryCapReadWrite,
      /* 11110 */ kMemoryCapReadWrite,
      /* 11111 */ kMemoryCapReadWrite,
  };

  // Expansion table for permissions in the sealing format.
  static constexpr uint32_t kExpandSealed[8] = {
      kPermitNone,
      kPermitUnseal,
      kPermitSeal,
      kPermitUnseal | kPermitSeal,
      kUserPerm0,
      kUserPerm0 | kPermitUnseal,
      kUserPerm0 | kPermitSeal,
      kUserPerm0 | kPermitUnseal | kPermitSeal,
  };
  // Expansion table for permissions in the executable format.
  static constexpr uint32_t kExpandExecutable[8] = {
      kPermitNone,
      kPermitLoadGlobal,
      kPermitLoadMutable,
      kPermitLoadMutable | kPermitLoadGlobal,
      kPermitAccessSystemRegisters,
      kPermitAccessSystemRegisters | kPermitLoadGlobal,
      kPermitAccessSystemRegisters | kPermitLoadMutable,
      kPermitAccessSystemRegisters | kPermitLoadMutable | kPermitLoadGlobal,
  };
  // Expansion table for permissions in the memory data only format.
  static constexpr uint32_t kExpandMemoryDataOnly[4] = {
      kPermitNone,
      kPermitStore,
      kPermitLoad,
      kPermitStore | kPermitLoad,
  };
  // Expansion table for permissions in the memory cap read only format.
  static constexpr uint32_t kExpandMemoryCapReadOnly[4] = {
      kPermitNone,
      kPermitLoadGlobal,
      kPermitLoadMutable,
      kPermitLoadMutable | kPermitLoadGlobal,
  };
  // Expansion table for permissions in the memory cap read/write format.
  static constexpr uint32_t kExpandMemoryCapReadWrite[8] = {
      kPermitNone,
      kPermitLoadGlobal,
      kPermitLoadMutable,
      kPermitLoadMutable | kPermitLoadGlobal,
      kPermitStoreLocalCapability,
      kPermitStoreLocalCapability | kPermitLoadGlobal,
      kPermitStoreLocalCapability | kPermitLoadMutable,
      kPermitStoreLocalCapability | kPermitLoadMutable | kPermitLoadGlobal,
  };
  // Get the permission format based on the current permissions.
  PermissionFormats GetPermissionFormat() const;
  // Return the current permissions in compressed form.
  uint32_t CompressPermissions() const;
  // Return the expanded view of the given compressed form of permissions.
  uint32_t ExpandPermissions(uint32_t compressed) const;

  // If top or base is changed, set is_dirty_ so that the values get properly
  // compressed if written to memory.
  void set_top(uint64_t top) {
    top_ = top;
    is_dirty_ = true;
  }
  void set_base(uint32_t base) {
    base_ = base;
    is_dirty_ = true;
  }

  PermissionFormats permissions_format() const { return permissions_format_; }
  void set_permissions_format(PermissionFormats format) {
    permissions_format_ = format;
  }
  bool tag_ = false;
  uint64_t top_;
  uint32_t base_;
  // Stores the 12 permissions.
  uint32_t permissions_;
  PermissionFormats permissions_format_;
  // Stores the 3 bit object type.
  uint32_t object_type_;
  uint32_t reserved_;
  bool is_dirty_ = false;
  bool is_null_ = false;
  uint32_t raw_ = 0xdeadbeef;
  uint32_t exponent_ = 0;
};

}  // namespace cheriot
}  // namespace sim
}  // namespace mpact

#endif  // MPACT_CHERIOT__CHERIOT_REGISTER_H_
