2 * PowerPC emulation special registers manipulation helpers for qemu.
4 * Copyright (c) 2003-2007 Jocelyn Mayer
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.
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"
22 #include "qemu/main-loop.h"
23 #include "exec/exec-all.h"
24 #include "sysemu/kvm.h"
25 #include "sysemu/tcg.h"
26 #include "helper_regs.h"
27 #include "power8-pmu.h"
28 #include "cpu-models.h"
29 #include "spr_common.h"
31 /* Swap temporary saved registers with GPRs */
32 void hreg_swap_gpr_tgpr(CPUPPCState
*env
)
37 env
->gpr
[0] = env
->tgpr
[0];
40 env
->gpr
[1] = env
->tgpr
[1];
43 env
->gpr
[2] = env
->tgpr
[2];
46 env
->gpr
[3] = env
->tgpr
[3];
50 #if defined(TARGET_PPC64)
51 static bool hreg_check_bhrb_enable(CPUPPCState
*env
)
53 bool pr
= !!(env
->msr
& (1 << MSR_PR
));
58 /* ISA 3.1 adds the PMCRA[BRHBRD] and problem state checks */
59 if ((env
->insns_flags2
& PPC2_ISA310
) &&
60 ((env
->spr
[SPR_POWER_MMCRA
] & MMCRA_BHRBRD
) || !pr
)) {
64 /* Check for BHRB "frozen" conditions */
65 mmcr0
= env
->spr
[SPR_POWER_MMCR0
];
66 fcp
= !!(mmcr0
& MMCR0_FCP
);
67 if (mmcr0
& MMCR0_FCPC
) {
68 hv
= !!(env
->msr
& (1ull << MSR_HV
));
73 } else if (!hv
&& pr
) {
76 } else if (fcp
&& pr
) {
83 static uint32_t hreg_compute_pmu_hflags_value(CPUPPCState
*env
)
87 #if defined(TARGET_PPC64)
88 if (env
->spr
[SPR_POWER_MMCR0
] & MMCR0_PMCC0
) {
89 hflags
|= 1 << HFLAGS_PMCC0
;
91 if (env
->spr
[SPR_POWER_MMCR0
] & MMCR0_PMCC1
) {
92 hflags
|= 1 << HFLAGS_PMCC1
;
94 if (env
->spr
[SPR_POWER_MMCR0
] & MMCR0_PMCjCE
) {
95 hflags
|= 1 << HFLAGS_PMCJCE
;
97 if (hreg_check_bhrb_enable(env
)) {
98 hflags
|= 1 << HFLAGS_BHRB_ENABLE
;
101 #ifndef CONFIG_USER_ONLY
102 if (env
->pmc_ins_cnt
) {
103 hflags
|= 1 << HFLAGS_INSN_CNT
;
105 if (env
->pmc_ins_cnt
& 0x1e) {
106 hflags
|= 1 << HFLAGS_PMC_OTHER
;
114 /* Mask of all PMU hflags */
115 static uint32_t hreg_compute_pmu_hflags_mask(CPUPPCState
*env
)
117 uint32_t hflags_mask
= 0;
118 #if defined(TARGET_PPC64)
119 hflags_mask
|= 1 << HFLAGS_PMCC0
;
120 hflags_mask
|= 1 << HFLAGS_PMCC1
;
121 hflags_mask
|= 1 << HFLAGS_PMCJCE
;
122 hflags_mask
|= 1 << HFLAGS_INSN_CNT
;
123 hflags_mask
|= 1 << HFLAGS_PMC_OTHER
;
124 hflags_mask
|= 1 << HFLAGS_BHRB_ENABLE
;
129 static uint32_t hreg_compute_hflags_value(CPUPPCState
*env
)
131 target_ulong msr
= env
->msr
;
132 uint32_t ppc_flags
= env
->flags
;
136 /* Some bits come straight across from MSR. */
137 QEMU_BUILD_BUG_ON(MSR_LE
!= HFLAGS_LE
);
138 QEMU_BUILD_BUG_ON(MSR_PR
!= HFLAGS_PR
);
139 QEMU_BUILD_BUG_ON(MSR_DR
!= HFLAGS_DR
);
140 QEMU_BUILD_BUG_ON(MSR_FP
!= HFLAGS_FP
);
141 msr_mask
= ((1 << MSR_LE
) | (1 << MSR_PR
) |
142 (1 << MSR_DR
) | (1 << MSR_FP
));
144 if (ppc_flags
& POWERPC_FLAG_DE
) {
145 target_ulong dbcr0
= env
->spr
[SPR_BOOKE_DBCR0
];
146 if ((dbcr0
& DBCR0_ICMP
) && FIELD_EX64(env
->msr
, MSR
, DE
)) {
147 hflags
|= 1 << HFLAGS_SE
;
149 if ((dbcr0
& DBCR0_BRT
) && FIELD_EX64(env
->msr
, MSR
, DE
)) {
150 hflags
|= 1 << HFLAGS_BE
;
153 if (ppc_flags
& POWERPC_FLAG_BE
) {
154 QEMU_BUILD_BUG_ON(MSR_BE
!= HFLAGS_BE
);
155 msr_mask
|= 1 << MSR_BE
;
157 if (ppc_flags
& POWERPC_FLAG_SE
) {
158 QEMU_BUILD_BUG_ON(MSR_SE
!= HFLAGS_SE
);
159 msr_mask
|= 1 << MSR_SE
;
163 if (msr_is_64bit(env
, msr
)) {
164 hflags
|= 1 << HFLAGS_64
;
166 if ((ppc_flags
& POWERPC_FLAG_SPE
) && (msr
& (1 << MSR_SPE
))) {
167 hflags
|= 1 << HFLAGS_SPE
;
169 if (ppc_flags
& POWERPC_FLAG_VRE
) {
170 QEMU_BUILD_BUG_ON(MSR_VR
!= HFLAGS_VR
);
171 msr_mask
|= 1 << MSR_VR
;
173 if (ppc_flags
& POWERPC_FLAG_VSX
) {
174 QEMU_BUILD_BUG_ON(MSR_VSX
!= HFLAGS_VSX
);
175 msr_mask
|= 1 << MSR_VSX
;
177 if ((ppc_flags
& POWERPC_FLAG_TM
) && (msr
& (1ull << MSR_TM
))) {
178 hflags
|= 1 << HFLAGS_TM
;
180 if (env
->spr
[SPR_LPCR
] & LPCR_GTSE
) {
181 hflags
|= 1 << HFLAGS_GTSE
;
183 if (env
->spr
[SPR_LPCR
] & LPCR_HR
) {
184 hflags
|= 1 << HFLAGS_HR
;
187 #ifndef CONFIG_USER_ONLY
188 if (!env
->has_hv_mode
|| (msr
& (1ull << MSR_HV
))) {
189 hflags
|= 1 << HFLAGS_HV
;
193 * This is our encoding for server processors. The architecture
194 * specifies that there is no such thing as userspace with
195 * translation off, however it appears that MacOS does it and some
196 * 32-bit CPUs support it. Weird...
198 * 0 = Guest User space virtual mode
199 * 1 = Guest Kernel space virtual mode
200 * 2 = Guest User space real mode
201 * 3 = Guest Kernel space real mode
202 * 4 = HV User space virtual mode
203 * 5 = HV Kernel space virtual mode
204 * 6 = HV User space real mode
205 * 7 = HV Kernel space real mode
207 * For BookE, we need 8 MMU modes as follow:
209 * 0 = AS 0 HV User space
210 * 1 = AS 0 HV Kernel space
211 * 2 = AS 1 HV User space
212 * 3 = AS 1 HV Kernel space
213 * 4 = AS 0 Guest User space
214 * 5 = AS 0 Guest Kernel space
215 * 6 = AS 1 Guest User space
216 * 7 = AS 1 Guest Kernel space
218 unsigned immu_idx
, dmmu_idx
;
219 dmmu_idx
= msr
& (1 << MSR_PR
) ? 0 : 1;
220 if (env
->mmu_model
== POWERPC_MMU_BOOKE
||
221 env
->mmu_model
== POWERPC_MMU_BOOKE206
) {
222 dmmu_idx
|= msr
& (1 << MSR_GS
) ? 4 : 0;
224 immu_idx
|= msr
& (1 << MSR_IS
) ? 2 : 0;
225 dmmu_idx
|= msr
& (1 << MSR_DS
) ? 2 : 0;
227 dmmu_idx
|= msr
& (1ull << MSR_HV
) ? 4 : 0;
229 immu_idx
|= msr
& (1 << MSR_IR
) ? 0 : 2;
230 dmmu_idx
|= msr
& (1 << MSR_DR
) ? 0 : 2;
232 hflags
|= immu_idx
<< HFLAGS_IMMU_IDX
;
233 hflags
|= dmmu_idx
<< HFLAGS_DMMU_IDX
;
236 hflags
|= hreg_compute_pmu_hflags_value(env
);
238 return hflags
| (msr
& msr_mask
);
241 void hreg_compute_hflags(CPUPPCState
*env
)
243 env
->hflags
= hreg_compute_hflags_value(env
);
247 * This can be used as a lighter-weight alternative to hreg_compute_hflags
248 * when PMU MMCR0 or pmc_ins_cnt changes. pmc_ins_cnt is changed by
249 * pmu_update_summaries.
251 void hreg_update_pmu_hflags(CPUPPCState
*env
)
253 env
->hflags
&= ~hreg_compute_pmu_hflags_mask(env
);
254 env
->hflags
|= hreg_compute_pmu_hflags_value(env
);
257 #ifdef CONFIG_DEBUG_TCG
258 void cpu_get_tb_cpu_state(CPUPPCState
*env
, vaddr
*pc
,
259 uint64_t *cs_base
, uint32_t *flags
)
261 uint32_t hflags_current
= env
->hflags
;
262 uint32_t hflags_rebuilt
;
266 *flags
= hflags_current
;
268 hflags_rebuilt
= hreg_compute_hflags_value(env
);
269 if (unlikely(hflags_current
!= hflags_rebuilt
)) {
270 cpu_abort(env_cpu(env
),
271 "TCG hflags mismatch (current:0x%08x rebuilt:0x%08x)\n",
272 hflags_current
, hflags_rebuilt
);
277 void cpu_interrupt_exittb(CPUState
*cs
)
280 * We don't need to worry about translation blocks
281 * unless running with TCG.
285 cpu_interrupt(cs
, CPU_INTERRUPT_EXITTB
);
289 int hreg_store_msr(CPUPPCState
*env
, target_ulong value
, int alter_hv
)
292 #if !defined(CONFIG_USER_ONLY)
293 CPUState
*cs
= env_cpu(env
);
297 value
&= env
->msr_mask
;
298 #if !defined(CONFIG_USER_ONLY)
299 /* Neither mtmsr nor guest state can alter HV */
300 if (!alter_hv
|| !(env
->msr
& MSR_HVB
)) {
302 value
|= env
->msr
& MSR_HVB
;
304 /* Attempt to modify MSR[ME] in guest state is ignored */
305 if (is_book3s_arch2x(env
) && !(env
->msr
& MSR_HVB
)) {
306 value
&= ~(1 << MSR_ME
);
307 value
|= env
->msr
& (1 << MSR_ME
);
309 if ((value
^ env
->msr
) & (R_MSR_IR_MASK
| R_MSR_DR_MASK
)) {
310 cpu_interrupt_exittb(cs
);
312 if ((env
->mmu_model
== POWERPC_MMU_BOOKE
||
313 env
->mmu_model
== POWERPC_MMU_BOOKE206
) &&
314 ((value
^ env
->msr
) & R_MSR_GS_MASK
)) {
315 cpu_interrupt_exittb(cs
);
317 if (unlikely((env
->flags
& POWERPC_FLAG_TGPR
) &&
318 ((value
^ env
->msr
) & (1 << MSR_TGPR
)))) {
319 /* Swap temporary saved registers with GPRs */
320 hreg_swap_gpr_tgpr(env
);
322 if (unlikely((value
^ env
->msr
) & R_MSR_EP_MASK
)) {
323 env
->excp_prefix
= FIELD_EX64(value
, MSR
, EP
) * 0xFFF00000;
326 * If PR=1 then EE, IR and DR must be 1
328 * Note: We only enforce this on 64-bit server processors.
330 * - 32-bit implementations supports PR=1 and EE/DR/IR=0 and MacOS
332 * - 64-bit embedded implementations do not need any operation to be
333 * performed when PR is set.
335 if (is_book3s_arch2x(env
) && ((value
>> MSR_PR
) & 1)) {
336 value
|= (1 << MSR_EE
) | (1 << MSR_DR
) | (1 << MSR_IR
);
340 hreg_compute_hflags(env
);
341 #if !defined(CONFIG_USER_ONLY)
342 ppc_maybe_interrupt(env
);
344 if (unlikely(FIELD_EX64(env
->msr
, MSR
, POW
))) {
345 if (!env
->pending_interrupts
&& (*env
->check_pow
)(env
)) {
355 #ifndef CONFIG_USER_ONLY
356 void store_40x_sler(CPUPPCState
*env
, uint32_t val
)
358 /* XXX: TO BE FIXED */
359 if (val
!= 0x00000000) {
360 cpu_abort(env_cpu(env
),
361 "Little-endian regions are not supported by now\n");
363 env
->spr
[SPR_405_SLER
] = val
;
366 void check_tlb_flush(CPUPPCState
*env
, bool global
)
368 CPUState
*cs
= env_cpu(env
);
370 /* Handle global flushes first */
371 if (global
&& (env
->tlb_need_flush
& TLB_NEED_GLOBAL_FLUSH
)) {
372 env
->tlb_need_flush
&= ~TLB_NEED_GLOBAL_FLUSH
;
373 env
->tlb_need_flush
&= ~TLB_NEED_LOCAL_FLUSH
;
374 tlb_flush_all_cpus_synced(cs
);
378 /* Then handle local ones */
379 if (env
->tlb_need_flush
& TLB_NEED_LOCAL_FLUSH
) {
380 env
->tlb_need_flush
&= ~TLB_NEED_LOCAL_FLUSH
;
384 #endif /* !CONFIG_USER_ONLY */
389 * Register an SPR with all the callbacks required for tcg,
390 * and the ID number for KVM.
392 * The reason for the conditional compilation is that the tcg functions
393 * may be compiled out, and the system kvm header may not be available
394 * for supplying the ID numbers. This is ugly, but the best we can do.
396 void _spr_register(CPUPPCState
*env
, int num
, const char *name
,
397 USR_ARG(spr_callback
*uea_read
)
398 USR_ARG(spr_callback
*uea_write
)
399 SYS_ARG(spr_callback
*oea_read
)
400 SYS_ARG(spr_callback
*oea_write
)
401 SYS_ARG(spr_callback
*hea_read
)
402 SYS_ARG(spr_callback
*hea_write
)
403 KVM_ARG(uint64_t one_reg_id
)
404 target_ulong initial_value
)
406 ppc_spr_t
*spr
= &env
->spr_cb
[num
];
408 /* No SPR should be registered twice. */
409 assert(spr
->name
== NULL
);
410 assert(name
!= NULL
);
413 spr
->default_value
= initial_value
;
414 env
->spr
[num
] = initial_value
;
417 spr
->uea_read
= uea_read
;
418 spr
->uea_write
= uea_write
;
419 # ifndef CONFIG_USER_ONLY
420 spr
->oea_read
= oea_read
;
421 spr
->oea_write
= oea_write
;
422 spr
->hea_read
= hea_read
;
423 spr
->hea_write
= hea_write
;
427 spr
->one_reg_id
= one_reg_id
;
431 /* Generic PowerPC SPRs */
432 void register_generic_sprs(PowerPCCPU
*cpu
)
434 PowerPCCPUClass
*pcc
= POWERPC_CPU_GET_CLASS(cpu
);
435 CPUPPCState
*env
= &cpu
->env
;
437 /* Integer processing */
438 spr_register(env
, SPR_XER
, "XER",
439 &spr_read_xer
, &spr_write_xer
,
440 &spr_read_xer
, &spr_write_xer
,
443 spr_register(env
, SPR_LR
, "LR",
444 &spr_read_lr
, &spr_write_lr
,
445 &spr_read_lr
, &spr_write_lr
,
447 spr_register(env
, SPR_CTR
, "CTR",
448 &spr_read_ctr
, &spr_write_ctr
,
449 &spr_read_ctr
, &spr_write_ctr
,
451 /* Interrupt processing */
452 spr_register(env
, SPR_SRR0
, "SRR0",
453 SPR_NOACCESS
, SPR_NOACCESS
,
454 &spr_read_generic
, &spr_write_generic
,
456 spr_register(env
, SPR_SRR1
, "SRR1",
457 SPR_NOACCESS
, SPR_NOACCESS
,
458 &spr_read_generic
, &spr_write_generic
,
460 /* Processor control */
461 spr_register(env
, SPR_SPRG0
, "SPRG0",
462 SPR_NOACCESS
, SPR_NOACCESS
,
463 &spr_read_generic
, &spr_write_generic
,
465 spr_register(env
, SPR_SPRG1
, "SPRG1",
466 SPR_NOACCESS
, SPR_NOACCESS
,
467 &spr_read_generic
, &spr_write_generic
,
469 spr_register(env
, SPR_SPRG2
, "SPRG2",
470 SPR_NOACCESS
, SPR_NOACCESS
,
471 &spr_read_generic
, &spr_write_generic
,
473 spr_register(env
, SPR_SPRG3
, "SPRG3",
474 SPR_NOACCESS
, SPR_NOACCESS
,
475 &spr_read_generic
, &spr_write_generic
,
478 spr_register(env
, SPR_PVR
, "PVR",
479 /* Linux permits userspace to read PVR */
480 #if defined(CONFIG_LINUX_USER)
486 &spr_read_generic
, SPR_NOACCESS
,
489 /* Register SVR if it's defined to anything else than POWERPC_SVR_NONE */
490 if (pcc
->svr
!= POWERPC_SVR_NONE
) {
491 if (pcc
->svr
& POWERPC_SVR_E500
) {
492 spr_register(env
, SPR_E500_SVR
, "SVR",
493 SPR_NOACCESS
, SPR_NOACCESS
,
494 &spr_read_generic
, SPR_NOACCESS
,
495 pcc
->svr
& ~POWERPC_SVR_E500
);
497 spr_register(env
, SPR_SVR
, "SVR",
498 SPR_NOACCESS
, SPR_NOACCESS
,
499 &spr_read_generic
, SPR_NOACCESS
,
505 #if defined(TARGET_PPC64)
506 spr_register(env
, SPR_TBL
, "TB",
508 spr_register(env
, SPR_TBL
, "TBL",
510 &spr_read_tbl
, SPR_NOACCESS
,
511 &spr_read_tbl
, SPR_NOACCESS
,
513 spr_register(env
, SPR_TBU
, "TBU",
514 &spr_read_tbu
, SPR_NOACCESS
,
515 &spr_read_tbu
, SPR_NOACCESS
,
517 #ifndef CONFIG_USER_ONLY
518 if (env
->has_hv_mode
) {
519 spr_register_hv(env
, SPR_WR_TBL
, "TBL",
520 SPR_NOACCESS
, SPR_NOACCESS
,
521 SPR_NOACCESS
, SPR_NOACCESS
,
522 SPR_NOACCESS
, &spr_write_tbl
,
524 spr_register_hv(env
, SPR_WR_TBU
, "TBU",
525 SPR_NOACCESS
, SPR_NOACCESS
,
526 SPR_NOACCESS
, SPR_NOACCESS
,
527 SPR_NOACCESS
, &spr_write_tbu
,
530 spr_register(env
, SPR_WR_TBL
, "TBL",
531 SPR_NOACCESS
, SPR_NOACCESS
,
532 SPR_NOACCESS
, &spr_write_tbl
,
534 spr_register(env
, SPR_WR_TBU
, "TBU",
535 SPR_NOACCESS
, SPR_NOACCESS
,
536 SPR_NOACCESS
, &spr_write_tbu
,
542 void register_non_embedded_sprs(CPUPPCState
*env
)
544 /* Exception processing */
545 spr_register_kvm(env
, SPR_DSISR
, "DSISR",
546 SPR_NOACCESS
, SPR_NOACCESS
,
547 &spr_read_generic
, &spr_write_generic32
,
548 KVM_REG_PPC_DSISR
, 0x00000000);
549 spr_register_kvm(env
, SPR_DAR
, "DAR",
550 SPR_NOACCESS
, SPR_NOACCESS
,
551 &spr_read_generic
, &spr_write_generic
,
552 KVM_REG_PPC_DAR
, 0x00000000);
554 spr_register(env
, SPR_DECR
, "DEC",
555 SPR_NOACCESS
, SPR_NOACCESS
,
556 &spr_read_decr
, &spr_write_decr
,
560 /* Storage Description Register 1 */
561 void register_sdr1_sprs(CPUPPCState
*env
)
563 #ifndef CONFIG_USER_ONLY
564 if (env
->has_hv_mode
) {
566 * SDR1 is a hypervisor resource on CPUs which have a
569 spr_register_hv(env
, SPR_SDR1
, "SDR1",
570 SPR_NOACCESS
, SPR_NOACCESS
,
571 SPR_NOACCESS
, SPR_NOACCESS
,
572 &spr_read_generic
, &spr_write_sdr1
,
575 spr_register(env
, SPR_SDR1
, "SDR1",
576 SPR_NOACCESS
, SPR_NOACCESS
,
577 &spr_read_generic
, &spr_write_sdr1
,
584 void register_low_BATs(CPUPPCState
*env
)
586 #if !defined(CONFIG_USER_ONLY)
587 spr_register(env
, SPR_IBAT0U
, "IBAT0U",
588 SPR_NOACCESS
, SPR_NOACCESS
,
589 &spr_read_ibat
, &spr_write_ibatu
,
591 spr_register(env
, SPR_IBAT0L
, "IBAT0L",
592 SPR_NOACCESS
, SPR_NOACCESS
,
593 &spr_read_ibat
, &spr_write_ibatl
,
595 spr_register(env
, SPR_IBAT1U
, "IBAT1U",
596 SPR_NOACCESS
, SPR_NOACCESS
,
597 &spr_read_ibat
, &spr_write_ibatu
,
599 spr_register(env
, SPR_IBAT1L
, "IBAT1L",
600 SPR_NOACCESS
, SPR_NOACCESS
,
601 &spr_read_ibat
, &spr_write_ibatl
,
603 spr_register(env
, SPR_IBAT2U
, "IBAT2U",
604 SPR_NOACCESS
, SPR_NOACCESS
,
605 &spr_read_ibat
, &spr_write_ibatu
,
607 spr_register(env
, SPR_IBAT2L
, "IBAT2L",
608 SPR_NOACCESS
, SPR_NOACCESS
,
609 &spr_read_ibat
, &spr_write_ibatl
,
611 spr_register(env
, SPR_IBAT3U
, "IBAT3U",
612 SPR_NOACCESS
, SPR_NOACCESS
,
613 &spr_read_ibat
, &spr_write_ibatu
,
615 spr_register(env
, SPR_IBAT3L
, "IBAT3L",
616 SPR_NOACCESS
, SPR_NOACCESS
,
617 &spr_read_ibat
, &spr_write_ibatl
,
619 spr_register(env
, SPR_DBAT0U
, "DBAT0U",
620 SPR_NOACCESS
, SPR_NOACCESS
,
621 &spr_read_dbat
, &spr_write_dbatu
,
623 spr_register(env
, SPR_DBAT0L
, "DBAT0L",
624 SPR_NOACCESS
, SPR_NOACCESS
,
625 &spr_read_dbat
, &spr_write_dbatl
,
627 spr_register(env
, SPR_DBAT1U
, "DBAT1U",
628 SPR_NOACCESS
, SPR_NOACCESS
,
629 &spr_read_dbat
, &spr_write_dbatu
,
631 spr_register(env
, SPR_DBAT1L
, "DBAT1L",
632 SPR_NOACCESS
, SPR_NOACCESS
,
633 &spr_read_dbat
, &spr_write_dbatl
,
635 spr_register(env
, SPR_DBAT2U
, "DBAT2U",
636 SPR_NOACCESS
, SPR_NOACCESS
,
637 &spr_read_dbat
, &spr_write_dbatu
,
639 spr_register(env
, SPR_DBAT2L
, "DBAT2L",
640 SPR_NOACCESS
, SPR_NOACCESS
,
641 &spr_read_dbat
, &spr_write_dbatl
,
643 spr_register(env
, SPR_DBAT3U
, "DBAT3U",
644 SPR_NOACCESS
, SPR_NOACCESS
,
645 &spr_read_dbat
, &spr_write_dbatu
,
647 spr_register(env
, SPR_DBAT3L
, "DBAT3L",
648 SPR_NOACCESS
, SPR_NOACCESS
,
649 &spr_read_dbat
, &spr_write_dbatl
,
656 void register_high_BATs(CPUPPCState
*env
)
658 #if !defined(CONFIG_USER_ONLY)
659 spr_register(env
, SPR_IBAT4U
, "IBAT4U",
660 SPR_NOACCESS
, SPR_NOACCESS
,
661 &spr_read_ibat_h
, &spr_write_ibatu_h
,
663 spr_register(env
, SPR_IBAT4L
, "IBAT4L",
664 SPR_NOACCESS
, SPR_NOACCESS
,
665 &spr_read_ibat_h
, &spr_write_ibatl_h
,
667 spr_register(env
, SPR_IBAT5U
, "IBAT5U",
668 SPR_NOACCESS
, SPR_NOACCESS
,
669 &spr_read_ibat_h
, &spr_write_ibatu_h
,
671 spr_register(env
, SPR_IBAT5L
, "IBAT5L",
672 SPR_NOACCESS
, SPR_NOACCESS
,
673 &spr_read_ibat_h
, &spr_write_ibatl_h
,
675 spr_register(env
, SPR_IBAT6U
, "IBAT6U",
676 SPR_NOACCESS
, SPR_NOACCESS
,
677 &spr_read_ibat_h
, &spr_write_ibatu_h
,
679 spr_register(env
, SPR_IBAT6L
, "IBAT6L",
680 SPR_NOACCESS
, SPR_NOACCESS
,
681 &spr_read_ibat_h
, &spr_write_ibatl_h
,
683 spr_register(env
, SPR_IBAT7U
, "IBAT7U",
684 SPR_NOACCESS
, SPR_NOACCESS
,
685 &spr_read_ibat_h
, &spr_write_ibatu_h
,
687 spr_register(env
, SPR_IBAT7L
, "IBAT7L",
688 SPR_NOACCESS
, SPR_NOACCESS
,
689 &spr_read_ibat_h
, &spr_write_ibatl_h
,
691 spr_register(env
, SPR_DBAT4U
, "DBAT4U",
692 SPR_NOACCESS
, SPR_NOACCESS
,
693 &spr_read_dbat_h
, &spr_write_dbatu_h
,
695 spr_register(env
, SPR_DBAT4L
, "DBAT4L",
696 SPR_NOACCESS
, SPR_NOACCESS
,
697 &spr_read_dbat_h
, &spr_write_dbatl_h
,
699 spr_register(env
, SPR_DBAT5U
, "DBAT5U",
700 SPR_NOACCESS
, SPR_NOACCESS
,
701 &spr_read_dbat_h
, &spr_write_dbatu_h
,
703 spr_register(env
, SPR_DBAT5L
, "DBAT5L",
704 SPR_NOACCESS
, SPR_NOACCESS
,
705 &spr_read_dbat_h
, &spr_write_dbatl_h
,
707 spr_register(env
, SPR_DBAT6U
, "DBAT6U",
708 SPR_NOACCESS
, SPR_NOACCESS
,
709 &spr_read_dbat_h
, &spr_write_dbatu_h
,
711 spr_register(env
, SPR_DBAT6L
, "DBAT6L",
712 SPR_NOACCESS
, SPR_NOACCESS
,
713 &spr_read_dbat_h
, &spr_write_dbatl_h
,
715 spr_register(env
, SPR_DBAT7U
, "DBAT7U",
716 SPR_NOACCESS
, SPR_NOACCESS
,
717 &spr_read_dbat_h
, &spr_write_dbatu_h
,
719 spr_register(env
, SPR_DBAT7L
, "DBAT7L",
720 SPR_NOACCESS
, SPR_NOACCESS
,
721 &spr_read_dbat_h
, &spr_write_dbatl_h
,
727 /* Softare table search registers */
728 void register_6xx_7xx_soft_tlb(CPUPPCState
*env
, int nb_tlbs
, int nb_ways
)
730 #if !defined(CONFIG_USER_ONLY)
731 env
->nb_tlb
= nb_tlbs
;
732 env
->nb_ways
= nb_ways
;
733 env
->tlb_type
= TLB_6XX
;
734 spr_register(env
, SPR_DMISS
, "DMISS",
735 SPR_NOACCESS
, SPR_NOACCESS
,
736 &spr_read_generic
, SPR_NOACCESS
,
738 spr_register(env
, SPR_DCMP
, "DCMP",
739 SPR_NOACCESS
, SPR_NOACCESS
,
740 &spr_read_generic
, SPR_NOACCESS
,
742 spr_register(env
, SPR_HASH1
, "HASH1",
743 SPR_NOACCESS
, SPR_NOACCESS
,
744 &spr_read_generic
, SPR_NOACCESS
,
746 spr_register(env
, SPR_HASH2
, "HASH2",
747 SPR_NOACCESS
, SPR_NOACCESS
,
748 &spr_read_generic
, SPR_NOACCESS
,
750 spr_register(env
, SPR_IMISS
, "IMISS",
751 SPR_NOACCESS
, SPR_NOACCESS
,
752 &spr_read_generic
, SPR_NOACCESS
,
754 spr_register(env
, SPR_ICMP
, "ICMP",
755 SPR_NOACCESS
, SPR_NOACCESS
,
756 &spr_read_generic
, SPR_NOACCESS
,
758 spr_register(env
, SPR_RPA
, "RPA",
759 SPR_NOACCESS
, SPR_NOACCESS
,
760 &spr_read_generic
, &spr_write_generic
,
765 void register_thrm_sprs(CPUPPCState
*env
)
767 /* Thermal management */
768 spr_register(env
, SPR_THRM1
, "THRM1",
769 SPR_NOACCESS
, SPR_NOACCESS
,
770 &spr_read_thrm
, &spr_write_generic
,
773 spr_register(env
, SPR_THRM2
, "THRM2",
774 SPR_NOACCESS
, SPR_NOACCESS
,
775 &spr_read_thrm
, &spr_write_generic
,
778 spr_register(env
, SPR_THRM3
, "THRM3",
779 SPR_NOACCESS
, SPR_NOACCESS
,
780 &spr_read_thrm
, &spr_write_generic
,
784 void register_usprgh_sprs(CPUPPCState
*env
)
786 spr_register(env
, SPR_USPRG4
, "USPRG4",
787 &spr_read_ureg
, SPR_NOACCESS
,
788 &spr_read_ureg
, SPR_NOACCESS
,
790 spr_register(env
, SPR_USPRG5
, "USPRG5",
791 &spr_read_ureg
, SPR_NOACCESS
,
792 &spr_read_ureg
, SPR_NOACCESS
,
794 spr_register(env
, SPR_USPRG6
, "USPRG6",
795 &spr_read_ureg
, SPR_NOACCESS
,
796 &spr_read_ureg
, SPR_NOACCESS
,
798 spr_register(env
, SPR_USPRG7
, "USPRG7",
799 &spr_read_ureg
, SPR_NOACCESS
,
800 &spr_read_ureg
, SPR_NOACCESS
,