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

machine.c (5439B)


      1/*
      2 *  HPPA interrupt helper routines
      3 *
      4 *  Copyright (c) 2017 Richard Henderson
      5 *
      6 * This library is free software; you can redistribute it and/or
      7 * modify it under the terms of the GNU Lesser General Public
      8 * License as published by the Free Software Foundation; either
      9 * version 2.1 of the License, or (at your option) any later version.
     10 *
     11 * This library 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 GNU
     14 * Lesser General Public License for more details.
     15 *
     16 * You should have received a copy of the GNU Lesser General Public
     17 * License along with this library; if not, see <http://www.gnu.org/licenses/>.
     18 */
     19
     20#include "qemu/osdep.h"
     21#include "cpu.h"
     22#include "migration/cpu.h"
     23
     24#if TARGET_REGISTER_BITS == 64
     25#define qemu_put_betr   qemu_put_be64
     26#define qemu_get_betr   qemu_get_be64
     27#define VMSTATE_UINTTL_V(_f, _s, _v) \
     28    VMSTATE_UINT64_V(_f, _s, _v)
     29#define VMSTATE_UINTTL_ARRAY_V(_f, _s, _n, _v) \
     30    VMSTATE_UINT64_ARRAY_V(_f, _s, _n, _v)
     31#else
     32#define qemu_put_betr   qemu_put_be32
     33#define qemu_get_betr   qemu_get_be32
     34#define VMSTATE_UINTTR_V(_f, _s, _v) \
     35    VMSTATE_UINT32_V(_f, _s, _v)
     36#define VMSTATE_UINTTR_ARRAY_V(_f, _s, _n, _v) \
     37    VMSTATE_UINT32_ARRAY_V(_f, _s, _n, _v)
     38#endif
     39
     40#define VMSTATE_UINTTR(_f, _s) \
     41    VMSTATE_UINTTR_V(_f, _s, 0)
     42#define VMSTATE_UINTTR_ARRAY(_f, _s, _n) \
     43    VMSTATE_UINTTR_ARRAY_V(_f, _s, _n, 0)
     44
     45
     46static int get_psw(QEMUFile *f, void *opaque, size_t size,
     47                   const VMStateField *field)
     48{
     49    CPUHPPAState *env = opaque;
     50    cpu_hppa_put_psw(env, qemu_get_betr(f));
     51    return 0;
     52}
     53
     54static int put_psw(QEMUFile *f, void *opaque, size_t size,
     55                   const VMStateField *field, JSONWriter *vmdesc)
     56{
     57    CPUHPPAState *env = opaque;
     58    qemu_put_betr(f, cpu_hppa_get_psw(env));
     59    return 0;
     60}
     61
     62static const VMStateInfo vmstate_psw = {
     63    .name = "psw",
     64    .get = get_psw,
     65    .put = put_psw,
     66};
     67
     68/* FIXME: Use the PA2.0 format, which is a superset of the PA1.1 format.  */
     69static int get_tlb(QEMUFile *f, void *opaque, size_t size,
     70                   const VMStateField *field)
     71{
     72    hppa_tlb_entry *ent = opaque;
     73    uint32_t val;
     74
     75    memset(ent, 0, sizeof(*ent));
     76
     77    ent->va_b = qemu_get_be64(f);
     78    ent->pa = qemu_get_betr(f);
     79    val = qemu_get_be32(f);
     80
     81    ent->entry_valid = extract32(val, 0, 1);
     82    ent->access_id = extract32(val, 1, 18);
     83    ent->u = extract32(val, 19, 1);
     84    ent->ar_pl2 = extract32(val, 20, 2);
     85    ent->ar_pl1 = extract32(val, 22, 2);
     86    ent->ar_type = extract32(val, 24, 3);
     87    ent->b = extract32(val, 27, 1);
     88    ent->d = extract32(val, 28, 1);
     89    ent->t = extract32(val, 29, 1);
     90
     91    ent->va_e = ent->va_b + TARGET_PAGE_SIZE - 1;
     92    return 0;
     93}
     94
     95static int put_tlb(QEMUFile *f, void *opaque, size_t size,
     96                   const VMStateField *field, JSONWriter *vmdesc)
     97{
     98    hppa_tlb_entry *ent = opaque;
     99    uint32_t val = 0;
    100
    101    if (ent->entry_valid) {
    102        val = 1;
    103        val = deposit32(val, 1, 18, ent->access_id);
    104        val = deposit32(val, 19, 1, ent->u);
    105        val = deposit32(val, 20, 2, ent->ar_pl2);
    106        val = deposit32(val, 22, 2, ent->ar_pl1);
    107        val = deposit32(val, 24, 3, ent->ar_type);
    108        val = deposit32(val, 27, 1, ent->b);
    109        val = deposit32(val, 28, 1, ent->d);
    110        val = deposit32(val, 29, 1, ent->t);
    111    }
    112
    113    qemu_put_be64(f, ent->va_b);
    114    qemu_put_betr(f, ent->pa);
    115    qemu_put_be32(f, val);
    116    return 0;
    117}
    118
    119static const VMStateInfo vmstate_tlb = {
    120    .name = "tlb entry",
    121    .get = get_tlb,
    122    .put = put_tlb,
    123};
    124
    125static VMStateField vmstate_env_fields[] = {
    126    VMSTATE_UINTTR_ARRAY(gr, CPUHPPAState, 32),
    127    VMSTATE_UINT64_ARRAY(fr, CPUHPPAState, 32),
    128    VMSTATE_UINT64_ARRAY(sr, CPUHPPAState, 8),
    129    VMSTATE_UINTTR_ARRAY(cr, CPUHPPAState, 32),
    130    VMSTATE_UINTTR_ARRAY(cr_back, CPUHPPAState, 2),
    131    VMSTATE_UINTTR_ARRAY(shadow, CPUHPPAState, 7),
    132
    133    /* Save the architecture value of the psw, not the internally
    134       expanded version.  Since this architecture value does not
    135       exist in memory to be stored, this requires a but of hoop
    136       jumping.  We want OFFSET=0 so that we effectively pass ENV
    137       to the helper functions, and we need to fill in the name by
    138       hand since there's no field of that name.  */
    139    {
    140        .name = "psw",
    141        .version_id = 0,
    142        .size = sizeof(uint64_t),
    143        .info = &vmstate_psw,
    144        .flags = VMS_SINGLE,
    145        .offset = 0
    146    },
    147
    148    VMSTATE_UINTTR(iaoq_f, CPUHPPAState),
    149    VMSTATE_UINTTR(iaoq_b, CPUHPPAState),
    150    VMSTATE_UINT64(iasq_f, CPUHPPAState),
    151    VMSTATE_UINT64(iasq_b, CPUHPPAState),
    152
    153    VMSTATE_UINT32(fr0_shadow, CPUHPPAState),
    154
    155    VMSTATE_ARRAY(tlb, CPUHPPAState, ARRAY_SIZE(((CPUHPPAState *)0)->tlb),
    156                  0, vmstate_tlb, hppa_tlb_entry),
    157    VMSTATE_UINT32(tlb_last, CPUHPPAState),
    158
    159    VMSTATE_END_OF_LIST()
    160};
    161
    162static const VMStateDescription vmstate_env = {
    163    .name = "env",
    164    .version_id = 1,
    165    .minimum_version_id = 1,
    166    .fields = vmstate_env_fields,
    167};
    168
    169static VMStateField vmstate_cpu_fields[] = {
    170    VMSTATE_CPU(),
    171    VMSTATE_STRUCT(env, HPPACPU, 1, vmstate_env, CPUHPPAState),
    172    VMSTATE_END_OF_LIST()
    173};
    174
    175const VMStateDescription vmstate_hppa_cpu = {
    176    .name = "cpu",
    177    .version_id = 1,
    178    .minimum_version_id = 1,
    179    .fields = vmstate_cpu_fields,
    180};