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

dpcd.c (4788B)


      1/*
      2 * Xilinx Display Port Control Data
      3 *
      4 *  Copyright (C) 2015 : GreenSocs Ltd
      5 *      http://www.greensocs.com/ , email: info@greensocs.com
      6 *
      7 *  Developed by :
      8 *  Frederic Konrad   <fred.konrad@greensocs.com>
      9 *
     10 * This program is free software; you can redistribute it and/or modify
     11 * it under the terms of the GNU General Public License as published by
     12 * the Free Software Foundation, either version 2 of the License, or
     13 * (at your option)any later version.
     14 *
     15 * This program is distributed in the hope that it will be useful,
     16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
     17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     18 * GNU General Public License for more details.
     19 *
     20 * You should have received a copy of the GNU General Public License along
     21 * with this program; if not, see <http://www.gnu.org/licenses/>.
     22 *
     23 */
     24
     25/*
     26 * This is a simple AUX slave which emulates a connected screen.
     27 */
     28
     29#include "qemu/osdep.h"
     30#include "qemu/log.h"
     31#include "qemu/module.h"
     32#include "hw/misc/auxbus.h"
     33#include "migration/vmstate.h"
     34#include "hw/display/dpcd.h"
     35#include "trace.h"
     36
     37#define DPCD_READABLE_AREA                      0x600
     38
     39struct DPCDState {
     40    /*< private >*/
     41    AUXSlave parent_obj;
     42
     43    /*< public >*/
     44    /*
     45     * The DCPD is 0x7FFFF length but read as 0 after offset 0x5FF.
     46     */
     47    uint8_t dpcd_info[DPCD_READABLE_AREA];
     48
     49    MemoryRegion iomem;
     50};
     51
     52static uint64_t dpcd_read(void *opaque, hwaddr offset, unsigned size)
     53{
     54    uint8_t ret;
     55    DPCDState *e = DPCD(opaque);
     56
     57    if (offset < DPCD_READABLE_AREA) {
     58        ret = e->dpcd_info[offset];
     59    } else {
     60        qemu_log_mask(LOG_GUEST_ERROR, "dpcd: Bad offset 0x%" HWADDR_PRIX "\n",
     61                                       offset);
     62        ret = 0;
     63    }
     64    trace_dpcd_read(offset, ret);
     65
     66    return ret;
     67}
     68
     69static void dpcd_write(void *opaque, hwaddr offset, uint64_t value,
     70                       unsigned size)
     71{
     72    DPCDState *e = DPCD(opaque);
     73
     74    trace_dpcd_write(offset, value);
     75    if (offset < DPCD_READABLE_AREA) {
     76        e->dpcd_info[offset] = value;
     77    } else {
     78        qemu_log_mask(LOG_GUEST_ERROR, "dpcd: Bad offset 0x%" HWADDR_PRIX "\n",
     79                                       offset);
     80    }
     81}
     82
     83static const MemoryRegionOps aux_ops = {
     84    .read = dpcd_read,
     85    .write = dpcd_write,
     86    .valid = {
     87        .min_access_size = 1,
     88        .max_access_size = 1,
     89    },
     90    .impl = {
     91        .min_access_size = 1,
     92        .max_access_size = 1,
     93    },
     94};
     95
     96static void dpcd_reset(DeviceState *dev)
     97{
     98    DPCDState *s = DPCD(dev);
     99
    100    memset(&(s->dpcd_info), 0, sizeof(s->dpcd_info));
    101
    102    s->dpcd_info[DPCD_REVISION] = DPCD_REV_1_0;
    103    s->dpcd_info[DPCD_MAX_LINK_RATE] = DPCD_5_4GBPS;
    104    s->dpcd_info[DPCD_MAX_LANE_COUNT] = DPCD_FOUR_LANES;
    105    s->dpcd_info[DPCD_RECEIVE_PORT0_CAP_0] = DPCD_EDID_PRESENT;
    106    /* buffer size */
    107    s->dpcd_info[DPCD_RECEIVE_PORT0_CAP_1] = 0xFF;
    108
    109    s->dpcd_info[DPCD_LANE0_1_STATUS] = DPCD_LANE0_CR_DONE
    110                                      | DPCD_LANE0_CHANNEL_EQ_DONE
    111                                      | DPCD_LANE0_SYMBOL_LOCKED
    112                                      | DPCD_LANE1_CR_DONE
    113                                      | DPCD_LANE1_CHANNEL_EQ_DONE
    114                                      | DPCD_LANE1_SYMBOL_LOCKED;
    115    s->dpcd_info[DPCD_LANE2_3_STATUS] = DPCD_LANE2_CR_DONE
    116                                      | DPCD_LANE2_CHANNEL_EQ_DONE
    117                                      | DPCD_LANE2_SYMBOL_LOCKED
    118                                      | DPCD_LANE3_CR_DONE
    119                                      | DPCD_LANE3_CHANNEL_EQ_DONE
    120                                      | DPCD_LANE3_SYMBOL_LOCKED;
    121
    122    s->dpcd_info[DPCD_LANE_ALIGN_STATUS_UPDATED] = DPCD_INTERLANE_ALIGN_DONE;
    123    s->dpcd_info[DPCD_SINK_STATUS] = DPCD_RECEIVE_PORT_0_STATUS;
    124}
    125
    126static void dpcd_init(Object *obj)
    127{
    128    DPCDState *s = DPCD(obj);
    129
    130    memory_region_init_io(&s->iomem, obj, &aux_ops, s, TYPE_DPCD, 0x80000);
    131    aux_init_mmio(AUX_SLAVE(obj), &s->iomem);
    132}
    133
    134static const VMStateDescription vmstate_dpcd = {
    135    .name = TYPE_DPCD,
    136    .version_id = 0,
    137    .minimum_version_id = 0,
    138    .fields = (VMStateField[]) {
    139        VMSTATE_UINT8_ARRAY_V(dpcd_info, DPCDState, DPCD_READABLE_AREA, 0),
    140        VMSTATE_END_OF_LIST()
    141    }
    142};
    143
    144static void dpcd_class_init(ObjectClass *oc, void *data)
    145{
    146    DeviceClass *dc = DEVICE_CLASS(oc);
    147
    148    dc->reset = dpcd_reset;
    149    dc->vmsd = &vmstate_dpcd;
    150}
    151
    152static const TypeInfo dpcd_info = {
    153    .name          = TYPE_DPCD,
    154    .parent        = TYPE_AUX_SLAVE,
    155    .instance_size = sizeof(DPCDState),
    156    .class_init    = dpcd_class_init,
    157    .instance_init = dpcd_init,
    158};
    159
    160static void dpcd_register_types(void)
    161{
    162    type_register_static(&dpcd_info);
    163}
    164
    165type_init(dpcd_register_types)