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

#include "riscv/riscv_plic.h"

#include <cstdint>
#include <cstring>

#include "absl/log/log.h"
#include "absl/numeric/bits.h"
#include "absl/status/status.h"
#include "absl/strings/str_cat.h"
#include "absl/strings/string_view.h"
#include "re2/re2.h"

namespace mpact {
namespace sim {
namespace riscv {

RiscVPlic::RiscVPlic(int num_sources, int num_contexts)
    : num_sources_(num_sources), num_contexts_(num_contexts) {
  // Initialize the gateway info.
  gateway_info_ = new GatewayInfo[num_sources_];
  // Initialize the context interface.
  context_if_ = new RiscVPlicIrqInterface *[num_contexts_];
  context_irq_ = new bool[num_contexts_];
  for (int i = 0; i < num_contexts_; ++i) {
    context_if_[i] = nullptr;
    context_irq_[i] = false;
  }
  // Initialize the interrupt priority.
  interrupt_priority_ = new uint32_t[num_sources_];
  std::memset(interrupt_priority_, 0, sizeof(uint32_t) * num_sources_);
  // Initialize the interrupt pending bits.
  interrupt_pending_ = new uint32_t[num_sources_ / 32 + 1];
  std::memset(interrupt_pending_, 0,
              sizeof(uint32_t) * (num_sources_ / 32 + 1));
  // Initialize the interrupt enabled bits.
  interrupt_enabled_ = new uint32_t *[num_contexts_];
  for (int i = 0; i < num_contexts_; ++i) {
    interrupt_enabled_[i] = new uint32_t[num_sources_ / 32 + 1];
    std::memset(interrupt_enabled_[i], 0,
                sizeof(uint32_t) * (num_sources_ / 32 + 1));
  }
  // Initialize the priority threshold.
  priority_threshold_ = new uint32_t[num_contexts_];
  std::memset(priority_threshold_, 0, sizeof(uint32_t) * num_contexts_);
  // Initialize the interrupt claim/complete bits.
  interrupt_claim_complete_ = new uint32_t[num_contexts_];
  std::memset(interrupt_claim_complete_, 0, sizeof(uint32_t) * num_contexts_);
}

RiscVPlic::~RiscVPlic() {
  // Clean up all the allocated memory.
  delete[] gateway_info_;
  gateway_info_ = nullptr;
  delete[] context_if_;
  context_if_ = nullptr;
  delete[] context_irq_;
  context_irq_ = nullptr;
  delete[] interrupt_priority_;
  interrupt_priority_ = nullptr;
  delete[] interrupt_pending_;
  interrupt_pending_ = nullptr;
  for (int i = 0; i < num_contexts_; ++i) {
    delete[] interrupt_enabled_[i];
  }
  delete[] interrupt_enabled_;
  interrupt_enabled_ = nullptr;
  delete[] priority_threshold_;
  priority_threshold_ = nullptr;
  delete[] interrupt_claim_complete_;
  interrupt_claim_complete_ = nullptr;
}

absl::Status RiscVPlic::Configure(absl::string_view source_cfg,
                                  absl::string_view context_cfg) {
  // List of "<source>=<priority>;" items.
  RE2 re_source("^(\\d+)\\s*=\\s*(\\d+)\\s*(;|$)");
  int source;
  int priority;
  absl::string_view cfg = source_cfg;
  while (RE2::Consume(&cfg, re_source, &source, &priority)) {
    if (source >= num_sources_) {
      return absl::InvalidArgumentError(
          absl::StrCat("Invalid source number: ", source));
    }
    interrupt_priority_[source] = priority;
  }
  if (!cfg.empty()) {
    return absl::InvalidArgumentError(
        absl::StrCat("Invalid source configuration: ", cfg));
  }
  // List of "<context>=<source>,<threshold>,<enable>;" items.
  RE2 re_context("^(\\d+)\\s*=\\s*(\\d+)\\s*,\\s*");
  RE2 re_context_source("(\\d+)\\s*,\\s*(\\d)\\s*(,|;)\\s*");
  int context;
  int threshold;
  int enable;
  char terminator;
  cfg = context_cfg;
  while (RE2::Consume(&cfg, re_context, &context, &threshold)) {
    if (context >= num_contexts_) {
      return absl::InvalidArgumentError(
          absl::StrCat("Invalid context number: ", context));
    }
    priority_threshold_[context] = threshold;
    while (
        RE2::Consume(&cfg, re_context_source, &source, &enable, &terminator)) {
      if (source >= num_sources_) {
        return absl::InvalidArgumentError(
            absl::StrCat("Invalid source number: ", source));
      }
      source_to_context_.insert({source, context});
      context_to_source_.insert({context, source});
      int bit = source & 0x1f;
      int word = source / 32;
      uint32_t mask = ~(1 << bit);
      uint32_t value = interrupt_enabled_[context][word];
      value = (value & mask) | (enable << bit);
      interrupt_enabled_[context][word] = value;
      if (terminator == ';') break;
    }
  }
  if (!cfg.empty()) {
    return absl::InvalidArgumentError(
        absl::StrCat("Invalid context configuration: ", cfg));
  }
  return absl::OkStatus();
}

void RiscVPlic::SetInterrupt(int source, bool value, bool is_level) {
  // Make sure the source is in range.
  if ((source < 0) || (source >= num_sources_)) {
    LOG(WARNING) << "Invalid interrupt source: " << source;
    return;
  }
  // No action for clearing a non-level based interrupt.
  if (!value && !is_level) return;

  auto &info = gateway_info_[source];
  if (!info.ready || !value) {
    if (is_level) info.pending = value;
    return;
  }

  // If it is level based, latch the pending bit in the gateway.
  if (is_level) info.pending = true;

  // If the priority is 0, the interrupt is disabled.
  if (interrupt_priority_[source] == 0) return;

  // Accept the request, set ready to false to prevent any other requests
  // until this has been processed.
  info.ready = false;
  // Set the plic pending bit.
  SetPlicPendingInterrupt(source);
}

void RiscVPlic::SetPlicPendingInterrupt(int source) {
  if ((source <= 0) || (source >= num_sources_)) {
    LOG(ERROR) << "Invalid interrupt source: " << source;
    return;
  }
  // Return if source is already pending.
  if (IsPending(source)) return;
  // Get interrupt priority.
  auto priority = interrupt_priority_[source];
  // Return if source has priority 0.
  if (priority == 0) return;
  // Set source to pending.
  SetPending(source, true);
  // Iterate over all contexts that have this source enabled.
  auto [begin, end] = source_to_context_.equal_range(source);
  for (auto it = begin; it != end; ++it) {
    auto context = it->second;
    // If the priority is less or equal to the threshold, do not trigger the
    // interrupt.
    if (priority <= priority_threshold_[context]) continue;
    if (context_if_[context] == nullptr) continue;
    // Trigger the interrupt.
    context_if_[context]->SetIrq(true);
    context_irq_[context] = true;
  }
}

// Implementation of the memory load interface for reading memory mapped
// registers.
void RiscVPlic::Load(uint64_t address, DataBuffer *db, Instruction *inst,
                     ReferenceCount *context) {
  uint32_t offset = address & 0xff'ffff;
  switch (db->size<uint8_t>()) {
    case 1:
      db->Set<uint8_t>(0, static_cast<uint8_t>(Read(offset)));
      break;
    case 2:
      db->Set<uint16_t>(0, static_cast<uint16_t>(Read(offset)));
      break;
    case 4:
      db->Set<uint32_t>(0, static_cast<uint32_t>(Read(offset)));
      break;
    case 8:
      db->Set<uint32_t>(0, static_cast<uint32_t>(Read(offset)));
      db->Set<uint32_t>(1, static_cast<uint32_t>(Read(offset + 4)));
      break;
    default:
      ::memset(db->raw_ptr(), 0, sizeof(db->size<uint8_t>()));
      break;
  }
  // Execute the instruction to process and write back the load data.
  if (nullptr != inst) {
    if (db->latency() > 0) {
      inst->IncRef();
      if (context != nullptr) context->IncRef();
      inst->state()->function_delay_line()->Add(db->latency(),
                                                [inst, context]() {
                                                  inst->Execute(context);
                                                  if (context != nullptr)
                                                    context->DecRef();
                                                  inst->DecRef();
                                                });
    } else {
      inst->Execute(context);
    }
  }
}

// No support for vector loads.
void RiscVPlic::Load(DataBuffer *address_db, DataBuffer *mask_db, int el_size,
                     DataBuffer *db, Instruction *inst,
                     ReferenceCount *context) {
  LOG(FATAL) << "RiscVPlic does not support vector loads";
}

// Implementation of memory store interface to support writes to memory mapped
// registers.
void RiscVPlic::Store(uint64_t address, DataBuffer *db) {
  uint32_t offset = address & 0xff'ffff;
  switch (db->size<uint8_t>()) {
    case 1:
      return Write(offset, static_cast<uint32_t>(db->Get<uint8_t>(0)));
    case 2:
      return Write(offset, static_cast<uint32_t>(db->Get<uint16_t>(0)));
    case 4:
      return Write(offset, static_cast<uint32_t>(db->Get<uint32_t>(0)));
    case 8:
      return Write(offset, static_cast<uint32_t>(db->Get<uint32_t>(0)));
      return Write(offset + 4, static_cast<uint32_t>(db->Get<uint32_t>(1)));
    default:
      return;
  }
}

void RiscVPlic::SetContext(int context_no, RiscVPlicIrqInterface *context_if) {
  context_if_[context_no] = context_if;
}

// No support for vector stores.
void RiscVPlic::Store(DataBuffer *address, DataBuffer *mask, int el_size,
                      DataBuffer *db) {
  LOG(FATAL) << "RiscVPlic does not support vector stores";
}

uint32_t RiscVPlic::Read(uint32_t offset) {
  uint32_t value = 0;
  // Interrupt priority bit by source.
  if (offset < 0x00'1000) {
    value = interrupt_priority_[offset >> 2];
    return value;
  }

  // Interrupt pending bits by source/
  if (offset < 0x00'2000) {
    offset -= 0x00'1000;
    if (offset > (num_sources_ / 32)) {
      LOG(WARNING) << "Invalid offset: " << offset;
      return 0;
    }
    value = interrupt_pending_[offset];
    return value;
  }

  // Interrupt enable bits for sources by context.
  if (offset < 0x20'0000) {
    offset -= 0x00'2000;
    int context = offset >> 7;
    // Get the context id.
    if (context >= num_contexts_) {
      LOG(ERROR) << "Invalid context number: " << context;
      return 0;
    }
    // Get the word index in the source dimension.
    int word = offset & 0x7f;
    if (word * 32 >= num_sources_ + 32) {
      LOG(ERROR) << "Invalid source number";
      return 0;
    }
    value = interrupt_enabled_[context][word];
    return value;
  }

  // Interrupt priority threshold and claim/complete.
  // Get context id.
  offset -= 0x20'0000;
  int context = offset >> 12;
  if (context >= num_contexts_) {
    LOG(ERROR) << "Invalid context number: " << context;
    return 0;
  }
  auto reg_id = offset & 0xfff;
  switch (reg_id) {
    case 0x0:
      // Priority threshold.
      value = priority_threshold_[context];
      return value;
    case 0x4:
      // Claim/complete interrupt.
      value = ClaimInterrupt(context);
      return value;
    default:
      LOG(ERROR) << "Invalid offset: " << offset;
      break;
  }
  return value;
}

void RiscVPlic::Write(uint32_t offset, uint32_t value) {
  // Interrupt priority bit by source.
  if (offset < 0x00'1000) {
    int source = offset >> 3;
    if (source >= num_sources_) {
      LOG(ERROR) << "Invalid source number: " << source;
      return;
    }
    uint32_t prev = interrupt_priority_[source];
    interrupt_priority_[source] = value;
    // If the priority is being changed from 0 to non-zero, see if there is a
    // pending level based interrupt, and if so, set the plic pending bit.
    if (prev == 0 && value != 0) {
      auto &info = gateway_info_[source];
      if (info.ready && info.pending) {
        SetPlicPendingInterrupt(source);
      }
    }
    return;
  }

  // Interrupt pending bits.
  if (offset < 0x00'2000) {
    offset -= 0x00'1000;
    if (offset > (num_sources_ / 32)) {
      LOG(WARNING) << "Invalid offset: " << offset;
      return;
    }
    uint32_t prev = interrupt_pending_[offset];
    interrupt_pending_[offset] = value;
    // Determine which bits are being set.
    uint32_t bits_set = (value ^ prev) & value;
    // Trigger interrupts for any of the newly set pending bits.
    while (bits_set != 0) {
      int bit = absl::countr_zero(bits_set);
      int source = offset * 32 + bit;
      bits_set &= ~(1 << bit);
      auto [begin, end] = source_to_context_.equal_range(source);
      for (auto it = begin; it != end; ++it) {
        auto context = it->second;
        // If the context IRQ line is not already set, see if the priority is
        // above the threshold, and if so, set the IRQ line.
        if (!context_irq_[context]) {
          // If the priority is less or equal to the threshold, do not trigger
          // the interrupt.
          if (interrupt_priority_[source] <= priority_threshold_[context])
            continue;
          if (context_if_[context] == nullptr) {
            LOG(ERROR) << "No context interface for context " << context;
            continue;
          }
          // Trigger the interrupt.
          context_if_[context]->SetIrq(true);
          context_irq_[context] = true;
        }
      }
    }
    return;
  }

  // Interrupt enable bits for sources by context.
  if (offset < 0x20'0000) {
    offset -= 0x00'2000;
    // Convert from word address to index.
    offset >>= 2;
    // Get the word index in the source dimension.
    int word = (offset >> 2) & 0x1f;
    // Get the context id.
    int context = offset >> 7;
    uint32_t prev = interrupt_enabled_[context][word];
    // Determine which bits are being set.
    uint32_t bits_set = (value ^ prev) & value;
    uint32_t bits_cleared = (value ^ prev) & ~value;
    // Update the enable bits.
    interrupt_enabled_[context][word] = value;
    // Iterate over the set bits and add them to the source/context maps.
    while (bits_set != 0) {
      int bit = absl::countr_zero(bits_set);
      int source = word * 32 + bit;
      source_to_context_.insert({source, context});
      context_to_source_.insert({context, source});
      bits_set &= ~(1 << bit);
      if (context_if_[context] == nullptr) {
        LOG(ERROR) << "No context interface for context " << context;
        continue;
      }
      // If there is no pending IRQ for this context, and the priority is
      // above the threshold, set the IRQ.
      if (!context_irq_[context]) {
        if (interrupt_priority_[source] > priority_threshold_[context]) {
          context_irq_[context] = true;
          context_if_[context]->SetIrq(true);
        }
      }
    }
    // Iterate over the cleared bits and erase them from the source/context
    // maps.
    while (bits_cleared != 0) {
      int bit = absl::countr_zero(bits_cleared);
      int source = word * 32 + bit;
      auto [s2c_begin, s2c_end] = source_to_context_.equal_range(source);
      for (auto s2c_it = s2c_begin; s2c_it != s2c_end; ++s2c_it) {
        if (s2c_it->second == context) {
          source_to_context_.erase(s2c_it);
          break;
        }
      }
      auto [c2s_begin, c2s_end] = context_to_source_.equal_range(context);
      for (auto c2s_it = c2s_begin; c2s_it != c2s_end; ++c2s_it) {
        if (c2s_it->second == source) {
          context_to_source_.erase(c2s_it);
          break;
        }
      }
      bits_cleared &= ~(1 << bit);
    }
    return;
  }

  offset -= 0x20'0000;
  // Interrupt priority threshold and claim/complete.
  // Get context id.
  int context = offset >> 12;
  if (context >= num_contexts_) {
    LOG(ERROR) << "Invalid context number: " << context;
    return;
  }
  auto reg_id = offset & 0xfff;
  switch (reg_id) {
    case 0x0: {
      // Priority threshold.
      uint32_t prev = priority_threshold_[context];
      priority_threshold_[context] = value;
      if (value < prev) {
        // If the priority threshold is being lowered and there is no active
        // interrupt, see if there is a pending interrupt for this context,
        // and if so, set the IRQ.
        if (!context_irq_[context]) {
          if (context_if_[context] == nullptr) {
            LOG(ERROR) << "No context interface for context " << context;
            return;
          }
          auto [begin, end] = context_to_source_.equal_range(context);
          for (auto it = begin; it != end; ++it) {
            if (interrupt_priority_[it->second] > value) {
              context_irq_[context] = true;
              context_if_[context]->SetIrq(true);
              break;
            }
          }
        }
      }
      return;
    }
    case 0x4:
      // Claim/complete interrupt.
      CompleteInterrupt(context, value);
      return;
    default:
      LOG(ERROR) << "Invalid offset: " << offset;
      break;
  }
}

uint32_t RiscVPlic::ClaimInterrupt(int context) {
  if (context < 0 || context >= num_contexts_) return 0;
  uint32_t id = 0;
  int priority = 0;
  // Find the id of the highest-priority pending interrupt for this context.
  auto [begin, end] = context_to_source_.equal_range(context);
  int count = 0;
  int source = 0;
  for (auto it = begin; it != end; ++it) {
    source = it->second;
    // If the source is not pending, skip it.
    if (!IsPending(source)) continue;
    // If the priority is less or equal to the current priority, skip it.
    if (priority > interrupt_priority_[source]) continue;
    // If the priority is the same, the lower id is chosen, so if the new
    // source is greater than the current, go to the next.
    if ((priority == interrupt_priority_[source]) && (id < source)) continue;
    id = source;
    priority = interrupt_priority_[source];
    count++;
  }
  if (id != 0) {
    SetPending(id, false);
    interrupt_claim_complete_[context] = id;
    count--;
  }
  if (count == 0) {
    // If there are zero remaining pending interrupts, clear the IRQ line.
    context_if_[context]->SetIrq(false);
    context_irq_[context] = false;
  }
  return id;
}

void RiscVPlic::CompleteInterrupt(int context, uint32_t id) {
  if (context < 0 || context >= num_contexts_) return;
  // Check if id is in the set of enabled sources for context.
  auto [begin, end] = context_to_source_.equal_range(context);
  bool found = false;
  for (auto it = begin; it != end; ++it) {
    if (it->second == id) {
      found = true;
      break;
    }
  }
  if (!found) return;
  // The PLIC spec only requires that the id be valid for the set of
  // interrupts enabled for the context, not that it matches the
  // interrupt_claim_complete_ value.
  auto source = interrupt_claim_complete_[context];
  interrupt_claim_complete_[context] = 0;
  auto &info = gateway_info_[source];
  // Check to see if there's a pending level based interrupt w priority > 0.
  if (info.pending && (interrupt_priority_[source] > 0)) {
    // Set the plic pending bit but no need to set the ready bit as this will
    // be forwarded to the plic core right away.
    SetPlicPendingInterrupt(source);
    return;
  }
  // Set the gateway ready bit to true.
  info.ready = true;
}

void RiscVPlic::SetPending(int source, bool value) {
  int word = source >> 5;
  int bit = source & 0x1f;
  if (value) {
    interrupt_pending_[word] |= 1 << bit;
  } else {
    interrupt_pending_[word] &= ~(1 << bit);
  }
}

bool RiscVPlic::IsPending(int source) {
  int word = source >> 5;
  int bit = source & 0x1f;
  return (interrupt_pending_[word] & (1 << bit)) != 0;
}

RiscVPlicSourceInterface::RiscVPlicSourceInterface(RiscVPlic *plic, int source,
                                                   bool is_level)
    : plic_(plic), source_(source), is_level_(is_level) {}

}  // namespace riscv
}  // namespace sim
}  // namespace mpact
