/*
 * Copyright © 2021 The Fuchsia Authors
 *
 * Permission is hereby granted, free of charge, to any person obtaining a
 * copy of this software and associated documentation files (the "Software"),
 * to deal in the Software without restriction, including without limitation
 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
 * and/or sell copies of the Software, and to permit persons to whom the
 * Software is furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice (including the next
 * paragraph) shall be included in all copies or substantial portions of the
 * Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
 * IN THE SOFTWARE.
 *
 */

#ifndef ADDRESS_SPACE_ALLOCATOR_H
#define ADDRESS_SPACE_ALLOCATOR_H

#include <assert.h>
#include <limits.h>

class AddressSpaceAllocator {
 public:
  // Constructs an address space ranging from address base to address base + size.
  AddressSpaceAllocator(uint64_t base, size_t size) : base_(base), size_(size) {
    assert(size > 0);
    assert(size <= UINT64_MAX - base);
  }

  virtual ~AddressSpaceAllocator() = default;

  uint64_t base() const { return base_; }
  size_t size() const { return size_; }

  // Allocates an address for a region of the given size and alignment, where alignment
  // is specified by 2 << align_pow2.
  // If alignment is less than a page than page alignment will be used.
  // On success returns true and addr_out is set; otherwise returns false.
  virtual bool Alloc(size_t size, uint8_t align_pow2, uint64_t* addr_out) = 0;

  // Frees an address that was previously allocated.
  virtual bool Free(uint64_t addr) = 0;

  // Returns true and the size of the region if mapped; otherwise returns false.
  virtual bool GetSize(uint64_t addr, size_t* size_out) = 0;

  static inline uint32_t GetPageSize() { return PAGE_SIZE; }

  static inline bool IsPageAligned(uint64_t val) { return (val & (GetPageSize() - 1)) == 0; }

  template <class T>
  static bool IsPow2(T v, T* exponent = nullptr) {
    uint32_t pow = 0;
    if (v == 0) {
      return false;
    }

    for (uint32_t count = 0; v != 0; count += 1) {
      if (v & 1) {
        if (pow != 0) {
          return false;
        }
        pow = count;
      }
      v >>= 1;
    }

    if (exponent != nullptr) {
      *exponent = pow;
    }

    return true;
  }

  static inline uint32_t PageShift() {
    uint32_t exponent = 0;
    assert(IsPow2(GetPageSize(), &exponent));

    return exponent;
  }

  // Note, alignment must be a power of 2
  template <class T>
  static inline T RoundUp(T val, T alignment) {
    assert(IsPow2(alignment));
    return ((val - 1) | (alignment - 1)) + 1;
  }

 private:
  uint64_t base_;
  size_t size_;
};

#endif  // ADDRESS_SPACE_ALLOCATOR_H
