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, ®)) 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 ®.address, 133 1.1 christos &attach_space, &attach_address, me); 134 1.1 christos hw_unit_size_to_attach_size (hw_parent (me), ®.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