diff --git a/sim/bfin/ChangeLog b/sim/bfin/ChangeLog
index fb00c8b..2bdfc6e 100644
--- a/sim/bfin/ChangeLog
+++ b/sim/bfin/ChangeLog
@@ -1,5 +1,127 @@
 2015-12-26  Mike Frysinger  <vapier@gentoo.org>
 
+	* devices.c (bfin_mmr_invalid): Delete cpu arg and add missing arg.
+	Add cpu, rw, and reason local vars.  Rewrite error messages.  Add
+	more todo comments.
+	(dv_bfin_mmr_invalid): Update bfin_mmr_invalid call.
+	(dv_bfin_mmr_require): Likewise.  Change return to bool.  Check
+	alignment of the addr variable.
+	(bfin_mmr_check, dv_bfin_mmr_check, device_io_read_buffer,
+	device_io_write_buffer): Delete.
+	(dv_bfin_mmr_require_16_32): Define.
+	* devices.h (dv_bfin_mmr_require): Change return to bool.
+	(dv_bfin_mmr_check): Delete.
+	(dv_bfin_mmr_require_16_32): Define.
+	Add a few comments.
+	* dv-bfin_cec.c (bfin_cec_io_write_buffer): Call
+	dv_bfin_mmr_require_32.
+	(bfin_cec_io_read_buffer): Likewise.
+	* dv-bfin_ctimer.c (bfin_ctimer_io_write_buffer): Likewise.
+	(bfin_ctimer_io_read_buffer): Likewise.
+	* dv-bfin_dma.c (bfin_dma_io_write_buffer): Call
+	dv_bfin_mmr_require_16_32.  Return 0 in the default case.
+	(bfin_dma_io_read_buffer): Call dv_bfin_mmr_require_16_32.
+	* dv-bfin_ebiu_amc.c (bf50x_ebiu_amc_io_write_buffer): Return 0
+	when dv_bfin_mmr_require_16 fails and in the default case.
+	(bf53x_ebiu_amc_io_write_buffer): Likewise.
+	(bf54x_ebiu_amc_io_write_buffer): Likewise.
+	(bfin_ebiu_amc_io_write_buffer): Call dv_bfin_mmr_require_16_32.
+	(bf50x_ebiu_amc_io_read_buffer): Return 0 when
+	dv_bfin_mmr_require_16 fails and in the default case.
+	(bf53x_ebiu_amc_io_read_buffer): Likewise.
+	(bf54x_ebiu_amc_io_read_buffer): Likewise.
+	(bfin_ebiu_amc_io_read_buffer): Call dv_bfin_mmr_require_16_32.
+	* dv-bfin_ebiu_ddrc.c (bfin_ebiu_ddrc_io_write_buffer): Call
+	dv_bfin_mmr_require_16_32.  Return 0 when dv_bfin_mmr_require_16 or
+	dv_bfin_mmr_require_32 fails.
+	(bfin_ebiu_ddrc_io_read_buffer): Likewise.
+	* dv-bfin_ebiu_sdc.c (bfin_ebiu_sdc_io_write_buffer): Likewise.
+	(bfin_ebiu_sdc_io_read_buffer): Likewise.
+	* dv-bfin_emac.c (bfin_emac_io_write_buffer): Return 0 when
+	dv_bfin_mmr_require_32 fails and in the default case.
+	(bfin_emac_io_read_buffer): Likewise.
+	* dv-bfin_eppi.c (bfin_eppi_io_write_buffer): Call
+	dv_bfin_mmr_require_16_32 and return 0 when dv_bfin_mmr_require_16
+	or dv_bfin_mmr_require_32 fails and in the default case.
+	(bfin_eppi_io_read_buffer): Likewise.
+	* dv-bfin_evt.c (bfin_evt_io_write_buffer): Call
+	dv_bfin_mmr_require_32.
+	(bfin_evt_io_read_buffer): Likewise.
+	* dv-bfin_gpio.c (bfin_gpio_io_write_buffer): Move call to
+	dv_bfin_mmr_require_16 to earlier in the func.  Return 0 when it
+	fails and in the default case.
+	(bfin_gpio_io_read_buffer): Likewise.
+	* dv-bfin_gpio2.c (bfin_gpio_io_write_buffer): Move call to
+	dv_bfin_mmr_require_16 and dv_bfin_mmr_require_32 to earlier in the
+	func.  Return 0 when it fails and in the default case.
+	(bfin_gpio_io_read_buffer): Likewise.
+	* dv-bfin_gptimer.c (bfin_gptimer_io_write_buffer): Call
+	dv_bfin_mmr_require_16_32.  Return 0 when dv_bfin_mmr_require_16 or
+	dv_bfin_mmr_require_32 fails and in the default case.
+	(bfin_gptimer_io_read_buffer): Likewise.
+	* dv-bfin_jtag.c (bfin_jtag_io_write_buffer): Call
+	dv_bfin_mmr_require_32.  Return 0 in the default case.
+	(bfin_jtag_io_read_buffer): Likewise.  Delete while(1) loop.
+	* dv-bfin_mmu.c (bfin_mmu_io_write_buffer): Call
+	dv_bfin_mmr_require_32.  Return 0 in the default case.
+	(bfin_mmu_io_read_buffer): Likewise.  Delete while(1) loop.
+	* dv-bfin_nfc.c (bfin_nfc_io_write_buffer): Move call to
+	dv_bfin_mmr_require_16 to earlier in the func.  Return 0 when it
+	fails and in the default case.
+	(bfin_nfc_io_read_buffer): Likewise.
+	* dv-bfin_otp.c (bfin_otp_io_write_buffer): Call
+	dv_bfin_mmr_require_16_32.  Return 0 when dv_bfin_mmr_require_16
+	or dv_bfin_mmr_require_32 fails and in the default case.
+	(bfin_otp_io_read_buffer): Likewise.
+	* dv-bfin_pfmon.c (bfin_pfmon_io_write_buffer): Call
+	dv_bfin_mmr_require_32.  Return 0 in the default case.
+	(bfin_pfmon_io_read_buffer): Likewise.  Delete while(1) loop.
+	* dv-bfin_pint.c (bfin_pint_io_write_buffer): Move call to
+	dv_bfin_mmr_require_32 to earlier in the func.  Return 0 when it
+	fails and in the default case.
+	(bfin_pint_io_read_buffer): Likewise.
+	* dv-bfin_pll.c (bfin_pll_io_write_buffer): Call
+	dv_bfin_mmr_require_16_32.  Return 0 when dv_bfin_mmr_require_16
+	fails.
+	(bfin_pll_io_read_buffer): Likewise.
+	* dv-bfin_ppi.c (bfin_ppi_io_write_buffer): Move call to
+	dv_bfin_mmr_require_16 to earlier in the func.  Return 0 when it
+	fails and in the default case.
+	9bfin_ppi_io_read_buffer): Likewise.
+	* dv-bfin_rtc.c (bfin_rtc_io_write_buffer): Call
+	dv_bfin_mmr_require_16_32.
+	(bfin_rtc_io_read_buffer): Likewise.
+	* dv-bfin_sic.c (bfin_sic_52x_io_write_buffer): Likewise.
+	(bfin_sic_52x_io_read_buffer, bfin_sic_537_io_write_buffer,
+	bfin_sic_537_io_read_buffer, bfin_sic_54x_io_write_buffer,
+	bfin_sic_54x_io_read_buffer, bfin_sic_561_io_write_buffer,
+	bfin_sic_561_io_read_buffer): Likewise.
+	* dv-bfin_spi.c (bfin_spi_io_write_buffer): Move call to
+	dv_bfin_mmr_require_16 to earlier in the func.  Return 0 when it
+	fails and in the default case.
+	(bfin_spi_io_read_buffer): Likewise.
+	* dv-bfin_trace.c (bfin_trace_io_write_buffer): Call
+	dv_bfin_mmr_require_32.  Return 0 in the default case.
+	(bfin_trace_io_read_buffer): Likewise.  Delete while(1) loop.
+	* dv-bfin_twi.c (bfin_twi_io_write_buffer): Move call to
+	dv_bfin_mmr_require_16 to earlier in the func.  Return 0 when it
+	fails and in the default case.
+	(bfin_twi_io_read_buffer): Likewise.
+	* dv-bfin_uart.c (bfin_uart_io_write_buffer): Likewise.
+	(bfin_uart_io_read_buffer): Likewise.
+	* dv-bfin_uart2.c (bfin_uart_io_write_buffer): Likewise.
+	(bfin_uart_io_read_buffer): Likewise.
+	* dv-bfin_wdog.c (bfin_wdog_io_write_buffer): Call
+	dv_bfin_mmr_require_16_32.
+	(bfin_wdog_io_read_buffer): Likewise.  Return 0 when
+	dv_bfin_mmr_require_16 fails.
+	* dv-bfin_wp.c (bfin_wp_io_write_buffer): Call
+	dv_bfin_mmr_require_32.  Return 0 in the default case.
+	(bfin_wp_io_read_buffer): Likewise.  Delete while(1) loop.
+	* tconfig.h: Delete file.
+
+2015-12-26  Mike Frysinger  <vapier@gentoo.org>
+
 	* bfin-sim.c (decode_LDST_0): Add 4th element to posts array.
 
 2015-12-26  Mike Frysinger  <vapier@gentoo.org>
diff --git a/sim/bfin/devices.c b/sim/bfin/devices.c
index 7dab5f1..aec27d6 100644
--- a/sim/bfin/devices.c
+++ b/sim/bfin/devices.c
@@ -28,25 +28,32 @@
 #include "dv-bfin_mmu.h"
 
 static void
-bfin_mmr_invalid (struct hw *me, SIM_CPU *cpu, address_word addr,
-		  unsigned nr_bytes, bool write)
+bfin_mmr_invalid (struct hw *me, address_word addr,
+		  unsigned nr_bytes, bool write, bool missing)
 {
-  if (!cpu)
-    cpu = hw_system_cpu (me);
+  SIM_CPU *cpu = hw_system_cpu (me);
+  const char *rw = write ? "write" : "read";
+  const char *reason =
+    missing ? "no such register" :
+              (addr & 3) ? "must be 32-bit aligned" : "invalid length";
 
   /* Only throw a fit if the cpu is doing the access.  DMA/GDB simply
      go unnoticed.  Not exactly hardware behavior, but close enough.  */
   if (!cpu)
     {
-      sim_io_eprintf (hw_system (me), "%s: invalid MMR access @ %#x\n",
-		      hw_path (me), addr);
+      sim_io_eprintf (hw_system (me),
+		      "%s: invalid MMR %s at %#x length %u: %s\n",
+		      hw_path (me), rw, addr, nr_bytes, reason);
       return;
     }
 
-  HW_TRACE ((me, "invalid MMR %s to 0x%08lx length %u",
-	     write ? "write" : "read", (unsigned long) addr, nr_bytes));
+  HW_TRACE ((me, "invalid MMR %s at %#x length %u: %s",
+	     rw, addr, nr_bytes, reason));
 
-  /* XXX: is this what hardware does ?  */
+  /* XXX: is this what hardware does ?  What about priority of unaligned vs
+     wrong length vs missing register ?  What about system-vs-core ?  */
+  /* XXX: We should move this addr check to a model property so we get the
+     same behavior regardless of where we map the model.  */
   if (addr >= BFIN_CORE_MMR_BASE)
     /* XXX: This should be setting up CPLB fault addrs ?  */
     mmu_process_fault (cpu, addr, write, false, false, true);
@@ -60,93 +67,30 @@ void
 dv_bfin_mmr_invalid (struct hw *me, address_word addr, unsigned nr_bytes,
 		     bool write)
 {
-  bfin_mmr_invalid (me, NULL, addr, nr_bytes, write);
+  bfin_mmr_invalid (me, addr, nr_bytes, write, true);
 }
 
-void
+bool
 dv_bfin_mmr_require (struct hw *me, address_word addr, unsigned nr_bytes,
 		     unsigned size, bool write)
 {
-  if (nr_bytes != size)
-    dv_bfin_mmr_invalid (me, addr, nr_bytes, write);
-}
-
-static bool
-bfin_mmr_check (struct hw *me, SIM_CPU *cpu, address_word addr,
-		unsigned nr_bytes, bool write)
-{
-  if (addr >= BFIN_CORE_MMR_BASE)
-    {
-      /* All Core MMRs are aligned 32bits.  */
-      if ((addr & 3) == 0 && nr_bytes == 4)
-	return true;
-    }
-  else if (addr >= BFIN_SYSTEM_MMR_BASE)
-    {
-      /* All System MMRs are 32bit aligned, but can be 16bits or 32bits.  */
-      if ((addr & 0x3) == 0 && (nr_bytes == 2 || nr_bytes == 4))
-	return true;
-    }
-  else
+  if ((addr & 0x3) == 0 && nr_bytes == size)
     return true;
 
-  /* Still here ?  Must be crap.  */
-  bfin_mmr_invalid (me, cpu, addr, nr_bytes, write);
-
+  bfin_mmr_invalid (me, addr, nr_bytes, write, false);
   return false;
 }
 
+/* For 32-bit memory mapped registers that allow 16-bit or 32-bit access.  */
 bool
-dv_bfin_mmr_check (struct hw *me, address_word addr, unsigned nr_bytes,
-		   bool write)
-{
-  return bfin_mmr_check (me, NULL, addr, nr_bytes, write);
-}
-
-int
-device_io_read_buffer (device *me, void *source, int space,
-		       address_word addr, unsigned nr_bytes,
-		       SIM_DESC sd, SIM_CPU *cpu, sim_cia cia)
+dv_bfin_mmr_require_16_32 (struct hw *me, address_word addr, unsigned nr_bytes,
+			   bool write)
 {
-  struct hw *dv_me = (struct hw *) me;
-
-  if (STATE_ENVIRONMENT (sd) != OPERATING_ENVIRONMENT)
-    return nr_bytes;
-
-  if (bfin_mmr_check (dv_me, cpu, addr, nr_bytes, false))
-    if (cpu)
-      {
-	sim_cpu_hw_io_read_buffer (cpu, cia, dv_me, source, space,
-				   addr, nr_bytes);
-	return nr_bytes;
-      }
-    else
-      return sim_hw_io_read_buffer (sd, dv_me, source, space, addr, nr_bytes);
-  else
-    return 0;
-}
+  if ((addr & 0x3) == 0 && (nr_bytes == 2 || nr_bytes == 4))
+    return true;
 
-int
-device_io_write_buffer (device *me, const void *source, int space,
-			address_word addr, unsigned nr_bytes,
-                        SIM_DESC sd, SIM_CPU *cpu, sim_cia cia)
-{
-  struct hw *dv_me = (struct hw *) me;
-
-  if (STATE_ENVIRONMENT (sd) != OPERATING_ENVIRONMENT)
-    return nr_bytes;
-
-  if (bfin_mmr_check (dv_me, cpu, addr, nr_bytes, true))
-    if (cpu)
-      {
-	sim_cpu_hw_io_write_buffer (cpu, cia, dv_me, source, space,
-				    addr, nr_bytes);
-	return nr_bytes;
-      }
-    else
-      return sim_hw_io_write_buffer (sd, dv_me, source, space, addr, nr_bytes);
-  else
-    return 0;
+  bfin_mmr_invalid (me, addr, nr_bytes, write, false);
+  return false;
 }
 
 unsigned int dv_get_bus_num (struct hw *me)
diff --git a/sim/bfin/devices.h b/sim/bfin/devices.h
index a077d55..9bbcfe2 100644
--- a/sim/bfin/devices.h
+++ b/sim/bfin/devices.h
@@ -133,10 +133,12 @@ dv_get_state (SIM_CPU *cpu, const char *device_name)
   })
 
 void dv_bfin_mmr_invalid (struct hw *, address_word, unsigned nr_bytes, bool write);
-void dv_bfin_mmr_require (struct hw *, address_word, unsigned nr_bytes, unsigned size, bool write);
-bool dv_bfin_mmr_check (struct hw *, address_word, unsigned nr_bytes, bool write);
-
+bool dv_bfin_mmr_require (struct hw *, address_word, unsigned nr_bytes, unsigned size, bool write);
+/* For 32-bit memory mapped registers that allow 16-bit or 32-bit access.  */
+bool dv_bfin_mmr_require_16_32 (struct hw *, address_word, unsigned nr_bytes, bool write);
+/* For 32-bit memory mapped registers that only allow 16-bit access.  */
 #define dv_bfin_mmr_require_16(hw, addr, nr_bytes, write) dv_bfin_mmr_require (hw, addr, nr_bytes, 2, write)
+/* For 32-bit memory mapped registers that only allow 32-bit access.  */
 #define dv_bfin_mmr_require_32(hw, addr, nr_bytes, write) dv_bfin_mmr_require (hw, addr, nr_bytes, 4, write)
 
 #define HW_TRACE_WRITE() \
diff --git a/sim/bfin/dv-bfin_cec.c b/sim/bfin/dv-bfin_cec.c
index 186edcb..8ce0d2c 100644
--- a/sim/bfin/dv-bfin_cec.c
+++ b/sim/bfin/dv-bfin_cec.c
@@ -82,6 +82,10 @@ bfin_cec_io_write_buffer (struct hw *me, const void *source,
   bu32 mmr_off;
   bu32 value;
 
+  /* Invalid access mode is higher priority than missing register.  */
+  if (!dv_bfin_mmr_require_32 (me, addr, nr_bytes, true))
+    return 0;
+
   value = dv_load_4 (source);
   mmr_off = addr - cec->base;
 
@@ -118,6 +122,10 @@ bfin_cec_io_read_buffer (struct hw *me, void *dest,
   bu32 mmr_off;
   bu32 *valuep;
 
+  /* Invalid access mode is higher priority than missing register.  */
+  if (!dv_bfin_mmr_require_32 (me, addr, nr_bytes, false))
+    return 0;
+
   mmr_off = addr - cec->base;
   valuep = (void *)((unsigned long)cec + mmr_base() + mmr_off);
 
diff --git a/sim/bfin/dv-bfin_ctimer.c b/sim/bfin/dv-bfin_ctimer.c
index 6aa5c31..f361cb2 100644
--- a/sim/bfin/dv-bfin_ctimer.c
+++ b/sim/bfin/dv-bfin_ctimer.c
@@ -127,6 +127,10 @@ bfin_ctimer_io_write_buffer (struct hw *me, const void *source,
   bu32 value;
   bu32 *valuep;
 
+  /* Invalid access mode is higher priority than missing register.  */
+  if (!dv_bfin_mmr_require_32 (me, addr, nr_bytes, true))
+    return 0;
+
   value = dv_load_4 (source);
   mmr_off = addr - ctimer->base;
   valuep = (void *)((unsigned long)ctimer + mmr_base() + mmr_off);
@@ -192,6 +196,10 @@ bfin_ctimer_io_read_buffer (struct hw *me, void *dest,
   bu32 mmr_off;
   bu32 *valuep;
 
+  /* Invalid access mode is higher priority than missing register.  */
+  if (!dv_bfin_mmr_require_32 (me, addr, nr_bytes, false))
+    return 0;
+
   mmr_off = addr - ctimer->base;
   valuep = (void *)((unsigned long)ctimer + mmr_base() + mmr_off);
 
diff --git a/sim/bfin/dv-bfin_dma.c b/sim/bfin/dv-bfin_dma.c
index 33a80f3..c329ab7 100644
--- a/sim/bfin/dv-bfin_dma.c
+++ b/sim/bfin/dv-bfin_dma.c
@@ -318,6 +318,10 @@ bfin_dma_io_write_buffer (struct hw *me, const void *source, int space,
   bu32 *value32p;
   void *valuep;
 
+  /* Invalid access mode is higher priority than missing register.  */
+  if (!dv_bfin_mmr_require_16_32 (me, addr, nr_bytes, true))
+    return 0;
+
   if (nr_bytes == 4)
     value = dv_load_4 (source);
   else
@@ -401,7 +405,7 @@ bfin_dma_io_write_buffer (struct hw *me, const void *source, int space,
     default:
       /* XXX: The HW lets the pad regions be read/written ...  */
       dv_bfin_mmr_invalid (me, addr, nr_bytes, true);
-      break;
+      return 0;
     }
 
   return nr_bytes;
@@ -417,6 +421,10 @@ bfin_dma_io_read_buffer (struct hw *me, void *dest, int space,
   bu32 *value32p;
   void *valuep;
 
+  /* Invalid access mode is higher priority than missing register.  */
+  if (!dv_bfin_mmr_require_16_32 (me, addr, nr_bytes, false))
+    return 0;
+
   mmr_off = addr % dma->base;
   valuep = (void *)((unsigned long)dma + mmr_base() + mmr_off);
   value16p = valuep;
diff --git a/sim/bfin/dv-bfin_ebiu_amc.c b/sim/bfin/dv-bfin_ebiu_amc.c
index 3bdae61..623d696 100644
--- a/sim/bfin/dv-bfin_ebiu_amc.c
+++ b/sim/bfin/dv-bfin_ebiu_amc.c
@@ -121,7 +121,8 @@ bf50x_ebiu_amc_io_write_buffer (struct hw *me, const void *source, int space,
   switch (mmr_off)
     {
     case mmr_offset(amgctl):
-      dv_bfin_mmr_require_16 (me, addr, nr_bytes, true);
+      if (!dv_bfin_mmr_require_16 (me, addr, nr_bytes, true))
+	return 0;
       bfin_ebiu_amc_write_amgctl (me, amc, value);
       break;
     case mmr_offset(bf50x.ambctl0):
@@ -132,15 +133,17 @@ bf50x_ebiu_amc_io_write_buffer (struct hw *me, const void *source, int space,
       break;
     case mmr_offset(bf50x.mode):
       /* XXX: implement this.  */
-      dv_bfin_mmr_require_16 (me, addr, nr_bytes, true);
+      if (!dv_bfin_mmr_require_16 (me, addr, nr_bytes, true))
+	return 0;
       break;
     case mmr_offset(bf50x.fctl):
       /* XXX: implement this.  */
-      dv_bfin_mmr_require_16 (me, addr, nr_bytes, true);
+      if (!dv_bfin_mmr_require_16 (me, addr, nr_bytes, true))
+	return 0;
       break;
     default:
       dv_bfin_mmr_invalid (me, addr, nr_bytes, true);
-      break;
+      return 0;
     }
 
   return nr_bytes;
@@ -155,7 +158,8 @@ bf53x_ebiu_amc_io_write_buffer (struct hw *me, const void *source, int space,
   switch (mmr_off)
     {
     case mmr_offset(amgctl):
-      dv_bfin_mmr_require_16 (me, addr, nr_bytes, true);
+      if (!dv_bfin_mmr_require_16 (me, addr, nr_bytes, true))
+	return 0;
       bfin_ebiu_amc_write_amgctl (me, amc, value);
       break;
     case mmr_offset(bf53x.ambctl0):
@@ -166,7 +170,7 @@ bf53x_ebiu_amc_io_write_buffer (struct hw *me, const void *source, int space,
       break;
     default:
       dv_bfin_mmr_invalid (me, addr, nr_bytes, true);
-      break;
+      return 0;
     }
 
   return nr_bytes;
@@ -181,7 +185,8 @@ bf54x_ebiu_amc_io_write_buffer (struct hw *me, const void *source, int space,
   switch (mmr_off)
     {
     case mmr_offset(amgctl):
-      dv_bfin_mmr_require_16 (me, addr, nr_bytes, true);
+      if (!dv_bfin_mmr_require_16 (me, addr, nr_bytes, true))
+	return 0;
       bfin_ebiu_amc_write_amgctl (me, amc, value);
       break;
     case mmr_offset(bf54x.ambctl0):
@@ -204,7 +209,7 @@ bf54x_ebiu_amc_io_write_buffer (struct hw *me, const void *source, int space,
       break;
     default:
       dv_bfin_mmr_invalid (me, addr, nr_bytes, true);
-      break;
+      return 0;
     }
 
   return nr_bytes;
@@ -218,6 +223,10 @@ bfin_ebiu_amc_io_write_buffer (struct hw *me, const void *source, int space,
   bu32 mmr_off;
   bu32 value;
 
+  /* Invalid access mode is higher priority than missing register.  */
+  if (!dv_bfin_mmr_require_16_32 (me, addr, nr_bytes, true))
+    return 0;
+
   value = dv_load_4 (source);
   mmr_off = addr - amc->base;
 
@@ -237,7 +246,8 @@ bf50x_ebiu_amc_io_read_buffer (struct hw *me, void *dest, int space,
     {
     case mmr_offset(amgctl):
     case mmr_offset(bf50x.fctl):
-      dv_bfin_mmr_require_16 (me, addr, nr_bytes, false);
+      if (!dv_bfin_mmr_require_16 (me, addr, nr_bytes, false))
+	return 0;
       dv_store_2 (dest, *value16);
       break;
     case mmr_offset(bf50x.ambctl0):
@@ -247,7 +257,7 @@ bf50x_ebiu_amc_io_read_buffer (struct hw *me, void *dest, int space,
       break;
     default:
       dv_bfin_mmr_invalid (me, addr, nr_bytes, false);
-      break;
+      return 0;
     }
 
   return nr_bytes;
@@ -262,7 +272,8 @@ bf53x_ebiu_amc_io_read_buffer (struct hw *me, void *dest, int space,
   switch (mmr_off)
     {
     case mmr_offset(amgctl):
-      dv_bfin_mmr_require_16 (me, addr, nr_bytes, false);
+      if (!dv_bfin_mmr_require_16 (me, addr, nr_bytes, false))
+	return 0;
       dv_store_2 (dest, *value16);
       break;
     case mmr_offset(bf53x.ambctl0):
@@ -271,7 +282,7 @@ bf53x_ebiu_amc_io_read_buffer (struct hw *me, void *dest, int space,
       break;
     default:
       dv_bfin_mmr_invalid (me, addr, nr_bytes, false);
-      break;
+      return 0;
     }
 
   return nr_bytes;
@@ -286,7 +297,8 @@ bf54x_ebiu_amc_io_read_buffer (struct hw *me, void *dest, int space,
   switch (mmr_off)
     {
     case mmr_offset(amgctl):
-      dv_bfin_mmr_require_16 (me, addr, nr_bytes, false);
+      if (!dv_bfin_mmr_require_16 (me, addr, nr_bytes, false))
+	return 0;
       dv_store_2 (dest, *value16);
       break;
     case mmr_offset(bf54x.ambctl0):
@@ -299,7 +311,7 @@ bf54x_ebiu_amc_io_read_buffer (struct hw *me, void *dest, int space,
       break;
     default:
       dv_bfin_mmr_invalid (me, addr, nr_bytes, false);
-      break;
+      return 0;
     }
 
   return nr_bytes;
@@ -313,6 +325,10 @@ bfin_ebiu_amc_io_read_buffer (struct hw *me, void *dest, int space,
   bu32 mmr_off;
   void *valuep;
 
+  /* Invalid access mode is higher priority than missing register.  */
+  if (!dv_bfin_mmr_require_16_32 (me, addr, nr_bytes, false))
+    return 0;
+
   mmr_off = addr - amc->base;
   valuep = (void *)((unsigned long)amc + mmr_base() + mmr_off);
 
diff --git a/sim/bfin/dv-bfin_ebiu_ddrc.c b/sim/bfin/dv-bfin_ebiu_ddrc.c
index 51e1ed2..b0b820f 100644
--- a/sim/bfin/dv-bfin_ebiu_ddrc.c
+++ b/sim/bfin/dv-bfin_ebiu_ddrc.c
@@ -68,6 +68,10 @@ bfin_ebiu_ddrc_io_write_buffer (struct hw *me, const void *source,
   bu32 *value32p;
   void *valuep;
 
+  /* Invalid access mode is higher priority than missing register.  */
+  if (!dv_bfin_mmr_require_16_32 (me, addr, nr_bytes, true))
+    return 0;
+
   if (nr_bytes == 4)
     value = dv_load_4 (source);
   else
@@ -84,11 +88,13 @@ bfin_ebiu_ddrc_io_write_buffer (struct hw *me, const void *source,
     {
     case mmr_offset(errmst):
     case mmr_offset(rstctl):
-      dv_bfin_mmr_require_16 (me, addr, nr_bytes, true);
+      if (!dv_bfin_mmr_require_16 (me, addr, nr_bytes, true))
+	return 0;
       *value16p = value;
       break;
     default:
-      dv_bfin_mmr_require_32 (me, addr, nr_bytes, true);
+      if (!dv_bfin_mmr_require_32 (me, addr, nr_bytes, true))
+	return 0;
       *value32p = value;
       break;
     }
@@ -106,6 +112,10 @@ bfin_ebiu_ddrc_io_read_buffer (struct hw *me, void *dest,
   bu16 *value16p;
   void *valuep;
 
+  /* Invalid access mode is higher priority than missing register.  */
+  if (!dv_bfin_mmr_require_16_32 (me, addr, nr_bytes, true))
+    return 0;
+
   mmr_off = addr - ddrc->base;
   valuep = (void *)((unsigned long)ddrc + mmr_base() + mmr_off);
   value16p = valuep;
@@ -117,11 +127,13 @@ bfin_ebiu_ddrc_io_read_buffer (struct hw *me, void *dest,
     {
     case mmr_offset(errmst):
     case mmr_offset(rstctl):
-      dv_bfin_mmr_require_16 (me, addr, nr_bytes, false);
+      if (!dv_bfin_mmr_require_16 (me, addr, nr_bytes, false))
+	return 0;
       dv_store_2 (dest, *value16p);
       break;
     default:
-      dv_bfin_mmr_require_32 (me, addr, nr_bytes, false);
+      if (!dv_bfin_mmr_require_32 (me, addr, nr_bytes, false))
+	return 0;
       dv_store_4 (dest, *value32p);
       break;
     }
diff --git a/sim/bfin/dv-bfin_ebiu_sdc.c b/sim/bfin/dv-bfin_ebiu_sdc.c
index e7a036a..396b1e4 100644
--- a/sim/bfin/dv-bfin_ebiu_sdc.c
+++ b/sim/bfin/dv-bfin_ebiu_sdc.c
@@ -56,6 +56,10 @@ bfin_ebiu_sdc_io_write_buffer (struct hw *me, const void *source,
   bu32 *value32p;
   void *valuep;
 
+  /* Invalid access mode is higher priority than missing register.  */
+  if (!dv_bfin_mmr_require_16_32 (me, addr, nr_bytes, true))
+    return 0;
+
   if (nr_bytes == 4)
     value = dv_load_4 (source);
   else
@@ -77,21 +81,25 @@ bfin_ebiu_sdc_io_write_buffer (struct hw *me, const void *source,
     case mmr_offset(sdbctl):
       if (sdc->type == 561)
 	{
-	  dv_bfin_mmr_require_32 (me, addr, nr_bytes, true);
+	  if (!dv_bfin_mmr_require_32 (me, addr, nr_bytes, true))
+	    return 0;
 	  *value32p = value;
 	}
       else
 	{
-	  dv_bfin_mmr_require_16 (me, addr, nr_bytes, true);
+	  if (!dv_bfin_mmr_require_16 (me, addr, nr_bytes, true))
+	    return 0;
 	  *value16p = value;
 	}
       break;
     case mmr_offset(sdrrc):
-      dv_bfin_mmr_require_16 (me, addr, nr_bytes, true);
+      if (!dv_bfin_mmr_require_16 (me, addr, nr_bytes, true))
+	return 0;
       *value16p = value;
       break;
     case mmr_offset(sdstat):
-      dv_bfin_mmr_require_16 (me, addr, nr_bytes, true);
+      if (!dv_bfin_mmr_require_16 (me, addr, nr_bytes, true))
+	return 0;
       /* XXX: Some bits are W1C ...  */
       break;
     }
@@ -109,6 +117,10 @@ bfin_ebiu_sdc_io_read_buffer (struct hw *me, void *dest,
   bu16 *value16p;
   void *valuep;
 
+  /* Invalid access mode is higher priority than missing register.  */
+  if (!dv_bfin_mmr_require_16_32 (me, addr, nr_bytes, false))
+    return 0;
+
   mmr_off = addr - sdc->base;
   valuep = (void *)((unsigned long)sdc + mmr_base() + mmr_off);
   value16p = valuep;
@@ -124,18 +136,21 @@ bfin_ebiu_sdc_io_read_buffer (struct hw *me, void *dest,
     case mmr_offset(sdbctl):
       if (sdc->type == 561)
 	{
-	  dv_bfin_mmr_require_32 (me, addr, nr_bytes, false);
+	  if (!dv_bfin_mmr_require_32 (me, addr, nr_bytes, false))
+	    return 0;
 	  dv_store_4 (dest, *value32p);
 	}
       else
 	{
-	  dv_bfin_mmr_require_16 (me, addr, nr_bytes, false);
+	  if (!dv_bfin_mmr_require_16 (me, addr, nr_bytes, false))
+	    return 0;
 	  dv_store_2 (dest, *value16p);
 	}
       break;
     case mmr_offset(sdrrc):
     case mmr_offset(sdstat):
-      dv_bfin_mmr_require_16 (me, addr, nr_bytes, false);
+      if (!dv_bfin_mmr_require_16 (me, addr, nr_bytes, false))
+	return 0;
       dv_store_2 (dest, *value16p);
       break;
     }
diff --git a/sim/bfin/dv-bfin_emac.c b/sim/bfin/dv-bfin_emac.c
index 1abdf99..7bdedbb 100644
--- a/sim/bfin/dv-bfin_emac.c
+++ b/sim/bfin/dv-bfin_emac.c
@@ -177,8 +177,10 @@ bfin_emac_io_write_buffer (struct hw *me, const void *source,
   bu32 value;
   bu32 *valuep;
 
+  /* Invalid access mode is higher priority than missing register.  */
   /* XXX: 16bit accesses are allowed ...  */
-  dv_bfin_mmr_require_32 (me, addr, nr_bytes, true);
+  if (!dv_bfin_mmr_require_32 (me, addr, nr_bytes, true))
+    return 0;
   value = dv_load_4 (source);
 
   mmr_off = addr - emac->base;
@@ -263,7 +265,7 @@ bfin_emac_io_write_buffer (struct hw *me, const void *source,
       break;
     default:
       dv_bfin_mmr_invalid (me, addr, nr_bytes, true);
-      break;
+      return 0;
     }
 
   return nr_bytes;
@@ -277,8 +279,10 @@ bfin_emac_io_read_buffer (struct hw *me, void *dest,
   bu32 mmr_off;
   bu32 *valuep;
 
+  /* Invalid access mode is higher priority than missing register.  */
   /* XXX: 16bit accesses are allowed ...  */
-  dv_bfin_mmr_require_32 (me, addr, nr_bytes, false);
+  if (!dv_bfin_mmr_require_32 (me, addr, nr_bytes, false))
+    return 0;
 
   mmr_off = addr - emac->base;
   valuep = (void *)((unsigned long)emac + mmr_base() + mmr_off);
@@ -328,7 +332,7 @@ bfin_emac_io_read_buffer (struct hw *me, void *dest,
       break;
     default:
       dv_bfin_mmr_invalid (me, addr, nr_bytes, false);
-      break;
+      return 0;
     }
 
   return nr_bytes;
diff --git a/sim/bfin/dv-bfin_eppi.c b/sim/bfin/dv-bfin_eppi.c
index 5999568..5ca2a9c 100644
--- a/sim/bfin/dv-bfin_eppi.c
+++ b/sim/bfin/dv-bfin_eppi.c
@@ -90,6 +90,10 @@ bfin_eppi_io_write_buffer (struct hw *me, const void *source,
   bu32 *value32p;
   void *valuep;
 
+  /* Invalid access mode is higher priority than missing register.  */
+  if (!dv_bfin_mmr_require_16_32 (me, addr, nr_bytes, true))
+    return 0;
+
   if (nr_bytes == 4)
     value = dv_load_4 (source);
   else
@@ -105,7 +109,8 @@ bfin_eppi_io_write_buffer (struct hw *me, const void *source,
   switch (mmr_off)
     {
     case mmr_offset(status):
-      dv_bfin_mmr_require_16 (me, addr, nr_bytes, true);
+      if (!dv_bfin_mmr_require_16 (me, addr, nr_bytes, true))
+	return 0;
       dv_w1c_2 (value16p, value, 0x1ff);
       break;
     case mmr_offset(hcount):
@@ -115,7 +120,8 @@ bfin_eppi_io_write_buffer (struct hw *me, const void *source,
     case mmr_offset(frame):
     case mmr_offset(line):
     case mmr_offset(clkdiv):
-      dv_bfin_mmr_require_16 (me, addr, nr_bytes, true);
+      if (!dv_bfin_mmr_require_16 (me, addr, nr_bytes, true))
+	return 0;
       *value16p = value;
       break;
     case mmr_offset(control):
@@ -128,12 +134,13 @@ bfin_eppi_io_write_buffer (struct hw *me, const void *source,
     case mmr_offset(fs2p_lavf):
     case mmr_offset(clip):
     case mmr_offset(err):
-      dv_bfin_mmr_require_32 (me, addr, nr_bytes, true);
+      if (!dv_bfin_mmr_require_32 (me, addr, nr_bytes, true))
+	return 0;
       *value32p = value;
       break;
     default:
       dv_bfin_mmr_invalid (me, addr, nr_bytes, true);
-      break;
+      return 0;
     }
 
   return nr_bytes;
@@ -149,6 +156,10 @@ bfin_eppi_io_read_buffer (struct hw *me, void *dest,
   bu32 *value32p;
   void *valuep;
 
+  /* Invalid access mode is higher priority than missing register.  */
+  if (!dv_bfin_mmr_require_16_32 (me, addr, nr_bytes, true))
+    return 0;
+
   mmr_off = addr - eppi->base;
   valuep = (void *)((unsigned long)eppi + mmr_base() + mmr_off);
   value16p = valuep;
@@ -166,7 +177,8 @@ bfin_eppi_io_read_buffer (struct hw *me, void *dest,
     case mmr_offset(frame):
     case mmr_offset(line):
     case mmr_offset(clkdiv):
-      dv_bfin_mmr_require_16 (me, addr, nr_bytes, false);
+      if (!dv_bfin_mmr_require_16 (me, addr, nr_bytes, false))
+	return 0;
       dv_store_2 (dest, *value16p);
       break;
     case mmr_offset(control):
@@ -176,12 +188,13 @@ bfin_eppi_io_read_buffer (struct hw *me, void *dest,
     case mmr_offset(fs2p_lavf):
     case mmr_offset(clip):
     case mmr_offset(err):
-      dv_bfin_mmr_require_32 (me, addr, nr_bytes, false);
+      if (!dv_bfin_mmr_require_32 (me, addr, nr_bytes, false))
+	return 0;
       dv_store_4 (dest, *value32p);
       break;
     default:
       dv_bfin_mmr_invalid (me, addr, nr_bytes, false);
-      break;
+      return 0;
     }
 
   return nr_bytes;
diff --git a/sim/bfin/dv-bfin_evt.c b/sim/bfin/dv-bfin_evt.c
index 6f859b5..cb2d0df 100644
--- a/sim/bfin/dv-bfin_evt.c
+++ b/sim/bfin/dv-bfin_evt.c
@@ -50,6 +50,10 @@ bfin_evt_io_write_buffer (struct hw *me, const void *source,
   bu32 mmr_off;
   bu32 value;
 
+  /* Invalid access mode is higher priority than missing register.  */
+  if (!dv_bfin_mmr_require_32 (me, addr, nr_bytes, true))
+    return 0;
+
   value = dv_load_4 (source);
   mmr_off = addr - evt->base;
 
@@ -68,6 +72,10 @@ bfin_evt_io_read_buffer (struct hw *me, void *dest,
   bu32 mmr_off;
   bu32 value;
 
+  /* Invalid access mode is higher priority than missing register.  */
+  if (!dv_bfin_mmr_require_32 (me, addr, nr_bytes, false))
+    return 0;
+
   mmr_off = addr - evt->base;
 
   HW_TRACE_READ ();
diff --git a/sim/bfin/dv-bfin_gpio.c b/sim/bfin/dv-bfin_gpio.c
index 555d3f1..44c6e7a 100644
--- a/sim/bfin/dv-bfin_gpio.c
+++ b/sim/bfin/dv-bfin_gpio.c
@@ -110,14 +110,16 @@ bfin_gpio_io_write_buffer (struct hw *me, const void *source, int space,
   bu16 *valuep;
   bu32 data = port->data;
 
+  /* Invalid access mode is higher priority than missing register.  */
+  if (!dv_bfin_mmr_require_16 (me, addr, nr_bytes, true))
+    return 0;
+
   value = dv_load_2 (source);
   mmr_off = addr - port->base;
   valuep = (void *)((unsigned long)port + mmr_base() + mmr_off);
 
   HW_TRACE_WRITE ();
 
-  dv_bfin_mmr_require_16 (me, addr, nr_bytes, true);
-
   switch (mmr_off)
     {
     case mmr_offset(data):
@@ -153,7 +155,7 @@ bfin_gpio_io_write_buffer (struct hw *me, const void *source, int space,
       break;
     default:
       dv_bfin_mmr_invalid (me, addr, nr_bytes, true);
-      break;
+      return 0;
     }
 
   /* If updating masks, make sure we send updated port info.  */
@@ -182,13 +184,15 @@ bfin_gpio_io_read_buffer (struct hw *me, void *dest, int space,
   bu32 mmr_off;
   bu16 *valuep;
 
+  /* Invalid access mode is higher priority than missing register.  */
+  if (!dv_bfin_mmr_require_16 (me, addr, nr_bytes, false))
+    return 0;
+
   mmr_off = addr - port->base;
   valuep = (void *)((unsigned long)port + mmr_base() + mmr_off);
 
   HW_TRACE_READ ();
 
-  dv_bfin_mmr_require_16 (me, addr, nr_bytes, false);
-
   switch (mmr_off)
     {
     case mmr_offset(data):
@@ -218,7 +222,7 @@ bfin_gpio_io_read_buffer (struct hw *me, void *dest, int space,
       break;
     default:
       dv_bfin_mmr_invalid (me, addr, nr_bytes, false);
-      break;
+      return 0;
     }
 
   return nr_bytes;
diff --git a/sim/bfin/dv-bfin_gpio2.c b/sim/bfin/dv-bfin_gpio2.c
index 0069e0d..a2b9419 100644
--- a/sim/bfin/dv-bfin_gpio2.c
+++ b/sim/bfin/dv-bfin_gpio2.c
@@ -66,22 +66,28 @@ bfin_gpio_io_write_buffer (struct hw *me, const void *source, int space,
   bu32 *value32p;
   void *valuep;
 
+  mmr_off = addr - port->base;
+
+  /* Invalid access mode is higher priority than missing register.  */
+  if (mmr_off == mmr_offset (mux))
+    {
+      if (!dv_bfin_mmr_require_32 (me, addr, nr_bytes, true))
+	return 0;
+    }
+  else
+    if (!dv_bfin_mmr_require_16 (me, addr, nr_bytes, true))
+	return 0;
+
   if (nr_bytes == 4)
     value = dv_load_4 (source);
   else
     value = dv_load_2 (source);
-  mmr_off = addr - port->base;
   valuep = (void *)((unsigned long)port + mmr_base() + mmr_off);
   value16p = valuep;
   value32p = valuep;
 
   HW_TRACE_WRITE ();
 
-  if (mmr_off == mmr_offset (mux))
-    dv_bfin_mmr_require_32 (me, addr, nr_bytes, true);
-  else
-    dv_bfin_mmr_require_16 (me, addr, nr_bytes, true);
-
   switch (mmr_off)
     {
     case mmr_offset(fer):
@@ -108,7 +114,7 @@ bfin_gpio_io_write_buffer (struct hw *me, const void *source, int space,
       break;
     default:
       dv_bfin_mmr_invalid (me, addr, nr_bytes, true);
-      break;
+      return 0;
     }
 
   /* If tweaking output pins, make sure we send updated port info.  */
@@ -148,17 +154,23 @@ bfin_gpio_io_read_buffer (struct hw *me, void *dest, int space,
   void *valuep;
 
   mmr_off = addr - port->base;
+
+  /* Invalid access mode is higher priority than missing register.  */
+  if (mmr_off == mmr_offset (mux))
+    {
+      if (!dv_bfin_mmr_require_32 (me, addr, nr_bytes, false))
+	return 0;
+    }
+  else
+    if (!dv_bfin_mmr_require_16 (me, addr, nr_bytes, false))
+      return 0;
+
   valuep = (void *)((unsigned long)port + mmr_base() + mmr_off);
   value16p = valuep;
   value32p = valuep;
 
   HW_TRACE_READ ();
 
-  if (mmr_off == mmr_offset (mux))
-    dv_bfin_mmr_require_32 (me, addr, nr_bytes, false);
-  else
-    dv_bfin_mmr_require_16 (me, addr, nr_bytes, false);
-
   switch (mmr_off)
     {
     case mmr_offset(data):
@@ -179,7 +191,7 @@ bfin_gpio_io_read_buffer (struct hw *me, void *dest, int space,
       break;
     default:
       dv_bfin_mmr_invalid (me, addr, nr_bytes, false);
-      break;
+      return 0;
     }
 
   return nr_bytes;
diff --git a/sim/bfin/dv-bfin_gptimer.c b/sim/bfin/dv-bfin_gptimer.c
index 26f6a34..e4c05ca 100644
--- a/sim/bfin/dv-bfin_gptimer.c
+++ b/sim/bfin/dv-bfin_gptimer.c
@@ -61,6 +61,10 @@ bfin_gptimer_io_write_buffer (struct hw *me, const void *source, int space,
   bu32 *value32p;
   void *valuep;
 
+  /* Invalid access mode is higher priority than missing register.  */
+  if (!dv_bfin_mmr_require_16_32 (me, addr, nr_bytes, true))
+    return 0;
+
   if (nr_bytes == 4)
     value = dv_load_4 (source);
   else
@@ -76,18 +80,20 @@ bfin_gptimer_io_write_buffer (struct hw *me, const void *source, int space,
   switch (mmr_off)
     {
     case mmr_offset(config):
-      dv_bfin_mmr_require_16 (me, addr, nr_bytes, true);
+      if (!dv_bfin_mmr_require_16 (me, addr, nr_bytes, true))
+	return 0;
       *value16p = value;
       break;
     case mmr_offset(counter):
     case mmr_offset(period):
     case mmr_offset(width):
-      dv_bfin_mmr_require_32 (me, addr, nr_bytes, true);
+      if (!dv_bfin_mmr_require_32 (me, addr, nr_bytes, true))
+	return 0;
       *value32p = value;
       break;
     default:
       dv_bfin_mmr_invalid (me, addr, nr_bytes, true);
-      break;
+      return 0;
     }
 
   return nr_bytes;
@@ -103,6 +109,10 @@ bfin_gptimer_io_read_buffer (struct hw *me, void *dest, int space,
   bu32 *value32p;
   void *valuep;
 
+  /* Invalid access mode is higher priority than missing register.  */
+  if (!dv_bfin_mmr_require_16_32 (me, addr, nr_bytes, false))
+    return 0;
+
   mmr_off = addr - gptimer->base;
   valuep = (void *)((unsigned long)gptimer + mmr_base() + mmr_off);
   value16p = valuep;
@@ -113,18 +123,20 @@ bfin_gptimer_io_read_buffer (struct hw *me, void *dest, int space,
   switch (mmr_off)
     {
     case mmr_offset(config):
-      dv_bfin_mmr_require_16 (me, addr, nr_bytes, false);
+      if (!dv_bfin_mmr_require_16 (me, addr, nr_bytes, false))
+	return 0;
       dv_store_2 (dest, *value16p);
       break;
     case mmr_offset(counter):
     case mmr_offset(period):
     case mmr_offset(width):
-      dv_bfin_mmr_require_32 (me, addr, nr_bytes, false);
+      if (!dv_bfin_mmr_require_32 (me, addr, nr_bytes, false))
+	return 0;
       dv_store_4 (dest, *value32p);
       break;
     default:
       dv_bfin_mmr_invalid (me, addr, nr_bytes, false);
-      break;
+      return 0;
     }
 
   return nr_bytes;
diff --git a/sim/bfin/dv-bfin_jtag.c b/sim/bfin/dv-bfin_jtag.c
index 0f34c68..ad4c8b6 100644
--- a/sim/bfin/dv-bfin_jtag.c
+++ b/sim/bfin/dv-bfin_jtag.c
@@ -54,6 +54,10 @@ bfin_jtag_io_write_buffer (struct hw *me, const void *source, int space,
   bu32 value;
   bu32 *valuep;
 
+  /* Invalid access mode is higher priority than missing register.  */
+  if (!dv_bfin_mmr_require_32 (me, addr, nr_bytes, true))
+    return 0;
+
   value = dv_load_4 (source);
   mmr_off = addr - jtag->base;
   valuep = (void *)((unsigned long)jtag + mmr_base() + mmr_off);
@@ -70,7 +74,7 @@ bfin_jtag_io_write_buffer (struct hw *me, const void *source, int space,
       break;
     default:
       dv_bfin_mmr_invalid (me, addr, nr_bytes, true);
-      break;
+      return 0;
     }
 
   return nr_bytes;
@@ -85,6 +89,10 @@ bfin_jtag_io_read_buffer (struct hw *me, void *dest, int space,
   bu32 value;
   bu32 *valuep;
 
+  /* Invalid access mode is higher priority than missing register.  */
+  if (!dv_bfin_mmr_require_32 (me, addr, nr_bytes, false))
+    return 0;
+
   mmr_off = addr - jtag->base;
   valuep = (void *)((unsigned long)jtag + mmr_base() + mmr_off);
 
@@ -97,9 +105,8 @@ bfin_jtag_io_read_buffer (struct hw *me, void *dest, int space,
       value = *valuep;
       break;
     default:
-      while (1) /* Core MMRs -> exception -> doesn't return.  */
-	dv_bfin_mmr_invalid (me, addr, nr_bytes, false);
-      break;
+      dv_bfin_mmr_invalid (me, addr, nr_bytes, false);
+      return 0;
     }
 
   dv_store_4 (dest, value);
diff --git a/sim/bfin/dv-bfin_mmu.c b/sim/bfin/dv-bfin_mmu.c
index a3d5ba1..ce8cc9f 100644
--- a/sim/bfin/dv-bfin_mmu.c
+++ b/sim/bfin/dv-bfin_mmu.c
@@ -101,6 +101,10 @@ bfin_mmu_io_write_buffer (struct hw *me, const void *source,
   bu32 value;
   bu32 *valuep;
 
+  /* Invalid access mode is higher priority than missing register.  */
+  if (!dv_bfin_mmr_require_32 (me, addr, nr_bytes, true))
+    return 0;
+
   value = dv_load_4 (source);
 
   mmr_off = addr - mmu->base;
@@ -159,7 +163,7 @@ bfin_mmu_io_write_buffer (struct hw *me, const void *source,
       break;
     default:
       dv_bfin_mmr_invalid (me, addr, nr_bytes, true);
-      break;
+      return 0;
     }
 
   return nr_bytes;
@@ -173,6 +177,10 @@ bfin_mmu_io_read_buffer (struct hw *me, void *dest,
   bu32 mmr_off;
   bu32 *valuep;
 
+  /* Invalid access mode is higher priority than missing register.  */
+  if (!dv_bfin_mmr_require_32 (me, addr, nr_bytes, false))
+    return 0;
+
   mmr_off = addr - mmu->base;
   valuep = (void *)((unsigned long)mmu + mmr_base() + mmr_off);
 
@@ -200,9 +208,8 @@ bfin_mmu_io_read_buffer (struct hw *me, void *dest,
       dv_store_4 (dest, *valuep);
       break;
     default:
-      while (1) /* Core MMRs -> exception -> doesn't return.  */
-	dv_bfin_mmr_invalid (me, addr, nr_bytes, false);
-      break;
+      dv_bfin_mmr_invalid (me, addr, nr_bytes, false);
+      return 0;
     }
 
   return nr_bytes;
diff --git a/sim/bfin/dv-bfin_nfc.c b/sim/bfin/dv-bfin_nfc.c
index 478a682..288e251 100644
--- a/sim/bfin/dv-bfin_nfc.c
+++ b/sim/bfin/dv-bfin_nfc.c
@@ -77,14 +77,16 @@ bfin_nfc_io_write_buffer (struct hw *me, const void *source, int space,
   bu32 value;
   bu16 *valuep;
 
+  /* Invalid access mode is higher priority than missing register.  */
+  if (!dv_bfin_mmr_require_16 (me, addr, nr_bytes, true))
+    return 0;
+
   value = dv_load_2 (source);
   mmr_off = addr - nfc->base;
   valuep = (void *)((unsigned long)nfc + mmr_base() + mmr_off);
 
   HW_TRACE_WRITE ();
 
-  dv_bfin_mmr_require_16 (me, addr, nr_bytes, true);
-
   switch (mmr_off)
     {
     case mmr_offset(ctl):
@@ -112,7 +114,7 @@ bfin_nfc_io_write_buffer (struct hw *me, const void *source, int space,
       break;
     default:
       dv_bfin_mmr_invalid (me, addr, nr_bytes, true);
-      break;
+      return 0;
     }
 
   return nr_bytes;
@@ -126,13 +128,15 @@ bfin_nfc_io_read_buffer (struct hw *me, void *dest, int space,
   bu32 mmr_off;
   bu16 *valuep;
 
+  /* Invalid access mode is higher priority than missing register.  */
+  if (!dv_bfin_mmr_require_16 (me, addr, nr_bytes, false))
+    return 0;
+
   mmr_off = addr - nfc->base;
   valuep = (void *)((unsigned long)nfc + mmr_base() + mmr_off);
 
   HW_TRACE_READ ();
 
-  dv_bfin_mmr_require_16 (me, addr, nr_bytes, false);
-
   switch (mmr_off)
     {
     case mmr_offset(ctl):
@@ -156,7 +160,7 @@ bfin_nfc_io_read_buffer (struct hw *me, void *dest, int space,
       /* These regs are write only.  */
     default:
       dv_bfin_mmr_invalid (me, addr, nr_bytes, false);
-      break;
+      return 0;
     }
 
   return nr_bytes;
diff --git a/sim/bfin/dv-bfin_otp.c b/sim/bfin/dv-bfin_otp.c
index 52bcf47..4a20eb1 100644
--- a/sim/bfin/dv-bfin_otp.c
+++ b/sim/bfin/dv-bfin_otp.c
@@ -104,6 +104,10 @@ bfin_otp_io_write_buffer (struct hw *me, const void *source, int space,
   bu32 *value32p;
   void *valuep;
 
+  /* Invalid access mode is higher priority than missing register.  */
+  if (!dv_bfin_mmr_require_16_32 (me, addr, nr_bytes, true))
+    return 0;
+
   if (nr_bytes == 4)
     value = dv_load_4 (source);
   else
@@ -122,7 +126,8 @@ bfin_otp_io_write_buffer (struct hw *me, const void *source, int space,
       {
 	int page;
 
-	dv_bfin_mmr_require_16 (me, addr, nr_bytes, true);
+	if (!dv_bfin_mmr_require_16 (me, addr, nr_bytes, true))
+	  return 0;
 	/* XXX: Seems like these bits aren't writable.  */
 	*value16p = value & 0x39FF;
 
@@ -142,12 +147,14 @@ bfin_otp_io_write_buffer (struct hw *me, const void *source, int space,
 	break;
       }
     case mmr_offset(ben):
-      dv_bfin_mmr_require_16 (me, addr, nr_bytes, true);
+      if (!dv_bfin_mmr_require_16 (me, addr, nr_bytes, true))
+	return 0;
       /* XXX: All bits seem to be writable.  */
       *value16p = value;
       break;
     case mmr_offset(status):
-      dv_bfin_mmr_require_16 (me, addr, nr_bytes, true);
+      if (!dv_bfin_mmr_require_16 (me, addr, nr_bytes, true))
+	return 0;
       /* XXX: All bits seem to be W1C.  */
       dv_w1c_2 (value16p, value, -1);
       break;
@@ -156,12 +163,13 @@ bfin_otp_io_write_buffer (struct hw *me, const void *source, int space,
     case mmr_offset(data1):
     case mmr_offset(data2):
     case mmr_offset(data3):
-      dv_bfin_mmr_require_32 (me, addr, nr_bytes, true);
+      if (!dv_bfin_mmr_require_32 (me, addr, nr_bytes, true))
+	return 0;
       *value32p = value;
       break;
     default:
       dv_bfin_mmr_invalid (me, addr, nr_bytes, true);
-      break;
+      return 0;
     }
 
   return nr_bytes;
@@ -177,6 +185,10 @@ bfin_otp_io_read_buffer (struct hw *me, void *dest, int space,
   bu32 *value32p;
   void *valuep;
 
+  /* Invalid access mode is higher priority than missing register.  */
+  if (!dv_bfin_mmr_require_16_32 (me, addr, nr_bytes, false))
+    return 0;
+
   mmr_off = addr - otp->base;
   valuep = (void *)((unsigned long)otp + mmr_base() + mmr_off);
   value16p = valuep;
@@ -189,7 +201,8 @@ bfin_otp_io_read_buffer (struct hw *me, void *dest, int space,
     case mmr_offset(control):
     case mmr_offset(ben):
     case mmr_offset(status):
-      dv_bfin_mmr_require_16 (me, addr, nr_bytes, false);
+      if (!dv_bfin_mmr_require_16 (me, addr, nr_bytes, false))
+	return 0;
       dv_store_2 (dest, *value16p);
       break;
     case mmr_offset(timing):
@@ -197,12 +210,13 @@ bfin_otp_io_read_buffer (struct hw *me, void *dest, int space,
     case mmr_offset(data1):
     case mmr_offset(data2):
     case mmr_offset(data3):
-      dv_bfin_mmr_require_32 (me, addr, nr_bytes, false);
+      if (!dv_bfin_mmr_require_32 (me, addr, nr_bytes, false))
+	return 0;
       dv_store_4 (dest, *value32p);
       break;
     default:
       dv_bfin_mmr_invalid (me, addr, nr_bytes, false);
-      break;
+      return 0;
     }
 
   return nr_bytes;
diff --git a/sim/bfin/dv-bfin_pfmon.c b/sim/bfin/dv-bfin_pfmon.c
index 05eff5f..f97d5079 100644
--- a/sim/bfin/dv-bfin_pfmon.c
+++ b/sim/bfin/dv-bfin_pfmon.c
@@ -53,6 +53,10 @@ bfin_pfmon_io_write_buffer (struct hw *me, const void *source, int space,
   bu32 value;
   bu32 *valuep;
 
+  /* Invalid access mode is higher priority than missing register.  */
+  if (!dv_bfin_mmr_require_32 (me, addr, nr_bytes, true))
+    return 0;
+
   value = dv_load_4 (source);
   mmr_off = addr - pfmon->base;
   valuep = (void *)((unsigned long)pfmon + mmr_base() + mmr_off);
@@ -68,7 +72,7 @@ bfin_pfmon_io_write_buffer (struct hw *me, const void *source, int space,
       break;
     default:
       dv_bfin_mmr_invalid (me, addr, nr_bytes, true);
-      break;
+      return 0;
     }
 
   return nr_bytes;
@@ -83,6 +87,10 @@ bfin_pfmon_io_read_buffer (struct hw *me, void *dest, int space,
   bu32 value;
   bu32 *valuep;
 
+  /* Invalid access mode is higher priority than missing register.  */
+  if (!dv_bfin_mmr_require_32 (me, addr, nr_bytes, false))
+    return 0;
+
   mmr_off = addr - pfmon->base;
   valuep = (void *)((unsigned long)pfmon + mmr_base() + mmr_off);
 
@@ -96,9 +104,8 @@ bfin_pfmon_io_read_buffer (struct hw *me, void *dest, int space,
       value = *valuep;
       break;
     default:
-      while (1) /* Core MMRs -> exception -> doesn't return.  */
-	dv_bfin_mmr_invalid (me, addr, nr_bytes, false);
-      break;
+      dv_bfin_mmr_invalid (me, addr, nr_bytes, false);
+      return 0;
     }
 
   dv_store_4 (dest, value);
diff --git a/sim/bfin/dv-bfin_pint.c b/sim/bfin/dv-bfin_pint.c
index a6b83ec..4eadf9b 100644
--- a/sim/bfin/dv-bfin_pint.c
+++ b/sim/bfin/dv-bfin_pint.c
@@ -63,6 +63,11 @@ bfin_pint_io_write_buffer (struct hw *me, const void *source, int space,
   bu32 value;
   bu32 *valuep;
 
+  /* Invalid access mode is higher priority than missing register.  */
+  /* XXX: The hardware allows 16 or 32 bit accesses ...  */
+  if (!dv_bfin_mmr_require_32 (me, addr, nr_bytes, true))
+    return 0;
+
   if (nr_bytes == 4)
     value = dv_load_4 (source);
   else
@@ -72,9 +77,6 @@ bfin_pint_io_write_buffer (struct hw *me, const void *source, int space,
 
   HW_TRACE_WRITE ();
 
-  /* XXX: The hardware allows 16 or 32 bit accesses ...  */
-  dv_bfin_mmr_require_32 (me, addr, nr_bytes, true);
-
   switch (mmr_off)
     {
     case mmr_offset(request):
@@ -103,7 +105,7 @@ bfin_pint_io_write_buffer (struct hw *me, const void *source, int space,
       break;
     default:
       dv_bfin_mmr_invalid (me, addr, nr_bytes, true);
-      break;
+      return 0;
     }
 
 #if 0
@@ -134,14 +136,16 @@ bfin_pint_io_read_buffer (struct hw *me, void *dest, int space,
   bu32 mmr_off;
   bu32 *valuep;
 
+  /* Invalid access mode is higher priority than missing register.  */
+  /* XXX: The hardware allows 16 or 32 bit accesses ...  */
+  if (!dv_bfin_mmr_require_32 (me, addr, nr_bytes, false))
+    return 0;
+
   mmr_off = addr - pint->base;
   valuep = (void *)((unsigned long)pint + mmr_base() + mmr_off);
 
   HW_TRACE_READ ();
 
-  /* XXX: The hardware allows 16 or 32 bit accesses ...  */
-  dv_bfin_mmr_require_32 (me, addr, nr_bytes, false);
-
   switch (mmr_off)
     {
     case mmr_offset(request):
@@ -164,7 +168,7 @@ bfin_pint_io_read_buffer (struct hw *me, void *dest, int space,
       break;
     default:
       dv_bfin_mmr_invalid (me, addr, nr_bytes, false);
-      break;
+      return 0;
     }
 
   return nr_bytes;
diff --git a/sim/bfin/dv-bfin_pll.c b/sim/bfin/dv-bfin_pll.c
index 7729180..304d01a 100644
--- a/sim/bfin/dv-bfin_pll.c
+++ b/sim/bfin/dv-bfin_pll.c
@@ -59,6 +59,10 @@ bfin_pll_io_write_buffer (struct hw *me, const void *source,
   bu32 *value32p;
   void *valuep;
 
+  /* Invalid access mode is higher priority than missing register.  */
+  if (!dv_bfin_mmr_require_16_32 (me, addr, nr_bytes, true))
+    return 0;
+
   if (nr_bytes == 4)
     value = dv_load_4 (source);
   else
@@ -74,12 +78,14 @@ bfin_pll_io_write_buffer (struct hw *me, const void *source,
   switch (mmr_off)
     {
     case mmr_offset(pll_stat):
-      dv_bfin_mmr_require_16 (me, addr, nr_bytes, true);
+      if (!dv_bfin_mmr_require_16 (me, addr, nr_bytes, true))
+	return 0;
     case mmr_offset(chipid):
       /* Discard writes.  */
       break;
     default:
-      dv_bfin_mmr_require_16 (me, addr, nr_bytes, true);
+      if (!dv_bfin_mmr_require_16 (me, addr, nr_bytes, true))
+	return 0;
       *value16p = value;
       break;
     }
@@ -97,6 +103,10 @@ bfin_pll_io_read_buffer (struct hw *me, void *dest,
   bu16 *value16p;
   void *valuep;
 
+  /* Invalid access mode is higher priority than missing register.  */
+  if (!dv_bfin_mmr_require_16_32 (me, addr, nr_bytes, false))
+    return 0;
+
   mmr_off = addr - pll->base;
   valuep = (void *)((unsigned long)pll + mmr_base() + mmr_off);
   value16p = valuep;
@@ -110,7 +120,8 @@ bfin_pll_io_read_buffer (struct hw *me, void *dest,
       dv_store_4 (dest, *value32p);
       break;
     default:
-      dv_bfin_mmr_require_16 (me, addr, nr_bytes, false);
+      if (!dv_bfin_mmr_require_16 (me, addr, nr_bytes, false))
+	return 0;
       dv_store_2 (dest, *value16p);
       break;
     }
diff --git a/sim/bfin/dv-bfin_ppi.c b/sim/bfin/dv-bfin_ppi.c
index eadcfdb..7014e9a 100644
--- a/sim/bfin/dv-bfin_ppi.c
+++ b/sim/bfin/dv-bfin_ppi.c
@@ -85,14 +85,16 @@ bfin_ppi_io_write_buffer (struct hw *me, const void *source, int space,
   bu32 value;
   bu16 *valuep;
 
+  /* Invalid access mode is higher priority than missing register.  */
+  if (!dv_bfin_mmr_require_16 (me, addr, nr_bytes, true))
+    return 0;
+
   value = dv_load_2 (source);
   mmr_off = addr - ppi->base;
   valuep = (void *)((unsigned long)ppi + mmr_base() + mmr_off);
 
   HW_TRACE_WRITE ();
 
-  dv_bfin_mmr_require_16 (me, addr, nr_bytes, true);
-
   switch (mmr_off)
     {
     case mmr_offset(control):
@@ -109,7 +111,7 @@ bfin_ppi_io_write_buffer (struct hw *me, const void *source, int space,
       break;
     default:
       dv_bfin_mmr_invalid (me, addr, nr_bytes, true);
-      break;
+      return 0;
     }
 
   return nr_bytes;
@@ -123,13 +125,15 @@ bfin_ppi_io_read_buffer (struct hw *me, void *dest, int space,
   bu32 mmr_off;
   bu16 *valuep;
 
+  /* Invalid access mode is higher priority than missing register.  */
+  if (!dv_bfin_mmr_require_16 (me, addr, nr_bytes, false))
+    return 0;
+
   mmr_off = addr - ppi->base;
   valuep = (void *)((unsigned long)ppi + mmr_base() + mmr_off);
 
   HW_TRACE_READ ();
 
-  dv_bfin_mmr_require_16 (me, addr, nr_bytes, false);
-
   switch (mmr_off)
     {
     case mmr_offset(control):
@@ -141,7 +145,7 @@ bfin_ppi_io_read_buffer (struct hw *me, void *dest, int space,
       break;
     default:
       dv_bfin_mmr_invalid (me, addr, nr_bytes, false);
-      break;
+      return 0;
     }
 
   return nr_bytes;
diff --git a/sim/bfin/dv-bfin_rtc.c b/sim/bfin/dv-bfin_rtc.c
index d2220ca..49b6216 100644
--- a/sim/bfin/dv-bfin_rtc.c
+++ b/sim/bfin/dv-bfin_rtc.c
@@ -61,6 +61,10 @@ bfin_rtc_io_write_buffer (struct hw *me, const void *source,
   bu32 *value32p;
   void *valuep;
 
+  /* Invalid access mode is higher priority than missing register.  */
+  if (!dv_bfin_mmr_require_16_32 (me, addr, nr_bytes, true))
+    return 0;
+
   if (nr_bytes == 4)
     value = dv_load_4 (source);
   else
@@ -104,6 +108,10 @@ bfin_rtc_io_read_buffer (struct hw *me, void *dest,
   bu32 *value32p;
   void *valuep;
 
+  /* Invalid access mode is higher priority than missing register.  */
+  if (!dv_bfin_mmr_require_16_32 (me, addr, nr_bytes, false))
+    return 0;
+
   mmr_off = addr - rtc->base;
   valuep = (void *)((unsigned long)rtc + mmr_base() + mmr_off);
   value16p = valuep;
diff --git a/sim/bfin/dv-bfin_sic.c b/sim/bfin/dv-bfin_sic.c
index 3978543..3518581 100644
--- a/sim/bfin/dv-bfin_sic.c
+++ b/sim/bfin/dv-bfin_sic.c
@@ -150,6 +150,10 @@ bfin_sic_52x_io_write_buffer (struct hw *me, const void *source, int space,
   bu32 *value32p;
   void *valuep;
 
+  /* Invalid access mode is higher priority than missing register.  */
+  if (!dv_bfin_mmr_require_16_32 (me, addr, nr_bytes, true))
+    return 0;
+
   if (nr_bytes == 4)
     value = dv_load_4 (source);
   else
@@ -204,6 +208,10 @@ bfin_sic_52x_io_read_buffer (struct hw *me, void *dest, int space,
   bu32 *value32p;
   void *valuep;
 
+  /* Invalid access mode is higher priority than missing register.  */
+  if (!dv_bfin_mmr_require_16_32 (me, addr, nr_bytes, false))
+    return 0;
+
   mmr_off = addr - sic->base;
   valuep = (void *)((unsigned long)sic + mmr_base() + mmr_off);
   value16p = valuep;
@@ -256,6 +264,10 @@ bfin_sic_537_io_write_buffer (struct hw *me, const void *source, int space,
   bu32 *value32p;
   void *valuep;
 
+  /* Invalid access mode is higher priority than missing register.  */
+  if (!dv_bfin_mmr_require_16_32 (me, addr, nr_bytes, true))
+    return 0;
+
   if (nr_bytes == 4)
     value = dv_load_4 (source);
   else
@@ -309,6 +321,10 @@ bfin_sic_537_io_read_buffer (struct hw *me, void *dest, int space,
   bu32 *value32p;
   void *valuep;
 
+  /* Invalid access mode is higher priority than missing register.  */
+  if (!dv_bfin_mmr_require_16_32 (me, addr, nr_bytes, false))
+    return 0;
+
   mmr_off = addr - sic->base;
   valuep = (void *)((unsigned long)sic + mmr_base() + mmr_off);
   value16p = valuep;
@@ -362,6 +378,10 @@ bfin_sic_54x_io_write_buffer (struct hw *me, const void *source, int space,
   bu32 *value32p;
   void *valuep;
 
+  /* Invalid access mode is higher priority than missing register.  */
+  if (!dv_bfin_mmr_require_16_32 (me, addr, nr_bytes, true))
+    return 0;
+
   if (nr_bytes == 4)
     value = dv_load_4 (source);
   else
@@ -412,6 +432,10 @@ bfin_sic_54x_io_read_buffer (struct hw *me, void *dest, int space,
   bu32 *value32p;
   void *valuep;
 
+  /* Invalid access mode is higher priority than missing register.  */
+  if (!dv_bfin_mmr_require_16_32 (me, addr, nr_bytes, false))
+    return 0;
+
   mmr_off = addr - sic->base;
   valuep = (void *)((unsigned long)sic + mmr_base() + mmr_off);
   value16p = valuep;
@@ -461,6 +485,10 @@ bfin_sic_561_io_write_buffer (struct hw *me, const void *source, int space,
   bu32 *value32p;
   void *valuep;
 
+  /* Invalid access mode is higher priority than missing register.  */
+  if (!dv_bfin_mmr_require_16_32 (me, addr, nr_bytes, true))
+    return 0;
+
   if (nr_bytes == 4)
     value = dv_load_4 (source);
   else
@@ -515,6 +543,10 @@ bfin_sic_561_io_read_buffer (struct hw *me, void *dest, int space,
   bu32 *value32p;
   void *valuep;
 
+  /* Invalid access mode is higher priority than missing register.  */
+  if (!dv_bfin_mmr_require_16_32 (me, addr, nr_bytes, false))
+    return 0;
+
   mmr_off = addr - sic->base;
   valuep = (void *)((unsigned long)sic + mmr_base() + mmr_off);
   value16p = valuep;
diff --git a/sim/bfin/dv-bfin_spi.c b/sim/bfin/dv-bfin_spi.c
index 56a8f93..b4c68ca 100644
--- a/sim/bfin/dv-bfin_spi.c
+++ b/sim/bfin/dv-bfin_spi.c
@@ -77,14 +77,16 @@ bfin_spi_io_write_buffer (struct hw *me, const void *source, int space,
   bu32 value;
   bu16 *valuep;
 
+  /* Invalid access mode is higher priority than missing register.  */
+  if (!dv_bfin_mmr_require_16 (me, addr, nr_bytes, true))
+    return 0;
+
   value = dv_load_2 (source);
   mmr_off = addr - spi->base;
   valuep = (void *)((unsigned long)spi + mmr_base() + mmr_off);
 
   HW_TRACE_WRITE ();
 
-  dv_bfin_mmr_require_16 (me, addr, nr_bytes, true);
-
   switch (mmr_off)
     {
     case mmr_offset(stat):
@@ -107,7 +109,7 @@ bfin_spi_io_write_buffer (struct hw *me, const void *source, int space,
       break;
     default:
       dv_bfin_mmr_invalid (me, addr, nr_bytes, true);
-      break;
+      return 0;
     }
 
   return nr_bytes;
@@ -121,13 +123,15 @@ bfin_spi_io_read_buffer (struct hw *me, void *dest, int space,
   bu32 mmr_off;
   bu16 *valuep;
 
+  /* Invalid access mode is higher priority than missing register.  */
+  if (!dv_bfin_mmr_require_16 (me, addr, nr_bytes, false))
+    return 0;
+
   mmr_off = addr - spi->base;
   valuep = (void *)((unsigned long)spi + mmr_base() + mmr_off);
 
   HW_TRACE_READ ();
 
-  dv_bfin_mmr_require_16 (me, addr, nr_bytes, false);
-
   switch (mmr_off)
     {
     case mmr_offset(rdbr):
@@ -145,7 +149,7 @@ bfin_spi_io_read_buffer (struct hw *me, void *dest, int space,
       break;
     default:
       dv_bfin_mmr_invalid (me, addr, nr_bytes, false);
-      break;
+      return 0;
     }
 
   return nr_bytes;
diff --git a/sim/bfin/dv-bfin_trace.c b/sim/bfin/dv-bfin_trace.c
index 8358224..b6bed4d 100644
--- a/sim/bfin/dv-bfin_trace.c
+++ b/sim/bfin/dv-bfin_trace.c
@@ -80,6 +80,10 @@ bfin_trace_io_write_buffer (struct hw *me, const void *source,
   bu32 mmr_off;
   bu32 value;
 
+  /* Invalid access mode is higher priority than missing register.  */
+  if (!dv_bfin_mmr_require_32 (me, addr, nr_bytes, true))
+    return 0;
+
   value = dv_load_4 (source);
   mmr_off = addr - trace->base;
 
@@ -96,7 +100,7 @@ bfin_trace_io_write_buffer (struct hw *me, const void *source,
       break;
     default:
       dv_bfin_mmr_invalid (me, addr, nr_bytes, true);
-      break;
+      return 0;
     }
 
   return nr_bytes;
@@ -110,6 +114,10 @@ bfin_trace_io_read_buffer (struct hw *me, void *dest,
   bu32 mmr_off;
   bu32 value;
 
+  /* Invalid access mode is higher priority than missing register.  */
+  if (!dv_bfin_mmr_require_32 (me, addr, nr_bytes, false))
+    return 0;
+
   mmr_off = addr - trace->base;
 
   HW_TRACE_READ ();
@@ -148,9 +156,8 @@ bfin_trace_io_read_buffer (struct hw *me, void *dest,
 	break;
       }
     default:
-      while (1) /* Core MMRs -> exception -> doesn't return.  */
-	dv_bfin_mmr_invalid (me, addr, nr_bytes, false);
-      break;
+      dv_bfin_mmr_invalid (me, addr, nr_bytes, false);
+      return 0;
     }
 
   dv_store_4 (dest, value);
diff --git a/sim/bfin/dv-bfin_twi.c b/sim/bfin/dv-bfin_twi.c
index e1b4cde..6ceb7f9 100644
--- a/sim/bfin/dv-bfin_twi.c
+++ b/sim/bfin/dv-bfin_twi.c
@@ -81,14 +81,16 @@ bfin_twi_io_write_buffer (struct hw *me, const void *source, int space,
   bu32 value;
   bu16 *valuep;
 
+  /* Invalid access mode is higher priority than missing register.  */
+  if (!dv_bfin_mmr_require_16 (me, addr, nr_bytes, true))
+    return 0;
+
   value = dv_load_2 (source);
   mmr_off = addr - twi->base;
   valuep = (void *)((unsigned long)twi + mmr_base() + mmr_off);
 
   HW_TRACE_WRITE ();
 
-  dv_bfin_mmr_require_16 (me, addr, nr_bytes, true);
-
   switch (mmr_off)
     {
     case mmr_offset(clkdiv):
@@ -120,7 +122,7 @@ bfin_twi_io_write_buffer (struct hw *me, const void *source, int space,
       break;
     default:
       dv_bfin_mmr_invalid (me, addr, nr_bytes, true);
-      break;
+      return 0;
     }
 
   return nr_bytes;
@@ -134,13 +136,15 @@ bfin_twi_io_read_buffer (struct hw *me, void *dest, int space,
   bu32 mmr_off;
   bu16 *valuep;
 
+  /* Invalid access mode is higher priority than missing register.  */
+  if (!dv_bfin_mmr_require_16 (me, addr, nr_bytes, false))
+    return 0;
+
   mmr_off = addr - twi->base;
   valuep = (void *)((unsigned long)twi + mmr_base() + mmr_off);
 
   HW_TRACE_READ ();
 
-  dv_bfin_mmr_require_16 (me, addr, nr_bytes, false);
-
   switch (mmr_off)
     {
     case mmr_offset(clkdiv):
@@ -168,7 +172,7 @@ bfin_twi_io_read_buffer (struct hw *me, void *dest, int space,
       break;
     default:
       dv_bfin_mmr_invalid (me, addr, nr_bytes, false);
-      break;
+      return 0;
     }
 
   return nr_bytes;
diff --git a/sim/bfin/dv-bfin_uart.c b/sim/bfin/dv-bfin_uart.c
index 0460ca5..10cf7e1 100644
--- a/sim/bfin/dv-bfin_uart.c
+++ b/sim/bfin/dv-bfin_uart.c
@@ -138,14 +138,16 @@ bfin_uart_io_write_buffer (struct hw *me, const void *source,
   bu32 value;
   bu16 *valuep;
 
+  /* Invalid access mode is higher priority than missing register.  */
+  if (!dv_bfin_mmr_require_16 (me, addr, nr_bytes, true))
+    return 0;
+
   value = dv_load_2 (source);
   mmr_off = addr - uart->base;
   valuep = (void *)((unsigned long)uart + mmr_base() + mmr_off);
 
   HW_TRACE_WRITE ();
 
-  dv_bfin_mmr_require_16 (me, addr, nr_bytes, true);
-
   /* XXX: All MMRs are "8bit" ... what happens to high 8bits ?  */
   switch (mmr_off)
     {
@@ -181,7 +183,7 @@ bfin_uart_io_write_buffer (struct hw *me, const void *source,
       break;
     default:
       dv_bfin_mmr_invalid (me, addr, nr_bytes, true);
-      break;
+      return 0;
     }
 
   return nr_bytes;
@@ -260,13 +262,15 @@ bfin_uart_io_read_buffer (struct hw *me, void *dest,
   bu32 mmr_off;
   bu16 *valuep;
 
+  /* Invalid access mode is higher priority than missing register.  */
+  if (!dv_bfin_mmr_require_16 (me, addr, nr_bytes, false))
+    return 0;
+
   mmr_off = addr - uart->base;
   valuep = (void *)((unsigned long)uart + mmr_base() + mmr_off);
 
   HW_TRACE_READ ();
 
-  dv_bfin_mmr_require_16 (me, addr, nr_bytes, false);
-
   switch (mmr_off)
     {
     case mmr_offset(dll):
@@ -300,7 +304,7 @@ bfin_uart_io_read_buffer (struct hw *me, void *dest,
       break;
     default:
       dv_bfin_mmr_invalid (me, addr, nr_bytes, false);
-      break;
+      return 0;
     }
 
   return nr_bytes;
diff --git a/sim/bfin/dv-bfin_uart2.c b/sim/bfin/dv-bfin_uart2.c
index 40a7edd..59716b9 100644
--- a/sim/bfin/dv-bfin_uart2.c
+++ b/sim/bfin/dv-bfin_uart2.c
@@ -76,14 +76,16 @@ bfin_uart_io_write_buffer (struct hw *me, const void *source,
   bu32 value;
   bu16 *valuep;
 
+  /* Invalid access mode is higher priority than missing register.  */
+  if (!dv_bfin_mmr_require_16 (me, addr, nr_bytes, true))
+    return 0;
+
   value = dv_load_2 (source);
   mmr_off = addr - uart->base;
   valuep = (void *)((unsigned long)uart + mmr_base() + mmr_off);
 
   HW_TRACE_WRITE ();
 
-  dv_bfin_mmr_require_16 (me, addr, nr_bytes, true);
-
   /* XXX: All MMRs are "8bit" ... what happens to high 8bits ?  */
 
   switch (mmr_off)
@@ -118,7 +120,7 @@ bfin_uart_io_write_buffer (struct hw *me, const void *source,
       break;
     default:
       dv_bfin_mmr_invalid (me, addr, nr_bytes, true);
-      break;
+      return 0;
     }
 
   return nr_bytes;
@@ -132,13 +134,15 @@ bfin_uart_io_read_buffer (struct hw *me, void *dest,
   bu32 mmr_off;
   bu16 *valuep;
 
+  /* Invalid access mode is higher priority than missing register.  */
+  if (!dv_bfin_mmr_require_16 (me, addr, nr_bytes, false))
+    return 0;
+
   mmr_off = addr - uart->base;
   valuep = (void *)((unsigned long)uart + mmr_base() + mmr_off);
 
   HW_TRACE_READ ();
 
-  dv_bfin_mmr_require_16 (me, addr, nr_bytes, false);
-
   switch (mmr_off)
     {
     case mmr_offset(rbr):
@@ -165,7 +169,7 @@ bfin_uart_io_read_buffer (struct hw *me, void *dest,
       break;
     default:
       dv_bfin_mmr_invalid (me, addr, nr_bytes, false);
-      break;
+      return 0;
     }
 
   return nr_bytes;
diff --git a/sim/bfin/dv-bfin_wdog.c b/sim/bfin/dv-bfin_wdog.c
index d34bfa1..53d1692 100644
--- a/sim/bfin/dv-bfin_wdog.c
+++ b/sim/bfin/dv-bfin_wdog.c
@@ -61,6 +61,10 @@ bfin_wdog_io_write_buffer (struct hw *me, const void *source,
   bu32 *value32p;
   void *valuep;
 
+  /* Invalid access mode is higher priority than missing register.  */
+  if (!dv_bfin_mmr_require_16_32 (me, addr, nr_bytes, true))
+    return 0;
+
   if (nr_bytes == 4)
     value = dv_load_4 (source);
   else
@@ -111,6 +115,10 @@ bfin_wdog_io_read_buffer (struct hw *me, void *dest,
   bu32 *value32p;
   void *valuep;
 
+  /* Invalid access mode is higher priority than missing register.  */
+  if (!dv_bfin_mmr_require_16_32 (me, addr, nr_bytes, false))
+    return 0;
+
   mmr_off = addr - wdog->base;
   valuep = (void *)((unsigned long)wdog + mmr_base() + mmr_off);
   value16p = valuep;
@@ -121,7 +129,8 @@ bfin_wdog_io_read_buffer (struct hw *me, void *dest,
   switch (mmr_off)
     {
     case mmr_offset(ctl):
-      dv_bfin_mmr_require_16 (me, addr, nr_bytes, false);
+      if (!dv_bfin_mmr_require_16 (me, addr, nr_bytes, false))
+	return 0;
       dv_store_2 (dest, *value16p);
       break;
 
diff --git a/sim/bfin/dv-bfin_wp.c b/sim/bfin/dv-bfin_wp.c
index 5292cb2..17dc979 100644
--- a/sim/bfin/dv-bfin_wp.c
+++ b/sim/bfin/dv-bfin_wp.c
@@ -77,6 +77,10 @@ bfin_wp_io_write_buffer (struct hw *me, const void *source, int space,
   bu32 value;
   bu32 *valuep;
 
+  /* Invalid access mode is higher priority than missing register.  */
+  if (!dv_bfin_mmr_require_32 (me, addr, nr_bytes, true))
+    return 0;
+
   value = dv_load_4 (source);
   mmr_off = addr - wp->base;
   valuep = (void *)((unsigned long)wp + mmr_base() + mmr_off);
@@ -99,7 +103,7 @@ bfin_wp_io_write_buffer (struct hw *me, const void *source, int space,
       break;
     default:
       dv_bfin_mmr_invalid (me, addr, nr_bytes, true);
-      break;
+      return 0;
     }
 
   return nr_bytes;
@@ -114,6 +118,10 @@ bfin_wp_io_read_buffer (struct hw *me, void *dest, int space,
   bu32 value;
   bu32 *valuep;
 
+  /* Invalid access mode is higher priority than missing register.  */
+  if (!dv_bfin_mmr_require_32 (me, addr, nr_bytes, false))
+    return 0;
+
   mmr_off = addr - wp->base;
   valuep = (void *)((unsigned long)wp + mmr_base() + mmr_off);
 
@@ -131,9 +139,8 @@ bfin_wp_io_read_buffer (struct hw *me, void *dest, int space,
       value = *valuep;
       break;
     default:
-      while (1) /* Core MMRs -> exception -> doesn't return.  */
-	dv_bfin_mmr_invalid (me, addr, nr_bytes, false);
-      break;
+      dv_bfin_mmr_invalid (me, addr, nr_bytes, false);
+      return 0;
     }
 
   dv_store_4 (dest, value);
diff --git a/sim/bfin/tconfig.h b/sim/bfin/tconfig.h
deleted file mode 100644
index 3ecd174..0000000
--- a/sim/bfin/tconfig.h
+++ /dev/null
@@ -1,5 +0,0 @@
-/* Blackfin target configuration file.  -*- C -*- */
-
-/* We use this so that we are passed the requesting CPU for HW acesses.
-   Common sim core by default sets hw_system_cpu to NULL for WITH_HW.  */
-#define WITH_DEVICES 1
