2 * HPPA interrupt helper routines
4 * Copyright (c) 2017 Richard Henderson
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 of the License, or (at your option) any later version.
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.
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/>.
20 #include "qemu/osdep.h"
21 #include "qemu-common.h"
24 #include "hw/boards.h"
25 #include "migration/cpu.h"
27 #if TARGET_REGISTER_BITS == 64
28 #define qemu_put_betr qemu_put_be64
29 #define qemu_get_betr qemu_get_be64
30 #define VMSTATE_UINTTL_V(_f, _s, _v) \
31 VMSTATE_UINT64_V(_f, _s, _v)
32 #define VMSTATE_UINTTL_ARRAY_V(_f, _s, _n, _v) \
33 VMSTATE_UINT64_ARRAY_V(_f, _s, _n, _v)
35 #define qemu_put_betr qemu_put_be32
36 #define qemu_get_betr qemu_get_be32
37 #define VMSTATE_UINTTR_V(_f, _s, _v) \
38 VMSTATE_UINT32_V(_f, _s, _v)
39 #define VMSTATE_UINTTR_ARRAY_V(_f, _s, _n, _v) \
40 VMSTATE_UINT32_ARRAY_V(_f, _s, _n, _v)
43 #define VMSTATE_UINTTR(_f, _s) \
44 VMSTATE_UINTTR_V(_f, _s, 0)
45 #define VMSTATE_UINTTR_ARRAY(_f, _s, _n) \
46 VMSTATE_UINTTR_ARRAY_V(_f, _s, _n, 0)
49 static int get_psw(QEMUFile
*f
, void *opaque
, size_t size
,
50 const VMStateField
*field
)
52 CPUHPPAState
*env
= opaque
;
53 cpu_hppa_put_psw(env
, qemu_get_betr(f
));
57 static int put_psw(QEMUFile
*f
, void *opaque
, size_t size
,
58 const VMStateField
*field
, QJSON
*vmdesc
)
60 CPUHPPAState
*env
= opaque
;
61 qemu_put_betr(f
, cpu_hppa_get_psw(env
));
65 static const VMStateInfo vmstate_psw
= {
71 /* FIXME: Use the PA2.0 format, which is a superset of the PA1.1 format. */
72 static int get_tlb(QEMUFile
*f
, void *opaque
, size_t size
,
73 const VMStateField
*field
)
75 hppa_tlb_entry
*ent
= opaque
;
78 memset(ent
, 0, sizeof(*ent
));
80 ent
->va_b
= qemu_get_be64(f
);
81 ent
->pa
= qemu_get_betr(f
);
82 val
= qemu_get_be32(f
);
84 ent
->entry_valid
= extract32(val
, 0, 1);
85 ent
->access_id
= extract32(val
, 1, 18);
86 ent
->u
= extract32(val
, 19, 1);
87 ent
->ar_pl2
= extract32(val
, 20, 2);
88 ent
->ar_pl1
= extract32(val
, 22, 2);
89 ent
->ar_type
= extract32(val
, 24, 3);
90 ent
->b
= extract32(val
, 27, 1);
91 ent
->d
= extract32(val
, 28, 1);
92 ent
->t
= extract32(val
, 29, 1);
94 ent
->va_e
= ent
->va_b
+ TARGET_PAGE_SIZE
- 1;
98 static int put_tlb(QEMUFile
*f
, void *opaque
, size_t size
,
99 const VMStateField
*field
, QJSON
*vmdesc
)
101 hppa_tlb_entry
*ent
= opaque
;
104 if (ent
->entry_valid
) {
106 val
= deposit32(val
, 1, 18, ent
->access_id
);
107 val
= deposit32(val
, 19, 1, ent
->u
);
108 val
= deposit32(val
, 20, 2, ent
->ar_pl2
);
109 val
= deposit32(val
, 22, 2, ent
->ar_pl1
);
110 val
= deposit32(val
, 24, 3, ent
->ar_type
);
111 val
= deposit32(val
, 27, 1, ent
->b
);
112 val
= deposit32(val
, 28, 1, ent
->d
);
113 val
= deposit32(val
, 29, 1, ent
->t
);
116 qemu_put_be64(f
, ent
->va_b
);
117 qemu_put_betr(f
, ent
->pa
);
118 qemu_put_be32(f
, val
);
122 static const VMStateInfo vmstate_tlb
= {
128 static VMStateField vmstate_env_fields
[] = {
129 VMSTATE_UINTTR_ARRAY(gr
, CPUHPPAState
, 32),
130 VMSTATE_UINT64_ARRAY(fr
, CPUHPPAState
, 32),
131 VMSTATE_UINT64_ARRAY(sr
, CPUHPPAState
, 8),
132 VMSTATE_UINTTR_ARRAY(cr
, CPUHPPAState
, 32),
133 VMSTATE_UINTTR_ARRAY(cr_back
, CPUHPPAState
, 2),
134 VMSTATE_UINTTR_ARRAY(shadow
, CPUHPPAState
, 7),
136 /* Save the architecture value of the psw, not the internally
137 expanded version. Since this architecture value does not
138 exist in memory to be stored, this requires a but of hoop
139 jumping. We want OFFSET=0 so that we effectively pass ENV
140 to the helper functions, and we need to fill in the name by
141 hand since there's no field of that name. */
145 .size
= sizeof(uint64_t),
146 .info
= &vmstate_psw
,
151 VMSTATE_UINTTR(iaoq_f
, CPUHPPAState
),
152 VMSTATE_UINTTR(iaoq_b
, CPUHPPAState
),
153 VMSTATE_UINT64(iasq_f
, CPUHPPAState
),
154 VMSTATE_UINT64(iasq_b
, CPUHPPAState
),
156 VMSTATE_UINT32(fr0_shadow
, CPUHPPAState
),
158 VMSTATE_ARRAY(tlb
, CPUHPPAState
, ARRAY_SIZE(((CPUHPPAState
*)0)->tlb
),
159 0, vmstate_tlb
, hppa_tlb_entry
),
160 VMSTATE_UINT32(tlb_last
, CPUHPPAState
),
162 VMSTATE_END_OF_LIST()
165 static const VMStateDescription vmstate_env
= {
168 .minimum_version_id
= 1,
169 .fields
= vmstate_env_fields
,
172 static VMStateField vmstate_cpu_fields
[] = {
174 VMSTATE_STRUCT(env
, HPPACPU
, 1, vmstate_env
, CPUHPPAState
),
175 VMSTATE_END_OF_LIST()
178 const VMStateDescription vmstate_hppa_cpu
= {
181 .minimum_version_id
= 1,
182 .fields
= vmstate_cpu_fields
,