/* Blackfin Watchpoint (WP) model.

   Copyright (C) 2010-2013 Free Software Foundation, Inc.
   Contributed by Analog Devices, Inc.

   This file is part of simulators.

   This program is free software; you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
   the Free Software Foundation; either version 3 of the License, or
   (at your option) any later version.

   This program is distributed in the hope that it will be useful,
   but WITHOUT ANY WARRANTY; without even the implied warranty of
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   GNU General Public License for more details.

   You should have received a copy of the GNU General Public License
   along with this program.  If not, see <http://www.gnu.org/licenses/>.  */

#include "config.h"

#include "sim-main.h"
#include "devices.h"
#include "dv-bfin_wp.h"

/* XXX: This is mostly a stub.  */

#define WPI_NUM 6	/* 6 instruction watchpoints.  */
#define WPD_NUM 2	/* 2 data watchpoints.  */

struct bfin_wp
{
  bu32 base;

  /* Order after here is important -- matches hardware MMR layout.  */
  bu32 iactl;
  bu32 _pad0[15];
  bu32 ia[WPI_NUM];
  bu32 _pad1[16 - WPI_NUM];
  bu32 iacnt[WPI_NUM];
  bu32 _pad2[32 - WPI_NUM];

  bu32 dactl;
  bu32 _pad3[15];
  bu32 da[WPD_NUM];
  bu32 _pad4[16 - WPD_NUM];
  bu32 dacnt[WPD_NUM];
  bu32 _pad5[32 - WPD_NUM];

  bu32 stat;
};
#define mmr_base()      offsetof(struct bfin_wp, iactl)
#define mmr_offset(mmr) (offsetof(struct bfin_wp, mmr) - mmr_base())
#define mmr_idx(mmr)    (mmr_offset (mmr) / 4)

static const char * const mmr_names[] =
{
  [mmr_idx (iactl)] = "WPIACTL",
  [mmr_idx (ia)]    = "WPIA0", "WPIA1", "WPIA2", "WPIA3", "WPIA4", "WPIA5",
  [mmr_idx (iacnt)] = "WPIACNT0", "WPIACNT1", "WPIACNT2",
		      "WPIACNT3", "WPIACNT4", "WPIACNT5",
  [mmr_idx (dactl)] = "WPDACTL",
  [mmr_idx (da)]    = "WPDA0", "WPDA1", "WPDA2", "WPDA3", "WPDA4", "WPDA5",
  [mmr_idx (dacnt)] = "WPDACNT0", "WPDACNT1", "WPDACNT2",
		      "WPDACNT3", "WPDACNT4", "WPDACNT5",
  [mmr_idx (stat)]  = "WPSTAT",
};
#define mmr_name(off) (mmr_names[(off) / 4] ? : "<INV>")

static unsigned
bfin_wp_io_write_buffer (struct hw *me, const void *source, int space,
			 address_word addr, unsigned nr_bytes)
{
  struct bfin_wp *wp = hw_data (me);
  bu32 mmr_off;
  bu32 value;
  bu32 *valuep;

  value = dv_load_4 (source);
  mmr_off = addr - wp->base;
  valuep = (void *)((unsigned long)wp + mmr_base() + mmr_off);

  HW_TRACE_WRITE ();

  switch (mmr_off)
    {
    case mmr_offset(iactl):
    case mmr_offset(ia[0]) ... mmr_offset(ia[WPI_NUM - 1]):
    case mmr_offset(iacnt[0]) ... mmr_offset(iacnt[WPI_NUM - 1]):
    case mmr_offset(dactl):
    case mmr_offset(da[0]) ... mmr_offset(da[WPD_NUM - 1]):
    case mmr_offset(dacnt[0]) ... mmr_offset(dacnt[WPD_NUM - 1]):
      *valuep = value;
      break;
    case mmr_offset(stat):
      /* Yes, the hardware is this dumb -- clear all bits on any write.  */
      *valuep = 0;
      break;
    default:
      dv_bfin_mmr_invalid (me, addr, nr_bytes, true);
      break;
    }

  return nr_bytes;
}

static unsigned
bfin_wp_io_read_buffer (struct hw *me, void *dest, int space,
			address_word addr, unsigned nr_bytes)
{
  struct bfin_wp *wp = hw_data (me);
  bu32 mmr_off;
  bu32 value;
  bu32 *valuep;

  mmr_off = addr - wp->base;
  valuep = (void *)((unsigned long)wp + mmr_base() + mmr_off);

  HW_TRACE_READ ();

  switch (mmr_off)
    {
    case mmr_offset(iactl):
    case mmr_offset(ia[0]) ... mmr_offset(ia[WPI_NUM - 1]):
    case mmr_offset(iacnt[0]) ... mmr_offset(iacnt[WPI_NUM - 1]):
    case mmr_offset(dactl):
    case mmr_offset(da[0]) ... mmr_offset(da[WPD_NUM - 1]):
    case mmr_offset(dacnt[0]) ... mmr_offset(dacnt[WPD_NUM - 1]):
    case mmr_offset(stat):
      value = *valuep;
      break;
    default:
      while (1) /* Core MMRs -> exception -> doesn't return.  */
	dv_bfin_mmr_invalid (me, addr, nr_bytes, false);
      break;
    }

  dv_store_4 (dest, value);

  return nr_bytes;
}

static void
attach_bfin_wp_regs (struct hw *me, struct bfin_wp *wp)
{
  address_word attach_address;
  int attach_space;
  unsigned attach_size;
  reg_property_spec reg;

  if (hw_find_property (me, "reg") == NULL)
    hw_abort (me, "Missing \"reg\" property");

  if (!hw_find_reg_array_property (me, "reg", 0, &reg))
    hw_abort (me, "\"reg\" property must contain three addr/size entries");

  hw_unit_address_to_attach_address (hw_parent (me),
				     &reg.address,
				     &attach_space, &attach_address, me);
  hw_unit_size_to_attach_size (hw_parent (me), &reg.size, &attach_size, me);

  if (attach_size != BFIN_COREMMR_WP_SIZE)
    hw_abort (me, "\"reg\" size must be %#x", BFIN_COREMMR_WP_SIZE);

  hw_attach_address (hw_parent (me),
		     0, attach_space, attach_address, attach_size, me);

  wp->base = attach_address;
}

static void
bfin_wp_finish (struct hw *me)
{
  struct bfin_wp *wp;

  wp = HW_ZALLOC (me, struct bfin_wp);

  set_hw_data (me, wp);
  set_hw_io_read_buffer (me, bfin_wp_io_read_buffer);
  set_hw_io_write_buffer (me, bfin_wp_io_write_buffer);

  attach_bfin_wp_regs (me, wp);
}

const struct hw_descriptor dv_bfin_wp_descriptor[] =
{
  {"bfin_wp", bfin_wp_finish,},
  {NULL, NULL},
};
