Search
lxdream.org :: lxdream :: r577:a181aeacd6e8
lxdream 0.9.1
released Jun 29
Download Now
changeset577:a181aeacd6e8 lxdream-mmu
parent576:4945fa2ed24f
child578:5fbe050b0558
authornkeynes
dateMon Jan 14 10:23:49 2008 +0000 (16 years ago)
branchlxdream-mmu
Remove asm file and convert to inline (easier to cope with platform conventions)
Add breakpoint support
Add MMU store-queue support
src/Makefile.am
src/Makefile.in
src/sh4/ia32abi.h
src/sh4/ia32asm.s
src/sh4/ia32mac.h
src/sh4/ia64abi.h
src/sh4/mmu.c
src/sh4/sh4.c
src/sh4/sh4core.h
src/sh4/sh4mem.c
src/sh4/sh4trans.c
src/sh4/sh4trans.h
src/sh4/sh4x86.c
src/sh4/sh4x86.in
1.1 --- a/src/Makefile.am Mon Jan 14 09:08:58 2008 +0000
1.2 +++ b/src/Makefile.am Mon Jan 14 10:23:49 2008 +0000
1.3 @@ -51,25 +51,13 @@
1.4 x86dasm/i386-dis.c x86dasm/dis-init.c x86dasm/dis-buf.c
1.5
1.6 test_testsh4x86_LDADD = @GTK_LIBS@
1.7 -
1.8 -check_PROGRAMS += test/testsh4x86
1.9 -
1.10 -if BUILD_X86_64
1.11 -lxdream_SOURCES += sh4/ia64asm.s
1.12 test_testsh4x86_SOURCES = test/testsh4x86.c x86dasm/x86dasm.c \
1.13 x86dasm/x86dasm.h x86dasm/i386-dis.c x86dasm/dis-init.c \
1.14 x86dasm/dis-buf.c \
1.15 sh4/sh4dasm.c sh4/sh4trans.c sh4/sh4x86.c sh4/xltcache.c \
1.16 - sh4/xltcache.h mem.c util.c sh4/ia64asm.s
1.17 -else
1.18 -lxdream_SOURCES += sh4/ia32asm.s
1.19 -test_testsh4x86_SOURCES = test/testsh4x86.c x86dasm/x86dasm.c \
1.20 - x86dasm/x86dasm.h x86dasm/i386-dis.c x86dasm/dis-init.c \
1.21 - x86dasm/dis-buf.c \
1.22 - sh4/sh4dasm.c sh4/sh4trans.c sh4/sh4x86.c sh4/xltcache.c \
1.23 - sh4/xltcache.h mem.c util.c sh4/ia32asm.s
1.24 -endif
1.25 + sh4/xltcache.h mem.c util.c sh4/mmu.c
1.26
1.27 +check_PROGRAMS += test/testsh4x86
1.28 endif
1.29
1.30 if GUI_GTK
2.1 --- a/src/Makefile.in Mon Jan 14 09:08:58 2008 +0000
2.2 +++ b/src/Makefile.in Mon Jan 14 10:23:49 2008 +0000
2.3 @@ -43,18 +43,16 @@
2.4 @BUILD_SH4X86_TRUE@ x86dasm/i386-dis.c x86dasm/dis-init.c x86dasm/dis-buf.c
2.5
2.6 @BUILD_SH4X86_TRUE@am__append_2 = test/testsh4x86
2.7 -@BUILD_SH4X86_TRUE@@BUILD_X86_64_TRUE@am__append_3 = sh4/ia64asm.s
2.8 -@BUILD_SH4X86_TRUE@@BUILD_X86_64_FALSE@am__append_4 = sh4/ia32asm.s
2.9 -@GUI_GTK_TRUE@am__append_5 = gtkui/gtkui.c gtkui/gtkui.h \
2.10 +@GUI_GTK_TRUE@am__append_3 = gtkui/gtkui.c gtkui/gtkui.h \
2.11 @GUI_GTK_TRUE@ gtkui/main_win.c gtkui/gtkcb.c \
2.12 @GUI_GTK_TRUE@ gtkui/mmio_win.c gtkui/debug_win.c gtkui/dump_win.c \
2.13 @GUI_GTK_TRUE@ gtkui/ctrl_dlg.c gtkui/path_dlg.c gtkui/gdrom_menu.c \
2.14 @GUI_GTK_TRUE@ drivers/video_gtk.c drivers/video_gtk.h \
2.15 @GUI_GTK_TRUE@ drivers/video_glx.c drivers/video_glx.h
2.16
2.17 -@CDROM_LINUX_TRUE@am__append_6 = drivers/cd_linux.c
2.18 -@CDROM_LINUX_FALSE@am__append_7 = drivers/cd_none.c
2.19 -@AUDIO_ESOUND_TRUE@am__append_8 = drivers/audio_esd.c
2.20 +@CDROM_LINUX_TRUE@am__append_4 = drivers/cd_linux.c
2.21 +@CDROM_LINUX_FALSE@am__append_5 = drivers/cd_none.c
2.22 +@AUDIO_ESOUND_TRUE@am__append_6 = drivers/audio_esd.c
2.23 ACLOCAL = @ACLOCAL@
2.24 AMDEP_FALSE = @AMDEP_FALSE@
2.25 AMDEP_TRUE = @AMDEP_TRUE@
2.26 @@ -233,20 +231,14 @@
2.27 drivers/audio_null.c drivers/video_null.c \
2.28 drivers/gl_common.c drivers/gl_common.h drivers/gl_fbo.c \
2.29 drivers/gl_sl.c drivers/gl_slsrc.c\
2.30 -$(am__append_1) $(am__append_3) $(am__append_4) $(am__append_5) $(am__append_6) $(am__append_7) $(am__append_8)
2.31 +$(am__append_1) $(am__append_3) $(am__append_4) $(am__append_5) $(am__append_6)
2.32
2.33 @BUILD_SH4X86_TRUE@test_testsh4x86_LDADD = @GTK_LIBS@
2.34 -@BUILD_SH4X86_TRUE@@BUILD_X86_64_FALSE@test_testsh4x86_SOURCES = test/testsh4x86.c x86dasm/x86dasm.c \
2.35 -@BUILD_SH4X86_TRUE@@BUILD_X86_64_FALSE@ x86dasm/x86dasm.h x86dasm/i386-dis.c x86dasm/dis-init.c \
2.36 -@BUILD_SH4X86_TRUE@@BUILD_X86_64_FALSE@ x86dasm/dis-buf.c \
2.37 -@BUILD_SH4X86_TRUE@@BUILD_X86_64_FALSE@ sh4/sh4dasm.c sh4/sh4trans.c sh4/sh4x86.c sh4/xltcache.c \
2.38 -@BUILD_SH4X86_TRUE@@BUILD_X86_64_FALSE@ sh4/xltcache.h mem.c util.c sh4/ia32asm.s
2.39 -
2.40 -@BUILD_SH4X86_TRUE@@BUILD_X86_64_TRUE@test_testsh4x86_SOURCES = test/testsh4x86.c x86dasm/x86dasm.c \
2.41 -@BUILD_SH4X86_TRUE@@BUILD_X86_64_TRUE@ x86dasm/x86dasm.h x86dasm/i386-dis.c x86dasm/dis-init.c \
2.42 -@BUILD_SH4X86_TRUE@@BUILD_X86_64_TRUE@ x86dasm/dis-buf.c \
2.43 -@BUILD_SH4X86_TRUE@@BUILD_X86_64_TRUE@ sh4/sh4dasm.c sh4/sh4trans.c sh4/sh4x86.c sh4/xltcache.c \
2.44 -@BUILD_SH4X86_TRUE@@BUILD_X86_64_TRUE@ sh4/xltcache.h mem.c util.c sh4/ia64asm.s
2.45 +@BUILD_SH4X86_TRUE@test_testsh4x86_SOURCES = test/testsh4x86.c x86dasm/x86dasm.c \
2.46 +@BUILD_SH4X86_TRUE@ x86dasm/x86dasm.h x86dasm/i386-dis.c x86dasm/dis-init.c \
2.47 +@BUILD_SH4X86_TRUE@ x86dasm/dis-buf.c \
2.48 +@BUILD_SH4X86_TRUE@ sh4/sh4dasm.c sh4/sh4trans.c sh4/sh4x86.c sh4/xltcache.c \
2.49 +@BUILD_SH4X86_TRUE@ sh4/xltcache.h mem.c util.c sh4/mmu.c
2.50
2.51
2.52 lxdream_LDADD = @GTK_LIBS@ @LIBPNG_LIBS@ @ESOUND_LIBS@ $(INTLLIBS)
2.53 @@ -297,26 +289,24 @@
2.54 sh4/sh4x86.c sh4/x86op.h sh4/ia32abi.h sh4/ia32mac.h \
2.55 sh4/ia64abi.h sh4/sh4trans.c sh4/sh4trans.h x86dasm/x86dasm.c \
2.56 x86dasm/x86dasm.h x86dasm/i386-dis.c x86dasm/dis-init.c \
2.57 - x86dasm/dis-buf.c sh4/ia64asm.s sh4/ia32asm.s gtkui/gtkui.c \
2.58 - gtkui/gtkui.h gtkui/main_win.c gtkui/gtkcb.c gtkui/mmio_win.c \
2.59 - gtkui/debug_win.c gtkui/dump_win.c gtkui/ctrl_dlg.c \
2.60 - gtkui/path_dlg.c gtkui/gdrom_menu.c drivers/video_gtk.c \
2.61 - drivers/video_gtk.h drivers/video_glx.c drivers/video_glx.h \
2.62 - drivers/cd_linux.c drivers/cd_none.c drivers/audio_esd.c
2.63 + x86dasm/dis-buf.c gtkui/gtkui.c gtkui/gtkui.h gtkui/main_win.c \
2.64 + gtkui/gtkcb.c gtkui/mmio_win.c gtkui/debug_win.c \
2.65 + gtkui/dump_win.c gtkui/ctrl_dlg.c gtkui/path_dlg.c \
2.66 + gtkui/gdrom_menu.c drivers/video_gtk.c drivers/video_gtk.h \
2.67 + drivers/video_glx.c drivers/video_glx.h drivers/cd_linux.c \
2.68 + drivers/cd_none.c drivers/audio_esd.c
2.69 @BUILD_SH4X86_TRUE@am__objects_1 = sh4x86.$(OBJEXT) sh4trans.$(OBJEXT) \
2.70 @BUILD_SH4X86_TRUE@ x86dasm.$(OBJEXT) i386-dis.$(OBJEXT) \
2.71 @BUILD_SH4X86_TRUE@ dis-init.$(OBJEXT) dis-buf.$(OBJEXT)
2.72 -@BUILD_SH4X86_TRUE@@BUILD_X86_64_TRUE@am__objects_2 = ia64asm.$(OBJEXT)
2.73 -@BUILD_SH4X86_TRUE@@BUILD_X86_64_FALSE@am__objects_3 = ia32asm.$(OBJEXT)
2.74 -@GUI_GTK_TRUE@am__objects_4 = gtkui.$(OBJEXT) main_win.$(OBJEXT) \
2.75 +@GUI_GTK_TRUE@am__objects_2 = gtkui.$(OBJEXT) main_win.$(OBJEXT) \
2.76 @GUI_GTK_TRUE@ gtkcb.$(OBJEXT) mmio_win.$(OBJEXT) \
2.77 @GUI_GTK_TRUE@ debug_win.$(OBJEXT) dump_win.$(OBJEXT) \
2.78 @GUI_GTK_TRUE@ ctrl_dlg.$(OBJEXT) path_dlg.$(OBJEXT) \
2.79 @GUI_GTK_TRUE@ gdrom_menu.$(OBJEXT) video_gtk.$(OBJEXT) \
2.80 @GUI_GTK_TRUE@ video_glx.$(OBJEXT)
2.81 -@CDROM_LINUX_TRUE@am__objects_5 = cd_linux.$(OBJEXT)
2.82 -@CDROM_LINUX_FALSE@am__objects_6 = cd_none.$(OBJEXT)
2.83 -@AUDIO_ESOUND_TRUE@am__objects_7 = audio_esd.$(OBJEXT)
2.84 +@CDROM_LINUX_TRUE@am__objects_3 = cd_linux.$(OBJEXT)
2.85 +@CDROM_LINUX_FALSE@am__objects_4 = cd_none.$(OBJEXT)
2.86 +@AUDIO_ESOUND_TRUE@am__objects_5 = audio_esd.$(OBJEXT)
2.87 am_lxdream_OBJECTS = main.$(OBJEXT) config.$(OBJEXT) mem.$(OBJEXT) \
2.88 watch.$(OBJEXT) asic.$(OBJEXT) syscall.$(OBJEXT) bios.$(OBJEXT) \
2.89 dcload.$(OBJEXT) ide.$(OBJEXT) gdimage.$(OBJEXT) \
2.90 @@ -335,42 +325,20 @@
2.91 audio_null.$(OBJEXT) video_null.$(OBJEXT) gl_common.$(OBJEXT) \
2.92 gl_fbo.$(OBJEXT) gl_sl.$(OBJEXT) gl_slsrc.$(OBJEXT) \
2.93 $(am__objects_1) $(am__objects_2) $(am__objects_3) \
2.94 - $(am__objects_4) $(am__objects_5) $(am__objects_6) \
2.95 - $(am__objects_7)
2.96 + $(am__objects_4) $(am__objects_5)
2.97 lxdream_OBJECTS = $(am_lxdream_OBJECTS)
2.98 lxdream_DEPENDENCIES =
2.99 lxdream_LDFLAGS =
2.100 am__test_testsh4x86_SOURCES_DIST = test/testsh4x86.c x86dasm/x86dasm.c \
2.101 x86dasm/x86dasm.h x86dasm/i386-dis.c x86dasm/dis-init.c \
2.102 x86dasm/dis-buf.c sh4/sh4dasm.c sh4/sh4trans.c sh4/sh4x86.c \
2.103 - sh4/xltcache.c sh4/xltcache.h mem.c util.c sh4/ia32asm.s \
2.104 - sh4/ia64asm.s
2.105 -@BUILD_SH4X86_TRUE@@BUILD_X86_64_TRUE@am_test_testsh4x86_OBJECTS = \
2.106 -@BUILD_SH4X86_TRUE@@BUILD_X86_64_TRUE@ testsh4x86.$(OBJEXT) \
2.107 -@BUILD_SH4X86_TRUE@@BUILD_X86_64_TRUE@ x86dasm.$(OBJEXT) \
2.108 -@BUILD_SH4X86_TRUE@@BUILD_X86_64_TRUE@ i386-dis.$(OBJEXT) \
2.109 -@BUILD_SH4X86_TRUE@@BUILD_X86_64_TRUE@ dis-init.$(OBJEXT) \
2.110 -@BUILD_SH4X86_TRUE@@BUILD_X86_64_TRUE@ dis-buf.$(OBJEXT) \
2.111 -@BUILD_SH4X86_TRUE@@BUILD_X86_64_TRUE@ sh4dasm.$(OBJEXT) \
2.112 -@BUILD_SH4X86_TRUE@@BUILD_X86_64_TRUE@ sh4trans.$(OBJEXT) \
2.113 -@BUILD_SH4X86_TRUE@@BUILD_X86_64_TRUE@ sh4x86.$(OBJEXT) \
2.114 -@BUILD_SH4X86_TRUE@@BUILD_X86_64_TRUE@ xltcache.$(OBJEXT) \
2.115 -@BUILD_SH4X86_TRUE@@BUILD_X86_64_TRUE@ mem.$(OBJEXT) \
2.116 -@BUILD_SH4X86_TRUE@@BUILD_X86_64_TRUE@ util.$(OBJEXT) \
2.117 -@BUILD_SH4X86_TRUE@@BUILD_X86_64_TRUE@ ia64asm.$(OBJEXT)
2.118 -@BUILD_SH4X86_TRUE@@BUILD_X86_64_FALSE@am_test_testsh4x86_OBJECTS = \
2.119 -@BUILD_SH4X86_TRUE@@BUILD_X86_64_FALSE@ testsh4x86.$(OBJEXT) \
2.120 -@BUILD_SH4X86_TRUE@@BUILD_X86_64_FALSE@ x86dasm.$(OBJEXT) \
2.121 -@BUILD_SH4X86_TRUE@@BUILD_X86_64_FALSE@ i386-dis.$(OBJEXT) \
2.122 -@BUILD_SH4X86_TRUE@@BUILD_X86_64_FALSE@ dis-init.$(OBJEXT) \
2.123 -@BUILD_SH4X86_TRUE@@BUILD_X86_64_FALSE@ dis-buf.$(OBJEXT) \
2.124 -@BUILD_SH4X86_TRUE@@BUILD_X86_64_FALSE@ sh4dasm.$(OBJEXT) \
2.125 -@BUILD_SH4X86_TRUE@@BUILD_X86_64_FALSE@ sh4trans.$(OBJEXT) \
2.126 -@BUILD_SH4X86_TRUE@@BUILD_X86_64_FALSE@ sh4x86.$(OBJEXT) \
2.127 -@BUILD_SH4X86_TRUE@@BUILD_X86_64_FALSE@ xltcache.$(OBJEXT) \
2.128 -@BUILD_SH4X86_TRUE@@BUILD_X86_64_FALSE@ mem.$(OBJEXT) \
2.129 -@BUILD_SH4X86_TRUE@@BUILD_X86_64_FALSE@ util.$(OBJEXT) \
2.130 -@BUILD_SH4X86_TRUE@@BUILD_X86_64_FALSE@ ia32asm.$(OBJEXT)
2.131 + sh4/xltcache.c sh4/xltcache.h mem.c util.c sh4/mmu.c
2.132 +@BUILD_SH4X86_TRUE@am_test_testsh4x86_OBJECTS = testsh4x86.$(OBJEXT) \
2.133 +@BUILD_SH4X86_TRUE@ x86dasm.$(OBJEXT) i386-dis.$(OBJEXT) \
2.134 +@BUILD_SH4X86_TRUE@ dis-init.$(OBJEXT) dis-buf.$(OBJEXT) \
2.135 +@BUILD_SH4X86_TRUE@ sh4dasm.$(OBJEXT) sh4trans.$(OBJEXT) \
2.136 +@BUILD_SH4X86_TRUE@ sh4x86.$(OBJEXT) xltcache.$(OBJEXT) \
2.137 +@BUILD_SH4X86_TRUE@ mem.$(OBJEXT) util.$(OBJEXT) mmu.$(OBJEXT)
2.138 test_testsh4x86_OBJECTS = $(am_test_testsh4x86_OBJECTS)
2.139 @BUILD_SH4X86_TRUE@test_testsh4x86_DEPENDENCIES =
2.140 @BUILD_SH4X86_FALSE@test_testsh4x86_DEPENDENCIES =
2.141 @@ -430,7 +398,6 @@
2.142 $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
2.143 CCLD = $(CC)
2.144 LINK = $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -o $@
2.145 -CCASCOMPILE = $(CCAS) $(AM_CCASFLAGS) $(CCASFLAGS)
2.146 DIST_SOURCES = $(gendec_SOURCES) $(genglsl_SOURCES) \
2.147 $(am__lxdream_SOURCES_DIST) $(am__test_testsh4x86_SOURCES_DIST) \
2.148 $(test_testxlt_SOURCES)
2.149 @@ -441,7 +408,7 @@
2.150 $(MAKE) $(AM_MAKEFLAGS) all-am
2.151
2.152 .SUFFIXES:
2.153 -.SUFFIXES: .c .o .obj .s
2.154 +.SUFFIXES: .c .o .obj
2.155 $(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ Makefile.am $(top_srcdir)/configure.in $(ACLOCAL_M4)
2.156 cd $(top_srcdir) && \
2.157 $(AUTOMAKE) --gnu src/Makefile
2.158 @@ -2079,24 +2046,6 @@
2.159 @AMDEP_TRUE@@am__fastdepCC_FALSE@ depfile='$(DEPDIR)/testxlt.Po' tmpdepfile='$(DEPDIR)/testxlt.TPo' @AMDEPBACKSLASH@
2.160 @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
2.161 @am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o testxlt.obj `if test -f 'test/testxlt.c'; then $(CYGPATH_W) 'test/testxlt.c'; else $(CYGPATH_W) '$(srcdir)/test/testxlt.c'; fi`
2.162 -
2.163 -.s.o:
2.164 - $(CCASCOMPILE) -c `test -f '$<' || echo '$(srcdir)/'`$<
2.165 -
2.166 -.s.obj:
2.167 - $(CCASCOMPILE) -c `if test -f '$<'; then $(CYGPATH_W) '$<'; else $(CYGPATH_W) '$(srcdir)/$<'; fi`
2.168 -
2.169 -ia64asm.o: sh4/ia64asm.s
2.170 - $(CCAS) $(AM_CCASFLAGS) $(CCASFLAGS) -c -o ia64asm.o `test -f 'sh4/ia64asm.s' || echo '$(srcdir)/'`sh4/ia64asm.s
2.171 -
2.172 -ia64asm.obj: sh4/ia64asm.s
2.173 - $(CCAS) $(AM_CCASFLAGS) $(CCASFLAGS) -c -o ia64asm.obj `if test -f 'sh4/ia64asm.s'; then $(CYGPATH_W) 'sh4/ia64asm.s'; else $(CYGPATH_W) '$(srcdir)/sh4/ia64asm.s'; fi`
2.174 -
2.175 -ia32asm.o: sh4/ia32asm.s
2.176 - $(CCAS) $(AM_CCASFLAGS) $(CCASFLAGS) -c -o ia32asm.o `test -f 'sh4/ia32asm.s' || echo '$(srcdir)/'`sh4/ia32asm.s
2.177 -
2.178 -ia32asm.obj: sh4/ia32asm.s
2.179 - $(CCAS) $(AM_CCASFLAGS) $(CCASFLAGS) -c -o ia32asm.obj `if test -f 'sh4/ia32asm.s'; then $(CYGPATH_W) 'sh4/ia32asm.s'; else $(CYGPATH_W) '$(srcdir)/sh4/ia32asm.s'; fi`
2.180 uninstall-info-am:
2.181
2.182 ETAGS = etags
3.1 --- a/src/sh4/ia32abi.h Mon Jan 14 09:08:58 2008 +0000
3.2 +++ b/src/sh4/ia32abi.h Mon Jan 14 10:23:49 2008 +0000
3.3 @@ -244,6 +244,29 @@
3.4 }
3.5 }
3.6
3.7 +void *xlat_get_native_pc()
3.8 +{
3.9 + void *result = NULL;
3.10 + asm(
3.11 + "mov %%ebp, %%eax\n\t"
3.12 + "mov $0x8, %%ecx\n\t"
3.13 + "mov %1, %%edx\n"
3.14 +"frame_loop: test %%eax, %%eax\n\t"
3.15 + "je frame_not_found\n\t"
3.16 + "cmp (%%eax), %%edx\n\t"
3.17 + "je frame_found\n\t"
3.18 + "sub $0x1, %%ecx\n\t"
3.19 + "je frame_not_found\n\t"
3.20 + "movl (%%eax), %%eax\n\t"
3.21 + "jmp frame_loop\n"
3.22 +"frame_found: movl 0x4(%%eax), %0\n"
3.23 +"frame_not_found:"
3.24 + : "=r" (result)
3.25 + : "r" (&sh4r)
3.26 + : "eax", "ecx", "edx" );
3.27 + return result;
3.28 +}
3.29 +
3.30 #endif
3.31
3.32
4.1 --- a/src/sh4/ia32asm.s Mon Jan 14 09:08:58 2008 +0000
4.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
4.3 @@ -1,34 +0,0 @@
4.4 -#
4.5 -# Scan back through the stack until we hit the currently executing
4.6 -# translation block, and find the call return address to that block.
4.7 -#
4.8 -# Implementation: iterate back through each stack frame until we find
4.9 -# a frame that has a saved %ebp == sh4r (setup by the xlat blocks).
4.10 -# The return address is then the stack value immediately before the
4.11 -# saved %ebp.
4.12 -#
4.13 -# At most 8 stack frames are checked, to prevent infinite looping on a
4.14 -# corrupt stack.
4.15 -
4.16 -.global xlat_get_native_pc
4.17 -xlat_get_native_pc:
4.18 - mov %ebp, %eax
4.19 - mov $0x8, %ecx
4.20 - mov $sh4r, %edx
4.21 -
4.22 -frame_loop:
4.23 - test %eax, %eax
4.24 - je frame_not_found
4.25 - cmp (%eax), %edx
4.26 - je frame_found
4.27 - sub $0x1, %ecx
4.28 - je frame_not_found
4.29 - movl (%eax), %eax
4.30 - jmp frame_loop
4.31 -
4.32 -frame_found:
4.33 - movl 0x4(%eax), %eax
4.34 - ret
4.35 -frame_not_found:
4.36 - xor %eax, %eax
4.37 - ret
5.1 --- a/src/sh4/ia32mac.h Mon Jan 14 09:08:58 2008 +0000
5.2 +++ b/src/sh4/ia32mac.h Mon Jan 14 10:23:49 2008 +0000
5.3 @@ -267,6 +267,30 @@
5.4 }
5.5 }
5.6
5.7 +void *xlat_get_native_pc()
5.8 +{
5.9 + void *result = NULL;
5.10 + asm(
5.11 + "mov %%ebp, %%eax\n\t"
5.12 + "mov $0x8, %%ecx\n\t"
5.13 + "mov %1, %%edx\n"
5.14 +"frame_loop: test %%eax, %%eax\n\t"
5.15 + "je frame_not_found\n\t"
5.16 + "cmp (%%eax), %%edx\n\t"
5.17 + "je frame_found\n\t"
5.18 + "sub $0x1, %%ecx\n\t"
5.19 + "je frame_not_found\n\t"
5.20 + "movl (%%eax), %%eax\n\t"
5.21 + "jmp frame_loop\n"
5.22 +"frame_found: movl 0x4(%%eax), %0\n"
5.23 +"frame_not_found:"
5.24 + : "=r" (result)
5.25 + : "r" (&sh4r)
5.26 + : "eax", "ecx", "edx" );
5.27 + return result;
5.28 +}
5.29 +
5.30 +
5.31 #endif
5.32
5.33
6.1 --- a/src/sh4/ia64abi.h Mon Jan 14 09:08:58 2008 +0000
6.2 +++ b/src/sh4/ia64abi.h Mon Jan 14 10:23:49 2008 +0000
6.3 @@ -235,4 +235,28 @@
6.4 }
6.5 }
6.6
6.7 +
6.8 +void *xlat_get_native_pc()
6.9 +{
6.10 + void *result = NULL;
6.11 + asm(
6.12 + "mov %%rbp, %%rax\n\t"
6.13 + "mov $0x8, %%ecx\n\t"
6.14 + "mov %1, %%rdx\n"
6.15 +"frame_loop: test %%rax, %%rax\n\t"
6.16 + "je frame_not_found\n\t"
6.17 + "cmpq (%%rax), %%rdx\n\t"
6.18 + "je frame_found\n\t"
6.19 + "sub $0x1, %%ecx\n\t"
6.20 + "je frame_not_found\n\t"
6.21 + "movq (%%rax), %%rax\n\t"
6.22 + "jmp frame_loop\n"
6.23 +"frame_found: movq 0x4(%%rax), %0\n"
6.24 +"frame_not_found:"
6.25 + : "=r" (result)
6.26 + : "r" (&sh4r)
6.27 + : "rax", "rcx", "rdx" );
6.28 + return result;
6.29 +}
6.30 +
6.31 #endif
7.1 --- a/src/sh4/mmu.c Mon Jan 14 09:08:58 2008 +0000
7.2 +++ b/src/sh4/mmu.c Mon Jan 14 10:23:49 2008 +0000
7.3 @@ -845,3 +845,50 @@
7.4 return TRUE;
7.5 }
7.6 }
7.7 +
7.8 +gboolean sh4_flush_store_queue( sh4addr_t addr )
7.9 +{
7.10 + uint32_t mmucr = MMIO_READ(MMU,MMUCR);
7.11 + int queue = (addr&0x20)>>2;
7.12 + sh4ptr_t src = (sh4ptr_t)&sh4r.store_queue[queue];
7.13 + sh4addr_t target;
7.14 + /* Store queue operation */
7.15 + if( mmucr & MMUCR_AT ) {
7.16 + int entryNo;
7.17 + if( ((mmucr & MMUCR_SV) == 0) || !IS_SH4_PRIVMODE() ) {
7.18 + entryNo = mmu_utlb_lookup_vpn_asid( addr );
7.19 + } else {
7.20 + entryNo = mmu_utlb_lookup_vpn( addr );
7.21 + }
7.22 + switch(entryNo) {
7.23 + case -1:
7.24 + MMU_TLB_WRITE_MISS_ERROR(addr);
7.25 + return FALSE;
7.26 + case -2:
7.27 + MMU_TLB_MULTI_HIT_ERROR(addr);
7.28 + return FALSE;
7.29 + default:
7.30 + if( IS_SH4_PRIVMODE() ? ((mmu_utlb[entryNo].flags & TLB_WRITABLE) == 0)
7.31 + : ((mmu_utlb[entryNo].flags & TLB_USERWRITABLE) != TLB_USERWRITABLE) ) {
7.32 + /* protection violation */
7.33 + MMU_TLB_WRITE_PROT_ERROR(addr);
7.34 + return FALSE;
7.35 + }
7.36 +
7.37 + if( (mmu_utlb[entryNo].flags & TLB_DIRTY) == 0 ) {
7.38 + MMU_TLB_INITIAL_WRITE_ERROR(addr);
7.39 + return FALSE;
7.40 + }
7.41 +
7.42 + /* finally generate the target address */
7.43 + target = ((mmu_utlb[entryNo].ppn & mmu_utlb[entryNo].mask) |
7.44 + (addr & (~mmu_utlb[entryNo].mask))) & 0xFFFFFFE0;
7.45 + }
7.46 + } else {
7.47 + uint32_t hi = (MMIO_READ( MMU, (queue == 0 ? QACR0 : QACR1) ) & 0x1C) << 24;
7.48 + target = (addr&0x03FFFFE0) | hi;
7.49 + }
7.50 + mem_copy_to_sh4( target, src, 32 );
7.51 + return TRUE;
7.52 +}
7.53 +
8.1 --- a/src/sh4/sh4.c Mon Jan 14 09:08:58 2008 +0000
8.2 +++ b/src/sh4/sh4.c Mon Jan 14 10:23:49 2008 +0000
8.3 @@ -154,6 +154,9 @@
8.4 {
8.5 sh4_breakpoints[sh4_breakpoint_count].address = pc;
8.6 sh4_breakpoints[sh4_breakpoint_count].type = type;
8.7 + if( sh4_use_translator ) {
8.8 + xlat_invalidate_word( pc );
8.9 + }
8.10 sh4_breakpoint_count++;
8.11 }
8.12
8.13 @@ -168,6 +171,9 @@
8.14 sh4_breakpoints[i-1].address = sh4_breakpoints[i].address;
8.15 sh4_breakpoints[i-1].type = sh4_breakpoints[i].type;
8.16 }
8.17 + if( sh4_use_translator ) {
8.18 + xlat_invalidate_word( pc );
8.19 + }
8.20 sh4_breakpoint_count--;
8.21 return TRUE;
8.22 }
9.1 --- a/src/sh4/sh4core.h Mon Jan 14 09:08:58 2008 +0000
9.2 +++ b/src/sh4/sh4core.h Mon Jan 14 10:23:49 2008 +0000
9.3 @@ -135,7 +135,7 @@
9.4 void sh4_write_word( sh4addr_t addr, uint32_t val );
9.5 void sh4_write_byte( sh4addr_t addr, uint32_t val );
9.6 int32_t sh4_read_phys_word( sh4addr_t addr );
9.7 -void sh4_flush_store_queue( sh4addr_t addr );
9.8 +gboolean sh4_flush_store_queue( sh4addr_t addr );
9.9
9.10 /* SH4 Exceptions */
9.11 #define EXC_POWER_RESET 0x000 /* reset vector */
10.1 --- a/src/sh4/sh4mem.c Mon Jan 14 09:08:58 2008 +0000
10.2 +++ b/src/sh4/sh4mem.c Mon Jan 14 10:23:49 2008 +0000
10.3 @@ -423,19 +423,6 @@
10.4 }
10.5 }
10.6
10.7 -void sh4_flush_store_queue( sh4addr_t addr )
10.8 -{
10.9 - /* Store queue operation */
10.10 - if( IS_MMU_ENABLED() ) {
10.11 -
10.12 - }
10.13 - int queue = (addr&0x20)>>2;
10.14 - sh4ptr_t src = (sh4ptr_t)&sh4r.store_queue[queue];
10.15 - uint32_t hi = (MMIO_READ( MMU, (queue == 0 ? QACR0 : QACR1) ) & 0x1C) << 24;
10.16 - uint32_t target = (addr&0x03FFFFE0) | hi;
10.17 - mem_copy_to_sh4( target, src, 32 );
10.18 -}
10.19 -
10.20 sh4ptr_t sh4_get_region_by_vma( sh4addr_t vma )
10.21 {
10.22 uint64_t ppa = mmu_vma_to_phys_read(vma);
11.1 --- a/src/sh4/sh4trans.c Mon Jan 14 09:08:58 2008 +0000
11.2 +++ b/src/sh4/sh4trans.c Mon Jan 14 10:23:49 2008 +0000
11.3 @@ -42,7 +42,19 @@
11.4 }
11.5 }
11.6
11.7 - int jmp = setjmp(xlat_jmp_buf);
11.8 + switch( setjmp(xlat_jmp_buf) ) {
11.9 + case XLAT_EXIT_BREAKPOINT:
11.10 + sh4_clear_breakpoint( sh4r.pc, BREAK_ONESHOT );
11.11 + /* fallthrough */
11.12 + case XLAT_EXIT_HALT:
11.13 + if( sh4r.sh4_state != SH4_STATE_STANDBY ) {
11.14 + TMU_run_slice( sh4r.slice_cycle );
11.15 + SCIF_run_slice( sh4r.slice_cycle );
11.16 + dreamcast_stop();
11.17 + return sh4r.slice_cycle;
11.18 + }
11.19 + break;
11.20 + }
11.21
11.22 void * (*code)() = NULL;
11.23 while( sh4r.slice_cycle < nanosecs ) {
11.24 @@ -94,7 +106,7 @@
11.25 {
11.26 sh4addr_t pc = start;
11.27 sh4addr_t lastpc = (pc&0xFFFFF000)+0x1000;
11.28 - int done;
11.29 + int done, i;
11.30 xlat_cache_block_t block = xlat_start_block( start );
11.31 xlat_output = (uint8_t *)block->code;
11.32 xlat_recovery_posn = 0;
11.33 @@ -102,6 +114,13 @@
11.34 sh4_translate_begin_block(pc);
11.35
11.36 do {
11.37 + /* check for breakpoints at this pc */
11.38 + for( i=0; i<sh4_breakpoint_count; i++ ) {
11.39 + if( sh4_breakpoints[i].address == pc ) {
11.40 + sh4_translate_emit_breakpoint(pc);
11.41 + break;
11.42 + }
11.43 + }
11.44 if( eob - xlat_output < MAX_INSTRUCTION_SIZE ) {
11.45 uint8_t *oldstart = block->code;
11.46 block = xlat_extend_block( xlat_output - oldstart + MAX_INSTRUCTION_SIZE );
11.47 @@ -139,32 +158,6 @@
11.48 }
11.49
11.50 /**
11.51 - * Translate a linear basic block to a temporary buffer, execute it, and return
11.52 - * the result of the execution. The translation is discarded.
11.53 - */
11.54 -void *sh4_translate_and_run( sh4addr_t start )
11.55 -{
11.56 - unsigned char buf[65536];
11.57 -
11.58 - sh4addr_t pc = start;
11.59 - int done;
11.60 - xlat_output = buf;
11.61 - uint8_t *eob = xlat_output + sizeof(buf);
11.62 -
11.63 - sh4_translate_begin_block(pc);
11.64 -
11.65 - while( (done = sh4_translate_instruction( pc )) == 0 ) {
11.66 - assert( (eob - xlat_output) >= MAX_INSTRUCTION_SIZE );
11.67 - pc += 2;
11.68 - }
11.69 - pc+=2;
11.70 - sh4_translate_end_block(pc);
11.71 -
11.72 - void * (*code)() = (void *)buf;
11.73 - return code();
11.74 -}
11.75 -
11.76 -/**
11.77 * "Execute" the supplied recovery record. Currently this only updates
11.78 * sh4r.pc and sh4r.slice_cycle according to the currently executing
11.79 * instruction. In future this may be more sophisticated (ie will
11.80 @@ -179,10 +172,8 @@
11.81 void sh4_translate_unwind_stack( gboolean abort_after, unwind_thunk_t thunk )
11.82 {
11.83 void *pc = xlat_get_native_pc();
11.84 - if( pc == NULL ) {
11.85 - // This should never happen - indicative of a bug somewhere.
11.86 - FATAL("Attempted to unwind stack, but translator is not running or stack is corrupt");
11.87 - }
11.88 +
11.89 + assert( pc != NULL );
11.90 void *code = xlat_get_code( sh4r.pc );
11.91 xlat_recovery_record_t recover = xlat_get_recovery(code, pc, TRUE);
11.92 if( recover != NULL ) {
11.93 @@ -193,9 +184,24 @@
11.94 thunk();
11.95 }
11.96 // finally longjmp back into sh4_xlat_run_slice
11.97 - longjmp(xlat_jmp_buf, 1);
11.98 + longjmp(xlat_jmp_buf, XLAT_EXIT_CONTINUE);
11.99 }
11.100
11.101 +void sh4_translate_exit( int exit_code )
11.102 +{
11.103 + void *pc = xlat_get_native_pc();
11.104 + assert(pc != NULL);
11.105 +
11.106 + void *code = xlat_get_code( sh4r.pc );
11.107 + xlat_recovery_record_t recover = xlat_get_recovery(code, pc, TRUE);
11.108 + if( recover != NULL ) {
11.109 + // Can be null if there is no recovery necessary
11.110 + sh4_translate_run_recovery(recover);
11.111 + }
11.112 + // finally longjmp back into sh4_xlat_run_slice
11.113 + longjmp(xlat_jmp_buf, exit_code);
11.114 +}
11.115 +
11.116 /**
11.117 * Exit the current block at the end of the current instruction, flush the
11.118 * translation cache (completely) and return control to sh4_xlat_run_slice.
11.119 @@ -210,17 +216,15 @@
11.120 void sh4_translate_flush_cache()
11.121 {
11.122 void *pc = xlat_get_native_pc();
11.123 - if( pc == NULL ) {
11.124 - // This should never happen - indicative of a bug somewhere.
11.125 - FATAL("Attempted to unwind stack, but translator is not running or stack is corrupt");
11.126 - }
11.127 + assert( pc != NULL );
11.128 +
11.129 void *code = xlat_get_code( sh4r.pc );
11.130 xlat_recovery_record_t recover = xlat_get_recovery(code, pc, TRUE);
11.131 if( recover != NULL ) {
11.132 // Can be null if there is no recovery necessary
11.133 sh4_translate_run_recovery(recover);
11.134 xlat_flush_cache();
11.135 - longjmp(xlat_jmp_buf, 1);
11.136 + longjmp(xlat_jmp_buf, XLAT_EXIT_CONTINUE);
11.137 } else {
11.138 xlat_flush_cache();
11.139 return;
11.140 @@ -232,6 +236,10 @@
11.141 void *result = NULL;
11.142
11.143 if( !IS_IN_ICACHE(vma) ) {
11.144 + if( vma > 0xFFFFFF00 ) {
11.145 + // lxdream hook
11.146 + return NULL;
11.147 + }
11.148 if( !mmu_update_icache(sh4r.pc) ) {
11.149 // fault - off to the fault handler
11.150 if( !mmu_update_icache(sh4r.pc) ) {
12.1 --- a/src/sh4/sh4trans.h Mon Jan 14 09:08:58 2008 +0000
12.2 +++ b/src/sh4/sh4trans.h Mon Jan 14 10:23:49 2008 +0000
12.3 @@ -35,6 +35,22 @@
12.4 #define MAX_RECOVERY_SIZE 2048
12.5
12.6 /**
12.7 + * Translation flag - exit the current block but continue (eg exception handling)
12.8 + */
12.9 +#define XLAT_EXIT_CONTINUE 1
12.10 +
12.11 +/**
12.12 + * Translation flag - exit the current block and halt immediately (eg fatal error)
12.13 + */
12.14 +#define XLAT_EXIT_HALT 2
12.15 +
12.16 +/**
12.17 + * Translation flag - exit the current block and halt immediately for a system
12.18 + * breakpoint.
12.19 + */
12.20 +#define XLAT_EXIT_BREAKPOINT 3
12.21 +
12.22 +/**
12.23 */
12.24 uint32_t sh4_xlat_run_slice( uint32_t nanosecs );
12.25
12.26 @@ -79,3 +95,9 @@
12.27 * @return This method never returns.
12.28 */
12.29 void sh4_translate_unwind_stack( gboolean is_completion, unwind_thunk_t thunk );
12.30 +
12.31 +/**
12.32 + * From within the translator, immediately exit the current translation block with
12.33 + * the specified exit code (one of the XLAT_EXIT_* values).
12.34 + */
12.35 +void sh4_translate_exit( int exit_code );
13.1 --- a/src/sh4/sh4x86.c Mon Jan 14 09:08:58 2008 +0000
13.2 +++ b/src/sh4/sh4x86.c Mon Jan 14 10:23:49 2008 +0000
13.3 @@ -125,7 +125,7 @@
13.4 xlat_recovery[xlat_recovery_posn].sh4_icount = (pc - sh4_x86.block_start_pc)>>1;
13.5 xlat_recovery_posn++;
13.6 }
13.7 -
13.8 +
13.9 /**
13.10 * Emit an instruction to load an SH4 reg into a real register
13.11 */
13.12 @@ -355,11 +355,18 @@
13.13 #endif
13.14 #endif
13.15
13.16 +void sh4_translate_emit_breakpoint( sh4vma_t pc )
13.17 +{
13.18 + load_imm32( R_EAX, XLAT_EXIT_BREAKPOINT );
13.19 + call_func1( sh4_translate_exit, R_EAX );
13.20 +}
13.21 +
13.22
13.23 /**
13.24 * Translate a single instruction. Delayed branches are handled specially
13.25 * by translating both branch and delayed instruction as a single unit (as
13.26 *
13.27 + * The instruction MUST be in the icache (assert check)
13.28 *
13.29 * @return true if the instruction marks the end of a basic block
13.30 * (eg a branch or
13.31 @@ -367,12 +374,21 @@
13.32 uint32_t sh4_translate_instruction( sh4addr_t pc )
13.33 {
13.34 uint32_t ir;
13.35 - /* Read instruction */
13.36 - if( IS_IN_ICACHE(pc) ) {
13.37 - ir = *(uint16_t *)GET_ICACHE_PTR(pc);
13.38 - } else {
13.39 + /* Read instruction from icache */
13.40 + assert( IS_IN_ICACHE(pc) );
13.41 + ir = *(uint16_t *)GET_ICACHE_PTR(pc);
13.42 +
13.43 + /* PC is not in the current icache - this usually means we're running
13.44 + * with MMU on, and we've gone past the end of the page. And since
13.45 + * sh4_translate_block is pretty careful about this, it means we're
13.46 + * almost certainly in a delay slot.
13.47 + *
13.48 + * Since we can't assume the page is present (and we can't fault it in
13.49 + * at this point, inline a call to sh4_execute_instruction (with a few
13.50 + * small repairs to cope with the different environment).
13.51 + */
13.52 ir = sh4_read_word(pc);
13.53 - }
13.54 +
13.55 if( !sh4_x86.in_delay_slot ) {
13.56 sh4_x86_add_recovery(pc);
13.57 }
13.58 @@ -488,8 +504,10 @@
13.59 MOV_r32_r32( R_EAX, R_ECX );
13.60 AND_imm32_r32( 0xFC000000, R_EAX );
13.61 CMP_imm32_r32( 0xE0000000, R_EAX );
13.62 - JNE_rel8(CALL_FUNC1_SIZE, end);
13.63 + JNE_rel8(8+CALL_FUNC1_SIZE, end);
13.64 call_func1( sh4_flush_store_queue, R_ECX );
13.65 + TEST_r32_r32( R_EAX, R_EAX );
13.66 + JE_exc(-1);
13.67 JMP_TARGET(end);
13.68 sh4_x86.tstate = TSTATE_NONE;
13.69 }
14.1 --- a/src/sh4/sh4x86.in Mon Jan 14 09:08:58 2008 +0000
14.2 +++ b/src/sh4/sh4x86.in Mon Jan 14 10:23:49 2008 +0000
14.3 @@ -125,7 +125,7 @@
14.4 xlat_recovery[xlat_recovery_posn].sh4_icount = (pc - sh4_x86.block_start_pc)>>1;
14.5 xlat_recovery_posn++;
14.6 }
14.7 -
14.8 +
14.9 /**
14.10 * Emit an instruction to load an SH4 reg into a real register
14.11 */
14.12 @@ -355,11 +355,18 @@
14.13 #endif
14.14 #endif
14.15
14.16 +void sh4_translate_emit_breakpoint( sh4vma_t pc )
14.17 +{
14.18 + load_imm32( R_EAX, XLAT_EXIT_BREAKPOINT );
14.19 + call_func1( sh4_translate_exit, R_EAX );
14.20 +}
14.21 +
14.22
14.23 /**
14.24 * Translate a single instruction. Delayed branches are handled specially
14.25 * by translating both branch and delayed instruction as a single unit (as
14.26 *
14.27 + * The instruction MUST be in the icache (assert check)
14.28 *
14.29 * @return true if the instruction marks the end of a basic block
14.30 * (eg a branch or
14.31 @@ -367,12 +374,21 @@
14.32 uint32_t sh4_translate_instruction( sh4addr_t pc )
14.33 {
14.34 uint32_t ir;
14.35 - /* Read instruction */
14.36 - if( IS_IN_ICACHE(pc) ) {
14.37 - ir = *(uint16_t *)GET_ICACHE_PTR(pc);
14.38 - } else {
14.39 + /* Read instruction from icache */
14.40 + assert( IS_IN_ICACHE(pc) );
14.41 + ir = *(uint16_t *)GET_ICACHE_PTR(pc);
14.42 +
14.43 + /* PC is not in the current icache - this usually means we're running
14.44 + * with MMU on, and we've gone past the end of the page. And since
14.45 + * sh4_translate_block is pretty careful about this, it means we're
14.46 + * almost certainly in a delay slot.
14.47 + *
14.48 + * Since we can't assume the page is present (and we can't fault it in
14.49 + * at this point, inline a call to sh4_execute_instruction (with a few
14.50 + * small repairs to cope with the different environment).
14.51 + */
14.52 ir = sh4_read_word(pc);
14.53 - }
14.54 +
14.55 if( !sh4_x86.in_delay_slot ) {
14.56 sh4_x86_add_recovery(pc);
14.57 }
14.58 @@ -2425,8 +2441,10 @@
14.59 MOV_r32_r32( R_EAX, R_ECX );
14.60 AND_imm32_r32( 0xFC000000, R_EAX );
14.61 CMP_imm32_r32( 0xE0000000, R_EAX );
14.62 - JNE_rel8(CALL_FUNC1_SIZE, end);
14.63 + JNE_rel8(8+CALL_FUNC1_SIZE, end);
14.64 call_func1( sh4_flush_store_queue, R_ECX );
14.65 + TEST_r32_r32( R_EAX, R_EAX );
14.66 + JE_exc(-1);
14.67 JMP_TARGET(end);
14.68 sh4_x86.tstate = TSTATE_NONE;
14.69 :}
.