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

imx_gpcv2.c (3501B)


      1/*
      2 * Copyright (c) 2018, Impinj, Inc.
      3 *
      4 * i.MX7 GPCv2 block emulation code
      5 *
      6 * Author: Andrey Smirnov <andrew.smirnov@gmail.com>
      7 *
      8 * This work is licensed under the terms of the GNU GPL, version 2 or later.
      9 * See the COPYING file in the top-level directory.
     10 */
     11
     12#include "qemu/osdep.h"
     13#include "hw/intc/imx_gpcv2.h"
     14#include "migration/vmstate.h"
     15#include "qemu/module.h"
     16
     17#define GPC_PU_PGC_SW_PUP_REQ       0x0f8
     18#define GPC_PU_PGC_SW_PDN_REQ       0x104
     19
     20#define USB_HSIC_PHY_SW_Pxx_REQ     BIT(4)
     21#define USB_OTG2_PHY_SW_Pxx_REQ     BIT(3)
     22#define USB_OTG1_PHY_SW_Pxx_REQ     BIT(2)
     23#define PCIE_PHY_SW_Pxx_REQ         BIT(1)
     24#define MIPI_PHY_SW_Pxx_REQ         BIT(0)
     25
     26
     27static void imx_gpcv2_reset(DeviceState *dev)
     28{
     29    IMXGPCv2State *s = IMX_GPCV2(dev);
     30
     31    memset(s->regs, 0, sizeof(s->regs));
     32}
     33
     34static uint64_t imx_gpcv2_read(void *opaque, hwaddr offset,
     35                               unsigned size)
     36{
     37    IMXGPCv2State *s = opaque;
     38
     39    return s->regs[offset / sizeof(uint32_t)];
     40}
     41
     42static void imx_gpcv2_write(void *opaque, hwaddr offset,
     43                            uint64_t value, unsigned size)
     44{
     45    IMXGPCv2State *s = opaque;
     46    const size_t idx = offset / sizeof(uint32_t);
     47
     48    s->regs[idx] = value;
     49
     50    /*
     51     * Real HW will clear those bits once as a way to indicate that
     52     * power up request is complete
     53     */
     54    if (offset == GPC_PU_PGC_SW_PUP_REQ ||
     55        offset == GPC_PU_PGC_SW_PDN_REQ) {
     56        s->regs[idx] &= ~(USB_HSIC_PHY_SW_Pxx_REQ |
     57                          USB_OTG2_PHY_SW_Pxx_REQ |
     58                          USB_OTG1_PHY_SW_Pxx_REQ |
     59                          PCIE_PHY_SW_Pxx_REQ     |
     60                          MIPI_PHY_SW_Pxx_REQ);
     61    }
     62}
     63
     64static const struct MemoryRegionOps imx_gpcv2_ops = {
     65    .read = imx_gpcv2_read,
     66    .write = imx_gpcv2_write,
     67    .endianness = DEVICE_NATIVE_ENDIAN,
     68    .impl = {
     69        /*
     70         * Our device would not work correctly if the guest was doing
     71         * unaligned access. This might not be a limitation on the real
     72         * device but in practice there is no reason for a guest to access
     73         * this device unaligned.
     74         */
     75        .min_access_size = 4,
     76        .max_access_size = 4,
     77        .unaligned = false,
     78    },
     79};
     80
     81static void imx_gpcv2_init(Object *obj)
     82{
     83    SysBusDevice *sd = SYS_BUS_DEVICE(obj);
     84    IMXGPCv2State *s = IMX_GPCV2(obj);
     85
     86    memory_region_init_io(&s->iomem,
     87                          obj,
     88                          &imx_gpcv2_ops,
     89                          s,
     90                          TYPE_IMX_GPCV2 ".iomem",
     91                          sizeof(s->regs));
     92    sysbus_init_mmio(sd, &s->iomem);
     93}
     94
     95static const VMStateDescription vmstate_imx_gpcv2 = {
     96    .name = TYPE_IMX_GPCV2,
     97    .version_id = 1,
     98    .minimum_version_id = 1,
     99    .fields = (VMStateField[]) {
    100        VMSTATE_UINT32_ARRAY(regs, IMXGPCv2State, GPC_NUM),
    101        VMSTATE_END_OF_LIST()
    102    },
    103};
    104
    105static void imx_gpcv2_class_init(ObjectClass *klass, void *data)
    106{
    107    DeviceClass *dc = DEVICE_CLASS(klass);
    108
    109    dc->reset = imx_gpcv2_reset;
    110    dc->vmsd  = &vmstate_imx_gpcv2;
    111    dc->desc  = "i.MX GPCv2 Module";
    112}
    113
    114static const TypeInfo imx_gpcv2_info = {
    115    .name          = TYPE_IMX_GPCV2,
    116    .parent        = TYPE_SYS_BUS_DEVICE,
    117    .instance_size = sizeof(IMXGPCv2State),
    118    .instance_init = imx_gpcv2_init,
    119    .class_init    = imx_gpcv2_class_init,
    120};
    121
    122static void imx_gpcv2_register_type(void)
    123{
    124    type_register_static(&imx_gpcv2_info);
    125}
    126type_init(imx_gpcv2_register_type)