Blame sim/bfin/dv-bfin_jtag.c

Packit Service 706eca
/* Blackfin JTAG model.
Packit Service 706eca
Packit Service 706eca
   Copyright (C) 2010-2018 Free Software Foundation, Inc.
Packit Service 706eca
   Contributed by Analog Devices, Inc.
Packit Service 706eca
Packit Service 706eca
   This file is part of simulators.
Packit Service 706eca
Packit Service 706eca
   This program is free software; you can redistribute it and/or modify
Packit Service 706eca
   it under the terms of the GNU General Public License as published by
Packit Service 706eca
   the Free Software Foundation; either version 3 of the License, or
Packit Service 706eca
   (at your option) any later version.
Packit Service 706eca
Packit Service 706eca
   This program is distributed in the hope that it will be useful,
Packit Service 706eca
   but WITHOUT ANY WARRANTY; without even the implied warranty of
Packit Service 706eca
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
Packit Service 706eca
   GNU General Public License for more details.
Packit Service 706eca
Packit Service 706eca
   You should have received a copy of the GNU General Public License
Packit Service 706eca
   along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
Packit Service 706eca
Packit Service 706eca
#include "config.h"
Packit Service 706eca
Packit Service 706eca
#include "sim-main.h"
Packit Service 706eca
#include "devices.h"
Packit Service 706eca
#include "dv-bfin_jtag.h"
Packit Service 706eca
Packit Service 706eca
/* XXX: This is mostly a stub.  There are more registers, but they're only
Packit Service 706eca
        accessible via the JTAG scan chain and not the MMR interface.  */
Packit Service 706eca
Packit Service 706eca
struct bfin_jtag
Packit Service 706eca
{
Packit Service 706eca
  bu32 base;
Packit Service 706eca
Packit Service 706eca
  /* Order after here is important -- matches hardware MMR layout.  */
Packit Service 706eca
  bu32 dspid;
Packit Service 706eca
  bu32 _pad0;
Packit Service 706eca
  bu32 dbgstat;
Packit Service 706eca
};
Packit Service 706eca
#define mmr_base()      offsetof(struct bfin_jtag, dspid)
Packit Service 706eca
#define mmr_offset(mmr) (offsetof(struct bfin_jtag, mmr) - mmr_base())
Packit Service 706eca
Packit Service 706eca
static const char * const mmr_names[] =
Packit Service 706eca
{
Packit Service 706eca
  "DSPID", NULL, "DBGSTAT",
Packit Service 706eca
};
Packit Service 706eca
#define mmr_name(off) (mmr_names[(off) / 4] ? : "<INV>")
Packit Service 706eca
Packit Service 706eca
static unsigned
Packit Service 706eca
bfin_jtag_io_write_buffer (struct hw *me, const void *source, int space,
Packit Service 706eca
			   address_word addr, unsigned nr_bytes)
Packit Service 706eca
{
Packit Service 706eca
  struct bfin_jtag *jtag = hw_data (me);
Packit Service 706eca
  bu32 mmr_off;
Packit Service 706eca
  bu32 value;
Packit Service 706eca
  bu32 *valuep;
Packit Service 706eca
Packit Service 706eca
  /* Invalid access mode is higher priority than missing register.  */
Packit Service 706eca
  if (!dv_bfin_mmr_require_32 (me, addr, nr_bytes, true))
Packit Service 706eca
    return 0;
Packit Service 706eca
Packit Service 706eca
  value = dv_load_4 (source);
Packit Service 706eca
  mmr_off = addr - jtag->base;
Packit Service 706eca
  valuep = (void *)((unsigned long)jtag + mmr_base() + mmr_off);
Packit Service 706eca
Packit Service 706eca
  HW_TRACE_WRITE ();
Packit Service 706eca
Packit Service 706eca
  switch (mmr_off)
Packit Service 706eca
    {
Packit Service 706eca
    case mmr_offset(dbgstat):
Packit Service 706eca
      dv_w1c_4 (valuep, value, 0xc);
Packit Service 706eca
      break;
Packit Service 706eca
    case mmr_offset(dspid):
Packit Service 706eca
      /* Discard writes to these.  */
Packit Service 706eca
      break;
Packit Service 706eca
    default:
Packit Service 706eca
      dv_bfin_mmr_invalid (me, addr, nr_bytes, true);
Packit Service 706eca
      return 0;
Packit Service 706eca
    }
Packit Service 706eca
Packit Service 706eca
  return nr_bytes;
Packit Service 706eca
}
Packit Service 706eca
Packit Service 706eca
static unsigned
Packit Service 706eca
bfin_jtag_io_read_buffer (struct hw *me, void *dest, int space,
Packit Service 706eca
			  address_word addr, unsigned nr_bytes)
Packit Service 706eca
{
Packit Service 706eca
  struct bfin_jtag *jtag = hw_data (me);
Packit Service 706eca
  bu32 mmr_off;
Packit Service 706eca
  bu32 value;
Packit Service 706eca
  bu32 *valuep;
Packit Service 706eca
Packit Service 706eca
  /* Invalid access mode is higher priority than missing register.  */
Packit Service 706eca
  if (!dv_bfin_mmr_require_32 (me, addr, nr_bytes, false))
Packit Service 706eca
    return 0;
Packit Service 706eca
Packit Service 706eca
  mmr_off = addr - jtag->base;
Packit Service 706eca
  valuep = (void *)((unsigned long)jtag + mmr_base() + mmr_off);
Packit Service 706eca
Packit Service 706eca
  HW_TRACE_READ ();
Packit Service 706eca
Packit Service 706eca
  switch (mmr_off)
Packit Service 706eca
    {
Packit Service 706eca
    case mmr_offset(dbgstat):
Packit Service 706eca
    case mmr_offset(dspid):
Packit Service 706eca
      value = *valuep;
Packit Service 706eca
      break;
Packit Service 706eca
    default:
Packit Service 706eca
      dv_bfin_mmr_invalid (me, addr, nr_bytes, false);
Packit Service 706eca
      return 0;
Packit Service 706eca
    }
Packit Service 706eca
Packit Service 706eca
  dv_store_4 (dest, value);
Packit Service 706eca
Packit Service 706eca
  return nr_bytes;
Packit Service 706eca
}
Packit Service 706eca
Packit Service 706eca
static void
Packit Service 706eca
attach_bfin_jtag_regs (struct hw *me, struct bfin_jtag *jtag)
Packit Service 706eca
{
Packit Service 706eca
  address_word attach_address;
Packit Service 706eca
  int attach_space;
Packit Service 706eca
  unsigned attach_size;
Packit Service 706eca
  reg_property_spec reg;
Packit Service 706eca
Packit Service 706eca
  if (hw_find_property (me, "reg") == NULL)
Packit Service 706eca
    hw_abort (me, "Missing \"reg\" property");
Packit Service 706eca
Packit Service 706eca
  if (!hw_find_reg_array_property (me, "reg", 0, &reg))
Packit Service 706eca
    hw_abort (me, "\"reg\" property must contain three addr/size entries");
Packit Service 706eca
Packit Service 706eca
  hw_unit_address_to_attach_address (hw_parent (me),
Packit Service 706eca
				     &reg.address,
Packit Service 706eca
				     &attach_space, &attach_address, me);
Packit Service 706eca
  hw_unit_size_to_attach_size (hw_parent (me), &reg.size, &attach_size, me);
Packit Service 706eca
Packit Service 706eca
  if (attach_size != BFIN_COREMMR_JTAG_SIZE)
Packit Service 706eca
    hw_abort (me, "\"reg\" size must be %#x", BFIN_COREMMR_JTAG_SIZE);
Packit Service 706eca
Packit Service 706eca
  hw_attach_address (hw_parent (me),
Packit Service 706eca
		     0, attach_space, attach_address, attach_size, me);
Packit Service 706eca
Packit Service 706eca
  jtag->base = attach_address;
Packit Service 706eca
}
Packit Service 706eca
Packit Service 706eca
static void
Packit Service 706eca
bfin_jtag_finish (struct hw *me)
Packit Service 706eca
{
Packit Service 706eca
  struct bfin_jtag *jtag;
Packit Service 706eca
Packit Service 706eca
  jtag = HW_ZALLOC (me, struct bfin_jtag);
Packit Service 706eca
Packit Service 706eca
  set_hw_data (me, jtag);
Packit Service 706eca
  set_hw_io_read_buffer (me, bfin_jtag_io_read_buffer);
Packit Service 706eca
  set_hw_io_write_buffer (me, bfin_jtag_io_write_buffer);
Packit Service 706eca
Packit Service 706eca
  attach_bfin_jtag_regs (me, jtag);
Packit Service 706eca
Packit Service 706eca
  /* Initialize the JTAG state.  */
Packit Service 706eca
  jtag->dspid = bfin_model_get_dspid (hw_system (me));
Packit Service 706eca
}
Packit Service 706eca
Packit Service 706eca
const struct hw_descriptor dv_bfin_jtag_descriptor[] =
Packit Service 706eca
{
Packit Service 706eca
  {"bfin_jtag", bfin_jtag_finish,},
Packit Service 706eca
  {NULL, NULL},
Packit Service 706eca
};