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

allwinner-h3-sysctrl.c (4176B)


      1/*
      2 * Allwinner H3 System Control emulation
      3 *
      4 * Copyright (C) 2019 Niek Linnenbank <nieklinnenbank@gmail.com>
      5 *
      6 * This program is free software: you can redistribute it and/or modify
      7 * it under the terms of the GNU General Public License as published by
      8 * the Free Software Foundation, either version 2 of the License, or
      9 * (at your option) any later version.
     10 *
     11 * This program is distributed in the hope that it will be useful,
     12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
     13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     14 * GNU General Public License for more details.
     15 *
     16 * You should have received a copy of the GNU General Public License
     17 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
     18 */
     19
     20#include "qemu/osdep.h"
     21#include "qemu/units.h"
     22#include "hw/sysbus.h"
     23#include "migration/vmstate.h"
     24#include "qemu/log.h"
     25#include "qemu/module.h"
     26#include "hw/misc/allwinner-h3-sysctrl.h"
     27
     28/* System Control register offsets */
     29enum {
     30    REG_VER               = 0x24,  /* Version */
     31    REG_EMAC_PHY_CLK      = 0x30,  /* EMAC PHY Clock */
     32};
     33
     34#define REG_INDEX(offset)   (offset / sizeof(uint32_t))
     35
     36/* System Control register reset values */
     37enum {
     38    REG_VER_RST           = 0x0,
     39    REG_EMAC_PHY_CLK_RST  = 0x58000,
     40};
     41
     42static uint64_t allwinner_h3_sysctrl_read(void *opaque, hwaddr offset,
     43                                          unsigned size)
     44{
     45    const AwH3SysCtrlState *s = AW_H3_SYSCTRL(opaque);
     46    const uint32_t idx = REG_INDEX(offset);
     47
     48    if (idx >= AW_H3_SYSCTRL_REGS_NUM) {
     49        qemu_log_mask(LOG_GUEST_ERROR, "%s: out-of-bounds offset 0x%04x\n",
     50                      __func__, (uint32_t)offset);
     51        return 0;
     52    }
     53
     54    return s->regs[idx];
     55}
     56
     57static void allwinner_h3_sysctrl_write(void *opaque, hwaddr offset,
     58                                       uint64_t val, unsigned size)
     59{
     60    AwH3SysCtrlState *s = AW_H3_SYSCTRL(opaque);
     61    const uint32_t idx = REG_INDEX(offset);
     62
     63    if (idx >= AW_H3_SYSCTRL_REGS_NUM) {
     64        qemu_log_mask(LOG_GUEST_ERROR, "%s: out-of-bounds offset 0x%04x\n",
     65                      __func__, (uint32_t)offset);
     66        return;
     67    }
     68
     69    switch (offset) {
     70    case REG_VER:       /* Version */
     71        break;
     72    default:
     73        s->regs[idx] = (uint32_t) val;
     74        break;
     75    }
     76}
     77
     78static const MemoryRegionOps allwinner_h3_sysctrl_ops = {
     79    .read = allwinner_h3_sysctrl_read,
     80    .write = allwinner_h3_sysctrl_write,
     81    .endianness = DEVICE_NATIVE_ENDIAN,
     82    .valid = {
     83        .min_access_size = 4,
     84        .max_access_size = 4,
     85    },
     86    .impl.min_access_size = 4,
     87};
     88
     89static void allwinner_h3_sysctrl_reset(DeviceState *dev)
     90{
     91    AwH3SysCtrlState *s = AW_H3_SYSCTRL(dev);
     92
     93    /* Set default values for registers */
     94    s->regs[REG_INDEX(REG_VER)] = REG_VER_RST;
     95    s->regs[REG_INDEX(REG_EMAC_PHY_CLK)] = REG_EMAC_PHY_CLK_RST;
     96}
     97
     98static void allwinner_h3_sysctrl_init(Object *obj)
     99{
    100    SysBusDevice *sbd = SYS_BUS_DEVICE(obj);
    101    AwH3SysCtrlState *s = AW_H3_SYSCTRL(obj);
    102
    103    /* Memory mapping */
    104    memory_region_init_io(&s->iomem, OBJECT(s), &allwinner_h3_sysctrl_ops, s,
    105                           TYPE_AW_H3_SYSCTRL, 4 * KiB);
    106    sysbus_init_mmio(sbd, &s->iomem);
    107}
    108
    109static const VMStateDescription allwinner_h3_sysctrl_vmstate = {
    110    .name = "allwinner-h3-sysctrl",
    111    .version_id = 1,
    112    .minimum_version_id = 1,
    113    .fields = (VMStateField[]) {
    114        VMSTATE_UINT32_ARRAY(regs, AwH3SysCtrlState, AW_H3_SYSCTRL_REGS_NUM),
    115        VMSTATE_END_OF_LIST()
    116    }
    117};
    118
    119static void allwinner_h3_sysctrl_class_init(ObjectClass *klass, void *data)
    120{
    121    DeviceClass *dc = DEVICE_CLASS(klass);
    122
    123    dc->reset = allwinner_h3_sysctrl_reset;
    124    dc->vmsd = &allwinner_h3_sysctrl_vmstate;
    125}
    126
    127static const TypeInfo allwinner_h3_sysctrl_info = {
    128    .name          = TYPE_AW_H3_SYSCTRL,
    129    .parent        = TYPE_SYS_BUS_DEVICE,
    130    .instance_init = allwinner_h3_sysctrl_init,
    131    .instance_size = sizeof(AwH3SysCtrlState),
    132    .class_init    = allwinner_h3_sysctrl_class_init,
    133};
    134
    135static void allwinner_h3_sysctrl_register(void)
    136{
    137    type_register_static(&allwinner_h3_sysctrl_info);
    138}
    139
    140type_init(allwinner_h3_sysctrl_register)