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 static uint32_t hreg_compute_pmu_hflags_value(CPUPPCState
*env
)
54 #if defined(TARGET_PPC64)
55 if (env
->spr
[SPR_POWER_MMCR0
] & MMCR0_PMCC0
) {
56 hflags
|= 1 << HFLAGS_PMCC0
;
58 if (env
->spr
[SPR_POWER_MMCR0
] & MMCR0_PMCC1
) {
59 hflags
|= 1 << HFLAGS_PMCC1
;
61 if (env
->spr
[SPR_POWER_MMCR0
] & MMCR0_PMCjCE
) {
62 hflags
|= 1 << HFLAGS_PMCJCE
;
65 #ifndef CONFIG_USER_ONLY
66 if (env
->pmc_ins_cnt
) {
67 hflags
|= 1 << HFLAGS_INSN_CNT
;
69 if (env
->pmc_ins_cnt
& 0x1e) {
70 hflags
|= 1 << HFLAGS_PMC_OTHER
;
78 /* Mask of all PMU hflags */
79 static uint32_t hreg_compute_pmu_hflags_mask(CPUPPCState
*env
)
81 uint32_t hflags_mask
= 0;
82 #if defined(TARGET_PPC64)
83 hflags_mask
|= 1 << HFLAGS_PMCC0
;
84 hflags_mask
|= 1 << HFLAGS_PMCC1
;
85 hflags_mask
|= 1 << HFLAGS_PMCJCE
;
86 hflags_mask
|= 1 << HFLAGS_INSN_CNT
;
87 hflags_mask
|= 1 << HFLAGS_PMC_OTHER
;
92 static uint32_t hreg_compute_hflags_value(CPUPPCState
*env
)
94 target_ulong msr
= env
->msr
;
95 uint32_t ppc_flags
= env
->flags
;
99 /* Some bits come straight across from MSR. */
100 QEMU_BUILD_BUG_ON(MSR_LE
!= HFLAGS_LE
);
101 QEMU_BUILD_BUG_ON(MSR_PR
!= HFLAGS_PR
);
102 QEMU_BUILD_BUG_ON(MSR_DR
!= HFLAGS_DR
);
103 QEMU_BUILD_BUG_ON(MSR_FP
!= HFLAGS_FP
);
104 msr_mask
= ((1 << MSR_LE
) | (1 << MSR_PR
) |
105 (1 << MSR_DR
) | (1 << MSR_FP
));
107 if (ppc_flags
& POWERPC_FLAG_DE
) {
108 target_ulong dbcr0
= env
->spr
[SPR_BOOKE_DBCR0
];
109 if ((dbcr0
& DBCR0_ICMP
) && FIELD_EX64(env
->msr
, MSR
, DE
)) {
110 hflags
|= 1 << HFLAGS_SE
;
112 if ((dbcr0
& DBCR0_BRT
) && FIELD_EX64(env
->msr
, MSR
, DE
)) {
113 hflags
|= 1 << HFLAGS_BE
;
116 if (ppc_flags
& POWERPC_FLAG_BE
) {
117 QEMU_BUILD_BUG_ON(MSR_BE
!= HFLAGS_BE
);
118 msr_mask
|= 1 << MSR_BE
;
120 if (ppc_flags
& POWERPC_FLAG_SE
) {
121 QEMU_BUILD_BUG_ON(MSR_SE
!= HFLAGS_SE
);
122 msr_mask
|= 1 << MSR_SE
;
126 if (msr_is_64bit(env
, msr
)) {
127 hflags
|= 1 << HFLAGS_64
;
129 if ((ppc_flags
& POWERPC_FLAG_SPE
) && (msr
& (1 << MSR_SPE
))) {
130 hflags
|= 1 << HFLAGS_SPE
;
132 if (ppc_flags
& POWERPC_FLAG_VRE
) {
133 QEMU_BUILD_BUG_ON(MSR_VR
!= HFLAGS_VR
);
134 msr_mask
|= 1 << MSR_VR
;
136 if (ppc_flags
& POWERPC_FLAG_VSX
) {
137 QEMU_BUILD_BUG_ON(MSR_VSX
!= HFLAGS_VSX
);
138 msr_mask
|= 1 << MSR_VSX
;
140 if ((ppc_flags
& POWERPC_FLAG_TM
) && (msr
& (1ull << MSR_TM
))) {
141 hflags
|= 1 << HFLAGS_TM
;
143 if (env
->spr
[SPR_LPCR
] & LPCR_GTSE
) {
144 hflags
|= 1 << HFLAGS_GTSE
;
146 if (env
->spr
[SPR_LPCR
] & LPCR_HR
) {
147 hflags
|= 1 << HFLAGS_HR
;
150 #ifndef CONFIG_USER_ONLY
151 if (!env
->has_hv_mode
|| (msr
& (1ull << MSR_HV
))) {
152 hflags
|= 1 << HFLAGS_HV
;
156 * This is our encoding for server processors. The architecture
157 * specifies that there is no such thing as userspace with
158 * translation off, however it appears that MacOS does it and some
159 * 32-bit CPUs support it. Weird...
161 * 0 = Guest User space virtual mode
162 * 1 = Guest Kernel space virtual mode
163 * 2 = Guest User space real mode
164 * 3 = Guest Kernel space real mode
165 * 4 = HV User space virtual mode
166 * 5 = HV Kernel space virtual mode
167 * 6 = HV User space real mode
168 * 7 = HV Kernel space real mode
170 * For BookE, we need 8 MMU modes as follow:
172 * 0 = AS 0 HV User space
173 * 1 = AS 0 HV Kernel space
174 * 2 = AS 1 HV User space
175 * 3 = AS 1 HV Kernel space
176 * 4 = AS 0 Guest User space
177 * 5 = AS 0 Guest Kernel space
178 * 6 = AS 1 Guest User space
179 * 7 = AS 1 Guest Kernel space
181 unsigned immu_idx
, dmmu_idx
;
182 dmmu_idx
= msr
& (1 << MSR_PR
) ? 0 : 1;
183 if (env
->mmu_model
== POWERPC_MMU_BOOKE
||
184 env
->mmu_model
== POWERPC_MMU_BOOKE206
) {
185 dmmu_idx
|= msr
& (1 << MSR_GS
) ? 4 : 0;
187 immu_idx
|= msr
& (1 << MSR_IS
) ? 2 : 0;
188 dmmu_idx
|= msr
& (1 << MSR_DS
) ? 2 : 0;
190 dmmu_idx
|= msr
& (1ull << MSR_HV
) ? 4 : 0;
192 immu_idx
|= msr
& (1 << MSR_IR
) ? 0 : 2;
193 dmmu_idx
|= msr
& (1 << MSR_DR
) ? 0 : 2;
195 hflags
|= immu_idx
<< HFLAGS_IMMU_IDX
;
196 hflags
|= dmmu_idx
<< HFLAGS_DMMU_IDX
;
199 hflags
|= hreg_compute_pmu_hflags_value(env
);
201 return hflags
| (msr
& msr_mask
);
204 void hreg_compute_hflags(CPUPPCState
*env
)
206 env
->hflags
= hreg_compute_hflags_value(env
);
210 * This can be used as a lighter-weight alternative to hreg_compute_hflags
211 * when PMU MMCR0 or pmc_ins_cnt changes. pmc_ins_cnt is changed by
212 * pmu_update_summaries.
214 void hreg_update_pmu_hflags(CPUPPCState
*env
)
216 env
->hflags
&= ~hreg_compute_pmu_hflags_mask(env
);
217 env
->hflags
|= hreg_compute_pmu_hflags_value(env
);
220 #ifdef CONFIG_DEBUG_TCG
221 void cpu_get_tb_cpu_state(CPUPPCState
*env
, vaddr
*pc
,
222 uint64_t *cs_base
, uint32_t *flags
)
224 uint32_t hflags_current
= env
->hflags
;
225 uint32_t hflags_rebuilt
;
229 *flags
= hflags_current
;
231 hflags_rebuilt
= hreg_compute_hflags_value(env
);
232 if (unlikely(hflags_current
!= hflags_rebuilt
)) {
233 cpu_abort(env_cpu(env
),
234 "TCG hflags mismatch (current:0x%08x rebuilt:0x%08x)\n",
235 hflags_current
, hflags_rebuilt
);
240 void cpu_interrupt_exittb(CPUState
*cs
)
243 * We don't need to worry about translation blocks
244 * unless running with TCG.
248 cpu_interrupt(cs
, CPU_INTERRUPT_EXITTB
);
252 int hreg_store_msr(CPUPPCState
*env
, target_ulong value
, int alter_hv
)
255 #if !defined(CONFIG_USER_ONLY)
256 CPUState
*cs
= env_cpu(env
);
260 value
&= env
->msr_mask
;
261 #if !defined(CONFIG_USER_ONLY)
262 /* Neither mtmsr nor guest state can alter HV */
263 if (!alter_hv
|| !(env
->msr
& MSR_HVB
)) {
265 value
|= env
->msr
& MSR_HVB
;
267 /* Attempt to modify MSR[ME] in guest state is ignored */
268 if (is_book3s_arch2x(env
) && !(env
->msr
& MSR_HVB
)) {
269 value
&= ~(1 << MSR_ME
);
270 value
|= env
->msr
& (1 << MSR_ME
);
272 if ((value
^ env
->msr
) & (R_MSR_IR_MASK
| R_MSR_DR_MASK
)) {
273 cpu_interrupt_exittb(cs
);
275 if ((env
->mmu_model
== POWERPC_MMU_BOOKE
||
276 env
->mmu_model
== POWERPC_MMU_BOOKE206
) &&
277 ((value
^ env
->msr
) & R_MSR_GS_MASK
)) {
278 cpu_interrupt_exittb(cs
);
280 if (unlikely((env
->flags
& POWERPC_FLAG_TGPR
) &&
281 ((value
^ env
->msr
) & (1 << MSR_TGPR
)))) {
282 /* Swap temporary saved registers with GPRs */
283 hreg_swap_gpr_tgpr(env
);
285 if (unlikely((value
^ env
->msr
) & R_MSR_EP_MASK
)) {
286 env
->excp_prefix
= FIELD_EX64(value
, MSR
, EP
) * 0xFFF00000;
289 * If PR=1 then EE, IR and DR must be 1
291 * Note: We only enforce this on 64-bit server processors.
293 * - 32-bit implementations supports PR=1 and EE/DR/IR=0 and MacOS
295 * - 64-bit embedded implementations do not need any operation to be
296 * performed when PR is set.
298 if (is_book3s_arch2x(env
) && ((value
>> MSR_PR
) & 1)) {
299 value
|= (1 << MSR_EE
) | (1 << MSR_DR
) | (1 << MSR_IR
);
303 hreg_compute_hflags(env
);
304 #if !defined(CONFIG_USER_ONLY)
305 ppc_maybe_interrupt(env
);
307 if (unlikely(FIELD_EX64(env
->msr
, MSR
, POW
))) {
308 if (!env
->pending_interrupts
&& (*env
->check_pow
)(env
)) {
318 #ifndef CONFIG_USER_ONLY
319 void store_40x_sler(CPUPPCState
*env
, uint32_t val
)
321 /* XXX: TO BE FIXED */
322 if (val
!= 0x00000000) {
323 cpu_abort(env_cpu(env
),
324 "Little-endian regions are not supported by now\n");
326 env
->spr
[SPR_405_SLER
] = val
;
329 void check_tlb_flush(CPUPPCState
*env
, bool global
)
331 CPUState
*cs
= env_cpu(env
);
333 /* Handle global flushes first */
334 if (global
&& (env
->tlb_need_flush
& TLB_NEED_GLOBAL_FLUSH
)) {
335 env
->tlb_need_flush
&= ~TLB_NEED_GLOBAL_FLUSH
;
336 env
->tlb_need_flush
&= ~TLB_NEED_LOCAL_FLUSH
;
337 tlb_flush_all_cpus(cs
);
341 /* Then handle local ones */
342 if (env
->tlb_need_flush
& TLB_NEED_LOCAL_FLUSH
) {
343 env
->tlb_need_flush
&= ~TLB_NEED_LOCAL_FLUSH
;
347 #endif /* !CONFIG_USER_ONLY */
352 * Register an SPR with all the callbacks required for tcg,
353 * and the ID number for KVM.
355 * The reason for the conditional compilation is that the tcg functions
356 * may be compiled out, and the system kvm header may not be available
357 * for supplying the ID numbers. This is ugly, but the best we can do.
359 void _spr_register(CPUPPCState
*env
, int num
, const char *name
,
360 USR_ARG(spr_callback
*uea_read
)
361 USR_ARG(spr_callback
*uea_write
)
362 SYS_ARG(spr_callback
*oea_read
)
363 SYS_ARG(spr_callback
*oea_write
)
364 SYS_ARG(spr_callback
*hea_read
)
365 SYS_ARG(spr_callback
*hea_write
)
366 KVM_ARG(uint64_t one_reg_id
)
367 target_ulong initial_value
)
369 ppc_spr_t
*spr
= &env
->spr_cb
[num
];
371 /* No SPR should be registered twice. */
372 assert(spr
->name
== NULL
);
373 assert(name
!= NULL
);
376 spr
->default_value
= initial_value
;
377 env
->spr
[num
] = initial_value
;
380 spr
->uea_read
= uea_read
;
381 spr
->uea_write
= uea_write
;
382 # ifndef CONFIG_USER_ONLY
383 spr
->oea_read
= oea_read
;
384 spr
->oea_write
= oea_write
;
385 spr
->hea_read
= hea_read
;
386 spr
->hea_write
= hea_write
;
390 spr
->one_reg_id
= one_reg_id
;
394 /* Generic PowerPC SPRs */
395 void register_generic_sprs(PowerPCCPU
*cpu
)
397 PowerPCCPUClass
*pcc
= POWERPC_CPU_GET_CLASS(cpu
);
398 CPUPPCState
*env
= &cpu
->env
;
400 /* Integer processing */
401 spr_register(env
, SPR_XER
, "XER",
402 &spr_read_xer
, &spr_write_xer
,
403 &spr_read_xer
, &spr_write_xer
,
406 spr_register(env
, SPR_LR
, "LR",
407 &spr_read_lr
, &spr_write_lr
,
408 &spr_read_lr
, &spr_write_lr
,
410 spr_register(env
, SPR_CTR
, "CTR",
411 &spr_read_ctr
, &spr_write_ctr
,
412 &spr_read_ctr
, &spr_write_ctr
,
414 /* Interrupt processing */
415 spr_register(env
, SPR_SRR0
, "SRR0",
416 SPR_NOACCESS
, SPR_NOACCESS
,
417 &spr_read_generic
, &spr_write_generic
,
419 spr_register(env
, SPR_SRR1
, "SRR1",
420 SPR_NOACCESS
, SPR_NOACCESS
,
421 &spr_read_generic
, &spr_write_generic
,
423 /* Processor control */
424 spr_register(env
, SPR_SPRG0
, "SPRG0",
425 SPR_NOACCESS
, SPR_NOACCESS
,
426 &spr_read_generic
, &spr_write_generic
,
428 spr_register(env
, SPR_SPRG1
, "SPRG1",
429 SPR_NOACCESS
, SPR_NOACCESS
,
430 &spr_read_generic
, &spr_write_generic
,
432 spr_register(env
, SPR_SPRG2
, "SPRG2",
433 SPR_NOACCESS
, SPR_NOACCESS
,
434 &spr_read_generic
, &spr_write_generic
,
436 spr_register(env
, SPR_SPRG3
, "SPRG3",
437 SPR_NOACCESS
, SPR_NOACCESS
,
438 &spr_read_generic
, &spr_write_generic
,
441 spr_register(env
, SPR_PVR
, "PVR",
442 /* Linux permits userspace to read PVR */
443 #if defined(CONFIG_LINUX_USER)
449 &spr_read_generic
, SPR_NOACCESS
,
452 /* Register SVR if it's defined to anything else than POWERPC_SVR_NONE */
453 if (pcc
->svr
!= POWERPC_SVR_NONE
) {
454 if (pcc
->svr
& POWERPC_SVR_E500
) {
455 spr_register(env
, SPR_E500_SVR
, "SVR",
456 SPR_NOACCESS
, SPR_NOACCESS
,
457 &spr_read_generic
, SPR_NOACCESS
,
458 pcc
->svr
& ~POWERPC_SVR_E500
);
460 spr_register(env
, SPR_SVR
, "SVR",
461 SPR_NOACCESS
, SPR_NOACCESS
,
462 &spr_read_generic
, SPR_NOACCESS
,
468 #if defined(TARGET_PPC64)
469 spr_register(env
, SPR_TBL
, "TB",
471 spr_register(env
, SPR_TBL
, "TBL",
473 &spr_read_tbl
, SPR_NOACCESS
,
474 &spr_read_tbl
, SPR_NOACCESS
,
476 spr_register(env
, SPR_TBU
, "TBU",
477 &spr_read_tbu
, SPR_NOACCESS
,
478 &spr_read_tbu
, SPR_NOACCESS
,
480 #ifndef CONFIG_USER_ONLY
481 if (env
->has_hv_mode
) {
482 spr_register_hv(env
, SPR_WR_TBL
, "TBL",
483 SPR_NOACCESS
, SPR_NOACCESS
,
484 SPR_NOACCESS
, SPR_NOACCESS
,
485 SPR_NOACCESS
, &spr_write_tbl
,
487 spr_register_hv(env
, SPR_WR_TBU
, "TBU",
488 SPR_NOACCESS
, SPR_NOACCESS
,
489 SPR_NOACCESS
, SPR_NOACCESS
,
490 SPR_NOACCESS
, &spr_write_tbu
,
493 spr_register(env
, SPR_WR_TBL
, "TBL",
494 SPR_NOACCESS
, SPR_NOACCESS
,
495 SPR_NOACCESS
, &spr_write_tbl
,
497 spr_register(env
, SPR_WR_TBU
, "TBU",
498 SPR_NOACCESS
, SPR_NOACCESS
,
499 SPR_NOACCESS
, &spr_write_tbu
,
505 void register_non_embedded_sprs(CPUPPCState
*env
)
507 /* Exception processing */
508 spr_register_kvm(env
, SPR_DSISR
, "DSISR",
509 SPR_NOACCESS
, SPR_NOACCESS
,
510 &spr_read_generic
, &spr_write_generic32
,
511 KVM_REG_PPC_DSISR
, 0x00000000);
512 spr_register_kvm(env
, SPR_DAR
, "DAR",
513 SPR_NOACCESS
, SPR_NOACCESS
,
514 &spr_read_generic
, &spr_write_generic
,
515 KVM_REG_PPC_DAR
, 0x00000000);
517 spr_register(env
, SPR_DECR
, "DEC",
518 SPR_NOACCESS
, SPR_NOACCESS
,
519 &spr_read_decr
, &spr_write_decr
,
523 /* Storage Description Register 1 */
524 void register_sdr1_sprs(CPUPPCState
*env
)
526 #ifndef CONFIG_USER_ONLY
527 if (env
->has_hv_mode
) {
529 * SDR1 is a hypervisor resource on CPUs which have a
532 spr_register_hv(env
, SPR_SDR1
, "SDR1",
533 SPR_NOACCESS
, SPR_NOACCESS
,
534 SPR_NOACCESS
, SPR_NOACCESS
,
535 &spr_read_generic
, &spr_write_sdr1
,
538 spr_register(env
, SPR_SDR1
, "SDR1",
539 SPR_NOACCESS
, SPR_NOACCESS
,
540 &spr_read_generic
, &spr_write_sdr1
,
547 void register_low_BATs(CPUPPCState
*env
)
549 #if !defined(CONFIG_USER_ONLY)
550 spr_register(env
, SPR_IBAT0U
, "IBAT0U",
551 SPR_NOACCESS
, SPR_NOACCESS
,
552 &spr_read_ibat
, &spr_write_ibatu
,
554 spr_register(env
, SPR_IBAT0L
, "IBAT0L",
555 SPR_NOACCESS
, SPR_NOACCESS
,
556 &spr_read_ibat
, &spr_write_ibatl
,
558 spr_register(env
, SPR_IBAT1U
, "IBAT1U",
559 SPR_NOACCESS
, SPR_NOACCESS
,
560 &spr_read_ibat
, &spr_write_ibatu
,
562 spr_register(env
, SPR_IBAT1L
, "IBAT1L",
563 SPR_NOACCESS
, SPR_NOACCESS
,
564 &spr_read_ibat
, &spr_write_ibatl
,
566 spr_register(env
, SPR_IBAT2U
, "IBAT2U",
567 SPR_NOACCESS
, SPR_NOACCESS
,
568 &spr_read_ibat
, &spr_write_ibatu
,
570 spr_register(env
, SPR_IBAT2L
, "IBAT2L",
571 SPR_NOACCESS
, SPR_NOACCESS
,
572 &spr_read_ibat
, &spr_write_ibatl
,
574 spr_register(env
, SPR_IBAT3U
, "IBAT3U",
575 SPR_NOACCESS
, SPR_NOACCESS
,
576 &spr_read_ibat
, &spr_write_ibatu
,
578 spr_register(env
, SPR_IBAT3L
, "IBAT3L",
579 SPR_NOACCESS
, SPR_NOACCESS
,
580 &spr_read_ibat
, &spr_write_ibatl
,
582 spr_register(env
, SPR_DBAT0U
, "DBAT0U",
583 SPR_NOACCESS
, SPR_NOACCESS
,
584 &spr_read_dbat
, &spr_write_dbatu
,
586 spr_register(env
, SPR_DBAT0L
, "DBAT0L",
587 SPR_NOACCESS
, SPR_NOACCESS
,
588 &spr_read_dbat
, &spr_write_dbatl
,
590 spr_register(env
, SPR_DBAT1U
, "DBAT1U",
591 SPR_NOACCESS
, SPR_NOACCESS
,
592 &spr_read_dbat
, &spr_write_dbatu
,
594 spr_register(env
, SPR_DBAT1L
, "DBAT1L",
595 SPR_NOACCESS
, SPR_NOACCESS
,
596 &spr_read_dbat
, &spr_write_dbatl
,
598 spr_register(env
, SPR_DBAT2U
, "DBAT2U",
599 SPR_NOACCESS
, SPR_NOACCESS
,
600 &spr_read_dbat
, &spr_write_dbatu
,
602 spr_register(env
, SPR_DBAT2L
, "DBAT2L",
603 SPR_NOACCESS
, SPR_NOACCESS
,
604 &spr_read_dbat
, &spr_write_dbatl
,
606 spr_register(env
, SPR_DBAT3U
, "DBAT3U",
607 SPR_NOACCESS
, SPR_NOACCESS
,
608 &spr_read_dbat
, &spr_write_dbatu
,
610 spr_register(env
, SPR_DBAT3L
, "DBAT3L",
611 SPR_NOACCESS
, SPR_NOACCESS
,
612 &spr_read_dbat
, &spr_write_dbatl
,
619 void register_high_BATs(CPUPPCState
*env
)
621 #if !defined(CONFIG_USER_ONLY)
622 spr_register(env
, SPR_IBAT4U
, "IBAT4U",
623 SPR_NOACCESS
, SPR_NOACCESS
,
624 &spr_read_ibat_h
, &spr_write_ibatu_h
,
626 spr_register(env
, SPR_IBAT4L
, "IBAT4L",
627 SPR_NOACCESS
, SPR_NOACCESS
,
628 &spr_read_ibat_h
, &spr_write_ibatl_h
,
630 spr_register(env
, SPR_IBAT5U
, "IBAT5U",
631 SPR_NOACCESS
, SPR_NOACCESS
,
632 &spr_read_ibat_h
, &spr_write_ibatu_h
,
634 spr_register(env
, SPR_IBAT5L
, "IBAT5L",
635 SPR_NOACCESS
, SPR_NOACCESS
,
636 &spr_read_ibat_h
, &spr_write_ibatl_h
,
638 spr_register(env
, SPR_IBAT6U
, "IBAT6U",
639 SPR_NOACCESS
, SPR_NOACCESS
,
640 &spr_read_ibat_h
, &spr_write_ibatu_h
,
642 spr_register(env
, SPR_IBAT6L
, "IBAT6L",
643 SPR_NOACCESS
, SPR_NOACCESS
,
644 &spr_read_ibat_h
, &spr_write_ibatl_h
,
646 spr_register(env
, SPR_IBAT7U
, "IBAT7U",
647 SPR_NOACCESS
, SPR_NOACCESS
,
648 &spr_read_ibat_h
, &spr_write_ibatu_h
,
650 spr_register(env
, SPR_IBAT7L
, "IBAT7L",
651 SPR_NOACCESS
, SPR_NOACCESS
,
652 &spr_read_ibat_h
, &spr_write_ibatl_h
,
654 spr_register(env
, SPR_DBAT4U
, "DBAT4U",
655 SPR_NOACCESS
, SPR_NOACCESS
,
656 &spr_read_dbat_h
, &spr_write_dbatu_h
,
658 spr_register(env
, SPR_DBAT4L
, "DBAT4L",
659 SPR_NOACCESS
, SPR_NOACCESS
,
660 &spr_read_dbat_h
, &spr_write_dbatl_h
,
662 spr_register(env
, SPR_DBAT5U
, "DBAT5U",
663 SPR_NOACCESS
, SPR_NOACCESS
,
664 &spr_read_dbat_h
, &spr_write_dbatu_h
,
666 spr_register(env
, SPR_DBAT5L
, "DBAT5L",
667 SPR_NOACCESS
, SPR_NOACCESS
,
668 &spr_read_dbat_h
, &spr_write_dbatl_h
,
670 spr_register(env
, SPR_DBAT6U
, "DBAT6U",
671 SPR_NOACCESS
, SPR_NOACCESS
,
672 &spr_read_dbat_h
, &spr_write_dbatu_h
,
674 spr_register(env
, SPR_DBAT6L
, "DBAT6L",
675 SPR_NOACCESS
, SPR_NOACCESS
,
676 &spr_read_dbat_h
, &spr_write_dbatl_h
,
678 spr_register(env
, SPR_DBAT7U
, "DBAT7U",
679 SPR_NOACCESS
, SPR_NOACCESS
,
680 &spr_read_dbat_h
, &spr_write_dbatu_h
,
682 spr_register(env
, SPR_DBAT7L
, "DBAT7L",
683 SPR_NOACCESS
, SPR_NOACCESS
,
684 &spr_read_dbat_h
, &spr_write_dbatl_h
,
690 /* Softare table search registers */
691 void register_6xx_7xx_soft_tlb(CPUPPCState
*env
, int nb_tlbs
, int nb_ways
)
693 #if !defined(CONFIG_USER_ONLY)
694 env
->nb_tlb
= nb_tlbs
;
695 env
->nb_ways
= nb_ways
;
697 env
->tlb_type
= TLB_6XX
;
698 spr_register(env
, SPR_DMISS
, "DMISS",
699 SPR_NOACCESS
, SPR_NOACCESS
,
700 &spr_read_generic
, SPR_NOACCESS
,
702 spr_register(env
, SPR_DCMP
, "DCMP",
703 SPR_NOACCESS
, SPR_NOACCESS
,
704 &spr_read_generic
, SPR_NOACCESS
,
706 spr_register(env
, SPR_HASH1
, "HASH1",
707 SPR_NOACCESS
, SPR_NOACCESS
,
708 &spr_read_generic
, SPR_NOACCESS
,
710 spr_register(env
, SPR_HASH2
, "HASH2",
711 SPR_NOACCESS
, SPR_NOACCESS
,
712 &spr_read_generic
, SPR_NOACCESS
,
714 spr_register(env
, SPR_IMISS
, "IMISS",
715 SPR_NOACCESS
, SPR_NOACCESS
,
716 &spr_read_generic
, SPR_NOACCESS
,
718 spr_register(env
, SPR_ICMP
, "ICMP",
719 SPR_NOACCESS
, SPR_NOACCESS
,
720 &spr_read_generic
, SPR_NOACCESS
,
722 spr_register(env
, SPR_RPA
, "RPA",
723 SPR_NOACCESS
, SPR_NOACCESS
,
724 &spr_read_generic
, &spr_write_generic
,
729 void register_thrm_sprs(CPUPPCState
*env
)
731 /* Thermal management */
732 spr_register(env
, SPR_THRM1
, "THRM1",
733 SPR_NOACCESS
, SPR_NOACCESS
,
734 &spr_read_thrm
, &spr_write_generic
,
737 spr_register(env
, SPR_THRM2
, "THRM2",
738 SPR_NOACCESS
, SPR_NOACCESS
,
739 &spr_read_thrm
, &spr_write_generic
,
742 spr_register(env
, SPR_THRM3
, "THRM3",
743 SPR_NOACCESS
, SPR_NOACCESS
,
744 &spr_read_thrm
, &spr_write_generic
,
748 void register_usprgh_sprs(CPUPPCState
*env
)
750 spr_register(env
, SPR_USPRG4
, "USPRG4",
751 &spr_read_ureg
, SPR_NOACCESS
,
752 &spr_read_ureg
, SPR_NOACCESS
,
754 spr_register(env
, SPR_USPRG5
, "USPRG5",
755 &spr_read_ureg
, SPR_NOACCESS
,
756 &spr_read_ureg
, SPR_NOACCESS
,
758 spr_register(env
, SPR_USPRG6
, "USPRG6",
759 &spr_read_ureg
, SPR_NOACCESS
,
760 &spr_read_ureg
, SPR_NOACCESS
,
762 spr_register(env
, SPR_USPRG7
, "USPRG7",
763 &spr_read_ureg
, SPR_NOACCESS
,
764 &spr_read_ureg
, SPR_NOACCESS
,