/* Blackfin device support.

   Copyright (C) 2010-2016 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 "sim-hw.h"
#include "hw-device.h"
#include "devices.h"
#include "dv-bfin_cec.h"
#include "dv-bfin_mmu.h"

static void
bfin_mmr_invalid (struct hw *me, address_word addr,
		  unsigned nr_bytes, bool write, bool missing)
{
  SIM_CPU *cpu = hw_system_cpu (me);
  const char *rw = write ? "write" : "read";
  const char *reason =
    missing ? "no such register" :
              (addr & 3) ? "must be 32-bit aligned" : "invalid length";

  /* Only throw a fit if the cpu is doing the access.  DMA/GDB simply
     go unnoticed.  Not exactly hardware behavior, but close enough.  */
  if (!cpu)
    {
      sim_io_eprintf (hw_system (me),
		      "%s: invalid MMR %s at %#x length %u: %s\n",
		      hw_path (me), rw, addr, nr_bytes, reason);
      return;
    }

  HW_TRACE ((me, "invalid MMR %s at %#x length %u: %s",
	     rw, addr, nr_bytes, reason));

  /* XXX: is this what hardware does ?  What about priority of unaligned vs
     wrong length vs missing register ?  What about system-vs-core ?  */
  /* XXX: We should move this addr check to a model property so we get the
     same behavior regardless of where we map the model.  */
  if (addr >= BFIN_CORE_MMR_BASE)
    /* XXX: This should be setting up CPLB fault addrs ?  */
    mmu_process_fault (cpu, addr, write, false, false, true);
  else
    /* XXX: Newer parts set up an interrupt from EBIU and program
            EBIU_ERRADDR with the address.  */
    cec_hwerr (cpu, HWERR_SYSTEM_MMR);
}

void
dv_bfin_mmr_invalid (struct hw *me, address_word addr, unsigned nr_bytes,
		     bool write)
{
  bfin_mmr_invalid (me, addr, nr_bytes, write, true);
}

bool
dv_bfin_mmr_require (struct hw *me, address_word addr, unsigned nr_bytes,
		     unsigned size, bool write)
{
  if ((addr & 0x3) == 0 && nr_bytes == size)
    return true;

  bfin_mmr_invalid (me, addr, nr_bytes, write, false);
  return false;
}

/* For 32-bit memory mapped registers that allow 16-bit or 32-bit access.  */
bool
dv_bfin_mmr_require_16_32 (struct hw *me, address_word addr, unsigned nr_bytes,
			   bool write)
{
  if ((addr & 0x3) == 0 && (nr_bytes == 2 || nr_bytes == 4))
    return true;

  bfin_mmr_invalid (me, addr, nr_bytes, write, false);
  return false;
}

unsigned int dv_get_bus_num (struct hw *me)
{
  const hw_unit *unit = hw_unit_address (me);
  return unit->cells[unit->nr_cells - 1];
}
