// 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 HARDWARE_STATUS_PAGE_H
#define HARDWARE_STATUS_PAGE_H

#include <lib/magma/util/short_macros.h>

#include <optional>

#include "address_space.h"
#include "gpu_mapping.h"
#include "types.h"

// There is a global HWSP for each engine command streamer, and a per-process
// HWSP for each context.  The layout of GHWSP and PPHWSP differs.
class GlobalHardwareStatusPage {
 public:
  GlobalHardwareStatusPage(EngineCommandStreamerId id, std::unique_ptr<GpuMapping> mapping)
      : id_(id), mapping_(std::move(mapping)) {
    if (!mapping_->buffer()->platform_buffer()->MapCpu(&cpu_addr_)) {
      DASSERT(false);
      cpu_addr_ = 0;
    }
  }

  EngineCommandStreamerId id() { return id_; }

  uint64_t gpu_addr() { return mapping_->gpu_addr(); }

  void write_sequence_number(uint32_t val) {
    write_general_purpose_offset(val, kSequenceNumberOffset);
  }

  uint32_t read_sequence_number() { return read_general_purpose_offset(kSequenceNumberOffset); }

  void InitContextStatusGen12();

  // Reads all available context status entries; if there are any, then |idle_out| is set
  // according to the most recent status.  Updates |read_index|.
  void ReadContextStatus(uint64_t& read_index, std::optional<bool>* idle_out);
  void ReadContextStatusGen12(uint64_t& read_index, std::optional<bool>* idle_out);

  // from intel-gfx-prm-osrc-kbl-vol02d-commandreference-structures.pdf pp.284-286
  // https://01.org/sites/default/files/documentation/intel-gfx-prm-osrc-tgl-vol02d-commandreference-structures_0.pdf
  // p.600
  static constexpr uint32_t kContextStatusStartOffset = 16 * sizeof(uint32_t);
  static constexpr uint32_t kContextStatusEndOffsetGen12 = 39 * sizeof(uint32_t);
  static constexpr uint32_t kLastWrittenContextStatusOffsetGen12 = 47 * sizeof(uint32_t);
  static constexpr uint32_t kGeneralPurposeStartOffset = 48 * sizeof(uint32_t);
  static constexpr uint32_t kGeneralPurposeEndOffset = 1023 * sizeof(uint32_t);

  static constexpr uint64_t kStatusQwordsGen12 = 12;
  static_assert(kStatusQwordsGen12 * sizeof(uint64_t) ==
                kContextStatusEndOffsetGen12 - kContextStatusStartOffset + sizeof(uint32_t));

  // Our definitions
  static constexpr uint32_t kSequenceNumberOffset = kGeneralPurposeStartOffset;
  static constexpr uint32_t kScratchOffset = kSequenceNumberOffset + sizeof(uint64_t);

 private:
  void write_general_purpose_offset(uint32_t val, uint32_t offset) {
    DASSERT((offset & 0x3) == 0);
    DASSERT(offset >= kGeneralPurposeStartOffset && offset <= kGeneralPurposeEndOffset);
    reinterpret_cast<uint32_t*>(cpu_addr_)[offset >> 2] = val;
  }

  uint32_t read_general_purpose_offset(uint32_t offset) {
    DASSERT((offset & 0x3) == 0);
    DASSERT(offset >= kGeneralPurposeStartOffset && offset <= kGeneralPurposeEndOffset);
    return reinterpret_cast<uint32_t*>(cpu_addr_)[offset >> 2];
  }

  void write_context_status_gen12(uint32_t offset, std::pair<uint32_t, uint32_t> val) {
    DASSERT((offset & 0x3) == 0);
    DASSERT(offset >= kContextStatusStartOffset && offset <= kContextStatusEndOffsetGen12);
    auto ptr = reinterpret_cast<volatile uint32_t*>(cpu_addr_);
    uint32_t index = offset >> 2;
    ptr[index] = val.first;
    ptr[index + 1] = val.second;
  }

  std::pair<uint32_t, uint32_t> read_context_status_gen12(uint32_t offset) {
    DASSERT((offset & 0x3) == 0);
    DASSERT(offset >= kContextStatusStartOffset && offset <= kContextStatusEndOffsetGen12);
    auto ptr = reinterpret_cast<volatile uint32_t*>(cpu_addr_);
    uint32_t index = offset >> 2;
    return {ptr[index], ptr[index + 1]};
  }

  EngineCommandStreamerId id_;
  std::unique_ptr<GpuMapping> mapping_;
  void* cpu_addr_;
};

#endif  // HARDWARE_STATUS_PAGE_H
