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

lasi.c (9561B)


      1/*
      2 * HP-PARISC Lasi chipset emulation.
      3 *
      4 * (C) 2019 by Helge Deller <deller@gmx.de>
      5 *
      6 * This work is licensed under the GNU GPL license version 2 or later.
      7 *
      8 * Documentation available at:
      9 * https://parisc.wiki.kernel.org/images-parisc/7/79/Lasi_ers.pdf
     10 */
     11
     12#include "qemu/osdep.h"
     13#include "qemu/units.h"
     14#include "qemu/log.h"
     15#include "qapi/error.h"
     16#include "trace.h"
     17#include "hw/irq.h"
     18#include "sysemu/sysemu.h"
     19#include "sysemu/runstate.h"
     20#include "hppa_sys.h"
     21#include "hw/net/lasi_82596.h"
     22#include "hw/char/parallel.h"
     23#include "hw/char/serial.h"
     24#include "hw/input/lasips2.h"
     25#include "migration/vmstate.h"
     26#include "qom/object.h"
     27
     28#define TYPE_LASI_CHIP "lasi-chip"
     29
     30#define LASI_IRR        0x00    /* RO */
     31#define LASI_IMR        0x04
     32#define LASI_IPR        0x08
     33#define LASI_ICR        0x0c
     34#define LASI_IAR        0x10
     35
     36#define LASI_PCR        0x0C000 /* LASI Power Control register */
     37#define LASI_ERRLOG     0x0C004 /* LASI Error Logging register */
     38#define LASI_VER        0x0C008 /* LASI Version Control register */
     39#define LASI_IORESET    0x0C00C /* LASI I/O Reset register */
     40#define LASI_AMR        0x0C010 /* LASI Arbitration Mask register */
     41#define LASI_IO_CONF    0x7FFFE /* LASI primary configuration register */
     42#define LASI_IO_CONF2   0x7FFFF /* LASI secondary configuration register */
     43
     44#define LASI_BIT(x)     (1ul << (x))
     45#define LASI_IRQ_BITS   (LASI_BIT(5) | LASI_BIT(7) | LASI_BIT(8) | LASI_BIT(9) \
     46            | LASI_BIT(13) | LASI_BIT(14) | LASI_BIT(16) | LASI_BIT(17) \
     47            | LASI_BIT(18) | LASI_BIT(19) | LASI_BIT(20) | LASI_BIT(21) \
     48            | LASI_BIT(26))
     49
     50#define ICR_BUS_ERROR_BIT  LASI_BIT(8)  /* bit 8 in ICR */
     51#define ICR_TOC_BIT        LASI_BIT(1)  /* bit 1 in ICR */
     52
     53OBJECT_DECLARE_SIMPLE_TYPE(LasiState, LASI_CHIP)
     54
     55struct LasiState {
     56    PCIHostState parent_obj;
     57
     58    uint32_t irr;
     59    uint32_t imr;
     60    uint32_t ipr;
     61    uint32_t icr;
     62    uint32_t iar;
     63
     64    uint32_t errlog;
     65    uint32_t amr;
     66    uint32_t rtc;
     67    time_t rtc_ref;
     68
     69    MemoryRegion this_mem;
     70};
     71
     72static bool lasi_chip_mem_valid(void *opaque, hwaddr addr,
     73                                unsigned size, bool is_write,
     74                                MemTxAttrs attrs)
     75{
     76    bool ret = false;
     77
     78    switch (addr) {
     79    case LASI_IRR:
     80    case LASI_IMR:
     81    case LASI_IPR:
     82    case LASI_ICR:
     83    case LASI_IAR:
     84
     85    case (LASI_LAN_HPA - LASI_HPA):
     86    case (LASI_LPT_HPA - LASI_HPA):
     87    case (LASI_UART_HPA - LASI_HPA):
     88    case (LASI_RTC_HPA - LASI_HPA):
     89
     90    case LASI_PCR ... LASI_AMR:
     91        ret = true;
     92    }
     93
     94    trace_lasi_chip_mem_valid(addr, ret);
     95    return ret;
     96}
     97
     98static MemTxResult lasi_chip_read_with_attrs(void *opaque, hwaddr addr,
     99                                             uint64_t *data, unsigned size,
    100                                             MemTxAttrs attrs)
    101{
    102    LasiState *s = opaque;
    103    MemTxResult ret = MEMTX_OK;
    104    uint32_t val;
    105
    106    switch (addr) {
    107    case LASI_IRR:
    108        val = s->irr;
    109        break;
    110    case LASI_IMR:
    111        val = s->imr;
    112        break;
    113    case LASI_IPR:
    114        val = s->ipr;
    115        /* Any read to IPR clears the register.  */
    116        s->ipr = 0;
    117        break;
    118    case LASI_ICR:
    119        val = s->icr & ICR_BUS_ERROR_BIT; /* bus_error */
    120        break;
    121    case LASI_IAR:
    122        val = s->iar;
    123        break;
    124
    125    case (LASI_LAN_HPA - LASI_HPA):
    126    case (LASI_LPT_HPA - LASI_HPA):
    127    case (LASI_UART_HPA - LASI_HPA):
    128        val = 0;
    129        break;
    130    case (LASI_RTC_HPA - LASI_HPA):
    131        val = time(NULL);
    132        val += s->rtc_ref;
    133        break;
    134
    135    case LASI_PCR:
    136    case LASI_VER:      /* only version 0 existed. */
    137    case LASI_IORESET:
    138        val = 0;
    139        break;
    140    case LASI_ERRLOG:
    141        val = s->errlog;
    142        break;
    143    case LASI_AMR:
    144        val = s->amr;
    145        break;
    146
    147    default:
    148        /* Controlled by lasi_chip_mem_valid above. */
    149        g_assert_not_reached();
    150    }
    151
    152    trace_lasi_chip_read(addr, val);
    153
    154    *data = val;
    155    return ret;
    156}
    157
    158static MemTxResult lasi_chip_write_with_attrs(void *opaque, hwaddr addr,
    159                                              uint64_t val, unsigned size,
    160                                              MemTxAttrs attrs)
    161{
    162    LasiState *s = opaque;
    163
    164    trace_lasi_chip_write(addr, val);
    165
    166    switch (addr) {
    167    case LASI_IRR:
    168        /* read-only.  */
    169        break;
    170    case LASI_IMR:
    171        s->imr = val;
    172        if (((val & LASI_IRQ_BITS) != val) && (val != 0xffffffff))
    173            qemu_log_mask(LOG_GUEST_ERROR,
    174                "LASI: tried to set invalid %lx IMR value.\n",
    175                (unsigned long) val);
    176        break;
    177    case LASI_IPR:
    178        /* Any write to IPR clears the register. */
    179        s->ipr = 0;
    180        break;
    181    case LASI_ICR:
    182        s->icr = val;
    183        /* if (val & ICR_TOC_BIT) issue_toc(); */
    184        break;
    185    case LASI_IAR:
    186        s->iar = val;
    187        break;
    188
    189    case (LASI_LAN_HPA - LASI_HPA):
    190        /* XXX: reset LAN card */
    191        break;
    192    case (LASI_LPT_HPA - LASI_HPA):
    193        /* XXX: reset parallel port */
    194        break;
    195    case (LASI_UART_HPA - LASI_HPA):
    196        /* XXX: reset serial port */
    197        break;
    198    case (LASI_RTC_HPA - LASI_HPA):
    199        s->rtc_ref = val - time(NULL);
    200        break;
    201
    202    case LASI_PCR:
    203        if (val == 0x02) /* immediately power off */
    204            qemu_system_shutdown_request(SHUTDOWN_CAUSE_GUEST_SHUTDOWN);
    205        break;
    206    case LASI_ERRLOG:
    207        s->errlog = val;
    208        break;
    209    case LASI_VER:
    210        /* read-only.  */
    211        break;
    212    case LASI_IORESET:
    213        break;  /* XXX: TODO: Reset various devices. */
    214    case LASI_AMR:
    215        s->amr = val;
    216        break;
    217
    218    default:
    219        /* Controlled by lasi_chip_mem_valid above. */
    220        g_assert_not_reached();
    221    }
    222    return MEMTX_OK;
    223}
    224
    225static const MemoryRegionOps lasi_chip_ops = {
    226    .read_with_attrs = lasi_chip_read_with_attrs,
    227    .write_with_attrs = lasi_chip_write_with_attrs,
    228    .endianness = DEVICE_BIG_ENDIAN,
    229    .valid = {
    230        .min_access_size = 1,
    231        .max_access_size = 4,
    232        .accepts = lasi_chip_mem_valid,
    233    },
    234    .impl = {
    235        .min_access_size = 1,
    236        .max_access_size = 4,
    237    },
    238};
    239
    240static const VMStateDescription vmstate_lasi = {
    241    .name = "Lasi",
    242    .version_id = 1,
    243    .minimum_version_id = 1,
    244    .fields = (VMStateField[]) {
    245        VMSTATE_UINT32(irr, LasiState),
    246        VMSTATE_UINT32(imr, LasiState),
    247        VMSTATE_UINT32(ipr, LasiState),
    248        VMSTATE_UINT32(icr, LasiState),
    249        VMSTATE_UINT32(iar, LasiState),
    250        VMSTATE_UINT32(errlog, LasiState),
    251        VMSTATE_UINT32(amr, LasiState),
    252        VMSTATE_END_OF_LIST()
    253    }
    254};
    255
    256
    257static void lasi_set_irq(void *opaque, int irq, int level)
    258{
    259    LasiState *s = opaque;
    260    uint32_t bit = 1u << irq;
    261
    262    if (level) {
    263        s->ipr |= bit;
    264        if (bit & s->imr) {
    265            uint32_t iar = s->iar;
    266            s->irr |= bit;
    267            if ((s->icr & ICR_BUS_ERROR_BIT) == 0) {
    268                stl_be_phys(&address_space_memory, iar & -32, iar & 31);
    269            }
    270        }
    271    }
    272}
    273
    274static int lasi_get_irq(unsigned long hpa)
    275{
    276    switch (hpa) {
    277    case LASI_HPA:
    278        return 14;
    279    case LASI_UART_HPA:
    280        return 5;
    281    case LASI_LPT_HPA:
    282        return 7;
    283    case LASI_LAN_HPA:
    284        return 8;
    285    case LASI_SCSI_HPA:
    286        return 9;
    287    case LASI_AUDIO_HPA:
    288        return 13;
    289    case LASI_PS2KBD_HPA:
    290    case LASI_PS2MOU_HPA:
    291        return 26;
    292    default:
    293        g_assert_not_reached();
    294    }
    295}
    296
    297DeviceState *lasi_init(MemoryRegion *address_space)
    298{
    299    DeviceState *dev;
    300    LasiState *s;
    301
    302    dev = qdev_new(TYPE_LASI_CHIP);
    303    s = LASI_CHIP(dev);
    304    s->iar = CPU_HPA + 3;
    305
    306    /* Lasi access from main memory.  */
    307    memory_region_init_io(&s->this_mem, OBJECT(s), &lasi_chip_ops,
    308                          s, "lasi", 0x100000);
    309    memory_region_add_subregion(address_space, LASI_HPA, &s->this_mem);
    310
    311    sysbus_realize_and_unref(SYS_BUS_DEVICE(dev), &error_fatal);
    312
    313    /* LAN */
    314    if (enable_lasi_lan()) {
    315        qemu_irq lan_irq = qemu_allocate_irq(lasi_set_irq, s,
    316                lasi_get_irq(LASI_LAN_HPA));
    317        lasi_82596_init(address_space, LASI_LAN_HPA, lan_irq);
    318    }
    319
    320    /* Parallel port */
    321    qemu_irq lpt_irq = qemu_allocate_irq(lasi_set_irq, s,
    322            lasi_get_irq(LASI_LPT_HPA));
    323    parallel_mm_init(address_space, LASI_LPT_HPA + 0x800, 0,
    324                     lpt_irq, parallel_hds[0]);
    325
    326    /* Real time clock (RTC), it's only one 32-bit counter @9000 */
    327
    328    s->rtc = time(NULL);
    329    s->rtc_ref = 0;
    330
    331    if (serial_hd(1)) {
    332        /* Serial port */
    333        qemu_irq serial_irq = qemu_allocate_irq(lasi_set_irq, s,
    334                lasi_get_irq(LASI_UART_HPA));
    335        serial_mm_init(address_space, LASI_UART_HPA + 0x800, 0,
    336                serial_irq, 8000000 / 16,
    337                serial_hd(0), DEVICE_NATIVE_ENDIAN);
    338    }
    339
    340    /* PS/2 Keyboard/Mouse */
    341    qemu_irq ps2kbd_irq = qemu_allocate_irq(lasi_set_irq, s,
    342            lasi_get_irq(LASI_PS2KBD_HPA));
    343    lasips2_init(address_space, LASI_PS2KBD_HPA,  ps2kbd_irq);
    344
    345    return dev;
    346}
    347
    348static void lasi_class_init(ObjectClass *klass, void *data)
    349{
    350    DeviceClass *dc = DEVICE_CLASS(klass);
    351
    352    dc->vmsd = &vmstate_lasi;
    353}
    354
    355static const TypeInfo lasi_pcihost_info = {
    356    .name          = TYPE_LASI_CHIP,
    357    .parent        = TYPE_SYS_BUS_DEVICE,
    358    .instance_size = sizeof(LasiState),
    359    .class_init    = lasi_class_init,
    360};
    361
    362static void lasi_register_types(void)
    363{
    364    type_register_static(&lasi_pcihost_info);
    365}
    366
    367type_init(lasi_register_types)