Home | History | Annotate | Line # | Download | only in bfin
dv-bfin_pfmon.c revision 1.1
      1  1.1  christos /* Blackfin Performance Monitor model.
      2  1.1  christos 
      3  1.1  christos    Copyright (C) 2010-2013 Free Software Foundation, Inc.
      4  1.1  christos    Contributed by Analog Devices, Inc.
      5  1.1  christos 
      6  1.1  christos    This file is part of simulators.
      7  1.1  christos 
      8  1.1  christos    This program is free software; you can redistribute it and/or modify
      9  1.1  christos    it under the terms of the GNU General Public License as published by
     10  1.1  christos    the Free Software Foundation; either version 3 of the License, or
     11  1.1  christos    (at your option) any later version.
     12  1.1  christos 
     13  1.1  christos    This program is distributed in the hope that it will be useful,
     14  1.1  christos    but WITHOUT ANY WARRANTY; without even the implied warranty of
     15  1.1  christos    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     16  1.1  christos    GNU General Public License for more details.
     17  1.1  christos 
     18  1.1  christos    You should have received a copy of the GNU General Public License
     19  1.1  christos    along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
     20  1.1  christos 
     21  1.1  christos #include "config.h"
     22  1.1  christos 
     23  1.1  christos #include "sim-main.h"
     24  1.1  christos #include "devices.h"
     25  1.1  christos #include "dv-bfin_pfmon.h"
     26  1.1  christos 
     27  1.1  christos /* XXX: This is mostly a stub.  */
     28  1.1  christos 
     29  1.1  christos struct bfin_pfmon
     30  1.1  christos {
     31  1.1  christos   bu32 base;
     32  1.1  christos 
     33  1.1  christos   /* Order after here is important -- matches hardware MMR layout.  */
     34  1.1  christos   bu32 ctl;
     35  1.1  christos   bu32 _pad0[63];
     36  1.1  christos   bu32 cntr0, cntr1;
     37  1.1  christos };
     38  1.1  christos #define mmr_base()      offsetof(struct bfin_pfmon, ctl)
     39  1.1  christos #define mmr_offset(mmr) (offsetof(struct bfin_pfmon, mmr) - mmr_base())
     40  1.1  christos 
     41  1.1  christos static const char * const mmr_names[] =
     42  1.1  christos {
     43  1.1  christos   "PFCTL", [mmr_offset (cntr0)] = "PFCNTR0", "PFCNTR1",
     44  1.1  christos };
     45  1.1  christos #define mmr_name(off) (mmr_names[(off) / 4] ? : "<INV>")
     46  1.1  christos 
     47  1.1  christos static unsigned
     48  1.1  christos bfin_pfmon_io_write_buffer (struct hw *me, const void *source, int space,
     49  1.1  christos 			    address_word addr, unsigned nr_bytes)
     50  1.1  christos {
     51  1.1  christos   struct bfin_pfmon *pfmon = hw_data (me);
     52  1.1  christos   bu32 mmr_off;
     53  1.1  christos   bu32 value;
     54  1.1  christos   bu32 *valuep;
     55  1.1  christos 
     56  1.1  christos   value = dv_load_4 (source);
     57  1.1  christos   mmr_off = addr - pfmon->base;
     58  1.1  christos   valuep = (void *)((unsigned long)pfmon + mmr_base() + mmr_off);
     59  1.1  christos 
     60  1.1  christos   HW_TRACE_WRITE ();
     61  1.1  christos 
     62  1.1  christos   switch (mmr_off)
     63  1.1  christos     {
     64  1.1  christos     case mmr_offset(ctl):
     65  1.1  christos     case mmr_offset(cntr0):
     66  1.1  christos     case mmr_offset(cntr1):
     67  1.1  christos       *valuep = value;
     68  1.1  christos       break;
     69  1.1  christos     default:
     70  1.1  christos       dv_bfin_mmr_invalid (me, addr, nr_bytes, true);
     71  1.1  christos       break;
     72  1.1  christos     }
     73  1.1  christos 
     74  1.1  christos   return nr_bytes;
     75  1.1  christos }
     76  1.1  christos 
     77  1.1  christos static unsigned
     78  1.1  christos bfin_pfmon_io_read_buffer (struct hw *me, void *dest, int space,
     79  1.1  christos 			   address_word addr, unsigned nr_bytes)
     80  1.1  christos {
     81  1.1  christos   struct bfin_pfmon *pfmon = hw_data (me);
     82  1.1  christos   bu32 mmr_off;
     83  1.1  christos   bu32 value;
     84  1.1  christos   bu32 *valuep;
     85  1.1  christos 
     86  1.1  christos   mmr_off = addr - pfmon->base;
     87  1.1  christos   valuep = (void *)((unsigned long)pfmon + mmr_base() + mmr_off);
     88  1.1  christos 
     89  1.1  christos   HW_TRACE_READ ();
     90  1.1  christos 
     91  1.1  christos   switch (mmr_off)
     92  1.1  christos     {
     93  1.1  christos     case mmr_offset(ctl):
     94  1.1  christos     case mmr_offset(cntr0):
     95  1.1  christos     case mmr_offset(cntr1):
     96  1.1  christos       value = *valuep;
     97  1.1  christos       break;
     98  1.1  christos     default:
     99  1.1  christos       while (1) /* Core MMRs -> exception -> doesn't return.  */
    100  1.1  christos 	dv_bfin_mmr_invalid (me, addr, nr_bytes, false);
    101  1.1  christos       break;
    102  1.1  christos     }
    103  1.1  christos 
    104  1.1  christos   dv_store_4 (dest, value);
    105  1.1  christos 
    106  1.1  christos   return nr_bytes;
    107  1.1  christos }
    108  1.1  christos 
    109  1.1  christos static void
    110  1.1  christos attach_bfin_pfmon_regs (struct hw *me, struct bfin_pfmon *pfmon)
    111  1.1  christos {
    112  1.1  christos   address_word attach_address;
    113  1.1  christos   int attach_space;
    114  1.1  christos   unsigned attach_size;
    115  1.1  christos   reg_property_spec reg;
    116  1.1  christos 
    117  1.1  christos   if (hw_find_property (me, "reg") == NULL)
    118  1.1  christos     hw_abort (me, "Missing \"reg\" property");
    119  1.1  christos 
    120  1.1  christos   if (!hw_find_reg_array_property (me, "reg", 0, &reg))
    121  1.1  christos     hw_abort (me, "\"reg\" property must contain three addr/size entries");
    122  1.1  christos 
    123  1.1  christos   hw_unit_address_to_attach_address (hw_parent (me),
    124  1.1  christos 				     &reg.address,
    125  1.1  christos 				     &attach_space, &attach_address, me);
    126  1.1  christos   hw_unit_size_to_attach_size (hw_parent (me), &reg.size, &attach_size, me);
    127  1.1  christos 
    128  1.1  christos   if (attach_size != BFIN_COREMMR_PFMON_SIZE)
    129  1.1  christos     hw_abort (me, "\"reg\" size must be %#x", BFIN_COREMMR_PFMON_SIZE);
    130  1.1  christos 
    131  1.1  christos   hw_attach_address (hw_parent (me),
    132  1.1  christos 		     0, attach_space, attach_address, attach_size, me);
    133  1.1  christos 
    134  1.1  christos   pfmon->base = attach_address;
    135  1.1  christos }
    136  1.1  christos 
    137  1.1  christos static void
    138  1.1  christos bfin_pfmon_finish (struct hw *me)
    139  1.1  christos {
    140  1.1  christos   struct bfin_pfmon *pfmon;
    141  1.1  christos 
    142  1.1  christos   pfmon = HW_ZALLOC (me, struct bfin_pfmon);
    143  1.1  christos 
    144  1.1  christos   set_hw_data (me, pfmon);
    145  1.1  christos   set_hw_io_read_buffer (me, bfin_pfmon_io_read_buffer);
    146  1.1  christos   set_hw_io_write_buffer (me, bfin_pfmon_io_write_buffer);
    147  1.1  christos 
    148  1.1  christos   attach_bfin_pfmon_regs (me, pfmon);
    149  1.1  christos }
    150  1.1  christos 
    151  1.1  christos const struct hw_descriptor dv_bfin_pfmon_descriptor[] =
    152  1.1  christos {
    153  1.1  christos   {"bfin_pfmon", bfin_pfmon_finish,},
    154  1.1  christos   {NULL, NULL},
    155  1.1  christos };
    156