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

grlib_ahb_apb_pnp.c (10502B)


      1/*
      2 * GRLIB AHB APB PNP
      3 *
      4 *  Copyright (C) 2019 AdaCore
      5 *
      6 *  Developed by :
      7 *  Frederic Konrad   <frederic.konrad@adacore.com>
      8 *
      9 * This program is free software; you can redistribute it and/or modify
     10 * it under the terms of the GNU General Public License as published by
     11 * the Free Software Foundation, either version 2 of the License, or
     12 * (at your option) any later version.
     13 *
     14 * This program is distributed in the hope that it will be useful,
     15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
     16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     17 * GNU General Public License for more details.
     18 *
     19 * You should have received a copy of the GNU General Public License along
     20 * with this program; if not, see <http://www.gnu.org/licenses/>.
     21 *
     22 */
     23
     24#include "qemu/osdep.h"
     25#include "qemu/log.h"
     26#include "hw/sysbus.h"
     27#include "hw/misc/grlib_ahb_apb_pnp.h"
     28#include "trace.h"
     29
     30#define GRLIB_PNP_VENDOR_SHIFT (24)
     31#define GRLIB_PNP_VENDOR_SIZE   (8)
     32#define GRLIB_PNP_DEV_SHIFT    (12)
     33#define GRLIB_PNP_DEV_SIZE     (12)
     34#define GRLIB_PNP_VER_SHIFT     (5)
     35#define GRLIB_PNP_VER_SIZE      (5)
     36#define GRLIB_PNP_IRQ_SHIFT     (0)
     37#define GRLIB_PNP_IRQ_SIZE      (5)
     38#define GRLIB_PNP_ADDR_SHIFT   (20)
     39#define GRLIB_PNP_ADDR_SIZE    (12)
     40#define GRLIB_PNP_MASK_SHIFT    (4)
     41#define GRLIB_PNP_MASK_SIZE    (12)
     42
     43#define GRLIB_AHB_DEV_ADDR_SHIFT   (20)
     44#define GRLIB_AHB_DEV_ADDR_SIZE    (12)
     45#define GRLIB_AHB_ENTRY_SIZE       (0x20)
     46#define GRLIB_AHB_MAX_DEV          (64)
     47#define GRLIB_AHB_SLAVE_OFFSET     (0x800)
     48
     49#define GRLIB_APB_DEV_ADDR_SHIFT   (8)
     50#define GRLIB_APB_DEV_ADDR_SIZE    (12)
     51#define GRLIB_APB_ENTRY_SIZE       (0x08)
     52#define GRLIB_APB_MAX_DEV          (512)
     53
     54#define GRLIB_PNP_MAX_REGS         (0x1000)
     55
     56typedef struct AHBPnp {
     57    SysBusDevice parent_obj;
     58    MemoryRegion iomem;
     59
     60    uint32_t regs[GRLIB_PNP_MAX_REGS >> 2];
     61    uint8_t master_count;
     62    uint8_t slave_count;
     63} AHBPnp;
     64
     65void grlib_ahb_pnp_add_entry(AHBPnp *dev, uint32_t address, uint32_t mask,
     66                             uint8_t vendor, uint16_t device, int slave,
     67                             int type)
     68{
     69    unsigned int reg_start;
     70
     71    /*
     72     * AHB entries look like this:
     73     *
     74     * 31 -------- 23 -------- 11 ----- 9 -------- 4 --- 0
     75     *  | VENDOR ID | DEVICE ID | IRQ ? | VERSION  | IRQ |
     76     *  --------------------------------------------------
     77     *  |                      USER                      |
     78     *  --------------------------------------------------
     79     *  |                      USER                      |
     80     *  --------------------------------------------------
     81     *  |                      USER                      |
     82     *  --------------------------------------------------
     83     *  |                      USER                      |
     84     *  --------------------------------------------------
     85     * 31 ----------- 20 --- 15 ----------------- 3 ---- 0
     86     *  | ADDR[31..12] | 00PC |        MASK       | TYPE |
     87     *  --------------------------------------------------
     88     * 31 ----------- 20 --- 15 ----------------- 3 ---- 0
     89     *  | ADDR[31..12] | 00PC |        MASK       | TYPE |
     90     *  --------------------------------------------------
     91     * 31 ----------- 20 --- 15 ----------------- 3 ---- 0
     92     *  | ADDR[31..12] | 00PC |        MASK       | TYPE |
     93     *  --------------------------------------------------
     94     * 31 ----------- 20 --- 15 ----------------- 3 ---- 0
     95     *  | ADDR[31..12] | 00PC |        MASK       | TYPE |
     96     *  --------------------------------------------------
     97     */
     98
     99    if (slave) {
    100        assert(dev->slave_count < GRLIB_AHB_MAX_DEV);
    101        reg_start = (GRLIB_AHB_SLAVE_OFFSET
    102                  + (dev->slave_count * GRLIB_AHB_ENTRY_SIZE)) >> 2;
    103        dev->slave_count++;
    104    } else {
    105        assert(dev->master_count < GRLIB_AHB_MAX_DEV);
    106        reg_start = (dev->master_count * GRLIB_AHB_ENTRY_SIZE) >> 2;
    107        dev->master_count++;
    108    }
    109
    110    dev->regs[reg_start] = deposit32(dev->regs[reg_start],
    111                                     GRLIB_PNP_VENDOR_SHIFT,
    112                                     GRLIB_PNP_VENDOR_SIZE,
    113                                     vendor);
    114    dev->regs[reg_start] = deposit32(dev->regs[reg_start],
    115                                     GRLIB_PNP_DEV_SHIFT,
    116                                     GRLIB_PNP_DEV_SIZE,
    117                                     device);
    118    reg_start += 4;
    119    /* AHB Memory Space */
    120    dev->regs[reg_start] = type;
    121    dev->regs[reg_start] = deposit32(dev->regs[reg_start],
    122                                     GRLIB_PNP_ADDR_SHIFT,
    123                                     GRLIB_PNP_ADDR_SIZE,
    124                                     extract32(address,
    125                                               GRLIB_AHB_DEV_ADDR_SHIFT,
    126                                               GRLIB_AHB_DEV_ADDR_SIZE));
    127    dev->regs[reg_start] = deposit32(dev->regs[reg_start],
    128                                     GRLIB_PNP_MASK_SHIFT,
    129                                     GRLIB_PNP_MASK_SIZE,
    130                                     mask);
    131}
    132
    133static uint64_t grlib_ahb_pnp_read(void *opaque, hwaddr offset, unsigned size)
    134{
    135    AHBPnp *ahb_pnp = GRLIB_AHB_PNP(opaque);
    136    uint32_t val;
    137
    138    val = ahb_pnp->regs[offset >> 2];
    139    trace_grlib_ahb_pnp_read(offset, val);
    140
    141    return val;
    142}
    143
    144static void grlib_ahb_pnp_write(void *opaque, hwaddr addr,
    145                                uint64_t val, unsigned size)
    146{
    147    qemu_log_mask(LOG_UNIMP, "%s not implemented\n", __func__);
    148}
    149
    150static const MemoryRegionOps grlib_ahb_pnp_ops = {
    151    .read       = grlib_ahb_pnp_read,
    152    .write      = grlib_ahb_pnp_write,
    153    .endianness = DEVICE_BIG_ENDIAN,
    154    .impl = {
    155        .min_access_size = 4,
    156        .max_access_size = 4,
    157    },
    158};
    159
    160static void grlib_ahb_pnp_realize(DeviceState *dev, Error **errp)
    161{
    162    AHBPnp *ahb_pnp = GRLIB_AHB_PNP(dev);
    163    SysBusDevice *sbd = SYS_BUS_DEVICE(dev);
    164
    165    memory_region_init_io(&ahb_pnp->iomem, OBJECT(dev), &grlib_ahb_pnp_ops,
    166                          ahb_pnp, TYPE_GRLIB_AHB_PNP, GRLIB_PNP_MAX_REGS);
    167    sysbus_init_mmio(sbd, &ahb_pnp->iomem);
    168}
    169
    170static void grlib_ahb_pnp_class_init(ObjectClass *klass, void *data)
    171{
    172    DeviceClass *dc = DEVICE_CLASS(klass);
    173
    174    dc->realize = grlib_ahb_pnp_realize;
    175}
    176
    177static const TypeInfo grlib_ahb_pnp_info = {
    178    .name          = TYPE_GRLIB_AHB_PNP,
    179    .parent        = TYPE_SYS_BUS_DEVICE,
    180    .instance_size = sizeof(AHBPnp),
    181    .class_init    = grlib_ahb_pnp_class_init,
    182};
    183
    184/* APBPnp */
    185
    186typedef struct APBPnp {
    187    SysBusDevice parent_obj;
    188    MemoryRegion iomem;
    189
    190    uint32_t regs[GRLIB_PNP_MAX_REGS >> 2];
    191    uint32_t entry_count;
    192} APBPnp;
    193
    194void grlib_apb_pnp_add_entry(APBPnp *dev, uint32_t address, uint32_t mask,
    195                             uint8_t vendor, uint16_t device, uint8_t version,
    196                             uint8_t irq, int type)
    197{
    198    unsigned int reg_start;
    199
    200    /*
    201     * APB entries look like this:
    202     *
    203     * 31 -------- 23 -------- 11 ----- 9 ------- 4 --- 0
    204     *  | VENDOR ID | DEVICE ID | IRQ ? | VERSION | IRQ |
    205     *
    206     * 31 ---------- 20 --- 15 ----------------- 3 ---- 0
    207     *  | ADDR[20..8] | 0000 |        MASK       | TYPE |
    208     */
    209
    210    assert(dev->entry_count < GRLIB_APB_MAX_DEV);
    211    reg_start = (dev->entry_count * GRLIB_APB_ENTRY_SIZE) >> 2;
    212    dev->entry_count++;
    213
    214    dev->regs[reg_start] = deposit32(dev->regs[reg_start],
    215                                     GRLIB_PNP_VENDOR_SHIFT,
    216                                     GRLIB_PNP_VENDOR_SIZE,
    217                                     vendor);
    218    dev->regs[reg_start] = deposit32(dev->regs[reg_start],
    219                                     GRLIB_PNP_DEV_SHIFT,
    220                                     GRLIB_PNP_DEV_SIZE,
    221                                     device);
    222    dev->regs[reg_start] = deposit32(dev->regs[reg_start],
    223                                     GRLIB_PNP_VER_SHIFT,
    224                                     GRLIB_PNP_VER_SIZE,
    225                                     version);
    226    dev->regs[reg_start] = deposit32(dev->regs[reg_start],
    227                                     GRLIB_PNP_IRQ_SHIFT,
    228                                     GRLIB_PNP_IRQ_SIZE,
    229                                     irq);
    230    reg_start += 1;
    231    dev->regs[reg_start] = type;
    232    dev->regs[reg_start] = deposit32(dev->regs[reg_start],
    233                                     GRLIB_PNP_ADDR_SHIFT,
    234                                     GRLIB_PNP_ADDR_SIZE,
    235                                     extract32(address,
    236                                               GRLIB_APB_DEV_ADDR_SHIFT,
    237                                               GRLIB_APB_DEV_ADDR_SIZE));
    238    dev->regs[reg_start] = deposit32(dev->regs[reg_start],
    239                                     GRLIB_PNP_MASK_SHIFT,
    240                                     GRLIB_PNP_MASK_SIZE,
    241                                     mask);
    242}
    243
    244static uint64_t grlib_apb_pnp_read(void *opaque, hwaddr offset, unsigned size)
    245{
    246    APBPnp *apb_pnp = GRLIB_APB_PNP(opaque);
    247    uint32_t val;
    248
    249    val = apb_pnp->regs[offset >> 2];
    250    trace_grlib_apb_pnp_read(offset, val);
    251
    252    return val;
    253}
    254
    255static void grlib_apb_pnp_write(void *opaque, hwaddr addr,
    256                                uint64_t val, unsigned size)
    257{
    258    qemu_log_mask(LOG_UNIMP, "%s not implemented\n", __func__);
    259}
    260
    261static const MemoryRegionOps grlib_apb_pnp_ops = {
    262    .read       = grlib_apb_pnp_read,
    263    .write      = grlib_apb_pnp_write,
    264    .endianness = DEVICE_BIG_ENDIAN,
    265    .impl = {
    266        .min_access_size = 4,
    267        .max_access_size = 4,
    268    },
    269};
    270
    271static void grlib_apb_pnp_realize(DeviceState *dev, Error **errp)
    272{
    273    APBPnp *apb_pnp = GRLIB_APB_PNP(dev);
    274    SysBusDevice *sbd = SYS_BUS_DEVICE(dev);
    275
    276    memory_region_init_io(&apb_pnp->iomem, OBJECT(dev), &grlib_apb_pnp_ops,
    277                          apb_pnp, TYPE_GRLIB_APB_PNP, GRLIB_PNP_MAX_REGS);
    278    sysbus_init_mmio(sbd, &apb_pnp->iomem);
    279}
    280
    281static void grlib_apb_pnp_class_init(ObjectClass *klass, void *data)
    282{
    283    DeviceClass *dc = DEVICE_CLASS(klass);
    284
    285    dc->realize = grlib_apb_pnp_realize;
    286}
    287
    288static const TypeInfo grlib_apb_pnp_info = {
    289    .name          = TYPE_GRLIB_APB_PNP,
    290    .parent        = TYPE_SYS_BUS_DEVICE,
    291    .instance_size = sizeof(APBPnp),
    292    .class_init    = grlib_apb_pnp_class_init,
    293};
    294
    295static void grlib_ahb_apb_pnp_register_types(void)
    296{
    297    type_register_static(&grlib_ahb_pnp_info);
    298    type_register_static(&grlib_apb_pnp_info);
    299}
    300
    301type_init(grlib_ahb_apb_pnp_register_types)