/* Blackfin Watchpoint (WP) model.

   Copyright (C) 2010-2021 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/>.  */

/* This must come before any other includes.  */
#include "defs.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;

  /* Invalid access mode is higher priority than missing register.  */
  if (!dv_bfin_mmr_require_32 (me, addr, nr_bytes, true))
    return 0;

  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);
      return 0;
    }

  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;

  /* Invalid access mode is higher priority than missing register.  */
  if (!dv_bfin_mmr_require_32 (me, addr, nr_bytes, false))
    return 0;

  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:
      dv_bfin_mmr_invalid (me, addr, nr_bytes, false);
      return 0;
    }

  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},
};
