commit 1ad2134f914dfd4c8f92307c94c9a5a1e28f0059
Author: Paul Brook <paul@codesourcery.com>
Date:   Tue May 19 16:17:58 2009 +0100

    Hardware convenience library
    
    The only target dependency for most hardware is sizeof(target_phys_addr_t).
    Build these files into a convenience library, and use that instead of
    building for every target.
    
    Remove and poison various target specific macros to avoid bogus target
    dependencies creeping back in.
    
    Big/Little endian is not handled because devices should not know or care
    about this to start with.
    
    Signed-off-by: Paul Brook <paul@codesourcery.com>

diff --git a/.gitignore b/.gitignore
index f38bb30..bd7b808 100644
--- a/.gitignore
+++ b/.gitignore
@@ -4,6 +4,8 @@ i386
 *-darwin-user
 *-linux-user
 *-bsd-user
+libhw32
+libhw64
 qemu-doc.html
 qemu-tech.html
 qemu-doc.info
diff --git a/Makefile b/Makefile
index f303aff..bbb5e91 100644
--- a/Makefile
+++ b/Makefile
@@ -1,6 +1,8 @@
 # Makefile for QEMU.
 
 ifneq ($(wildcard config-host.mak),)
+# Put the all: rule here so that config-host.mak can contain dependencies.
+all: build-all
 include config-host.mak
 include $(SRC_PATH)/rules.mak
 else
@@ -41,7 +43,7 @@ ifdef CONFIG_WIN32
 LIBS+=-lwinmm -lws2_32 -liphlpapi
 endif
 
-all: $(TOOLS) $(DOCS) recurse-all
+build-all: $(TOOLS) $(DOCS) recurse-all
 
 config-host.mak: configure
 ifneq ($(wildcard config-host.mak),)
@@ -237,14 +239,14 @@ clean:
 	rm -f *.o *.d *.a $(TOOLS) TAGS cscope.* *.pod *~ */*~
 	rm -f slirp/*.o slirp/*.d audio/*.o audio/*.d block/*.o block/*.d
 	$(MAKE) -C tests clean
-	for d in $(TARGET_DIRS); do \
+	for d in $(TARGET_DIRS) libhw32 libhw64; do \
 	$(MAKE) -C $$d $@ || exit 1 ; \
         done
 
 distclean: clean
 	rm -f config-host.mak config-host.h $(DOCS) qemu-options.texi
 	rm -f qemu-{doc,tech}.{info,aux,cp,dvi,fn,info,ky,log,pg,toc,tp,vr}
-	for d in $(TARGET_DIRS); do \
+	for d in $(TARGET_DIRS) libhw32 libhw64; do \
 	rm -rf $$d || exit 1 ; \
         done
 
diff --git a/Makefile.hw b/Makefile.hw
new file mode 100644
index 0000000..a8c7174
--- /dev/null
+++ b/Makefile.hw
@@ -0,0 +1,36 @@
+# Makefile for qemu target independent devices.
+
+include config.mak
+include ../config-host.mak
+include $(SRC_PATH)/rules.mak
+
+.PHONY: all
+
+VPATH=$(SRC_PATH):$(SRC_PATH)/hw
+
+CFLAGS += $(OS_CFLAGS) $(ARCH_CFLAGS)
+LDFLAGS += $(OS_LDFLAGS) $(ARCH_LDFLAGS)
+
+CPPFLAGS += -I. -I$(SRC_PATH) -MMD -MP -MT $@
+CPPFLAGS += -D_GNU_SOURCE -D_FILE_OFFSET_BITS=64 -D_LARGEFILE_SOURCE
+CPPFLAGS+=-I$(SRC_PATH)/fpu
+
+OBJS=
+OBJS+= virtio.o virtio-pci.o
+OBJS+= fw_cfg.o
+OBJS+= watchdog.o
+OBJS+= nand.o ecc.o
+
+OBJS+= m48t59.o
+
+OBJS+= dma-helpers.o sysbus.o
+
+all: $(HWLIB)
+
+$(HWLIB): $(OBJS)
+
+clean:
+	rm -f *.o *.d *.a *~
+
+# Include automatically generated dependency files
+-include $(wildcard *.d */*.d)
diff --git a/Makefile.target b/Makefile.target
index 4f7f47d..60dcf30 100644
--- a/Makefile.target
+++ b/Makefile.target
@@ -485,13 +485,11 @@ endif #CONFIG_BSD_USER
 # System emulator target
 ifndef CONFIG_USER_ONLY
 
-OBJS=vl.o osdep.o monitor.o pci.o loader.o isa_mmio.o machine.o dma-helpers.o \
-     gdbstub.o gdbstub-xml.o sysbus.o
+OBJS=vl.o osdep.o monitor.o pci.o loader.o isa_mmio.o machine.o \
+     gdbstub.o gdbstub-xml.o
 # virtio has to be here due to weird dependency between PCI and virtio-net.
 # need to fix this properly
-OBJS+=virtio.o virtio-pci.o
 OBJS+=virtio-blk.o virtio-balloon.o virtio-net.o virtio-console.o
-OBJS+=fw_cfg.o
 ifdef CONFIG_KVM
 OBJS+=kvm.o kvm-all.o
 endif
@@ -564,7 +562,6 @@ OBJS += rtl8139.o
 OBJS += e1000.o
 
 # Generic watchdog support and some watchdog devices
-OBJS += watchdog.o
 OBJS += wdt_ib700.o wdt_i6300esb.o
 
 ifeq ($(TARGET_BASE_ARCH), i386)
@@ -581,7 +578,7 @@ CPPFLAGS += -DHAS_AUDIO -DHAS_AUDIO_CHOICE
 # shared objects
 OBJS+= ppc.o ide.o vga.o $(SOUND_HW) dma.o openpic.o
 # PREP target
-OBJS+= pckbd.o serial.o i8259.o i8254.o fdc.o m48t59.o mc146818rtc.o
+OBJS+= pckbd.o serial.o i8259.o i8254.o fdc.o mc146818rtc.o
 OBJS+= prep_pci.o ppc_prep.o
 # Mac shared devices
 OBJS+= macio.o cuda.o adb.o mac_nvram.o mac_dbdma.o escc.o
@@ -624,15 +621,15 @@ OBJS+= etraxfs_eth.o
 OBJS+= etraxfs_timer.o
 OBJS+= etraxfs_ser.o
 
-OBJS+= pflash_cfi02.o nand.o
+OBJS+= pflash_cfi02.o
 endif
 ifeq ($(TARGET_BASE_ARCH), sparc)
 ifeq ($(TARGET_ARCH), sparc64)
 OBJS+= sun4u.o ide.o pckbd.o vga.o apb_pci.o
-OBJS+= fdc.o mc146818rtc.o serial.o m48t59.o
+OBJS+= fdc.o mc146818rtc.o serial.o
 OBJS+= cirrus_vga.o parallel.o
 else
-OBJS+= sun4m.o tcx.o iommu.o m48t59.o slavio_intctl.o
+OBJS+= sun4m.o tcx.o iommu.o slavio_intctl.o
 OBJS+= slavio_timer.o escc.o slavio_misc.o fdc.o sparc32_dma.o
 OBJS+= cs4231.o eccmemctl.o sbi.o sun4c_intctl.o
 endif
@@ -648,7 +645,7 @@ OBJS+= arm-semi.o
 OBJS+= pxa2xx.o pxa2xx_pic.o pxa2xx_gpio.o pxa2xx_timer.o pxa2xx_dma.o
 OBJS+= pxa2xx_lcd.o pxa2xx_mmci.o pxa2xx_pcmcia.o pxa2xx_keypad.o
 OBJS+= pflash_cfi01.o gumstix.o
-OBJS+= zaurus.o ide.o serial.o nand.o ecc.o spitz.o tosa.o tc6393xb.o
+OBJS+= zaurus.o ide.o serial.o spitz.o tosa.o tc6393xb.o
 OBJS+= omap1.o omap_lcdc.o omap_dma.o omap_clk.o omap_mmc.o omap_i2c.o
 OBJS+= omap2.o omap_dss.o soc_dma.o
 OBJS+= omap_sx1.o palm.o tsc210x.o
@@ -717,8 +714,8 @@ endif
 vl.o: qemu-options.h
 
 $(QEMU_PROG): LIBS += $(SDL_LIBS) $(COCOA_LIBS) $(CURSES_LIBS) $(BRLAPI_LIBS) $(VDE_LIBS)
-$(QEMU_PROG): ARLIBS=../libqemu_common.a libqemu.a
-$(QEMU_PROG): $(OBJS) ../libqemu_common.a libqemu.a
+$(QEMU_PROG): ARLIBS=../libqemu_common.a libqemu.a $(HWLIB)
+$(QEMU_PROG): $(OBJS) ../libqemu_common.a libqemu.a $(HWLIB)
 	$(call LINK,$(OBJS))
 
 endif # !CONFIG_USER_ONLY
diff --git a/configure b/configure
index 4111e7c..8fdbc1c 100755
--- a/configure
+++ b/configure
@@ -1724,6 +1724,7 @@ fi
 echo "TOOLS=$tools" >> $config_mak
 
 test -f ${config_h}~ && cmp -s $config_h ${config_h}~ && mv ${config_h}~ $config_h
+config_host_mak=${config_mak}
 
 for target in $target_list; do
 target_dir="$target"
@@ -1844,6 +1845,7 @@ case "$target_cpu" in
       echo "CONFIG_XEN=yes" >> $config_mak
       echo "#define CONFIG_XEN 1" >> $config_h
     fi
+    target_phys_bits=32
   ;;
   x86_64)
     echo "TARGET_ARCH=x86_64" >> $config_mak
@@ -1865,11 +1867,13 @@ case "$target_cpu" in
       echo "CONFIG_XEN=yes" >> $config_mak
       echo "#define CONFIG_XEN 1" >> $config_h
     fi
+    target_phys_bits=64
   ;;
   alpha)
     echo "TARGET_ARCH=alpha" >> $config_mak
     echo "#define TARGET_ARCH \"alpha\"" >> $config_h
     echo "#define TARGET_ALPHA 1" >> $config_h
+    target_phys_bits=64
   ;;
   arm|armeb)
     echo "TARGET_ARCH=arm" >> $config_mak
@@ -1878,12 +1882,14 @@ case "$target_cpu" in
     bflt="yes"
     target_nptl="yes"
     gdb_xml_files="arm-core.xml arm-vfp.xml arm-vfp3.xml arm-neon.xml"
+    target_phys_bits=32
   ;;
   cris)
     echo "TARGET_ARCH=cris" >> $config_mak
     echo "#define TARGET_ARCH \"cris\"" >> $config_h
     echo "#define TARGET_CRIS 1" >> $config_h
     target_nptl="yes"
+    target_phys_bits=32
   ;;
   m68k)
     echo "TARGET_ARCH=m68k" >> $config_mak
@@ -1891,18 +1897,21 @@ case "$target_cpu" in
     echo "#define TARGET_M68K 1" >> $config_h
     bflt="yes"
     gdb_xml_files="cf-core.xml cf-fp.xml"
+    target_phys_bits=32
   ;;
   mips|mipsel)
     echo "TARGET_ARCH=mips" >> $config_mak
     echo "#define TARGET_ARCH \"mips\"" >> $config_h
     echo "#define TARGET_MIPS 1" >> $config_h
     echo "#define TARGET_ABI_MIPSO32 1" >> $config_h
+    target_phys_bits=64
   ;;
   mipsn32|mipsn32el)
     echo "TARGET_ARCH=mipsn32" >> $config_mak
     echo "#define TARGET_ARCH \"mipsn32\"" >> $config_h
     echo "#define TARGET_MIPS 1" >> $config_h
     echo "#define TARGET_ABI_MIPSN32 1" >> $config_h
+    target_phys_bits=64
   ;;
   mips64|mips64el)
     echo "TARGET_ARCH=mips64" >> $config_mak
@@ -1910,12 +1919,14 @@ case "$target_cpu" in
     echo "#define TARGET_MIPS 1" >> $config_h
     echo "#define TARGET_MIPS64 1" >> $config_h
     echo "#define TARGET_ABI_MIPSN64 1" >> $config_h
+    target_phys_bits=64
   ;;
   ppc)
     echo "TARGET_ARCH=ppc" >> $config_mak
     echo "#define TARGET_ARCH \"ppc\"" >> $config_h
     echo "#define TARGET_PPC 1" >> $config_h
     gdb_xml_files="power-core.xml power-fpu.xml power-altivec.xml power-spe.xml"
+    target_phys_bits=32
   ;;
   ppcemb)
     echo "TARGET_ARCH=ppcemb" >> $config_mak
@@ -1929,6 +1940,7 @@ case "$target_cpu" in
       echo "#define CONFIG_KVM 1" >> $config_h
     fi
     gdb_xml_files="power-core.xml power-fpu.xml power-altivec.xml power-spe.xml"
+    target_phys_bits=64
   ;;
   ppc64)
     echo "TARGET_ARCH=ppc64" >> $config_mak
@@ -1937,6 +1949,7 @@ case "$target_cpu" in
     echo "#define TARGET_PPC 1" >> $config_h
     echo "#define TARGET_PPC64 1" >> $config_h
     gdb_xml_files="power64-core.xml power-fpu.xml power-altivec.xml power-spe.xml"
+    target_phys_bits=64
   ;;
   ppc64abi32)
     echo "TARGET_ARCH=ppc64" >> $config_mak
@@ -1947,6 +1960,7 @@ case "$target_cpu" in
     echo "#define TARGET_PPC64 1" >> $config_h
     echo "#define TARGET_ABI32 1" >> $config_h
     gdb_xml_files="power64-core.xml power-fpu.xml power-altivec.xml power-spe.xml"
+    target_phys_bits=64
   ;;
   sh4|sh4eb)
     echo "TARGET_ARCH=sh4" >> $config_mak
@@ -1954,11 +1968,13 @@ case "$target_cpu" in
     echo "#define TARGET_SH4 1" >> $config_h
     bflt="yes"
     target_nptl="yes"
+    target_phys_bits=32
   ;;
   sparc)
     echo "TARGET_ARCH=sparc" >> $config_mak
     echo "#define TARGET_ARCH \"sparc\"" >> $config_h
     echo "#define TARGET_SPARC 1" >> $config_h
+    target_phys_bits=64
   ;;
   sparc64)
     echo "TARGET_ARCH=sparc64" >> $config_mak
@@ -1966,6 +1982,7 @@ case "$target_cpu" in
     echo "#define TARGET_SPARC 1" >> $config_h
     echo "#define TARGET_SPARC64 1" >> $config_h
     elfload32="yes"
+    target_phys_bits=64
   ;;
   sparc32plus)
     echo "TARGET_ARCH=sparc64" >> $config_mak
@@ -1975,12 +1992,19 @@ case "$target_cpu" in
     echo "#define TARGET_SPARC 1" >> $config_h
     echo "#define TARGET_SPARC64 1" >> $config_h
     echo "#define TARGET_ABI32 1" >> $config_h
+    target_phys_bits=64
   ;;
   *)
     echo "Unsupported target CPU"
     exit 1
   ;;
 esac
+if [ $target_phys_bits -lt $hostlongbits ] ; then
+  target_phys_bits=$hostlongbits
+fi
+echo "HWLIB=../libhw$target_phys_bits/libqemuhw$target_phys_bits.a" >> $config_mak
+echo "#define TARGET_PHYS_ADDR_BITS $target_phys_bits" >> $config_h
+echo "subdir-$target: subdir-libhw$target_phys_bits" >> $config_host_mak
 if test "$target_bigendian" = "yes" ; then
   echo "TARGET_WORDS_BIGENDIAN=yes" >> $config_mak
   echo "#define TARGET_WORDS_BIGENDIAN 1" >> $config_h
@@ -2065,3 +2089,12 @@ if test "$source_path_used" = "yes" ; then
         ln -s $source_path/$f $f
     done
 fi
+
+for hwlib in 32 64; do
+  d=libhw$hwlib
+  mkdir -p $d
+  rm -f $d/Makefile
+  ln -s $source_path/Makefile.hw $d/Makefile
+  echo "HWLIB=libqemuhw$hwlib.a" > $d/config.mak
+  echo "CPPFLAGS=-DTARGET_PHYS_ADDR_BITS=$hwlib" >> $d/config.mak
+done
diff --git a/cpu-all.h b/cpu-all.h
index 0df54b6..b23be60 100644
--- a/cpu-all.h
+++ b/cpu-all.h
@@ -21,10 +21,7 @@
 #define CPU_ALL_H
 
 #include "qemu-common.h"
-
-#if defined(__arm__) || defined(__sparc__) || defined(__mips__) || defined(__hppa__)
-#define WORDS_ALIGNED
-#endif
+#include "cpu-common.h"
 
 /* some important defines:
  *
@@ -39,7 +36,6 @@
  * TARGET_WORDS_BIGENDIAN : same for target cpu
  */
 
-#include "bswap.h"
 #include "softfloat.h"
 
 #if defined(WORDS_BIGENDIAN) != defined(TARGET_WORDS_BIGENDIAN)
@@ -847,13 +843,6 @@ int cpu_inw(CPUState *env, int addr);
 int cpu_inl(CPUState *env, int addr);
 #endif
 
-/* address in the RAM (different from a physical address) */
-#ifdef CONFIG_KQEMU
-typedef uint32_t ram_addr_t;
-#else
-typedef unsigned long ram_addr_t;
-#endif
-
 /* memory API */
 
 extern int phys_ram_fd;
@@ -867,19 +856,8 @@ extern ram_addr_t last_ram_offset;
    3 flags.  The ROMD code stores the page ram offset in iotlb entry, 
    so only a limited number of ids are avaiable.  */
 
-#define IO_MEM_SHIFT       3
 #define IO_MEM_NB_ENTRIES  (1 << (TARGET_PAGE_BITS  - IO_MEM_SHIFT))
 
-#define IO_MEM_RAM         (0 << IO_MEM_SHIFT) /* hardcoded offset */
-#define IO_MEM_ROM         (1 << IO_MEM_SHIFT) /* hardcoded offset */
-#define IO_MEM_UNASSIGNED  (2 << IO_MEM_SHIFT)
-#define IO_MEM_NOTDIRTY    (3 << IO_MEM_SHIFT)
-
-/* Acts like a ROM when read and like a device when written.  */
-#define IO_MEM_ROMD        (1)
-#define IO_MEM_SUBPAGE     (2)
-#define IO_MEM_SUBWIDTH    (4)
-
 /* Flags stored in the low bits of the TLB virtual address.  These are
    defined so that fast path ram access is all zeros.  */
 /* Zero if TLB entry is valid.  */
@@ -890,67 +868,6 @@ extern ram_addr_t last_ram_offset;
 /* Set if TLB entry is an IO callback.  */
 #define TLB_MMIO        (1 << 5)
 
-typedef void CPUWriteMemoryFunc(void *opaque, target_phys_addr_t addr, uint32_t value);
-typedef uint32_t CPUReadMemoryFunc(void *opaque, target_phys_addr_t addr);
-
-void cpu_register_physical_memory_offset(target_phys_addr_t start_addr,
-                                         ram_addr_t size,
-                                         ram_addr_t phys_offset,
-                                         ram_addr_t region_offset);
-static inline void cpu_register_physical_memory(target_phys_addr_t start_addr,
-                                                ram_addr_t size,
-                                                ram_addr_t phys_offset)
-{
-    cpu_register_physical_memory_offset(start_addr, size, phys_offset, 0);
-}
-
-ram_addr_t cpu_get_physical_page_desc(target_phys_addr_t addr);
-ram_addr_t qemu_ram_alloc(ram_addr_t);
-void qemu_ram_free(ram_addr_t addr);
-/* This should only be used for ram local to a device.  */
-void *qemu_get_ram_ptr(ram_addr_t addr);
-/* This should not be used by devices.  */
-ram_addr_t qemu_ram_addr_from_host(void *ptr);
-
-int cpu_register_io_memory(int io_index,
-                           CPUReadMemoryFunc **mem_read,
-                           CPUWriteMemoryFunc **mem_write,
-                           void *opaque);
-void cpu_unregister_io_memory(int table_address);
-
-void cpu_physical_memory_rw(target_phys_addr_t addr, uint8_t *buf,
-                            int len, int is_write);
-static inline void cpu_physical_memory_read(target_phys_addr_t addr,
-                                            uint8_t *buf, int len)
-{
-    cpu_physical_memory_rw(addr, buf, len, 0);
-}
-static inline void cpu_physical_memory_write(target_phys_addr_t addr,
-                                             const uint8_t *buf, int len)
-{
-    cpu_physical_memory_rw(addr, (uint8_t *)buf, len, 1);
-}
-void *cpu_physical_memory_map(target_phys_addr_t addr,
-                              target_phys_addr_t *plen,
-                              int is_write);
-void cpu_physical_memory_unmap(void *buffer, target_phys_addr_t len,
-                               int is_write, target_phys_addr_t access_len);
-void *cpu_register_map_client(void *opaque, void (*callback)(void *opaque));
-void cpu_unregister_map_client(void *cookie);
-
-uint32_t ldub_phys(target_phys_addr_t addr);
-uint32_t lduw_phys(target_phys_addr_t addr);
-uint32_t ldl_phys(target_phys_addr_t addr);
-uint64_t ldq_phys(target_phys_addr_t addr);
-void stl_phys_notdirty(target_phys_addr_t addr, uint32_t val);
-void stq_phys_notdirty(target_phys_addr_t addr, uint64_t val);
-void stb_phys(target_phys_addr_t addr, uint32_t val);
-void stw_phys(target_phys_addr_t addr, uint32_t val);
-void stl_phys(target_phys_addr_t addr, uint32_t val);
-void stq_phys(target_phys_addr_t addr, uint64_t val);
-
-void cpu_physical_memory_write_rom(target_phys_addr_t addr,
-                                   const uint8_t *buf, int len);
 int cpu_memory_rw_debug(CPUState *env, target_ulong addr,
                         uint8_t *buf, int len, int is_write);
 
diff --git a/cpu-common.h b/cpu-common.h
new file mode 100644
index 0000000..4640924
--- /dev/null
+++ b/cpu-common.h
@@ -0,0 +1,96 @@
+#ifndef CPU_COMMON_H
+#define CPU_COMMON_H 1
+
+/* CPU interfaces that are target indpendent.  */
+
+#if defined(__arm__) || defined(__sparc__) || defined(__mips__) || defined(__hppa__)
+#define WORDS_ALIGNED
+#endif
+
+#include "bswap.h"
+
+/* address in the RAM (different from a physical address) */
+#ifdef CONFIG_KQEMU
+/* FIXME: This is wrong.  */
+typedef uint32_t ram_addr_t;
+#else
+typedef unsigned long ram_addr_t;
+#endif
+
+/* memory API */
+
+typedef void CPUWriteMemoryFunc(void *opaque, target_phys_addr_t addr, uint32_t value);
+typedef uint32_t CPUReadMemoryFunc(void *opaque, target_phys_addr_t addr);
+
+void cpu_register_physical_memory_offset(target_phys_addr_t start_addr,
+                                         ram_addr_t size,
+                                         ram_addr_t phys_offset,
+                                         ram_addr_t region_offset);
+static inline void cpu_register_physical_memory(target_phys_addr_t start_addr,
+                                                ram_addr_t size,
+                                                ram_addr_t phys_offset)
+{
+    cpu_register_physical_memory_offset(start_addr, size, phys_offset, 0);
+}
+
+ram_addr_t cpu_get_physical_page_desc(target_phys_addr_t addr);
+ram_addr_t qemu_ram_alloc(ram_addr_t);
+void qemu_ram_free(ram_addr_t addr);
+/* This should only be used for ram local to a device.  */
+void *qemu_get_ram_ptr(ram_addr_t addr);
+/* This should not be used by devices.  */
+ram_addr_t qemu_ram_addr_from_host(void *ptr);
+
+int cpu_register_io_memory(int io_index,
+                           CPUReadMemoryFunc **mem_read,
+                           CPUWriteMemoryFunc **mem_write,
+                           void *opaque);
+void cpu_unregister_io_memory(int table_address);
+
+void cpu_physical_memory_rw(target_phys_addr_t addr, uint8_t *buf,
+                            int len, int is_write);
+static inline void cpu_physical_memory_read(target_phys_addr_t addr,
+                                            uint8_t *buf, int len)
+{
+    cpu_physical_memory_rw(addr, buf, len, 0);
+}
+static inline void cpu_physical_memory_write(target_phys_addr_t addr,
+                                             const uint8_t *buf, int len)
+{
+    cpu_physical_memory_rw(addr, (uint8_t *)buf, len, 1);
+}
+void *cpu_physical_memory_map(target_phys_addr_t addr,
+                              target_phys_addr_t *plen,
+                              int is_write);
+void cpu_physical_memory_unmap(void *buffer, target_phys_addr_t len,
+                               int is_write, target_phys_addr_t access_len);
+void *cpu_register_map_client(void *opaque, void (*callback)(void *opaque));
+void cpu_unregister_map_client(void *cookie);
+
+uint32_t ldub_phys(target_phys_addr_t addr);
+uint32_t lduw_phys(target_phys_addr_t addr);
+uint32_t ldl_phys(target_phys_addr_t addr);
+uint64_t ldq_phys(target_phys_addr_t addr);
+void stl_phys_notdirty(target_phys_addr_t addr, uint32_t val);
+void stq_phys_notdirty(target_phys_addr_t addr, uint64_t val);
+void stb_phys(target_phys_addr_t addr, uint32_t val);
+void stw_phys(target_phys_addr_t addr, uint32_t val);
+void stl_phys(target_phys_addr_t addr, uint32_t val);
+void stq_phys(target_phys_addr_t addr, uint64_t val);
+
+void cpu_physical_memory_write_rom(target_phys_addr_t addr,
+                                   const uint8_t *buf, int len);
+
+#define IO_MEM_SHIFT       3
+
+#define IO_MEM_RAM         (0 << IO_MEM_SHIFT) /* hardcoded offset */
+#define IO_MEM_ROM         (1 << IO_MEM_SHIFT) /* hardcoded offset */
+#define IO_MEM_UNASSIGNED  (2 << IO_MEM_SHIFT)
+#define IO_MEM_NOTDIRTY    (3 << IO_MEM_SHIFT)
+
+/* Acts like a ROM when read and like a device when written.  */
+#define IO_MEM_ROMD        (1)
+#define IO_MEM_SUBPAGE     (2)
+#define IO_MEM_SUBWIDTH    (4)
+
+#endif /* !CPU_COMMON_H */
diff --git a/cpu-defs.h b/cpu-defs.h
index 0a82197..0d0eaa1 100644
--- a/cpu-defs.h
+++ b/cpu-defs.h
@@ -30,19 +30,12 @@
 #include <signal.h>
 #include "osdep.h"
 #include "sys-queue.h"
+#include "targphys.h"
 
 #ifndef TARGET_LONG_BITS
 #error TARGET_LONG_BITS must be defined before including this header
 #endif
 
-#ifndef TARGET_PHYS_ADDR_BITS
-#if TARGET_LONG_BITS >= HOST_LONG_BITS
-#define TARGET_PHYS_ADDR_BITS TARGET_LONG_BITS
-#else
-#define TARGET_PHYS_ADDR_BITS HOST_LONG_BITS
-#endif
-#endif
-
 #define TARGET_LONG_SIZE (TARGET_LONG_BITS / 8)
 
 /* target_ulong is the type of a virtual address */
@@ -62,22 +55,6 @@ typedef uint64_t target_ulong;
 #error TARGET_LONG_SIZE undefined
 #endif
 
-/* target_phys_addr_t is the type of a physical address (its size can
-   be different from 'target_ulong'). We have sizeof(target_phys_addr)
-   = max(sizeof(unsigned long),
-   sizeof(size_of_target_physical_address)) because we must pass a
-   host pointer to memory operations in some cases */
-
-#if TARGET_PHYS_ADDR_BITS == 32
-typedef uint32_t target_phys_addr_t;
-#define TARGET_FMT_plx "%08x"
-#elif TARGET_PHYS_ADDR_BITS == 64
-typedef uint64_t target_phys_addr_t;
-#define TARGET_FMT_plx "%016" PRIx64
-#else
-#error TARGET_PHYS_ADDR_BITS undefined
-#endif
-
 #define HOST_LONG_SIZE (HOST_LONG_BITS / 8)
 
 #define EXCP_INTERRUPT 	0x10000 /* async interruption */
diff --git a/dma.h b/dma.h
index 7d2ab45..4fd80b9 100644
--- a/dma.h
+++ b/dma.h
@@ -11,7 +11,8 @@
 #define DMA_H
 
 #include <stdio.h>
-#include "cpu.h"
+//#include "cpu.h"
+#include "hw/hw.h"
 #include "block.h"
 
 typedef struct {
diff --git a/hw/etraxfs_pic.c b/hw/etraxfs_pic.c
index 9f650de..da9d0c3 100644
--- a/hw/etraxfs_pic.c
+++ b/hw/etraxfs_pic.c
@@ -24,8 +24,8 @@
 
 #include "sysbus.h"
 #include "hw.h"
-#include "pc.h"
-#include "etraxfs.h"
+//#include "pc.h"
+//#include "etraxfs.h"
 
 #define D(x)
 
diff --git a/hw/hw.h b/hw/hw.h
index d0cf598..c990d1a 100644
--- a/hw/hw.h
+++ b/hw/hw.h
@@ -3,6 +3,13 @@
 #define QEMU_HW_H
 
 #include "qemu-common.h"
+
+#if defined(TARGET_PHYS_ADDR_BITS) && !defined(NEED_CPU_H)
+#include "targphys.h"
+#include "poison.h"
+#include "cpu-common.h"
+#endif
+
 #include "irq.h"
 
 /* VM Load/Save */
diff --git a/hw/poison.h b/hw/poison.h
new file mode 100644
index 0000000..94abff2
--- /dev/null
+++ b/hw/poison.h
@@ -0,0 +1,27 @@
+/* Poison identifiers that should not be used when building
+   target independent device code.  */
+
+#ifndef HW_POISON_H
+#define HW_POISON_H
+#ifdef __GNUC__
+
+#pragma GCC poison TARGET_I386
+#pragma GCC poison TARGET_X86_64
+#pragma GCC poison TARGET_ALPHA
+#pragma GCC poison TARGET_ARM
+#pragma GCC poison TARGET_CRIS
+#pragma GCC poison TARGET_M68K
+#pragma GCC poison TARGET_MIPS
+#pragma GCC poison TARGET_MIPS64
+#pragma GCC poison TARGET_PPC
+#pragma GCC poison TARGET_PPCEMB
+#pragma GCC poison TARGET_PPC64
+#pragma GCC poison TARGET_ABI32
+#pragma GCC poison TARGET_SH4
+#pragma GCC poison TARGET_SPARC
+#pragma GCC poison TARGET_SPARC64
+
+#pragma GCC poison TARGET_WORDS_BIGENDIAN
+
+#endif
+#endif
diff --git a/hw/virtio-pci.c b/hw/virtio-pci.c
index ebc84cc..c072423 100644
--- a/hw/virtio-pci.c
+++ b/hw/virtio-pci.c
@@ -17,7 +17,7 @@
 
 #include "virtio.h"
 #include "pci.h"
-#include "sysemu.h"
+//#include "sysemu.h"
 
 /* from Linux's linux/virtio_pci.h */
 
diff --git a/sysemu.h b/sysemu.h
index 1e4be53..7d65804 100644
--- a/sysemu.h
+++ b/sysemu.h
@@ -38,12 +38,14 @@ void qemu_system_powerdown_request(void);
 int qemu_shutdown_requested(void);
 int qemu_reset_requested(void);
 int qemu_powerdown_requested(void);
+#ifdef NEED_CPU_H
 #if !defined(TARGET_SPARC) && !defined(TARGET_I386)
 // Please implement a power failure function to signal the OS
 #define qemu_system_powerdown() do{}while(0)
 #else
 void qemu_system_powerdown(void);
 #endif
+#endif
 void qemu_system_reset(void);
 
 void do_savevm(Monitor *mon, const char *name);
@@ -117,11 +119,13 @@ extern uint64_t node_mem[MAX_NODES];
 extern const char *option_rom[MAX_OPTION_ROMS];
 extern int nb_option_roms;
 
+#ifdef NEED_CPU_H
 #if defined(TARGET_SPARC) || defined(TARGET_PPC)
 #define MAX_PROM_ENVS 128
 extern const char *prom_envs[MAX_PROM_ENVS];
 extern unsigned int nb_prom_envs;
 #endif
+#endif
 
 typedef enum {
     IF_IDE, IF_SCSI, IF_FLOPPY, IF_PFLASH, IF_MTD, IF_SD, IF_VIRTIO, IF_XEN,
diff --git a/target-mips/mips-defs.h b/target-mips/mips-defs.h
index 2d0c138..54e80f1 100644
--- a/target-mips/mips-defs.h
+++ b/target-mips/mips-defs.h
@@ -14,9 +14,6 @@
 #define TARGET_LONG_BITS 32
 #endif
 
-/* Even MIPS32 can have 36 bits physical address space. */
-#define TARGET_PHYS_ADDR_BITS 64
-
 /* Masks used to mark instructions to indicate which ISA level they
    were introduced in. */
 #define		ISA_MIPS1	0x00000001
diff --git a/target-ppc/cpu.h b/target-ppc/cpu.h
index 8dbc45d..59d47d2 100644
--- a/target-ppc/cpu.h
+++ b/target-ppc/cpu.h
@@ -37,7 +37,6 @@
 #if defined(TARGET_PPCEMB)
 /* Specific definitions for PowerPC embedded */
 /* BookE have 36 bits physical address space */
-#define TARGET_PHYS_ADDR_BITS 64
 #if defined(CONFIG_USER_ONLY)
 /* It looks like a lot of Linux programs assume page size
  * is 4kB long. This is evil, but we have to deal with it...
diff --git a/target-sparc/cpu.h b/target-sparc/cpu.h
index 32b45f9..d592bea 100644
--- a/target-sparc/cpu.h
+++ b/target-sparc/cpu.h
@@ -13,8 +13,6 @@
 #define TARGET_PAGE_BITS 13 /* 8k */
 #endif
 
-#define TARGET_PHYS_ADDR_BITS 64
-
 #define CPUState struct CPUSPARCState
 
 #include "cpu-defs.h"
diff --git a/targphys.h b/targphys.h
new file mode 100644
index 0000000..81a9c37
--- /dev/null
+++ b/targphys.h
@@ -0,0 +1,22 @@
+/* Define target_phys_addr_t if it exists.  */
+
+#ifndef TARGPHYS_H
+#define TARGPHYS_H
+
+#ifdef TARGET_PHYS_ADDR_BITS
+/* target_phys_addr_t is the type of a physical address (its size can
+   be different from 'target_ulong'). We have sizeof(target_phys_addr)
+   = max(sizeof(unsigned long),
+   sizeof(size_of_target_physical_address)) because we must pass a
+   host pointer to memory operations in some cases */
+
+#if TARGET_PHYS_ADDR_BITS == 32
+typedef uint32_t target_phys_addr_t;
+#define TARGET_FMT_plx "%08x"
+#elif TARGET_PHYS_ADDR_BITS == 64
+typedef uint64_t target_phys_addr_t;
+#define TARGET_FMT_plx "%016" PRIx64
+#endif
+#endif
+
+#endif
