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

cs4231.c (4859B)


      1/*
      2 * QEMU Crystal CS4231 audio chip emulation
      3 *
      4 * Copyright (c) 2006 Fabrice Bellard
      5 *
      6 * Permission is hereby granted, free of charge, to any person obtaining a copy
      7 * of this software and associated documentation files (the "Software"), to deal
      8 * in the Software without restriction, including without limitation the rights
      9 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
     10 * copies of the Software, and to permit persons to whom the Software is
     11 * furnished to do so, subject to the following conditions:
     12 *
     13 * The above copyright notice and this permission notice shall be included in
     14 * all copies or substantial portions of the Software.
     15 *
     16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
     17 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
     18 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
     19 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
     20 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
     21 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
     22 * THE SOFTWARE.
     23 */
     24
     25#include "qemu/osdep.h"
     26#include "hw/sysbus.h"
     27#include "migration/vmstate.h"
     28#include "qemu/module.h"
     29#include "trace.h"
     30#include "qom/object.h"
     31
     32/*
     33 * In addition to Crystal CS4231 there is a DMA controller on Sparc.
     34 */
     35#define CS_SIZE 0x40
     36#define CS_REGS 16
     37#define CS_DREGS 32
     38#define CS_MAXDREG (CS_DREGS - 1)
     39
     40#define TYPE_CS4231 "sun-CS4231"
     41typedef struct CSState CSState;
     42DECLARE_INSTANCE_CHECKER(CSState, CS4231,
     43                         TYPE_CS4231)
     44
     45struct CSState {
     46    SysBusDevice parent_obj;
     47
     48    MemoryRegion iomem;
     49    qemu_irq irq;
     50    uint32_t regs[CS_REGS];
     51    uint8_t dregs[CS_DREGS];
     52};
     53
     54#define CS_RAP(s) ((s)->regs[0] & CS_MAXDREG)
     55#define CS_VER 0xa0
     56#define CS_CDC_VER 0x8a
     57
     58static void cs_reset(DeviceState *d)
     59{
     60    CSState *s = CS4231(d);
     61
     62    memset(s->regs, 0, CS_REGS * 4);
     63    memset(s->dregs, 0, CS_DREGS);
     64    s->dregs[12] = CS_CDC_VER;
     65    s->dregs[25] = CS_VER;
     66}
     67
     68static uint64_t cs_mem_read(void *opaque, hwaddr addr,
     69                            unsigned size)
     70{
     71    CSState *s = opaque;
     72    uint32_t saddr, ret;
     73
     74    saddr = addr >> 2;
     75    switch (saddr) {
     76    case 1:
     77        switch (CS_RAP(s)) {
     78        case 3: // Write only
     79            ret = 0;
     80            break;
     81        default:
     82            ret = s->dregs[CS_RAP(s)];
     83            break;
     84        }
     85        trace_cs4231_mem_readl_dreg(CS_RAP(s), ret);
     86        break;
     87    default:
     88        ret = s->regs[saddr];
     89        trace_cs4231_mem_readl_reg(saddr, ret);
     90        break;
     91    }
     92    return ret;
     93}
     94
     95static void cs_mem_write(void *opaque, hwaddr addr,
     96                         uint64_t val, unsigned size)
     97{
     98    CSState *s = opaque;
     99    uint32_t saddr;
    100
    101    saddr = addr >> 2;
    102    trace_cs4231_mem_writel_reg(saddr, s->regs[saddr], val);
    103    switch (saddr) {
    104    case 1:
    105        trace_cs4231_mem_writel_dreg(CS_RAP(s), s->dregs[CS_RAP(s)], val);
    106        switch(CS_RAP(s)) {
    107        case 11:
    108        case 25: // Read only
    109            break;
    110        case 12:
    111            val &= 0x40;
    112            val |= CS_CDC_VER; // Codec version
    113            s->dregs[CS_RAP(s)] = val;
    114            break;
    115        default:
    116            s->dregs[CS_RAP(s)] = val;
    117            break;
    118        }
    119        break;
    120    case 2: // Read only
    121        break;
    122    case 4:
    123        if (val & 1) {
    124            cs_reset(DEVICE(s));
    125        }
    126        val &= 0x7f;
    127        s->regs[saddr] = val;
    128        break;
    129    default:
    130        s->regs[saddr] = val;
    131        break;
    132    }
    133}
    134
    135static const MemoryRegionOps cs_mem_ops = {
    136    .read = cs_mem_read,
    137    .write = cs_mem_write,
    138    .endianness = DEVICE_NATIVE_ENDIAN,
    139};
    140
    141static const VMStateDescription vmstate_cs4231 = {
    142    .name ="cs4231",
    143    .version_id = 1,
    144    .minimum_version_id = 1,
    145    .fields = (VMStateField[]) {
    146        VMSTATE_UINT32_ARRAY(regs, CSState, CS_REGS),
    147        VMSTATE_UINT8_ARRAY(dregs, CSState, CS_DREGS),
    148        VMSTATE_END_OF_LIST()
    149    }
    150};
    151
    152static void cs4231_init(Object *obj)
    153{
    154    CSState *s = CS4231(obj);
    155    SysBusDevice *dev = SYS_BUS_DEVICE(obj);
    156
    157    memory_region_init_io(&s->iomem, obj, &cs_mem_ops, s, "cs4321",
    158                          CS_SIZE);
    159    sysbus_init_mmio(dev, &s->iomem);
    160    sysbus_init_irq(dev, &s->irq);
    161}
    162
    163static void cs4231_class_init(ObjectClass *klass, void *data)
    164{
    165    DeviceClass *dc = DEVICE_CLASS(klass);
    166
    167    dc->reset = cs_reset;
    168    dc->vmsd = &vmstate_cs4231;
    169}
    170
    171static const TypeInfo cs4231_info = {
    172    .name          = TYPE_CS4231,
    173    .parent        = TYPE_SYS_BUS_DEVICE,
    174    .instance_size = sizeof(CSState),
    175    .instance_init = cs4231_init,
    176    .class_init    = cs4231_class_init,
    177};
    178
    179static void cs4231_register_types(void)
    180{
    181    type_register_static(&cs4231_info);
    182}
    183
    184type_init(cs4231_register_types)