xref: /openbmc/qemu/target/ppc/helper_regs.c (revision 6e7c96ae)
1 /*
2  *  PowerPC emulation special registers manipulation helpers for qemu.
3  *
4  *  Copyright (c) 2003-2007 Jocelyn Mayer
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 "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"
30 
31 /* Swap temporary saved registers with GPRs */
32 void hreg_swap_gpr_tgpr(CPUPPCState *env)
33 {
34     target_ulong tmp;
35 
36     tmp = env->gpr[0];
37     env->gpr[0] = env->tgpr[0];
38     env->tgpr[0] = tmp;
39     tmp = env->gpr[1];
40     env->gpr[1] = env->tgpr[1];
41     env->tgpr[1] = tmp;
42     tmp = env->gpr[2];
43     env->gpr[2] = env->tgpr[2];
44     env->tgpr[2] = tmp;
45     tmp = env->gpr[3];
46     env->gpr[3] = env->tgpr[3];
47     env->tgpr[3] = tmp;
48 }
49 
50 #if defined(TARGET_PPC64)
51 static bool hreg_check_bhrb_enable(CPUPPCState *env)
52 {
53     bool pr = !!(env->msr & (1 << MSR_PR));
54     target_long mmcr0;
55     bool fcp;
56     bool hv;
57 
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)) {
61         return false;
62     }
63 
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));
69         if (fcp) {
70             if (hv && pr) {
71                 return false;
72             }
73         } else if (!hv && pr) {
74             return false;
75         }
76     } else if (fcp && pr) {
77         return false;
78     }
79     return true;
80 }
81 #endif
82 
83 static uint32_t hreg_compute_pmu_hflags_value(CPUPPCState *env)
84 {
85     uint32_t hflags = 0;
86 #if defined(TARGET_PPC64)
87     target_ulong mmcr0 = env->spr[SPR_POWER_MMCR0];
88 
89     if (mmcr0 & MMCR0_PMCC0) {
90         hflags |= 1 << HFLAGS_PMCC0;
91     }
92     if (mmcr0 & MMCR0_PMCC1) {
93         hflags |= 1 << HFLAGS_PMCC1;
94     }
95     if (mmcr0 & MMCR0_PMCjCE) {
96         hflags |= 1 << HFLAGS_PMCJCE;
97     }
98     if (hreg_check_bhrb_enable(env)) {
99         hflags |= 1 << HFLAGS_BHRB_ENABLE;
100     }
101 
102 #ifndef CONFIG_USER_ONLY
103     if (env->pmc_ins_cnt) {
104         hflags |= 1 << HFLAGS_INSN_CNT;
105         if (env->pmc_ins_cnt & 0x1e) {
106             hflags |= 1 << HFLAGS_PMC_OTHER;
107         }
108     }
109 #endif
110 #endif
111 
112     return hflags;
113 }
114 
115 /* Mask of all PMU hflags */
116 static uint32_t hreg_compute_pmu_hflags_mask(CPUPPCState *env)
117 {
118     uint32_t hflags_mask = 0;
119 #if defined(TARGET_PPC64)
120     hflags_mask |= 1 << HFLAGS_PMCC0;
121     hflags_mask |= 1 << HFLAGS_PMCC1;
122     hflags_mask |= 1 << HFLAGS_PMCJCE;
123     hflags_mask |= 1 << HFLAGS_INSN_CNT;
124     hflags_mask |= 1 << HFLAGS_PMC_OTHER;
125     hflags_mask |= 1 << HFLAGS_BHRB_ENABLE;
126 #endif
127     return hflags_mask;
128 }
129 
130 static uint32_t hreg_compute_hflags_value(CPUPPCState *env)
131 {
132     target_ulong msr = env->msr;
133     uint32_t ppc_flags = env->flags;
134     uint32_t hflags = 0;
135     uint32_t msr_mask;
136 
137     /* Some bits come straight across from MSR. */
138     QEMU_BUILD_BUG_ON(MSR_LE != HFLAGS_LE);
139     QEMU_BUILD_BUG_ON(MSR_PR != HFLAGS_PR);
140     QEMU_BUILD_BUG_ON(MSR_DR != HFLAGS_DR);
141     QEMU_BUILD_BUG_ON(MSR_FP != HFLAGS_FP);
142     msr_mask = ((1 << MSR_LE) | (1 << MSR_PR) |
143                 (1 << MSR_DR) | (1 << MSR_FP));
144 
145     if (ppc_flags & POWERPC_FLAG_DE) {
146         target_ulong dbcr0 = env->spr[SPR_BOOKE_DBCR0];
147         if ((dbcr0 & DBCR0_ICMP) && FIELD_EX64(msr, MSR, DE)) {
148             hflags |= 1 << HFLAGS_SE;
149         }
150         if ((dbcr0 & DBCR0_BRT) && FIELD_EX64(msr, MSR, DE)) {
151             hflags |= 1 << HFLAGS_BE;
152         }
153     } else {
154         if (ppc_flags & POWERPC_FLAG_BE) {
155             QEMU_BUILD_BUG_ON(MSR_BE != HFLAGS_BE);
156             msr_mask |= 1 << MSR_BE;
157         }
158         if (ppc_flags & POWERPC_FLAG_SE) {
159             QEMU_BUILD_BUG_ON(MSR_SE != HFLAGS_SE);
160             msr_mask |= 1 << MSR_SE;
161         }
162     }
163 
164     if (msr_is_64bit(env, msr)) {
165         hflags |= 1 << HFLAGS_64;
166     }
167     if ((ppc_flags & POWERPC_FLAG_SPE) && (msr & (1 << MSR_SPE))) {
168         hflags |= 1 << HFLAGS_SPE;
169     }
170     if (ppc_flags & POWERPC_FLAG_VRE) {
171         QEMU_BUILD_BUG_ON(MSR_VR != HFLAGS_VR);
172         msr_mask |= 1 << MSR_VR;
173     }
174     if (ppc_flags & POWERPC_FLAG_VSX) {
175         QEMU_BUILD_BUG_ON(MSR_VSX != HFLAGS_VSX);
176         msr_mask |= 1 << MSR_VSX;
177     }
178     if ((ppc_flags & POWERPC_FLAG_TM) && (msr & (1ull << MSR_TM))) {
179         hflags |= 1 << HFLAGS_TM;
180     }
181     if (env->spr[SPR_LPCR] & LPCR_GTSE) {
182         hflags |= 1 << HFLAGS_GTSE;
183     }
184     if (env->spr[SPR_LPCR] & LPCR_HR) {
185         hflags |= 1 << HFLAGS_HR;
186     }
187 
188 #ifndef CONFIG_USER_ONLY
189     if (!env->has_hv_mode || (msr & (1ull << MSR_HV))) {
190         hflags |= 1 << HFLAGS_HV;
191     }
192 
193     /*
194      * This is our encoding for server processors. The architecture
195      * specifies that there is no such thing as userspace with
196      * translation off, however it appears that MacOS does it and some
197      * 32-bit CPUs support it. Weird...
198      *
199      *   0 = Guest User space virtual mode
200      *   1 = Guest Kernel space virtual mode
201      *   2 = Guest User space real mode
202      *   3 = Guest Kernel space real mode
203      *   4 = HV User space virtual mode
204      *   5 = HV Kernel space virtual mode
205      *   6 = HV User space real mode
206      *   7 = HV Kernel space real mode
207      *
208      * For BookE, we need 8 MMU modes as follow:
209      *
210      *  0 = AS 0 HV User space
211      *  1 = AS 0 HV Kernel space
212      *  2 = AS 1 HV User space
213      *  3 = AS 1 HV Kernel space
214      *  4 = AS 0 Guest User space
215      *  5 = AS 0 Guest Kernel space
216      *  6 = AS 1 Guest User space
217      *  7 = AS 1 Guest Kernel space
218      */
219     unsigned immu_idx, dmmu_idx;
220     dmmu_idx = msr & (1 << MSR_PR) ? 0 : 1;
221     if (env->mmu_model == POWERPC_MMU_BOOKE ||
222         env->mmu_model == POWERPC_MMU_BOOKE206) {
223         dmmu_idx |= msr & (1 << MSR_GS) ? 4 : 0;
224         immu_idx = dmmu_idx;
225         immu_idx |= msr & (1 << MSR_IS) ? 2 : 0;
226         dmmu_idx |= msr & (1 << MSR_DS) ? 2 : 0;
227     } else {
228         dmmu_idx |= msr & (1ull << MSR_HV) ? 4 : 0;
229         immu_idx = dmmu_idx;
230         immu_idx |= msr & (1 << MSR_IR) ? 0 : 2;
231         dmmu_idx |= msr & (1 << MSR_DR) ? 0 : 2;
232     }
233     hflags |= immu_idx << HFLAGS_IMMU_IDX;
234     hflags |= dmmu_idx << HFLAGS_DMMU_IDX;
235 #endif
236 
237     hflags |= hreg_compute_pmu_hflags_value(env);
238 
239     return hflags | (msr & msr_mask);
240 }
241 
242 void hreg_compute_hflags(CPUPPCState *env)
243 {
244     env->hflags = hreg_compute_hflags_value(env);
245 }
246 
247 /*
248  * This can be used as a lighter-weight alternative to hreg_compute_hflags
249  * when PMU MMCR0 or pmc_ins_cnt changes. pmc_ins_cnt is changed by
250  * pmu_update_summaries.
251  */
252 void hreg_update_pmu_hflags(CPUPPCState *env)
253 {
254     env->hflags &= ~hreg_compute_pmu_hflags_mask(env);
255     env->hflags |= hreg_compute_pmu_hflags_value(env);
256 }
257 
258 #ifdef CONFIG_DEBUG_TCG
259 void cpu_get_tb_cpu_state(CPUPPCState *env, vaddr *pc,
260                           uint64_t *cs_base, uint32_t *flags)
261 {
262     uint32_t hflags_current = env->hflags;
263     uint32_t hflags_rebuilt;
264 
265     *pc = env->nip;
266     *cs_base = 0;
267     *flags = hflags_current;
268 
269     hflags_rebuilt = hreg_compute_hflags_value(env);
270     if (unlikely(hflags_current != hflags_rebuilt)) {
271         cpu_abort(env_cpu(env),
272                   "TCG hflags mismatch (current:0x%08x rebuilt:0x%08x)\n",
273                   hflags_current, hflags_rebuilt);
274     }
275 }
276 #endif
277 
278 void cpu_interrupt_exittb(CPUState *cs)
279 {
280     /*
281      * We don't need to worry about translation blocks
282      * unless running with TCG.
283      */
284     if (tcg_enabled()) {
285         BQL_LOCK_GUARD();
286         cpu_interrupt(cs, CPU_INTERRUPT_EXITTB);
287     }
288 }
289 
290 int hreg_store_msr(CPUPPCState *env, target_ulong value, int alter_hv)
291 {
292     int excp;
293 #if !defined(CONFIG_USER_ONLY)
294     CPUState *cs = env_cpu(env);
295 #endif
296 
297     excp = 0;
298     value &= env->msr_mask;
299 #if !defined(CONFIG_USER_ONLY)
300     /* Neither mtmsr nor guest state can alter HV */
301     if (!alter_hv || !(env->msr & MSR_HVB)) {
302         value &= ~MSR_HVB;
303         value |= env->msr & MSR_HVB;
304     }
305     /* Attempt to modify MSR[ME] in guest state is ignored */
306     if (is_book3s_arch2x(env) && !(env->msr & MSR_HVB)) {
307         value &= ~(1 << MSR_ME);
308         value |= env->msr & (1 << MSR_ME);
309     }
310     if ((value ^ env->msr) & (R_MSR_IR_MASK | R_MSR_DR_MASK)) {
311         cpu_interrupt_exittb(cs);
312     }
313     if ((env->mmu_model == POWERPC_MMU_BOOKE ||
314          env->mmu_model == POWERPC_MMU_BOOKE206) &&
315         ((value ^ env->msr) & R_MSR_GS_MASK)) {
316         cpu_interrupt_exittb(cs);
317     }
318     if (unlikely((env->flags & POWERPC_FLAG_TGPR) &&
319                  ((value ^ env->msr) & (1 << MSR_TGPR)))) {
320         /* Swap temporary saved registers with GPRs */
321         hreg_swap_gpr_tgpr(env);
322     }
323     if (unlikely((value ^ env->msr) & R_MSR_EP_MASK)) {
324         env->excp_prefix = FIELD_EX64(value, MSR, EP) * 0xFFF00000;
325     }
326     /*
327      * If PR=1 then EE, IR and DR must be 1
328      *
329      * Note: We only enforce this on 64-bit server processors.
330      * It appears that:
331      * - 32-bit implementations supports PR=1 and EE/DR/IR=0 and MacOS
332      *   exploits it.
333      * - 64-bit embedded implementations do not need any operation to be
334      *   performed when PR is set.
335      */
336     if (is_book3s_arch2x(env) && ((value >> MSR_PR) & 1)) {
337         value |= (1 << MSR_EE) | (1 << MSR_DR) | (1 << MSR_IR);
338     }
339 #endif
340     env->msr = value;
341     hreg_compute_hflags(env);
342 #if !defined(CONFIG_USER_ONLY)
343     ppc_maybe_interrupt(env);
344 
345     if (unlikely(FIELD_EX64(env->msr, MSR, POW))) {
346         if (!env->pending_interrupts && (*env->check_pow)(env)) {
347             cs->halted = 1;
348             excp = EXCP_HALTED;
349         }
350     }
351 #endif
352 
353     return excp;
354 }
355 
356 #ifndef CONFIG_USER_ONLY
357 void store_40x_sler(CPUPPCState *env, uint32_t val)
358 {
359     /* XXX: TO BE FIXED */
360     if (val != 0x00000000) {
361         cpu_abort(env_cpu(env),
362                   "Little-endian regions are not supported by now\n");
363     }
364     env->spr[SPR_405_SLER] = val;
365 }
366 
367 void check_tlb_flush(CPUPPCState *env, bool global)
368 {
369     CPUState *cs = env_cpu(env);
370 
371     /* Handle global flushes first */
372     if (global && (env->tlb_need_flush & TLB_NEED_GLOBAL_FLUSH)) {
373         env->tlb_need_flush &= ~TLB_NEED_GLOBAL_FLUSH;
374         env->tlb_need_flush &= ~TLB_NEED_LOCAL_FLUSH;
375         tlb_flush_all_cpus_synced(cs);
376         return;
377     }
378 
379     /* Then handle local ones */
380     if (env->tlb_need_flush & TLB_NEED_LOCAL_FLUSH) {
381         env->tlb_need_flush &= ~TLB_NEED_LOCAL_FLUSH;
382         tlb_flush(cs);
383     }
384 }
385 #endif /* !CONFIG_USER_ONLY */
386 
387 /**
388  * _spr_register
389  *
390  * Register an SPR with all the callbacks required for tcg,
391  * and the ID number for KVM.
392  *
393  * The reason for the conditional compilation is that the tcg functions
394  * may be compiled out, and the system kvm header may not be available
395  * for supplying the ID numbers.  This is ugly, but the best we can do.
396  */
397 void _spr_register(CPUPPCState *env, int num, const char *name,
398                    USR_ARG(spr_callback *uea_read)
399                    USR_ARG(spr_callback *uea_write)
400                    SYS_ARG(spr_callback *oea_read)
401                    SYS_ARG(spr_callback *oea_write)
402                    SYS_ARG(spr_callback *hea_read)
403                    SYS_ARG(spr_callback *hea_write)
404                    KVM_ARG(uint64_t one_reg_id)
405                    target_ulong initial_value)
406 {
407     ppc_spr_t *spr = &env->spr_cb[num];
408 
409     /* No SPR should be registered twice. */
410     assert(spr->name == NULL);
411     assert(name != NULL);
412 
413     spr->name = name;
414     spr->default_value = initial_value;
415     env->spr[num] = initial_value;
416 
417 #ifdef CONFIG_TCG
418     spr->uea_read = uea_read;
419     spr->uea_write = uea_write;
420 # ifndef CONFIG_USER_ONLY
421     spr->oea_read = oea_read;
422     spr->oea_write = oea_write;
423     spr->hea_read = hea_read;
424     spr->hea_write = hea_write;
425 # endif
426 #endif
427 #ifdef CONFIG_KVM
428     spr->one_reg_id = one_reg_id;
429 #endif
430 }
431 
432 /* Generic PowerPC SPRs */
433 void register_generic_sprs(PowerPCCPU *cpu)
434 {
435     PowerPCCPUClass *pcc = POWERPC_CPU_GET_CLASS(cpu);
436     CPUPPCState *env = &cpu->env;
437 
438     /* Integer processing */
439     spr_register(env, SPR_XER, "XER",
440                  &spr_read_xer, &spr_write_xer,
441                  &spr_read_xer, &spr_write_xer,
442                  0x00000000);
443     /* Branch control */
444     spr_register(env, SPR_LR, "LR",
445                  &spr_read_lr, &spr_write_lr,
446                  &spr_read_lr, &spr_write_lr,
447                  0x00000000);
448     spr_register(env, SPR_CTR, "CTR",
449                  &spr_read_ctr, &spr_write_ctr,
450                  &spr_read_ctr, &spr_write_ctr,
451                  0x00000000);
452     /* Interrupt processing */
453     spr_register(env, SPR_SRR0, "SRR0",
454                  SPR_NOACCESS, SPR_NOACCESS,
455                  &spr_read_generic, &spr_write_generic,
456                  0x00000000);
457     spr_register(env, SPR_SRR1, "SRR1",
458                  SPR_NOACCESS, SPR_NOACCESS,
459                  &spr_read_generic, &spr_write_generic,
460                  0x00000000);
461     /* Processor control */
462     spr_register(env, SPR_SPRG0, "SPRG0",
463                  SPR_NOACCESS, SPR_NOACCESS,
464                  &spr_read_generic, &spr_write_generic,
465                  0x00000000);
466     spr_register(env, SPR_SPRG1, "SPRG1",
467                  SPR_NOACCESS, SPR_NOACCESS,
468                  &spr_read_generic, &spr_write_generic,
469                  0x00000000);
470     spr_register(env, SPR_SPRG2, "SPRG2",
471                  SPR_NOACCESS, SPR_NOACCESS,
472                  &spr_read_generic, &spr_write_generic,
473                  0x00000000);
474     spr_register(env, SPR_SPRG3, "SPRG3",
475                  SPR_NOACCESS, SPR_NOACCESS,
476                  &spr_read_generic, &spr_write_generic,
477                  0x00000000);
478 
479     spr_register(env, SPR_PVR, "PVR",
480                  /* Linux permits userspace to read PVR */
481 #if defined(CONFIG_LINUX_USER)
482                  &spr_read_generic,
483 #else
484                  SPR_NOACCESS,
485 #endif
486                  SPR_NOACCESS,
487                  &spr_read_generic, SPR_NOACCESS,
488                  pcc->pvr);
489 
490     /* Register SVR if it's defined to anything else than POWERPC_SVR_NONE */
491     if (pcc->svr != POWERPC_SVR_NONE) {
492         if (pcc->svr & POWERPC_SVR_E500) {
493             spr_register(env, SPR_E500_SVR, "SVR",
494                          SPR_NOACCESS, SPR_NOACCESS,
495                          &spr_read_generic, SPR_NOACCESS,
496                          pcc->svr & ~POWERPC_SVR_E500);
497         } else {
498             spr_register(env, SPR_SVR, "SVR",
499                          SPR_NOACCESS, SPR_NOACCESS,
500                          &spr_read_generic, SPR_NOACCESS,
501                          pcc->svr);
502         }
503     }
504 
505     /* Time base */
506 #if defined(TARGET_PPC64)
507     spr_register(env, SPR_TBL, "TB",
508 #else
509     spr_register(env, SPR_TBL, "TBL",
510 #endif
511                  &spr_read_tbl, SPR_NOACCESS,
512                  &spr_read_tbl, SPR_NOACCESS,
513                  0x00000000);
514     spr_register(env, SPR_TBU, "TBU",
515                  &spr_read_tbu, SPR_NOACCESS,
516                  &spr_read_tbu, SPR_NOACCESS,
517                  0x00000000);
518 #ifndef CONFIG_USER_ONLY
519     if (env->has_hv_mode) {
520         spr_register_hv(env, SPR_WR_TBL, "TBL",
521                         SPR_NOACCESS, SPR_NOACCESS,
522                         SPR_NOACCESS, SPR_NOACCESS,
523                         SPR_NOACCESS, &spr_write_tbl,
524                         0x00000000);
525         spr_register_hv(env, SPR_WR_TBU, "TBU",
526                         SPR_NOACCESS, SPR_NOACCESS,
527                         SPR_NOACCESS, SPR_NOACCESS,
528                         SPR_NOACCESS, &spr_write_tbu,
529                         0x00000000);
530     } else {
531         spr_register(env, SPR_WR_TBL, "TBL",
532                      SPR_NOACCESS, SPR_NOACCESS,
533                      SPR_NOACCESS, &spr_write_tbl,
534                      0x00000000);
535         spr_register(env, SPR_WR_TBU, "TBU",
536                      SPR_NOACCESS, SPR_NOACCESS,
537                      SPR_NOACCESS, &spr_write_tbu,
538                      0x00000000);
539     }
540 #endif
541 }
542 
543 void register_non_embedded_sprs(CPUPPCState *env)
544 {
545     /* Exception processing */
546     spr_register_kvm(env, SPR_DSISR, "DSISR",
547                      SPR_NOACCESS, SPR_NOACCESS,
548                      &spr_read_generic, &spr_write_generic32,
549                      KVM_REG_PPC_DSISR, 0x00000000);
550     spr_register_kvm(env, SPR_DAR, "DAR",
551                      SPR_NOACCESS, SPR_NOACCESS,
552                      &spr_read_generic, &spr_write_generic,
553                      KVM_REG_PPC_DAR, 0x00000000);
554     /* Timer */
555     spr_register(env, SPR_DECR, "DEC",
556                  SPR_NOACCESS, SPR_NOACCESS,
557                  &spr_read_decr, &spr_write_decr,
558                  0x00000000);
559 }
560 
561 /* Storage Description Register 1 */
562 void register_sdr1_sprs(CPUPPCState *env)
563 {
564 #ifndef CONFIG_USER_ONLY
565     if (env->has_hv_mode) {
566         /*
567          * SDR1 is a hypervisor resource on CPUs which have a
568          * hypervisor mode
569          */
570         spr_register_hv(env, SPR_SDR1, "SDR1",
571                         SPR_NOACCESS, SPR_NOACCESS,
572                         SPR_NOACCESS, SPR_NOACCESS,
573                         &spr_read_generic, &spr_write_sdr1,
574                         0x00000000);
575     } else {
576         spr_register(env, SPR_SDR1, "SDR1",
577                      SPR_NOACCESS, SPR_NOACCESS,
578                      &spr_read_generic, &spr_write_sdr1,
579                      0x00000000);
580     }
581 #endif
582 }
583 
584 /* BATs 0-3 */
585 void register_low_BATs(CPUPPCState *env)
586 {
587 #if !defined(CONFIG_USER_ONLY)
588     spr_register(env, SPR_IBAT0U, "IBAT0U",
589                  SPR_NOACCESS, SPR_NOACCESS,
590                  &spr_read_ibat, &spr_write_ibatu,
591                  0x00000000);
592     spr_register(env, SPR_IBAT0L, "IBAT0L",
593                  SPR_NOACCESS, SPR_NOACCESS,
594                  &spr_read_ibat, &spr_write_ibatl,
595                  0x00000000);
596     spr_register(env, SPR_IBAT1U, "IBAT1U",
597                  SPR_NOACCESS, SPR_NOACCESS,
598                  &spr_read_ibat, &spr_write_ibatu,
599                  0x00000000);
600     spr_register(env, SPR_IBAT1L, "IBAT1L",
601                  SPR_NOACCESS, SPR_NOACCESS,
602                  &spr_read_ibat, &spr_write_ibatl,
603                  0x00000000);
604     spr_register(env, SPR_IBAT2U, "IBAT2U",
605                  SPR_NOACCESS, SPR_NOACCESS,
606                  &spr_read_ibat, &spr_write_ibatu,
607                  0x00000000);
608     spr_register(env, SPR_IBAT2L, "IBAT2L",
609                  SPR_NOACCESS, SPR_NOACCESS,
610                  &spr_read_ibat, &spr_write_ibatl,
611                  0x00000000);
612     spr_register(env, SPR_IBAT3U, "IBAT3U",
613                  SPR_NOACCESS, SPR_NOACCESS,
614                  &spr_read_ibat, &spr_write_ibatu,
615                  0x00000000);
616     spr_register(env, SPR_IBAT3L, "IBAT3L",
617                  SPR_NOACCESS, SPR_NOACCESS,
618                  &spr_read_ibat, &spr_write_ibatl,
619                  0x00000000);
620     spr_register(env, SPR_DBAT0U, "DBAT0U",
621                  SPR_NOACCESS, SPR_NOACCESS,
622                  &spr_read_dbat, &spr_write_dbatu,
623                  0x00000000);
624     spr_register(env, SPR_DBAT0L, "DBAT0L",
625                  SPR_NOACCESS, SPR_NOACCESS,
626                  &spr_read_dbat, &spr_write_dbatl,
627                  0x00000000);
628     spr_register(env, SPR_DBAT1U, "DBAT1U",
629                  SPR_NOACCESS, SPR_NOACCESS,
630                  &spr_read_dbat, &spr_write_dbatu,
631                  0x00000000);
632     spr_register(env, SPR_DBAT1L, "DBAT1L",
633                  SPR_NOACCESS, SPR_NOACCESS,
634                  &spr_read_dbat, &spr_write_dbatl,
635                  0x00000000);
636     spr_register(env, SPR_DBAT2U, "DBAT2U",
637                  SPR_NOACCESS, SPR_NOACCESS,
638                  &spr_read_dbat, &spr_write_dbatu,
639                  0x00000000);
640     spr_register(env, SPR_DBAT2L, "DBAT2L",
641                  SPR_NOACCESS, SPR_NOACCESS,
642                  &spr_read_dbat, &spr_write_dbatl,
643                  0x00000000);
644     spr_register(env, SPR_DBAT3U, "DBAT3U",
645                  SPR_NOACCESS, SPR_NOACCESS,
646                  &spr_read_dbat, &spr_write_dbatu,
647                  0x00000000);
648     spr_register(env, SPR_DBAT3L, "DBAT3L",
649                  SPR_NOACCESS, SPR_NOACCESS,
650                  &spr_read_dbat, &spr_write_dbatl,
651                  0x00000000);
652     env->nb_BATs += 4;
653 #endif
654 }
655 
656 /* BATs 4-7 */
657 void register_high_BATs(CPUPPCState *env)
658 {
659 #if !defined(CONFIG_USER_ONLY)
660     spr_register(env, SPR_IBAT4U, "IBAT4U",
661                  SPR_NOACCESS, SPR_NOACCESS,
662                  &spr_read_ibat_h, &spr_write_ibatu_h,
663                  0x00000000);
664     spr_register(env, SPR_IBAT4L, "IBAT4L",
665                  SPR_NOACCESS, SPR_NOACCESS,
666                  &spr_read_ibat_h, &spr_write_ibatl_h,
667                  0x00000000);
668     spr_register(env, SPR_IBAT5U, "IBAT5U",
669                  SPR_NOACCESS, SPR_NOACCESS,
670                  &spr_read_ibat_h, &spr_write_ibatu_h,
671                  0x00000000);
672     spr_register(env, SPR_IBAT5L, "IBAT5L",
673                  SPR_NOACCESS, SPR_NOACCESS,
674                  &spr_read_ibat_h, &spr_write_ibatl_h,
675                  0x00000000);
676     spr_register(env, SPR_IBAT6U, "IBAT6U",
677                  SPR_NOACCESS, SPR_NOACCESS,
678                  &spr_read_ibat_h, &spr_write_ibatu_h,
679                  0x00000000);
680     spr_register(env, SPR_IBAT6L, "IBAT6L",
681                  SPR_NOACCESS, SPR_NOACCESS,
682                  &spr_read_ibat_h, &spr_write_ibatl_h,
683                  0x00000000);
684     spr_register(env, SPR_IBAT7U, "IBAT7U",
685                  SPR_NOACCESS, SPR_NOACCESS,
686                  &spr_read_ibat_h, &spr_write_ibatu_h,
687                  0x00000000);
688     spr_register(env, SPR_IBAT7L, "IBAT7L",
689                  SPR_NOACCESS, SPR_NOACCESS,
690                  &spr_read_ibat_h, &spr_write_ibatl_h,
691                  0x00000000);
692     spr_register(env, SPR_DBAT4U, "DBAT4U",
693                  SPR_NOACCESS, SPR_NOACCESS,
694                  &spr_read_dbat_h, &spr_write_dbatu_h,
695                  0x00000000);
696     spr_register(env, SPR_DBAT4L, "DBAT4L",
697                  SPR_NOACCESS, SPR_NOACCESS,
698                  &spr_read_dbat_h, &spr_write_dbatl_h,
699                  0x00000000);
700     spr_register(env, SPR_DBAT5U, "DBAT5U",
701                  SPR_NOACCESS, SPR_NOACCESS,
702                  &spr_read_dbat_h, &spr_write_dbatu_h,
703                  0x00000000);
704     spr_register(env, SPR_DBAT5L, "DBAT5L",
705                  SPR_NOACCESS, SPR_NOACCESS,
706                  &spr_read_dbat_h, &spr_write_dbatl_h,
707                  0x00000000);
708     spr_register(env, SPR_DBAT6U, "DBAT6U",
709                  SPR_NOACCESS, SPR_NOACCESS,
710                  &spr_read_dbat_h, &spr_write_dbatu_h,
711                  0x00000000);
712     spr_register(env, SPR_DBAT6L, "DBAT6L",
713                  SPR_NOACCESS, SPR_NOACCESS,
714                  &spr_read_dbat_h, &spr_write_dbatl_h,
715                  0x00000000);
716     spr_register(env, SPR_DBAT7U, "DBAT7U",
717                  SPR_NOACCESS, SPR_NOACCESS,
718                  &spr_read_dbat_h, &spr_write_dbatu_h,
719                  0x00000000);
720     spr_register(env, SPR_DBAT7L, "DBAT7L",
721                  SPR_NOACCESS, SPR_NOACCESS,
722                  &spr_read_dbat_h, &spr_write_dbatl_h,
723                  0x00000000);
724     env->nb_BATs += 4;
725 #endif
726 }
727 
728 /* Softare table search registers */
729 void register_6xx_7xx_soft_tlb(CPUPPCState *env, int nb_tlbs, int nb_ways)
730 {
731 #if !defined(CONFIG_USER_ONLY)
732     env->nb_tlb = nb_tlbs;
733     env->nb_ways = nb_ways;
734     env->tlb_type = TLB_6XX;
735     spr_register(env, SPR_DMISS, "DMISS",
736                  SPR_NOACCESS, SPR_NOACCESS,
737                  &spr_read_generic, SPR_NOACCESS,
738                  0x00000000);
739     spr_register(env, SPR_DCMP, "DCMP",
740                  SPR_NOACCESS, SPR_NOACCESS,
741                  &spr_read_generic, SPR_NOACCESS,
742                  0x00000000);
743     spr_register(env, SPR_HASH1, "HASH1",
744                  SPR_NOACCESS, SPR_NOACCESS,
745                  &spr_read_generic, SPR_NOACCESS,
746                  0x00000000);
747     spr_register(env, SPR_HASH2, "HASH2",
748                  SPR_NOACCESS, SPR_NOACCESS,
749                  &spr_read_generic, SPR_NOACCESS,
750                  0x00000000);
751     spr_register(env, SPR_IMISS, "IMISS",
752                  SPR_NOACCESS, SPR_NOACCESS,
753                  &spr_read_generic, SPR_NOACCESS,
754                  0x00000000);
755     spr_register(env, SPR_ICMP, "ICMP",
756                  SPR_NOACCESS, SPR_NOACCESS,
757                  &spr_read_generic, SPR_NOACCESS,
758                  0x00000000);
759     spr_register(env, SPR_RPA, "RPA",
760                  SPR_NOACCESS, SPR_NOACCESS,
761                  &spr_read_generic, &spr_write_generic,
762                  0x00000000);
763 #endif
764 }
765 
766 void register_thrm_sprs(CPUPPCState *env)
767 {
768     /* Thermal management */
769     spr_register(env, SPR_THRM1, "THRM1",
770                  SPR_NOACCESS, SPR_NOACCESS,
771                  &spr_read_thrm, &spr_write_generic,
772                  0x00000000);
773 
774     spr_register(env, SPR_THRM2, "THRM2",
775                  SPR_NOACCESS, SPR_NOACCESS,
776                  &spr_read_thrm, &spr_write_generic,
777                  0x00000000);
778 
779     spr_register(env, SPR_THRM3, "THRM3",
780                  SPR_NOACCESS, SPR_NOACCESS,
781                  &spr_read_thrm, &spr_write_generic,
782                  0x00000000);
783 }
784 
785 void register_usprgh_sprs(CPUPPCState *env)
786 {
787     spr_register(env, SPR_USPRG4, "USPRG4",
788                  &spr_read_ureg, SPR_NOACCESS,
789                  &spr_read_ureg, SPR_NOACCESS,
790                  0x00000000);
791     spr_register(env, SPR_USPRG5, "USPRG5",
792                  &spr_read_ureg, SPR_NOACCESS,
793                  &spr_read_ureg, SPR_NOACCESS,
794                  0x00000000);
795     spr_register(env, SPR_USPRG6, "USPRG6",
796                  &spr_read_ureg, SPR_NOACCESS,
797                  &spr_read_ureg, SPR_NOACCESS,
798                  0x00000000);
799     spr_register(env, SPR_USPRG7, "USPRG7",
800                  &spr_read_ureg, SPR_NOACCESS,
801                  &spr_read_ureg, SPR_NOACCESS,
802                  0x00000000);
803 }
804