qemu

FORK: QEMU emulator
git clone https://git.neptards.moe/neptards/qemu.git
Log | Files | Refs | Submodules | LICENSE

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 
     46 static 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 
     54 static 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 
     62 static 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.  */
     69 static 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 
     95 static 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 
    119 static const VMStateInfo vmstate_tlb = {
    120     .name = "tlb entry",
    121     .get = get_tlb,
    122     .put = put_tlb,
    123 };
    124 
    125 static 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 
    162 static const VMStateDescription vmstate_env = {
    163     .name = "env",
    164     .version_id = 1,
    165     .minimum_version_id = 1,
    166     .fields = vmstate_env_fields,
    167 };
    168 
    169 static VMStateField vmstate_cpu_fields[] = {
    170     VMSTATE_CPU(),
    171     VMSTATE_STRUCT(env, HPPACPU, 1, vmstate_env, CPUHPPAState),
    172     VMSTATE_END_OF_LIST()
    173 };
    174 
    175 const VMStateDescription vmstate_hppa_cpu = {
    176     .name = "cpu",
    177     .version_id = 1,
    178     .minimum_version_id = 1,
    179     .fields = vmstate_cpu_fields,
    180 };