#include "config.h"
#include "memory.h"
#include "driver_log.h"

/**
 * CONFIG_PHYS_OFFSET taken from /proc/iomem
 */
const PhysicalAddress kPossibleConfigPhysOffset[] = {
    0x0000000040000000ULL,  // A6+ EUR_OPEN
    0x0000000010000000ULL   // A6+ SEA, CHN
};

#define COUNT_OF(arr) (sizeof(arr) / sizeof(arr[0]))

static const uint64_t kInvalidOffset = (uint64_t)-1;

// Current memory configuration
static uint64_t g_phys_offset = kInvalidOffset;

PaTzResult KernelNextMemoryConfiguration(void) {
  static size_t counter = 0;

  if (g_phys_offset == kInvalidOffset) {
    counter = 0;
  } else if (counter >= COUNT_OF(kPossibleConfigPhysOffset) - 1) {
    LOG_E("All memory configuration is checked.\n");
    return PA_TZ_GENERAL_ERROR;
  } else {
    counter++;
  }

  g_phys_offset = kPossibleConfigPhysOffset[counter];
  LOG_D("Use PHYS_OFFSET[%d]: 0x%08x%08x\n", counter,
      (uint32_t)(g_phys_offset >> 32), (uint32_t)(g_phys_offset));

  return PA_TZ_SUCCESS;
}

PhysicalAddress KernelGetConfigPhysOffset() {
  return g_phys_offset;
}

PhysicalAddress KernelGetStartPhysAddr(void) {
  return g_phys_offset;
}