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 "helper_regs.h"
26 #include "power8-pmu.h"
27 #include "cpu-models.h"
28 #include "spr_common.h"
30 /* Swap temporary saved registers with GPRs */
31 void hreg_swap_gpr_tgpr(CPUPPCState
*env
)
36 env
->gpr
[0] = env
->tgpr
[0];
39 env
->gpr
[1] = env
->tgpr
[1];
42 env
->gpr
[2] = env
->tgpr
[2];
45 env
->gpr
[3] = env
->tgpr
[3];
49 static uint32_t hreg_compute_hflags_value(CPUPPCState
*env
)
51 target_ulong msr
= env
->msr
;
52 uint32_t ppc_flags
= env
->flags
;
56 /* Some bits come straight across from MSR. */
57 QEMU_BUILD_BUG_ON(MSR_LE
!= HFLAGS_LE
);
58 QEMU_BUILD_BUG_ON(MSR_PR
!= HFLAGS_PR
);
59 QEMU_BUILD_BUG_ON(MSR_DR
!= HFLAGS_DR
);
60 QEMU_BUILD_BUG_ON(MSR_FP
!= HFLAGS_FP
);
61 msr_mask
= ((1 << MSR_LE
) | (1 << MSR_PR
) |
62 (1 << MSR_DR
) | (1 << MSR_FP
));
64 if (ppc_flags
& POWERPC_FLAG_DE
) {
65 target_ulong dbcr0
= env
->spr
[SPR_BOOKE_DBCR0
];
66 if (dbcr0
& DBCR0_ICMP
) {
67 hflags
|= 1 << HFLAGS_SE
;
69 if (dbcr0
& DBCR0_BRT
) {
70 hflags
|= 1 << HFLAGS_BE
;
73 if (ppc_flags
& POWERPC_FLAG_BE
) {
74 QEMU_BUILD_BUG_ON(MSR_BE
!= HFLAGS_BE
);
75 msr_mask
|= 1 << MSR_BE
;
77 if (ppc_flags
& POWERPC_FLAG_SE
) {
78 QEMU_BUILD_BUG_ON(MSR_SE
!= HFLAGS_SE
);
79 msr_mask
|= 1 << MSR_SE
;
83 if (msr_is_64bit(env
, msr
)) {
84 hflags
|= 1 << HFLAGS_64
;
86 if ((ppc_flags
& POWERPC_FLAG_SPE
) && (msr
& (1 << MSR_SPE
))) {
87 hflags
|= 1 << HFLAGS_SPE
;
89 if (ppc_flags
& POWERPC_FLAG_VRE
) {
90 QEMU_BUILD_BUG_ON(MSR_VR
!= HFLAGS_VR
);
91 msr_mask
|= 1 << MSR_VR
;
93 if (ppc_flags
& POWERPC_FLAG_VSX
) {
94 QEMU_BUILD_BUG_ON(MSR_VSX
!= HFLAGS_VSX
);
95 msr_mask
|= 1 << MSR_VSX
;
97 if ((ppc_flags
& POWERPC_FLAG_TM
) && (msr
& (1ull << MSR_TM
))) {
98 hflags
|= 1 << HFLAGS_TM
;
100 if (env
->spr
[SPR_LPCR
] & LPCR_GTSE
) {
101 hflags
|= 1 << HFLAGS_GTSE
;
103 if (env
->spr
[SPR_LPCR
] & LPCR_HR
) {
104 hflags
|= 1 << HFLAGS_HR
;
106 if (env
->spr
[SPR_POWER_MMCR0
] & MMCR0_PMCC0
) {
107 hflags
|= 1 << HFLAGS_PMCC0
;
109 if (env
->spr
[SPR_POWER_MMCR0
] & MMCR0_PMCC1
) {
110 hflags
|= 1 << HFLAGS_PMCC1
;
113 #ifndef CONFIG_USER_ONLY
114 if (!env
->has_hv_mode
|| (msr
& (1ull << MSR_HV
))) {
115 hflags
|= 1 << HFLAGS_HV
;
118 #if defined(TARGET_PPC64)
119 if (env
->pmc_ins_cnt
) {
120 hflags
|= 1 << HFLAGS_INSN_CNT
;
125 * This is our encoding for server processors. The architecture
126 * specifies that there is no such thing as userspace with
127 * translation off, however it appears that MacOS does it and some
128 * 32-bit CPUs support it. Weird...
130 * 0 = Guest User space virtual mode
131 * 1 = Guest Kernel space virtual mode
132 * 2 = Guest User space real mode
133 * 3 = Guest Kernel space real mode
134 * 4 = HV User space virtual mode
135 * 5 = HV Kernel space virtual mode
136 * 6 = HV User space real mode
137 * 7 = HV Kernel space real mode
139 * For BookE, we need 8 MMU modes as follow:
141 * 0 = AS 0 HV User space
142 * 1 = AS 0 HV Kernel space
143 * 2 = AS 1 HV User space
144 * 3 = AS 1 HV Kernel space
145 * 4 = AS 0 Guest User space
146 * 5 = AS 0 Guest Kernel space
147 * 6 = AS 1 Guest User space
148 * 7 = AS 1 Guest Kernel space
150 unsigned immu_idx
, dmmu_idx
;
151 dmmu_idx
= msr
& (1 << MSR_PR
) ? 0 : 1;
152 if (env
->mmu_model
== POWERPC_MMU_BOOKE
||
153 env
->mmu_model
== POWERPC_MMU_BOOKE206
) {
154 dmmu_idx
|= msr
& (1 << MSR_GS
) ? 4 : 0;
156 immu_idx
|= msr
& (1 << MSR_IS
) ? 2 : 0;
157 dmmu_idx
|= msr
& (1 << MSR_DS
) ? 2 : 0;
159 dmmu_idx
|= msr
& (1ull << MSR_HV
) ? 4 : 0;
161 immu_idx
|= msr
& (1 << MSR_IR
) ? 0 : 2;
162 dmmu_idx
|= msr
& (1 << MSR_DR
) ? 0 : 2;
164 hflags
|= immu_idx
<< HFLAGS_IMMU_IDX
;
165 hflags
|= dmmu_idx
<< HFLAGS_DMMU_IDX
;
168 return hflags
| (msr
& msr_mask
);
171 void hreg_compute_hflags(CPUPPCState
*env
)
173 env
->hflags
= hreg_compute_hflags_value(env
);
176 #ifdef CONFIG_DEBUG_TCG
177 void cpu_get_tb_cpu_state(CPUPPCState
*env
, target_ulong
*pc
,
178 target_ulong
*cs_base
, uint32_t *flags
)
180 uint32_t hflags_current
= env
->hflags
;
181 uint32_t hflags_rebuilt
;
185 *flags
= hflags_current
;
187 hflags_rebuilt
= hreg_compute_hflags_value(env
);
188 if (unlikely(hflags_current
!= hflags_rebuilt
)) {
189 cpu_abort(env_cpu(env
),
190 "TCG hflags mismatch (current:0x%08x rebuilt:0x%08x)\n",
191 hflags_current
, hflags_rebuilt
);
196 void cpu_interrupt_exittb(CPUState
*cs
)
199 * We don't need to worry about translation blocks
200 * when running with KVM.
206 if (!qemu_mutex_iothread_locked()) {
207 qemu_mutex_lock_iothread();
208 cpu_interrupt(cs
, CPU_INTERRUPT_EXITTB
);
209 qemu_mutex_unlock_iothread();
211 cpu_interrupt(cs
, CPU_INTERRUPT_EXITTB
);
215 int hreg_store_msr(CPUPPCState
*env
, target_ulong value
, int alter_hv
)
218 #if !defined(CONFIG_USER_ONLY)
219 CPUState
*cs
= env_cpu(env
);
223 value
&= env
->msr_mask
;
224 #if !defined(CONFIG_USER_ONLY)
225 /* Neither mtmsr nor guest state can alter HV */
226 if (!alter_hv
|| !(env
->msr
& MSR_HVB
)) {
228 value
|= env
->msr
& MSR_HVB
;
230 if (((value
>> MSR_IR
) & 1) != msr_ir
||
231 ((value
>> MSR_DR
) & 1) != msr_dr
) {
232 cpu_interrupt_exittb(cs
);
234 if ((env
->mmu_model
== POWERPC_MMU_BOOKE
||
235 env
->mmu_model
== POWERPC_MMU_BOOKE206
) &&
236 ((value
>> MSR_GS
) & 1) != msr_gs
) {
237 cpu_interrupt_exittb(cs
);
239 if (unlikely((env
->flags
& POWERPC_FLAG_TGPR
) &&
240 ((value
^ env
->msr
) & (1 << MSR_TGPR
)))) {
241 /* Swap temporary saved registers with GPRs */
242 hreg_swap_gpr_tgpr(env
);
244 if (unlikely((value
>> MSR_EP
) & 1) != msr_ep
) {
245 env
->excp_prefix
= ((value
>> MSR_EP
) & 1) * 0xFFF00000;
248 * If PR=1 then EE, IR and DR must be 1
250 * Note: We only enforce this on 64-bit server processors.
252 * - 32-bit implementations supports PR=1 and EE/DR/IR=0 and MacOS
254 * - 64-bit embedded implementations do not need any operation to be
255 * performed when PR is set.
257 if (is_book3s_arch2x(env
) && ((value
>> MSR_PR
) & 1)) {
258 value
|= (1 << MSR_EE
) | (1 << MSR_DR
) | (1 << MSR_IR
);
262 hreg_compute_hflags(env
);
263 #if !defined(CONFIG_USER_ONLY)
264 if (unlikely(msr_pow
== 1)) {
265 if (!env
->pending_interrupts
&& (*env
->check_pow
)(env
)) {
275 #ifdef CONFIG_SOFTMMU
276 void store_40x_sler(CPUPPCState
*env
, uint32_t val
)
278 /* XXX: TO BE FIXED */
279 if (val
!= 0x00000000) {
280 cpu_abort(env_cpu(env
),
281 "Little-endian regions are not supported by now\n");
283 env
->spr
[SPR_405_SLER
] = val
;
285 #endif /* CONFIG_SOFTMMU */
287 #ifndef CONFIG_USER_ONLY
288 void check_tlb_flush(CPUPPCState
*env
, bool global
)
290 CPUState
*cs
= env_cpu(env
);
292 /* Handle global flushes first */
293 if (global
&& (env
->tlb_need_flush
& TLB_NEED_GLOBAL_FLUSH
)) {
294 env
->tlb_need_flush
&= ~TLB_NEED_GLOBAL_FLUSH
;
295 env
->tlb_need_flush
&= ~TLB_NEED_LOCAL_FLUSH
;
296 tlb_flush_all_cpus_synced(cs
);
300 /* Then handle local ones */
301 if (env
->tlb_need_flush
& TLB_NEED_LOCAL_FLUSH
) {
302 env
->tlb_need_flush
&= ~TLB_NEED_LOCAL_FLUSH
;
311 * Register an SPR with all the callbacks required for tcg,
312 * and the ID number for KVM.
314 * The reason for the conditional compilation is that the tcg functions
315 * may be compiled out, and the system kvm header may not be available
316 * for supplying the ID numbers. This is ugly, but the best we can do.
318 void _spr_register(CPUPPCState
*env
, int num
, const char *name
,
319 USR_ARG(spr_callback
*uea_read
)
320 USR_ARG(spr_callback
*uea_write
)
321 SYS_ARG(spr_callback
*oea_read
)
322 SYS_ARG(spr_callback
*oea_write
)
323 SYS_ARG(spr_callback
*hea_read
)
324 SYS_ARG(spr_callback
*hea_write
)
325 KVM_ARG(uint64_t one_reg_id
)
326 target_ulong initial_value
)
328 ppc_spr_t
*spr
= &env
->spr_cb
[num
];
330 /* No SPR should be registered twice. */
331 assert(spr
->name
== NULL
);
332 assert(name
!= NULL
);
335 spr
->default_value
= initial_value
;
336 env
->spr
[num
] = initial_value
;
339 spr
->uea_read
= uea_read
;
340 spr
->uea_write
= uea_write
;
341 # ifndef CONFIG_USER_ONLY
342 spr
->oea_read
= oea_read
;
343 spr
->oea_write
= oea_write
;
344 spr
->hea_read
= hea_read
;
345 spr
->hea_write
= hea_write
;
349 spr
->one_reg_id
= one_reg_id
;
353 /* Generic PowerPC SPRs */
354 void register_generic_sprs(PowerPCCPU
*cpu
)
356 PowerPCCPUClass
*pcc
= POWERPC_CPU_GET_CLASS(cpu
);
357 CPUPPCState
*env
= &cpu
->env
;
359 /* Integer processing */
360 spr_register(env
, SPR_XER
, "XER",
361 &spr_read_xer
, &spr_write_xer
,
362 &spr_read_xer
, &spr_write_xer
,
365 spr_register(env
, SPR_LR
, "LR",
366 &spr_read_lr
, &spr_write_lr
,
367 &spr_read_lr
, &spr_write_lr
,
369 spr_register(env
, SPR_CTR
, "CTR",
370 &spr_read_ctr
, &spr_write_ctr
,
371 &spr_read_ctr
, &spr_write_ctr
,
373 /* Interrupt processing */
374 spr_register(env
, SPR_SRR0
, "SRR0",
375 SPR_NOACCESS
, SPR_NOACCESS
,
376 &spr_read_generic
, &spr_write_generic
,
378 spr_register(env
, SPR_SRR1
, "SRR1",
379 SPR_NOACCESS
, SPR_NOACCESS
,
380 &spr_read_generic
, &spr_write_generic
,
382 /* Processor control */
383 spr_register(env
, SPR_SPRG0
, "SPRG0",
384 SPR_NOACCESS
, SPR_NOACCESS
,
385 &spr_read_generic
, &spr_write_generic
,
387 spr_register(env
, SPR_SPRG1
, "SPRG1",
388 SPR_NOACCESS
, SPR_NOACCESS
,
389 &spr_read_generic
, &spr_write_generic
,
391 spr_register(env
, SPR_SPRG2
, "SPRG2",
392 SPR_NOACCESS
, SPR_NOACCESS
,
393 &spr_read_generic
, &spr_write_generic
,
395 spr_register(env
, SPR_SPRG3
, "SPRG3",
396 SPR_NOACCESS
, SPR_NOACCESS
,
397 &spr_read_generic
, &spr_write_generic
,
400 spr_register(env
, SPR_PVR
, "PVR",
401 /* Linux permits userspace to read PVR */
402 #if defined(CONFIG_LINUX_USER)
408 &spr_read_generic
, SPR_NOACCESS
,
411 /* Register SVR if it's defined to anything else than POWERPC_SVR_NONE */
412 if (pcc
->svr
!= POWERPC_SVR_NONE
) {
413 if (pcc
->svr
& POWERPC_SVR_E500
) {
414 spr_register(env
, SPR_E500_SVR
, "SVR",
415 SPR_NOACCESS
, SPR_NOACCESS
,
416 &spr_read_generic
, SPR_NOACCESS
,
417 pcc
->svr
& ~POWERPC_SVR_E500
);
419 spr_register(env
, SPR_SVR
, "SVR",
420 SPR_NOACCESS
, SPR_NOACCESS
,
421 &spr_read_generic
, SPR_NOACCESS
,
427 spr_register(env
, SPR_VTBL
, "TBL",
428 &spr_read_tbl
, SPR_NOACCESS
,
429 &spr_read_tbl
, SPR_NOACCESS
,
431 spr_register(env
, SPR_TBL
, "TBL",
432 &spr_read_tbl
, SPR_NOACCESS
,
433 &spr_read_tbl
, &spr_write_tbl
,
435 spr_register(env
, SPR_VTBU
, "TBU",
436 &spr_read_tbu
, SPR_NOACCESS
,
437 &spr_read_tbu
, SPR_NOACCESS
,
439 spr_register(env
, SPR_TBU
, "TBU",
440 &spr_read_tbu
, SPR_NOACCESS
,
441 &spr_read_tbu
, &spr_write_tbu
,
445 void register_non_embedded_sprs(CPUPPCState
*env
)
447 /* Exception processing */
448 spr_register_kvm(env
, SPR_DSISR
, "DSISR",
449 SPR_NOACCESS
, SPR_NOACCESS
,
450 &spr_read_generic
, &spr_write_generic
,
451 KVM_REG_PPC_DSISR
, 0x00000000);
452 spr_register_kvm(env
, SPR_DAR
, "DAR",
453 SPR_NOACCESS
, SPR_NOACCESS
,
454 &spr_read_generic
, &spr_write_generic
,
455 KVM_REG_PPC_DAR
, 0x00000000);
457 spr_register(env
, SPR_DECR
, "DECR",
458 SPR_NOACCESS
, SPR_NOACCESS
,
459 &spr_read_decr
, &spr_write_decr
,
463 /* Storage Description Register 1 */
464 void register_sdr1_sprs(CPUPPCState
*env
)
466 #ifndef CONFIG_USER_ONLY
467 if (env
->has_hv_mode
) {
469 * SDR1 is a hypervisor resource on CPUs which have a
472 spr_register_hv(env
, SPR_SDR1
, "SDR1",
473 SPR_NOACCESS
, SPR_NOACCESS
,
474 SPR_NOACCESS
, SPR_NOACCESS
,
475 &spr_read_generic
, &spr_write_sdr1
,
478 spr_register(env
, SPR_SDR1
, "SDR1",
479 SPR_NOACCESS
, SPR_NOACCESS
,
480 &spr_read_generic
, &spr_write_sdr1
,
487 void register_low_BATs(CPUPPCState
*env
)
489 #if !defined(CONFIG_USER_ONLY)
490 spr_register(env
, SPR_IBAT0U
, "IBAT0U",
491 SPR_NOACCESS
, SPR_NOACCESS
,
492 &spr_read_ibat
, &spr_write_ibatu
,
494 spr_register(env
, SPR_IBAT0L
, "IBAT0L",
495 SPR_NOACCESS
, SPR_NOACCESS
,
496 &spr_read_ibat
, &spr_write_ibatl
,
498 spr_register(env
, SPR_IBAT1U
, "IBAT1U",
499 SPR_NOACCESS
, SPR_NOACCESS
,
500 &spr_read_ibat
, &spr_write_ibatu
,
502 spr_register(env
, SPR_IBAT1L
, "IBAT1L",
503 SPR_NOACCESS
, SPR_NOACCESS
,
504 &spr_read_ibat
, &spr_write_ibatl
,
506 spr_register(env
, SPR_IBAT2U
, "IBAT2U",
507 SPR_NOACCESS
, SPR_NOACCESS
,
508 &spr_read_ibat
, &spr_write_ibatu
,
510 spr_register(env
, SPR_IBAT2L
, "IBAT2L",
511 SPR_NOACCESS
, SPR_NOACCESS
,
512 &spr_read_ibat
, &spr_write_ibatl
,
514 spr_register(env
, SPR_IBAT3U
, "IBAT3U",
515 SPR_NOACCESS
, SPR_NOACCESS
,
516 &spr_read_ibat
, &spr_write_ibatu
,
518 spr_register(env
, SPR_IBAT3L
, "IBAT3L",
519 SPR_NOACCESS
, SPR_NOACCESS
,
520 &spr_read_ibat
, &spr_write_ibatl
,
522 spr_register(env
, SPR_DBAT0U
, "DBAT0U",
523 SPR_NOACCESS
, SPR_NOACCESS
,
524 &spr_read_dbat
, &spr_write_dbatu
,
526 spr_register(env
, SPR_DBAT0L
, "DBAT0L",
527 SPR_NOACCESS
, SPR_NOACCESS
,
528 &spr_read_dbat
, &spr_write_dbatl
,
530 spr_register(env
, SPR_DBAT1U
, "DBAT1U",
531 SPR_NOACCESS
, SPR_NOACCESS
,
532 &spr_read_dbat
, &spr_write_dbatu
,
534 spr_register(env
, SPR_DBAT1L
, "DBAT1L",
535 SPR_NOACCESS
, SPR_NOACCESS
,
536 &spr_read_dbat
, &spr_write_dbatl
,
538 spr_register(env
, SPR_DBAT2U
, "DBAT2U",
539 SPR_NOACCESS
, SPR_NOACCESS
,
540 &spr_read_dbat
, &spr_write_dbatu
,
542 spr_register(env
, SPR_DBAT2L
, "DBAT2L",
543 SPR_NOACCESS
, SPR_NOACCESS
,
544 &spr_read_dbat
, &spr_write_dbatl
,
546 spr_register(env
, SPR_DBAT3U
, "DBAT3U",
547 SPR_NOACCESS
, SPR_NOACCESS
,
548 &spr_read_dbat
, &spr_write_dbatu
,
550 spr_register(env
, SPR_DBAT3L
, "DBAT3L",
551 SPR_NOACCESS
, SPR_NOACCESS
,
552 &spr_read_dbat
, &spr_write_dbatl
,
559 void register_high_BATs(CPUPPCState
*env
)
561 #if !defined(CONFIG_USER_ONLY)
562 spr_register(env
, SPR_IBAT4U
, "IBAT4U",
563 SPR_NOACCESS
, SPR_NOACCESS
,
564 &spr_read_ibat_h
, &spr_write_ibatu_h
,
566 spr_register(env
, SPR_IBAT4L
, "IBAT4L",
567 SPR_NOACCESS
, SPR_NOACCESS
,
568 &spr_read_ibat_h
, &spr_write_ibatl_h
,
570 spr_register(env
, SPR_IBAT5U
, "IBAT5U",
571 SPR_NOACCESS
, SPR_NOACCESS
,
572 &spr_read_ibat_h
, &spr_write_ibatu_h
,
574 spr_register(env
, SPR_IBAT5L
, "IBAT5L",
575 SPR_NOACCESS
, SPR_NOACCESS
,
576 &spr_read_ibat_h
, &spr_write_ibatl_h
,
578 spr_register(env
, SPR_IBAT6U
, "IBAT6U",
579 SPR_NOACCESS
, SPR_NOACCESS
,
580 &spr_read_ibat_h
, &spr_write_ibatu_h
,
582 spr_register(env
, SPR_IBAT6L
, "IBAT6L",
583 SPR_NOACCESS
, SPR_NOACCESS
,
584 &spr_read_ibat_h
, &spr_write_ibatl_h
,
586 spr_register(env
, SPR_IBAT7U
, "IBAT7U",
587 SPR_NOACCESS
, SPR_NOACCESS
,
588 &spr_read_ibat_h
, &spr_write_ibatu_h
,
590 spr_register(env
, SPR_IBAT7L
, "IBAT7L",
591 SPR_NOACCESS
, SPR_NOACCESS
,
592 &spr_read_ibat_h
, &spr_write_ibatl_h
,
594 spr_register(env
, SPR_DBAT4U
, "DBAT4U",
595 SPR_NOACCESS
, SPR_NOACCESS
,
596 &spr_read_dbat_h
, &spr_write_dbatu_h
,
598 spr_register(env
, SPR_DBAT4L
, "DBAT4L",
599 SPR_NOACCESS
, SPR_NOACCESS
,
600 &spr_read_dbat_h
, &spr_write_dbatl_h
,
602 spr_register(env
, SPR_DBAT5U
, "DBAT5U",
603 SPR_NOACCESS
, SPR_NOACCESS
,
604 &spr_read_dbat_h
, &spr_write_dbatu_h
,
606 spr_register(env
, SPR_DBAT5L
, "DBAT5L",
607 SPR_NOACCESS
, SPR_NOACCESS
,
608 &spr_read_dbat_h
, &spr_write_dbatl_h
,
610 spr_register(env
, SPR_DBAT6U
, "DBAT6U",
611 SPR_NOACCESS
, SPR_NOACCESS
,
612 &spr_read_dbat_h
, &spr_write_dbatu_h
,
614 spr_register(env
, SPR_DBAT6L
, "DBAT6L",
615 SPR_NOACCESS
, SPR_NOACCESS
,
616 &spr_read_dbat_h
, &spr_write_dbatl_h
,
618 spr_register(env
, SPR_DBAT7U
, "DBAT7U",
619 SPR_NOACCESS
, SPR_NOACCESS
,
620 &spr_read_dbat_h
, &spr_write_dbatu_h
,
622 spr_register(env
, SPR_DBAT7L
, "DBAT7L",
623 SPR_NOACCESS
, SPR_NOACCESS
,
624 &spr_read_dbat_h
, &spr_write_dbatl_h
,
630 /* Softare table search registers */
631 void register_6xx_7xx_soft_tlb(CPUPPCState
*env
, int nb_tlbs
, int nb_ways
)
633 #if !defined(CONFIG_USER_ONLY)
634 env
->nb_tlb
= nb_tlbs
;
635 env
->nb_ways
= nb_ways
;
637 env
->tlb_type
= TLB_6XX
;
638 spr_register(env
, SPR_DMISS
, "DMISS",
639 SPR_NOACCESS
, SPR_NOACCESS
,
640 &spr_read_generic
, SPR_NOACCESS
,
642 spr_register(env
, SPR_DCMP
, "DCMP",
643 SPR_NOACCESS
, SPR_NOACCESS
,
644 &spr_read_generic
, SPR_NOACCESS
,
646 spr_register(env
, SPR_HASH1
, "HASH1",
647 SPR_NOACCESS
, SPR_NOACCESS
,
648 &spr_read_generic
, SPR_NOACCESS
,
650 spr_register(env
, SPR_HASH2
, "HASH2",
651 SPR_NOACCESS
, SPR_NOACCESS
,
652 &spr_read_generic
, SPR_NOACCESS
,
654 spr_register(env
, SPR_IMISS
, "IMISS",
655 SPR_NOACCESS
, SPR_NOACCESS
,
656 &spr_read_generic
, SPR_NOACCESS
,
658 spr_register(env
, SPR_ICMP
, "ICMP",
659 SPR_NOACCESS
, SPR_NOACCESS
,
660 &spr_read_generic
, SPR_NOACCESS
,
662 spr_register(env
, SPR_RPA
, "RPA",
663 SPR_NOACCESS
, SPR_NOACCESS
,
664 &spr_read_generic
, &spr_write_generic
,
669 void register_thrm_sprs(CPUPPCState
*env
)
671 /* Thermal management */
672 spr_register(env
, SPR_THRM1
, "THRM1",
673 SPR_NOACCESS
, SPR_NOACCESS
,
674 &spr_read_thrm
, &spr_write_generic
,
677 spr_register(env
, SPR_THRM2
, "THRM2",
678 SPR_NOACCESS
, SPR_NOACCESS
,
679 &spr_read_thrm
, &spr_write_generic
,
682 spr_register(env
, SPR_THRM3
, "THRM3",
683 SPR_NOACCESS
, SPR_NOACCESS
,
684 &spr_read_thrm
, &spr_write_generic
,
688 void register_usprgh_sprs(CPUPPCState
*env
)
690 spr_register(env
, SPR_USPRG4
, "USPRG4",
691 &spr_read_ureg
, SPR_NOACCESS
,
692 &spr_read_ureg
, SPR_NOACCESS
,
694 spr_register(env
, SPR_USPRG5
, "USPRG5",
695 &spr_read_ureg
, SPR_NOACCESS
,
696 &spr_read_ureg
, SPR_NOACCESS
,
698 spr_register(env
, SPR_USPRG6
, "USPRG6",
699 &spr_read_ureg
, SPR_NOACCESS
,
700 &spr_read_ureg
, SPR_NOACCESS
,
702 spr_register(env
, SPR_USPRG7
, "USPRG7",
703 &spr_read_ureg
, SPR_NOACCESS
,
704 &spr_read_ureg
, SPR_NOACCESS
,