cachepc-qemu

Fork of AMDESE/qemu with changes for cachepc side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-qemu
Log | Files | Refs | Submodules | LICENSE | sfeed.txt

omap_l4.c (4420B)


      1/*
      2 * TI OMAP L4 interconnect emulation.
      3 *
      4 * Copyright (C) 2007-2009 Nokia Corporation
      5 * Written by Andrzej Zaborowski <andrew@openedhand.com>
      6 *
      7 * This program is free software; you can redistribute it and/or
      8 * modify it under the terms of the GNU General Public License as
      9 * published by the Free Software Foundation; either version 2 or
     10 * (at your option) any later version of the License.
     11 *
     12 * This program is distributed in the hope that it will be useful,
     13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
     14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     15 * GNU General Public License for more details.
     16 *
     17 * You should have received a copy of the GNU General Public License along
     18 * with this program; if not, see <http://www.gnu.org/licenses/>.
     19 */
     20#include "qemu/osdep.h"
     21#include "hw/arm/omap.h"
     22
     23struct omap_l4_s {
     24    MemoryRegion *address_space;
     25    hwaddr base;
     26    int ta_num;
     27    struct omap_target_agent_s ta[];
     28};
     29
     30struct omap_l4_s *omap_l4_init(MemoryRegion *address_space,
     31                               hwaddr base, int ta_num)
     32{
     33    struct omap_l4_s *bus = g_malloc0(
     34                    sizeof(*bus) + ta_num * sizeof(*bus->ta));
     35
     36    bus->address_space = address_space;
     37    bus->ta_num = ta_num;
     38    bus->base = base;
     39
     40    return bus;
     41}
     42
     43hwaddr omap_l4_region_base(struct omap_target_agent_s *ta,
     44                                       int region)
     45{
     46    return ta->bus->base + ta->start[region].offset;
     47}
     48
     49hwaddr omap_l4_region_size(struct omap_target_agent_s *ta,
     50                                       int region)
     51{
     52    return ta->start[region].size;
     53}
     54
     55static uint64_t omap_l4ta_read(void *opaque, hwaddr addr,
     56                               unsigned size)
     57{
     58    struct omap_target_agent_s *s = (struct omap_target_agent_s *) opaque;
     59
     60    if (size != 2) {
     61        return omap_badwidth_read16(opaque, addr);
     62    }
     63
     64    switch (addr) {
     65    case 0x00:	/* COMPONENT */
     66        return s->component;
     67
     68    case 0x20:	/* AGENT_CONTROL */
     69        return s->control;
     70
     71    case 0x28:	/* AGENT_STATUS */
     72        return s->status;
     73    }
     74
     75    OMAP_BAD_REG(addr);
     76    return 0;
     77}
     78
     79static void omap_l4ta_write(void *opaque, hwaddr addr,
     80                            uint64_t value, unsigned size)
     81{
     82    struct omap_target_agent_s *s = (struct omap_target_agent_s *) opaque;
     83
     84    if (size != 4) {
     85        omap_badwidth_write32(opaque, addr, value);
     86        return;
     87    }
     88
     89    switch (addr) {
     90    case 0x00:	/* COMPONENT */
     91    case 0x28:	/* AGENT_STATUS */
     92        OMAP_RO_REG(addr);
     93        break;
     94
     95    case 0x20:	/* AGENT_CONTROL */
     96        s->control = value & 0x01000700;
     97        if (value & 1)					/* OCP_RESET */
     98            s->status &= ~1;				/* REQ_TIMEOUT */
     99        break;
    100
    101    default:
    102        OMAP_BAD_REG(addr);
    103    }
    104}
    105
    106static const MemoryRegionOps omap_l4ta_ops = {
    107    .read = omap_l4ta_read,
    108    .write = omap_l4ta_write,
    109    .endianness = DEVICE_NATIVE_ENDIAN,
    110};
    111
    112struct omap_target_agent_s *omap_l4ta_get(struct omap_l4_s *bus,
    113        const struct omap_l4_region_s *regions,
    114        const struct omap_l4_agent_info_s *agents,
    115        int cs)
    116{
    117    int i;
    118    struct omap_target_agent_s *ta = NULL;
    119    const struct omap_l4_agent_info_s *info = NULL;
    120
    121    for (i = 0; i < bus->ta_num; i ++)
    122        if (agents[i].ta == cs) {
    123            ta = &bus->ta[i];
    124            info = &agents[i];
    125            break;
    126        }
    127    if (!ta) {
    128        fprintf(stderr, "%s: bad target agent (%i)\n", __func__, cs);
    129        exit(-1);
    130    }
    131
    132    ta->bus = bus;
    133    ta->start = &regions[info->region];
    134    ta->regions = info->regions;
    135
    136    ta->component = ('Q' << 24) | ('E' << 16) | ('M' << 8) | ('U' << 0);
    137    ta->status = 0x00000000;
    138    ta->control = 0x00000200;	/* XXX 01000200 for L4TAO */
    139
    140    memory_region_init_io(&ta->iomem, NULL, &omap_l4ta_ops, ta, "omap.l4ta",
    141                          omap_l4_region_size(ta, info->ta_region));
    142    omap_l4_attach(ta, info->ta_region, &ta->iomem);
    143
    144    return ta;
    145}
    146
    147hwaddr omap_l4_attach(struct omap_target_agent_s *ta,
    148                                         int region, MemoryRegion *mr)
    149{
    150    hwaddr base;
    151
    152    if (region < 0 || region >= ta->regions) {
    153        fprintf(stderr, "%s: bad io region (%i)\n", __func__, region);
    154        exit(-1);
    155    }
    156
    157    base = ta->bus->base + ta->start[region].offset;
    158    if (mr) {
    159        memory_region_add_subregion(ta->bus->address_space, base, mr);
    160    }
    161
    162    return base;
    163}