// Copyright 2021 The Fuchsia Authors
//
// Use of this source code is governed by a MIT-style
// license that can be found in the LICENSE file or at
// https://opensource.org/licenses/MIT

#ifndef ZIRCON_KERNEL_PHYS_LIB_MEMALLOC_INCLUDE_LIB_MEMALLOC_RANGE_H_
#define ZIRCON_KERNEL_PHYS_LIB_MEMALLOC_INCLUDE_LIB_MEMALLOC_RANGE_H_

#include <lib/fit/function.h>
#include <lib/stdcompat/span.h>
#include <zircon/boot/image.h>

#include <algorithm>
#include <array>
#include <string_view>

namespace memalloc {

constexpr uint64_t kMinExtendedTypeValue =
    static_cast<uint64_t>(std::numeric_limits<uint32_t>::max()) + 1;

// The type of a physical memory range. Represented by 64 bits, the lower 2^32
// values in the space are reserved for memory range types defined in the ZBI
// spec, the "base types"; the types in the upper half are referred to as
// "extended types", and increment from kMinExtendedTypeValue in value.
//
// As is detailed in the ZBI spec regarding overlaps, among the base types,
// kReserved and kPeripheral ranges have the highest precedence, in that order.
// Further, by definition here, an extended type is only permitted to overlap
// with kFreeRam or the same type.
enum class Type : uint64_t {
  //
  // ZBI memory range types:
  //

  kFreeRam = ZBI_MEM_RANGE_RAM,
  kPeripheral = ZBI_MEM_RANGE_PERIPHERAL,
  kReserved = ZBI_MEM_RANGE_RESERVED,

  //
  // Extended types:
  //

  // Reserved for internal bookkeeping.
  kPoolBookkeeping = kMinExtendedTypeValue,

  // The phys kernel memory image.
  kPhysKernel,

  // The kernel memory image.
  kKernel,

  // The kernel memory image at a fixed address of 1MiB.
  kFixedAddressKernel,

  // A (decompressed) STORAGE_KERNEL ZBI payload.
  kKernelStorage,

  // The data ZBI, as placed by the bootloader.
  kDataZbi,

  // Data structures related to legacy boot protocols.
  kLegacyBootData,

  // Identity-mapping page tables.
  kIdentityPageTables,

  // General scratch space used by the phys kernel, but that which is free for
  // the next kernel as of hand-off.
  kPhysScratch,

  // A generic allocated type for Pool tests.
  kPoolTestPayload,

  // A generic allocated type for ZBI tests.
  kZbiTestPayload,

  // Memory carved out for the kernel.test.ram.reserve boot option.
  kTestRamReserve,

  // Memory carved out for the ZBI_TYPE_NVRAM region.
  kNvram,

  // A placeholder value signifying the last extended type. It must not be used
  // as an actual type value.
  kMaxExtended,
};

static_assert(static_cast<uint64_t>(Type::kFreeRam) < kMinExtendedTypeValue);
static_assert(static_cast<uint64_t>(Type::kPeripheral) < kMinExtendedTypeValue);
static_assert(static_cast<uint64_t>(Type::kReserved) < kMinExtendedTypeValue);

constexpr uint64_t kMaxExtendedTypeValue = static_cast<uint64_t>(Type::kMaxExtended);
constexpr size_t kNumExtendedTypes = kMaxExtendedTypeValue - kMinExtendedTypeValue;
constexpr size_t kNumBaseTypes = 3;

std::string_view ToString(Type type);

constexpr bool IsExtendedType(Type type) {
  return static_cast<uint64_t>(type) >= kMinExtendedTypeValue;
}

// A memory range type that is layout-compatible to zbi_mem_range_t, but with
// the benefit of being able to use extended types.
struct Range {
  uint64_t addr;
  uint64_t size;
  Type type;

  // The end of the memory range. This method may only be called if addr + size
  // has been normalized to not overflow.
  constexpr uint64_t end() const { return addr + size; }

  constexpr bool operator==(const Range& other) const {
    return addr == other.addr && size == other.size && type == other.type;
  }
  constexpr bool operator!=(const Range& other) const { return !(*this == other); }

  // Gives a lexicographic order on Range.
  constexpr bool operator<(const Range& other) const {
    return addr < other.addr || (addr == other.addr && size < other.size);
  }
};

// We have constrained Type so that the ZBI memory type's value space
// identically embeds into the lower 2^32 values of Type; the upper 2^32 values
// is reserved for Type's extensions. Accordingly, in order to coherently
// recast a zbi_mem_range_t as a Range, the former's `reserved` field -
// which, layout-wise, corresponds to the upper half of Type - must be zeroed
// out.
cpp20::span<Range> AsRanges(cpp20::span<zbi_mem_range_t> ranges);

namespace internal {

// Effectively just a span and an iterator. This is used internally to iterate
// over a variable number of range arrays.
struct RangeIterationContext {
  RangeIterationContext() = default;

  // Lexicographically sorts the ranges on construction.
  explicit RangeIterationContext(cpp20::span<Range> ranges) : ranges_(ranges), it_(ranges.begin()) {
    std::sort(ranges_.begin(), ranges_.end());
  }

  cpp20::span<Range> ranges_;
  typename cpp20::span<Range>::iterator it_;
};

}  // namespace internal

}  // namespace memalloc

#endif  // ZIRCON_KERNEL_PHYS_LIB_MEMALLOC_INCLUDE_LIB_MEMALLOC_RANGE_H_
