diff --git a/sim/cris/ChangeLog b/sim/cris/ChangeLog
index 6fa2523..3768768 100644
--- a/sim/cris/ChangeLog
+++ b/sim/cris/ChangeLog
@@ -1,5 +1,17 @@
 2015-12-25  Mike Frysinger  <vapier@gentoo.org>
 
+	* configure.ac (SIM_AC_OPTION_HARDWARE): Change default to yes and
+	add cris_900000xx.
+	* configure: Regenerated.
+	* devices.c: Delete file.
+	* dv-cris_900000xx.c: New device model.
+	* Makefile.in (SIM_OBJS): Delete devices.o.
+	* sim-if.c (sim_open): Replace cris_have_900000xxif logic with a
+	call to sim_hw_parse.
+	* tconfig.h: Delete file.
+
+2015-12-25  Mike Frysinger  <vapier@gentoo.org>
+
 	* rvdummy.c (_GNU_SOURCE): Delete.
 	(setupsocket): Mark static.
 
diff --git a/sim/cris/Makefile.in b/sim/cris/Makefile.in
index 384922f..a0520ac 100644
--- a/sim/cris/Makefile.in
+++ b/sim/cris/Makefile.in
@@ -29,7 +29,7 @@ SIM_OBJS = \
 	sim-if.o arch.o \
 	$(CRISV10F_OBJS) \
 	$(CRISV32F_OBJS) \
-	traps.o devices.o \
+	traps.o \
 	cris-desc.o
 
 # Extra headers included by sim-main.h.
diff --git a/sim/cris/configure b/sim/cris/configure
index a40197f..46daa18 100755
--- a/sim/cris/configure
+++ b/sim/cris/configure
@@ -13362,7 +13362,7 @@ if test ""; then
 else
   hardware="cfi core pal glue"
 fi
-hardware="$hardware rv cris"
+hardware="$hardware rv cris cris_900000xx"
 
 sim_hw_cflags="-DWITH_HW=1"
 sim_hw="$hardware"
@@ -13372,7 +13372,7 @@ sim_hw_objs="\$(SIM_COMMON_HW_OBJS) `echo $sim_hw | sed -e 's/\([^ ][^ ]*\)/dv-\
 if test "${enable_sim_hardware+set}" = set; then :
   enableval=$enable_sim_hardware;
 else
-  enable_sim_hardware="no"
+  enable_sim_hardware="yes"
 fi
 
 case ${enable_sim_hardware} in
diff --git a/sim/cris/configure.ac b/sim/cris/configure.ac
index 2e9050e..4543342 100644
--- a/sim/cris/configure.ac
+++ b/sim/cris/configure.ac
@@ -12,7 +12,7 @@ SIM_AC_OPTION_ALIGNMENT(NONSTRICT_ALIGNMENT)
 SIM_AC_OPTION_HOSTENDIAN
 SIM_AC_OPTION_SCACHE(16384)
 SIM_AC_OPTION_WARNINGS
-SIM_AC_OPTION_HARDWARE(no,,rv cris)
+SIM_AC_OPTION_HARDWARE(yes,,rv cris cris_900000xx)
 
 # The default model shouldn't matter as long as there's a BFD.
 SIM_AC_OPTION_DEFAULT_MODEL(crisv32)
diff --git a/sim/cris/devices.c b/sim/cris/devices.c
deleted file mode 100644
index 56cdfed..0000000
--- a/sim/cris/devices.c
+++ /dev/null
@@ -1,79 +0,0 @@
-/* CRIS device support
-   Copyright (C) 2004-2015 Free Software Foundation, Inc.
-   Contributed by Axis Communications.
-
-This file is part of the GNU simulators.
-
-This program is free software; you can redistribute it and/or modify
-it under the terms of the GNU General Public License as published by
-the Free Software Foundation; either version 3 of the License, or
-(at your option) any later version.
-
-This program is distributed in the hope that it will be useful,
-but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-GNU General Public License for more details.
-
-You should have received a copy of the GNU General Public License
-along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
-
-/* Based on the i960 devices.c (for the purposes, the same as all the
-   others).  */
-
-#include "sim-main.h"
-
-#ifdef HAVE_DV_SOCKSER
-#include "dv-sockser.h"
-#endif
-
-#include "hw-device.h"
-
-/* Placeholder definition.  */
-struct _device { char dummy; } cris_devices;
-
-int
-device_io_read_buffer (device *me ATTRIBUTE_UNUSED,
-		       void *source ATTRIBUTE_UNUSED,
-		       int space ATTRIBUTE_UNUSED,
-		       address_word addr ATTRIBUTE_UNUSED,
-		       unsigned nr_bytes ATTRIBUTE_UNUSED,
-		       SIM_DESC sd ATTRIBUTE_UNUSED,
-		       SIM_CPU *cpu ATTRIBUTE_UNUSED,
-		       sim_cia cia ATTRIBUTE_UNUSED)
-{
-#if WITH_HW
-  return hw_io_read_buffer ((struct hw *) me, source, space, addr, nr_bytes);
-#else
-  abort ();
-#endif
-}
-
-int
-device_io_write_buffer (device *me ATTRIBUTE_UNUSED,
-			const void *source,
-			int space ATTRIBUTE_UNUSED,
-			address_word addr, unsigned nr_bytes,
-			SIM_DESC sd, SIM_CPU *cpu, sim_cia cia)
-{
-  static const unsigned char ok[] = { 4, 0, 0, 0x90};
-  static const unsigned char bad[] = { 8, 0, 0, 0x90};
-
-  if (cris_have_900000xxif)
-    {
-      if (addr == 0x90000004 && memcmp (source, ok, sizeof ok) == 0)
-	return cris_break_13_handler (cpu, 1, 0, 0, 0, 0, 0, 0, cia);
-      else if (addr == 0x90000008
-	       && memcmp (source, bad, sizeof bad) == 0)
-	return cris_break_13_handler (cpu, 1, 34, 0, 0, 0, 0, 0, cia);
-    }
-#if WITH_HW
-  else
-    return hw_io_write_buffer ((struct hw *) me, source, space, addr, nr_bytes);
-#endif
-
-  /* If it wasn't one of those, send an invalid-memory signal.  */
-  sim_core_signal (sd, cpu, cia, 0, nr_bytes, addr,
-		   write_transfer, sim_core_unmapped_signal);
-
-  return 0;
-}
diff --git a/sim/cris/dv-cris_900000xx.c b/sim/cris/dv-cris_900000xx.c
new file mode 100644
index 0000000..5525e60
--- /dev/null
+++ b/sim/cris/dv-cris_900000xx.c
@@ -0,0 +1,91 @@
+/* Handle 0x900000xx addresses in the sim.
+
+   Copyright (C) 2004-2015 Free Software Foundation, Inc.
+   Contributed by Axis Communications.
+
+   This file is part of the GNU simulators.
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 3 of the License, or
+   (at your option) any later version.
+
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
+
+#include "sim-main.h"
+#include "hw-main.h"
+
+struct cris_900000xx_hw
+{
+};
+
+static unsigned
+cris_io_write_buffer (struct hw *me, const void *source,
+		      int space, address_word addr, unsigned nr_bytes)
+{
+  static const unsigned char ok[] = { 4, 0, 0, 0x90};
+  static const unsigned char bad[] = { 8, 0, 0, 0x90};
+  SIM_CPU *cpu = hw_system_cpu (me);
+  SIM_DESC sd = CPU_STATE (cpu);
+  sim_cia cia = CPU_PC_GET (cpu);
+
+  if (addr == 0x90000004 && memcmp (source, ok, sizeof ok) == 0)
+    return cris_break_13_handler (cpu, 1, 0, 0, 0, 0, 0, 0, cia);
+  else if (addr == 0x90000008
+	   && memcmp (source, bad, sizeof bad) == 0)
+    return cris_break_13_handler (cpu, 1, 34, 0, 0, 0, 0, 0, cia);
+
+  /* If it wasn't one of those, send an invalid-memory signal.  */
+  sim_core_signal (sd, cpu, cia, 0, nr_bytes, addr,
+		   write_transfer, sim_core_unmapped_signal);
+
+  return 0;
+}
+
+/* Instance initializer function.  */
+
+static void
+attach_regs (struct hw *me, struct cris_900000xx_hw *hw)
+{
+  address_word attach_address;
+  int attach_space;
+  unsigned attach_size;
+  reg_property_spec reg;
+
+  if (hw_find_property (me, "reg") == NULL)
+    hw_abort (me, "Missing \"reg\" property");
+
+  if (!hw_find_reg_array_property (me, "reg", 0, &reg))
+    hw_abort (me, "\"reg\" property must contain three addr/size entries");
+
+  hw_unit_address_to_attach_address (hw_parent (me),
+				     &reg.address,
+				     &attach_space, &attach_address, me);
+  hw_unit_size_to_attach_size (hw_parent (me), &reg.size, &attach_size, me);
+
+  hw_attach_address (hw_parent (me),
+		     0, attach_space, attach_address, attach_size, me);
+}
+
+static void
+cris_900000xx_finish (struct hw *me)
+{
+  struct cris_900000xx_hw *hw;
+
+  hw = HW_ZALLOC (me, struct cris_900000xx_hw);
+  set_hw_data (me, hw);
+  set_hw_io_write_buffer (me, cris_io_write_buffer);
+
+  attach_regs (me, hw);
+}
+
+const struct hw_descriptor dv_cris_900000xx_descriptor[] = {
+  { "cris_900000xx", cris_900000xx_finish, },
+  { NULL },
+};
diff --git a/sim/cris/sim-if.c b/sim/cris/sim-if.c
index 115ff21..3e04655 100644
--- a/sim/cris/sim-if.c
+++ b/sim/cris/sim-if.c
@@ -977,18 +977,7 @@ sim_open (SIM_OPEN_KIND kind, host_callback *callback, struct bfd *abfd,
 
   /* Allocate simulator I/O managed memory if none specified by user.  */
   if (cris_have_900000xxif)
-    {
-      if (sim_core_read_buffer (sd, NULL, read_map, &c, 0x90000000, 1) == 0)
-	sim_core_attach (sd, NULL, 0, access_write, 0, 0x90000000, 0x100,
-			 0, &cris_devices, NULL);
-      else
-	{
-	  (*callback->
-	   printf_filtered) (callback,
-			     "Seeing --cris-900000xx with memory defined there\n");
-	  goto abandon_chip;
-	}
-    }
+    sim_hw_parse (sd, "/core/%s/reg %#x %i", "cris_900000xx", 0x90000000, 0x100);
 
   /* Establish any remaining configuration options.  */
   if (sim_config (sd) != SIM_RC_OK)
diff --git a/sim/cris/tconfig.h b/sim/cris/tconfig.h
deleted file mode 100644
index 2ac6c5b..0000000
--- a/sim/cris/tconfig.h
+++ /dev/null
@@ -1,30 +0,0 @@
-/* CRIS target configuration file.  -*- C -*-
-   Copyright (C) 2004-2015 Free Software Foundation, Inc.
-   Contributed by Axis Communications.
-
-This file is part of the GNU simulators.
-
-This program is free software; you can redistribute it and/or modify
-it under the terms of the GNU General Public License as published by
-the Free Software Foundation; either version 3 of the License, or
-(at your option) any later version.
-
-This program is distributed in the hope that it will be useful,
-but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-GNU General Public License for more details.
-
-You should have received a copy of the GNU General Public License
-along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
-
-#ifndef CRIS_TCONFIG_H
-#define CRIS_TCONFIG_H
-
-/* There's basically a a big ??? FIXME: CHECK THIS on everything in this
-   file.  I just copied it from m32r, pruned some stuff and added
-   HAVE_MODEL because it seemed useful.  */
-
-/* For MSPR support.  FIXME: revisit.  */
-#define WITH_DEVICES 1
-
-#endif /* CRIS_TCONFIG_H */
diff --git a/sim/testsuite/sim/cris/ChangeLog b/sim/testsuite/sim/cris/ChangeLog
index 22fb88a..fa34863 100644
--- a/sim/testsuite/sim/cris/ChangeLog
+++ b/sim/testsuite/sim/cris/ChangeLog
@@ -1,5 +1,9 @@
 2015-12-25  Mike Frysinger  <vapier@gentoo.org>
 
+	* asm/io1.ms: Update expected output.
+
+2015-12-25  Mike Frysinger  <vapier@gentoo.org>
+
 	* hw/rv-n-cris/rvc.exp (rvdummy): Set up sane default.
 
 2012-03-24  Mike Frysinger  <vapier@gentoo.org>
diff --git a/sim/testsuite/sim/cris/asm/io1.ms b/sim/testsuite/sim/cris/asm/io1.ms
index a8335a8..3d252ae 100644
--- a/sim/testsuite/sim/cris/asm/io1.ms
+++ b/sim/testsuite/sim/cris/asm/io1.ms
@@ -1,7 +1,7 @@
 # mach: crisv32
 # sim: --cris-900000xx --memory-region 0x90000000,0x10
 # xerror:
-# output: Seeing --cris-900000xx with memory defined there\n
+# output: /core/cris_900000xx: memory map 0:0x90000000..0x900000ff (256 bytes) overlaps 0:0x90000000..0x9000000f (16 bytes)\nQuit Simulator\n
 
 ; Check that I/O region overlap is detected.
 
