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

#include <lib/zx/vmar.h>
#include <lib/zx/vmo.h>
#include <limits.h>
#include <zircon/assert.h>
#include <zircon/syscalls.h>
#include <zircon/types.h>

#include <algorithm>
#include <vector>

#include <fbl/algorithm.h>
#include <perftest/perftest.h>

#include "assert.h"

namespace {

#define KB(n) ((n)*1024ull)
#define MB(n) (KB(n) * 1024ull)
#define GB(n) (MB(n) * 1024ull)

constexpr size_t kSize = MB(1);

struct Helper {
  Helper() {
    ASSERT_OK(zx::vmar::root_self()->allocate(ZX_VM_CAN_MAP_READ | ZX_VM_CAN_MAP_SPECIFIC, 0,
                                              GB(1), &vmar, &vmar_base));

    const uint64_t vmo_size = MB(4);
    ASSERT_OK(zx::vmo::create(vmo_size, 0, &vmo));

    // Write random contents to the VMO to ensure it has backing pages so that mappings will happen.
    std::vector<char> buffer(vmo_size);
    zx_cprng_draw(buffer.data(), buffer.size());

    ASSERT_OK(vmo.write(buffer.data(), 0, buffer.size()));
  }

  ~Helper() { vmar.destroy(); }

  // Cyclically maps the first chunk_size bytes of |vmo| into the |length| bytes
  // of vmar, starting from offset 0.   Mapping is done |chunk_size| bytes at a
  // time.  |chunk_size| and |length| must be multiples of PAGE_SIZE. As a
  // precondition, |vmar| should be empty.
  zx_status_t MapInChunks(size_t chunk_size, size_t length, bool force_into_mmu);

  zx::vmar vmar;
  zx::vmo vmo;
  uintptr_t vmar_base;
};

zx_status_t Helper::MapInChunks(size_t chunk_size, size_t length, bool force_into_mmu) {
  zx_status_t status;
  zx_vm_option_t flags = ZX_VM_SPECIFIC | ZX_VM_PERM_READ;
  if (force_into_mmu) {
    flags |= ZX_VM_MAP_RANGE;
  }

  for (size_t offset = 0; offset < length; offset += chunk_size) {
    uintptr_t addr;
    size_t len = std::min(chunk_size, length - offset);
    status = vmar.map(flags, offset, vmo, 0, len, &addr);
    if (status != ZX_OK) {
      return status;
    }
  }
  return ZX_OK;
}

// This attempts to measure the amount of time it takes to add and remove
// mappings through the kernel VM layer and the arch MMU layer.
bool MmuMapUnmapTest(perftest::RepeatState* state) {
  state->DeclareStep("map");
  state->DeclareStep("unmap");

  Helper helper;
  while (state->KeepRunning()) {
    // Map just under a large page at a time, to force small pages.  We map many
    // pages at once still, to exercise any optimizations the kernel may perform
    // for small contiguous mappings.
    ASSERT_OK(helper.MapInChunks(511 * KB(4), kSize,
                                 /* force_into_mmu */ true));

    state->NextStep();
    ASSERT_OK(helper.vmar.unmap(helper.vmar_base, kSize));
  }
  return true;
}

// This attempts to measure the amount of time it takes to add mappings in
// the kernel VM layer, page fault the mappings into the arch MMU layer, and
// then remove the mappings from both.
bool MmuMapUnmapWithFaultsTest(perftest::RepeatState* state) {
  state->DeclareStep("map");
  state->DeclareStep("fault_in");
  state->DeclareStep("unmap");

  Helper helper;
  while (state->KeepRunning()) {
    // Map just under a large page at a time, to force small pages.  We map many
    // pages at once still, to exercise any optimizations the kernel may perform
    // for small contiguous mappings.
    ASSERT_OK(helper.MapInChunks(511 * KB(4), kSize,
                                 /* force_into_mmu */ false));

    state->NextStep();
    // Read fault everything in
    auto p = reinterpret_cast<volatile uint8_t*>(helper.vmar_base);
    for (size_t offset = 0; offset < kSize; offset += PAGE_SIZE) {
      p[offset];
    }

    state->NextStep();
    ASSERT_OK(helper.vmar.unmap(helper.vmar_base, kSize));
  }
  return true;
}

void RegisterTests() {
  perftest::RegisterTest("Mmu/MapUnmap", MmuMapUnmapTest);
  perftest::RegisterTest("Mmu/MapUnmapWithFaults", MmuMapUnmapWithFaultsTest);
}
PERFTEST_CTOR(RegisterTests);

}  // namespace
