Home | History | Annotate | Line # | Download | only in bfin
      1       1.1  christos /* Blackfin Performance Monitor model.
      2       1.1  christos 
      3  1.1.1.10  christos    Copyright (C) 2010-2025 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.1.8  christos /* This must come before any other includes.  */
     22   1.1.1.8  christos #include "defs.h"
     23       1.1  christos 
     24       1.1  christos #include "sim-main.h"
     25       1.1  christos #include "devices.h"
     26       1.1  christos #include "dv-bfin_pfmon.h"
     27       1.1  christos 
     28       1.1  christos /* XXX: This is mostly a stub.  */
     29       1.1  christos 
     30       1.1  christos struct bfin_pfmon
     31       1.1  christos {
     32       1.1  christos   bu32 base;
     33       1.1  christos 
     34       1.1  christos   /* Order after here is important -- matches hardware MMR layout.  */
     35       1.1  christos   bu32 ctl;
     36       1.1  christos   bu32 _pad0[63];
     37       1.1  christos   bu32 cntr0, cntr1;
     38       1.1  christos };
     39       1.1  christos #define mmr_base()      offsetof(struct bfin_pfmon, ctl)
     40       1.1  christos #define mmr_offset(mmr) (offsetof(struct bfin_pfmon, mmr) - mmr_base())
     41       1.1  christos 
     42       1.1  christos static const char * const mmr_names[] =
     43       1.1  christos {
     44       1.1  christos   "PFCTL", [mmr_offset (cntr0)] = "PFCNTR0", "PFCNTR1",
     45       1.1  christos };
     46       1.1  christos #define mmr_name(off) (mmr_names[(off) / 4] ? : "<INV>")
     47       1.1  christos 
     48       1.1  christos static unsigned
     49       1.1  christos bfin_pfmon_io_write_buffer (struct hw *me, const void *source, int space,
     50       1.1  christos 			    address_word addr, unsigned nr_bytes)
     51       1.1  christos {
     52       1.1  christos   struct bfin_pfmon *pfmon = hw_data (me);
     53       1.1  christos   bu32 mmr_off;
     54       1.1  christos   bu32 value;
     55       1.1  christos   bu32 *valuep;
     56       1.1  christos 
     57   1.1.1.4  christos   /* Invalid access mode is higher priority than missing register.  */
     58   1.1.1.4  christos   if (!dv_bfin_mmr_require_32 (me, addr, nr_bytes, true))
     59   1.1.1.4  christos     return 0;
     60   1.1.1.4  christos 
     61       1.1  christos   value = dv_load_4 (source);
     62       1.1  christos   mmr_off = addr - pfmon->base;
     63   1.1.1.8  christos   valuep = (void *)((uintptr_t)pfmon + mmr_base() + mmr_off);
     64       1.1  christos 
     65       1.1  christos   HW_TRACE_WRITE ();
     66       1.1  christos 
     67       1.1  christos   switch (mmr_off)
     68       1.1  christos     {
     69       1.1  christos     case mmr_offset(ctl):
     70       1.1  christos     case mmr_offset(cntr0):
     71       1.1  christos     case mmr_offset(cntr1):
     72       1.1  christos       *valuep = value;
     73       1.1  christos       break;
     74       1.1  christos     default:
     75       1.1  christos       dv_bfin_mmr_invalid (me, addr, nr_bytes, true);
     76   1.1.1.4  christos       return 0;
     77       1.1  christos     }
     78       1.1  christos 
     79       1.1  christos   return nr_bytes;
     80       1.1  christos }
     81       1.1  christos 
     82       1.1  christos static unsigned
     83       1.1  christos bfin_pfmon_io_read_buffer (struct hw *me, void *dest, int space,
     84       1.1  christos 			   address_word addr, unsigned nr_bytes)
     85       1.1  christos {
     86       1.1  christos   struct bfin_pfmon *pfmon = hw_data (me);
     87       1.1  christos   bu32 mmr_off;
     88       1.1  christos   bu32 value;
     89       1.1  christos   bu32 *valuep;
     90       1.1  christos 
     91   1.1.1.4  christos   /* Invalid access mode is higher priority than missing register.  */
     92   1.1.1.4  christos   if (!dv_bfin_mmr_require_32 (me, addr, nr_bytes, false))
     93   1.1.1.4  christos     return 0;
     94   1.1.1.4  christos 
     95       1.1  christos   mmr_off = addr - pfmon->base;
     96   1.1.1.8  christos   valuep = (void *)((uintptr_t)pfmon + mmr_base() + mmr_off);
     97       1.1  christos 
     98       1.1  christos   HW_TRACE_READ ();
     99       1.1  christos 
    100       1.1  christos   switch (mmr_off)
    101       1.1  christos     {
    102       1.1  christos     case mmr_offset(ctl):
    103       1.1  christos     case mmr_offset(cntr0):
    104       1.1  christos     case mmr_offset(cntr1):
    105       1.1  christos       value = *valuep;
    106       1.1  christos       break;
    107       1.1  christos     default:
    108   1.1.1.4  christos       dv_bfin_mmr_invalid (me, addr, nr_bytes, false);
    109   1.1.1.4  christos       return 0;
    110       1.1  christos     }
    111       1.1  christos 
    112       1.1  christos   dv_store_4 (dest, value);
    113       1.1  christos 
    114       1.1  christos   return nr_bytes;
    115       1.1  christos }
    116       1.1  christos 
    117       1.1  christos static void
    118       1.1  christos attach_bfin_pfmon_regs (struct hw *me, struct bfin_pfmon *pfmon)
    119       1.1  christos {
    120       1.1  christos   address_word attach_address;
    121       1.1  christos   int attach_space;
    122       1.1  christos   unsigned attach_size;
    123       1.1  christos   reg_property_spec reg;
    124       1.1  christos 
    125       1.1  christos   if (hw_find_property (me, "reg") == NULL)
    126       1.1  christos     hw_abort (me, "Missing \"reg\" property");
    127       1.1  christos 
    128       1.1  christos   if (!hw_find_reg_array_property (me, "reg", 0, &reg))
    129       1.1  christos     hw_abort (me, "\"reg\" property must contain three addr/size entries");
    130       1.1  christos 
    131       1.1  christos   hw_unit_address_to_attach_address (hw_parent (me),
    132       1.1  christos 				     &reg.address,
    133       1.1  christos 				     &attach_space, &attach_address, me);
    134       1.1  christos   hw_unit_size_to_attach_size (hw_parent (me), &reg.size, &attach_size, me);
    135       1.1  christos 
    136       1.1  christos   if (attach_size != BFIN_COREMMR_PFMON_SIZE)
    137       1.1  christos     hw_abort (me, "\"reg\" size must be %#x", BFIN_COREMMR_PFMON_SIZE);
    138       1.1  christos 
    139       1.1  christos   hw_attach_address (hw_parent (me),
    140       1.1  christos 		     0, attach_space, attach_address, attach_size, me);
    141       1.1  christos 
    142       1.1  christos   pfmon->base = attach_address;
    143       1.1  christos }
    144       1.1  christos 
    145       1.1  christos static void
    146       1.1  christos bfin_pfmon_finish (struct hw *me)
    147       1.1  christos {
    148       1.1  christos   struct bfin_pfmon *pfmon;
    149       1.1  christos 
    150       1.1  christos   pfmon = HW_ZALLOC (me, struct bfin_pfmon);
    151       1.1  christos 
    152       1.1  christos   set_hw_data (me, pfmon);
    153       1.1  christos   set_hw_io_read_buffer (me, bfin_pfmon_io_read_buffer);
    154       1.1  christos   set_hw_io_write_buffer (me, bfin_pfmon_io_write_buffer);
    155       1.1  christos 
    156       1.1  christos   attach_bfin_pfmon_regs (me, pfmon);
    157       1.1  christos }
    158       1.1  christos 
    159       1.1  christos const struct hw_descriptor dv_bfin_pfmon_descriptor[] =
    160       1.1  christos {
    161       1.1  christos   {"bfin_pfmon", bfin_pfmon_finish,},
    162       1.1  christos   {NULL, NULL},
    163       1.1  christos };
    164