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

port92.c (2880B)


      1/*
      2 * QEMU I/O port 0x92 (System Control Port A, to handle Fast Gate A20)
      3 *
      4 * Copyright (c) 2003-2004 Fabrice Bellard
      5 *
      6 * SPDX-License-Identifier: MIT
      7 */
      8
      9#include "qemu/osdep.h"
     10#include "sysemu/runstate.h"
     11#include "migration/vmstate.h"
     12#include "hw/irq.h"
     13#include "hw/i386/pc.h"
     14#include "trace.h"
     15#include "qom/object.h"
     16
     17OBJECT_DECLARE_SIMPLE_TYPE(Port92State, PORT92)
     18
     19struct Port92State {
     20    ISADevice parent_obj;
     21
     22    MemoryRegion io;
     23    uint8_t outport;
     24    qemu_irq a20_out;
     25};
     26
     27static void port92_write(void *opaque, hwaddr addr, uint64_t val,
     28                         unsigned size)
     29{
     30    Port92State *s = opaque;
     31    int oldval = s->outport;
     32
     33    trace_port92_write(val);
     34    s->outport = val;
     35    qemu_set_irq(s->a20_out, (val >> 1) & 1);
     36    if ((val & 1) && !(oldval & 1)) {
     37        qemu_system_reset_request(SHUTDOWN_CAUSE_GUEST_RESET);
     38    }
     39}
     40
     41static uint64_t port92_read(void *opaque, hwaddr addr,
     42                            unsigned size)
     43{
     44    Port92State *s = opaque;
     45    uint32_t ret;
     46
     47    ret = s->outport;
     48    trace_port92_read(ret);
     49
     50    return ret;
     51}
     52
     53static const VMStateDescription vmstate_port92_isa = {
     54    .name = "port92",
     55    .version_id = 1,
     56    .minimum_version_id = 1,
     57    .fields = (VMStateField[]) {
     58        VMSTATE_UINT8(outport, Port92State),
     59        VMSTATE_END_OF_LIST()
     60    }
     61};
     62
     63static void port92_reset(DeviceState *d)
     64{
     65    Port92State *s = PORT92(d);
     66
     67    s->outport &= ~1;
     68}
     69
     70static const MemoryRegionOps port92_ops = {
     71    .read = port92_read,
     72    .write = port92_write,
     73    .impl = {
     74        .min_access_size = 1,
     75        .max_access_size = 1,
     76    },
     77    .endianness = DEVICE_LITTLE_ENDIAN,
     78};
     79
     80static void port92_initfn(Object *obj)
     81{
     82    Port92State *s = PORT92(obj);
     83
     84    memory_region_init_io(&s->io, OBJECT(s), &port92_ops, s, "port92", 1);
     85
     86    s->outport = 0;
     87
     88    qdev_init_gpio_out_named(DEVICE(obj), &s->a20_out, PORT92_A20_LINE, 1);
     89}
     90
     91static void port92_realizefn(DeviceState *dev, Error **errp)
     92{
     93    ISADevice *isadev = ISA_DEVICE(dev);
     94    Port92State *s = PORT92(dev);
     95
     96    isa_register_ioport(isadev, &s->io, 0x92);
     97}
     98
     99static void port92_class_initfn(ObjectClass *klass, void *data)
    100{
    101    DeviceClass *dc = DEVICE_CLASS(klass);
    102
    103    dc->realize = port92_realizefn;
    104    dc->reset = port92_reset;
    105    dc->vmsd = &vmstate_port92_isa;
    106    /*
    107     * Reason: unlike ordinary ISA devices, this one needs additional
    108     * wiring: its A20 output line needs to be wired up with
    109     * qdev_connect_gpio_out_named().
    110     */
    111    dc->user_creatable = false;
    112}
    113
    114static const TypeInfo port92_info = {
    115    .name          = TYPE_PORT92,
    116    .parent        = TYPE_ISA_DEVICE,
    117    .instance_size = sizeof(Port92State),
    118    .instance_init = port92_initfn,
    119    .class_init    = port92_class_initfn,
    120};
    121
    122static void port92_register_types(void)
    123{
    124    type_register_static(&port92_info);
    125}
    126
    127type_init(port92_register_types)