#include <grub/dl.h>
#include <grub/cache.h>
#include <grub/arm/system.h>
#ifdef GRUB_MACHINE_UBOOT
#include <grub/uboot/uboot.h>
#include <grub/uboot/api_public.h>
#include <grub/mm.h>
#endif

/* This is only about cache architecture. It doesn't imply
   the CPU architecture.  */
static enum
  {
    ARCH_UNKNOWN,
    ARCH_ARMV5_WRITE_THROUGH,
    ARCH_ARMV6,
    ARCH_ARMV6_UNIFIED,
    ARCH_ARMV7
  } type = ARCH_UNKNOWN;

static int is_v6_mmu;

static grub_uint32_t grub_arch_cache_dlinesz;
static grub_uint32_t grub_arch_cache_ilinesz;
static grub_uint32_t grub_arch_cache_max_linesz;

/* Prototypes for asm functions.  */
void grub_arm_clean_dcache_range_armv6 (grub_addr_t start, grub_addr_t end,
					grub_addr_t dlinesz);
void grub_arm_clean_dcache_range_armv7 (grub_addr_t start, grub_addr_t end,
					grub_addr_t dlinesz);
void grub_arm_clean_dcache_range_poc_armv7 (grub_addr_t start, grub_addr_t end,
					    grub_addr_t dlinesz);
void grub_arm_invalidate_icache_range_armv6 (grub_addr_t start, grub_addr_t end,
					     grub_addr_t dlinesz);
void grub_arm_invalidate_icache_range_armv7 (grub_addr_t start, grub_addr_t end,
					     grub_addr_t dlinesz);
void grub_arm_disable_caches_mmu_armv6 (void);
void grub_arm_disable_caches_mmu_armv7 (void);
grub_uint32_t grub_arm_main_id (void);
grub_uint32_t grub_arm_cache_type (void);

static void
probe_caches (void)
{
  grub_uint32_t main_id, cache_type;

  /* Read main ID Register */
  main_id = grub_arm_main_id ();

  switch ((main_id >> 16) & 0xf)
    {
    case 0x3:
    case 0x4:
    case 0x5:
    case 0x6:
      is_v6_mmu = 0;
      break;
    case 0x7:
    case 0xf:
      is_v6_mmu = 1;
      break;
    default:
      grub_fatal ("Unsupported ARM ID 0x%x", main_id);
    }

  /* Read Cache Type Register */
  cache_type = grub_arm_cache_type ();

  switch (cache_type >> 24)
    {
    case 0x00:
    case 0x01:
      grub_arch_cache_dlinesz = 8 << ((cache_type >> 12) & 3);
      grub_arch_cache_ilinesz = 8 << (cache_type & 3);
      type = ARCH_ARMV5_WRITE_THROUGH;
      break;
    case 0x04:
    case 0x0a:
    case 0x0c:
    case 0x0e:
    case 0x1c:
      grub_arch_cache_dlinesz = 8 << ((cache_type >> 12) & 3);
      grub_arch_cache_ilinesz = 8 << (cache_type & 3);
      type = ARCH_ARMV6_UNIFIED;
      break;
    case 0x05:
    case 0x0b:
    case 0x0d:
    case 0x0f:
    case 0x1d:
      grub_arch_cache_dlinesz = 8 << ((cache_type >> 12) & 3);
      grub_arch_cache_ilinesz = 8 << (cache_type & 3);
      type = ARCH_ARMV6;
      break;
    case 0x80 ... 0x8f:
      grub_arch_cache_dlinesz = 4 << ((cache_type >> 16) & 0xf);
      grub_arch_cache_ilinesz = 4 << (cache_type & 0xf);
      type = ARCH_ARMV7;
      break;
    default:
      grub_fatal ("Unsupported cache type 0x%x", cache_type);
    }
  if (grub_arch_cache_dlinesz > grub_arch_cache_ilinesz)
    grub_arch_cache_max_linesz = grub_arch_cache_dlinesz;
  else
    grub_arch_cache_max_linesz = grub_arch_cache_ilinesz;
}

#ifdef GRUB_MACHINE_UBOOT

static void subdivide (grub_uint32_t *table, grub_uint32_t *subtable,
		       grub_uint32_t addr)
{
  grub_uint32_t j;
  addr = addr >> 20 << 20;
  table[addr >> 20] = (grub_addr_t) subtable | 1;
  for (j = 0; j < 256; j++)
    subtable[j] = addr | (j << 12)
      | (3 << 4) | (3 << 6) | (3 << 8) | (3 << 10)
      | (0 << 3) | (1 << 2) | 2;
}

void
grub_arm_enable_caches_mmu (void)
{
  grub_uint32_t *table;
  grub_uint32_t i;
  grub_uint32_t border_crossing = 0;
  grub_uint32_t *subtable;
  struct sys_info *si = grub_uboot_get_sys_info ();

  if (!si || (si->mr_no == 0))
    {
      grub_printf ("couldn't get memory map, not enabling caches");
      grub_errno = GRUB_ERR_NONE;
      return;
    }

  if (type == ARCH_UNKNOWN)
    probe_caches ();

  for (i = 0; (signed) i < si->mr_no; i++)
    {
      if (si->mr[i].start & ((1 << 20) - 1))
	border_crossing++;
      if ((si->mr[i].start + si->mr[i].size) & ((1 << 20) - 1))
	border_crossing++;
    }

  grub_printf ("%d crossers\n", border_crossing);

  table = grub_memalign (1 << 14, (1 << 14) + (border_crossing << 10));
  if (!table)
    {
      grub_printf ("couldn't allocate place for MMU table, not enabling caches");
      grub_errno = GRUB_ERR_NONE;
      return;
    }

  subtable = table + (1 << 12);
  /* Map all unknown as device.  */
  for (i = 0; i < (1 << 12); i++)
    table[i] = (i << 20) | (3 << 10) | (0 << 3) | (1 << 2) | 2;
  /*
    Device: TEX= 0, C=0, B=1
    normal: TEX= 0, C=1, B=1
    AP = 3
    IMP = 0
    Domain = 0
*/

  for (i = 0; (signed) i < si->mr_no; i++)
    {
      if (si->mr[i].start & ((1 << 20) - 1))
	{
	  subdivide (table, subtable, si->mr[i].start);
	  subtable += (1 << 8);
	}
      if ((si->mr[i].start + si->mr[i].size) & ((1 << 20) - 1))
	{
	  subdivide (table, subtable, si->mr[i].start + si->mr[i].size);
	  subtable += (1 << 8);
	}
    }

  for (i = 0; (signed) i < si->mr_no; i++)
    if ((si->mr[i].flags & MR_ATTR_MASK) == MR_ATTR_DRAM
	|| (si->mr[i].flags & MR_ATTR_MASK) == MR_ATTR_SRAM
	|| (si->mr[i].flags & MR_ATTR_MASK) == MR_ATTR_FLASH)
      {
	grub_uint32_t cur, end;
	cur = si->mr[i].start;
	end = si->mr[i].start + si->mr[i].size;
	while (cur < end)
	  {
	    grub_uint32_t *st;
	    if ((table[cur >> 20] & 3) == 2)
	      {
		cur = cur >> 20 << 20;
		table[cur >> 20] = cur | (3 << 10) | (1 << 3) | (1 << 2) | 2;
		cur += (1 << 20);
		continue;
	      }
	    cur = cur >> 12 << 12;
	    st = (grub_uint32_t *) (table[cur >> 20] & ~0x3ff);
	    st[(cur >> 12) & 0xff] = cur | (3 << 4) | (3 << 6)
	      | (3 << 8) | (3 << 10)
	      | (1 << 3) | (1 << 2) | 2;
	    cur += (1 << 12);
	  }
      }

  grub_printf ("MMU tables generated\n");
  if (is_v6_mmu)
    grub_arm_clear_mmu_v6 ();

  grub_printf ("enabling MMU\n");
  grub_arm_enable_mmu (table);
  grub_printf ("MMU enabled\n");
}

#endif

void
grub_arch_sync_caches (void *address, grub_size_t len)
{
  grub_addr_t start = (grub_addr_t) address;
  grub_addr_t end = start + len;

  if (type == ARCH_UNKNOWN)
    probe_caches ();
  start = ALIGN_DOWN (start, grub_arch_cache_max_linesz);
  end = ALIGN_UP (end, grub_arch_cache_max_linesz);
  switch (type)
    {
    case ARCH_ARMV6:
      grub_arm_clean_dcache_range_armv6 (start, end, grub_arch_cache_dlinesz);
      grub_arm_invalidate_icache_range_armv6 (start, end,
					      grub_arch_cache_ilinesz);
      break;
    case ARCH_ARMV7:
      grub_arm_clean_dcache_range_armv7 (start, end, grub_arch_cache_dlinesz);
      grub_arm_invalidate_icache_range_armv7 (start, end,
					      grub_arch_cache_ilinesz);
      break;
      /* Nothing to do.  */
    case ARCH_ARMV5_WRITE_THROUGH:
    case ARCH_ARMV6_UNIFIED:
      break;
      /* Pacify GCC.  */
    case ARCH_UNKNOWN:
      break;
    }
}

void
grub_arch_sync_dma_caches (volatile void *address, grub_size_t len)
{
  grub_addr_t start = (grub_addr_t) address;
  grub_addr_t end = start + len;

  if (type == ARCH_UNKNOWN)
    probe_caches ();
  start = ALIGN_DOWN (start, grub_arch_cache_max_linesz);
  end = ALIGN_UP (end, grub_arch_cache_max_linesz);
  switch (type)
    {
    case ARCH_ARMV6:
      grub_arm_clean_dcache_range_armv6 (start, end, grub_arch_cache_dlinesz);
      grub_arm_invalidate_icache_range_armv6 (start, end,
					      grub_arch_cache_ilinesz);
      break;
    case ARCH_ARMV5_WRITE_THROUGH:
    case ARCH_ARMV6_UNIFIED:
      grub_arm_clean_dcache_range_armv6 (start, end, grub_arch_cache_dlinesz);
      break;
    case ARCH_ARMV7:
      grub_arm_clean_dcache_range_poc_armv7 (start, end, grub_arch_cache_dlinesz);
      grub_arm_invalidate_icache_range_armv7 (start, end,
					      grub_arch_cache_ilinesz);
      break;
      /* Pacify GCC.  */
    case ARCH_UNKNOWN:
      break;
    }
}

void
grub_arm_disable_caches_mmu (void)
{
  if (type == ARCH_UNKNOWN)
    probe_caches ();
  switch (type)
    {
    case ARCH_ARMV5_WRITE_THROUGH:
    case ARCH_ARMV6_UNIFIED:
    case ARCH_ARMV6:
      grub_arm_disable_caches_mmu_armv6 ();
      break;
    case ARCH_ARMV7:
      grub_arm_disable_caches_mmu_armv7 ();
      break;
      /* Pacify GCC.  */
    case ARCH_UNKNOWN:
      break;
    }
}
