+#endif
+
+/*****************************************************************************/
+/* BATs management */
+#if !defined(FLUSH_ALL_TLBS)
+static inline void do_invalidate_BAT (CPUPPCState *env,
+ target_ulong BATu, target_ulong mask)
+{
+ target_ulong base, end, page;
+ base = BATu & ~0x0001FFFF;
+ end = base + mask + 0x00020000;
+#if defined (DEBUG_BATS)
+ if (loglevel != 0)
+ fprintf(logfile, "Flush BAT from %08x to %08x (%08x)\n", base, end, mask);
+#endif
+ for (page = base; page != end; page += TARGET_PAGE_SIZE)
+ tlb_flush_page(env, page);
+#if defined (DEBUG_BATS)
+ if (loglevel != 0)
+ fprintf(logfile, "Flush done\n");
+#endif
+}
+#endif
+
+static inline void dump_store_bat (CPUPPCState *env, char ID, int ul, int nr,
+ target_ulong value)
+{
+#if defined (DEBUG_BATS)
+ if (loglevel != 0) {
+ fprintf(logfile, "Set %cBAT%d%c to 0x%08lx (0x%08lx)\n",
+ ID, nr, ul == 0 ? 'u' : 'l', (unsigned long)value,
+ (unsigned long)env->nip);
+ }
+#endif
+}
+
+target_ulong do_load_ibatu (CPUPPCState *env, int nr)
+{
+ return env->IBAT[0][nr];
+}
+
+target_ulong do_load_ibatl (CPUPPCState *env, int nr)
+{
+ return env->IBAT[1][nr];
+}
+
+void do_store_ibatu (CPUPPCState *env, int nr, target_ulong value)
+{
+ target_ulong mask;
+
+ dump_store_bat(env, 'I', 0, nr, value);
+ if (env->IBAT[0][nr] != value) {
+ mask = (value << 15) & 0x0FFE0000UL;
+#if !defined(FLUSH_ALL_TLBS)
+ do_invalidate_BAT(env, env->IBAT[0][nr], mask);
+#endif
+ /* When storing valid upper BAT, mask BEPI and BRPN
+ * and invalidate all TLBs covered by this BAT
+ */
+ mask = (value << 15) & 0x0FFE0000UL;
+ env->IBAT[0][nr] = (value & 0x00001FFFUL) |
+ (value & ~0x0001FFFFUL & ~mask);
+ env->IBAT[1][nr] = (env->IBAT[1][nr] & 0x0000007B) |
+ (env->IBAT[1][nr] & ~0x0001FFFF & ~mask);
+#if !defined(FLUSH_ALL_TLBS)
+ do_invalidate_BAT(env, env->IBAT[0][nr], mask);
+#endif
+#if defined(FLUSH_ALL_TLBS)
+ tlb_flush(env, 1);
+#endif
+ }
+}
+
+void do_store_ibatl (CPUPPCState *env, int nr, target_ulong value)
+{
+ dump_store_bat(env, 'I', 1, nr, value);
+ env->IBAT[1][nr] = value;
+}
+
+target_ulong do_load_dbatu (CPUPPCState *env, int nr)
+{
+ return env->DBAT[0][nr];
+}
+
+target_ulong do_load_dbatl (CPUPPCState *env, int nr)
+{
+ return env->DBAT[1][nr];
+}
+
+void do_store_dbatu (CPUPPCState *env, int nr, target_ulong value)
+{
+ target_ulong mask;
+
+ dump_store_bat(env, 'D', 0, nr, value);
+ if (env->DBAT[0][nr] != value) {
+ /* When storing valid upper BAT, mask BEPI and BRPN
+ * and invalidate all TLBs covered by this BAT
+ */
+ mask = (value << 15) & 0x0FFE0000UL;
+#if !defined(FLUSH_ALL_TLBS)
+ do_invalidate_BAT(env, env->DBAT[0][nr], mask);
+#endif
+ mask = (value << 15) & 0x0FFE0000UL;
+ env->DBAT[0][nr] = (value & 0x00001FFFUL) |
+ (value & ~0x0001FFFFUL & ~mask);
+ env->DBAT[1][nr] = (env->DBAT[1][nr] & 0x0000007B) |
+ (env->DBAT[1][nr] & ~0x0001FFFF & ~mask);
+#if !defined(FLUSH_ALL_TLBS)
+ do_invalidate_BAT(env, env->DBAT[0][nr], mask);
+#else
+ tlb_flush(env, 1);
+#endif
+ }
+}
+
+void do_store_dbatl (CPUPPCState *env, int nr, target_ulong value)
+{
+ dump_store_bat(env, 'D', 1, nr, value);
+ env->DBAT[1][nr] = value;
+}