VirtualBox

Changeset 2422 in vbox for trunk/src


Ignore:
Timestamp:
Apr 30, 2007 12:03:47 PM (18 years ago)
Author:
vboxsync
Message:

Removed the old recompiler code.

Location:
trunk/src
Files:
3 deleted
32 edited
12 copied

Legend:

Unmodified
Added
Removed
  • trunk/src/Makefile

    r1697 r2422  
    3131endif
    3232
    33 SUBDIRS += bldprogs libs VBox
    34 #ifeq ($(filter linux.x86 l4.x86 win.x86 os2.x86,$(BUILD_TARGET).$(BUILD_TARGET_ARCH)),)
    35  SUBDIRS += recompiler/new
    36 #else
    37 # SUBDIRS += recompiler
    38 #endif
     33SUBDIRS += bldprogs libs VBox recompiler
    3934ifneq ($(wildcard apps),)
    4035 SUBDIRS += apps
  • trunk/src/recompiler/InnoTek/Makefile.kmk

    r1 r2422  
    1818DEPTH = ../../..
    1919include $(PATH_KBUILD)/up.kmk
    20 
  • trunk/src/recompiler/InnoTek/config-host.h

    r1 r2422  
     1/* $Id$ */
    12/** @file
    23 * Innotek Host Config - Maintained by hand
     
    1920 */
    2021
    21 #define HOST_I386 1
    22 #ifdef __WIN32__
    23 # define CONFIG_WIN32 1
    24 #elif defined(__OS2__)
    25 # define CONFIG_OS2
    26 #elif defined(__DARWIN__)
    27 # define CONFIG_DARWIN
     22
     23#if defined(__amd64__) || defined(HOST_X86_64) /* latter, for dyngen on win64. */
     24# define HOST_X86_64 1
     25# define HOST_LONG_BITS 64
    2826#else
    29 # define HAVE_BYTESWAP_H 1
     27# define HOST_I386 1
     28# define HOST_LONG_BITS 32
     29# ifdef __WIN32__
     30#  define CONFIG_WIN32 1
     31# elif defined(__OS2__)
     32#  define CONFIG_OS2
     33# elif defined(__DARWIN__)
     34#  define CONFIG_DARWIN
     35# elif defined(__FREEBSD__) || defined(__NETBSD__) || defined(__OPENBSD__)
     36/*#  define CONFIG_BSD*/
     37# elif defined(__SOLARIS__)
     38/*#  define CONFIG_SUN*/
     39# elif !defined(IPRT_NO_CRT)
     40#  define HAVE_BYTESWAP_H 1
     41# endif
    3042#endif
    31 #define CONFIG_SOFTMMU 1
     43#define QEMU_VERSION "0.8.1"
     44#define CONFIG_UNAME_RELEASE ""
     45#define CONFIG_QEMU_SHAREDIR "."
    3246
    33 #define CONFIG_SDL 1
    34 #define CONFIG_SLIRP 1
    35 
    36 #ifdef __LINUX__
    37 #define CONFIG_GDBSTUB 1
    38 #endif
    39 /* #define HAVE_GPROF 1 */
    40 /* #define CONFIG_STATIC 1 */
    41 #define QEMU_VERSION "0.6.1"
    42 #define CONFIG_QEMU_SHAREDIR "."
  • trunk/src/recompiler/InnoTek/config.h

    r1 r2422  
     1/* $Id$ */
    12/** @file
    23 * Innotek Config - Maintained by hand
     
    2425#define TARGET_I386 1
    2526#define CONFIG_SOFTMMU 1
     27
  • trunk/src/recompiler/Makefile.kmk

    r1 r2422  
     1# $Id$
    12## @file
    2 #
    3 # !GNU MAKE!
     3# The Recompiler Makefile.
     4#
     5# There are a few of complicating factors here, esp. on AMD64 systems:
     6#
     7#   * op.c doesn't compile work correctly with gcc 4. For this we've
     8#     checked in op.S, which is the reason why we don't compile op.c
     9#     directly but always compile via the assembly file.s
     10#   * On 64-bit Windows we lack a compiler and have to resort to a
     11#     linux cross compiler building an ELF relocatable module which
     12#     we then load using a wrapper module. Thus the REM_MOD mess.
     13#   * On platforms using the 64-bit GCC ABI, we're not allowed to
     14#     generate non-PIC shared objects, and op.c requires the code
     15#     to be non-PIC. We apply the same trick as we developed for
     16#     64-bit windows.
     17#
     18
    419#
    520# Copyright (C) 2006 InnoTek Systemberatung GmbH
     
    2237include $(PATH_KBUILD)/header.kmk
    2338
     39
    2440# todo this is a BUILD_PLATFORM binary, to a target binary!
    25 ifeq ($(filter darwin,$(BUILD_TARGET)),)
    26  ifeq ($(VBOX_USING_GCC4),)
    27   BLDPROGS            = dyngen
    28  endif
    29  DLLS                 = VBoxREM
    30  ifeq ($(BUILD_TARGET_ARCH),amd64)
    31   SYSMODS             = VBoxREM2
    32   REM_MOD             = VBoxREM2
    33  else
    34   REM_MOD             = VBoxREM
    35  endif
    36 endif # !darwin
     41BLDPROGS              = dyngen
     42ifeq ($(BUILD_TARGET_ARCH),amd64)
     43 SYSMODS              = VBoxREM2
     44 REM_MOD              = VBoxREM2
     45else
     46 REM_MOD              = VBoxREM
     47endif
     48DLLS                  = VBoxREM
    3749IMPORT_LIBS           = VBoxREMImp
    38 GPLEXPORTS            = qemu-source-drop
    3950
    4051OTHER_CLEAN           = \
     
    4253        $(PATH_$(REM_MOD))/opc.h \
    4354        $(PATH_$(REM_MOD))/gen-op.h \
    44         $(PATH_$(REM_MOD))/opc.h \
    45         $(PATH_TARGET)/VBoxREMImp.c
    46 
    47 #DEFS += DEBUG_DISAS
    48 
    49 # private hack for gcc 4.1
    50 ifeq ($(USERNAME).$(BUILD_TARGET),bird.linux)
    51  TOOL_GCC3_CC = gcc-3.4.6
    52  override VBOX_GCC_Wno-variadic-macros=
    53  override VBOX_USING_GCC4=
    54 endif
    55 
     55        $(PATH_$(REM_MOD))/opc.h
     56
     57DEFS.amd64 += REM_PHYS_ADDR_IN_TLB
     58
     59#
     60# L4 must use the no-crt path because it's lacking math stuff it seems...
     61# Darwin must use the non-crt path because it can't compile op.c nativly.
     62# All the AMD64 target must use the no-crt path because ELF doesn't like op.c
     63# when stuffed into a shared library and windows doesn't have 64-bit gcc (yet).
     64#
     65ifeq ($(filter-out l4 darwin freebsd,$(BUILD_TARGET)),)
     66 REM_USE_NOCRT := 1
     67endif
     68ifeq ($(BUILD_TARGET_ARCH),amd64)
     69 REM_USE_NOCRT := 1
     70endif
     71
     72
     73#
     74# The dyngen build tool.
     75#
    5676ifeq ($(BUILD_PLATFORM),win)
    5777 dyngen_TOOL          = MINGW32
     
    6080 dyngen_BLD_TRG_ARCH  = x86
    6181 dyngen_BLD_TRG_CPU   = i386
    62  dyngen_CFLAGS        = -Wall -g -fno-strict-aliasing
     82 dyngen_CFLAGS        = -Wall -g -fno-strict-aliasing
     83 ifeq ($(BUILD_TARGET_ARCH),amd64)
     84  dyngen_DEFS        += HOST_X86_64=1
     85 endif
    6386else
    64  dyngen_TEMPLATE      = VBOXBLDPRO
    65 endif
     87 dyngen_TEMPLATE      = VBOXBLDPROG
     88endif
     89dyngen_CFLAGS        += -Wno-missing-prototypes -Wno-missing-declarations
    6690dyngen_INCS           = \
    6791        InnoTek \
    6892        target-i386 \
    69         fpu \
    70         $(PATH_ROOT)/ ## @todo what is $(PATH_ROOT) doing here?
     93        fpu
    7194dyngen_SOURCES        = dyngen.c
    7295
    7396
    7497#
    75 # The VBoxREM or VBoxREM2 DLL/SO.
    76 #
    77 $(REM_MOD)_TOOL          = GCC3
    78 $(REM_MOD)_TOOL.win.x86  = MINGW32
    79 $(REM_MOD)_TOOL.win.amd64= XGCCAMD64LINUX
    80 $(REM_MOD)_SDKS.win.x86  = W32API                                                       ## @todo do we really need this now?
    81 $(REM_MOD)_ASFLAGS       = -x assembler-with-cpp                        ## @todo didn't I make this default already?
    82 $(REM_MOD)_SYSSUFF       = .rel                             # amd64
    83 
    84 $(REM_MOD)_CFLAGS        = -Wall -g
    85 ifdef ($(BUILD_TARGET),win64) # with -O1 and higher, it generates incorrect code for double and long double constants. ## @todo didn't I fix this yet?
    86  REMNoCRT_CFLAGS.release  = -O0
    87  $(REM_MOD)_CFLAGS.amd64  = -mcmodel=medium -fno-common -O0 -fno-strict-aliasing -fno-math-errno -fno-peephole2
    88 else
    89 $(REM_MOD)_CFLAGS.amd64  = -mcmodel=medium -fno-common -O2 -fno-strict-aliasing
    90 endif
    91 $(REM_MOD)_CFLAGS.debug  = -O0
    92 ifdef ($(BUILD_TARGET_ARCH),x86)
    93 $(REM_MOD)_CFLAGS.release += -fomit-frame-pointer -fno-gcse
    94 endif
    95 $(REM_MOD)_CFLAGS.profile = $($(REM_MOD)_CFLAGS.release)
    96 $(REM_MOD)_CFLAGS.kprofile = $($(REM_MOD)_CFLAGS.release)
    97 $(REM_MOD)_CFLAGS.l4     = -nostdinc
    98 $(REM_MOD)_INCS          = \
     98# The VBoxREM.[dll|so|..] or VBoxREM2.rel.
     99#
     100$(REM_MOD)_DEFS             = IN_REM_R3 REM_INCLUDE_CPU_H
     101#$(REM_MOD)_DEFS          += DEBUG_ALL_LOGGING DEBUG_DISAS DEBUG_PCALL DEBUG_EXEC DEBUG_FLUSH DEBUG_IOPORT DEBUG_SIGNAL DEBUG_TLB_CHECK DEBUG_TB_INVALIDATE DEBUG_TLB  # Enables huge amounts of debug logging.
     102
     103$(REM_MOD)_INCS             = \
    99104        InnoTek \
    100         InnoTek/crt \
     105        InnoTek/crt\
    101106        target-i386 \
    102107        fpu \
    103108        $(PATH_$(REM_MOD)) \
    104109        $(PATH_ROOT)/src/VBox/VMM
    105 ifeq ($(BUILD_TARGET),l4)
    106 $(REM_MOD)_INCS         += $(VBOX_L4_GCC3_INCS) $(L4_INCDIR)
    107 endif
    108 $(REM_MOD)_DEFS          = IN_RING3 IN_REM_R3 REM_INCLUDE_CPU_H #LOG_USE_C99
    109 #$(REM_MOD)_DEFS          += DEBUG_PCALL DEBUG_EXEC DEBUG_FLUSH DEBUG_IOPORT DEBUG_SIGNAL DEBUG_TLB_CHECK DEBUG_TB_INVALIDATE DEBUG_TLB  # Enables huge amounts of debug logging.
    110 # these defines are probably all irrelevant now:
    111 $(REM_MOD)_DEFS         += _GNU_SOURCE _FILE_OFFSET_BITS=64 _LARGEFILE_SOURCE _REENTRANT
    112 ifeq ($(VBOX_USING_GCC4),)
    113  $(REM_MOD)_SOURCES      = \
     110
     111$(REM_MOD)_SOURCES          = \
    114112        VBoxRecompiler.c \
    115113        cpu-exec.c \
    116114        exec.c \
    117115        translate-all.c \
     116        translate-op.c \
     117        fpu/softfloat-native.c \
    118118        target-i386/helper.c \
    119119        target-i386/helper2.c \
    120         target-i386/translate.c
    121 #       translate-op.c \
    122 #       fpu/softfloat-native.c \
    123 #       InnoTek/testmath.c
    124 
    125 # ***hacking***
    126 # ifeq ($(filter-out win os2,$(BUILD_TARGET)),)
    127   $(REM_MOD)_SOURCES    += target-i386/op.c
    128   FILE_OP_OBJ            = $(PATH_$(REM_MOD)_target-i386/op.c)/op.o
    129 # else # The remaining targets can be using gcc-4 and needs checking.
    130 #  $(REM_MOD)_SOURCES    += $(PATH_$(REM_MOD))/op.S
    131 #  FILE_OP_OBJ            = $(PATH_$(REM_MOD)_$(PATH_$(REM_MOD))/op.S)/op.o
    132 #  $(REM_MOD)_CLEAN       = $(FILE_OP_OBJ)
    133 # endif
    134  $(REM_MOD)_SOURCES     += InnoTek/loghack.c                                                            # this will be obsoleted soon.
    135 else
    136  $(REM_MOD)_SOURCES      = \
    137         precompiled/VBoxRecompiler.o \
    138         precompiled/cpu-exec.o \
    139         precompiled/exec.o \
    140         precompiled/translate-all.o \
    141         precompiled/op.o \
    142         precompiled/helper.o \
    143         precompiled/helper2.o \
    144         precompiled/translate.o \
    145         precompiled/loghack.o
    146  FILE_OP_OBJ             = precompiled/op.o
    147 endif
    148 $(REM_MOD)_DEFS         += fprintf=hacked_fprintf printf=hacked_printf      # ditto
    149 ifneq ($(BUILD_TYPE),debug)
    150 $(REM_MOD)_SOURCES.win.x86 = $(REM_MOD).def
    151 else
    152 $(REM_MOD)_LDFLAGS.win.x86 = --export-all-symbols --output-def $(PATH_TARGET)/$(REM_MOD)-new.def \
    153         --exclude-symbols=console_main --exclude-symbols=WinMain@16
    154 endif
    155 $(REM_MOD)_SOURCES.os2   = $(PATH_TARGET)/VBoxREMOS2.def
    156 $(REM_MOD)_LDFLAGS.linux = -Wl,--no-undefined
    157 $(REM_MOD)_LDFLAGS.l4    = -T$(L4_LIBDIR)/../main_rel.ld -nostdlib -Wl,--no-undefined
    158 
    159 ifeq ($(BUILD_TARGET_ARCH),amd64)
    160 $(REM_MOD)_LIBS           = \
    161         $(LIB_RUNTIME_NOCRT_GCC64) # !create this!
    162 #       $(VBOX_GCC_LIBGCC)  - fix this
    163 else # x86
    164 $(REM_MOD)_LIBS           = \
    165         $(LIB_VMM) \
    166         $(LIB_RUNTIME)
    167 $(REM_MOD)_LIBS.win       = \
    168         mingw32 \
    169         user32 gdi32 winmm ws2_32 iphlpapi dxguid
    170 $(REM_MOD)_LIBS.linux     = \
    171         $(LIB_UUID) \
    172         m \
    173         util \
    174         rt \
    175         $(LIB_PTHREAD)
    176 $(REM_MOD)_LIBS.l4        = \
    177         gcc \
    178         $(L4_LIBDIR)/libvboxserver.s.so \
    179         $(L4_LIBDIR)/libdl.s.so \
    180         $(L4_LIBDIR)/libuc.0.s.so
    181 endif # x86
     120        target-i386/translate.c \
     121        InnoTek/testmath.c
     122ifeq ($(filter-out win os2,$(BUILD_TARGET)),)
     123 $(REM_MOD)_SOURCES        += target-i386/op.c
     124 FILE_OP_OBJ                = $(PATH_$(REM_MOD)_target-i386/op.c)/op.o
     125else # The remaining targets can be using gcc-4 and needs checking.
     126 $(REM_MOD)_SOURCES        += $(PATH_$(REM_MOD))/op.S
     127 FILE_OP_OBJ                = $(PATH_$(REM_MOD)_$(PATH_$(REM_MOD))/op.S)/op.o
     128 $(REM_MOD)_CLEAN           = $(FILE_OP_OBJ) $(PATH_$(REM_MOD))/op.S.dep
     129endif
     130#$(REM_MOD)_SOURCES.os2      = $(PATH_TARGET)/$(REM_MOD).def
     131$(REM_MOD)_SOURCES.win.x86  = $(REM_MOD).def
     132
     133
     134ifdef REM_USE_NOCRT
     135 $(REM_MOD)_TEMPLATE        = VBOXNOCRTGAS
     136 $(REM_MOD)_DEFS           += LOG_USE_C99
     137 $(REM_MOD)_CFLAGS.amd64    = -O2
     138 $(REM_MOD)_CFLAGS.debug    = -O0
     139 $(REM_MOD)_CFLAGS.darwin   = -fno-common -mdynamic-no-pic
     140 ifdef ($(BUILD_TARGET_ARCH),x86)
     141  $(REM_MOD)_CFLAGS.release+= -fomit-frame-pointer -fno-gcse
     142 endif
     143
     144 # This doesn't fit in IPRT because it requires GAS and is LGPL.
     145 $(REM_MOD)_SOURCES        += \
     146        InnoTek/e_powl-$(BUILD_TARGET_ARCH).S
     147
     148 ifeq ($(REM_MOD),VBoxREM)
     149  $(REM_MOD)_LIBS           = \
     150        $(PATH_LIB)/RuntimeR3NoCRTGCC$(VBOX_SUFF_LIB) \
     151        $(LIB_VMM) \
     152        $(LIB_RUNTIME)
     153  $(REM_MOD)_LIBS.darwin    = \
     154        $(TARGET_VBoxREMImp)
     155#       $(PATH_BIN)/VBoxREMImp.dylib
     156  $(REM_MOD)_LDFLAGS.darwin  = -read_only_relocs suppress -multiply_defined warning  #-install_name @executable_path/$(REM_MOD).dylib#
     157 else
     158  $(REM_MOD)_LIBS           = \
     159        $(PATH_LIB)/RuntimeR3NoCRTGCC$(VBOX_SUFF_LIB)
     160  $(REM_MOD)_SYSSUFF        = .rel
     161 endif
     162
     163else # !REM_USE_NOCRT
     164
     165 $(REM_MOD)_TOOL            = GCC3
     166 $(REM_MOD)_TOOL.win.x86    = MINGW32
     167 $(REM_MOD)_TOOL.win.amd64  = XGCCAMD64LINUX
     168 $(REM_MOD)_SDKS.win.x86    = W32API                                                    ## @todo do we really need this now?
     169 $(REM_MOD)_ASFLAGS         = -x assembler-with-cpp                     ## @todo didn't I make this default already?
     170 $(REM_MOD)_CFLAGS          = -Wall -g
     171 $(REM_MOD)_CFLAGS.debug    = -O0
     172 $(REM_MOD)_CFLAGS.release += -fomit-frame-pointer -fno-gcse
     173 $(REM_MOD)_CFLAGS.profile  = $($(REM_MOD)_CFLAGS.release)
     174 $(REM_MOD)_CFLAGS.kprofile = $($(REM_MOD)_CFLAGS.release)
     175 $(REM_MOD)_CFLAGS.l4       = -nostdinc
     176 ifeq ($(BUILD_TARGET),l4)
     177  $(REM_MOD)_INCS          += $(VBOX_L4_GCC3_INCS) $(L4_INCDIR)
     178 endif
     179
     180 $(REM_MOD)_DEFS           += IN_RING3 LOG_USE_C99
     181 #$(REM_MOD)_DEFS          += DEBUG_DISAS DEBUG_PCALL DEBUG_EXEC DEBUG_FLUSH DEBUG_IOPORT DEBUG_SIGNAL DEBUG_TLB_CHECK DEBUG_TB_INVALIDATE DEBUG_TLB  # Enables huge amounts of debug logging.
     182 # these defines are probably all irrelevant now:
     183 $(REM_MOD)_DEFS           += _GNU_SOURCE _FILE_OFFSET_BITS=64 _LARGEFILE_SOURCE _REENTRANT
     184
     185 $(REM_MOD)_LDFLAGS.darwin  = -read_only_relocs suppress -install_name @executable_path/$(REM_MOD).dylib -multiple_defined warning
     186 $(REM_MOD)_LDFLAGS.l4      = -T$(L4_LIBDIR)/../main_rel.ld -nostdlib -Wl,--no-undefined
     187 $(REM_MOD)_LDFLAGS.os2     = -Zomf
     188 $(REM_MOD)_LDFLAGS.debug   = -g
     189 ifeq ($(BUILD_TARGET_ARCH),amd64)
     190  $(REM_MOD)_LIBS           = $(FILE_TOOL_GCC3_LIBGCC)
     191 else # x86
     192  $(REM_MOD)_LIBS           = \
     193        $(LIB_VMM) \
     194        $(LIB_RUNTIME)
     195  $(REM_MOD)_LIBS.win.x86   = \
     196        mingw32 \
     197        user32 gdi32 winmm ws2_32 iphlpapi dxguid
     198  $(REM_MOD)_LIBS.linux     = \
     199        $(LIB_UUID) \
     200        m \
     201        util \
     202        rt \
     203        $(LIB_PTHREAD)
     204  $(REM_MOD)_LIBS.l4        = \
     205        gcc \
     206        $(L4_LIBDIR)/libvboxserver.s.so \
     207        $(L4_LIBDIR)/libdl.s.so \
     208        $(L4_LIBDIR)/libuc.0.s.so
     209 endif # x86
     210
     211endif # !REM_USE_NOCRT
    182212
    183213# Extra flags for these source modules.
    184214target-i386/op.c_CFLAGS         = -O2 -fno-strict-aliasing -fomit-frame-pointer -falign-functions=0 -fno-reorder-blocks -fno-optimize-sibling-calls
    185215target-i386/op.c_CFLAGS.x86     = -fno-gcse -fno-instrument-functions -mpreferred-stack-boundary=2
     216target-i386/op.c_CFLAGS.darwin.x86 = -m128bit-long-double -mpreferred-stack-boundary=4 ## @todo This means we can't use staged/op-elf-x86.s...
    186217target-i386/helper.c_CFLAGS.x86 = -O2 -fomit-frame-pointer -fno-strict-aliasing -fno-gcse
    187218cpu-exec.c_CFLAGS.x86           = -O2 -fomit-frame-pointer -fno-strict-aliasing -fno-gcse
     219
     220
     221#
     222# The math testcase as a standalone program for testing and debugging purposes.
     223#
     224## @todo This is a bit messy because of MINGW32.
     225#BLDPROGS += testmath
     226testmath_TOOL           = GCC3
     227testmath_TOOL.win.x86   = MINGW32
     228testmath_SDKS.win.x86   = W32API
     229ifeq ($(BUILD_PLATFORM).$(BUILD_PLATFORM_ARCH),win.amd64)
     230 # 64-bit windows: Pretend to be 32-bit.
     231 testmath_BLD_TRG       = win32
     232 testmath_BLD_TRG_ARCH  = x86
     233 testmath_BLD_TRG_CPU   = i386
     234endif
     235testmath_ASTOOL         = $(VBOX_ASTOOL)
     236ifeq ($(filter-out win32 win64,$(BUILD_PLATFORM)),)
     237 testmath_ASFLAGS        = -f win32 -DNASM_FORMAT_PE $(VBOX_ASFLAGS) -w+orphan-labels
     238else
     239 testmath_ASFLAGS        = -f elf -DNASM_FORMAT_ELF $(VBOX_ASFLAGS) -w+orphan-labels
     240endif
     241testmath_ASFLAGS.amd64  = -m amd64
     242testmath_CFLAGS         = -Wall -g
     243testmath_CFLAGS.release = -O3
     244testmath_LDFLAGS        = -g
     245testmath_DEFS           = MATHTEST_STANDALONE
     246testmath_SOURCES        = InnoTek/testmath.c
     247#testmath_SOURCES        += $(PATH_LIB)/RuntimeR3NoCRTGCC$(VBOX_SUFF_LIB)
    188248
    189249
     
    197257        VBoxREMWrapper.cpp \
    198258        VBoxREMWrapperA.asm
     259VBoxREM_LDFLAGS.darwin = -install_name @executable_path/VBoxREM.dylib
    199260VBoxREM_LIBS           = \
    200261        $(LIB_VMM) \
     
    207268#
    208269VBoxREMImp_TEMPLATE         = VBOXR3
     270ifeq ($(BUILD_TARGET),darwin)
     271VBoxREMImp_INST             = $(INST_LIB)
     272endif
    209273VBoxREMImp_SOURCES.win      = VBoxREM.def
    210274VBoxREMImp_SOURCES.os2      = $(PATH_TARGET)/VBoxREMOS2.def
    211275ifeq ($(filter win os2,$(BUILD_TARGET)),)
    212276VBoxREMImp_SOURCES          = $(PATH_TARGET)/VBoxREMImp.c
     277VBoxREMImp_CLEAN            = $(PATH_TARGET)/VBoxREMImp.c
    213278endif
    214279VBoxREMImp_SONAME.linux     = VBoxREM.so
    215280VBoxREMImp_SONAME.l4        = VBoxREM.s.so
    216 VBoxREMImp_LDFLAGS.darwin   = -install_name VBoxREM.dylib
     281VBoxREMImp_LDFLAGS.darwin   = -install_name @executable_path/VBoxREM.dylib
     282#VBoxREMImp_LDFLAGS.darwin   = -install_name VBoxREM.dylib
    217283VBoxREMImp_LDFLAGS.l4       = -T$(L4_LIBDIR)/../main_rel.ld -nostdlib
    218284
     
    238304# Generate the op.S file somehow...
    239305#
    240 # Gathering the flags, defines and include dirs for the command is a lot 
    241 # of work. Unfortunately, there is only a highly specialized kBuild function 
     306# Gathering the flags, defines and include dirs for the command is a lot
     307# of work. Unfortunately, there is only a highly specialized kBuild function
    242308# for doing this, so we're currently left to our own devices here.
    243309#
    244 
     310# Add something like VBOX_RECOMPILER_OP_GCC = gcc-3.4.6 to LocalConfig.kmk
     311# to be 100% sure that you get a working op.S. My gcc 4.1.1 seems to work
     312# fine, so feel free to try VBOX_RECOMPILER_OP_GCC = gcc.
     313#
     314# The op-undefined.lst is generated by finding all the undefined symbols
     315# in one (or more) ELF op.o files using nm.
     316#
    245317ifndef VBOX_RECOMPILER_OP_GCC
    246318 ifeq ($(BUILD_TARGET).$(BUILD_TARGET_ARCH),darwin.x86)
    247   VBOX_RECOMPILER_OP_GCC ?= gcc-elf-something
    248  endif
    249  ifeq ($(USERNAME).$(BUILD_TARGET),bird.linux)
    250   VBOX_RECOMPILER_OP_GCC ?= gcc-3.4.6
    251  endif
    252  VBOX_RECOMPILER_OP_GCC ?= $(TOOL_$(VBOX_GCC_TOOL)_CC)
    253  VBOX_RECOMPILER_OP_GCC ?= false
    254 endif
    255 
    256 ## @todo Check gcc version if plain gcc, gcc32 or gcc64.
    257 ## @todo minimal dependencies.
    258 
    259 $(PATH_$(REM_MOD))/op.S: target-i386/op.c staged/op-elf-$(BUILD_TARGET_ARCH).S | $(call DIRDEP,$(PATH_$(REM_MOD)))
    260         $(RM) -f $@ [email protected] [email protected]
    261         $(VBOX_RECOMPILER_OP_GCC) $(addsuffix $(SP)\$(NL)$(TAB),\
    262                 -S -s \
    263                 $(filter-out -g -O0, \
    264                         $($(REM_MOD)_CFLAGS) $($(REM_MOD)_CFLAGS.$(BUILD_TYPE)) $($(REM_MOD)_CFLAGS.$(BUILD_TARGET_ARCH)) \
    265                         $(target-i386/op.c_CFLAGS) $(target-i386/op.c_CFLAGS.$(BUILD_TARGET_ARCH)) \
    266                         ) \
    267                 $(addprefix -I, \
    268                         $($(REM_MOD)_CINCS.$(BUILD_TARGET_ARCH)) $($(REM_MOD)_CINCS.$(BUILD_TARGET)) $($(REM_MOD)_CINCS) $(CINCS) \
    269                         $($(REM_MOD)_INCS.$(BUILD_TARGET_ARCH))  $($(REM_MOD)_INCS.$(BUILD_TARGET))  $($(REM_MOD)_INCS) $(INCS) \
    270                         ) \
    271                 $(addprefix -D, \
    272                         $($(REM_MOD)_CDEFS.$(BUILD_TARGET_ARCH)) $($(REM_MOD)_CDEFS.$(BUILD_TARGET)) $($(REM_MOD)_CDEFS) $(CDEFS.$(BUILD_TARGET)) $(CDEFS.release) $(CDEFS) \
    273                         $($(REM_MOD)_DEFS.$(BUILD_TARGET_ARCH))  $($(REM_MOD)_DEFS.$(BUILD_TARGET))  $($(REM_MOD)_DEFS)  $(DEFS.$(BUILD_TARGET))  $(DEFS.release)  $(DEFS) \
    274                         ) \
     319  VBOX_RECOMPILER_OP_GCC ?= i386-elf-gcc-3.4.3 # (port install i386-gcc-elf)
     320  VBOX_RECOMPILER_OP_GCC_OK := yes
     321  VBOX_RECOMPILER_OP_GCC_INCS ?= $(abspath $(dir $(shell LC_ALL=C $(VBOX_RECOMPILER_OP_GCC) -print-libgcc-file-name)))/include
     322 endif
     323 ifndef VBOX_RECOMPILER_OP_GCC
     324  VBOX_RECOMPILER_OP_GCC := $(TOOL_$(VBOX_GCC_TOOL)_CC)
     325  VBOX_RECOMPILER_OP_GCC_OK := dunno
     326 endif
     327else
     328 # If set, assume it's an OK compiler.
     329 VBOX_RECOMPILER_OP_GCC_OK := yes
     330endif
     331
     332
     333# The command sans -o op.S.tmp.
     334COMPILE_OP_CMDS = $(VBOX_RECOMPILER_OP_GCC) \
     335        -S -s \
     336        $(filter-out -g -O0, \
     337                $($(REM_MOD)_CFLAGS) $($(REM_MOD)_CFLAGS.$(BUILD_TYPE)) $($(REM_MOD)_CFLAGS.$(BUILD_TARGET)) $($(REM_MOD)_CFLAGS.$(BUILD_TARGET_ARCH)) $($(REM_MOD)_CFLAGS.$(BUILD_TARGET).$(BUILD_TARGET_ARCH)) \
     338                $(target-i386/op.c_CFLAGS) $(target-i386/op.c_CFLAGS.$(BUILD_TARGET)) $(target-i386/op.c_CFLAGS.$(BUILD_TARGET_ARCH)) $(target-i386/op.c_CFLAGS.$(BUILD_TARGET).$(BUILD_TARGET_ARCH)) \
     339                ) \
     340        $(addprefix -I, \
     341                $($(REM_MOD)_CINCS.$(BUILD_TARGET_ARCH)) $($(REM_MOD)_CINCS.$(BUILD_TARGET)) $($(REM_MOD)_CINCS) $(CINCS) \
     342                $($(REM_MOD)_INCS.$(BUILD_TARGET_ARCH))  $($(REM_MOD)_INCS.$(BUILD_TARGET))  $($(REM_MOD)_INCS) $(INCS) \
     343                ) \
     344        $(addprefix -D, \
     345                $($(REM_MOD)_CDEFS.$(BUILD_TARGET_ARCH)) $($(REM_MOD)_CDEFS.$(BUILD_TARGET)) $($(REM_MOD)_CDEFS) $(CDEFS.$(BUILD_TARGET)) $(CDEFS.$(BUILD_TARGET_ARCH)) $(CDEFS.$(BUILD_TYPE)) $(CDEFS) \
     346                $($(REM_MOD)_DEFS.$(BUILD_TARGET_ARCH))  $($(REM_MOD)_DEFS.$(BUILD_TARGET))  $($(REM_MOD)_DEFS)  $(DEFS.$(BUILD_TARGET))  $(DEFS.$(BUILD_TARGET_ARCH))  $(DEFS.$(BUILD_TYPE))  $(DEFS) \
     347                ) \
     348        -Wp,-MD,$(PATH_$(REM_MOD))/op.S.dep \
     349        -Wp,-MT,$(PATH_$(REM_MOD))/op.S \
     350        -Wp,-MP \
     351        target-i386/op.c
     352
     353# Use the right GCC includes.
     354ifdef VBOX_RECOMPILER_OP_GCC_INCS
     355COMPILE_OP_CMDS := $(subst $(VBOX_PATH_GCC_INCS),$(VBOX_RECOMPILER_OP_GCC_INCS),$(COMPILE_OP_CMDS))
     356endif
     357
     358# Drop incompatible options when using the cross-compiler on darwin.
     359ifeq ($(BUILD_TARGET),darwin)
     360 ifeq ($(filter-out i386-elf-gcc%, $(VBOX_RECOMPILER_OP_GCC)),)
     361  COMPILE_OP_CMDS := $(filter-out -mdynamic-no-pic, $(COMPILE_OP_CMDS))
     362 endif
     363endif
     364
     365# include the dependencies
     366-include $(PATH_$(REM_MOD))/op.S.dep
     367
     368# The rule.
     369$(PATH_$(REM_MOD))/op.S: \
    275370                target-i386/op.c \
    276                 ) -o [email protected] \
    277                 || $(CP) staged/op-elf-$(BUILD_TARGET_ARCH).S [email protected] # @todo only do this with gcc-4.
    278         $(SED) -f op-validate.sed [email protected] || $(CP) staged/op-elf-$(BUILD_TARGET_ARCH).S [email protected] # This isn't good enough yet.
     371                staged/op-elf-$(BUILD_TARGET_ARCH).S \
     372                op-validate.sed \
     373                op-darwin.sed \
     374                op-undefined.lst \
     375                Makefile.kmk \
     376                $(comp-cmds COMPILE_OP_CMDS,COMPILE_OP_CMDS_PREV,FORCE) \
     377                | $(call DIRDEP,$(PATH_$(REM_MOD)))
     378        $(RM) -f $@ [email protected] [email protected] [email protected]
     379ifeq ($(VBOX_RECOMPILER_OP_GCC_OK),yes)
     380        $(call MSG_COMPILE,VBoxREM,$<,$@,AS)
     381        $(addsuffix $(SP)\$(NL)$(TAB)  ,$(COMPILE_OP_CMDS)) -o [email protected]
     382else ifeq ($(VBOX_RECOMPILER_OP_GCC_OK),dunno) # (permit 3.x.x and 4.1.x+ for now)
     383        major_ver=`$(VBOX_RECOMPILER_OP_GCC) -dumpversion | $(SED) -e 's/^\([2-9]\)\..*$$/\1/'`; \
     384        minor_ver=`$(VBOX_RECOMPILER_OP_GCC) -dumpversion | $(SED) -e 's/^[2-9]\.\([0-9]\)\..*$$/\1/'`; \
     385        bugfix_ver=`$(VBOX_RECOMPILER_OP_GCC) -dumpversion | $(SED) -e 's/^[2-9]\.[0-9]\.\([0-9]\).*$$/\1/'`; \
     386        if test "$$major_ver" = "3" -o "(" "$$major_ver" = "4" -a "$$minor_ver" != "0" ")"; then \
     387                $(ECHO_EXT) "Compiling $< => $@ [gcc v$${major_ver}.$${minor_ver}.$${bugfix_ver}]" && \
     388                $(addsuffix $(SP)\$(NL)$(TAB)$(TAB)  ,$(COMPILE_OP_CMDS)) -o [email protected]; \
     389        else \
     390                $(ECHO_EXT) "Using staged op.S [gcc v$${major_ver}.$${minor_ver}.$${bugfix_ver}]" && \
     391                $(CP_EXT) -f staged/op-elf-$(BUILD_TARGET_ARCH).S [email protected]; \
     392        fi
     393else
     394        $(CP) staged/op-elf-$(BUILD_TARGET_ARCH).S [email protected]
     395endif
     396        $(SED) -f op-validate.sed [email protected]
    279397ifeq ($(BUILD_TARGET),darwin)
    280398        $(SED) -f op-darwin.sed [email protected] > [email protected]
    281         $(MV) -f [email protected] [email protected]
     399        $(SED) -e 's/^\(.*\)$$/#define \1 _\1/' op-undefined.lst > [email protected]
     400        $(CAT_EXT) [email protected] >> [email protected]
    282401endif
    283402        $(MV) -f [email protected] $@
    284        
    285 
    286 # predefined dependencies to the headers are generated.
    287 translate-all.c:             $(PATH_$(REM_MOD))/op.h     $(PATH_$(REM_MOD))/opc.h
    288 target-i386/translate.c:     $(PATH_$(REM_MOD))/gen-op.h $(PATH_$(REM_MOD))/opc.h
    289 
    290 # atm this will be build because of the direct dependency.
     403        $(QUIET2)$(APPEND) "[email protected]"
     404        $(QUIET2)$(APPEND) "[email protected]" 'define COMPILE_OP_CMDS_PREV'
     405        $(QUIET2)$(APPEND) "[email protected]" '$(subst $(NL),'$(NL)$(TAB)@$(APPEND) "[email protected]" ',$(COMPILE_OP_CMDS))'
     406        $(QUIET2)$(APPEND) "[email protected]" 'endef'
     407
     408
     409# Hack for crosscompiling.
    291410DYNGEN = $(PATH_dyngen)/dyngen$(HOSTSUFF_EXE)
    292411DYNGEN_EXEC = $(DYNGEN)
     
    298417endif
    299418
    300 
     419# The dyngen rules.
    301420$(PATH_$(REM_MOD))/op.h:     $(FILE_OP_OBJ) $(DYNGEN)
    302421        $(call MSG_L1,dyngen => $@)
     
    311430        $(QUIET)$(DYNGEN_EXEC) -g -o $@ $<
    312431
     432# Dyngen dependants (sp?).
     433translate-all.c \
     434translate-op.c \
     435target-i386/translate.c \
     436        : $(PATH_$(REM_MOD))/op.h $(PATH_$(REM_MOD))/opc.h $(PATH_$(REM_MOD))/gen-op.h
     437
     438
     439# Some aliases
     440do_dyngen: $(PATH_$(REM_MOD))/gen-op.h $(PATH_$(REM_MOD))/opc.h $(PATH_$(REM_MOD))/op.h
    313441importlib: $(LIB_REM)
    314 
    315 
    316 #
    317 # Phony rule for making the qemu source drop.
    318 # This is just an incomplete EXAMPLE. It does NOT include all we have to ship!
    319 #
    320 .PHONY: qemu-source-drop
    321 qemu-source-drop:
    322         $(RM) -f $(PATH_BIN)/qemu-source.zip
    323         zip -9 $(PATH_BIN)/qemu-source.zip \
    324                 target-i386/op.c \
    325                 target-i386/helper.c \
    326                 target-i386/ops_template_mem.h \
    327                 target-i386/ops_sse.h \
    328                 target-i386/helper2.c \
    329                 target-i386/ops_template.h \
    330                 target-i386/ops_mem.h \
    331                 target-i386/translate-copy.c \
    332                 target-i386/exec.h \
    333                 target-i386/cpu.h \
    334                 target-i386/opreg_template.h \
    335                 target-i386/translate.c \
    336                 \
    337                 a.out.h \
    338                 COPYING.LIB \
    339                 cpu-defs.h \
    340                 dyngen.c \
    341                 dyngen.h \
    342                 elf.h \
    343                 exec.c \
    344                 softmmu_header.h \
    345                 translate-all.c \
    346                 bswap.h \
    347                 cpu-all.h \
    348                 cpu-exec.c \
    349                 disas.h \
    350                 dyngen-exec.h \
    351                 dyngen-op.h \
    352                 exec-all.h \
    353                 osdep.h \
    354                 softmmu_template.h \
    355                 vl.h \
    356                 \
    357                 tests/hello-arm.c \
    358                 tests/hello-i386.c \
    359                 tests/linux-test.c \
    360                 tests/Makefile \
    361                 tests/pi_10.com \
    362                 tests/qruncom.c \
    363                 tests/runcom.c \
    364                 tests/sha1.c \
    365                 tests/test-i386.c \
    366                 tests/test-i386-code16.S \
    367                 tests/test-i386.h \
    368                 tests/test-i386-muldiv.h \
    369                 tests/test-i386-shift.h \
    370                 tests/test-i386-vm86.S \
    371                 tests/test_path.c \
    372                 tests/testthread.c
    373 
     442op.S: $(PATH_$(REM_MOD))/op.S
     443
     444
  • trunk/src/recompiler/VBoxREM.def

    r1 r2422  
     1; $Id$
    12;; @file
    23;
  • trunk/src/recompiler/VBoxRecompiler.c

    r2223 r2422  
     1/* $Id$ */
    12/** @file
    2  *
    33 * VBox Recompiler - QEMU.
    44 */
     
    2424*   Header Files                                                               *
    2525*******************************************************************************/
     26#define LOG_GROUP LOG_GROUP_REM
    2627#include "vl.h"
    2728#include "exec-all.h"
     
    4748#include <VBox/err.h>
    4849
    49 #define LOG_GROUP LOG_GROUP_REM
    5050#include <VBox/log.h>
    5151#include <iprt/semaphore.h>
     
    5454#include <iprt/thread.h>
    5555#include <iprt/string.h>
    56 
    5756
    5857/* Don't wanna include everything. */
     
    8887static DECLCALLBACK(int) remR3Load(PVM pVM, PSSMHANDLE pSSM, uint32_t u32Version);
    8988static void     remR3StateUpdate(PVM pVM);
     89
     90#if defined(PGM_DYNAMIC_RAM_ALLOC) && !defined(REM_PHYS_ADDR_IN_TLB)
     91DECLINLINE(target_ulong) remR3HCVirt2GCPhysInlined(PVM pVM, void *addr);
     92DECLINLINE(void *) remR3GCPhys2HCVirtInlined(PVM pVM, target_ulong addr);
     93#endif
     94
    9095static uint32_t remR3MMIOReadU8(void *pvVM, target_phys_addr_t GCPhys);
    9196static uint32_t remR3MMIOReadU16(void *pvVM, target_phys_addr_t GCPhys);
     
    106111*   Global Variables                                                           *
    107112*******************************************************************************/
    108 
    109 /** The log level of the recompiler. */
    110 #if 1
    111 extern int loglevel;
    112 #else
    113 int loglevel = ~0;
    114 FILE *logfile = NULL;
    115 #endif
    116 
    117113
    118114/** @todo Move stats to REM::s some rainy day we have nothing do to. */
     
    128124static STAMPROFILEADV gStatMemRead;
    129125static STAMPROFILEADV gStatMemWrite;
     126#ifndef REM_PHYS_ADDR_IN_TLB
     127static STAMPROFILEADV gStatMemReadHCPtr;
     128static STAMPROFILEADV gStatMemWriteHCPtr;
     129#endif
     130#ifdef PGM_DYNAMIC_RAM_ALLOC
     131static STAMPROFILE    gStatGCPhys2HCVirt;
     132static STAMPROFILE    gStatHCVirt2GCPhys;
     133#endif
     134static STAMCOUNTER    gStatCpuGetTSC;
    130135static STAMCOUNTER    gStatRefuseTFInhibit;
    131136static STAMCOUNTER    gStatRefuseVM86;
     
    182187};
    183188
    184 #ifndef PGM_DYNAMIC_RAM_ALLOC
    185 /* Guest physical RAM base. Not to be used in external code. */
    186 static uint8_t *phys_ram_base;
    187 #endif
    188 
    189 /*
    190  * Instance stuff.
    191  */
    192 /** Pointer to the cpu state. */
    193 CPUState       *cpu_single_env;
    194 
    195189
    196190#ifdef VBOX_WITH_DEBUGGER
     
    227221
    228222
     223/* Instantiate the structure signatures. */
     224#define REM_STRUCT_OP 0
     225#include "InnoTek/structs.h"
     226
     227
     228
    229229/*******************************************************************************
    230230*   Internal Functions                                                         *
    231231*******************************************************************************/
    232232static void remAbort(int rc, const char *pszTip);
    233 
     233extern int testmath(void);
    234234
    235235/* Put them here to avoid unused variable warning. */
    236236AssertCompile(RT_SIZEOFMEMB(VM, rem.padding) >= RT_SIZEOFMEMB(VM, rem.s));
    237 //AssertCompileMemberSize(REM, Env, REM_ENV_SIZE);
    238 //AssertCompile(RT_SIZEOFMEMB(REM, Env) <= REM_ENV_SIZE);
     237#if !defined(IPRT_NO_CRT) && (defined(__LINUX__) || defined(__DARWIN__) || defined(__WIN__))
     238AssertCompileMemberSize(REM, Env, REM_ENV_SIZE);
     239#else
     240AssertCompile(RT_SIZEOFMEMB(REM, Env) <= REM_ENV_SIZE);
     241#endif
     242
    239243
    240244/**
     
    247251{
    248252    uint32_t u32Dummy;
     253    unsigned i;
     254
     255    /*
     256     * Assert sanity.
     257     */
    249258    AssertReleaseMsg(sizeof(pVM->rem.padding) >= sizeof(pVM->rem.s), ("%#x >= %#x; sizeof(Env)=%#x\n", sizeof(pVM->rem.padding), sizeof(pVM->rem.s), sizeof(pVM->rem.s.Env)));
    250     //AssertReleaseMsg(sizeof(pVM->rem.s.Env) <= REM_ENV_SIZE, ("%#x == %#x\n", sizeof(pVM->rem.s.Env), REM_ENV_SIZE));
     259    AssertReleaseMsg(sizeof(pVM->rem.s.Env) <= REM_ENV_SIZE, ("%#x == %#x\n", sizeof(pVM->rem.s.Env), REM_ENV_SIZE));
    251260    AssertReleaseMsg(!(RT_OFFSETOF(VM, rem) & 31), ("off=%#x\n", RT_OFFSETOF(VM, rem)));
    252 #if 0 /* not merged yet */
    253261    Assert(!testmath());
    254 #endif
     262    ASSERT_STRUCT_TABLE(Misc);
     263    ASSERT_STRUCT_TABLE(TLB);
     264    ASSERT_STRUCT_TABLE(SegmentCache);
     265    ASSERT_STRUCT_TABLE(XMMReg);
     266    ASSERT_STRUCT_TABLE(MMXReg);
     267    ASSERT_STRUCT_TABLE(float_status);
     268    ASSERT_STRUCT_TABLE(float32u);
     269    ASSERT_STRUCT_TABLE(float64u);
     270    ASSERT_STRUCT_TABLE(floatx80u);
     271    ASSERT_STRUCT_TABLE(CPUState);
    255272
    256273    /*
     
    272289    AssertMsg(MMR3PhysGetRamSize(pVM) == 0, ("Init order have changed! REM depends on notification about ALL physical memory registrations\n"));
    273290
     291    /* ignore all notifications */
     292    pVM->rem.s.fIgnoreAll = true;
     293
    274294    /*
    275295     * Init the recompiler.
     
    280300        return VERR_GENERAL_FAILURE;
    281301    }
    282     CPUMGetGuestCpuId(pVM, 1, &u32Dummy, &u32Dummy, &pVM->rem.s.Env.cpuid_ext_features, &pVM->rem.s.Env.cpuid_features);
     302    CPUMGetGuestCpuId(pVM,          1, &u32Dummy, &u32Dummy, &pVM->rem.s.Env.cpuid_ext_features, &pVM->rem.s.Env.cpuid_features);
     303    CPUMGetGuestCpuId(pVM, 0x80000001, &u32Dummy, &u32Dummy, &u32Dummy, &pVM->rem.s.Env.cpuid_ext2_features);
    283304
    284305    /* allocate code buffer for single instruction emulation. */
     
    293314    pVM->rem.s.u32PendingInterrupt = REM_NO_PENDING_IRQ;
    294315
    295 #ifdef DEBUG_bird
    296     //cpu_breakpoint_insert(&pVM->rem.s.Env, some-address);
    297 #endif
    298 
    299316    /*
    300317     * Register ram types.
    301318     */
    302     pVM->rem.s.iMMIOMemType    = cpu_register_io_memory(0, g_apfnMMIORead, g_apfnMMIOWrite, pVM);
    303     AssertReleaseMsg(pVM->rem.s.iMMIOMemType > 0, ("pVM->rem.s.iMMIOMemType=%d\n", pVM->rem.s.iMMIOMemType));
    304     pVM->rem.s.iHandlerMemType = cpu_register_io_memory(0, g_apfnHandlerRead, g_apfnHandlerWrite, pVM);
    305     AssertReleaseMsg(pVM->rem.s.iHandlerMemType > 0, ("pVM->rem.s.iHandlerMemType=%d\n", pVM->rem.s.iHandlerMemType));
     319    pVM->rem.s.iMMIOMemType    = cpu_register_io_memory(-1, g_apfnMMIORead, g_apfnMMIOWrite, pVM);
     320    AssertReleaseMsg(pVM->rem.s.iMMIOMemType >= 0, ("pVM->rem.s.iMMIOMemType=%d\n", pVM->rem.s.iMMIOMemType));
     321    pVM->rem.s.iHandlerMemType = cpu_register_io_memory(-1, g_apfnHandlerRead, g_apfnHandlerWrite, pVM);
     322    AssertReleaseMsg(pVM->rem.s.iHandlerMemType >= 0, ("pVM->rem.s.iHandlerMemType=%d\n", pVM->rem.s.iHandlerMemType));
    306323    Log2(("REM: iMMIOMemType=%d iHandlerMemType=%d\n", pVM->rem.s.iMMIOMemType, pVM->rem.s.iHandlerMemType));
     324
     325    /* stop ignoring. */
     326    pVM->rem.s.fIgnoreAll = false;
    307327
    308328    /*
     
    342362    STAM_REG(pVM, &gStatMemRead,            STAMTYPE_PROFILE, "/PROF/REM/MemRead",    STAMUNIT_TICKS_PER_CALL, "Profiling memory access.");
    343363    STAM_REG(pVM, &gStatMemWrite,           STAMTYPE_PROFILE, "/PROF/REM/MemWrite",   STAMUNIT_TICKS_PER_CALL, "Profiling memory access.");
     364#ifndef REM_PHYS_ADDR_IN_TLB
     365    STAM_REG(pVM, &gStatMemReadHCPtr,       STAMTYPE_PROFILE, "/PROF/REM/MemReadHCPtr", STAMUNIT_TICKS_PER_CALL, "Profiling memory access.");
     366    STAM_REG(pVM, &gStatMemWriteHCPtr,      STAMTYPE_PROFILE, "/PROF/REM/MemWriteHCPtr", STAMUNIT_TICKS_PER_CALL, "Profiling memory access.");
     367#endif
     368#ifdef PGM_DYNAMIC_RAM_ALLOC
     369    STAM_REG(pVM, &gStatHCVirt2GCPhys,      STAMTYPE_PROFILE, "/PROF/REM/HCVirt2GCPhys", STAMUNIT_TICKS_PER_CALL, "Profiling memory convertion.");
     370    STAM_REG(pVM, &gStatGCPhys2HCVirt,      STAMTYPE_PROFILE, "/PROF/REM/GCPhys2HCVirt", STAMUNIT_TICKS_PER_CALL, "Profiling memory convertion.");
     371#endif
     372
     373    STAM_REG(pVM, &gStatCpuGetTSC,          STAMTYPE_COUNTER, "/REM/CpuGetTSC",         STAMUNIT_OCCURENCES,     "cpu_get_tsc calls");
    344374
    345375    STAM_REG(pVM, &gStatRefuseTFInhibit,    STAMTYPE_COUNTER, "/REM/Refuse/TFInibit", STAMUNIT_OCCURENCES,     "Raw mode refused because of TF or irq inhibit");
     
    373403    STAM_REG(pVM, &gStatSelOutOfSyncStateBack[5],    STAMTYPE_COUNTER, "/REM/StateBack/SelOutOfSync/GS",        STAMUNIT_OCCURENCES,     "GS out of sync");
    374404
     405
    375406#endif
     407
     408#ifdef DEBUG_ALL_LOGGING
     409    loglevel = ~0;
     410#endif
     411
    376412    return rc;
    377413}
     
    403439REMR3DECL(void) REMR3Reset(PVM pVM)
    404440{
    405     pVM->rem.s.fIgnoreCR3Load = true;
    406     pVM->rem.s.fIgnoreInvlPg = true;
    407     pVM->rem.s.fIgnoreCpuMode = true;
    408 
    409441    /*
    410442     * Reset the REM cpu.
    411443     */
     444    pVM->rem.s.fIgnoreAll = true;
    412445    cpu_reset(&pVM->rem.s.Env);
    413446    pVM->rem.s.cInvalidatedPages = 0;
    414 
    415     pVM->rem.s.fIgnoreCR3Load = false;
    416     pVM->rem.s.fIgnoreInvlPg = false;
    417     pVM->rem.s.fIgnoreCpuMode = false;
     447    pVM->rem.s.fIgnoreAll = false;
    418448}
    419449
     
    441471
    442472    /* Remember if we've entered raw mode (vital for ring 1 checks in e.g. iret emulation). */
    443     SSMR3PutUInt(pSSM, !!(pRem->Env.state & CPU_RAW_RING0));
     473    SSMR3PutU32(pSSM, !!(pRem->Env.state & CPU_RAW_RING0));
    444474
    445475    /*
     
    469499    uint32_t u32Dummy;
    470500    uint32_t fRawRing0 = false;
    471 
    472501    LogFlow(("remR3Load:\n"));
    473502
     
    488517    /*
    489518     * Ignore all ignorable notifications.
    490      * Not doing this will cause big trouble.
    491      */
    492     pVM->rem.s.fIgnoreCR3Load = true;
    493     pVM->rem.s.fIgnoreInvlPg = true;
    494     pVM->rem.s.fIgnoreCpuMode = true;
     519     * (Not doing this will cause serious trouble.)
     520     */
     521    pVM->rem.s.fIgnoreAll = true;
    495522
    496523    /*
     
    549576     * Get the CPUID features.
    550577     */
    551     CPUMGetGuestCpuId(pVM, 1, &u32Dummy, &u32Dummy, &pVM->rem.s.Env.cpuid_ext_features, &pVM->rem.s.Env.cpuid_features);
     578    CPUMGetGuestCpuId(pVM,          1, &u32Dummy, &u32Dummy, &pVM->rem.s.Env.cpuid_ext_features, &pVM->rem.s.Env.cpuid_features);
     579    CPUMGetGuestCpuId(pVM, 0x80000001, &u32Dummy, &u32Dummy, &u32Dummy, &pVM->rem.s.Env.cpuid_ext2_features);
    552580
    553581    /*
     
    566594     * Stop ignoring ignornable notifications.
    567595     */
    568     pVM->rem.s.fIgnoreCpuMode = false;
    569     pVM->rem.s.fIgnoreInvlPg = false;
    570     pVM->rem.s.fIgnoreCR3Load = false;
     596    pVM->rem.s.fIgnoreAll = false;
    571597
    572598    return VINF_SUCCESS;
     
    628654        {
    629655            case EXCP_INTERRUPT:    rc = VINF_SUCCESS; break;
    630             case EXCP_HLT:          rc = VINF_EM_HALT; break;
     656            case EXCP_HLT:
     657            case EXCP_HALTED:       rc = VINF_EM_HALT; break;
    631658            case EXCP_RC:
    632659                rc = pVM->rem.s.rc;
     
    711738REMR3DECL(int) REMR3EmulateInstruction(PVM pVM)
    712739{
    713     Log2(("REMR3EmulateInstruction: (cs:eip=%04x:%08x)\n", pVM->rem.s.Env.segs[R_CS].selector, pVM->rem.s.Env.eip));
     740    Log2(("REMR3EmulateInstruction: (cs:eip=%04x:%08x)\n", pVM->rem.s.pCtx->cs, pVM->rem.s.pCtx->eip));
    714741
    715742    /*
     
    777804
    778805            /*
     806             * The VM has halted.
     807             */
     808            case EXCP_HALTED:
     809                Log2(("REMR3EmulateInstruction: cpu_exec -> EXCP_HALTED\n"));
     810                rc = VINF_EM_HALT;
     811                break;
     812
     813            /*
    779814             * Switch to RAW-mode.
    780815             */
     
    826861         * right way in will cause serious trouble if a longjmp was attempted.)
    827862         */
    828         #ifdef DEBUG_bird
     863# ifdef DEBUG_bird
    829864        remR3DisasInstr(&pVM->rem.s.Env, 1, "REMR3EmulateInstruction");
    830         #endif
     865# endif
    831866        int cTimesMax = 16384;
    832867        uint32_t eip = pVM->rem.s.Env.eip;
     
    834869        {
    835870            rc = cpu_exec(&pVM->rem.s.Env);
     871
    836872        } while (   eip == pVM->rem.s.Env.eip
    837873                 && (rc == EXCP_DEBUG || rc == EXCP_EXECUTE_RAW)
     
    863899            case EXCP_HLT:
    864900                Log2(("REMR3EmulateInstruction: cpu_exec -> EXCP_HLT\n"));
     901                rc = VINF_EM_HALT;
     902                break;
     903
     904            /*
     905             * The VM has halted.
     906             */
     907            case EXCP_HALTED:
     908                Log2(("REMR3EmulateInstruction: cpu_exec -> EXCP_HALTED\n"));
    865909                rc = VINF_EM_HALT;
    866910                break;
     
    9701014        case EXCP_HLT:
    9711015            Log2(("REMR3Run: cpu_exec -> EXCP_HLT\n"));
     1016            rc = VINF_EM_HALT;
     1017            break;
     1018
     1019        /*
     1020         * The VM has halted.
     1021         */
     1022        case EXCP_HALTED:
     1023            Log2(("REMR3Run: cpu_exec -> EXCP_HALTED\n"));
    9721024            rc = VINF_EM_HALT;
    9731025            break;
     
    10251077         */
    10261078        case EXCP_EXECUTE_HWACC:
    1027             Log2(("REMR3EmulateInstruction: cpu_exec -> EXCP_EXECUTE_HWACC\n"));
     1079            Log2(("REMR3Run: cpu_exec -> EXCP_EXECUTE_HWACC\n"));
    10281080            rc = VINF_EM_RESCHEDULE_HWACC;
    10291081            break;
     
    12901342     * state we disable this path.
    12911343     */
    1292     if (pVM->rem.s.fIgnoreInvlPg)
     1344    if (pVM->rem.s.fIgnoreInvlPg || pVM->rem.s.fIgnoreAll)
    12931345        return;
    12941346    Log(("remR3FlushPage: GCPtr=%VGv\n", GCPtr));
     1347    Assert(pVM->rem.s.fInREM);
    12951348
    12961349    //RAWEx_ProfileStop(env, STATS_QEMU_TOTAL);
     
    13211374 * @param   env         Pointer to cpu environment.
    13221375 */
    1323 void remR3SetPage(CPUState *env, CPUTLBEntry *pRead,  CPUTLBEntry *pWrite, int prot, int is_user)
    1324 {
    1325     uint32_t virt_addr, addend;
    1326 
    1327     Log2(("tlb_set_page_raw read (%x-%x) write (%x-%x) prot %x is_user %d\n", pRead->address, pRead->addend, pWrite->address, pWrite->addend, prot, is_user));
    1328 
     1376void remR3SetPage(CPUState *env, CPUTLBEntry *pTLBEntry,  CPUTLBEntry *pTLBEntryIgnored, int prot, int is_user)
     1377{
     1378    target_ulong virt_addr;
     1379    if (env->pVM->rem.s.fIgnoreSetPage || env->pVM->rem.s.fIgnoreAll)
     1380        return;
     1381    Assert(env->pVM->rem.s.fInREM || env->pVM->rem.s.fInStateSync);
     1382
     1383#ifndef PGM_DYNAMIC_RAM_ALLOC
     1384    if(!is_user && !(env->state & CPU_RAW_RING0))
     1385        return; /* We are currently not interested in kernel pages */
     1386#endif
     1387
     1388#if !defined(PGM_DYNAMIC_RAM_ALLOC) && !defined(REM_PHYS_ADDR_IN_TLB)
     1389    Log2(("tlb_set_page_raw (r=%x|w=%x)-%x prot %x is_user %d phys base %x\n",
     1390          pTLBEntry->addr_read, pTLBEntry->addr_write, pTLBEntry->addend, prot, is_user, phys_ram_base));
     1391#else /* PGM_DYNAMIC_RAM_ALLOC */
     1392    Log2(("tlb_set_page_raw (r=%x|w=%x)-%x prot %x is_user %d\n",
     1393          pTLBEntry->addr_read, pTLBEntry->addr_write, pTLBEntry->addend, prot, is_user));
     1394#endif/* PGM_DYNAMIC_RAM_ALLOC */
     1395
     1396    /*
     1397     * Extract the virtual address.
     1398     */
    13291399    if (prot & PAGE_WRITE)
    1330     {
    1331         addend = pWrite->addend;
    1332         virt_addr = pWrite->address;
    1333     }
     1400        virt_addr = pTLBEntry->addr_write;
     1401    else if (prot & PAGE_READ)
     1402        virt_addr = pTLBEntry->addr_read;
    13341403    else
    1335     if (prot & PAGE_READ)
    1336     {
    1337         addend = pRead->addend;
    1338         virt_addr = pRead->address;
    1339     }
    1340     else
    1341     {
    1342         // Should never happen!
    1343         AssertMsgFailed(("tlb_set_page_raw unexpected protection flags %x\n", prot));
    1344         return;
    1345     }
    1346 
    1347     // Clear IO_* flags (TODO: are they actually useful for us??)
    1348     virt_addr &= ~0xFFF;
     1404        AssertMsgFailedReturnVoid(("tlb_set_page_raw unexpected protection flags %x\n", prot));
     1405    virt_addr &= TARGET_PAGE_MASK;
    13491406
    13501407    /*
     
    13621419    if (VBOX_FAILURE(rc))
    13631420    {
    1364         AssertMsgFailed(("RAWEx_SetPageEntry %x %x %d failed!!\n", virt_addr, prot, is_user));
     1421#ifdef VBOX_STRICT
     1422        target_ulong addend = pTLBEntry->addend;
     1423        target_ulong phys_addr;
     1424
     1425        if (!(addend & IO_MEM_ROM))
     1426# ifdef REM_PHYS_ADDR_IN_TLB
     1427            phys_addr = virt_addr + addend;
     1428# elif defined(PGM_DYNAMIC_RAM_ALLOC)
     1429            phys_addr = remR3HCVirt2GCPhysInlined(env->pVM, (void *)(virt_addr + addend));
     1430# else
     1431            phys_addr = virt_addr - (uintptr_t)phys_ram_base + addend;
     1432# endif
     1433        else
     1434            phys_addr = addend;
     1435        AssertMsgFailed(("RAWEx_SetPageEntry %x %x %x %d failed!!\n", virt_addr, phys_addr, prot, is_user));
     1436#endif /* VBOX_STRICT */
    13651437        VM_FF_SET(env->pVM, VM_FF_PGM_SYNC_CR3);
    13661438    }
     
    13751447void remR3ProtectCode(CPUState *env, RTGCPTR GCPtr)
    13761448{
     1449    Assert(env->pVM->rem.s.fInREM);
    13771450    if (     (env->cr[0] & X86_CR0_PG)                      /* paging must be enabled */
    13781451        &&  !(env->state & CPU_EMULATE_SINGLE_INSTR)        /* ignore during single instruction execution */
     
    13981471     * state we disable this path.
    13991472     */
    1400     if (pVM->rem.s.fIgnoreCR3Load)
     1473    if (pVM->rem.s.fIgnoreCR3Load || pVM->rem.s.fIgnoreAll)
    14011474        return;
     1475    Assert(pVM->rem.s.fInREM);
    14021476
    14031477    /*
     
    14371511     * state this path is disabled.
    14381512     */
    1439     if (pVM->rem.s.fIgnoreCpuMode)
     1513    if (pVM->rem.s.fIgnoreCpuMode || pVM->rem.s.fIgnoreAll)
    14401514        return;
     1515    Assert(pVM->rem.s.fInREM);
    14411516
    14421517    /*
     
    15201595    if(uTrap < 0x20)
    15211596    {
     1597#ifdef DEBUG
    15221598        remR3DisasInstr(env, 1, "remR3NotifyTrap: ");
    1523 
     1599#endif
    15241600        if(pVM->rem.s.uPendingException == uTrap && ++pVM->rem.s.cPendingExceptions > 128)
    15251601        {
     
    15751651REMR3DECL(int) REMR3State(PVM pVM)
    15761652{
    1577     Assert(!pVM->rem.s.fInREM);
    15781653    Log2(("REMR3State:\n"));
    15791654    STAM_PROFILE_START(&pVM->rem.s.StatsState, a);
     
    15811656    register unsigned       fFlags;
    15821657    bool                    fHiddenSelRegsValid = CPUMAreHiddenSelRegsValid(pVM);
     1658
     1659    Assert(!pVM->rem.s.fInREM);
     1660    pVM->rem.s.fInStateSync = true;
    15831661
    15841662    /*
     
    16181696
    16191697    /*
     1698     * Clear the halted hidden flag (the interrupt waking up the CPU can
     1699     * have been dispatched in raw mode).
     1700     */
     1701    pVM->rem.s.Env.hflags      &= ~HF_HALTED_MASK;
     1702
     1703    /*
    16201704     * Replay invlpg?
    16211705     */
     
    16341718
    16351719    /*
    1636      * Registers which are seldomly changed and require special handling / order when changed.
     1720     * Registers which are rarely changed and require special handling / order when changed.
    16371721     */
    16381722    fFlags = CPUMGetAndClearChangedFlagsREM(pVM);
     
    19302014     */
    19312015    pVM->rem.s.fInREM = true;
     2016    pVM->rem.s.fInStateSync = false;
    19322017    pVM->rem.s.cCanExecuteRaw = 0;
    19332018    STAM_PROFILE_STOP(&pVM->rem.s.StatsState, a);
     
    24412526REMR3DECL(void) REMR3NotifyPhysRamRegister(PVM pVM, RTGCPHYS GCPhys, RTUINT cb, void *pvRam, unsigned fFlags)
    24422527{
    2443     Log(("REMR3NotifyPhysRamRegister: GCPhys=%VGp cb=%d pvRam=%p fFlags=%d\n", GCPhys, cb, pvRam, fFlags));
     2528    LogFlow(("REMR3NotifyPhysRamRegister: GCPhys=%VGp cb=%d pvRam=%p fFlags=%d\n", GCPhys, cb, pvRam, fFlags));
    24442529    VM_ASSERT_EMT(pVM);
    24452530
     
    24582543    if (!GCPhys)
    24592544    {
    2460 #ifndef PGM_DYNAMIC_RAM_ALLOC
     2545#if !defined(PGM_DYNAMIC_RAM_ALLOC) && !defined(REM_PHYS_ADDR_IN_TLB)
    24612546        AssertRelease(!phys_ram_base);
    24622547        phys_ram_base = pvRam;
    24632548#endif
    24642549        phys_ram_size = cb;
    2465         phys_ram_dirty = MMR3HeapAllocZ(pVM, MM_TAG_REM, cb >> PAGE_SHIFT);
    2466         AssertReleaseMsg(phys_ram_dirty, ("failed to allocate %d bytes of dirty bytes\n", cb >> PAGE_SHIFT));
    2467     }
    2468 #ifndef PGM_DYNAMIC_RAM_ALLOC
    2469     AssertRelease(phys_ram_base);
     2550        phys_ram_dirty_size = cb >> PAGE_SHIFT;
     2551#ifndef VBOX_STRICT
     2552        phys_ram_dirty = MMR3HeapAlloc(pVM, MM_TAG_REM, phys_ram_dirty_size);
     2553        AssertReleaseMsg(phys_ram_dirty, ("failed to allocate %d bytes of dirty bytes\n", phys_ram_dirty_size));
     2554#else /* VBOX_STRICT: allocate a full map and make the out of bounds pages invalid. */
     2555        phys_ram_dirty = RTMemPageAlloc(_4G >> PAGE_SHIFT);
     2556        AssertReleaseMsg(phys_ram_dirty, ("failed to allocate %d bytes of dirty bytes\n", _4G >> PAGE_SHIFT));
     2557        uint32_t cbBitmap = RT_ALIGN_32(phys_ram_dirty_size, PAGE_SIZE);
     2558        int rc = RTMemProtect(phys_ram_dirty + cbBitmap, (_4G >> PAGE_SHIFT) - cbBitmap, RTMEM_PROT_NONE);
     2559        AssertRC(rc);
     2560        phys_ram_dirty += cbBitmap - phys_ram_dirty_size;
    24702561#endif
     2562        memset(phys_ram_dirty, 0xff, phys_ram_dirty_size);
     2563    }
    24712564
    24722565    /*
    24732566     * Register the ram.
    24742567     */
     2568    Assert(!pVM->rem.s.fIgnoreAll);
     2569    pVM->rem.s.fIgnoreAll = true;
     2570
    24752571#ifdef PGM_DYNAMIC_RAM_ALLOC
    24762572    if (!GCPhys)
     
    24782574    else
    24792575    {
     2576# ifndef REM_PHYS_ADDR_IN_TLB
    24802577        uint32_t i;
     2578# endif
    24812579
    24822580        cpu_register_physical_memory(GCPhys, cb, GCPhys | (fFlags & MM_RAM_FLAGS_RESERVED ? IO_MEM_UNASSIGNED : 0));
    24832581
     2582# ifndef REM_PHYS_ADDR_IN_TLB
    24842583        AssertRelease(pVM->rem.s.cPhysRegistrations < REM_MAX_PHYS_REGISTRATIONS);
    2485         for (i=0;i<pVM->rem.s.cPhysRegistrations;i++)
     2584        for (i = 0; i < pVM->rem.s.cPhysRegistrations; i++)
    24862585        {
    24872586            if (pVM->rem.s.aPhysReg[i].GCPhys == GCPhys)
     
    24992598            pVM->rem.s.cPhysRegistrations++;
    25002599        }
    2501     }
     2600# endif /* !REM_PHYS_ADDR_IN_TLB */
     2601    }
     2602#elif defined(REM_PHYS_ADDR_IN_TLB)
     2603    cpu_register_physical_memory(GCPhys, cb, GCPhys | (fFlags & MM_RAM_FLAGS_RESERVED ? IO_MEM_UNASSIGNED : 0));
    25022604#else
     2605    AssertRelease(phys_ram_base);
    25032606    cpu_register_physical_memory(GCPhys, cb, ((uintptr_t)pvRam - (uintptr_t)phys_ram_base)
    25042607                                             | (fFlags & MM_RAM_FLAGS_RESERVED ? IO_MEM_UNASSIGNED : 0));
    25052608#endif
     2609    Assert(pVM->rem.s.fIgnoreAll);
     2610    pVM->rem.s.fIgnoreAll = false;
    25062611}
    25072612
     
    25182623REMR3DECL(void) REMR3NotifyPhysRamChunkRegister(PVM pVM, RTGCPHYS GCPhys, RTUINT cb, RTHCUINTPTR pvRam, unsigned fFlags)
    25192624{
     2625#ifdef PGM_DYNAMIC_RAM_ALLOC
     2626# ifndef REM_PHYS_ADDR_IN_TLB
    25202627    uint32_t idx;
     2628#endif
    25212629
    25222630    Log(("REMR3NotifyPhysRamChunkRegister: GCPhys=%VGp cb=%d pvRam=%p fFlags=%d\n", GCPhys, cb, pvRam, fFlags));
     
    25322640    Assert(fFlags == 0 /* normal RAM */);
    25332641
     2642# ifndef REM_PHYS_ADDR_IN_TLB
    25342643    if (!pVM->rem.s.paHCVirtToGCPhys)
    25352644    {
     
    25702679        }
    25712680    }
     2681# endif /* !REM_PHYS_ADDR_IN_TLB */
     2682
     2683    Assert(!pVM->rem.s.fIgnoreAll);
     2684    pVM->rem.s.fIgnoreAll = true;
     2685
    25722686    cpu_register_physical_memory(GCPhys, cb, GCPhys);
    2573 }
     2687
     2688    Assert(pVM->rem.s.fIgnoreAll);
     2689    pVM->rem.s.fIgnoreAll = false;
     2690
     2691#else
     2692    AssertReleaseFailed();
     2693#endif
     2694}
     2695
     2696
     2697#ifdef PGM_DYNAMIC_RAM_ALLOC
     2698# ifndef REM_PHYS_ADDR_IN_TLB
     2699#if 0
     2700static const uint8_t gabZeroPage[PAGE_SIZE];
     2701#endif
    25742702
    25752703/**
     
    25802708 * @param   addr        The physical address.
    25812709 */
    2582 void *remR3GCPhys2HCVirt(void *env, target_ulong addr)
    2583 {
    2584 #ifdef PGM_DYNAMIC_RAM_ALLOC
    2585     PVM      pVM = ((CPUState *)env)->pVM;
     2710DECLINLINE(void *) remR3GCPhys2HCVirtInlined(PVM pVM, target_ulong addr)
     2711{
    25862712    uint32_t i;
    2587 
     2713    void    *pv;
     2714    STAM_PROFILE_START(&gStatGCPhys2HCVirt, a);
     2715
     2716#if 1
    25882717    /* lookup in pVM->rem.s.aPhysReg array first (for ROM range(s) inside the guest's RAM) */
    2589     for (i=0;i<pVM->rem.s.cPhysRegistrations;i++)
    2590     {
    2591         uint32_t off = addr - pVM->rem.s.aPhysReg[i].GCPhys;
     2718    for (i = 0; i < pVM->rem.s.cPhysRegistrations; i++)
     2719    {
     2720        RTGCPHYS off = addr - pVM->rem.s.aPhysReg[i].GCPhys;
    25922721        if (off < pVM->rem.s.aPhysReg[i].cb)
    25932722        {
    2594             Log2(("remR3GCPhys2HCVirt: %x -> %x\n", addr, pVM->rem.s.aPhysReg[i].HCVirt + off));
    2595             return (void *)(pVM->rem.s.aPhysReg[i].HCVirt + off);
     2723            pv = (void *)(pVM->rem.s.aPhysReg[i].HCVirt + off);
     2724            Log2(("remR3GCPhys2HCVirt: %x -> %x\n", addr, pv));
     2725            STAM_PROFILE_STOP(&gStatGCPhys2HCVirt, a);
     2726            return pv;
    25962727        }
    25972728    }
    25982729    AssertMsg(addr < phys_ram_size, ("remR3GCPhys2HCVirt: unknown physical address %x\n", addr));
    2599     Log2(("remR3GCPhys2HCVirt: %x -> %x\n", addr, pVM->rem.s.paGCPhysToHCVirt[addr >> PGM_DYNAMIC_CHUNK_SHIFT] + (addr & PGM_DYNAMIC_CHUNK_OFFSET_MASK)));
    2600     return (void *)(pVM->rem.s.paGCPhysToHCVirt[addr >> PGM_DYNAMIC_CHUNK_SHIFT] + (addr & PGM_DYNAMIC_CHUNK_OFFSET_MASK));
     2730    pv = (void *)(pVM->rem.s.paGCPhysToHCVirt[addr >> PGM_DYNAMIC_CHUNK_SHIFT] + (addr & PGM_DYNAMIC_CHUNK_OFFSET_MASK));
     2731    Log2(("remR3GCPhys2HCVirt: %x -> %x\n", addr, pv));
    26012732#else
    2602     return phys_ram_base + addr;
    2603 #endif
    2604 }
     2733    /** @todo figure out why this is faster than the above code. */
     2734    int rc = PGMPhysGCPhys2HCPtr(pVM, addr & X86_PTE_PAE_PG_MASK, PAGE_SIZE, &pv);
     2735    if (RT_FAILURE(rc))
     2736    {
     2737        AssertMsgFailed(("remR3GCPhys2HCVirt: unknown physical address %x\n", addr));
     2738        pv = gabZeroPage;
     2739    }
     2740    pv = (void *)((uintptr_t)pv | (addr & PAGE_OFFSET_MASK));
     2741#endif
     2742    return pv;
     2743}
     2744
    26052745
    26062746/**
     
    26112751 * @param   addr        The physical address.
    26122752 */
    2613 target_ulong remR3HCVirt2GCPhys(void *env, void *addr)
    2614 {
    2615 #ifdef PGM_DYNAMIC_RAM_ALLOC
    2616     PVM         pVM    = ((CPUState *)env)->pVM;
     2753DECLINLINE(target_ulong) remR3HCVirt2GCPhysInlined(PVM pVM, void *addr)
     2754{
    26172755    RTHCUINTPTR HCVirt = (RTHCUINTPTR)addr;
    26182756    uint32_t    idx    = (HCVirt >> PGM_DYNAMIC_CHUNK_SHIFT);
    26192757    RTHCUINTPTR off;
    26202758    RTUINT      i;
     2759    target_ulong GCPhys;
    26212760
    26222761    off = HCVirt - pVM->rem.s.paHCVirtToGCPhys[idx].pChunk1;
    26232762
    2624     if (    pVM->rem.s.paHCVirtToGCPhys[idx].pChunk1 
     2763    if (    pVM->rem.s.paHCVirtToGCPhys[idx].pChunk1
    26252764        &&  off < PGM_DYNAMIC_CHUNK_SIZE)
    26262765    {
    2627         Log2(("remR3HCVirt2GCPhys %x -> %x\n", addr, pVM->rem.s.paHCVirtToGCPhys[idx].GCPhys1 + off));
    2628         return pVM->rem.s.paHCVirtToGCPhys[idx].GCPhys1 + off;
    2629     }
    2630    
     2766        GCPhys = pVM->rem.s.paHCVirtToGCPhys[idx].GCPhys1 + off;
     2767        Log2(("remR3HCVirt2GCPhys %x -> %x\n", addr, GCPhys));
     2768        return GCPhys;
     2769    }
     2770
    26312771    off = HCVirt - pVM->rem.s.paHCVirtToGCPhys[idx].pChunk2;
    2632     if (    pVM->rem.s.paHCVirtToGCPhys[idx].pChunk2 
     2772    if (    pVM->rem.s.paHCVirtToGCPhys[idx].pChunk2
    26332773        &&  off < PGM_DYNAMIC_CHUNK_SIZE)
    26342774    {
    2635         Log2(("remR3HCVirt2GCPhys %x -> %x\n", addr, pVM->rem.s.paHCVirtToGCPhys[idx].GCPhys2 + off));
    2636         return pVM->rem.s.paHCVirtToGCPhys[idx].GCPhys2 + off;
     2775        GCPhys = pVM->rem.s.paHCVirtToGCPhys[idx].GCPhys2 + off;
     2776        Log2(("remR3HCVirt2GCPhys %x -> %x\n", addr, GCPhys));
     2777        return GCPhys;
    26372778    }
    26382779
    26392780    /* Must be externally registered RAM/ROM range */
    2640     for (i=0;i<pVM->rem.s.cPhysRegistrations;i++)
     2781    for (i = 0; i < pVM->rem.s.cPhysRegistrations; i++)
    26412782    {
    26422783        uint32_t off = HCVirt - pVM->rem.s.aPhysReg[i].HCVirt;
    26432784        if (off < pVM->rem.s.aPhysReg[i].cb)
    26442785        {
    2645             Log2(("remR3HCVirt2GCPhys %x -> %x\n", addr, pVM->rem.s.aPhysReg[i].GCPhys + off));
    2646             return pVM->rem.s.aPhysReg[i].GCPhys + off;
     2786            GCPhys = pVM->rem.s.aPhysReg[i].GCPhys + off;
     2787            Log2(("remR3HCVirt2GCPhys %x -> %x\n", addr, GCPhys));
     2788            return GCPhys;
    26472789        }
    26482790    }
    26492791    AssertReleaseMsgFailed(("No translation for physical address %VHv???\n", addr));
    26502792    return 0;
    2651 #else
    2652     return (target_ulong)addr - (target_ulong)phys_ram_base;
    2653 #endif
    2654 }
     2793}
     2794
     2795/**
     2796 *  Convert GC physical address to HC virt
     2797 *
     2798 * @returns The HC virt address corresponding to addr.
     2799 * @param   env         The cpu environment.
     2800 * @param   addr        The physical address.
     2801 */
     2802void *remR3GCPhys2HCVirt(void *env, target_ulong addr)
     2803{
     2804    PVM     pVM = ((CPUState *)env)->pVM;
     2805    void   *pv;
     2806    STAM_PROFILE_START(&gStatGCPhys2HCVirt, a);
     2807    pv = remR3GCPhys2HCVirtInlined(pVM, addr);
     2808    STAM_PROFILE_STOP(&gStatGCPhys2HCVirt, a);
     2809    return pv;
     2810}
     2811
     2812
     2813/**
     2814 *  Convert GC physical address to HC virt
     2815 *
     2816 * @returns The HC virt address corresponding to addr.
     2817 * @param   env         The cpu environment.
     2818 * @param   addr        The physical address.
     2819 */
     2820target_ulong remR3HCVirt2GCPhys(void *env, void *addr)
     2821{
     2822    PVM pVM = ((CPUState *)env)->pVM;
     2823    target_ulong GCPhys;
     2824    STAM_PROFILE_START(&gStatHCVirt2GCPhys, a);
     2825    GCPhys = remR3HCVirt2GCPhysInlined(pVM, addr);
     2826    STAM_PROFILE_STOP(&gStatHCVirt2GCPhys, a);
     2827    return GCPhys;
     2828}
     2829
     2830# endif /* !REM_PHYS_ADDR_IN_TLB */
    26552831
    26562832/**
     
    26752851}
    26762852
     2853#endif /* PGM_DYNAMIC_RAM_ALLOC */
     2854
     2855
    26772856/**
    26782857 * Notification about a successful MMR3PhysRomRegister() call.
     
    26852864REMR3DECL(void) REMR3NotifyPhysRomRegister(PVM pVM, RTGCPHYS GCPhys, RTUINT cb, void *pvCopy)
    26862865{
    2687 #ifdef PGM_DYNAMIC_RAM_ALLOC
     2866#if defined(PGM_DYNAMIC_RAM_ALLOC) && !defined(REM_PHYS_ADDR_IN_TLB)
    26882867    uint32_t i;
    26892868#endif
    2690     Log(("REMR3NotifyPhysRomRegister: GCPhys=%VGp cb=%d pvCopy=%p\n", GCPhys, cb, pvCopy));
     2869    LogFlow(("REMR3NotifyPhysRomRegister: GCPhys=%VGp cb=%d pvCopy=%p\n", GCPhys, cb, pvCopy));
    26912870    VM_ASSERT_EMT(pVM);
    26922871
     
    27032882     * Register the rom.
    27042883     */
    2705 #ifdef PGM_DYNAMIC_RAM_ALLOC
     2884    Assert(!pVM->rem.s.fIgnoreAll);
     2885    pVM->rem.s.fIgnoreAll = true;
     2886
     2887#ifdef REM_PHYS_ADDR_IN_TLB
     2888    cpu_register_physical_memory(GCPhys, cb, GCPhys | IO_MEM_ROM);
     2889#elif defined(PGM_DYNAMIC_RAM_ALLOC)
    27062890    cpu_register_physical_memory(GCPhys, cb, GCPhys | IO_MEM_ROM);
    27072891    AssertRelease(pVM->rem.s.cPhysRegistrations < REM_MAX_PHYS_REGISTRATIONS);
    2708     for (i=0;i<pVM->rem.s.cPhysRegistrations;i++)
     2892    for (i = 0; i < pVM->rem.s.cPhysRegistrations; i++)
    27092893    {
    27102894        if (pVM->rem.s.aPhysReg[i].GCPhys == GCPhys)
     
    27262910    cpu_register_physical_memory(GCPhys, cb, ((uintptr_t)pvCopy - (uintptr_t)phys_ram_base) | IO_MEM_ROM);
    27272911#endif
     2912
    27282913    Log2(("%.64Vhxd\n", (char *)pvCopy + cb - 64));
     2914
     2915    Assert(pVM->rem.s.fIgnoreAll);
     2916    pVM->rem.s.fIgnoreAll = false;
    27292917}
    27302918
     
    27522940     * Unassigning the memory.
    27532941     */
     2942    Assert(!pVM->rem.s.fIgnoreAll);
     2943    pVM->rem.s.fIgnoreAll = true;
     2944
    27542945    cpu_register_physical_memory(GCPhys, cb, IO_MEM_UNASSIGNED);
     2946
     2947    Assert(pVM->rem.s.fIgnoreAll);
     2948    pVM->rem.s.fIgnoreAll = false;
    27552949}
    27562950
     
    27792973        REMR3ReplayHandlerNotifications(pVM);
    27802974
     2975    Assert(!pVM->rem.s.fIgnoreAll);
     2976    pVM->rem.s.fIgnoreAll = true;
     2977
    27812978    if (enmType == PGMPHYSHANDLERTYPE_MMIO)
    27822979        cpu_register_physical_memory(GCPhys, cb, pVM->rem.s.iMMIOMemType);
    27832980    else if (fHasHCHandler)
    27842981        cpu_register_physical_memory(GCPhys, cb, pVM->rem.s.iHandlerMemType);
     2982
     2983    Assert(pVM->rem.s.fIgnoreAll);
     2984    pVM->rem.s.fIgnoreAll = false;
    27852985}
    27862986
     
    28043004    if (pVM->rem.s.cHandlerNotifications)
    28053005        REMR3ReplayHandlerNotifications(pVM);
     3006
     3007    Assert(!pVM->rem.s.fIgnoreAll);
     3008    pVM->rem.s.fIgnoreAll = true;
    28063009
    28073010    if (enmType == PGMPHYSHANDLERTYPE_MMIO)
     
    28163019        else
    28173020        {
    2818             /* This is not prefect, but it'll do for PD monitoring... */
     3021            /* This is not perfect, but it'll do for PD monitoring... */
    28193022            Assert(cb == PAGE_SIZE);
    28203023            Assert(RT_ALIGN_T(GCPhys, PAGE_SIZE, RTGCPHYS) == GCPhys);
    2821             Assert(remR3HCVirt2GCPhys(cpu_single_env, pvHCPtr) < MMR3PhysGetRamSize(pVM));
    2822 #ifdef PGM_DYNAMIC_RAM_ALLOC
     3024#ifdef REM_PHYS_ADDR_IN_TLB
     3025            cpu_register_physical_memory(GCPhys, cb, GCPhys);
     3026#elif defined(PGM_DYNAMIC_RAM_ALLOC)
     3027            Assert(remR3HCVirt2GCPhysInlined(pVM, pvHCPtr) < MMR3PhysGetRamSize(pVM));
    28233028            cpu_register_physical_memory(GCPhys, cb, GCPhys);
    28243029#else
    2825             cpu_register_physical_memory(GCPhys, cb, remR3HCVirt2GCPhys(cpu_single_env, pvHCPtr));
     3030            Assert((uintptr_t)pvHCPtr - (uintptr_t)phys_ram_base < MMR3PhysGetRamSize(pVM));
     3031            cpu_register_physical_memory(GCPhys, cb, (uintptr_t)pvHCPtr - (uintptr_t)phys_ram_base);
    28263032#endif
    28273033        }
    28283034    }
     3035
     3036    Assert(pVM->rem.s.fIgnoreAll);
     3037    pVM->rem.s.fIgnoreAll = false;
    28293038}
    28303039
     
    28533062    if (fHasHCHandler)
    28543063    {
     3064        Assert(!pVM->rem.s.fIgnoreAll);
     3065        pVM->rem.s.fIgnoreAll = true;
     3066
    28553067        /*
    28563068         * Reset the old page.
     
    28603072        else
    28613073        {
    2862             /* This is not prefect, but it'll do for PD monitoring... */
     3074            /* This is not perfect, but it'll do for PD monitoring... */
    28633075            Assert(cb == PAGE_SIZE);
    28643076            Assert(RT_ALIGN_T(GCPhysOld, PAGE_SIZE, RTGCPHYS) == GCPhysOld);
    2865             Assert(remR3HCVirt2GCPhys(cpu_single_env, pvHCPtr) < MMR3PhysGetRamSize(pVM));
    2866 #ifdef PGM_DYNAMIC_RAM_ALLOC
     3077#ifdef REM_PHYS_ADDR_IN_TLB
     3078            cpu_register_physical_memory(GCPhysOld, cb, GCPhysOld);
     3079#elif defined(PGM_DYNAMIC_RAM_ALLOC)
     3080            Assert(remR3HCVirt2GCPhysInlined(pVM, pvHCPtr) < MMR3PhysGetRamSize(pVM));
    28673081            cpu_register_physical_memory(GCPhysOld, cb, GCPhysOld);
    28683082#else
    2869             cpu_register_physical_memory(GCPhysOld, cb, remR3HCVirt2GCPhys(cpu_single_env, pvHCPtr));
     3083            AssertMsg((uintptr_t)pvHCPtr - (uintptr_t)phys_ram_base < MMR3PhysGetRamSize(pVM),
     3084                      ("pvHCPtr=%p phys_ram_base=%p size=%RX64 cb=%RGp\n", pvHCPtr, phys_ram_base, MMR3PhysGetRamSize(pVM), cb));
     3085            cpu_register_physical_memory(GCPhysOld, cb, (uintptr_t)pvHCPtr - (uintptr_t)phys_ram_base);
    28703086#endif
    28713087        }
     
    28773093        Assert(RT_ALIGN_T(cb, PAGE_SIZE, RTGCPHYS) == cb);
    28783094        cpu_register_physical_memory(GCPhysNew, cb, pVM->rem.s.iHandlerMemType);
     3095
     3096        Assert(pVM->rem.s.fIgnoreAll);
     3097        pVM->rem.s.fIgnoreAll = false;
    28793098    }
    28803099}
     
    29213140{
    29223141    PVM pVM = env->pVM;
    2923     if ((pTLBEntry->address & ~TARGET_PAGE_MASK) == pVM->rem.s.iHandlerMemType)
     3142    if ((pTLBEntry->addr_code & ~TARGET_PAGE_MASK) == pVM->rem.s.iHandlerMemType)
    29243143    {
    29253144        target_ulong ret = pTLBEntry->addend + addr;
    2926         AssertMsg2("remR3PhysGetPhysicalAddressCode: addr=%VGv address=%VGv addend=%VGp ret=%VGp\n",
    2927                 (RTGCPTR)addr, (RTGCPTR)pTLBEntry->address, (RTGCPHYS)pTLBEntry->addend, ret);
     3145        AssertMsg2("remR3PhysGetPhysicalAddressCode: addr=%VGv addr_code=%VGv addend=%VGp ret=%VGp\n",
     3146                   (RTGCPTR)addr, (RTGCPTR)pTLBEntry->addr_code, (RTGCPHYS)pTLBEntry->addend, ret);
    29283147        return ret;
    29293148    }
    2930     LogRel(("\nTrying to execute code with memory type address=%VGv addend=%VGp at %VGv! (iHandlerMemType=%#x iMMIOMemType=%#x)\n"
     3149    LogRel(("\nTrying to execute code with memory type addr_code=%VGv addend=%VGp at %VGv! (iHandlerMemType=%#x iMMIOMemType=%#x)\n"
    29313150            "*** handlers\n",
    2932             (RTGCPTR)pTLBEntry->address, (RTGCPHYS)pTLBEntry->addend, (RTGCPTR)addr, pVM->rem.s.iHandlerMemType, pVM->rem.s.iMMIOMemType));
     3151            (RTGCPTR)pTLBEntry->addr_code, (RTGCPHYS)pTLBEntry->addend, (RTGCPTR)addr, pVM->rem.s.iHandlerMemType, pVM->rem.s.iMMIOMemType));
    29333152    DBGFR3Info(pVM, "handlers", NULL, DBGFR3InfoLogRelHlp());
    29343153    LogRel(("*** mmio\n"));
     
    29363155    LogRel(("*** phys\n"));
    29373156    DBGFR3Info(pVM, "phys", NULL, DBGFR3InfoLogRelHlp());
    2938     cpu_abort(env, "Trying to execute code with memory type address=%VGv addend=%VGp at %VGv. (iHandlerMemType=%#x iMMIOMemType=%#x)\n",
    2939               (RTGCPTR)pTLBEntry->address, (RTGCPHYS)pTLBEntry->addend, (RTGCPTR)addr, pVM->rem.s.iHandlerMemType, pVM->rem.s.iMMIOMemType);
     3157    cpu_abort(env, "Trying to execute code with memory type addr_code=%VGv addend=%VGp at %VGv. (iHandlerMemType=%#x iMMIOMemType=%#x)\n",
     3158              (RTGCPTR)pTLBEntry->addr_code, (RTGCPHYS)pTLBEntry->addend, (RTGCPTR)addr, pVM->rem.s.iHandlerMemType, pVM->rem.s.iMMIOMemType);
    29403159    AssertFatalFailed();
    29413160}
     3161
     3162
     3163/** Validate the physical address passed to the read functions.
     3164 * Useful for finding non-guest-ram reads/writes.  */
     3165#if 1 /* disable if it becomes bothersome... */
     3166# define VBOX_CHECK_ADDR(GCPhys) AssertMsg(PGMPhysIsGCPhysValid(cpu_single_env->pVM, (GCPhys)), ("%VGp\n", (GCPhys)))
     3167#else
     3168# define VBOX_CHECK_ADDR(GCPhys) do { } while (0)
     3169#endif
     3170
     3171/**
     3172 * Read guest RAM and ROM.
     3173 *
     3174 * @param   SrcGCPhys       The source address (guest physical).
     3175 * @param   pvDst           The destination address.
     3176 * @param   cb              Number of bytes
     3177 */
     3178void remR3PhysRead(RTGCPHYS SrcGCPhys, void *pvDst, unsigned cb)
     3179{
     3180    STAM_PROFILE_ADV_START(&gStatMemRead, a);
     3181    VBOX_CHECK_ADDR(SrcGCPhys);
     3182    PGMPhysRead(cpu_single_env->pVM, SrcGCPhys, pvDst, cb);
     3183    STAM_PROFILE_ADV_STOP(&gStatMemRead, a);
     3184}
     3185
     3186
     3187/**
     3188 * Read guest RAM and ROM, unsigned 8-bit.
     3189 *
     3190 * @param   SrcGCPhys       The source address (guest physical).
     3191 */
     3192uint8_t remR3PhysReadU8(RTGCPHYS SrcGCPhys)
     3193{
     3194    uint8_t val;
     3195    STAM_PROFILE_ADV_START(&gStatMemRead, a);
     3196    VBOX_CHECK_ADDR(SrcGCPhys);
     3197    val = PGMR3PhysReadByte(cpu_single_env->pVM, SrcGCPhys);
     3198    STAM_PROFILE_ADV_STOP(&gStatMemRead, a);
     3199    return val;
     3200}
     3201
     3202
     3203/**
     3204 * Read guest RAM and ROM, signed 8-bit.
     3205 *
     3206 * @param   SrcGCPhys       The source address (guest physical).
     3207 */
     3208int8_t remR3PhysReadS8(RTGCPHYS SrcGCPhys)
     3209{
     3210    int8_t val;
     3211    STAM_PROFILE_ADV_START(&gStatMemRead, a);
     3212    VBOX_CHECK_ADDR(SrcGCPhys);
     3213    val = PGMR3PhysReadByte(cpu_single_env->pVM, SrcGCPhys);
     3214    STAM_PROFILE_ADV_STOP(&gStatMemRead, a);
     3215    return val;
     3216}
     3217
     3218
     3219/**
     3220 * Read guest RAM and ROM, unsigned 16-bit.
     3221 *
     3222 * @param   SrcGCPhys       The source address (guest physical).
     3223 */
     3224uint16_t remR3PhysReadU16(RTGCPHYS SrcGCPhys)
     3225{
     3226    uint16_t val;
     3227    STAM_PROFILE_ADV_START(&gStatMemRead, a);
     3228    VBOX_CHECK_ADDR(SrcGCPhys);
     3229    val = PGMR3PhysReadWord(cpu_single_env->pVM, SrcGCPhys);
     3230    STAM_PROFILE_ADV_STOP(&gStatMemRead, a);
     3231    return val;
     3232}
     3233
     3234
     3235/**
     3236 * Read guest RAM and ROM, signed 16-bit.
     3237 *
     3238 * @param   SrcGCPhys       The source address (guest physical).
     3239 */
     3240int16_t remR3PhysReadS16(RTGCPHYS SrcGCPhys)
     3241{
     3242    uint16_t val;
     3243    STAM_PROFILE_ADV_START(&gStatMemRead, a);
     3244    VBOX_CHECK_ADDR(SrcGCPhys);
     3245    val = PGMR3PhysReadWord(cpu_single_env->pVM, SrcGCPhys);
     3246    STAM_PROFILE_ADV_STOP(&gStatMemRead, a);
     3247    return val;
     3248}
     3249
     3250
     3251/**
     3252 * Read guest RAM and ROM, unsigned 32-bit.
     3253 *
     3254 * @param   SrcGCPhys       The source address (guest physical).
     3255 */
     3256uint32_t remR3PhysReadU32(RTGCPHYS SrcGCPhys)
     3257{
     3258    uint32_t val;
     3259    STAM_PROFILE_ADV_START(&gStatMemRead, a);
     3260    VBOX_CHECK_ADDR(SrcGCPhys);
     3261    val = PGMR3PhysReadDword(cpu_single_env->pVM, SrcGCPhys);
     3262    STAM_PROFILE_ADV_STOP(&gStatMemRead, a);
     3263    return val;
     3264}
     3265
     3266
     3267/**
     3268 * Read guest RAM and ROM, signed 32-bit.
     3269 *
     3270 * @param   SrcGCPhys       The source address (guest physical).
     3271 */
     3272int32_t remR3PhysReadS32(RTGCPHYS SrcGCPhys)
     3273{
     3274    int32_t val;
     3275    STAM_PROFILE_ADV_START(&gStatMemRead, a);
     3276    VBOX_CHECK_ADDR(SrcGCPhys);
     3277    val = PGMR3PhysReadDword(cpu_single_env->pVM, SrcGCPhys);
     3278    STAM_PROFILE_ADV_STOP(&gStatMemRead, a);
     3279    return val;
     3280}
     3281
     3282
     3283/**
     3284 * Read guest RAM and ROM, unsigned 64-bit.
     3285 *
     3286 * @param   SrcGCPhys       The source address (guest physical).
     3287 */
     3288uint64_t remR3PhysReadU64(RTGCPHYS SrcGCPhys)
     3289{
     3290    uint64_t val;
     3291    STAM_PROFILE_ADV_START(&gStatMemRead, a);
     3292    VBOX_CHECK_ADDR(SrcGCPhys);
     3293    val =            PGMR3PhysReadDword(cpu_single_env->pVM, SrcGCPhys)
     3294        | ((uint64_t)PGMR3PhysReadDword(cpu_single_env->pVM, SrcGCPhys + 4) << 32); /** @todo fix me! */
     3295    STAM_PROFILE_ADV_STOP(&gStatMemRead, a);
     3296    return val;
     3297}
     3298
     3299
     3300/**
     3301 * Write guest RAM.
     3302 *
     3303 * @param   DstGCPhys       The destination address (guest physical).
     3304 * @param   pvSrc           The source address.
     3305 * @param   cb              Number of bytes to write
     3306 */
     3307void remR3PhysWrite(RTGCPHYS DstGCPhys, const void *pvSrc, unsigned cb)
     3308{
     3309    STAM_PROFILE_ADV_START(&gStatMemWrite, a);
     3310    VBOX_CHECK_ADDR(DstGCPhys);
     3311    PGMPhysWrite(cpu_single_env->pVM, DstGCPhys, pvSrc, cb);
     3312    STAM_PROFILE_ADV_STOP(&gStatMemWrite, a);
     3313}
     3314
     3315
     3316/**
     3317 * Write guest RAM, unsigned 8-bit.
     3318 *
     3319 * @param   DstGCPhys       The destination address (guest physical).
     3320 * @param   val             Value
     3321 */
     3322void remR3PhysWriteU8(RTGCPHYS DstGCPhys, uint8_t val)
     3323{
     3324    STAM_PROFILE_ADV_START(&gStatMemWrite, a);
     3325    VBOX_CHECK_ADDR(DstGCPhys);
     3326    PGMR3PhysWriteByte(cpu_single_env->pVM, DstGCPhys, val);
     3327    STAM_PROFILE_ADV_STOP(&gStatMemWrite, a);
     3328}
     3329
     3330
     3331/**
     3332 * Write guest RAM, unsigned 8-bit.
     3333 *
     3334 * @param   DstGCPhys       The destination address (guest physical).
     3335 * @param   val             Value
     3336 */
     3337void remR3PhysWriteU16(RTGCPHYS DstGCPhys, uint16_t val)
     3338{
     3339    STAM_PROFILE_ADV_START(&gStatMemWrite, a);
     3340    VBOX_CHECK_ADDR(DstGCPhys);
     3341    PGMR3PhysWriteWord(cpu_single_env->pVM, DstGCPhys, val);
     3342    STAM_PROFILE_ADV_STOP(&gStatMemWrite, a);
     3343}
     3344
     3345
     3346/**
     3347 * Write guest RAM, unsigned 32-bit.
     3348 *
     3349 * @param   DstGCPhys       The destination address (guest physical).
     3350 * @param   val             Value
     3351 */
     3352void remR3PhysWriteU32(RTGCPHYS DstGCPhys, uint32_t val)
     3353{
     3354    STAM_PROFILE_ADV_START(&gStatMemWrite, a);
     3355    VBOX_CHECK_ADDR(DstGCPhys);
     3356    PGMR3PhysWriteDword(cpu_single_env->pVM, DstGCPhys, val);
     3357    STAM_PROFILE_ADV_STOP(&gStatMemWrite, a);
     3358}
     3359
     3360
     3361/**
     3362 * Write guest RAM, unsigned 64-bit.
     3363 *
     3364 * @param   DstGCPhys       The destination address (guest physical).
     3365 * @param   val             Value
     3366 */
     3367void remR3PhysWriteU64(RTGCPHYS DstGCPhys, uint64_t val)
     3368{
     3369    STAM_PROFILE_ADV_START(&gStatMemWrite, a);
     3370    VBOX_CHECK_ADDR(DstGCPhys);
     3371    PGMR3PhysWriteDword(cpu_single_env->pVM, DstGCPhys, (uint32_t)val); /** @todo add U64 interface. */
     3372    PGMR3PhysWriteDword(cpu_single_env->pVM, DstGCPhys + 4, val >> 32);
     3373    STAM_PROFILE_ADV_STOP(&gStatMemWrite, a);
     3374}
     3375
     3376
     3377#ifndef REM_PHYS_ADDR_IN_TLB
    29423378
    29433379/**
     
    29483384 * @param   cb              Number of bytes
    29493385 */
    2950 void remR3PhysReadBytes(uint8_t *pbSrcPhys, void *pvDst, unsigned cb)
    2951 {
    2952     STAM_PROFILE_ADV_START(&gStatMemRead, a);
     3386void remR3PhysReadHCPtr(uint8_t *pbSrcPhys, void *pvDst, unsigned cb)
     3387{
     3388    STAM_PROFILE_ADV_START(&gStatMemReadHCPtr, a);
    29533389
    29543390    /*
     
    29563392     * ROM is accessed this way, even if it's not part of the RAM.
    29573393     */
    2958     /** @todo This is rather ugly, but there's no other way when we don't wish to touch *many* other files. */
    2959     uintptr_t off = remR3HCVirt2GCPhys(cpu_single_env, pbSrcPhys);
    2960     if (off < (uintptr_t)phys_ram_size)
    2961         PGMPhysRead(cpu_single_env->pVM, (RTGCPHYS)off, pvDst, cb);
    2962     else
    2963     {
    2964         /* ROM range outside physical RAM, HC address passed directly */
    2965         Log4(("remR3PhysReadBytes ROM: %p\n", pbSrcPhys));
    2966         memcpy(pvDst, pbSrcPhys, cb);
    2967     }
    2968     STAM_PROFILE_ADV_STOP(&gStatMemRead, a);
    2969 }
    2970 
    2971 /** @todo r=bird: s/Byte/U8/ s/Word/U16/ s/Dword/U32/, see MMIO and other functions.
    2972  * It could be an idea to inline these wrapper functions... */
    2973 
    2974 /**
    2975  * Read guest RAM and ROM.
     3394#ifdef PGM_DYNAMIC_RAM_ALLOC
     3395    uintptr_t off = remR3HCVirt2GCPhysInlined(cpu_single_env->pVM, pbSrcPhys);
     3396#else
     3397    uintptr_t off = pbSrcPhys - phys_ram_base;
     3398#endif
     3399    PGMPhysRead(cpu_single_env->pVM, (RTGCPHYS)off, pvDst, cb);
     3400    STAM_PROFILE_ADV_STOP(&gStatMemReadHCPtr, a);
     3401}
     3402
     3403
     3404/**
     3405 * Read guest RAM and ROM, unsigned 8-bit.
    29763406 *
    29773407 * @param   pbSrcPhys       The source address. Relative to guest RAM.
    29783408 */
    2979 uint8_t remR3PhysReadUByte(uint8_t *pbSrcPhys)
     3409uint8_t remR3PhysReadHCPtrU8(uint8_t *pbSrcPhys)
    29803410{
    29813411    uint8_t val;
    29823412
    2983     STAM_PROFILE_ADV_START(&gStatMemRead, a);
     3413    STAM_PROFILE_ADV_START(&gStatMemReadHCPtr, a);
    29843414
    29853415    /*
     
    29873417     * ROM is accessed this way, even if it's not part of the RAM.
    29883418     */
    2989     /** @todo This is rather ugly, but there's no other way when we don't wish to touch *many* other files. */
    2990     uintptr_t off = remR3HCVirt2GCPhys(cpu_single_env, pbSrcPhys);
    2991     if (off < (uintptr_t)phys_ram_size)
    2992         val = PGMR3PhysReadByte(cpu_single_env->pVM, (RTGCPHYS)off);
    2993     else
    2994     {
    2995         /* ROM range outside physical RAM, HC address passed directly */
    2996         Log4(("remR3PhysReadBytes ROM: %p\n", pbSrcPhys));
    2997         val = *pbSrcPhys;
    2998     }
    2999     STAM_PROFILE_ADV_STOP(&gStatMemRead, a);
     3419#ifdef PGM_DYNAMIC_RAM_ALLOC
     3420    uintptr_t off = remR3HCVirt2GCPhysInlined(cpu_single_env->pVM, pbSrcPhys);
     3421#else
     3422    uintptr_t off = pbSrcPhys - phys_ram_base;
     3423#endif
     3424    val = PGMR3PhysReadByte(cpu_single_env->pVM, (RTGCPHYS)off);
     3425    STAM_PROFILE_ADV_STOP(&gStatMemReadHCPtr, a);
    30003426    return val;
    30013427}
    30023428
    3003 /**
    3004  * Read guest RAM and ROM.
     3429
     3430/**
     3431 * Read guest RAM and ROM, signed 8-bit.
    30053432 *
    30063433 * @param   pbSrcPhys       The source address. Relative to guest RAM.
    30073434 */
    3008 int8_t remR3PhysReadSByte(uint8_t *pbSrcPhys)
     3435int8_t remR3PhysReadHCPtrS8(uint8_t *pbSrcPhys)
    30093436{
    30103437    int8_t val;
    30113438
    3012     STAM_PROFILE_ADV_START(&gStatMemRead, a);
     3439    STAM_PROFILE_ADV_START(&gStatMemReadHCPtr, a);
    30133440
    30143441    /*
     
    30163443     * ROM is accessed this way, even if it's not part of the RAM.
    30173444     */
    3018     /** @todo This is rather ugly, but there's no other way when we don't wish to touch *many* other files. */
    3019     uintptr_t off = remR3HCVirt2GCPhys(cpu_single_env, pbSrcPhys);
    3020     if (off < (uintptr_t)phys_ram_size)
    3021         val = PGMR3PhysReadByte(cpu_single_env->pVM, (RTGCPHYS)off);
    3022     else
    3023     {
    3024         /* ROM range outside physical RAM, HC address passed directly */
    3025         Log4(("remR3PhysReadBytes ROM: %p\n", pbSrcPhys));
    3026         val = *(int8_t *)pbSrcPhys;
    3027     }
    3028     STAM_PROFILE_ADV_STOP(&gStatMemRead, a);
     3445#ifdef PGM_DYNAMIC_RAM_ALLOC
     3446    uintptr_t off = remR3HCVirt2GCPhysInlined(cpu_single_env->pVM, pbSrcPhys);
     3447#else
     3448    uintptr_t off = pbSrcPhys - phys_ram_base;
     3449#endif
     3450    val = PGMR3PhysReadByte(cpu_single_env->pVM, (RTGCPHYS)off);
     3451    STAM_PROFILE_ADV_STOP(&gStatMemReadHCPtr, a);
    30293452    return val;
    30303453}
    30313454
    3032 /**
    3033  * Read guest RAM and ROM.
     3455
     3456/**
     3457 * Read guest RAM and ROM, unsigned 16-bit.
    30343458 *
    30353459 * @param   pbSrcPhys       The source address. Relative to guest RAM.
    30363460 */
    3037 uint16_t remR3PhysReadUWord(uint8_t *pbSrcPhys)
     3461uint16_t remR3PhysReadHCPtrU16(uint8_t *pbSrcPhys)
    30383462{
    30393463    uint16_t val;
    30403464
    3041     STAM_PROFILE_ADV_START(&gStatMemRead, a);
     3465    STAM_PROFILE_ADV_START(&gStatMemReadHCPtr, a);
    30423466
    30433467    /*
     
    30453469     * ROM is accessed this way, even if it's not part of the RAM.
    30463470     */
    3047     /** @todo This is rather ugly, but there's no other way when we don't wish to touch *many* other files. */
    3048     uintptr_t off = remR3HCVirt2GCPhys(cpu_single_env, pbSrcPhys);
    3049     if (off < (uintptr_t)phys_ram_size)
    3050         val = PGMR3PhysReadWord(cpu_single_env->pVM, (RTGCPHYS)off);
    3051     else
    3052     {
    3053         /* ROM range outside physical RAM, HC address passed directly */
    3054         Log4(("remR3PhysReadBytes ROM: %p\n", pbSrcPhys));
    3055         val = *(uint16_t *)pbSrcPhys;
    3056     }
    3057     STAM_PROFILE_ADV_STOP(&gStatMemRead, a);
     3471#ifdef PGM_DYNAMIC_RAM_ALLOC
     3472    uintptr_t off = remR3HCVirt2GCPhysInlined(cpu_single_env->pVM, pbSrcPhys);
     3473#else
     3474    uintptr_t off = pbSrcPhys - phys_ram_base;
     3475#endif
     3476    val = PGMR3PhysReadWord(cpu_single_env->pVM, (RTGCPHYS)off);
     3477    STAM_PROFILE_ADV_STOP(&gStatMemReadHCPtr, a);
    30583478    return val;
    30593479}
    30603480
    3061 /**
    3062  * Read guest RAM and ROM.
     3481
     3482/**
     3483 * Read guest RAM and ROM, signed 16-bit.
    30633484 *
    30643485 * @param   pbSrcPhys       The source address. Relative to guest RAM.
    30653486 */
    3066 int16_t remR3PhysReadSWord(uint8_t *pbSrcPhys)
     3487int16_t remR3PhysReadHCPtrS16(uint8_t *pbSrcPhys)
    30673488{
    30683489    int16_t val;
    30693490
    3070     STAM_PROFILE_ADV_START(&gStatMemRead, a);
     3491    STAM_PROFILE_ADV_START(&gStatMemReadHCPtr, a);
    30713492
    30723493    /*
     
    30753496     */
    30763497    /** @todo This is rather ugly, but there's no other way when we don't wish to touch *many* other files. */
    3077     uintptr_t off = remR3HCVirt2GCPhys(cpu_single_env, pbSrcPhys);
    3078     if (off < (uintptr_t)phys_ram_size)
    3079         val = PGMR3PhysReadWord(cpu_single_env->pVM, (RTGCPHYS)off);
    3080     else
    3081     {
    3082         /* ROM range outside physical RAM, HC address passed directly */
    3083         Log4(("remR3PhysReadBytes ROM: %p\n", pbSrcPhys));
    3084         val = *(int16_t *)pbSrcPhys;
    3085     }
    3086     STAM_PROFILE_ADV_STOP(&gStatMemRead, a);
     3498#ifdef PGM_DYNAMIC_RAM_ALLOC
     3499    uintptr_t off = remR3HCVirt2GCPhysInlined(cpu_single_env->pVM, pbSrcPhys);
     3500#else
     3501    uintptr_t off = pbSrcPhys - phys_ram_base;
     3502#endif
     3503    val = PGMR3PhysReadWord(cpu_single_env->pVM, (RTGCPHYS)off);
     3504    STAM_PROFILE_ADV_STOP(&gStatMemReadHCPtr, a);
    30873505    return val;
    30883506}
    30893507
    3090 /**
    3091  * Read guest RAM and ROM.
     3508
     3509/**
     3510 * Read guest RAM and ROM, unsigned 32-bit.
    30923511 *
    30933512 * @param   pbSrcPhys       The source address. Relative to guest RAM.
    30943513 */
    3095 uint32_t remR3PhysReadULong(uint8_t *pbSrcPhys)
     3514uint32_t remR3PhysReadHCPtrU32(uint8_t *pbSrcPhys)
    30963515{
    30973516    uint32_t val;
    30983517
    3099     STAM_PROFILE_ADV_START(&gStatMemRead, a);
     3518    STAM_PROFILE_ADV_START(&gStatMemReadHCPtr, a);
    31003519
    31013520    /*
     
    31033522     * ROM is accessed this way, even if it's not part of the RAM.
    31043523     */
    3105     /** @todo This is rather ugly, but there's no other way when we don't wish to touch *many* other files. */
    3106     uintptr_t off = remR3HCVirt2GCPhys(cpu_single_env, pbSrcPhys);
    3107     if (off < (uintptr_t)phys_ram_size)
    3108         val = PGMR3PhysReadDword(cpu_single_env->pVM, (RTGCPHYS)off);
    3109     else
    3110     {
    3111         /* ROM range outside physical RAM, HC address passed directly */
    3112         Log4(("remR3PhysReadBytes ROM: %p\n", pbSrcPhys));
    3113         val = *(uint32_t *)pbSrcPhys;
    3114     }
    3115     STAM_PROFILE_ADV_STOP(&gStatMemRead, a);
     3524#ifdef PGM_DYNAMIC_RAM_ALLOC
     3525    uintptr_t off = remR3HCVirt2GCPhysInlined(cpu_single_env->pVM, pbSrcPhys);
     3526#else
     3527    uintptr_t off = pbSrcPhys - phys_ram_base;
     3528#endif
     3529    val = PGMR3PhysReadDword(cpu_single_env->pVM, (RTGCPHYS)off);
     3530    STAM_PROFILE_ADV_STOP(&gStatMemReadHCPtr, a);
    31163531    return val;
    31173532}
    31183533
    3119 /**
    3120  * Read guest RAM and ROM.
     3534
     3535/**
     3536 * Read guest RAM and ROM, signed 32-bit.
    31213537 *
    31223538 * @param   pbSrcPhys       The source address. Relative to guest RAM.
    31233539 */
    3124 int32_t remR3PhysReadSLong(uint8_t *pbSrcPhys)
     3540int32_t remR3PhysReadHCPtrS32(uint8_t *pbSrcPhys)
    31253541{
    31263542    int32_t val;
    31273543
    3128     STAM_PROFILE_ADV_START(&gStatMemRead, a);
     3544    STAM_PROFILE_ADV_START(&gStatMemReadHCPtr, a);
    31293545
    31303546    /*
     
    31323548     * ROM is accessed this way, even if it's not part of the RAM.
    31333549     */
    3134     /** @todo This is rather ugly, but there's no other way when we don't wish to touch *many* other files. */
    3135     uintptr_t off = remR3HCVirt2GCPhys(cpu_single_env, pbSrcPhys);
    3136     if (off < (uintptr_t)phys_ram_size)
    3137         val = PGMR3PhysReadDword(cpu_single_env->pVM, (RTGCPHYS)off);
    3138     else
    3139     {
    3140         /* ROM range outside physical RAM, HC address passed directly */
    3141         Log4(("remR3PhysReadBytes ROM: %p\n", pbSrcPhys));
    3142         val = *(int32_t *)pbSrcPhys;
    3143     }
    3144     STAM_PROFILE_ADV_STOP(&gStatMemRead, a);
     3550#ifdef PGM_DYNAMIC_RAM_ALLOC
     3551    uintptr_t off = remR3HCVirt2GCPhysInlined(cpu_single_env->pVM, pbSrcPhys);
     3552#else
     3553    uintptr_t off = pbSrcPhys - phys_ram_base;
     3554#endif
     3555    val = PGMR3PhysReadDword(cpu_single_env->pVM, (RTGCPHYS)off);
     3556    STAM_PROFILE_ADV_STOP(&gStatMemReadHCPtr, a);
    31453557    return val;
    31463558}
     3559
     3560
     3561/**
     3562 * Read guest RAM and ROM, unsigned 64-bit.
     3563 *
     3564 * @param   pbSrcPhys       The source address. Relative to guest RAM.
     3565 */
     3566uint64_t remR3PhysReadHCPtrU64(uint8_t *pbSrcPhys)
     3567{
     3568    uint64_t val;
     3569
     3570    STAM_PROFILE_ADV_START(&gStatMemReadHCPtr, a);
     3571
     3572    /*
     3573     * Calc the physical address ('off') and check that it's within the RAM.
     3574     * ROM is accessed this way, even if it's not part of the RAM.
     3575     */
     3576#ifdef PGM_DYNAMIC_RAM_ALLOC
     3577    uintptr_t off = remR3HCVirt2GCPhysInlined(cpu_single_env->pVM, pbSrcPhys);
     3578#else
     3579    uintptr_t off = pbSrcPhys - phys_ram_base;
     3580#endif
     3581    val =            PGMR3PhysReadDword(cpu_single_env->pVM, (RTGCPHYS)off)
     3582        | ((uint64_t)PGMR3PhysReadDword(cpu_single_env->pVM, (RTGCPHYS)off + 4) << 32); /** @todo fix me! */
     3583    STAM_PROFILE_ADV_STOP(&gStatMemReadHCPtr, a);
     3584    return val;
     3585}
     3586
    31473587
    31483588/**
     
    31533593 * @param   cb              Number of bytes to write
    31543594 */
    3155 void remR3PhysWriteBytes(uint8_t *pbDstPhys, const void *pvSrc, unsigned cb)
    3156 {
    3157     STAM_PROFILE_ADV_START(&gStatMemWrite, a);
     3595void remR3PhysWriteHCPtr(uint8_t *pbDstPhys, const void *pvSrc, unsigned cb)
     3596{
     3597    STAM_PROFILE_ADV_START(&gStatMemWriteHCPtr, a);
    31583598    /*
    31593599     * Calc the physical address ('off') and check that it's within the RAM.
    31603600     */
    3161     uintptr_t off = remR3HCVirt2GCPhys(cpu_single_env, pbDstPhys);
    3162     if (off < (uintptr_t)phys_ram_size)
    3163         PGMPhysWrite(cpu_single_env->pVM, (RTGCPHYS)off, pvSrc, cb);
    3164     else
    3165         AssertMsgFailed(("pbDstPhys=%p off=%p cb=%d\n", pbDstPhys, off, cb));
    3166     STAM_PROFILE_ADV_STOP(&gStatMemWrite, a);
    3167 }
    3168 
    3169 
    3170 /**
    3171  * Write guest RAM.
     3601#ifdef PGM_DYNAMIC_RAM_ALLOC
     3602    uintptr_t off = remR3HCVirt2GCPhysInlined(cpu_single_env->pVM, pbDstPhys);
     3603#else
     3604    uintptr_t off = pbDstPhys - phys_ram_base;
     3605#endif
     3606    PGMPhysWrite(cpu_single_env->pVM, (RTGCPHYS)off, pvSrc, cb);
     3607    STAM_PROFILE_ADV_STOP(&gStatMemWriteHCPtr, a);
     3608}
     3609
     3610
     3611/**
     3612 * Write guest RAM, unsigned 8-bit.
    31723613 *
    31733614 * @param   pbDstPhys       The destination address. Relative to guest RAM.
    31743615 * @param   val             Value
    31753616 */
    3176 void remR3PhysWriteByte(uint8_t *pbDstPhys, uint8_t val)
    3177 {
    3178     STAM_PROFILE_ADV_START(&gStatMemWrite, a);
     3617void remR3PhysWriteHCPtrU8(uint8_t *pbDstPhys, uint8_t val)
     3618{
     3619    STAM_PROFILE_ADV_START(&gStatMemWriteHCPtr, a);
    31793620    /*
    31803621     * Calc the physical address ('off') and check that it's within the RAM.
    31813622     */
    3182     uintptr_t off = remR3HCVirt2GCPhys(cpu_single_env, pbDstPhys);
    3183     if (off < (uintptr_t)phys_ram_size)
    3184         PGMR3PhysWriteByte(cpu_single_env->pVM, (RTGCPHYS)off, val);
    3185     else
    3186         AssertMsgFailed(("pbDstPhys=%p off=%p cb=%d\n", pbDstPhys, off, 1));
    3187     STAM_PROFILE_ADV_STOP(&gStatMemWrite, a);
    3188 }
    3189 
    3190 /**
    3191  * Write guest RAM.
     3623#ifdef PGM_DYNAMIC_RAM_ALLOC
     3624    uintptr_t off = remR3HCVirt2GCPhysInlined(cpu_single_env->pVM, pbDstPhys);
     3625#else
     3626    uintptr_t off = pbDstPhys - phys_ram_base;
     3627#endif
     3628    PGMR3PhysWriteByte(cpu_single_env->pVM, (RTGCPHYS)off, val);
     3629    STAM_PROFILE_ADV_STOP(&gStatMemWriteHCPtr, a);
     3630}
     3631
     3632
     3633/**
     3634 * Write guest RAM, unsigned 16-bit.
    31923635 *
    31933636 * @param   pbDstPhys       The destination address. Relative to guest RAM.
    31943637 * @param   val             Value
    31953638 */
    3196 void remR3PhysWriteWord(uint8_t *pbDstPhys, uint16_t val)
    3197 {
    3198     STAM_PROFILE_ADV_START(&gStatMemWrite, a);
     3639void remR3PhysWriteHCPtrU16(uint8_t *pbDstPhys, uint16_t val)
     3640{
     3641    STAM_PROFILE_ADV_START(&gStatMemWriteHCPtr, a);
    31993642    /*
    32003643     * Calc the physical address ('off') and check that it's within the RAM.
    32013644     */
    3202     uintptr_t off = remR3HCVirt2GCPhys(cpu_single_env, pbDstPhys);
    3203     if (off < (uintptr_t)phys_ram_size)
    3204         PGMR3PhysWriteWord(cpu_single_env->pVM, (RTGCPHYS)off, val);
    3205     else
    3206         AssertMsgFailed(("pbDstPhys=%p off=%p cb=%d\n", pbDstPhys, off, 2));
    3207     STAM_PROFILE_ADV_STOP(&gStatMemWrite, a);
    3208 }
    3209 
    3210 /**
    3211  * Write guest RAM.
     3645#ifdef PGM_DYNAMIC_RAM_ALLOC
     3646    uintptr_t off = remR3HCVirt2GCPhysInlined(cpu_single_env->pVM, pbDstPhys);
     3647#else
     3648    uintptr_t off = pbDstPhys - phys_ram_base;
     3649#endif
     3650    PGMR3PhysWriteWord(cpu_single_env->pVM, (RTGCPHYS)off, val);
     3651    STAM_PROFILE_ADV_STOP(&gStatMemWriteHCPtr, a);
     3652}
     3653
     3654
     3655/**
     3656 * Write guest RAM, unsigned 32-bit.
    32123657 *
    32133658 * @param   pbDstPhys       The destination address. Relative to guest RAM.
    32143659 * @param   val             Value
    32153660 */
    3216 void remR3PhysWriteDword(uint8_t *pbDstPhys, uint32_t val)
    3217 {
    3218     STAM_PROFILE_ADV_START(&gStatMemWrite, a);
     3661void remR3PhysWriteHCPtrU32(uint8_t *pbDstPhys, uint32_t val)
     3662{
     3663    STAM_PROFILE_ADV_START(&gStatMemWriteHCPtr, a);
    32193664    /*
    32203665     * Calc the physical address ('off') and check that it's within the RAM.
    32213666     */
    3222     uintptr_t off = remR3HCVirt2GCPhys(cpu_single_env, pbDstPhys);
    3223     if (off < (uintptr_t)phys_ram_size)
    3224         PGMR3PhysWriteDword(cpu_single_env->pVM, (RTGCPHYS)off, val);
    3225     else
    3226         AssertMsgFailed(("pbDstPhys=%p off=%p cb=%d\n", pbDstPhys, off, 4));
    3227     STAM_PROFILE_ADV_STOP(&gStatMemWrite, a);
    3228 }
    3229 
     3667#ifdef PGM_DYNAMIC_RAM_ALLOC
     3668    uintptr_t off = remR3HCVirt2GCPhysInlined(cpu_single_env->pVM, pbDstPhys);
     3669#else
     3670    uintptr_t off = pbDstPhys - phys_ram_base;
     3671#endif
     3672    PGMR3PhysWriteDword(cpu_single_env->pVM, (RTGCPHYS)off, val);
     3673    STAM_PROFILE_ADV_STOP(&gStatMemWriteHCPtr, a);
     3674}
     3675
     3676
     3677/**
     3678 * Write guest RAM, unsigned 64-bit.
     3679 *
     3680 * @param   pbDstPhys       The destination address. Relative to guest RAM.
     3681 * @param   val             Value
     3682 */
     3683void remR3PhysWriteHCPtrU64(uint8_t *pbDstPhys, uint64_t val)
     3684{
     3685    STAM_PROFILE_ADV_START(&gStatMemWriteHCPtr, a);
     3686    /*
     3687     * Calc the physical address ('off') and check that it's within the RAM.
     3688     */
     3689#ifdef PGM_DYNAMIC_RAM_ALLOC
     3690    uintptr_t off = remR3HCVirt2GCPhysInlined(cpu_single_env->pVM, pbDstPhys);
     3691#else
     3692    uintptr_t off = pbDstPhys - phys_ram_base;
     3693#endif
     3694    PGMR3PhysWriteDword(cpu_single_env->pVM, (RTGCPHYS)off, (uint32_t)val); /** @todo add U64 interface. */
     3695    PGMR3PhysWriteDword(cpu_single_env->pVM, (RTGCPHYS)off + 4, val >> 32);
     3696    STAM_PROFILE_ADV_STOP(&gStatMemWriteHCPtr, a);
     3697}
     3698
     3699#endif /* !REM_PHYS_ADDR_IN_TLB */
    32303700
    32313701
     
    34593929    {
    34603930        /* physical address */
    3461         int rc = PGMPhysGCPhys2HCPtr(env->pVM, (RTGCPHYS)GCPtrPC, nrInstructions*16, &pvPC);
     3931        int rc = PGMPhysGCPhys2HCPtr(env->pVM, (RTGCPHYS)GCPtrPC, nrInstructions * 16, &pvPC);
    34623932        if (VBOX_FAILURE(rc))
    34633933            return false;
     
    36824152        for (;;)
    36834153        {
    3684             char    szBuf[256];
    3685             size_t  cbInstr;
     4154            char        szBuf[256];
     4155            uint32_t    cbInstr;
    36864156            int rc = DBGFR3DisasInstrEx(pVM,
    36874157                                        cs,
     
    39784448uint64_t cpu_get_tsc(CPUX86State *env)
    39794449{
     4450    STAM_COUNTER_INC(&gStatCpuGetTSC);
    39804451    return TMCpuTickGet(env->pVM);
    39814452}
     
    48985369    };
    48995370    uint32_t    uEAX;
    4900 #ifndef DEBUG_bird
    49015371    if (!LogIsEnabled())
    49025372        return;
    4903 #endif
    49045373    uEAX = CPUMGetGuestEAX(pVM);
    49055374    switch (uEAX)
     
    49195388    }
    49205389}
     5390
     5391
     5392#if defined(IPRT_NO_CRT) && defined(__WIN__) && defined(__X86__)
     5393/**
     5394 * The Dll main entry point (stub).
     5395 */
     5396bool __stdcall _DllMainCRTStartup(void *hModule, uint32_t dwReason, void *pvReserved)
     5397{
     5398    return true;
     5399}
     5400
     5401void *memcpy(void *dst, const void *src, size_t size)
     5402{
     5403    uint8_t*pbDst = dst, *pbSrc = src;
     5404    while (size-- > 0)
     5405        *pbDst++ = *pbSrc++;
     5406    return dst;
     5407}
     5408
     5409#endif
     5410
  • trunk/src/recompiler/a.out.h

    r1 r2422  
    152152#define E_DIMNUM        4       /* # array dimensions in auxiliary entry */
    153153
    154 #pragma pack(1)
    155 
    156 struct external_syment
     154struct __attribute__((packed)) external_syment
    157155{
    158156  union {
     
    169167  char e_numaux[1];
    170168};
    171 
    172 #pragma pack()
    173169
    174170#define N_BTMASK        (0xf)
  • trunk/src/recompiler/bswap.h

    r1 r2422  
    4343#else
    4444
    45 #define bswap_16(x) \
     45#define bswap_16(x) __extension__ /* <- VBOX */ \
    4646({ \
    4747        uint16_t __x = (x); \
     
    5151})
    5252
    53 #define bswap_32(x) \
     53#define bswap_32(x) __extension__ /* <- VBOX */ \
    5454({ \
    5555        uint32_t __x = (x); \
     
    6161})
    6262
    63 #define bswap_64(x) \
     63#define bswap_64(x) __extension__ /* <- VBOX */ \
    6464({ \
    6565        uint64_t __x = (x); \
  • trunk/src/recompiler/cpu-all.h

    r55 r2422  
    2121#define CPU_ALL_H
    2222
     23#ifdef VBOX
     24# ifndef LOG_GROUP
     25#  include <VBox/log.h>
     26#  define LOG_GROUP LOG_GROUP_REM
     27# endif
     28# include <VBox/pgm.h> /* PGM_DYNAMIC_RAM_ALLOC */
     29#endif
     30
    2331#if defined(__arm__) || defined(__sparc__)
    2432#define WORDS_ALIGNED
     
    110118#define tswapl(s) tswap32(s)
    111119#define tswapls(s) tswap32s((uint32_t *)(s))
     120#define bswaptls(s) bswap32s(s)
    112121#else
    113122#define tswapl(s) tswap64(s)
    114123#define tswapls(s) tswap64s((uint64_t *)(s))
     124#define bswaptls(s) bswap64s(s)
    115125#endif
    116126
     
    118128   endian ! */
    119129typedef union {
    120     double d;
    121 #if defined(WORDS_BIGENDIAN) || (defined(__arm__) && !defined(__VFP_FP__))
     130    float64 d;
     131#if defined(WORDS_BIGENDIAN) \
     132    || (defined(__arm__) && !defined(__VFP_FP__) && !defined(CONFIG_SOFTFLOAT))
    122133    struct {
    123134        uint32_t upper;
     
    170181#ifdef VBOX
    171182
    172 #if !defined(REMR3PHYSREADWRITE_DEFINED)
    173 #define REMR3PHYSREADWRITE_DEFINED
    174 /* Header sharing between vbox & qemu is rather ugly. */
    175 void     remR3PhysReadBytes(uint8_t *pbSrcPhys, void *pvDst, unsigned cb);
    176 uint8_t  remR3PhysReadUByte(uint8_t *pbSrcPhys);
    177 int8_t   remR3PhysReadSByte(uint8_t *pbSrcPhys);
    178 uint16_t remR3PhysReadUWord(uint8_t *pbSrcPhys);
    179 int16_t  remR3PhysReadSWord(uint8_t *pbSrcPhys);
    180 uint32_t remR3PhysReadULong(uint8_t *pbSrcPhys);
    181 int32_t  remR3PhysReadSLong(uint8_t *pbSrcPhys);
    182 void     remR3PhysWriteBytes(uint8_t *pbDstPhys, const void *pvSrc, unsigned cb);
    183 void     remR3PhysWriteByte(uint8_t *pbDstPhys, uint8_t val);
    184 void     remR3PhysWriteWord(uint8_t *pbDstPhys, uint16_t val);
    185 void     remR3PhysWriteDword(uint8_t *pbDstPhys, uint32_t val);
     183void     remR3PhysRead(RTGCPHYS SrcGCPhys, void *pvDst, unsigned cb);
     184uint8_t  remR3PhysReadU8(RTGCPHYS SrcGCPhys);
     185int8_t   remR3PhysReadS8(RTGCPHYS SrcGCPhys);
     186uint16_t remR3PhysReadU16(RTGCPHYS SrcGCPhys);
     187int16_t  remR3PhysReadS16(RTGCPHYS SrcGCPhys);
     188uint32_t remR3PhysReadU32(RTGCPHYS SrcGCPhys);
     189int32_t  remR3PhysReadS32(RTGCPHYS SrcGCPhys);
     190uint64_t remR3PhysReadU64(RTGCPHYS SrcGCPhys);
     191int64_t  remR3PhysReadS64(RTGCPHYS SrcGCPhys);
     192void     remR3PhysWrite(RTGCPHYS DstGCPhys, const void *pvSrc, unsigned cb);
     193void     remR3PhysWriteU8(RTGCPHYS DstGCPhys, uint8_t val);
     194void     remR3PhysWriteU16(RTGCPHYS DstGCPhys, uint16_t val);
     195void     remR3PhysWriteU32(RTGCPHYS DstGCPhys, uint32_t val);
     196void     remR3PhysWriteU64(RTGCPHYS DstGCPhys, uint64_t val);
     197
     198#ifndef REM_PHYS_ADDR_IN_TLB
     199void     remR3PhysReadHCPtr(uint8_t *pbSrcPhys, void *pvDst, unsigned cb);
     200uint8_t  remR3PhysReadHCPtrU8(uint8_t *pbSrcPhys);
     201int8_t   remR3PhysReadHCPtrS8(uint8_t *pbSrcPhys);
     202uint16_t remR3PhysReadHCPtrU16(uint8_t *pbSrcPhys);
     203int16_t  remR3PhysReadHCPtrS16(uint8_t *pbSrcPhys);
     204uint32_t remR3PhysReadHCPtrU32(uint8_t *pbSrcPhys);
     205int32_t  remR3PhysReadHCPtrS32(uint8_t *pbSrcPhys);
     206uint64_t remR3PhysReadHCPtrU64(uint8_t *pbSrcPhys);
     207int64_t  remR3PhysReadHCPtrS64(uint8_t *pbSrcPhys);
     208void     remR3PhysWriteHCPtr(uint8_t *pbDstPhys, const void *pvSrc, unsigned cb);
     209void     remR3PhysWriteHCPtrU8(uint8_t *pbDstPhys, uint8_t val);
     210void     remR3PhysWriteHCPtrU16(uint8_t *pbDstPhys, uint16_t val);
     211void     remR3PhysWriteHCPtrU32(uint8_t *pbDstPhys, uint32_t val);
     212void     remR3PhysWriteHCPtrU64(uint8_t *pbDstPhys, uint64_t val);
     213#endif
     214
     215#ifdef PGM_DYNAMIC_RAM_ALLOC
     216# ifndef REM_PHYS_ADDR_IN_TLB
    186217void    *remR3GCPhys2HCVirt(void *env, target_ulong addr);
    187218target_ulong remR3HCVirt2GCPhys(void *env, void *addr);
     219# endif
    188220void     remR3GrowDynRange(unsigned long physaddr);
    189221#endif
     222#if 0 /*defined(__AMD64__) && defined(VBOX_STRICT)*/
     223# define VBOX_CHECK_ADDR(ptr) do { if ((uintptr_t)(ptr) >= _4G) __asm__("int3"); } while (0)
     224#else
     225# define VBOX_CHECK_ADDR(ptr) do { } while (0)
     226#endif
    190227
    191228static inline int ldub_p(void *ptr)
    192229{
    193     return remR3PhysReadUByte(ptr);
     230#ifdef REM_PHYS_ADDR_IN_TLB
     231    VBOX_CHECK_ADDR(ptr);
     232    return remR3PhysReadU8((uintptr_t)ptr);
     233#else
     234    return remR3PhysReadHCPtrU8(ptr);
     235#endif
    194236}
    195237
    196238static inline int ldsb_p(void *ptr)
    197239{
    198     return remR3PhysReadSByte(ptr);
     240#ifdef REM_PHYS_ADDR_IN_TLB
     241    VBOX_CHECK_ADDR(ptr);
     242    return remR3PhysReadS8((uintptr_t)ptr);
     243#else
     244    return remR3PhysReadHCPtrS8(ptr);
     245#endif
    199246}
    200247
    201248static inline void stb_p(void *ptr, int v)
    202249{
    203     remR3PhysWriteByte(ptr, v);
    204 }
    205 
    206 #else
     250#ifdef REM_PHYS_ADDR_IN_TLB
     251    VBOX_CHECK_ADDR(ptr);
     252    remR3PhysWriteU8((uintptr_t)ptr, v);
     253#else
     254    remR3PhysWriteHCPtrU8(ptr, v);
     255#endif
     256}
     257
     258static inline int lduw_le_p(void *ptr)
     259{
     260#ifdef REM_PHYS_ADDR_IN_TLB
     261    VBOX_CHECK_ADDR(ptr);
     262    return remR3PhysReadU16((uintptr_t)ptr);
     263#else
     264    return remR3PhysReadHCPtrU16(ptr);
     265#endif
     266}
     267
     268static inline int ldsw_le_p(void *ptr)
     269{
     270#ifdef REM_PHYS_ADDR_IN_TLB
     271    VBOX_CHECK_ADDR(ptr);
     272    return remR3PhysReadS16((uintptr_t)ptr);
     273#else
     274    return remR3PhysReadHCPtrS16(ptr);
     275#endif
     276}
     277
     278static inline void stw_le_p(void *ptr, int v)
     279{
     280#ifdef REM_PHYS_ADDR_IN_TLB
     281    VBOX_CHECK_ADDR(ptr);
     282    remR3PhysWriteU16((uintptr_t)ptr, v);
     283#else
     284    remR3PhysWriteHCPtrU16(ptr, v);
     285#endif
     286}
     287
     288static inline int ldl_le_p(void *ptr)
     289{
     290#ifdef REM_PHYS_ADDR_IN_TLB
     291    VBOX_CHECK_ADDR(ptr);
     292    return remR3PhysReadU32((uintptr_t)ptr);
     293#else
     294    return remR3PhysReadHCPtrU32(ptr);
     295#endif
     296}
     297
     298static inline void stl_le_p(void *ptr, int v)
     299{
     300#ifdef REM_PHYS_ADDR_IN_TLB
     301    VBOX_CHECK_ADDR(ptr);
     302    remR3PhysWriteU32((uintptr_t)ptr, v);
     303#else
     304    remR3PhysWriteHCPtrU32(ptr, v);
     305#endif
     306}
     307
     308static inline void stq_le_p(void *ptr, uint64_t v)
     309{
     310#ifdef REM_PHYS_ADDR_IN_TLB
     311    VBOX_CHECK_ADDR(ptr);
     312    remR3PhysWriteU64((uintptr_t)ptr, v);
     313#else
     314    remR3PhysWriteHCPtrU64(ptr, v);
     315#endif
     316}
     317
     318static inline uint64_t ldq_le_p(void *ptr)
     319{
     320#ifdef REM_PHYS_ADDR_IN_TLB
     321    VBOX_CHECK_ADDR(ptr);
     322    return remR3PhysReadU64((uintptr_t)ptr);
     323#else
     324    return remR3PhysReadHCPtrU64(ptr);
     325#endif
     326}
     327
     328#undef VBOX_CHECK_ADDR
     329
     330/* float access */
     331
     332static inline float32 ldfl_le_p(void *ptr)
     333{
     334    union {
     335        float32 f;
     336        uint32_t i;
     337    } u;
     338    u.i = ldl_le_p(ptr);
     339    return u.f;
     340}
     341
     342static inline void stfl_le_p(void *ptr, float32 v)
     343{
     344    union {
     345        float32 f;
     346        uint32_t i;
     347    } u;
     348    u.f = v;
     349    stl_le_p(ptr, u.i);
     350}
     351
     352static inline float64 ldfq_le_p(void *ptr)
     353{
     354    CPU_DoubleU u;
     355    u.l.lower = ldl_le_p(ptr);
     356    u.l.upper = ldl_le_p(ptr + 4);
     357    return u.d;
     358}
     359
     360static inline void stfq_le_p(void *ptr, float64 v)
     361{
     362    CPU_DoubleU u;
     363    u.d = v;
     364    stl_le_p(ptr, u.l.lower);
     365    stl_le_p(ptr + 4, u.l.upper);
     366}
     367
     368#else  /* !VBOX */
     369
    207370static inline int ldub_p(void *ptr)
    208371{
     
    219382    *(uint8_t *)ptr = v;
    220383}
    221 #endif
    222384
    223385/* NOTE: on arm, putting 2 in /proc/sys/debug/alignment so that the
    224386   kernel handles unaligned load/stores may give better results, but
    225387   it is a system wide setting : bad */
    226 #if !defined(TARGET_WORDS_BIGENDIAN) && (defined(WORDS_BIGENDIAN) || defined(WORDS_ALIGNED))
     388#if defined(WORDS_BIGENDIAN) || defined(WORDS_ALIGNED)
     389
    227390/* conservative code for little endian unaligned accesses */
    228 static inline int lduw_p(void *ptr)
     391static inline int lduw_le_p(void *ptr)
    229392{
    230393#ifdef __powerpc__
     
    238401}
    239402
    240 static inline int ldsw_p(void *ptr)
     403static inline int ldsw_le_p(void *ptr)
    241404{
    242405#ifdef __powerpc__
     
    250413}
    251414
    252 static inline int ldl_p(void *ptr)
     415static inline int ldl_le_p(void *ptr)
    253416{
    254417#ifdef __powerpc__
     
    262425}
    263426
    264 static inline uint64_t ldq_p(void *ptr)
     427static inline uint64_t ldq_le_p(void *ptr)
    265428{
    266429    uint8_t *p = ptr;
    267430    uint32_t v1, v2;
    268     v1 = ldl_p(p);
    269     v2 = ldl_p(p + 4);
     431    v1 = ldl_le_p(p);
     432    v2 = ldl_le_p(p + 4);
    270433    return v1 | ((uint64_t)v2 << 32);
    271434}
    272435
    273 static inline void stw_p(void *ptr, int v)
     436static inline void stw_le_p(void *ptr, int v)
    274437{
    275438#ifdef __powerpc__
     
    282445}
    283446
    284 static inline void stl_p(void *ptr, int v)
     447static inline void stl_le_p(void *ptr, int v)
    285448{
    286449#ifdef __powerpc__
     
    295458}
    296459
    297 static inline void stq_p(void *ptr, uint64_t v)
     460static inline void stq_le_p(void *ptr, uint64_t v)
    298461{
    299462    uint8_t *p = ptr;
    300     stl_p(p, (uint32_t)v);
    301     stl_p(p + 4, v >> 32);
     463    stl_le_p(p, (uint32_t)v);
     464    stl_le_p(p + 4, v >> 32);
    302465}
    303466
    304467/* float access */
    305468
    306 static inline float ldfl_p(void *ptr)
     469static inline float32 ldfl_le_p(void *ptr)
    307470{
    308471    union {
    309         float f;
     472        float32 f;
    310473        uint32_t i;
    311474    } u;
    312     u.i = ldl_p(ptr);
     475    u.i = ldl_le_p(ptr);
    313476    return u.f;
    314477}
    315478
    316 static inline void stfl_p(void *ptr, float v)
     479static inline void stfl_le_p(void *ptr, float32 v)
    317480{
    318481    union {
    319         float f;
     482        float32 f;
    320483        uint32_t i;
    321484    } u;
    322485    u.f = v;
    323     stl_p(ptr, u.i);
    324 }
    325 
    326 static inline double ldfq_p(void *ptr)
     486    stl_le_p(ptr, u.i);
     487}
     488
     489static inline float64 ldfq_le_p(void *ptr)
    327490{
    328491    CPU_DoubleU u;
    329     u.l.lower = ldl_p(ptr);
    330     u.l.upper = ldl_p(ptr + 4);
     492    u.l.lower = ldl_le_p(ptr);
     493    u.l.upper = ldl_le_p(ptr + 4);
    331494    return u.d;
    332495}
    333496
    334 static inline void stfq_p(void *ptr, double v)
     497static inline void stfq_le_p(void *ptr, float64 v)
    335498{
    336499    CPU_DoubleU u;
    337500    u.d = v;
    338     stl_p(ptr, u.l.lower);
    339     stl_p(ptr + 4, u.l.upper);
    340 }
    341 
    342 #elif defined(TARGET_WORDS_BIGENDIAN) && (!defined(WORDS_BIGENDIAN) || defined(WORDS_ALIGNED))
    343 static inline int lduw_p(void *ptr)
     501    stl_le_p(ptr, u.l.lower);
     502    stl_le_p(ptr + 4, u.l.upper);
     503}
     504
     505#else
     506
     507static inline int lduw_le_p(void *ptr)
     508{
     509    return *(uint16_t *)ptr;
     510}
     511
     512static inline int ldsw_le_p(void *ptr)
     513{
     514    return *(int16_t *)ptr;
     515}
     516
     517static inline int ldl_le_p(void *ptr)
     518{
     519    return *(uint32_t *)ptr;
     520}
     521
     522static inline uint64_t ldq_le_p(void *ptr)
     523{
     524    return *(uint64_t *)ptr;
     525}
     526
     527static inline void stw_le_p(void *ptr, int v)
     528{
     529    *(uint16_t *)ptr = v;
     530}
     531
     532static inline void stl_le_p(void *ptr, int v)
     533{
     534    *(uint32_t *)ptr = v;
     535}
     536
     537static inline void stq_le_p(void *ptr, uint64_t v)
     538{
     539    *(uint64_t *)ptr = v;
     540}
     541
     542/* float access */
     543
     544static inline float32 ldfl_le_p(void *ptr)
     545{
     546    return *(float32 *)ptr;
     547}
     548
     549static inline float64 ldfq_le_p(void *ptr)
     550{
     551    return *(float64 *)ptr;
     552}
     553
     554static inline void stfl_le_p(void *ptr, float32 v)
     555{
     556    *(float32 *)ptr = v;
     557}
     558
     559static inline void stfq_le_p(void *ptr, float64 v)
     560{
     561    *(float64 *)ptr = v;
     562}
     563#endif
     564#endif /* !VBOX */
     565
     566#if !defined(WORDS_BIGENDIAN) || defined(WORDS_ALIGNED)
     567
     568static inline int lduw_be_p(void *ptr)
    344569{
    345570#if defined(__i386__)
     
    356581}
    357582
    358 static inline int ldsw_p(void *ptr)
     583static inline int ldsw_be_p(void *ptr)
    359584{
    360585#if defined(__i386__)
     
    371596}
    372597
    373 static inline int ldl_p(void *ptr)
     598static inline int ldl_be_p(void *ptr)
    374599{
    375600#if defined(__i386__) || defined(__x86_64__)
     
    386611}
    387612
    388 static inline uint64_t ldq_p(void *ptr)
     613static inline uint64_t ldq_be_p(void *ptr)
    389614{
    390615    uint32_t a,b;
    391     a = ldl_p(ptr);
    392     b = ldl_p(ptr+4);
     616    a = ldl_be_p(ptr);
     617    b = ldl_be_p(ptr+4);
    393618    return (((uint64_t)a<<32)|b);
    394619}
    395620
    396 static inline void stw_p(void *ptr, int v)
     621static inline void stw_be_p(void *ptr, int v)
    397622{
    398623#if defined(__i386__)
     
    408633}
    409634
    410 static inline void stl_p(void *ptr, int v)
     635static inline void stl_be_p(void *ptr, int v)
    411636{
    412637#if defined(__i386__) || defined(__x86_64__)
     
    424649}
    425650
    426 static inline void stq_p(void *ptr, uint64_t v)
    427 {
    428     stl_p(ptr, v >> 32);
    429     stl_p(ptr + 4, v);
     651static inline void stq_be_p(void *ptr, uint64_t v)
     652{
     653    stl_be_p(ptr, v >> 32);
     654    stl_be_p(ptr + 4, v);
    430655}
    431656
    432657/* float access */
    433658
    434 static inline float ldfl_p(void *ptr)
     659static inline float32 ldfl_be_p(void *ptr)
    435660{
    436661    union {
    437         float f;
     662        float32 f;
    438663        uint32_t i;
    439664    } u;
    440     u.i = ldl_p(ptr);
     665    u.i = ldl_be_p(ptr);
    441666    return u.f;
    442667}
    443668
    444 static inline void stfl_p(void *ptr, float v)
     669static inline void stfl_be_p(void *ptr, float32 v)
    445670{
    446671    union {
    447         float f;
     672        float32 f;
    448673        uint32_t i;
    449674    } u;
    450675    u.f = v;
    451     stl_p(ptr, u.i);
    452 }
    453 
    454 static inline double ldfq_p(void *ptr)
     676    stl_be_p(ptr, u.i);
     677}
     678
     679static inline float64 ldfq_be_p(void *ptr)
    455680{
    456681    CPU_DoubleU u;
    457     u.l.upper = ldl_p(ptr);
    458     u.l.lower = ldl_p(ptr + 4);
     682    u.l.upper = ldl_be_p(ptr);
     683    u.l.lower = ldl_be_p(ptr + 4);
    459684    return u.d;
    460685}
    461686
    462 static inline void stfq_p(void *ptr, double v)
     687static inline void stfq_be_p(void *ptr, float64 v)
    463688{
    464689    CPU_DoubleU u;
    465690    u.d = v;
    466     stl_p(ptr, u.l.upper);
    467     stl_p(ptr + 4, u.l.lower);
    468 }
    469 
    470 #else
    471 
    472 #ifdef VBOX
    473 static inline int lduw_p(void *ptr)
    474 {
    475     return remR3PhysReadUWord(ptr);
    476 }
    477 
    478 static inline int ldsw_p(void *ptr)
    479 {
    480     return remR3PhysReadSWord(ptr);
    481 }
    482 
    483 static inline int ldl_p(void *ptr)
    484 {
    485     return remR3PhysReadULong(ptr);
    486 }
    487 
    488 static inline uint64_t ldq_p(void *ptr)
    489 {
    490     uint64_t val;
    491 
    492     remR3PhysReadBytes(ptr, &val, sizeof(val));
    493     return val;
    494 }
    495 
    496 static inline void stw_p(void *ptr, int v)
    497 {
    498     remR3PhysWriteWord(ptr, (uint16_t)v);
    499 }
    500 
    501 static inline void stl_p(void *ptr, int v)
    502 {
    503     remR3PhysWriteDword(ptr, (uint32_t)v);
    504 }
    505 
    506 static inline void stq_p(void *ptr, uint64_t v)
    507 {
    508     remR3PhysWriteBytes(ptr, &v, sizeof(v));
     691    stl_be_p(ptr, u.l.upper);
     692    stl_be_p(ptr + 4, u.l.lower);
     693}
     694
     695#else
     696
     697static inline int lduw_be_p(void *ptr)
     698{
     699    return *(uint16_t *)ptr;
     700}
     701
     702static inline int ldsw_be_p(void *ptr)
     703{
     704    return *(int16_t *)ptr;
     705}
     706
     707static inline int ldl_be_p(void *ptr)
     708{
     709    return *(uint32_t *)ptr;
     710}
     711
     712static inline uint64_t ldq_be_p(void *ptr)
     713{
     714    return *(uint64_t *)ptr;
     715}
     716
     717static inline void stw_be_p(void *ptr, int v)
     718{
     719    *(uint16_t *)ptr = v;
     720}
     721
     722static inline void stl_be_p(void *ptr, int v)
     723{
     724    *(uint32_t *)ptr = v;
     725}
     726
     727static inline void stq_be_p(void *ptr, uint64_t v)
     728{
     729    *(uint64_t *)ptr = v;
    509730}
    510731
    511732/* float access */
    512733
    513 static inline float ldfl_p(void *ptr)
    514 {
    515     float val;
    516 
    517     remR3PhysReadBytes(ptr, &val, sizeof(val));
    518     return val;
    519 }
    520 
    521 static inline double ldfq_p(void *ptr)
    522 {
    523     double val;
    524 
    525     remR3PhysReadBytes(ptr, &val, sizeof(val));
    526     return val;
    527 }
    528 
    529 static inline void stfl_p(void *ptr, float v)
    530 {
    531     remR3PhysWriteBytes(ptr, &v, sizeof(v));
    532 }
    533 
    534 static inline void stfq_p(void *ptr, double v)
    535 {
    536     remR3PhysWriteBytes(ptr, &v, sizeof(v));
    537 }
    538 #else
    539 static inline int lduw_p(void *ptr)
    540 {
    541     return *(uint16_t *)ptr;
    542 }
    543 
    544 static inline int ldsw_p(void *ptr)
    545 {
    546     return *(int16_t *)ptr;
    547 }
    548 
    549 static inline int ldl_p(void *ptr)
    550 {
    551     return *(uint32_t *)ptr;
    552 }
    553 
    554 static inline uint64_t ldq_p(void *ptr)
    555 {
    556     return *(uint64_t *)ptr;
    557 }
    558 
    559 static inline void stw_p(void *ptr, int v)
    560 {
    561     *(uint16_t *)ptr = v;
    562 }
    563 
    564 static inline void stl_p(void *ptr, int v)
    565 {
    566     *(uint32_t *)ptr = v;
    567 }
    568 
    569 static inline void stq_p(void *ptr, uint64_t v)
    570 {
    571     *(uint64_t *)ptr = v;
    572 }
    573 
    574 /* float access */
    575 
    576 static inline float ldfl_p(void *ptr)
    577 {
    578     return *(float *)ptr;
    579 }
    580 
    581 static inline double ldfq_p(void *ptr)
    582 {
    583     return *(double *)ptr;
    584 }
    585 
    586 static inline void stfl_p(void *ptr, float v)
    587 {
    588     *(float *)ptr = v;
    589 }
    590 
    591 static inline void stfq_p(void *ptr, double v)
    592 {
    593     *(double *)ptr = v;
    594 }
    595 #endif /* VBOX */
    596 
     734static inline float32 ldfl_be_p(void *ptr)
     735{
     736    return *(float32 *)ptr;
     737}
     738
     739static inline float64 ldfq_be_p(void *ptr)
     740{
     741    return *(float64 *)ptr;
     742}
     743
     744static inline void stfl_be_p(void *ptr, float32 v)
     745{
     746    *(float32 *)ptr = v;
     747}
     748
     749static inline void stfq_be_p(void *ptr, float64 v)
     750{
     751    *(float64 *)ptr = v;
     752}
     753
     754#endif
     755
     756/* target CPU memory access functions */
     757#if defined(TARGET_WORDS_BIGENDIAN)
     758#define lduw_p(p) lduw_be_p(p)
     759#define ldsw_p(p) ldsw_be_p(p)
     760#define ldl_p(p) ldl_be_p(p)
     761#define ldq_p(p) ldq_be_p(p)
     762#define ldfl_p(p) ldfl_be_p(p)
     763#define ldfq_p(p) ldfq_be_p(p)
     764#define stw_p(p, v) stw_be_p(p, v)
     765#define stl_p(p, v) stl_be_p(p, v)
     766#define stq_p(p, v) stq_be_p(p, v)
     767#define stfl_p(p, v) stfl_be_p(p, v)
     768#define stfq_p(p, v) stfq_be_p(p, v)
     769#else
     770#define lduw_p(p) lduw_le_p(p)
     771#define ldsw_p(p) ldsw_le_p(p)
     772#define ldl_p(p) ldl_le_p(p)
     773#define ldq_p(p) ldq_le_p(p)
     774#define ldfl_p(p) ldfl_le_p(p)
     775#define ldfq_p(p) ldfq_le_p(p)
     776#define stw_p(p, v) stw_le_p(p, v)
     777#define stl_p(p, v) stl_le_p(p, v)
     778#define stq_p(p, v) stq_le_p(p, v)
     779#define stfl_p(p, v) stfl_le_p(p, v)
     780#define stfq_p(p, v) stfq_le_p(p, v)
    597781#endif
    598782
    599783/* MMU memory access macros */
    600784
     785#if defined(CONFIG_USER_ONLY)
     786/* On some host systems the guest address space is reserved on the host.
     787 * This allows the guest address space to be offset to a convenient location.
     788 */
     789//#define GUEST_BASE 0x20000000
     790#define GUEST_BASE 0
     791
     792/* All direct uses of g2h and h2g need to go away for usermode softmmu.  */
     793#define g2h(x) ((void *)((unsigned long)(x) + GUEST_BASE))
     794#define h2g(x) ((target_ulong)(x - GUEST_BASE))
     795
     796#define saddr(x) g2h(x)
     797#define laddr(x) g2h(x)
     798
     799#else /* !CONFIG_USER_ONLY */
    601800/* NOTE: we use double casts if pointers and target_ulong have
    602801   different sizes */
    603 #define ldub_raw(p) ldub_p((uint8_t *)(long)(p))
    604 #define ldsb_raw(p) ldsb_p((uint8_t *)(long)(p))
    605 #define lduw_raw(p) lduw_p((uint8_t *)(long)(p))
    606 #define ldsw_raw(p) ldsw_p((uint8_t *)(long)(p))
    607 #define ldl_raw(p) ldl_p((uint8_t *)(long)(p))
    608 #define ldq_raw(p) ldq_p((uint8_t *)(long)(p))
    609 #define ldfl_raw(p) ldfl_p((uint8_t *)(long)(p))
    610 #define ldfq_raw(p) ldfq_p((uint8_t *)(long)(p))
    611 #define stb_raw(p, v) stb_p((uint8_t *)(long)(p), v)
    612 #define stw_raw(p, v) stw_p((uint8_t *)(long)(p), v)
    613 #define stl_raw(p, v) stl_p((uint8_t *)(long)(p), v)
    614 #define stq_raw(p, v) stq_p((uint8_t *)(long)(p), v)
    615 #define stfl_raw(p, v) stfl_p((uint8_t *)(long)(p), v)
    616 #define stfq_raw(p, v) stfq_p((uint8_t *)(long)(p), v)
     802#define saddr(x) (uint8_t *)(long)(x)
     803#define laddr(x) (uint8_t *)(long)(x)
     804#endif
     805
     806#define ldub_raw(p) ldub_p(laddr((p)))
     807#define ldsb_raw(p) ldsb_p(laddr((p)))
     808#define lduw_raw(p) lduw_p(laddr((p)))
     809#define ldsw_raw(p) ldsw_p(laddr((p)))
     810#define ldl_raw(p) ldl_p(laddr((p)))
     811#define ldq_raw(p) ldq_p(laddr((p)))
     812#define ldfl_raw(p) ldfl_p(laddr((p)))
     813#define ldfq_raw(p) ldfq_p(laddr((p)))
     814#define stb_raw(p, v) stb_p(saddr((p)), v)
     815#define stw_raw(p, v) stw_p(saddr((p)), v)
     816#define stl_raw(p, v) stl_p(saddr((p)), v)
     817#define stq_raw(p, v) stq_p(saddr((p)), v)
     818#define stfl_raw(p, v) stfl_p(saddr((p)), v)
     819#define stfq_raw(p, v) stfq_p(saddr((p)), v)
    617820
    618821
     
    663866#define TARGET_PAGE_ALIGN(addr) (((addr) + TARGET_PAGE_SIZE - 1) & TARGET_PAGE_MASK)
    664867
     868/* ??? These should be the larger of unsigned long and target_ulong.  */
    665869extern unsigned long qemu_real_host_page_size;
    666870extern unsigned long qemu_host_page_bits;
     
    681885
    682886void page_dump(FILE *f);
    683 int page_get_flags(unsigned long address);
    684 void page_set_flags(unsigned long start, unsigned long end, int flags);
    685 void page_unprotect_range(uint8_t *data, unsigned long data_size);
     887int page_get_flags(target_ulong address);
     888void page_set_flags(target_ulong start, target_ulong end, int flags);
     889void page_unprotect_range(target_ulong data, target_ulong data_size);
    686890
    687891#define SINGLE_CPU_DEFINES
     
    720924#define cpu_signal_handler cpu_ppc_signal_handler
    721925
     926#elif defined(TARGET_M68K)
     927#define CPUState CPUM68KState
     928#define cpu_init cpu_m68k_init
     929#define cpu_exec cpu_m68k_exec
     930#define cpu_gen_code cpu_m68k_gen_code
     931#define cpu_signal_handler cpu_m68k_signal_handler
     932
     933#elif defined(TARGET_MIPS)
     934#define CPUState CPUMIPSState
     935#define cpu_init cpu_mips_init
     936#define cpu_exec cpu_mips_exec
     937#define cpu_gen_code cpu_mips_gen_code
     938#define cpu_signal_handler cpu_mips_signal_handler
     939
     940#elif defined(TARGET_SH4)
     941#define CPUState CPUSH4State
     942#define cpu_init cpu_sh4_init
     943#define cpu_exec cpu_sh4_exec
     944#define cpu_gen_code cpu_sh4_gen_code
     945#define cpu_signal_handler cpu_sh4_signal_handler
     946
    722947#else
    723948
     
    733958
    734959void cpu_abort(CPUState *env, const char *fmt, ...);
     960extern CPUState *first_cpu;
    735961extern CPUState *cpu_single_env;
    736962extern int code_copy_enabled;
     
    740966#define CPU_INTERRUPT_EXITTB 0x04 /* exit the current TB (use for x86 a20 case) */
    741967#define CPU_INTERRUPT_TIMER  0x08 /* internal timer exception pending */
     968#define CPU_INTERRUPT_FIQ    0x10 /* Fast interrupt pending.  */
     969#define CPU_INTERRUPT_HALT   0x20 /* CPU halt wanted */
     970#define CPU_INTERRUPT_SMI    0x40 /* (x86 only) SMI interrupt pending */
     971
    742972#ifdef VBOX
    743973/** Executes a single instruction. cpu_exec() will normally return EXCP_SINGLE_INSTR. */
    744 #define CPU_INTERRUPT_SINGLE_INSTR              0x0040
     974#define CPU_INTERRUPT_SINGLE_INSTR              0x0200
    745975/** Executing a CPU_INTERRUPT_SINGLE_INSTR request, quit the cpu_loop. (for exceptions and suchlike) */
    746 #define CPU_INTERRUPT_SINGLE_INSTR_IN_FLIGHT    0x0080
     976#define CPU_INTERRUPT_SINGLE_INSTR_IN_FLIGHT    0x0400
    747977/** VM execution was interrupted by VMR3Reset, VMR3Suspend or VMR3PowerOff. */
    748 #define CPU_INTERRUPT_RC                        0x0100
     978#define CPU_INTERRUPT_RC                        0x0800
    749979/** Exit current TB to process an external interrupt request (also in op.c!!) */
    750 #define CPU_INTERRUPT_EXTERNAL_EXIT             0x0200
     980#define CPU_INTERRUPT_EXTERNAL_EXIT             0x1000
    751981/** Exit current TB to process an external interrupt request (also in op.c!!) */
    752 #define CPU_INTERRUPT_EXTERNAL_HARD             0x0400
     982#define CPU_INTERRUPT_EXTERNAL_HARD             0x2000
    753983/** Exit current TB to process an external interrupt request (also in op.c!!) */
    754 #define CPU_INTERRUPT_EXTERNAL_TIMER            0x0800
     984#define CPU_INTERRUPT_EXTERNAL_TIMER            0x4000
    755985/** Exit current TB to process an external interrupt request (also in op.c!!) */
    756 #define CPU_INTERRUPT_EXTERNAL_DMA              0x1000
     986#define CPU_INTERRUPT_EXTERNAL_DMA              0x8000
    757987#endif /* VBOX */
    758988void cpu_interrupt(CPUState *s, int mask);
     
    8061036
    8071037/* memory API */
    808 extern uint32_t phys_ram_size;
     1038
    8091039#ifndef VBOX
     1040extern int phys_ram_size;
    8101041extern int phys_ram_fd;
    8111042extern int phys_ram_size;
     1043#else /* VBOX */
     1044extern RTGCPHYS phys_ram_size;
     1045/** This is required for bounds checking the phys_ram_dirty accesses. */
     1046extern uint32_t phys_ram_dirty_size;
     1047#endif /* VBOX */
     1048#if !defined(VBOX) || !(defined(PGM_DYNAMIC_RAM_ALLOC) || defined(REM_PHYS_ADDR_IN_TLB))
    8121049extern uint8_t *phys_ram_base;
    8131050#endif
     
    8151052
    8161053/* physical memory access */
    817 #define IO_MEM_NB_ENTRIES  256
    8181054#define TLB_INVALID_MASK   (1 << 3)
    8191055#define IO_MEM_SHIFT       4
     1056#define IO_MEM_NB_ENTRIES  (1 << (TARGET_PAGE_BITS  - IO_MEM_SHIFT))
    8201057
    8211058#define IO_MEM_RAM         (0 << IO_MEM_SHIFT) /* hardcoded offset */
    8221059#define IO_MEM_ROM         (1 << IO_MEM_SHIFT) /* hardcoded offset */
    8231060#define IO_MEM_UNASSIGNED  (2 << IO_MEM_SHIFT)
    824 #define IO_MEM_CODE        (3 << IO_MEM_SHIFT) /* used internally, never use directly */
    8251061#define IO_MEM_NOTDIRTY    (4 << IO_MEM_SHIFT) /* used internally, never use directly */
    826 #ifdef VBOX
     1062#if defined(VBOX) && defined(PGM_DYNAMIC_RAM_ALLOC)
    8271063#define IO_MEM_RAM_MISSING (5 << IO_MEM_SHIFT) /* used internally, never use directly */
    8281064#endif
     1065/* acts like a ROM when read and like a device when written. As an
     1066   exception, the write memory callback gets the ram offset instead of
     1067   the physical address */
     1068#define IO_MEM_ROMD        (1)
    8291069
    8301070typedef void CPUWriteMemoryFunc(void *opaque, target_phys_addr_t addr, uint32_t value);
     
    8341074                                  unsigned long size,
    8351075                                  unsigned long phys_offset);
     1076uint32_t cpu_get_physical_page_desc(target_phys_addr_t addr);
    8361077int cpu_register_io_memory(int io_index,
    8371078                           CPUReadMemoryFunc **mem_read,
     
    8531094    cpu_physical_memory_rw(addr, (uint8_t *)buf, len, 1);
    8541095}
     1096uint32_t ldub_phys(target_phys_addr_t addr);
     1097uint32_t lduw_phys(target_phys_addr_t addr);
    8551098uint32_t ldl_phys(target_phys_addr_t addr);
     1099uint64_t ldq_phys(target_phys_addr_t addr);
    8561100void stl_phys_notdirty(target_phys_addr_t addr, uint32_t val);
     1101void stb_phys(target_phys_addr_t addr, uint32_t val);
     1102void stw_phys(target_phys_addr_t addr, uint32_t val);
    8571103void stl_phys(target_phys_addr_t addr, uint32_t val);
    858 
     1104void stq_phys(target_phys_addr_t addr, uint64_t val);
     1105
     1106void cpu_physical_memory_write_rom(target_phys_addr_t addr,
     1107                                   const uint8_t *buf, int len);
    8591108int cpu_memory_rw_debug(CPUState *env, target_ulong addr,
    8601109                        uint8_t *buf, int len, int is_write);
    8611110
     1111#define VGA_DIRTY_FLAG  0x01
     1112#define CODE_DIRTY_FLAG 0x02
     1113
    8621114/* read dirty bit (return 0 or 1) */
    863 static inline int cpu_physical_memory_is_dirty(target_ulong addr)
    864 {
    865     return phys_ram_dirty[addr >> TARGET_PAGE_BITS];
    866 }
    867 
    868 static inline void cpu_physical_memory_set_dirty(target_ulong addr)
    869 {
    870     phys_ram_dirty[addr >> TARGET_PAGE_BITS] = 1;
    871 }
    872 
    873 void cpu_physical_memory_reset_dirty(target_ulong start, target_ulong end);
     1115static inline int cpu_physical_memory_is_dirty(ram_addr_t addr)
     1116{
     1117#ifdef VBOX
     1118    if (RT_UNLIKELY((addr >> TARGET_PAGE_BITS) >= phys_ram_dirty_size))
     1119    {
     1120        Log(("cpu_physical_memory_is_dirty: %VGp\n", (RTGCPHYS)addr));
     1121        /*AssertMsgFailed(("cpu_physical_memory_is_dirty: %VGp\n", (RTGCPHYS)addr));*/
     1122        return 0;
     1123    }
     1124#endif
     1125    return phys_ram_dirty[addr >> TARGET_PAGE_BITS] == 0xff;
     1126}
     1127
     1128static inline int cpu_physical_memory_get_dirty(ram_addr_t addr,
     1129                                                int dirty_flags)
     1130{
     1131#ifdef VBOX
     1132    if (RT_UNLIKELY((addr >> TARGET_PAGE_BITS) >= phys_ram_dirty_size))
     1133    {
     1134        Log(("cpu_physical_memory_is_dirty: %VGp\n", (RTGCPHYS)addr));
     1135        /*AssertMsgFailed(("cpu_physical_memory_is_dirty: %VGp\n", (RTGCPHYS)addr));*/
     1136        return 0xff & dirty_flags; /** @todo I don't think this is the right thing to return, fix! */
     1137    }
     1138#endif
     1139    return phys_ram_dirty[addr >> TARGET_PAGE_BITS] & dirty_flags;
     1140}
     1141
     1142static inline void cpu_physical_memory_set_dirty(ram_addr_t addr)
     1143{
     1144#ifdef VBOX
     1145    if (RT_UNLIKELY((addr >> TARGET_PAGE_BITS) >= phys_ram_dirty_size))
     1146    {
     1147        Log(("cpu_physical_memory_is_dirty: %VGp\n", (RTGCPHYS)addr));
     1148        /*AssertMsgFailed(("cpu_physical_memory_is_dirty: %VGp\n", (RTGCPHYS)addr));*/
     1149        return;
     1150    }
     1151#endif
     1152    phys_ram_dirty[addr >> TARGET_PAGE_BITS] = 0xff;
     1153}
     1154
     1155void cpu_physical_memory_reset_dirty(ram_addr_t start, ram_addr_t end,
     1156                                     int dirty_flags);
     1157void cpu_tlb_update_dirty(CPUState *env);
    8741158
    8751159void dump_exec_info(FILE *f,
    8761160                    int (*cpu_fprintf)(FILE *f, const char *fmt, ...));
    8771161
     1162/*******************************************/
     1163/* host CPU ticks (if available) */
     1164
     1165#if defined(__powerpc__)
     1166
     1167static inline uint32_t get_tbl(void)
     1168{
     1169    uint32_t tbl;
     1170    asm volatile("mftb %0" : "=r" (tbl));
     1171    return tbl;
     1172}
     1173
     1174static inline uint32_t get_tbu(void)
     1175{
     1176        uint32_t tbl;
     1177        asm volatile("mftbu %0" : "=r" (tbl));
     1178        return tbl;
     1179}
     1180
     1181static inline int64_t cpu_get_real_ticks(void)
     1182{
     1183    uint32_t l, h, h1;
     1184    /* NOTE: we test if wrapping has occurred */
     1185    do {
     1186        h = get_tbu();
     1187        l = get_tbl();
     1188        h1 = get_tbu();
     1189    } while (h != h1);
     1190    return ((int64_t)h << 32) | l;
     1191}
     1192
     1193#elif defined(__i386__)
     1194
     1195static inline int64_t cpu_get_real_ticks(void)
     1196{
     1197    int64_t val;
     1198    asm volatile ("rdtsc" : "=A" (val));
     1199    return val;
     1200}
     1201
     1202#elif defined(__x86_64__)
     1203
     1204static inline int64_t cpu_get_real_ticks(void)
     1205{
     1206    uint32_t low,high;
     1207    int64_t val;
     1208    asm volatile("rdtsc" : "=a" (low), "=d" (high));
     1209    val = high;
     1210    val <<= 32;
     1211    val |= low;
     1212    return val;
     1213}
     1214
     1215#elif defined(__ia64)
     1216
     1217static inline int64_t cpu_get_real_ticks(void)
     1218{
     1219        int64_t val;
     1220        asm volatile ("mov %0 = ar.itc" : "=r"(val) :: "memory");
     1221        return val;
     1222}
     1223
     1224#elif defined(__s390__)
     1225
     1226static inline int64_t cpu_get_real_ticks(void)
     1227{
     1228    int64_t val;
     1229    asm volatile("stck 0(%1)" : "=m" (val) : "a" (&val) : "cc");
     1230    return val;
     1231}
     1232
     1233#elif defined(__sparc_v9__)
     1234
     1235static inline int64_t cpu_get_real_ticks (void)
     1236{
     1237#if     defined(_LP64)
     1238        uint64_t        rval;
     1239        asm volatile("rd %%tick,%0" : "=r"(rval));
     1240        return rval;
     1241#else
     1242        union {
     1243                uint64_t i64;
     1244                struct {
     1245                        uint32_t high;
     1246                        uint32_t low;
     1247                }       i32;
     1248        } rval;
     1249        asm volatile("rd %%tick,%1; srlx %1,32,%0"
     1250                : "=r"(rval.i32.high), "=r"(rval.i32.low));
     1251        return rval.i64;
     1252#endif
     1253}
     1254#else
     1255/* The host CPU doesn't have an easily accessible cycle counter.
     1256   Just return a monotonically increasing vlue.  This will be totally wrong,
     1257   but hopefully better than nothing.  */
     1258static inline int64_t cpu_get_real_ticks (void)
     1259{
     1260    static int64_t ticks = 0;
     1261    return ticks++;
     1262}
     1263#endif
     1264
     1265/* profiling */
     1266#ifdef CONFIG_PROFILER
     1267static inline int64_t profile_getclock(void)
     1268{
     1269    return cpu_get_real_ticks();
     1270}
     1271
     1272extern int64_t kqemu_time, kqemu_time_start;
     1273extern int64_t qemu_time, qemu_time_start;
     1274extern int64_t tlb_flush_time;
     1275extern int64_t kqemu_exec_count;
     1276extern int64_t dev_time;
     1277extern int64_t kqemu_ret_int_count;
     1278extern int64_t kqemu_ret_excp_count;
     1279extern int64_t kqemu_ret_intr_count;
     1280
     1281#endif
    8781282
    8791283#ifdef VBOX
    8801284void tb_invalidate_virt(CPUState *env, uint32_t eip);
    881 #endif
     1285#endif /* VBOX */
    8821286
    8831287#endif /* CPU_ALL_H */
  • trunk/src/recompiler/cpu-defs.h

    r1 r2422  
    3030#endif
    3131
    32 #if defined(__alpha__) || defined (__ia64__) || defined(__x86_64__)
    33 #define HOST_LONG_BITS 64
    34 #else
    35 #define HOST_LONG_BITS 32
    36 #endif
    37 
    3832#ifndef TARGET_PHYS_ADDR_BITS
    3933#if TARGET_LONG_BITS >= HOST_LONG_BITS
     
    5448typedef int64_t target_long;
    5549typedef uint64_t target_ulong;
    56 #define TARGET_FMT_lx "%016llx"
     50#define TARGET_FMT_lx "%016" PRIx64
    5751#else
    5852#error TARGET_LONG_SIZE undefined
     
    7367#endif
    7468
     69/* address in the RAM (different from a physical address) */
     70typedef unsigned long ram_addr_t;
     71
    7572#define HOST_LONG_SIZE (HOST_LONG_BITS / 8)
    7673
    77 #define EXCP_INTERRUPT  256 /* async interruption */
    78 #define EXCP_HLT        257 /* hlt instruction reached */
    79 #define EXCP_DEBUG      258 /* cpu stopped after a breakpoint or singlestep */
     74#define EXCP_INTERRUPT  0x10000 /* async interruption */
     75#define EXCP_HLT        0x10001 /* hlt instruction reached */
     76#define EXCP_DEBUG      0x10002 /* cpu stopped after a breakpoint or singlestep */
     77#define EXCP_HALTED     0x10003 /* cpu is halted (waiting for external event) */
    8078#if defined(VBOX)
    81 #define EXCP_EXECUTE_RAW    1024 /* execute raw mode. */
    82 #define EXCP_EXECUTE_HWACC  1025 /* execute hardware accelerated raw mode. */
    83 #define EXCP_SINGLE_INSTR   1026 /* executed single instruction. */
    84 #define EXCP_RC             1027 /* a EM rc was raised (VMR3Reset/Suspend/PowerOff). */
     79#define EXCP_EXECUTE_RAW    0x11024 /* execute raw mode. */
     80#define EXCP_EXECUTE_HWACC  0x11025 /* execute hardware accelerated raw mode. */
     81#define EXCP_SINGLE_INSTR   0x11026 /* executed single instruction. */
     82#define EXCP_RC             0x11027 /* a EM rc was raised (VMR3Reset/Suspend/PowerOff). */
    8583#endif /* VBOX */
    86 
    8784#define MAX_BREAKPOINTS 32
    8885
    89 #define CPU_TLB_SIZE 256
     86#define TB_JMP_CACHE_BITS 12
     87#define TB_JMP_CACHE_SIZE (1 << TB_JMP_CACHE_BITS)
     88
     89/* Only the bottom TB_JMP_PAGE_BITS of the jump cache hash bits vary for
     90   addresses on the same page.  The top bits are the same.  This allows
     91   TLB invalidation to quickly clear a subset of the hash table.  */
     92#define TB_JMP_PAGE_BITS (TB_JMP_CACHE_BITS / 2)
     93#define TB_JMP_PAGE_SIZE (1 << TB_JMP_PAGE_BITS)
     94#define TB_JMP_ADDR_MASK (TB_JMP_PAGE_SIZE - 1)
     95#define TB_JMP_PAGE_MASK (TB_JMP_CACHE_SIZE - TB_JMP_PAGE_SIZE)
     96
     97#define CPU_TLB_BITS 8
     98#define CPU_TLB_SIZE (1 << CPU_TLB_BITS)
    9099
    91100typedef struct CPUTLBEntry {
     
    96105       bit 2..0                   : zero
    97106    */
    98     target_ulong address;
     107    target_ulong addr_read;
     108    target_ulong addr_write;
     109    target_ulong addr_code;
    99110    /* addend to virtual address to get physical address */
    100111    target_phys_addr_t addend;
    101112} CPUTLBEntry;
    102113
     114#define CPU_COMMON                                                      \
     115    struct TranslationBlock *current_tb; /* currently executing TB  */  \
     116    /* soft mmu support */                                              \
     117    /* in order to avoid passing too many arguments to the memory       \
     118       write helpers, we store some rarely used information in the CPU  \
     119       context) */                                                      \
     120    unsigned long mem_write_pc; /* host pc at which the memory was      \
     121                                   written */                           \
     122    target_ulong mem_write_vaddr; /* target virtual addr at which the   \
     123                                     memory was written */              \
     124    /* 0 = kernel, 1 = user */                                          \
     125    CPUTLBEntry tlb_table[2][CPU_TLB_SIZE];                             \
     126    struct TranslationBlock *tb_jmp_cache[TB_JMP_CACHE_SIZE];           \
     127                                                                        \
     128    /* from this point: preserved by CPU reset */                       \
     129    /* ice debug support */                                             \
     130    target_ulong breakpoints[MAX_BREAKPOINTS];                          \
     131    int nb_breakpoints;                                                 \
     132    int singlestep_enabled;                                             \
     133                                                                        \
     134    void *next_cpu; /* next CPU sharing TB cache */                     \
     135    int cpu_index; /* CPU index (informative) */                        \
     136    /* user data */                                                     \
     137    void *opaque;
     138
    103139#endif
  • trunk/src/recompiler/cpu-exec.c

    r1147 r2422  
    11/*
    22 *  i386 emulator main execution loop
    3  *
    4  *  Copyright (c) 2003 Fabrice Bellard
     3 * 
     4 *  Copyright (c) 2003-2005 Fabrice Bellard
    55 *
    66 * This library is free software; you can redistribute it and/or
     
    4141//#define DEBUG_SIGNAL
    4242
    43 #if defined(TARGET_ARM) || defined(TARGET_SPARC)
     43#if defined(TARGET_ARM) || defined(TARGET_SPARC) || defined(TARGET_M68K)
    4444/* XXX: unify with i386 target */
    4545void cpu_loop_exit(void)
     
    4747    longjmp(env->jmp_env, 1);
    4848}
     49#endif
     50#if !(defined(TARGET_SPARC) || defined(TARGET_SH4) || defined(TARGET_M68K))
     51#define reg_T2
    4952#endif
    5053
     
    5255   restored in a state compatible with the CPU emulator
    5356 */
    54 void cpu_resume_from_signal(CPUState *env1, void *puc)
     57void cpu_resume_from_signal(CPUState *env1, void *puc) 
    5558{
    5659#if !defined(CONFIG_SOFTMMU)
     
    7174}
    7275
     76
     77static TranslationBlock *tb_find_slow(target_ulong pc,
     78                                      target_ulong cs_base,
     79                                      unsigned int flags)
     80{
     81    TranslationBlock *tb, **ptb1;
     82    int code_gen_size;
     83    unsigned int h;
     84    target_ulong phys_pc, phys_page1, phys_page2, virt_page2;
     85    uint8_t *tc_ptr;
     86   
     87    spin_lock(&tb_lock);
     88
     89    tb_invalidated_flag = 0;
     90   
     91    regs_to_env(); /* XXX: do it just before cpu_gen_code() */
     92   
     93    /* find translated block using physical mappings */
     94    phys_pc = get_phys_addr_code(env, pc);
     95    phys_page1 = phys_pc & TARGET_PAGE_MASK;
     96    phys_page2 = -1;
     97    h = tb_phys_hash_func(phys_pc);
     98    ptb1 = &tb_phys_hash[h];
     99    for(;;) {
     100        tb = *ptb1;
     101        if (!tb)
     102            goto not_found;
     103        if (tb->pc == pc &&
     104            tb->page_addr[0] == phys_page1 &&
     105            tb->cs_base == cs_base &&
     106            tb->flags == flags) {
     107            /* check next page if needed */
     108            if (tb->page_addr[1] != -1) {
     109                virt_page2 = (pc & TARGET_PAGE_MASK) +
     110                    TARGET_PAGE_SIZE;
     111                phys_page2 = get_phys_addr_code(env, virt_page2);
     112                if (tb->page_addr[1] == phys_page2)
     113                    goto found;
     114            } else {
     115                goto found;
     116            }
     117        }
     118        ptb1 = &tb->phys_hash_next;
     119    }
     120 not_found:
     121    /* if no translated code available, then translate it now */
     122    tb = tb_alloc(pc);
     123    if (!tb) {
     124        /* flush must be done */
     125        tb_flush(env);
     126        /* cannot fail at this point */
     127        tb = tb_alloc(pc);
     128        /* don't forget to invalidate previous TB info */
     129        tb_invalidated_flag = 1;
     130    }
     131    tc_ptr = code_gen_ptr;
     132    tb->tc_ptr = tc_ptr;
     133    tb->cs_base = cs_base;
     134    tb->flags = flags;
     135    cpu_gen_code(env, tb, CODE_GEN_MAX_SIZE, &code_gen_size);
     136    code_gen_ptr = (void *)(((unsigned long)code_gen_ptr + code_gen_size + CODE_GEN_ALIGN - 1) & ~(CODE_GEN_ALIGN - 1));
     137   
     138    /* check next page if needed */
     139    virt_page2 = (pc + tb->size - 1) & TARGET_PAGE_MASK;
     140    phys_page2 = -1;
     141    if ((pc & TARGET_PAGE_MASK) != virt_page2) {
     142        phys_page2 = get_phys_addr_code(env, virt_page2);
     143    }
     144    tb_link_phys(tb, phys_pc, phys_page2);
     145   
     146 found:
     147    /* we add the TB in the virtual pc hash table */
     148    env->tb_jmp_cache[tb_jmp_cache_hash_func(pc)] = tb;
     149    spin_unlock(&tb_lock);
     150    return tb;
     151}
     152
     153static inline TranslationBlock *tb_find_fast(void)
     154{
     155    TranslationBlock *tb;
     156    target_ulong cs_base, pc;
     157    unsigned int flags;
     158
     159    /* we record a subset of the CPU state. It will
     160       always be the same before a given translated block
     161       is executed. */
     162#if defined(TARGET_I386)
     163    flags = env->hflags;
     164    flags |= (env->eflags & (IOPL_MASK | TF_MASK | VM_MASK));
     165    cs_base = env->segs[R_CS].base;
     166    pc = cs_base + env->eip;
     167#elif defined(TARGET_ARM)
     168    flags = env->thumb | (env->vfp.vec_len << 1)
     169            | (env->vfp.vec_stride << 4);
     170    if ((env->uncached_cpsr & CPSR_M) != ARM_CPU_MODE_USR)
     171        flags |= (1 << 6);
     172    if (env->vfp.xregs[ARM_VFP_FPEXC] & (1 << 30))
     173        flags |= (1 << 7);
     174    cs_base = 0;
     175    pc = env->regs[15];
     176#elif defined(TARGET_SPARC)
     177#ifdef TARGET_SPARC64
     178    // Combined FPU enable bits . PRIV . DMMU enabled . IMMU enabled
     179    flags = (((env->pstate & PS_PEF) >> 1) | ((env->fprs & FPRS_FEF) << 2))
     180        | (env->pstate & PS_PRIV) | ((env->lsu & (DMMU_E | IMMU_E)) >> 2);
     181#else
     182    // FPU enable . MMU enabled . MMU no-fault . Supervisor
     183    flags = (env->psref << 3) | ((env->mmuregs[0] & (MMU_E | MMU_NF)) << 1)
     184        | env->psrs;
     185#endif
     186    cs_base = env->npc;
     187    pc = env->pc;
     188#elif defined(TARGET_PPC)
     189    flags = (msr_pr << MSR_PR) | (msr_fp << MSR_FP) |
     190        (msr_se << MSR_SE) | (msr_le << MSR_LE);
     191    cs_base = 0;
     192    pc = env->nip;
     193#elif defined(TARGET_MIPS)
     194    flags = env->hflags & (MIPS_HFLAG_TMASK | MIPS_HFLAG_BMASK);
     195    cs_base = 0;
     196    pc = env->PC;
     197#elif defined(TARGET_M68K)
     198    flags = env->fpcr & M68K_FPCR_PREC;
     199    cs_base = 0;
     200    pc = env->pc;
     201#elif defined(TARGET_SH4)
     202    flags = env->sr & (SR_MD | SR_RB);
     203    cs_base = 0;         /* XXXXX */
     204    pc = env->pc;
     205#else
     206#error unsupported CPU
     207#endif
     208    tb = env->tb_jmp_cache[tb_jmp_cache_hash_func(pc)];
     209    if (__builtin_expect(!tb || tb->pc != pc || tb->cs_base != cs_base ||
     210                         tb->flags != flags, 0)) {
     211        tb = tb_find_slow(pc, cs_base, flags);
     212        /* Note: we do it here to avoid a gcc bug on Mac OS X when
     213           doing it in tb_find_slow */
     214        if (tb_invalidated_flag) {
     215            /* as some TB could have been invalidated because
     216               of memory exceptions while generating the code, we
     217               must recompute the hash index here */
     218            T0 = 0;
     219        }
     220    }
     221    return tb;
     222}
     223
     224
    73225/* main execution loop */
    74226
     
    77229int cpu_exec(CPUState *env1)
    78230{
    79     int saved_T0, saved_T1, saved_T2;
    80     CPUState *saved_env;
    81 #ifdef reg_EAX
    82     int saved_EAX;
    83 #endif
    84 #ifdef reg_ECX
    85     int saved_ECX;
    86 #endif
    87 #ifdef reg_EDX
    88     int saved_EDX;
    89 #endif
    90 #ifdef reg_EBX
    91     int saved_EBX;
    92 #endif
    93 #ifdef reg_ESP
    94     int saved_ESP;
    95 #endif
    96 #ifdef reg_EBP
    97     int saved_EBP;
    98 #endif
    99 #ifdef reg_ESI
    100     int saved_ESI;
    101 #endif
    102 #ifdef reg_EDI
    103     int saved_EDI;
    104 #endif
    105     int code_gen_size, ret, interrupt_request;
     231#define DECLARE_HOST_REGS 1
     232#include "hostregs_helper.h"
     233    int ret, interrupt_request;
    106234    void (*gen_func)(void);
    107     TranslationBlock *tb, **ptb;
    108     target_ulong cs_base, pc;
     235    TranslationBlock *tb;
    109236    uint8_t *tc_ptr;
    110     unsigned int flags;
     237
     238#if defined(TARGET_I386)
     239    /* handle exit of HALTED state */
     240    if (env1->hflags & HF_HALTED_MASK) {
     241        /* disable halt condition */
     242        if ((env1->interrupt_request & CPU_INTERRUPT_HARD) &&
     243            (env1->eflags & IF_MASK)) {
     244            env1->hflags &= ~HF_HALTED_MASK;
     245        } else {
     246            return EXCP_HALTED;
     247        }
     248    }
     249#elif defined(TARGET_PPC)
     250    if (env1->halted) {
     251        if (env1->msr[MSR_EE] &&
     252            (env1->interrupt_request &
     253             (CPU_INTERRUPT_HARD | CPU_INTERRUPT_TIMER))) {
     254            env1->halted = 0;
     255        } else {
     256            return EXCP_HALTED;
     257        }
     258    }
     259#elif defined(TARGET_SPARC)
     260    if (env1->halted) {
     261        if ((env1->interrupt_request & CPU_INTERRUPT_HARD) &&
     262            (env1->psret != 0)) {
     263            env1->halted = 0;
     264        } else {
     265            return EXCP_HALTED;
     266        }
     267    }
     268#elif defined(TARGET_ARM)
     269    if (env1->halted) {
     270        /* An interrupt wakes the CPU even if the I and F CPSR bits are
     271           set.  */
     272        if (env1->interrupt_request
     273            & (CPU_INTERRUPT_FIQ | CPU_INTERRUPT_HARD)) {
     274            env1->halted = 0;
     275        } else {
     276            return EXCP_HALTED;
     277        }
     278    }
     279#elif defined(TARGET_MIPS)
     280    if (env1->halted) {
     281        if (env1->interrupt_request &
     282            (CPU_INTERRUPT_HARD | CPU_INTERRUPT_TIMER)) {
     283            env1->halted = 0;
     284        } else {
     285            return EXCP_HALTED;
     286        }
     287    }
     288#endif
     289
     290    cpu_single_env = env1;
    111291
    112292    /* first we save global registers */
    113     saved_env = env;
     293#define SAVE_HOST_REGS 1
     294#include "hostregs_helper.h"
    114295    env = env1;
    115     saved_T0 = T0;
    116     saved_T1 = T1;
    117     saved_T2 = T2;
    118 
    119 #ifdef reg_EAX
    120     saved_EAX = EAX;
    121 #endif
    122 #ifdef reg_ECX
    123     saved_ECX = ECX;
    124 #endif
    125 #ifdef reg_EDX
    126     saved_EDX = EDX;
    127 #endif
    128 #ifdef reg_EBX
    129     saved_EBX = EBX;
    130 #endif
    131 #ifdef reg_ESP
    132     saved_ESP = ESP;
    133 #endif
    134 #ifdef reg_EBP
    135     saved_EBP = EBP;
    136 #endif
    137 #ifdef reg_ESI
    138     saved_ESI = ESI;
    139 #endif
    140 #ifdef reg_EDI
    141     saved_EDI = EDI;
    142 #endif
     296#if defined(__sparc__) && !defined(HOST_SOLARIS)
     297    /* we also save i7 because longjmp may not restore it */
     298    asm volatile ("mov %%i7, %0" : "=r" (saved_i7));
     299#endif
     300
     301#if defined(TARGET_I386)
    143302
    144303    env_to_regs();
     
    148307    CC_OP = CC_OP_EFLAGS;
    149308    env->eflags &= ~(DF_MASK | CC_O | CC_S | CC_Z | CC_A | CC_P | CC_C);
    150 
     309#elif defined(TARGET_ARM)
     310#elif defined(TARGET_SPARC)
     311#if defined(reg_REGWPTR)
     312    saved_regwptr = REGWPTR;
     313#endif
     314#elif defined(TARGET_PPC)
     315#elif defined(TARGET_MIPS)
     316#elif defined(TARGET_SH4)
     317    /* XXXXX */
     318#else
     319#error unsupported target CPU
     320#endif
    151321#ifndef VBOX /* VBOX: We need to raise traps and suchlike from the outside. */
    152322    env->exception_index = -1;
    153 #endif
     323#endif 
    154324
    155325    /* prepare setjmp context for exception handling */
    156326    for(;;) {
    157         if (setjmp(env->jmp_env) == 0)
     327        if (setjmp(env->jmp_env) == 0) 
    158328        {
    159329            env->current_tb = NULL;
     
    164334             * Check for fatal errors first
    165335             */
    166             if (env->interrupt_request & CPU_INTERRUPT_RC)
    167             {
     336            if (env->interrupt_request & CPU_INTERRUPT_RC) {
    168337                env->exception_index = EXCP_RC;
    169338                ASMAtomicAndS32(&env->interrupt_request, ~CPU_INTERRUPT_RC);
     
    173342
    174343            /* if an exception is pending, we execute it here */
    175             if (env->exception_index >= 0)
    176             {
     344            if (env->exception_index >= 0) {
    177345                Assert(!env->user_mode_only);
    178                 if (env->exception_index >= EXCP_INTERRUPT)
    179                 {
     346                if (env->exception_index >= EXCP_INTERRUPT) {
    180347                    /* exit request from the cpu execution loop */
    181348                    ret = env->exception_index;
    182349                    break;
    183                 }
    184                 else
    185                 {
     350                } else {
    186351                    /* simulate a real cpu exception. On i386, it can
    187352                       trigger new exceptions, but we do not handle
     
    189354                    RAWEx_ProfileStart(env, STATS_IRQ_HANDLING);
    190355                    Log(("do_interrupt %d %d %08x\n", env->exception_index, env->exception_is_int, env->exception_next_eip));
    191                     do_interrupt(env->exception_index,
    192                                  env->exception_is_int,
    193                                  env->error_code,
     356                    do_interrupt(env->exception_index, 
     357                                 env->exception_is_int, 
     358                                 env->error_code, 
    194359                                 env->exception_next_eip, 0);
    195360                    RAWEx_ProfileStop(env, STATS_IRQ_HANDLING);
     
    235400
    236401                    RAWEx_ProfileStart(env, STATS_IRQ_HANDLING);
    237                     /* if hardware interrupt pending, we execute it */
    238                     if ((interrupt_request & CPU_INTERRUPT_HARD) &&
    239                         (env->eflags & IF_MASK) &&
    240                         !(env->hflags & HF_INHIBIT_IRQ_MASK))
     402                    if ((interrupt_request & CPU_INTERRUPT_SMI) &&
     403                        !(env->hflags & HF_SMM_MASK)) {
     404                        env->interrupt_request &= ~CPU_INTERRUPT_SMI;
     405                        do_smm_enter();
     406                        T0 = 0;
     407                    }
     408                    else if ((interrupt_request & CPU_INTERRUPT_HARD) &&
     409                             (env->eflags & IF_MASK) &&
     410                             !(env->hflags & HF_INHIBIT_IRQ_MASK))
    241411                    {
     412                        /* if hardware interrupt pending, we execute it */
    242413                        int intno;
    243414                        ASMAtomicAndS32(&env->interrupt_request, ~CPU_INTERRUPT_HARD);
     
    252423                        T0 = 0;
    253424                    }
    254                     if (interrupt_request & CPU_INTERRUPT_EXITTB)
     425                    if (env->interrupt_request & CPU_INTERRUPT_EXITTB)
    255426                    {
    256427                        ASMAtomicAndS32(&env->interrupt_request, ~CPU_INTERRUPT_EXITTB);
     
    260431                    }
    261432                    RAWEx_ProfileStop(env, STATS_IRQ_HANDLING);
    262                     if (interrupt_request & CPU_INTERRUPT_EXIT)
     433                    if (interrupt_request & CPU_INTERRUPT_EXIT) 
    263434                    {
    264435                        env->exception_index = EXCP_INTERRUPT;
     
    267438                        cpu_loop_exit();
    268439                    }
    269                     if (interrupt_request & CPU_INTERRUPT_RC)
     440                    if (interrupt_request & CPU_INTERRUPT_RC) 
    270441                    {
    271442                        env->exception_index = EXCP_RC;
     
    275446                    }
    276447                }
    277                 /* we record a subset of the CPU state. It will
    278                    always be the same before a given translated block
    279                    is executed. */
    280                 flags = env->hflags;
    281                 flags |= (env->eflags & (IOPL_MASK | TF_MASK | VM_MASK));
    282                 cs_base = env->segs[R_CS].base;
    283                 pc = cs_base + env->eip;
    284 
     448
     449                /*
     450                 * Check if we the CPU state allows us to execute the code in raw-mode.
     451                 */
    285452                RAWEx_ProfileStart(env, STATS_RAW_CHECK);
    286                 if (remR3CanExecuteRaw(env, pc, flags, &env->exception_index))
     453                if (remR3CanExecuteRaw(env,
     454                                       env->eip + env->segs[R_CS].base,
     455                                       env->hflags | (env->eflags & (IOPL_MASK | TF_MASK | VM_MASK)),
     456                                       &env->exception_index))
    287457                {
    288458                    RAWEx_ProfileStop(env, STATS_RAW_CHECK);
     
    293463
    294464                RAWEx_ProfileStart(env, STATS_TLB_LOOKUP);
    295                 tb = tb_find(&ptb, pc, cs_base,
    296                              flags);
    297                 if (!tb)
     465                tb = tb_find_fast();
     466
     467                /* see if we can patch the calling TB. When the TB
     468                   spans two pages, we cannot safely do a direct
     469                   jump. */
     470                if (T0 != 0
     471                    && !(tb->cflags & CF_RAW_MODE)
     472                    && tb->page_addr[1] == -1)
    298473                {
    299                     TranslationBlock **ptb1;
    300                     unsigned int h;
    301                     target_ulong phys_pc, phys_page1, phys_page2, virt_page2;
    302 
    303                     spin_lock(&tb_lock);
    304 
    305                     tb_invalidated_flag = 0;
    306 
    307                     regs_to_env(); /* XXX: do it just before cpu_gen_code() */
    308 
    309                     /* find translated block using physical mappings */
    310                     phys_pc = get_phys_addr_code(env, pc);
    311                     phys_page1 = phys_pc & TARGET_PAGE_MASK;
    312                     phys_page2 = -1;
    313                     h = tb_phys_hash_func(phys_pc);
    314                     ptb1 = &tb_phys_hash[h];
    315                     for(;;) {
    316                         tb = *ptb1;
    317                         if (!tb)
    318                             goto not_found;
    319                         if (tb->pc == pc &&
    320                             tb->page_addr[0] == phys_page1 &&
    321                             tb->cs_base == cs_base &&
    322                             tb->flags == flags) {
    323                             /* check next page if needed */
    324                             if (tb->page_addr[1] != -1) {
    325                                 virt_page2 = (pc & TARGET_PAGE_MASK) +
    326                                     TARGET_PAGE_SIZE;
    327                                 phys_page2 = get_phys_addr_code(env, virt_page2);
    328                                 if (tb->page_addr[1] == phys_page2)
    329                                     goto found;
    330                             } else {
    331                                 goto found;
    332                             }
    333                         }
    334                         ptb1 = &tb->phys_hash_next;
    335                     }
    336                 not_found:
    337                     /* if no translated code available, then translate it now */
    338                     tb = tb_alloc(pc);
    339                     if (!tb) {
    340                         /* flush must be done */
    341                         tb_flush(env);
    342                         /* cannot fail at this point */
    343                         tb = tb_alloc(pc);
    344                         /* don't forget to invalidate previous TB info */
    345                         ptb = &tb_hash[tb_hash_func(pc)];
    346                         T0 = 0;
    347                     }
    348                     tc_ptr = code_gen_ptr;
    349                     tb->tc_ptr = tc_ptr;
    350                     tb->cs_base = cs_base;
    351                     tb->flags = flags;
    352                     RAWEx_ProfileStop(env, STATS_TLB_LOOKUP);
    353                     cpu_gen_code(env, tb, CODE_GEN_MAX_SIZE, &code_gen_size);
    354                     RAWEx_ProfileStart(env, STATS_TLB_LOOKUP);
    355                     code_gen_ptr = (void *)(((unsigned long)code_gen_ptr + code_gen_size + CODE_GEN_ALIGN - 1) & ~(CODE_GEN_ALIGN - 1));
    356 
    357                     /* check next page if needed */
    358                     virt_page2 = (pc + tb->size - 1) & TARGET_PAGE_MASK;
    359                     phys_page2 = -1;
    360                     if ((pc & TARGET_PAGE_MASK) != virt_page2) {
    361                         phys_page2 = get_phys_addr_code(env, virt_page2);
    362                     }
    363                     tb_link_phys(tb, phys_pc, phys_page2);
    364 
    365                 found:
    366                     if (tb_invalidated_flag) {
    367                         /* as some TB could have been invalidated because
    368                            of memory exceptions while generating the code, we
    369                            must recompute the hash index here */
    370                         ptb = &tb_hash[tb_hash_func(pc)];
    371                         while (*ptb != NULL)
    372                             ptb = &(*ptb)->hash_next;
    373                         T0 = 0;
    374                     }
    375                     /* we add the TB in the virtual pc hash table */
    376                     *ptb = tb;
    377                     tb->hash_next = NULL;
    378                     tb_link(tb);
    379                     spin_unlock(&tb_lock);
    380                 }
    381                 /* see if we can patch the calling TB. */
    382                 {
    383                     if (T0 != 0
    384                     && !(tb->cflags & CF_RAW_MODE)
    385                     ) {
    386474                    spin_lock(&tb_lock);
    387475                    tb_add_jump((TranslationBlock *)(long)(T0 & ~3), T0 & 3, tb);
    388476                    spin_unlock(&tb_lock);
    389                 }
    390477                }
    391478                tc_ptr = tb->tc_ptr;
     
    397484#if defined(DEBUG) && defined(VBOX) && !defined(DEBUG_dmik)
    398485#if !defined(DEBUG_bird)
    399                 if (((env->hflags >> HF_CPL_SHIFT) & 3) == 0 && (env->hflags & HF_PE_MASK) && (env->cr[0] & CR0_PG_MASK))
     486                if (((env->hflags >> HF_CPL_SHIFT) & 3) == 0 && (env->hflags & HF_PE_MASK) && (env->cr[0] & CR0_PG_MASK)) 
    400487                {
    401488                    if(!(env->state & CPU_EMULATE_SINGLE_STEP))
     
    405492                }
    406493                else
    407                 if (((env->hflags >> HF_CPL_SHIFT) & 3) == 3 && (env->hflags & HF_PE_MASK) && (env->cr[0] & CR0_PG_MASK))
     494                if (((env->hflags >> HF_CPL_SHIFT) & 3) == 3 && (env->hflags & HF_PE_MASK) && (env->cr[0] & CR0_PG_MASK)) 
    408495                {
    409496                    if(!(env->state & CPU_EMULATE_SINGLE_STEP))
     
    411498                        if(env->eflags & VM_MASK)
    412499                        {
    413                             Log(("EMV86: %04X:%04X IF=%d TF=%d CPL=%d flags=%08X CR0=%08X\n", env->segs[R_CS].selector, env->eip, (env->eflags & IF_MASK) ? 1 : 0, (env->eflags & TF_MASK) ? 1 : 0, (env->hflags >> HF_CPL_SHIFT) & 3, flags, env->cr[0]));
     500                            Log(("EMV86: %04X:%04X IF=%d TF=%d CPL=%d CR0=%08X\n", env->segs[R_CS].selector, env->eip, (env->eflags & IF_MASK) ? 1 : 0, (env->eflags & TF_MASK) ? 1 : 0, (env->hflags >> HF_CPL_SHIFT) & 3, env->cr[0]));
    414501                        }
    415502                        else
    416503                        {
    417                             Log(("EMR3: %08X ESP=%08X IF=%d TF=%d CPL=%d IOPL=%d flags=%08X CR0=%08X\n", env->eip, ESP, (env->eflags & IF_MASK) ? 1 : 0, (env->eflags & TF_MASK) ? 1 : 0, (env->hflags >> HF_CPL_SHIFT) & 3, ((env->eflags >> IOPL_SHIFT) & 3), flags, env->cr[0]));
     504                            Log(("EMR3: %08X ESP=%08X IF=%d TF=%d CPL=%d IOPL=%d CR0=%08X\n", env->eip, ESP, (env->eflags & IF_MASK) ? 1 : 0, (env->eflags & TF_MASK) ? 1 : 0, (env->hflags >> HF_CPL_SHIFT) & 3, ((env->eflags >> IOPL_SHIFT) & 3), env->cr[0]));
    418505                        }
    419506                    }
    420507                }
    421                 else
     508                else 
    422509                {
    423510                    Log(("EMRM: %04X:%08X SS:ESP=%04X:%08X IF=%d TF=%d CPL=%d PE=%d PG=%d\n", env->segs[R_CS].selector, env->eip, env->segs[R_SS].selector, ESP, (env->eflags & IF_MASK) ? 1 : 0, (env->eflags & TF_MASK) ? 1 : 0, (env->hflags >> HF_CPL_SHIFT) & 3, env->cr[0] & X86_CR0_PE, env->cr[0] & X86_CR0_PG));
     
    437524                        #else
    438525                        env->state &= ~CPU_EMULATE_SINGLE_STEP;
    439                         #endif
    440                     }
    441 #endif
    442 
     526                        #endif
     527                    }
     528#endif
    443529                    TMCpuTickPause(env->pVM);
    444530                    remR3DisasInstr(env, -1, NULL);
     
    449535                    }
    450536                }
    451                 else
     537                else 
    452538                {
    453539                    RAWEx_ProfileStart(env, STATS_QEMU_RUN_EMULATED_CODE);
     
    477563        }
    478564#ifdef VBOX_HIGH_RES_TIMERS_HACK
    479         /* NULL the current_tb here so cpu_interrupt() doesn't do
     565        /* NULL the current_tb here so cpu_interrupt() doesn't do 
    480566           anything unnecessary (like crashing during emulate single instruction). */
    481567        env->current_tb = NULL;
     
    487573    /* restore flags in standard format */
    488574    env->eflags = env->eflags | cc_table[CC_OP].compute_all() | (DF & DF_MASK);
    489 
    490     /* restore global registers */
    491 #ifdef reg_EAX
    492     EAX = saved_EAX;
    493 #endif
    494 #ifdef reg_ECX
    495     ECX = saved_ECX;
    496 #endif
    497 #ifdef reg_EDX
    498     EDX = saved_EDX;
    499 #endif
    500 #ifdef reg_EBX
    501     EBX = saved_EBX;
    502 #endif
    503 #ifdef reg_ESP
    504     ESP = saved_ESP;
    505 #endif
    506 #ifdef reg_EBP
    507     EBP = saved_EBP;
    508 #endif
    509 #ifdef reg_ESI
    510     ESI = saved_ESI;
    511 #endif
    512 #ifdef reg_EDI
    513     EDI = saved_EDI;
    514 #endif
    515575#else
    516576#error unsupported target CPU
    517577#endif
    518     T0 = saved_T0;
    519     T1 = saved_T1;
    520     T2 = saved_T2;
    521     env = saved_env;
     578#include "hostregs_helper.h"
    522579    return ret;
    523580}
     
    529586int cpu_exec(CPUState *env1)
    530587{
    531     int saved_T0, saved_T1, saved_T2;
    532     CPUState *saved_env;
    533 #ifdef reg_EAX
    534     int saved_EAX;
    535 #endif
    536 #ifdef reg_ECX
    537     int saved_ECX;
    538 #endif
    539 #ifdef reg_EDX
    540     int saved_EDX;
    541 #endif
    542 #ifdef reg_EBX
    543     int saved_EBX;
    544 #endif
    545 #ifdef reg_ESP
    546     int saved_ESP;
    547 #endif
    548 #ifdef reg_EBP
    549     int saved_EBP;
    550 #endif
    551 #ifdef reg_ESI
    552     int saved_ESI;
    553 #endif
    554 #ifdef reg_EDI
    555     int saved_EDI;
    556 #endif
    557 #ifdef __sparc__
    558     int saved_i7, tmp_T0;
    559 #endif
    560     int code_gen_size, ret, interrupt_request;
     588#define DECLARE_HOST_REGS 1
     589#include "hostregs_helper.h"
     590#if defined(__sparc__) && !defined(HOST_SOLARIS)
     591    int saved_i7;
     592    target_ulong tmp_T0;
     593#endif
     594    int ret, interrupt_request;
    561595    void (*gen_func)(void);
    562     TranslationBlock *tb, **ptb;
    563     target_ulong cs_base, pc;
     596    TranslationBlock *tb;
    564597    uint8_t *tc_ptr;
    565     unsigned int flags;
     598
     599#if defined(TARGET_I386)
     600    /* handle exit of HALTED state */
     601    if (env1->hflags & HF_HALTED_MASK) {
     602        /* disable halt condition */
     603        if ((env1->interrupt_request & CPU_INTERRUPT_HARD) &&
     604            (env1->eflags & IF_MASK)) {
     605            env1->hflags &= ~HF_HALTED_MASK;
     606        } else {
     607            return EXCP_HALTED;
     608        }
     609    }
     610#elif defined(TARGET_PPC)
     611    if (env1->halted) {
     612        if (env1->msr[MSR_EE] &&
     613            (env1->interrupt_request &
     614             (CPU_INTERRUPT_HARD | CPU_INTERRUPT_TIMER))) {
     615            env1->halted = 0;
     616        } else {
     617            return EXCP_HALTED;
     618        }
     619    }
     620#elif defined(TARGET_SPARC)
     621    if (env1->halted) {
     622        if ((env1->interrupt_request & CPU_INTERRUPT_HARD) &&
     623            (env1->psret != 0)) {
     624            env1->halted = 0;
     625        } else {
     626            return EXCP_HALTED;
     627        }
     628    }
     629#elif defined(TARGET_ARM)
     630    if (env1->halted) {
     631        /* An interrupt wakes the CPU even if the I and F CPSR bits are
     632           set.  */
     633        if (env1->interrupt_request
     634            & (CPU_INTERRUPT_FIQ | CPU_INTERRUPT_HARD)) {
     635            env1->halted = 0;
     636        } else {
     637            return EXCP_HALTED;
     638        }
     639    }
     640#elif defined(TARGET_MIPS)
     641    if (env1->halted) {
     642        if (env1->interrupt_request &
     643            (CPU_INTERRUPT_HARD | CPU_INTERRUPT_TIMER)) {
     644            env1->halted = 0;
     645        } else {
     646            return EXCP_HALTED;
     647        }
     648    }
     649#endif
     650
     651    cpu_single_env = env1;
    566652
    567653    /* first we save global registers */
    568     saved_env = env;
     654#define SAVE_HOST_REGS 1
     655#include "hostregs_helper.h"
    569656    env = env1;
    570     saved_T0 = T0;
    571     saved_T1 = T1;
    572     saved_T2 = T2;
    573 #ifdef __sparc__
     657#if defined(__sparc__) && !defined(HOST_SOLARIS)
    574658    /* we also save i7 because longjmp may not restore it */
    575659    asm volatile ("mov %%i7, %0" : "=r" (saved_i7));
     
    577661
    578662#if defined(TARGET_I386)
    579 #ifdef reg_EAX
    580     saved_EAX = EAX;
    581 #endif
    582 #ifdef reg_ECX
    583     saved_ECX = ECX;
    584 #endif
    585 #ifdef reg_EDX
    586     saved_EDX = EDX;
    587 #endif
    588 #ifdef reg_EBX
    589     saved_EBX = EBX;
    590 #endif
    591 #ifdef reg_ESP
    592     saved_ESP = ESP;
    593 #endif
    594 #ifdef reg_EBP
    595     saved_EBP = EBP;
    596 #endif
    597 #ifdef reg_ESI
    598     saved_ESI = ESI;
    599 #endif
    600 #ifdef reg_EDI
    601     saved_EDI = EDI;
    602 #endif
    603 
    604663    env_to_regs();
    605664    /* put eflags in CPU temporary format */
     
    609668    env->eflags &= ~(DF_MASK | CC_O | CC_S | CC_Z | CC_A | CC_P | CC_C);
    610669#elif defined(TARGET_ARM)
    611     {
    612         unsigned int psr;
    613         psr = env->cpsr;
    614         env->CF = (psr >> 29) & 1;
    615         env->NZF = (psr & 0xc0000000) ^ 0x40000000;
    616         env->VF = (psr << 3) & 0x80000000;
    617         env->QF = (psr >> 27) & 1;
    618         env->cpsr = psr & ~CACHED_CPSR_BITS;
    619     }
    620670#elif defined(TARGET_SPARC)
     671#if defined(reg_REGWPTR)
     672    saved_regwptr = REGWPTR;
     673#endif
    621674#elif defined(TARGET_PPC)
     675#elif defined(TARGET_M68K)
     676    env->cc_op = CC_OP_FLAGS;
     677    env->cc_dest = env->sr & 0xf;
     678    env->cc_x = (env->sr >> 4) & 1;
     679#elif defined(TARGET_MIPS)
     680#elif defined(TARGET_SH4)
     681    /* XXXXX */
    622682#else
    623683#error unsupported target CPU
     
    625685#ifndef VBOX /* VBOX: We need to raise traps and suchlike from the outside. */
    626686    env->exception_index = -1;
    627 #endif
     687#endif 
    628688
    629689    /* prepare setjmp context for exception handling */
     
    631691        if (setjmp(env->jmp_env) == 0) {
    632692            env->current_tb = NULL;
    633 #ifdef VBOX
     693#ifdef VBOX 
    634694            VMMR3Unlock(env->pVM);
    635695            VMMR3Lock(env->pVM);
    636696
    637             /* Check for high priority requests first (like fatal
     697            /* Check for high priority requests first (like fatal 
    638698               errors). */
    639699            if (env->interrupt_request & CPU_INTERRUPT_RC) {
    640700                env->exception_index = EXCP_RC;
    641701                ASMAtomicAndS32(&env->interrupt_request, ~CPU_INTERRUPT_RC);
     702                ret = env->exception_index;
    642703                cpu_loop_exit();
    643704            }
     
    653714                } else if (env->user_mode_only) {
    654715                    /* if user mode only, we simulate a fake exception
    655                        which will be hanlded outside the cpu execution
     716                       which will be handled outside the cpu execution
    656717                       loop */
    657718#if defined(TARGET_I386)
    658                     do_interrupt_user(env->exception_index,
    659                                       env->exception_is_int,
    660                                       env->error_code,
     719                    do_interrupt_user(env->exception_index, 
     720                                      env->exception_is_int, 
     721                                      env->error_code, 
    661722                                      env->exception_next_eip);
    662723#endif
     
    668729                       trigger new exceptions, but we do not handle
    669730                       double or triple faults yet. */
    670                     do_interrupt(env->exception_index,
    671                                  env->exception_is_int,
    672                                  env->error_code,
     731                    do_interrupt(env->exception_index, 
     732                                 env->exception_is_int, 
     733                                 env->error_code, 
    673734                                 env->exception_next_eip, 0);
    674735#elif defined(TARGET_PPC)
    675736                    do_interrupt(env);
     737#elif defined(TARGET_MIPS)
     738                    do_interrupt(env);
    676739#elif defined(TARGET_SPARC)
    677                     do_interrupt(env->exception_index,
    678                                  env->error_code);
     740                    do_interrupt(env->exception_index);
     741#elif defined(TARGET_ARM)
     742                    do_interrupt(env);
     743#elif defined(TARGET_SH4)
     744                    do_interrupt(env);
    679745#endif
    680746                }
    681747                env->exception_index = -1;
     748            }
     749#ifdef USE_KQEMU
     750            if (kqemu_is_ok(env) && env->interrupt_request == 0) {
     751                int ret;
     752                env->eflags = env->eflags | cc_table[CC_OP].compute_all() | (DF & DF_MASK);
     753                ret = kqemu_cpu_exec(env);
     754                /* put eflags in CPU temporary format */
     755                CC_SRC = env->eflags & (CC_O | CC_S | CC_Z | CC_A | CC_P | CC_C);
     756                DF = 1 - (2 * ((env->eflags >> 10) & 1));
     757                CC_OP = CC_OP_EFLAGS;
     758                env->eflags &= ~(DF_MASK | CC_O | CC_S | CC_Z | CC_A | CC_P | CC_C);
     759                if (ret == 1) {
     760                    /* exception */
     761                    longjmp(env->jmp_env, 1);
     762                } else if (ret == 2) {
     763                    /* softmmu execution needed */
     764                } else {
     765                    if (env->interrupt_request != 0) {
     766                        /* hardware interrupt will be executed just after */
     767                    } else {
     768                        /* otherwise, we restart */
     769                        longjmp(env->jmp_env, 1);
     770                    }
     771                }
    682772            }
     773#endif
    683774
    684775            T0 = 0; /* force lookup of first TB */
    685776            for(;;) {
    686 #ifdef __sparc__
    687                 /* g1 can be modified by some libc? functions */
     777#if defined(__sparc__) && !defined(HOST_SOLARIS)
     778                /* g1 can be modified by some libc? functions */ 
    688779                tmp_T0 = T0;
    689 #endif
     780#endif     
    690781                interrupt_request = env->interrupt_request;
    691782                if (__builtin_expect(interrupt_request, 0)) {
    692783#ifdef VBOX
    693784                    /* Single instruction exec request, we execute it and return (one way or the other).
    694                        The caller will cleans the request if it's one of the other ways...  the caller
    695                        also locks everything so no atomic and/or required. */
    696                     if (interrupt_request & CPU_INTERRUPT_SINGLE_INSTR) {
     785                       The caller will always reschedule after doing this operation! */
     786                    if (interrupt_request & CPU_INTERRUPT_SINGLE_INSTR)
     787                    {
    697788                        /* not in flight are we? */
    698                         if (!(env->interrupt_request & CPU_INTERRUPT_SINGLE_INSTR_IN_FLIGHT)) {
    699                             env->interrupt_request |= CPU_INTERRUPT_SINGLE_INSTR_IN_FLIGHT;
     789                        if (!(env->interrupt_request & CPU_INTERRUPT_SINGLE_INSTR_IN_FLIGHT))
     790                        {
     791                            ASMAtomicOrS32(&env->interrupt_request, CPU_INTERRUPT_SINGLE_INSTR_IN_FLIGHT);
    700792                            env->exception_index = EXCP_SINGLE_INSTR;
    701793                            if (emulate_single_instr(env) == -1)
    702794                                AssertMsgFailed(("REM: emulate_single_instr failed for EIP=%08x!!\n", env->eip));
     795
     796                            /* When we receive an external interrupt during execution of this single
     797                               instruction, then we should stay here. We will leave when we're ready
     798                               for raw-mode or when interrupted by pending EMT requests.  */
     799                            interrupt_request = env->interrupt_request; /* reload this! */
     800                            if (   !(interrupt_request & CPU_INTERRUPT_HARD)
     801                                || !(env->eflags & IF_MASK)
     802                                ||  (env->hflags & HF_INHIBIT_IRQ_MASK)
     803                               )
     804                            {
     805                                env->exception_index = ret = EXCP_SINGLE_INSTR;
     806                                cpu_loop_exit();
     807                            }
    703808                        }
    704809                        env->exception_index = EXCP_SINGLE_INSTR;
    705810                        cpu_loop_exit();
    706811                    }
     812
     813                    RAWEx_ProfileStart(env, STATS_IRQ_HANDLING);
    707814#endif /* VBOX */
    708815#if defined(TARGET_I386)
    709                     /* if hardware interrupt pending, we execute it */
    710                     if ((interrupt_request & CPU_INTERRUPT_HARD) &&
    711                         (env->eflags & IF_MASK) &&
     816                    if ((interrupt_request & CPU_INTERRUPT_SMI) &&
     817                        !(env->hflags & HF_SMM_MASK)) {
     818                        env->interrupt_request &= ~CPU_INTERRUPT_SMI;
     819                        do_smm_enter();
     820#if defined(__sparc__) && !defined(HOST_SOLARIS)
     821                        tmp_T0 = 0;
     822#else
     823                        T0 = 0;
     824#endif
     825                    } else if ((interrupt_request & CPU_INTERRUPT_HARD) &&
     826                        (env->eflags & IF_MASK) &&
    712827                        !(env->hflags & HF_INHIBIT_IRQ_MASK)) {
    713828                        int intno;
     
    716831#else
    717832                        env->interrupt_request &= ~CPU_INTERRUPT_HARD;
    718 #endif
     833#endif 
    719834                        intno = cpu_get_pic_interrupt(env);
    720835                        if (loglevel & CPU_LOG_TB_IN_ASM) {
     
    727842                        /* ensure that no TB jump will be modified as
    728843                           the program flow was changed */
    729 #ifdef __sparc__
     844#if defined(__sparc__) && !defined(HOST_SOLARIS)
    730845                        tmp_T0 = 0;
    731846#else
     
    740855#endif
    741856                    if (msr_ee != 0) {
    742                     if ((interrupt_request & CPU_INTERRUPT_HARD)) {
     857                        if ((interrupt_request & CPU_INTERRUPT_HARD)) {
    743858                            /* Raise it */
    744859                            env->exception_index = EXCP_EXTERNAL;
    745860                            env->error_code = 0;
    746861                            do_interrupt(env);
    747                         env->interrupt_request &= ~CPU_INTERRUPT_HARD;
    748                         } else if ((interrupt_request & CPU_INTERRUPT_TIMER)) {
    749                             /* Raise it */
    750                             env->exception_index = EXCP_DECR;
    751                             env->error_code = 0;
    752                             do_interrupt(env);
     862                            env->interrupt_request &= ~CPU_INTERRUPT_HARD;
     863#if defined(__sparc__) && !defined(HOST_SOLARIS)
     864                            tmp_T0 = 0;
     865#else
     866                            T0 = 0;
     867#endif
     868                        } else if ((interrupt_request & CPU_INTERRUPT_TIMER)) {
     869                            /* Raise it */
     870                            env->exception_index = EXCP_DECR;
     871                            env->error_code = 0;
     872                            do_interrupt(env);
    753873                            env->interrupt_request &= ~CPU_INTERRUPT_TIMER;
     874#if defined(__sparc__) && !defined(HOST_SOLARIS)
     875                            tmp_T0 = 0;
     876#else
     877                            T0 = 0;
     878#endif
     879                        }
     880                    }
     881#elif defined(TARGET_MIPS)
     882                    if ((interrupt_request & CPU_INTERRUPT_HARD) &&
     883                        (env->CP0_Status & (1 << CP0St_IE)) &&
     884                        (env->CP0_Status & env->CP0_Cause & 0x0000FF00) &&
     885                        !(env->hflags & MIPS_HFLAG_EXL) &&
     886                        !(env->hflags & MIPS_HFLAG_ERL) &&
     887                        !(env->hflags & MIPS_HFLAG_DM)) {
     888                        /* Raise it */
     889                        env->exception_index = EXCP_EXT_INTERRUPT;
     890                        env->error_code = 0;
     891                        do_interrupt(env);
     892#if defined(__sparc__) && !defined(HOST_SOLARIS)
     893                        tmp_T0 = 0;
     894#else
     895                        T0 = 0;
     896#endif
     897                    }
     898#elif defined(TARGET_SPARC)
     899                    if ((interrupt_request & CPU_INTERRUPT_HARD) &&
     900                        (env->psret != 0)) {
     901                        int pil = env->interrupt_index & 15;
     902                        int type = env->interrupt_index & 0xf0;
     903
     904                        if (((type == TT_EXTINT) &&
     905                             (pil == 15 || pil > env->psrpil)) ||
     906                            type != TT_EXTINT) {
     907                            env->interrupt_request &= ~CPU_INTERRUPT_HARD;
     908                            do_interrupt(env->interrupt_index);
     909                            env->interrupt_index = 0;
     910#if defined(__sparc__) && !defined(HOST_SOLARIS)
     911                            tmp_T0 = 0;
     912#else
     913                            T0 = 0;
     914#endif
    754915                        }
    755                     }
    756 #elif defined(TARGET_SPARC)
    757                     if (interrupt_request & CPU_INTERRUPT_HARD) {
    758                         do_interrupt(env->interrupt_index, 0);
    759                         env->interrupt_request &= ~CPU_INTERRUPT_HARD;
    760916                    } else if (interrupt_request & CPU_INTERRUPT_TIMER) {
    761917                        //do_interrupt(0, 0, 0, 0, 0);
    762918                        env->interrupt_request &= ~CPU_INTERRUPT_TIMER;
    763                     }
    764 #endif
    765                     if (interrupt_request & CPU_INTERRUPT_EXITTB) {
     919                    } else if (interrupt_request & CPU_INTERRUPT_HALT) {
     920                        env->interrupt_request &= ~CPU_INTERRUPT_HALT;
     921                        env->halted = 1;
     922                        env->exception_index = EXCP_HLT;
     923                        cpu_loop_exit();
     924                    }
     925#elif defined(TARGET_ARM)
     926                    if (interrupt_request & CPU_INTERRUPT_FIQ
     927                        && !(env->uncached_cpsr & CPSR_F)) {
     928                        env->exception_index = EXCP_FIQ;
     929                        do_interrupt(env);
     930                    }
     931                    if (interrupt_request & CPU_INTERRUPT_HARD
     932                        && !(env->uncached_cpsr & CPSR_I)) {
     933                        env->exception_index = EXCP_IRQ;
     934                        do_interrupt(env);
     935                    }
     936#elif defined(TARGET_SH4)
     937                    /* XXXXX */
     938#endif
     939                   /* Don't use the cached interupt_request value,
     940                      do_interrupt may have updated the EXITTB flag. */
     941                    if (env->interrupt_request & CPU_INTERRUPT_EXITTB) {
    766942#if defined(VBOX)
    767943                        ASMAtomicAndS32(&env->interrupt_request, ~CPU_INTERRUPT_EXITTB);
    768944#else
    769945                        env->interrupt_request &= ~CPU_INTERRUPT_EXITTB;
    770 #endif
     946#endif 
    771947                        /* ensure that no TB jump will be modified as
    772948                           the program flow was changed */
    773 #ifdef __sparc__
     949#if defined(__sparc__) && !defined(HOST_SOLARIS)
    774950                        tmp_T0 = 0;
    775951#else
     
    777953#endif
    778954                    }
     955#ifdef VBOX
     956                    RAWEx_ProfileStop(env, STATS_IRQ_HANDLING);
     957#endif
    779958                    if (interrupt_request & CPU_INTERRUPT_EXIT) {
    780959#if defined(VBOX)
     
    784963                        env->interrupt_request &= ~CPU_INTERRUPT_EXIT;
    785964                        env->exception_index = EXCP_INTERRUPT;
    786 #endif
     965#endif 
    787966                        cpu_loop_exit();
    788967                    }
     
    796975                }
    797976#ifdef DEBUG_EXEC
    798                 if ((loglevel & CPU_LOG_EXEC)) {
     977                if ((loglevel & CPU_LOG_TB_CPU)) {
    799978#if defined(TARGET_I386)
    800979                    /* restore flags in standard format */
     980#ifdef reg_EAX
    801981                    env->regs[R_EAX] = EAX;
     982#endif
     983#ifdef reg_EBX
    802984                    env->regs[R_EBX] = EBX;
     985#endif
     986#ifdef reg_ECX
    803987                    env->regs[R_ECX] = ECX;
     988#endif
     989#ifdef reg_EDX
    804990                    env->regs[R_EDX] = EDX;
     991#endif
     992#ifdef reg_ESI
    805993                    env->regs[R_ESI] = ESI;
     994#endif
     995#ifdef reg_EDI
    806996                    env->regs[R_EDI] = EDI;
     997#endif
     998#ifdef reg_EBP
    807999                    env->regs[R_EBP] = EBP;
     1000#endif
     1001#ifdef reg_ESP
    8081002                    env->regs[R_ESP] = ESP;
     1003#endif
    8091004                    env->eflags = env->eflags | cc_table[CC_OP].compute_all() | (DF & DF_MASK);
    8101005                    cpu_dump_state(env, logfile, fprintf, X86_DUMP_CCOP);
    8111006                    env->eflags &= ~(DF_MASK | CC_O | CC_S | CC_Z | CC_A | CC_P | CC_C);
    8121007#elif defined(TARGET_ARM)
    813                     env->cpsr = compute_cpsr();
    8141008                    cpu_dump_state(env, logfile, fprintf, 0);
    815                     env->cpsr &= ~CACHED_CPSR_BITS;
    8161009#elif defined(TARGET_SPARC)
    817                     cpu_dump_state (env, logfile, fprintf, 0);
     1010                    REGWPTR = env->regbase + (env->cwp * 16);
     1011                    env->regwptr = REGWPTR;
     1012                    cpu_dump_state(env, logfile, fprintf, 0);
    8181013#elif defined(TARGET_PPC)
    8191014                    cpu_dump_state(env, logfile, fprintf, 0);
    820 #else
    821 #error unsupported target CPU
    822 #endif
    823                 }
    824 #endif
    825                 /* we record a subset of the CPU state. It will
    826                    always be the same before a given translated block
    827                    is executed. */
    828 #if defined(TARGET_I386)
    829                 flags = env->hflags;
    830                 flags |= (env->eflags & (IOPL_MASK | TF_MASK | VM_MASK));
    831                 cs_base = env->segs[R_CS].base;
    832                 pc = cs_base + env->eip;
    833 #elif defined(TARGET_ARM)
    834                 flags = env->thumb;
    835                 cs_base = 0;
    836                 pc = env->regs[15];
    837 #elif defined(TARGET_SPARC)
    838                 flags = 0;
    839                 cs_base = env->npc;
    840                 pc = env->pc;
    841 #elif defined(TARGET_PPC)
    842                 flags = 0;
    843                 cs_base = 0;
    844                 pc = env->nip;
    845 #else
    846 #error unsupported CPU
    847 #endif
    848 
     1015#elif defined(TARGET_M68K)
     1016                    cpu_m68k_flush_flags(env, env->cc_op);
     1017                    env->cc_op = CC_OP_FLAGS;
     1018                    env->sr = (env->sr & 0xffe0)
     1019                              | env->cc_dest | (env->cc_x << 4);
     1020                    cpu_dump_state(env, logfile, fprintf, 0);
     1021#elif defined(TARGET_MIPS)
     1022                    cpu_dump_state(env, logfile, fprintf, 0);
     1023#elif defined(TARGET_SH4)
     1024                    cpu_dump_state(env, logfile, fprintf, 0);
     1025#else
     1026#error unsupported target CPU
     1027#endif
     1028                }
     1029#endif
    8491030#ifdef VBOX
    850                 if (remR3CanExecuteRaw(env, pc, flags, &env->exception_index))
     1031                /*
     1032                 * Check if we the CPU state allows us to execute the code in raw-mode.
     1033                 */
     1034                RAWEx_ProfileStart(env, STATS_RAW_CHECK);
     1035                if (remR3CanExecuteRaw(env,
     1036                                       env->eip + env->segs[R_CS].base,
     1037                                       env->hflags | (env->eflags & (IOPL_MASK | TF_MASK | VM_MASK))
     1038                                       flags, &env->exception_index))
     1039                {
     1040                    RAWEx_ProfileStop(env, STATS_RAW_CHECK);
     1041                    ret = env->exception_index;
    8511042                    cpu_loop_exit();
     1043                }
     1044                RAWEx_ProfileStop(env, STATS_RAW_CHECK);
    8521045#endif /* VBOX */
    853 
    854                 tb = tb_find(&ptb, pc, cs_base,
    855                              flags);
    856                 if (!tb) {
    857                     TranslationBlock **ptb1;
    858                     unsigned int h;
    859                     target_ulong phys_pc, phys_page1, phys_page2, virt_page2;
    860 
    861 
    862                     spin_lock(&tb_lock);
    863 
    864                     tb_invalidated_flag = 0;
    865 
    866                     regs_to_env(); /* XXX: do it just before cpu_gen_code() */
    867 
    868                     /* find translated block using physical mappings */
    869                     phys_pc = get_phys_addr_code(env, pc);
    870                     phys_page1 = phys_pc & TARGET_PAGE_MASK;
    871                     phys_page2 = -1;
    872                     h = tb_phys_hash_func(phys_pc);
    873                     ptb1 = &tb_phys_hash[h];
    874                     for(;;) {
    875                         tb = *ptb1;
    876                         if (!tb)
    877                             goto not_found;
    878                         if (tb->pc == pc &&
    879                             tb->page_addr[0] == phys_page1 &&
    880                             tb->cs_base == cs_base &&
    881                             tb->flags == flags) {
    882                             /* check next page if needed */
    883                             if (tb->page_addr[1] != -1) {
    884                                 virt_page2 = (pc & TARGET_PAGE_MASK) +
    885                                     TARGET_PAGE_SIZE;
    886                                 phys_page2 = get_phys_addr_code(env, virt_page2);
    887                                 if (tb->page_addr[1] == phys_page2)
    888                                     goto found;
    889                             } else {
    890                                 goto found;
    891                             }
    892                         }
    893                         ptb1 = &tb->phys_hash_next;
    894                     }
    895                 not_found:
    896                     /* if no translated code available, then translate it now */
    897                     tb = tb_alloc(pc);
    898                     if (!tb) {
    899                         /* flush must be done */
    900                         tb_flush(env);
    901                         /* cannot fail at this point */
    902                         tb = tb_alloc(pc);
    903                         /* don't forget to invalidate previous TB info */
    904                         ptb = &tb_hash[tb_hash_func(pc)];
    905                         T0 = 0;
    906                     }
    907                     tc_ptr = code_gen_ptr;
    908                     tb->tc_ptr = tc_ptr;
    909                     tb->cs_base = cs_base;
    910                     tb->flags = flags;
    911                     cpu_gen_code(env, tb, CODE_GEN_MAX_SIZE, &code_gen_size);
    912                     code_gen_ptr = (void *)(((unsigned long)code_gen_ptr + code_gen_size + CODE_GEN_ALIGN - 1) & ~(CODE_GEN_ALIGN - 1));
    913 
    914                     /* check next page if needed */
    915                     virt_page2 = (pc + tb->size - 1) & TARGET_PAGE_MASK;
    916                     phys_page2 = -1;
    917                     if ((pc & TARGET_PAGE_MASK) != virt_page2) {
    918                         phys_page2 = get_phys_addr_code(env, virt_page2);
    919                     }
    920                     tb_link_phys(tb, phys_pc, phys_page2);
    921 
    922                 found:
    923                     if (tb_invalidated_flag) {
    924                         /* as some TB could have been invalidated because
    925                            of memory exceptions while generating the code, we
    926                            must recompute the hash index here */
    927                         ptb = &tb_hash[tb_hash_func(pc)];
    928                         while (*ptb != NULL)
    929                             ptb = &(*ptb)->hash_next;
    930                         T0 = 0;
    931                     }
    932                     /* we add the TB in the virtual pc hash table */
    933                     *ptb = tb;
    934                     tb->hash_next = NULL;
    935                     tb_link(tb);
    936                     spin_unlock(&tb_lock);
    937                 }
     1046                tb = tb_find_fast();
    9381047#ifdef DEBUG_EXEC
    9391048                if ((loglevel & CPU_LOG_EXEC)) {
     
    9431052                }
    9441053#endif
    945 #ifdef __sparc__
     1054#if defined(__sparc__) && !defined(HOST_SOLARIS)
    9461055                T0 = tmp_T0;
    947 #endif
    948                 /* see if we can patch the calling TB. */
     1056#endif     
     1057                /* see if we can patch the calling TB. When the TB
     1058                   spans two pages, we cannot safely do a direct
     1059                   jump. */
    9491060                {
    950                     if (T0 != 0
     1061                    if (T0 != 0 &&
     1062#if USE_KQEMU
     1063                        (env->kqemu_enabled != 2) &&
     1064#endif
    9511065#ifdef VBOX
    952                     && !(tb->cflags & CF_RAW_MODE)
    953 #endif
     1066                        !(tb->cflags & CF_RAW_MODE) &&
     1067#endif
     1068                        tb->page_addr[1] == -1
    9541069#if defined(TARGET_I386) && defined(USE_CODE_COPY)
    955                     && (tb->cflags & CF_CODE_COPY) ==
     1070                    && (tb->cflags & CF_CODE_COPY) == 
    9561071                    (((TranslationBlock *)(T0 & ~3))->cflags & CF_CODE_COPY)
    9571072#endif
     
    9611076#if defined(USE_CODE_COPY)
    9621077                    /* propagates the FP use info */
    963                     ((TranslationBlock *)(T0 & ~3))->cflags |=
     1078                    ((TranslationBlock *)(T0 & ~3))->cflags |= 
    9641079                        (tb->cflags & CF_FP_USED);
    9651080#endif
     
    9751090                                     "mov       %%o7,%%i0"
    9761091                                     : /* no outputs */
    977                                      : "r" (gen_func)
    978                                      : "i0", "i1", "i2", "i3", "i4", "i5");
     1092                                     : "r" (gen_func)
     1093                                     : "i0", "i1", "i2", "i3", "i4", "i5",
     1094                                       "l0", "l1", "l2", "l3", "l4", "l5",
     1095                                       "l6", "l7");
    9791096#elif defined(__arm__)
    9801097                asm volatile ("mov pc, %0\n\t"
     
    10581175    }
    10591176}
     1177#elif defined(__ia64)
     1178                struct fptr {
     1179                        void *ip;
     1180                        void *gp;
     1181                } fp;
     1182
     1183                fp.ip = tc_ptr;
     1184                fp.gp = code_gen_buffer + 2 * (1 << 20);
     1185                (*(void (*)(void)) &fp)();
    10601186#else
    10611187#if defined(DEBUG) && defined(VBOX) && !defined(DEBUG_dmik)
    10621188#if !defined(DEBUG_bird)
    1063                 if (((env->hflags >> HF_CPL_SHIFT) & 3) == 0 && (env->hflags & HF_PE_MASK) && (env->cr[0] & CR0_PG_MASK))
     1189                if (((env->hflags >> HF_CPL_SHIFT) & 3) == 0 && (env->hflags & HF_PE_MASK) && (env->cr[0] & CR0_PG_MASK)) 
    10641190                {
    10651191                    if(!(env->state & CPU_EMULATE_SINGLE_STEP))
     
    10691195                }
    10701196                else
    1071                 if (((env->hflags >> HF_CPL_SHIFT) & 3) == 3 && (env->hflags & HF_PE_MASK) && (env->cr[0] & CR0_PG_MASK))
     1197                if (((env->hflags >> HF_CPL_SHIFT) & 3) == 3 && (env->hflags & HF_PE_MASK) && (env->cr[0] & CR0_PG_MASK)) 
    10721198                {
    10731199                    if(!(env->state & CPU_EMULATE_SINGLE_STEP))
     
    10961222                        #else
    10971223                        env->state &= ~CPU_EMULATE_SINGLE_STEP;
    1098                         #endif
    1099                     }
    1100 #endif
     1224                        #endif 
     1225                    }
     1226#endif 
    11011227                    TMCpuTickPause(env->pVM);
    11021228                    remR3DisasInstr(env, -1, NULL);
     
    11071233                    }
    11081234                }
    1109                 else
     1235                else 
    11101236                {
    11111237                    RAWEx_ProfileStart(env, STATS_QEMU_RUN_EMULATED_CODE);
     
    11351261                }
    11361262#endif
     1263#if defined(USE_KQEMU)
     1264#define MIN_CYCLE_BEFORE_SWITCH (100 * 1000)
     1265                if (kqemu_is_ok(env) &&
     1266                    (cpu_get_time_fast() - env->last_io_time) >= MIN_CYCLE_BEFORE_SWITCH) {
     1267                    cpu_loop_exit();
     1268                }
     1269#endif
    11371270            }
    11381271        } else {
     
    11501283    /* restore flags in standard format */
    11511284    env->eflags = env->eflags | cc_table[CC_OP].compute_all() | (DF & DF_MASK);
    1152 
    1153     /* restore global registers */
    1154 #ifdef reg_EAX
    1155     EAX = saved_EAX;
    1156 #endif
    1157 #ifdef reg_ECX
    1158     ECX = saved_ECX;
    1159 #endif
    1160 #ifdef reg_EDX
    1161     EDX = saved_EDX;
    1162 #endif
    1163 #ifdef reg_EBX
    1164     EBX = saved_EBX;
    1165 #endif
    1166 #ifdef reg_ESP
    1167     ESP = saved_ESP;
    1168 #endif
    1169 #ifdef reg_EBP
    1170     EBP = saved_EBP;
    1171 #endif
    1172 #ifdef reg_ESI
    1173     ESI = saved_ESI;
    1174 #endif
    1175 #ifdef reg_EDI
    1176     EDI = saved_EDI;
    1177 #endif
    11781285#elif defined(TARGET_ARM)
    1179     env->cpsr = compute_cpsr();
     1286    /* XXX: Save/restore host fpu exception state?.  */
    11801287#elif defined(TARGET_SPARC)
     1288#if defined(reg_REGWPTR)
     1289    REGWPTR = saved_regwptr;
     1290#endif
    11811291#elif defined(TARGET_PPC)
     1292#elif defined(TARGET_M68K)
     1293    cpu_m68k_flush_flags(env, env->cc_op);
     1294    env->cc_op = CC_OP_FLAGS;
     1295    env->sr = (env->sr & 0xffe0)
     1296              | env->cc_dest | (env->cc_x << 4);
     1297#elif defined(TARGET_MIPS)
     1298#elif defined(TARGET_SH4)
     1299    /* XXXXX */
    11821300#else
    11831301#error unsupported target CPU
    11841302#endif
    1185 #ifdef __sparc__
     1303#if defined(__sparc__) && !defined(HOST_SOLARIS)
    11861304    asm volatile ("mov %0, %%i7" : : "r" (saved_i7));
    11871305#endif
    1188     T0 = saved_T0;
    1189     T1 = saved_T1;
    1190     T2 = saved_T2;
    1191     env = saved_env;
     1306#include "hostregs_helper.h"
     1307
     1308    /* fail safe : never use cpu_single_env outside cpu_exec() */
     1309    cpu_single_env = NULL;
    11921310    return ret;
    11931311}
     
    12181336    if (!(env->cr[0] & CR0_PE_MASK) || (env->eflags & VM_MASK)) {
    12191337        selector &= 0xffff;
    1220         cpu_x86_load_seg_cache(env, seg_reg, selector,
     1338        cpu_x86_load_seg_cache(env, seg_reg, selector, 
    12211339                               (selector << 4), 0xffff, 0);
    12221340    } else {
     
    12321350    saved_env = env;
    12331351    env = s;
    1234 
     1352   
    12351353    helper_fsave((target_ulong)ptr, data32);
    12361354
     
    12441362    saved_env = env;
    12451363    env = s;
    1246 
     1364   
    12471365    helper_frstor((target_ulong)ptr, data32);
    12481366
     
    12611379   signal set which should be restored */
    12621380static inline int handle_cpu_signal(unsigned long pc, unsigned long address,
    1263                                     int is_write, sigset_t *old_set,
     1381                                    int is_write, sigset_t *old_set, 
    12641382                                    void *puc)
    12651383{
     
    12701388        env = cpu_single_env; /* XXX: find a correct solution for multithread */
    12711389#if defined(DEBUG_SIGNAL)
    1272     qemu_printf("qemu: SIGSEGV pc=0x%08lx address=%08lx w=%d oldset=0x%08lx\n",
     1390    qemu_printf("qemu: SIGSEGV pc=0x%08lx address=%08lx w=%d oldset=0x%08lx\n", 
    12731391                pc, address, is_write, *(unsigned long *)old_set);
    12741392#endif
    12751393    /* XXX: locking issue */
    1276     if (is_write && page_unprotect(address, pc, puc)) {
     1394    if (is_write && page_unprotect(h2g(address), pc, puc)) {
    12771395        return 1;
    12781396    }
    12791397
    12801398    /* see if it is an MMU fault */
    1281     ret = cpu_x86_handle_mmu_fault(env, address, is_write,
     1399    ret = cpu_x86_handle_mmu_fault(env, address, is_write, 
    12821400                                   ((env->hflags & HF_CPL_MASK) == 3), 0);
    12831401    if (ret < 0)
     
    12941412    if (ret == 1) {
    12951413#if 0
    1296         printf("PF exception: EIP=0x%08x CR2=0x%08x error=0x%x\n",
     1414        printf("PF exception: EIP=0x%08x CR2=0x%08x error=0x%x\n", 
    12971415               env->eip, env->cr[2], env->error_code);
    12981416#endif
     
    13001418           do it (XXX: use sigsetjmp) */
    13011419        sigprocmask(SIG_SETMASK, old_set, NULL);
    1302         raise_exception_err(EXCP0E_PAGE, env->error_code);
     1420        raise_exception_err(env->exception_index, env->error_code);
    13031421    } else {
    13041422        /* activate soft MMU for this block */
     
    13211439        env = cpu_single_env; /* XXX: find a correct solution for multithread */
    13221440#if defined(DEBUG_SIGNAL)
    1323     printf("qemu: SIGSEGV pc=0x%08lx address=%08lx w=%d oldset=0x%08lx\n",
     1441    printf("qemu: SIGSEGV pc=0x%08lx address=%08lx w=%d oldset=0x%08lx\n", 
    13241442           pc, address, is_write, *(unsigned long *)old_set);
    13251443#endif
    13261444    /* XXX: locking issue */
    1327     if (is_write && page_unprotect(address, pc, puc)) {
     1445    if (is_write && page_unprotect(h2g(address), pc, puc)) {
    13281446        return 1;
    13291447    }
     
    13571475        env = cpu_single_env; /* XXX: find a correct solution for multithread */
    13581476#if defined(DEBUG_SIGNAL)
    1359     printf("qemu: SIGSEGV pc=0x%08lx address=%08lx w=%d oldset=0x%08lx\n",
     1477    printf("qemu: SIGSEGV pc=0x%08lx address=%08lx w=%d oldset=0x%08lx\n", 
    13601478           pc, address, is_write, *(unsigned long *)old_set);
    13611479#endif
    13621480    /* XXX: locking issue */
    1363     if (is_write && page_unprotect(address, pc, puc)) {
     1481    if (is_write && page_unprotect(h2g(address), pc, puc)) {
    13641482        return 1;
    13651483    }
     
    13891507    TranslationBlock *tb;
    13901508    int ret;
    1391 
     1509   
    13921510    if (cpu_single_env)
    13931511        env = cpu_single_env; /* XXX: find a correct solution for multithread */
    13941512#if defined(DEBUG_SIGNAL)
    1395     printf("qemu: SIGSEGV pc=0x%08lx address=%08lx w=%d oldset=0x%08lx\n",
     1513    printf("qemu: SIGSEGV pc=0x%08lx address=%08lx w=%d oldset=0x%08lx\n", 
    13961514           pc, address, is_write, *(unsigned long *)old_set);
    13971515#endif
    13981516    /* XXX: locking issue */
    1399     if (is_write && page_unprotect(address, pc, puc)) {
     1517    if (is_write && page_unprotect(h2g(address), pc, puc)) {
    14001518        return 1;
    14011519    }
     
    14171535    if (ret == 1) {
    14181536#if 0
    1419         printf("PF exception: NIP=0x%08x error=0x%x %p\n",
     1537        printf("PF exception: NIP=0x%08x error=0x%x %p\n", 
    14201538               env->nip, env->error_code, tb);
    14211539#endif
     
    14311549    return 1;
    14321550}
     1551
     1552#elif defined(TARGET_M68K)
     1553static inline int handle_cpu_signal(unsigned long pc, unsigned long address,
     1554                                    int is_write, sigset_t *old_set,
     1555                                    void *puc)
     1556{
     1557    TranslationBlock *tb;
     1558    int ret;
     1559
     1560    if (cpu_single_env)
     1561        env = cpu_single_env; /* XXX: find a correct solution for multithread */
     1562#if defined(DEBUG_SIGNAL)
     1563    printf("qemu: SIGSEGV pc=0x%08lx address=%08lx w=%d oldset=0x%08lx\n",
     1564           pc, address, is_write, *(unsigned long *)old_set);
     1565#endif
     1566    /* XXX: locking issue */
     1567    if (is_write && page_unprotect(address, pc, puc)) {
     1568        return 1;
     1569    }
     1570    /* see if it is an MMU fault */
     1571    ret = cpu_m68k_handle_mmu_fault(env, address, is_write, 1, 0);
     1572    if (ret < 0)
     1573        return 0; /* not an MMU fault */
     1574    if (ret == 0)
     1575        return 1; /* the MMU fault was handled without causing real CPU fault */
     1576    /* now we have a real cpu fault */
     1577    tb = tb_find_pc(pc);
     1578    if (tb) {
     1579        /* the PC is inside the translated code. It means that we have
     1580           a virtual CPU fault */
     1581        cpu_restore_state(tb, env, pc, puc);
     1582    }
     1583    /* we restore the process signal mask as the sigreturn should
     1584       do it (XXX: use sigsetjmp) */
     1585    sigprocmask(SIG_SETMASK, old_set, NULL);
     1586    cpu_loop_exit();
     1587    /* never comes here */
     1588    return 1;
     1589}
     1590
     1591#elif defined (TARGET_MIPS)
     1592static inline int handle_cpu_signal(unsigned long pc, unsigned long address,
     1593                                    int is_write, sigset_t *old_set,
     1594                                    void *puc)
     1595{
     1596    TranslationBlock *tb;
     1597    int ret;
     1598   
     1599    if (cpu_single_env)
     1600        env = cpu_single_env; /* XXX: find a correct solution for multithread */
     1601#if defined(DEBUG_SIGNAL)
     1602    printf("qemu: SIGSEGV pc=0x%08lx address=%08lx w=%d oldset=0x%08lx\n",
     1603           pc, address, is_write, *(unsigned long *)old_set);
     1604#endif
     1605    /* XXX: locking issue */
     1606    if (is_write && page_unprotect(h2g(address), pc, puc)) {
     1607        return 1;
     1608    }
     1609
     1610    /* see if it is an MMU fault */
     1611    ret = cpu_mips_handle_mmu_fault(env, address, is_write, 1, 0);
     1612    if (ret < 0)
     1613        return 0; /* not an MMU fault */
     1614    if (ret == 0)
     1615        return 1; /* the MMU fault was handled without causing real CPU fault */
     1616
     1617    /* now we have a real cpu fault */
     1618    tb = tb_find_pc(pc);
     1619    if (tb) {
     1620        /* the PC is inside the translated code. It means that we have
     1621           a virtual CPU fault */
     1622        cpu_restore_state(tb, env, pc, puc);
     1623    }
     1624    if (ret == 1) {
     1625#if 0
     1626        printf("PF exception: NIP=0x%08x error=0x%x %p\n",
     1627               env->nip, env->error_code, tb);
     1628#endif
     1629    /* we restore the process signal mask as the sigreturn should
     1630       do it (XXX: use sigsetjmp) */
     1631        sigprocmask(SIG_SETMASK, old_set, NULL);
     1632        do_raise_exception_err(env->exception_index, env->error_code);
     1633    } else {
     1634        /* activate soft MMU for this block */
     1635        cpu_resume_from_signal(env, puc);
     1636    }
     1637    /* never comes here */
     1638    return 1;
     1639}
     1640
     1641#elif defined (TARGET_SH4)
     1642static inline int handle_cpu_signal(unsigned long pc, unsigned long address,
     1643                                    int is_write, sigset_t *old_set,
     1644                                    void *puc)
     1645{
     1646    TranslationBlock *tb;
     1647    int ret;
     1648   
     1649    if (cpu_single_env)
     1650        env = cpu_single_env; /* XXX: find a correct solution for multithread */
     1651#if defined(DEBUG_SIGNAL)
     1652    printf("qemu: SIGSEGV pc=0x%08lx address=%08lx w=%d oldset=0x%08lx\n",
     1653           pc, address, is_write, *(unsigned long *)old_set);
     1654#endif
     1655    /* XXX: locking issue */
     1656    if (is_write && page_unprotect(h2g(address), pc, puc)) {
     1657        return 1;
     1658    }
     1659
     1660    /* see if it is an MMU fault */
     1661    ret = cpu_sh4_handle_mmu_fault(env, address, is_write, 1, 0);
     1662    if (ret < 0)
     1663        return 0; /* not an MMU fault */
     1664    if (ret == 0)
     1665        return 1; /* the MMU fault was handled without causing real CPU fault */
     1666
     1667    /* now we have a real cpu fault */
     1668    tb = tb_find_pc(pc);
     1669    if (tb) {
     1670        /* the PC is inside the translated code. It means that we have
     1671           a virtual CPU fault */
     1672        cpu_restore_state(tb, env, pc, puc);
     1673    }
     1674#if 0
     1675        printf("PF exception: NIP=0x%08x error=0x%x %p\n",
     1676               env->nip, env->error_code, tb);
     1677#endif
     1678    /* we restore the process signal mask as the sigreturn should
     1679       do it (XXX: use sigsetjmp) */
     1680    sigprocmask(SIG_SETMASK, old_set, NULL);
     1681    cpu_loop_exit();
     1682    /* never comes here */
     1683    return 1;
     1684}
    14331685#else
    14341686#error unsupported target CPU
     
    14381690
    14391691#if defined(USE_CODE_COPY)
    1440 static void cpu_send_trap(unsigned long pc, int trap,
     1692static void cpu_send_trap(unsigned long pc, int trap, 
    14411693                          struct ucontext *uc)
    14421694{
     
    14571709#endif
    14581710
    1459 int cpu_signal_handler(int host_signum, struct siginfo *info,
     1711int cpu_signal_handler(int host_signum, void *pinfo,
    14601712                       void *puc)
    14611713{
     1714    siginfo_t *info = pinfo;
    14621715    struct ucontext *uc = puc;
    14631716    unsigned long pc;
     
    14791732    } else
    14801733#endif
    1481         return handle_cpu_signal(pc, (unsigned long)info->si_addr,
    1482                                  trapno == 0xe ?
     1734        return handle_cpu_signal(pc, (unsigned long)info->si_addr, 
     1735                                 trapno == 0xe ? 
    14831736                                 (uc->uc_mcontext.gregs[REG_ERR] >> 1) & 1 : 0,
    14841737                                 &uc->uc_sigmask, puc);
     
    14871740#elif defined(__x86_64__)
    14881741
    1489 int cpu_signal_handler(int host_signum, struct siginfo *info,
     1742int cpu_signal_handler(int host_signum, void *pinfo,
    14901743                       void *puc)
    14911744{
     1745    siginfo_t *info = pinfo;
    14921746    struct ucontext *uc = puc;
    14931747    unsigned long pc;
    14941748
    14951749    pc = uc->uc_mcontext.gregs[REG_RIP];
    1496     return handle_cpu_signal(pc, (unsigned long)info->si_addr,
    1497                              uc->uc_mcontext.gregs[REG_TRAPNO] == 0xe ?
     1750    return handle_cpu_signal(pc, (unsigned long)info->si_addr, 
     1751                             uc->uc_mcontext.gregs[REG_TRAPNO] == 0xe ? 
    14981752                             (uc->uc_mcontext.gregs[REG_ERR] >> 1) & 1 : 0,
    14991753                             &uc->uc_sigmask, puc);
     
    15511805#endif /* __APPLE__ */
    15521806
    1553 int cpu_signal_handler(int host_signum, struct siginfo *info,
     1807int cpu_signal_handler(int host_signum, void *pinfo,
    15541808                       void *puc)
    15551809{
     1810    siginfo_t *info = pinfo;
    15561811    struct ucontext *uc = puc;
    15571812    unsigned long pc;
     
    15681823        is_write = 1;
    15691824#endif
    1570     return handle_cpu_signal(pc, (unsigned long)info->si_addr,
     1825    return handle_cpu_signal(pc, (unsigned long)info->si_addr, 
    15711826                             is_write, &uc->uc_sigmask, puc);
    15721827}
     
    15741829#elif defined(__alpha__)
    15751830
    1576 int cpu_signal_handler(int host_signum, struct siginfo *info,
     1831int cpu_signal_handler(int host_signum, void *pinfo,
    15771832                           void *puc)
    15781833{
     1834    siginfo_t *info = pinfo;
    15791835    struct ucontext *uc = puc;
    15801836    uint32_t *pc = uc->uc_mcontext.sc_pc;
     
    15981854    }
    15991855
    1600     return handle_cpu_signal(pc, (unsigned long)info->si_addr,
     1856    return handle_cpu_signal(pc, (unsigned long)info->si_addr, 
    16011857                             is_write, &uc->uc_sigmask, puc);
    16021858}
    16031859#elif defined(__sparc__)
    16041860
    1605 int cpu_signal_handler(int host_signum, struct siginfo *info,
     1861int cpu_signal_handler(int host_signum, void *pinfo,
    16061862                       void *puc)
    16071863{
     1864    siginfo_t *info = pinfo;
    16081865    uint32_t *regs = (uint32_t *)(info + 1);
    16091866    void *sigmask = (regs + 20);
     
    16111868    int is_write;
    16121869    uint32_t insn;
    1613 
     1870   
    16141871    /* XXX: is there a standard glibc define ? */
    16151872    pc = regs[1];
     
    16301887      }
    16311888    }
    1632     return handle_cpu_signal(pc, (unsigned long)info->si_addr,
     1889    return handle_cpu_signal(pc, (unsigned long)info->si_addr, 
    16331890                             is_write, sigmask, NULL);
    16341891}
     
    16361893#elif defined(__arm__)
    16371894
    1638 int cpu_signal_handler(int host_signum, struct siginfo *info,
     1895int cpu_signal_handler(int host_signum, void *pinfo,
    16391896                       void *puc)
    16401897{
     1898    siginfo_t *info = pinfo;
    16411899    struct ucontext *uc = puc;
    16421900    unsigned long pc;
    16431901    int is_write;
    1644 
     1902   
    16451903    pc = uc->uc_mcontext.gregs[R15];
    16461904    /* XXX: compute is_write */
    16471905    is_write = 0;
    1648     return handle_cpu_signal(pc, (unsigned long)info->si_addr,
     1906    return handle_cpu_signal(pc, (unsigned long)info->si_addr, 
    16491907                             is_write,
    1650                              &uc->uc_sigmask);
     1908                             &uc->uc_sigmask, puc);
    16511909}
    16521910
    16531911#elif defined(__mc68000)
    16541912
    1655 int cpu_signal_handler(int host_signum, struct siginfo *info,
     1913int cpu_signal_handler(int host_signum, void *pinfo,
    16561914                       void *puc)
    16571915{
     1916    siginfo_t *info = pinfo;
    16581917    struct ucontext *uc = puc;
    16591918    unsigned long pc;
    16601919    int is_write;
    1661 
     1920   
    16621921    pc = uc->uc_mcontext.gregs[16];
    16631922    /* XXX: compute is_write */
    16641923    is_write = 0;
    1665     return handle_cpu_signal(pc, (unsigned long)info->si_addr,
     1924    return handle_cpu_signal(pc, (unsigned long)info->si_addr, 
    16661925                             is_write,
    16671926                             &uc->uc_sigmask, puc);
    16681927}
    16691928
     1929#elif defined(__ia64)
     1930
     1931#ifndef __ISR_VALID
     1932  /* This ought to be in <bits/siginfo.h>... */
     1933# define __ISR_VALID    1
     1934#endif
     1935
     1936int cpu_signal_handler(int host_signum, void *pinfo, void *puc)
     1937{
     1938    siginfo_t *info = pinfo;
     1939    struct ucontext *uc = puc;
     1940    unsigned long ip;
     1941    int is_write = 0;
     1942
     1943    ip = uc->uc_mcontext.sc_ip;
     1944    switch (host_signum) {
     1945      case SIGILL:
     1946      case SIGFPE:
     1947      case SIGSEGV:
     1948      case SIGBUS:
     1949      case SIGTRAP:
     1950          if (info->si_code && (info->si_segvflags & __ISR_VALID))
     1951              /* ISR.W (write-access) is bit 33:  */
     1952              is_write = (info->si_isr >> 33) & 1;
     1953          break;
     1954
     1955      default:
     1956          break;
     1957    }
     1958    return handle_cpu_signal(ip, (unsigned long)info->si_addr,
     1959                             is_write,
     1960                             &uc->uc_sigmask, puc);
     1961}
     1962
     1963#elif defined(__s390__)
     1964
     1965int cpu_signal_handler(int host_signum, void *pinfo,
     1966                       void *puc)
     1967{
     1968    siginfo_t *info = pinfo;
     1969    struct ucontext *uc = puc;
     1970    unsigned long pc;
     1971    int is_write;
     1972   
     1973    pc = uc->uc_mcontext.psw.addr;
     1974    /* XXX: compute is_write */
     1975    is_write = 0;
     1976    return handle_cpu_signal(pc, (unsigned long)info->si_addr,
     1977                             is_write,
     1978                             &uc->uc_sigmask, puc);
     1979}
     1980
    16701981#else
    16711982
  • trunk/src/recompiler/disas.h

    r1 r2422  
    55void disas(FILE *out, void *code, unsigned long size);
    66void target_disas(FILE *out, target_ulong code, target_ulong size, int flags);
    7 void monitor_disas(target_ulong pc, int nb_insn, int is_physical, int flags);
     7void monitor_disas(CPUState *env,
     8                   target_ulong pc, int nb_insn, int is_physical, int flags);
    89
    910/* Look up symbol for debugging purpose.  Returns "" if unknown. */
  • trunk/src/recompiler/dyngen-exec.h

    r1 r2422  
    2121#define __DYNGEN_EXEC_H__
    2222
     23/* prevent Solaris from trying to typedef FILE in gcc's
     24   include/floatingpoint.h which will conflict with the
     25   definition down below */
     26#ifdef __sun__
     27#define _FILEDEFED
     28#endif
     29
    2330/* NOTE: standard headers should be used with special care at this
    2431   point because host CPU registers are used as global variables. Some
     
    2633#include <stddef.h>
    2734
    28 /* There are some conflicts with the uClibc headers. I'm _very_ amazed
    29    that we don't get the same conflicts when compiling against glibc ... */
    30 #if !defined(__L4ENV__) && !defined(__MINGW32__) /* VBOX: mingw 3.4.x got into trouble here. */
     35#ifndef VBOX
    3136
    3237typedef unsigned char uint8_t;
    3338typedef unsigned short uint16_t;
    3439typedef unsigned int uint32_t;
     40// Linux/Sparc64 defines uint64_t
     41#if !(defined (__sparc_v9__) && defined(__linux__))
    3542/* XXX may be done for all 64 bits targets ? */
    36 #if defined (__x86_64__)
     43#if defined (__x86_64__) || defined(__ia64)
    3744typedef unsigned long uint64_t;
    3845#else
    3946typedef unsigned long long uint64_t;
    4047#endif
    41 
     48#endif
     49
     50/* if Solaris/__sun__, don't typedef int8_t, as it will be typedef'd
     51   prior to this and will cause an error in compliation, conflicting
     52   with /usr/include/sys/int_types.h, line 75 */
     53#ifndef __sun__
    4254typedef signed char int8_t;
     55#endif
    4356typedef signed short int16_t;
    4457typedef signed int int32_t;
    45 #if defined (__x86_64__)
     58// Linux/Sparc64 defines int64_t
     59#if !(defined (__sparc_v9__) && defined(__linux__))
     60#if defined (__x86_64__) || defined(__ia64)
    4661typedef signed long int64_t;
    4762#else
    4863typedef signed long long int64_t;
    4964#endif
     65#endif
     66
     67/* XXX: This may be wrong for 64-bit ILP32 hosts.  */
     68typedef void * host_reg_t;
    5069
    5170#define INT8_MIN                (-128)
     
    6281#define UINT64_MAX              ((uint64_t)(18446744073709551615))
    6382
    64 #else /* __L4ENV__ */
    65 
    66 #include <stdint.h>
    67 
    68 #endif  /* __L4ENV__ */
    69 
    7083typedef struct FILE FILE;
    7184extern int fprintf(FILE *, const char *, ...);
     
    7386#undef NULL
    7487#define NULL 0
    75 #if defined(_BSD) && !defined(__APPLE__)
    76 #include <ieeefp.h>
    77 
    78 #define FE_TONEAREST   FP_RN
    79 #define FE_DOWNWARD    FP_RM
    80 #define FE_UPWARD      FP_RP
    81 #define FE_TOWARDZERO  FP_RZ
    82 #define fesetround(x)  fpsetround(x)
    83 #else
    84 #include <fenv.h>
    85 #endif
     88
     89#else  /* VBOX */
     90
     91/* XXX: This may be wrong for 64-bit ILP32 hosts.  */
     92typedef void * host_reg_t;
     93
     94#include <iprt/stdint.h>
     95#include <stdio.h>
     96
     97#endif /* VBOX */
    8698
    8799#ifdef __i386__
     
    96108#define AREG2 "r12"
    97109#define AREG3 "r13"
    98 #define AREG4 "r14"
    99 #define AREG5 "r15"
     110//#define AREG4 "r14"
     111//#define AREG5 "r15"
    100112#endif
    101113#ifdef __powerpc__
     
    131143#endif
    132144#ifdef __sparc__
     145#ifdef HOST_SOLARIS
     146#define AREG0 "g2"
     147#define AREG1 "g3"
     148#define AREG2 "g4"
     149#define AREG3 "g5"
     150#define AREG4 "g6"
     151#else
     152#ifdef __sparc_v9__
     153#define AREG0 "g1"
     154#define AREG1 "g4"
     155#define AREG2 "g5"
     156#define AREG3 "g7"
     157#else
    133158#define AREG0 "g6"
    134159#define AREG1 "g1"
     
    143168#define AREG10 "l6"
    144169#define AREG11 "l7"
     170#endif
     171#endif
    145172#define USE_FP_CONVERT
    146173#endif
     
    170197#endif
    171198#ifdef __ia64__
    172 #define AREG0 "r27"
    173 #define AREG1 "r24"
    174 #define AREG2 "r25"
    175 #define AREG3 "r26"
     199#define AREG0 "r7"
     200#define AREG1 "r4"
     201#define AREG2 "r5"
     202#define AREG3 "r6"
    176203#endif
    177204
    178205/* force GCC to generate only one epilog at the end of the function */
    179 #define FORCE_RET() asm volatile ("");
     206#define FORCE_RET() __asm__ __volatile__("" : : : "memory");
    180207
    181208#ifndef OPPROTO
     
    192219#define __hidden __attribute__((visibility("hidden")))
    193220#else
    194 #define __hidden
     221#define __hidden 
    195222#endif
    196223
     
    232259#ifdef __x86_64__
    233260#define EXIT_TB() asm volatile ("ret")
     261#define GOTO_LABEL_PARAM(n) asm volatile ("jmp " ASM_NAME(__op_gen_label) #n)
    234262#endif
    235263#ifdef __powerpc__
     
    239267#ifdef __s390__
    240268#define EXIT_TB() asm volatile ("br %r14")
     269#define GOTO_LABEL_PARAM(n) asm volatile ("b " ASM_NAME(__op_gen_label) #n)
    241270#endif
    242271#ifdef __alpha__
     
    245274#ifdef __ia64__
    246275#define EXIT_TB() asm volatile ("br.ret.sptk.many b0;;")
     276#define GOTO_LABEL_PARAM(n) asm volatile ("br.sptk.many " \
     277                                          ASM_NAME(__op_gen_label) #n)
    247278#endif
    248279#ifdef __sparc__
    249 #define EXIT_TB() asm volatile ("jmpl %i0 + 8, %g0\n" \
    250                                 "nop")
     280#define EXIT_TB() asm volatile ("jmpl %i0 + 8, %g0; nop")
     281#define GOTO_LABEL_PARAM(n) asm volatile ("ba " ASM_NAME(__op_gen_label) #n ";nop")
    251282#endif
    252283#ifdef __arm__
    253284#define EXIT_TB() asm volatile ("b exec_loop")
     285#define GOTO_LABEL_PARAM(n) asm volatile ("b " ASM_NAME(__op_gen_label) #n)
    254286#endif
    255287#ifdef __mc68000
  • trunk/src/recompiler/dyngen.c

    r1 r2422  
    130130typedef uint32_t host_ulong;
    131131#define swabls(x) swab32s(x)
     132#define swablss(x) swab32ss(x)
    132133#else
    133134typedef int64_t host_long;
    134135typedef uint64_t host_ulong;
    135136#define swabls(x) swab64s(x)
     137#define swablss(x) swab64ss(x)
    136138#endif
    137139
     
    181183#include <mach-o/nlist.h>
    182184#include <mach-o/reloc.h>
     185#if !defined(HOST_I386)
    183186#include <mach-o/ppc/reloc.h>
     187#endif
    184188
    185189# define check_mach_header(x) (x.magic == MH_MAGIC)
     
    202206#define EXE_RELOC struct relocation_info
    203207#define EXE_SYM struct nlist_extended
     208#if defined(HOST_I386)
     209# define r_offset r_address
     210#endif
    204211
    205212#endif /* CONFIG_FORMAT_MACH */
     
    222229    char n_other;
    223230    short n_desc;
    224     unsigned long st_value; // n_value -> st_value
    225     unsigned long st_size;  // added
     231    unsigned long st_value; /* n_value -> st_value */
     232    unsigned long st_size;  /* added */
    226233};
    227234
     
    237244    OUT_GEN_OP,
    238245    OUT_CODE,
    239     OUT_INDEX_OP,
     246    OUT_INDEX_OP
    240247};
    241248
     
    314321}
    315322
     323void swab32ss(int32_t *p)
     324{
     325    *p = bswap32(*p);
     326}
     327
    316328void swab64s(uint64_t *p)
     329{
     330    *p = bswap64(*p);
     331}
     332
     333void swab64ss(int64_t *p)
    317334{
    318335    *p = bswap64(*p);
     
    427444    swabls(&rel->r_info);
    428445#ifdef ELF_USES_RELOCA
    429     swabls(&rel->r_addend);
     446    swablss(&rel->r_addend);
    430447#endif
    431448}
     
    487504    ELF_RELOC *rel;
    488505   
    489     fd = open(filename, O_RDONLY);
     506    fd = open(filename, O_RDONLY
     507#ifdef O_BINARY
     508              | O_BINARY
     509#endif
     510              );
    490511    if (fd < 0)
    491512        error("can't open file '%s'", filename);
     
    508529        elf_swap_ehdr(&ehdr);
    509530    if (ehdr.e_ident[EI_CLASS] != ELF_CLASS)
    510         error("Unsupported ELF class");
     531        error("Unsupported ELF class (%#x)", ehdr.e_ident[EI_CLASS]);
    511532    if (ehdr.e_type != ET_REL)
    512533        error("ELF object file expected");
     
    535556
    536557    sec = &shdr[ehdr.e_shstrndx];
    537     shstr = sdata[ehdr.e_shstrndx];
     558    shstr = (char *)sdata[ehdr.e_shstrndx];
    538559
    539560    /* swap relocations */
     
    571592
    572593    symtab = (ElfW(Sym) *)sdata[symtab_sec - shdr];
    573     strtab = sdata[symtab_sec->sh_link];
     594    strtab = (char *)sdata[symtab_sec->sh_link];
    574595   
    575596    nb_syms = symtab_sec->sh_size / sizeof(ElfW(Sym));
     
    665686    if (!strcmp(name, ".data"))
    666687        name = name_for_dotdata(rel);
     688    if (name[0] == '.')
     689        return NULL;
    667690    return name;
    668691}
     
    704727       
    705728    fd = open(filename, O_RDONLY
    706 #ifdef _WIN32
     729#ifdef O_BINARY
    707730              | O_BINARY
    708731#endif
     
    907930
    908931
     932#if defined(HOST_PPC)
    909933static inline void fetch_next_pair_value(struct relocation_info * rel, unsigned int *value)
    910934{
     
    922946        }
    923947}
     948#endif
    924949
    925950/* find a sym name given its value, in a section number */
     
    10141039        }
    10151040
     1041#if defined(HOST_I386)
     1042        /* ignore internal pc relative fixups where both ends are in the text section. */
     1043        if (rel->r_pcrel && !rel->r_extern && rel->r_symbolnum == 1 /* ASSUMES text */)
     1044                return NULL;
     1045#endif
     1046
    10161047        /* Intruction contains an offset to the symbols pointed to, in the rel->r_symbolnum section */
    10171048        sectoffset = *(uint32_t *)(text + rel->r_address) & 0xffff;
     
    10241055                error("sectnum > segment->nsects");
    10251056
     1057#if defined(HOST_PPC)
    10261058        switch(rel->r_type)
    10271059        {
    1028                 case PPC_RELOC_LO16: fetch_next_pair_value(rel+1, &other_half); sectoffset = (sectoffset & 0xffff);
     1060                case PPC_RELOC_LO16: fetch_next_pair_value(rel+1, &other_half); sectoffset |= (other_half << 16);
    10291061                        break;
    1030                 case PPC_RELOC_HI16: fetch_next_pair_value(rel+1, &other_half); sectoffset = (other_half & 0xffff);
     1062                case PPC_RELOC_HI16: fetch_next_pair_value(rel+1, &other_half); sectoffset = (sectoffset << 16) | (uint16_t)(other_half & 0xffff);
    10311063                        break;
    1032                 case PPC_RELOC_HA16: fetch_next_pair_value(rel+1, &other_half); sectoffset = (other_half & 0xffff);
     1064                case PPC_RELOC_HA16: fetch_next_pair_value(rel+1, &other_half); sectoffset = (sectoffset << 16) + (int16_t)(other_half & 0xffff);
    10331065                        break;
    10341066                case PPC_RELOC_BR24:
     
    10391071                        error("switch(rel->type) not found");
    10401072        }
     1073#elif defined(HOST_I386)
     1074        /* The intruction contains the addend. */
     1075        sectoffset = *(uint32_t *)(text + rel->r_address);
     1076#else
     1077#error unsupported mach-o host
     1078#endif
    10411079
    10421080        if(rel->r_pcrel)
    10431081                sectoffset += rel->r_address;
    10441082                       
     1083#if defined(HOST_PPC)
    10451084        if (rel->r_type == PPC_RELOC_BR24)
    10461085                name = (char *)find_reloc_name_in_sec_ptr((int)sectoffset, &section_hdr[sectnum-1]);
     1086#endif
    10471087
    10481088        /* search it in the full symbol list, if not found */
     
    10531093}
    10541094
     1095#if defined(HOST_I386)
     1096static const char *get_rel_sym_name_and_addend(EXE_RELOC *rel, int *addend)
     1097{
     1098        const char *name = NULL;
     1099
     1100    if (R_SCATTERED & rel->r_address) {
     1101                unsigned int i;
     1102                struct scattered_relocation_info * sca_rel = (struct scattered_relocation_info*)rel;
     1103                if (sca_rel->r_length != 2 || rel->r_pcrel) {
     1104                        error("Fully implement R_SCATTERED! r_address=%#x r_type=%#x r_length=%d r_pcrel=%d r_value=%#x\n",
     1105                                  (int)sca_rel->r_address, sca_rel->r_type, sca_rel->r_length, sca_rel->r_pcrel, sca_rel->r_value);
     1106                }
     1107
     1108                /* this seems to be the way to calc the addend. */
     1109                *addend = *(int32_t *)(text + sca_rel->r_address) - sca_rel->r_value;
     1110
     1111                /* todo: do we need to ignore internal relocations? */
     1112#if 0
     1113                if (sca_rel->r_pcrel ...)
     1114                        return NULL;
     1115#endif
     1116
     1117                /* find_reloc_name_given_its_address doesn't do the right thing here, so
     1118                   we locate the section and use find_sym_with_value_and_sec_number  */
     1119                for (i = 0; i < segment->nsects ; i++) {
     1120                        if ((uintptr_t)sca_rel->r_value - section_hdr[i].addr < section_hdr[i].size) {
     1121                                int off = 0;
     1122                                name = find_sym_with_value_and_sec_number(sca_rel->r_value, i + 1, &off);
     1123                                if (name) {
     1124                                        *addend += off;
     1125                                         break;
     1126                                }
     1127                        }
     1128                }
     1129                if (!name)
     1130                        error("Fully implement R_SCATTERED! r_address=%#x r_type=%#x r_length=%d r_pcrel=%d r_value=%#x\n",
     1131                                  (int)sca_rel->r_address, sca_rel->r_type, sca_rel->r_length, sca_rel->r_pcrel, sca_rel->r_value);
     1132        }
     1133        else
     1134        {
     1135                /* ignore debug syms (paranoia). */
     1136                if (symtab[rel->r_symbolnum].n_type & N_STAB)
     1137                        return NULL;
     1138
     1139                /* ignore internal pc relative fixups where both ends are in the text section. */
     1140                if (rel->r_pcrel && !rel->r_extern && rel->r_symbolnum == 1 /* ASSUMES text */)
     1141                        return NULL;
     1142
     1143                /* get the addend, it is in the instruction stream. */
     1144                *addend = *(int32_t *)(text + rel->r_address);
     1145                if (rel->r_pcrel)
     1146                        *addend += rel->r_address;
     1147
     1148                /* external fixups are easy. */
     1149                if (rel->r_extern)
     1150                {
     1151                        if (rel->r_symbolnum >= nb_syms)
     1152                                error("rel->r_symbolnum (%d) >= nb_syms (%d)", rel->r_symbolnum, nb_syms);
     1153                        name = get_sym_name(&symtab[rel->r_symbolnum]);
     1154                }
     1155                else
     1156                {
     1157                        /* sanity checks. */
     1158                        if (rel->r_symbolnum == 0xffffff)
     1159                                return NULL;
     1160                        if (rel->r_symbolnum > segment->nsects)
     1161                                error("sectnum (%d) > segment->nsects (%d)", rel->r_symbolnum, segment->nsects);
     1162                        if (rel->r_pcrel)
     1163                                error("internal pcrel fixups not implemented");
     1164
     1165                        /* search for the symbol. */
     1166                        name = find_sym_with_value_and_sec_number(*addend, rel->r_symbolnum, addend);
     1167                }
     1168        }
     1169    return name;
     1170}
     1171#endif /* HOST_I386 */
     1172
    10551173/* Used by dyngen common code */
    10561174static const char * get_rel_sym_name(EXE_RELOC * rel)
    10571175{
    10581176        int sslide;
     1177#if defined(HOST_I386)
     1178        return get_rel_sym_name_and_addend(rel, &sslide);
     1179#else
    10591180        return get_reloc_name( rel, &sslide);
     1181#endif
    10601182}
    10611183
     
    10821204        struct nlist *syment;
    10831205   
    1084         fd = open(filename, O_RDONLY);
     1206        fd = open(filename, O_RDONLY
     1207#ifdef O_BINARY
     1208                  | O_BINARY
     1209#endif
     1210                  );
    10851211    if (fd < 0)
    10861212        error("can't open file '%s'", filename);
     
    10941220        error("bad Mach header");
    10951221    }
    1096    
     1222
     1223#if defined(HOST_PPC)
    10971224    if (mach_hdr.cputype != CPU_TYPE_POWERPC)
     1225#elif defined(HOST_I386)
     1226    if (mach_hdr.cputype != CPU_TYPE_X86)
     1227#else
     1228#error unsupported host
     1229#endif
    10981230        error("Unsupported CPU");
    10991231       
     
    11761308        /* Now transform the symtab, to an extended version, with the sym size, and the C name */
    11771309        for(i = 0, sym = symtab, syment = symtab_std; i < nb_syms; i++, sym++, syment++) {
    1178         const char *name;
    1179         struct nlist *sym_follow, *sym_next = 0;
     1310        struct nlist *sym_cur, *sym_next = 0;
    11801311        unsigned int j;
    1181         name = find_str_by_index(sym->n_un.n_strx);
    11821312                memset(sym, 0, sizeof(*sym));
    11831313               
    1184                 if ( sym->n_type & N_STAB ) /* Debug symbols are skipped */
     1314                if ( syment->n_type & N_STAB ) /* Debug symbols are skipped */
    11851315            continue;
    11861316                       
    11871317                memcpy(sym, syment, sizeof(*syment));
     1318
     1319#if defined(VBOX)
     1320        /* don't bother calcing size of internal symbol local symbols. */
     1321        if (strstart(find_str_by_index(sym->n_un.n_strx), ".L", NULL)) {
     1322            sym->st_size = 0;
     1323            continue;
     1324        }
     1325#endif
    11881326                       
    11891327                /* Find the following symbol in order to get the current symbol size */
    1190         for(j = 0, sym_follow = symtab_std; j < nb_syms; j++, sym_follow++) {
    1191             if ( sym_follow->n_sect != 1 || sym_follow->n_type & N_STAB || !(sym_follow->n_value > sym->st_value))
     1328        for (j = 0, sym_cur = symtab_std; j < nb_syms; j++, sym_cur++) {
     1329            if (    sym_cur->n_sect != /*syment->n_sect*/ 1
     1330                ||  (sym_cur->n_type & N_STAB)
     1331                ||  sym_cur->n_value <= syment->n_value)
    11921332                continue;
    1193             if(!sym_next) {
    1194                 sym_next = sym_follow;
     1333            if (     sym_next
     1334                &&   sym_next->n_value <= sym_cur->n_value)
    11951335                continue;
    1196             }
    1197             if(!(sym_next->n_value > sym_follow->n_value))
     1336#if defined(HOST_I386)
     1337            /* Ignore local labels (.Lxxx). */
     1338            if (strstart(find_str_by_index(sym_cur->n_un.n_strx), ".L", NULL))
    11981339                continue;
    1199             sym_next = sym_follow;
     1340#endif
     1341            /* a good one */
     1342            sym_next = sym_cur;
    12001343        }
    12011344                if(sym_next)
     
    13341477}
    13351478
    1336 /* load a a.out object file */
     1479/* load an a.out object file */
    13371480int load_object(const char *filename)
    13381481{
     
    14381581#ifdef HOST_SPARC
    14391582        if (sym_name[0] == '.')
    1440             snprintf(name, sizeof(name),
     1583            snprintf(name, name_size,
    14411584                     "(long)(&__dot_%s)",
    14421585                     sym_name + 1);
     
    14471590}
    14481591
     1592#ifdef HOST_IA64
     1593
     1594#define PLT_ENTRY_SIZE  16      /* 1 bundle containing "brl" */
     1595
     1596struct plt_entry {
     1597    struct plt_entry *next;
     1598    const char *name;
     1599    unsigned long addend;
     1600} *plt_list;
     1601
     1602static int
     1603get_plt_index (const char *name, unsigned long addend)
     1604{
     1605    struct plt_entry *plt, *prev= NULL;
     1606    int index = 0;
     1607
     1608    /* see if we already have an entry for this target: */
     1609    for (plt = plt_list; plt; ++index, prev = plt, plt = plt->next)
     1610        if (strcmp(plt->name, name) == 0 && plt->addend == addend)
     1611            return index;
     1612
     1613    /* nope; create a new PLT entry: */
     1614
     1615    plt = malloc(sizeof(*plt));
     1616    if (!plt) {
     1617        perror("malloc");
     1618        exit(1);
     1619    }
     1620    memset(plt, 0, sizeof(*plt));
     1621    plt->name = strdup(name);
     1622    plt->addend = addend;
     1623
     1624    /* append to plt-list: */
     1625    if (prev)
     1626        prev->next = plt;
     1627    else
     1628        plt_list = plt;
     1629    return index;
     1630}
     1631
     1632#endif
     1633
    14491634#ifdef HOST_ARM
    14501635
     
    14551640    uint8_t *p;
    14561641    uint32_t insn;
    1457     int offset, min_offset, pc_offset, data_size;
     1642    int offset, min_offset, pc_offset, data_size, spare, max_pool;
    14581643    uint8_t data_allocated[1024];
    14591644    unsigned int data_index;
     1645    int type;
    14601646   
    14611647    memset(data_allocated, 0, sizeof(data_allocated));
     
    14631649    p = p_start;
    14641650    min_offset = p_end - p_start;
     1651    spare = 0x7fffffff;
    14651652    while (p < p_start + min_offset) {
    14661653        insn = get32((uint32_t *)p);
     1654        /* TODO: Armv5e ldrd.  */
     1655        /* TODO: VFP load.  */
    14671656        if ((insn & 0x0d5f0000) == 0x051f0000) {
    14681657            /* ldr reg, [pc, #im] */
    14691658            offset = insn & 0xfff;
    14701659            if (!(insn & 0x00800000))
    1471                         offset = -offset;
     1660                offset = -offset;
     1661            max_pool = 4096;
     1662            type = 0;
     1663        } else if ((insn & 0x0e5f0f00) == 0x0c1f0100) {
     1664            /* FPA ldf.  */
     1665            offset = (insn & 0xff) << 2;
     1666            if (!(insn & 0x00800000))
     1667                offset = -offset;
     1668            max_pool = 1024;
     1669            type = 1;
     1670        } else if ((insn & 0x0fff0000) == 0x028f0000) {
     1671            /* Some gcc load a doubleword immediate with
     1672               add regN, pc, #imm
     1673               ldmia regN, {regN, regM}
     1674               Hope and pray the compiler never generates somethin like
     1675               add reg, pc, #imm1; ldr reg, [reg, #-imm2]; */
     1676            int r;
     1677
     1678            r = (insn & 0xf00) >> 7;
     1679            offset = ((insn & 0xff) >> r) | ((insn & 0xff) << (32 - r));
     1680            max_pool = 1024;
     1681            type = 2;
     1682        } else {
     1683            max_pool = 0;
     1684            type = -1;
     1685        }
     1686        if (type >= 0) {
     1687            /* PC-relative load needs fixing up.  */
     1688            if (spare > max_pool - offset)
     1689                spare = max_pool - offset;
    14721690            if ((offset & 3) !=0)
    1473                 error("%s:%04x: ldr pc offset must be 32 bit aligned",
     1691                error("%s:%04x: pc offset must be 32 bit aligned",
     1692                      name, start_offset + p - p_start);
     1693            if (offset < 0)
     1694                error("%s:%04x: Embedded literal value",
    14741695                      name, start_offset + p - p_start);
    14751696            pc_offset = p - p_start + offset + 8;
    14761697            if (pc_offset <= (p - p_start) ||
    14771698                pc_offset >= (p_end - p_start))
    1478                 error("%s:%04x: ldr pc offset must point inside the function code",
     1699                error("%s:%04x: pc offset must point inside the function code",
    14791700                      name, start_offset + p - p_start);
    14801701            if (pc_offset < min_offset)
    14811702                min_offset = pc_offset;
    14821703            if (outfile) {
    1483                 /* ldr position */
     1704                /* The intruction position */
    14841705                fprintf(outfile, "    arm_ldr_ptr->ptr = gen_code_ptr + %d;\n",
    14851706                        p - p_start);
    1486                 /* ldr data index */
    1487                 data_index = ((p_end - p_start) - pc_offset - 4) >> 2;
    1488                 fprintf(outfile, "    arm_ldr_ptr->data_ptr = arm_data_ptr + %d;\n",
     1707                /* The position of the constant pool data. */
     1708                data_index = ((p_end - p_start) - pc_offset) >> 2;
     1709                fprintf(outfile, "    arm_ldr_ptr->data_ptr = arm_data_ptr - %d;\n",
    14891710                        data_index);
     1711                fprintf(outfile, "    arm_ldr_ptr->type = %d;\n", type);
    14901712                fprintf(outfile, "    arm_ldr_ptr++;\n");
    1491                 if (data_index >= sizeof(data_allocated))
    1492                     error("%s: too many data", name);
    1493                 if (!data_allocated[data_index]) {
    1494                     ELF_RELOC *rel;
    1495                     int i, addend, type;
    1496                     const char *sym_name, *p;
    1497                     char relname[1024];
    1498 
    1499                     data_allocated[data_index] = 1;
    1500 
    1501                     /* data value */
    1502                     addend = get32((uint32_t *)(p_start + pc_offset));
    1503                     relname[0] = '\0';
    1504                     for(i = 0, rel = relocs;i < nb_relocs; i++, rel++) {
    1505                         if (rel->r_offset == (pc_offset + start_offset)) {
    1506                             sym_name = get_rel_sym_name(rel);
    1507                             /* the compiler leave some unnecessary references to the code */
    1508                             get_reloc_expr(relname, sizeof(relname), sym_name);
    1509                             type = ELF32_R_TYPE(rel->r_info);
    1510                             if (type != R_ARM_ABS32)
    1511                                 error("%s: unsupported data relocation", name);
    1512                             break;
    1513                         }
    1514                     }
    1515                     fprintf(outfile, "    arm_data_ptr[%d] = 0x%x",
    1516                             data_index, addend);
    1517                     if (relname[0] != '\0')
    1518                         fprintf(outfile, " + %s", relname);
    1519                     fprintf(outfile, ";\n");
    1520                 }
    15211713            }
    15221714        }
    15231715        p += 4;
    15241716    }
     1717
     1718    /* Copy and relocate the constant pool data.  */
    15251719    data_size = (p_end - p_start) - min_offset;
    15261720    if (data_size > 0 && outfile) {
    1527         fprintf(outfile, "    arm_data_ptr += %d;\n", data_size >> 2);
    1528     }
    1529 
    1530     /* the last instruction must be a mov pc, lr */
     1721        spare += min_offset;
     1722        fprintf(outfile, "    arm_data_ptr -= %d;\n", data_size >> 2);
     1723        fprintf(outfile, "    arm_pool_ptr -= %d;\n", data_size);
     1724        fprintf(outfile, "    if (arm_pool_ptr > gen_code_ptr + %d)\n"
     1725                         "        arm_pool_ptr = gen_code_ptr + %d;\n",
     1726                         spare, spare);
     1727
     1728        data_index = 0;
     1729        for (pc_offset = min_offset;
     1730             pc_offset < p_end - p_start;
     1731             pc_offset += 4) {
     1732
     1733            ELF_RELOC *rel;
     1734            int i, addend, type;
     1735            const char *sym_name;
     1736            char relname[1024];
     1737
     1738            /* data value */
     1739            addend = get32((uint32_t *)(p_start + pc_offset));
     1740            relname[0] = '\0';
     1741            for(i = 0, rel = relocs;i < nb_relocs; i++, rel++) {
     1742                if (rel->r_offset == (pc_offset + start_offset)) {
     1743                    sym_name = get_rel_sym_name(rel);
     1744                    /* the compiler leave some unnecessary references to the code */
     1745                    get_reloc_expr(relname, sizeof(relname), sym_name);
     1746                    type = ELF32_R_TYPE(rel->r_info);
     1747                    if (type != R_ARM_ABS32)
     1748                        error("%s: unsupported data relocation", name);
     1749                    break;
     1750                }
     1751            }
     1752            fprintf(outfile, "    arm_data_ptr[%d] = 0x%x",
     1753                    data_index, addend);
     1754            if (relname[0] != '\0')
     1755                fprintf(outfile, " + %s", relname);
     1756            fprintf(outfile, ";\n");
     1757
     1758            data_index++;
     1759        }
     1760    }
     1761
    15311762    if (p == p_start)
    15321763        goto arm_ret_error;
    15331764    p -= 4;
    15341765    insn = get32((uint32_t *)p);
    1535     if ((insn & 0xffff0000) != 0xe91b0000) {
     1766    /* The last instruction must be an ldm instruction.  There are several
     1767       forms generated by gcc:
     1768        ldmib sp, {..., pc}  (implies a sp adjustment of +4)
     1769        ldmia sp, {..., pc}
     1770        ldmea fp, {..., pc} */
     1771    if ((insn & 0xffff8000) == 0xe99d8000) {
     1772        if (outfile) {
     1773            fprintf(outfile,
     1774                    "    *(uint32_t *)(gen_code_ptr + %d) = 0xe28dd004;\n",
     1775                    p - p_start);
     1776        }
     1777        p += 4;
     1778    } else if ((insn & 0xffff8000) != 0xe89d8000
     1779        && (insn & 0xffff8000) != 0xe91b8000) {
    15361780    arm_ret_error:
    15371781        if (!outfile)
    15381782            printf("%s: invalid epilog\n", name);
    15391783    }
    1540     return p - p_start;     
     1784    return p - p_start;
    15411785}
    15421786#endif
     
    15661810    start_offset = offset;
    15671811#if defined(HOST_I386) || defined(HOST_X86_64)
    1568 #if defined(CONFIG_FORMAT_COFF) || defined(CONFIG_FORMAT_AOUT)
     1812#if defined(CONFIG_FORMAT_COFF) || defined(CONFIG_FORMAT_AOUT) || defined(CONFIG_FORMAT_MACH)
    15691813    {
    15701814        uint8_t *p;
     
    16361880        if (get32((uint32_t *)p) != 0x00840008)
    16371881            error("br.ret.sptk.many b0;; expected at the end of %s", name);
    1638         copy_size = p - p_start;
     1882        copy_size = p_end - p_start;
    16391883    }
    16401884#elif defined(HOST_SPARC)
    16411885    {
     1886#define INSN_SAVE       0x9de3a000
     1887#define INSN_RET        0x81c7e008
     1888#define INSN_RETL       0x81c3e008
     1889#define INSN_RESTORE    0x81e80000
     1890#define INSN_RETURN     0x81cfe008
     1891#define INSN_NOP        0x01000000
     1892#define INSN_ADD_SP     0x9c03a000 /* add %sp, nn, %sp */
     1893#define INSN_SUB_SP     0x9c23a000 /* sub %sp, nn, %sp */
     1894
    16421895        uint32_t start_insn, end_insn1, end_insn2;
    16431896        uint8_t *p;
     
    16481901        end_insn1 = get32((uint32_t *)(p + 0x0));
    16491902        end_insn2 = get32((uint32_t *)(p + 0x4));
    1650         if ((start_insn & ~0x1fff) == 0x9de3a000) {
     1903        if (((start_insn & ~0x1fff) == INSN_SAVE) ||
     1904            (start_insn & ~0x1fff) == INSN_ADD_SP) {
    16511905            p_start += 0x4;
    16521906            start_offset += 0x4;
    1653             if ((int)(start_insn | ~0x1fff) < -128)
    1654                 error("Found bogus save at the start of %s", name);
    1655             if (end_insn1 != 0x81c7e008 || end_insn2 != 0x81e80000)
     1907            if (end_insn1 == INSN_RET && end_insn2 == INSN_RESTORE)
     1908                /* SPARC v7: ret; restore; */ ;
     1909            else if (end_insn1 == INSN_RETURN && end_insn2 == INSN_NOP)
     1910                /* SPARC v9: return; nop; */ ;
     1911            else if (end_insn1 == INSN_RETL && (end_insn2 & ~0x1fff) == INSN_SUB_SP)
     1912                /* SPARC v7: retl; sub %sp, nn, %sp; */ ;
     1913            else
     1914
    16561915                error("ret; restore; not found at end of %s", name);
     1916        } else if (end_insn1 == INSN_RETL && end_insn2 == INSN_NOP) {
     1917            ;
    16571918        } else {
    16581919            error("No save at the beginning of %s", name);
     
    16621923        if (p > p_start) {
    16631924            skip_insn = get32((uint32_t *)(p - 0x4));
    1664             if (skip_insn == 0x01000000)
     1925            if (skip_insn == INSN_NOP)
    16651926                p -= 4;
    16661927        }
     
    16701931#elif defined(HOST_SPARC64)
    16711932    {
     1933#define INSN_SAVE       0x9de3a000
     1934#define INSN_RET        0x81c7e008
     1935#define INSN_RETL       0x81c3e008
     1936#define INSN_RESTORE    0x81e80000
     1937#define INSN_RETURN     0x81cfe008
     1938#define INSN_NOP        0x01000000
     1939#define INSN_ADD_SP     0x9c03a000 /* add %sp, nn, %sp */
     1940#define INSN_SUB_SP     0x9c23a000 /* sub %sp, nn, %sp */
     1941
    16721942        uint32_t start_insn, end_insn1, end_insn2, skip_insn;
    16731943        uint8_t *p;
    16741944        p = (void *)(p_end - 8);
     1945#if 0
     1946        /* XXX: check why it occurs */
    16751947        if (p <= p_start)
    16761948            error("empty code for %s", name);
     1949#endif
    16771950        start_insn = get32((uint32_t *)(p_start + 0x0));
    16781951        end_insn1 = get32((uint32_t *)(p + 0x0));
    16791952        end_insn2 = get32((uint32_t *)(p + 0x4));
    1680         if ((start_insn & ~0x1fff) == 0x9de3a000) {
     1953        if (((start_insn & ~0x1fff) == INSN_SAVE) ||
     1954            (start_insn & ~0x1fff) == INSN_ADD_SP) {
    16811955            p_start += 0x4;
    16821956            start_offset += 0x4;
    1683             if ((int)(start_insn | ~0x1fff) < -256)
    1684                 error("Found bogus save at the start of %s", name);
    1685             if (end_insn1 != 0x81c7e008 || end_insn2 != 0x81e80000)
     1957            if (end_insn1 == INSN_RET && end_insn2 == INSN_RESTORE)
     1958                /* SPARC v7: ret; restore; */ ;
     1959            else if (end_insn1 == INSN_RETURN && end_insn2 == INSN_NOP)
     1960                /* SPARC v9: return; nop; */ ;
     1961            else if (end_insn1 == INSN_RETL && (end_insn2 & ~0x1fff) == INSN_SUB_SP)
     1962                /* SPARC v7: retl; sub %sp, nn, %sp; */ ;
     1963            else
     1964
    16861965                error("ret; restore; not found at end of %s", name);
     1966        } else if (end_insn1 == INSN_RETL && end_insn2 == INSN_NOP) {
     1967            ;
    16871968        } else {
    16881969            error("No save at the beginning of %s", name);
     
    17001981#elif defined(HOST_ARM)
    17011982    {
     1983        uint32_t insn;
     1984
    17021985        if ((p_end - p_start) <= 16)
    17031986            error("%s: function too small", name);
     
    17081991        p_start += 12;
    17091992        start_offset += 12;
     1993        insn = get32((uint32_t *)p_start);
     1994        if ((insn & 0xffffff00) == 0xe24dd000) {
     1995            /* Stack adjustment.  Assume op uses the frame pointer.  */
     1996            p_start -= 4;
     1997            start_offset -= 4;
     1998        }
    17101999        copy_size = arm_emit_ldr_info(name, start_offset, NULL, p_start, p_end,
    17112000                                      relocs, nb_relocs);
     
    17172006        if (p == p_start)
    17182007            error("empty code for %s", name);
    1719         // remove NOP's, probably added for alignment
     2008        /* remove NOP's, probably added for alignment */
    17202009        while ((get16((uint16_t *)p) == 0x4e71) &&
    17212010               (p>p_start))
     
    17732062            fprintf(outfile, ";\n");
    17742063        }
     2064#if defined(HOST_IA64)
     2065        fprintf(outfile, "    extern char %s;\n", name);
     2066#else
    17752067        fprintf(outfile, "    extern void %s();\n", name);
     2068#endif
    17762069
    17772070        for(i = 0, rel = relocs;i < nb_relocs; i++, rel++) {
     
    17832076                    continue;
    17842077                if (*sym_name &&
     2078#ifdef VBOX
     2079                    !strstart(sym_name, "remR3PhysWrite", NULL) &&
     2080                    !strstart(sym_name, "remR3PhysRead", NULL) &&
     2081#endif
    17852082                    !strstart(sym_name, "__op_param", NULL) &&
    17862083                    !strstart(sym_name, "__op_jmp", NULL) &&
     
    17942091                    }
    17952092#endif
    1796 #ifdef VBOX
    1797                     if (   strcmp(sym_name, "remR3PhysWriteBytes")
    1798                         && strcmp(sym_name, "remR3PhysReadBytes")
    1799                         && strcmp(sym_name, "remR3PhysReadUByte")
    1800                         && strcmp(sym_name, "remR3PhysReadSByte")
    1801                         && strcmp(sym_name, "remR3PhysReadUWord")
    1802                         && strcmp(sym_name, "remR3PhysReadSWord")
    1803                         && strcmp(sym_name, "remR3PhysReadULong")
    1804                         && strcmp(sym_name, "remR3PhysReadSLong")
    1805                         && strcmp(sym_name, "remR3PhysWriteByte")
    1806                         && strcmp(sym_name, "remR3PhysWriteWord")
    1807                         && strcmp(sym_name, "remR3PhysWriteDword"))
    1808 #endif /* VBOX */
    1809 #ifdef __APPLE__
     2093#if defined(__APPLE__)
    18102094/* set __attribute((unused)) on darwin because we wan't to avoid warning when we don't use the symbol */
    18112095                    fprintf(outfile, "extern char %s __attribute__((unused));\n", sym_name);
     2096#elif defined(HOST_IA64)
     2097                        if (ELF64_R_TYPE(rel->r_info) != R_IA64_PCREL21B)
     2098                                /*
     2099                                 * PCREL21 br.call targets generally
     2100                                 * are out of range and need to go
     2101                                 * through an "import stub".
     2102                                 */
     2103                                fprintf(outfile, "    extern char %s;\n",
     2104                                        sym_name);
    18122105#else
    18132106                    fprintf(outfile, "extern char %s;\n", sym_name);
     
    18892182                    if (val >= start_offset && val <= start_offset + copy_size) {
    18902183                        n = strtol(p, NULL, 10);
    1891                         fprintf(outfile, "    label_offsets[%d] = %ld + (gen_code_ptr - gen_code_buf);\n", n, val - start_offset);
     2184                        fprintf(outfile, "    label_offsets[%d] = %ld + (gen_code_ptr - gen_code_buf);\n", n, (long)(val - start_offset));
    18922185                    }
    18932186                }
     
    19012194
    19022195        /* patch relocations */
    1903 #if defined(HOST_I386)
     2196#if defined(HOST_I386) 
    19042197            {
    19052198                char name[256];
    19062199                int type;
    19072200                int addend;
     2201                int reloc_offset;
    19082202                for(i = 0, rel = relocs;i < nb_relocs; i++, rel++) {
    1909                 if (rel->r_offset >= start_offset &&
    1910                     rel->r_offset < start_offset + copy_size) {
    1911 #ifdef CONFIG_FORMAT_AOUT
     2203                host_ulong offset = get_rel_offset(rel);
     2204                if (offset >= start_offset &&
     2205                    offset < start_offset + copy_size) {
     2206#if defined(CONFIG_FORMAT_AOUT) || defined(CONFIG_FORMAT_MACH)
    19122207                    sym_name = get_rel_sym_name_and_addend(rel, &addend);
    19132208#else
    19142209                    sym_name = get_rel_sym_name(rel);
    19152210#endif
     2211                    if (!sym_name)
     2212                        continue;
     2213                    reloc_offset = offset - start_offset;
    19162214                    if (strstart(sym_name, "__op_jmp", &p)) {
    19172215                        int n;
     
    19222220                           needs to be stored */
    19232221                        fprintf(outfile, "    jmp_offsets[%d] = %d + (gen_code_ptr - gen_code_buf);\n",
    1924                                 n, rel->r_offset - start_offset);
     2222                                n, reloc_offset);
    19252223                        continue;
    19262224                    }
    1927                        
     2225
    19282226                    get_reloc_expr(name, sizeof(name), sym_name);
    1929 #ifndef CONFIG_FORMAT_AOUT
    1930                     addend = get32((uint32_t *)(text + rel->r_offset));
     2227#if !defined(CONFIG_FORMAT_AOUT) && !defined(CONFIG_FORMAT_MACH)
     2228                    addend = get32((uint32_t *)(text + offset));
    19312229#endif
    19322230#ifdef CONFIG_FORMAT_ELF
     
    19352233                    case R_386_32:
    19362234                        fprintf(outfile, "    *(uint32_t *)(gen_code_ptr + %d) = %s + %d;\n",
    1937                                 rel->r_offset - start_offset, name, addend);
     2235                                reloc_offset, name, addend);
    19382236                        break;
    19392237                    case R_386_PC32:
    19402238                        fprintf(outfile, "    *(uint32_t *)(gen_code_ptr + %d) = %s - (long)(gen_code_ptr + %d) + %d;\n",
    1941                                 rel->r_offset - start_offset, name, rel->r_offset - start_offset, addend);
     2239                                reloc_offset, name, reloc_offset, addend);
    19422240                        break;
    19432241                    default:
     
    19622260                    case DIR32:
    19632261                        fprintf(outfile, "    *(uint32_t *)(gen_code_ptr + %d) = %s + %d;\n",
    1964                                 rel->r_offset - start_offset, name, addend);
     2262                                reloc_offset, name, addend);
    19652263                        break;
    19662264                    case DISP32:
    19672265                        fprintf(outfile, "    *(uint32_t *)(gen_code_ptr + %d) = %s - (long)(gen_code_ptr + %d) + %d -4;\n",
    1968                                 rel->r_offset - start_offset, name, rel->r_offset - start_offset, addend);
     2266                                reloc_offset, name, reloc_offset, addend);
    19692267                        break;
    19702268                    default:
    19712269                        error("unsupported i386 relocation (%d)", type);
    19722270                    }
    1973 #elif defined(CONFIG_FORMAT_AOUT)
     2271#elif defined(CONFIG_FORMAT_AOUT) || defined(CONFIG_FORMAT_MACH)
    19742272                    if (rel->r_pcrel) {
    19752273                        fprintf(outfile, "    *(uint32_t *)(gen_code_ptr + %d) = %s - (long)(gen_code_ptr + %d) + %d;\n",
    1976                                 rel->r_offset - start_offset, name, rel->r_offset - start_offset, addend);
     2274                                offset - start_offset, name, offset - start_offset, addend);
    19772275                    } else {
    19782276                        fprintf(outfile, "    *(uint32_t *)(gen_code_ptr + %d) = %s + %d;\n",
    1979                                 rel->r_offset - start_offset, name, addend);
     2277                                offset - start_offset, name, addend);
    19802278                    }
    19812279                    (void)type;
     
    19912289                int type;
    19922290                int addend;
     2291                int reloc_offset;
    19932292                for(i = 0, rel = relocs;i < nb_relocs; i++, rel++) {
    19942293                if (rel->r_offset >= start_offset &&
     
    19982297                    type = ELF32_R_TYPE(rel->r_info);
    19992298                    addend = rel->r_addend;
     2299                    reloc_offset = rel->r_offset - start_offset;
    20002300                    switch(type) {
    20012301                    case R_X86_64_32:
    20022302                        fprintf(outfile, "    *(uint32_t *)(gen_code_ptr + %d) = (uint32_t)%s + %d;\n",
    2003                                 rel->r_offset - start_offset, name, addend);
     2303                                reloc_offset, name, addend);
    20042304                        break;
    20052305                    case R_X86_64_32S:
    20062306                        fprintf(outfile, "    *(uint32_t *)(gen_code_ptr + %d) = (int32_t)%s + %d;\n",
    2007                                 rel->r_offset - start_offset, name, addend);
     2307                                reloc_offset, name, addend);
    20082308                        break;
    20092309                    case R_X86_64_PC32:
    20102310                        fprintf(outfile, "    *(uint32_t *)(gen_code_ptr + %d) = %s - (long)(gen_code_ptr + %d) + %d;\n",
    2011                                 rel->r_offset - start_offset, name, rel->r_offset - start_offset, addend);
     2311                                reloc_offset, name, reloc_offset, addend);
    20122312                        break;
     2313#ifdef VBOX /** @todo Re-check the sanity of this */
     2314                    case R_X86_64_64:
     2315                        fprintf(outfile, "    *(uint64_t *)(gen_code_ptr + %d) = (uint64_t)%s + %d;\n",
     2316                                reloc_offset, name, addend);
     2317                        break;
     2318#endif
    20132319                    default:
    20142320                        error("unsupported X86_64 relocation (%d)", type);
     
    20232329                int type;
    20242330                int addend;
     2331                int reloc_offset;
    20252332                for(i = 0, rel = relocs;i < nb_relocs; i++, rel++) {
    20262333                    if (rel->r_offset >= start_offset &&
    20272334                        rel->r_offset < start_offset + copy_size) {
    20282335                        sym_name = strtab + symtab[ELFW(R_SYM)(rel->r_info)].st_name;
     2336                        reloc_offset = rel->r_offset - start_offset;
    20292337                        if (strstart(sym_name, "__op_jmp", &p)) {
    20302338                            int n;
     
    20352343                               needs to be stored */
    20362344                            fprintf(outfile, "    jmp_offsets[%d] = %d + (gen_code_ptr - gen_code_buf);\n",
    2037                                     n, rel->r_offset - start_offset);
     2345                                    n, reloc_offset);
    20382346                            continue;
    20392347                        }
     
    20452353                        case R_PPC_ADDR32:
    20462354                            fprintf(outfile, "    *(uint32_t *)(gen_code_ptr + %d) = %s + %d;\n",
    2047                                     rel->r_offset - start_offset, name, addend);
     2355                                    reloc_offset, name, addend);
    20482356                            break;
    20492357                        case R_PPC_ADDR16_LO:
    20502358                            fprintf(outfile, "    *(uint16_t *)(gen_code_ptr + %d) = (%s + %d);\n",
    2051                                     rel->r_offset - start_offset, name, addend);
     2359                                    reloc_offset, name, addend);
    20522360                            break;
    20532361                        case R_PPC_ADDR16_HI:
    20542362                            fprintf(outfile, "    *(uint16_t *)(gen_code_ptr + %d) = (%s + %d) >> 16;\n",
    2055                                     rel->r_offset - start_offset, name, addend);
     2363                                    reloc_offset, name, addend);
    20562364                            break;
    20572365                        case R_PPC_ADDR16_HA:
    20582366                            fprintf(outfile, "    *(uint16_t *)(gen_code_ptr + %d) = (%s + %d + 0x8000) >> 16;\n",
    2059                                     rel->r_offset - start_offset, name, addend);
     2367                                    reloc_offset, name, addend);
    20602368                            break;
    20612369                        case R_PPC_REL24:
    20622370                            /* warning: must be at 32 MB distancy */
    20632371                            fprintf(outfile, "    *(uint32_t *)(gen_code_ptr + %d) = (*(uint32_t *)(gen_code_ptr + %d) & ~0x03fffffc) | ((%s - (long)(gen_code_ptr + %d) + %d) & 0x03fffffc);\n",
    2064                                     rel->r_offset - start_offset, rel->r_offset - start_offset, name, rel->r_offset - start_offset, addend);
     2372                                    reloc_offset, reloc_offset, name, reloc_offset, addend);
    20652373                            break;
    20662374                        default:
     
    21282436                                        switch(type) {
    21292437                                        case PPC_RELOC_BR24:
    2130                                                 fprintf(outfile, "{\n");
    2131                                                 fprintf(outfile, "    uint32_t imm = *(uint32_t *)(gen_code_ptr + %d) & 0x3fffffc;\n", slide);
    2132                                                 fprintf(outfile, "    *(uint32_t *)(gen_code_ptr + %d) = (*(uint32_t *)(gen_code_ptr + %d) & ~0x03fffffc) | ((imm + ((long)%s - (long)gen_code_ptr) + %d) & 0x03fffffc);\n",
     2438                                            if (!strstart(sym_name,"__op_gen_label",&p)) {
     2439                                                fprintf(outfile, "{\n");
     2440                                                fprintf(outfile, "    uint32_t imm = *(uint32_t *)(gen_code_ptr + %d) & 0x3fffffc;\n", slide);
     2441                                                fprintf(outfile, "    *(uint32_t *)(gen_code_ptr + %d) = (*(uint32_t *)(gen_code_ptr + %d) & ~0x03fffffc) | ((imm + ((long)%s - (long)gen_code_ptr) + %d) & 0x03fffffc);\n",
    21332442                                                                                        slide, slide, name, sslide );
    2134                                                 fprintf(outfile, "}\n");
     2443                                                fprintf(outfile, "}\n");
     2444                                        } else {
     2445                                                        fprintf(outfile, "    *(uint32_t *)(gen_code_ptr + %d) = (*(uint32_t *)(gen_code_ptr + %d) & ~0x03fffffc) | (((long)%s - (long)gen_code_ptr - %d) & 0x03fffffc);\n",
     2446                                                                                        slide, slide, final_sym_name, slide);
     2447                                        }
    21352448                                                break;
    21362449                                        case PPC_RELOC_HI16:
     
    21592472                int type;
    21602473                int addend;
     2474                int reloc_offset;
    21612475                for(i = 0, rel = relocs;i < nb_relocs; i++, rel++) {
    21622476                    if (rel->r_offset >= start_offset &&
     
    21662480                        type = ELF32_R_TYPE(rel->r_info);
    21672481                        addend = rel->r_addend;
     2482                        reloc_offset = rel->r_offset - start_offset;
    21682483                        switch(type) {
    21692484                        case R_390_32:
    21702485                            fprintf(outfile, "    *(uint32_t *)(gen_code_ptr + %d) = %s + %d;\n",
    2171                                     rel->r_offset - start_offset, name, addend);
     2486                                    reloc_offset, name, addend);
    21722487                            break;
    21732488                        case R_390_16:
    21742489                            fprintf(outfile, "    *(uint16_t *)(gen_code_ptr + %d) = %s + %d;\n",
    2175                                     rel->r_offset - start_offset, name, addend);
     2490                                    reloc_offset, name, addend);
    21762491                            break;
    21772492                        case R_390_8:
    21782493                            fprintf(outfile, "    *(uint8_t *)(gen_code_ptr + %d) = %s + %d;\n",
    2179                                     rel->r_offset - start_offset, name, addend);
     2494                                    reloc_offset, name, addend);
    21802495                            break;
    21812496                        default:
     
    21902505                    if (rel->r_offset >= start_offset && rel->r_offset < start_offset + copy_size) {
    21912506                        int type;
     2507                        long reloc_offset;
    21922508
    21932509                        type = ELF64_R_TYPE(rel->r_info);
    21942510                        sym_name = strtab + symtab[ELF64_R_SYM(rel->r_info)].st_name;
     2511                        reloc_offset = rel->r_offset - start_offset;
    21952512                        switch (type) {
    21962513                        case R_ALPHA_GPDISP:
     
    21982515                               as an immediate instead of constructing it from the pv or ra.  */
    21992516                            fprintf(outfile, "    immediate_ldah(gen_code_ptr + %ld, gp);\n",
    2200                                     rel->r_offset - start_offset);
     2517                                    reloc_offset);
    22012518                            fprintf(outfile, "    immediate_lda(gen_code_ptr + %ld, gp);\n",
    2202                                     rel->r_offset - start_offset + rel->r_addend);
     2519                                    reloc_offset + (int)rel->r_addend);
    22032520                            break;
    22042521                        case R_ALPHA_LITUSE:
     
    22202537                            if (strstart(sym_name, "__op_param", &p))
    22212538                                fprintf(outfile, "    immediate_ldah(gen_code_ptr + %ld, param%s);\n",
    2222                                         rel->r_offset - start_offset, p);
     2539                                        reloc_offset, p);
    22232540                            break;
    22242541                        case R_ALPHA_GPRELLOW:
    22252542                            if (strstart(sym_name, "__op_param", &p))
    22262543                                fprintf(outfile, "    immediate_lda(gen_code_ptr + %ld, param%s);\n",
    2227                                         rel->r_offset - start_offset, p);
     2544                                        reloc_offset, p);
    22282545                            break;
    22292546                        case R_ALPHA_BRSGP:
     
    22312548                               set up the gp from the pv.  */
    22322549                            fprintf(outfile, "    fix_bsr(gen_code_ptr + %ld, (uint8_t *) &%s - (gen_code_ptr + %ld + 4) + 8);\n",
    2233                                     rel->r_offset - start_offset, sym_name, rel->r_offset - start_offset);
     2550                                    reloc_offset, sym_name, reloc_offset);
    22342551                            break;
    22352552                        default:
     
    22412558#elif defined(HOST_IA64)
    22422559            {
     2560                unsigned long sym_idx;
     2561                long code_offset;
    22432562                char name[256];
    22442563                int type;
    2245                 int addend;
     2564                long addend;
     2565
    22462566                for(i = 0, rel = relocs;i < nb_relocs; i++, rel++) {
    2247                     if (rel->r_offset >= start_offset && rel->r_offset < start_offset + copy_size) {
    2248                         sym_name = strtab + symtab[ELF64_R_SYM(rel->r_info)].st_name;
    2249                         get_reloc_expr(name, sizeof(name), sym_name);
    2250                         type = ELF64_R_TYPE(rel->r_info);
    2251                         addend = rel->r_addend;
    2252                         switch(type) {
    2253                         case R_IA64_LTOFF22:
    2254                             error("must implemnt R_IA64_LTOFF22 relocation");
    2255                         case R_IA64_PCREL21B:
    2256                             error("must implemnt R_IA64_PCREL21B relocation");
    2257                         default:
    2258                             error("unsupported ia64 relocation (%d)", type);
    2259                         }
    2260                     }
     2567                    sym_idx = ELF64_R_SYM(rel->r_info);
     2568                    if (rel->r_offset < start_offset
     2569                        || rel->r_offset >= start_offset + copy_size)
     2570                        continue;
     2571                    sym_name = (strtab + symtab[sym_idx].st_name);
     2572                    code_offset = rel->r_offset - start_offset;
     2573                    if (strstart(sym_name, "__op_jmp", &p)) {
     2574                        int n;
     2575                        n = strtol(p, NULL, 10);
     2576                        /* __op_jmp relocations are done at
     2577                           runtime to do translated block
     2578                           chaining: the offset of the instruction
     2579                           needs to be stored */
     2580                        fprintf(outfile, "    jmp_offsets[%d] ="
     2581                                "%ld + (gen_code_ptr - gen_code_buf);\n",
     2582                                n, code_offset);
     2583                        continue;
     2584                    }
     2585                    get_reloc_expr(name, sizeof(name), sym_name);
     2586                    type = ELF64_R_TYPE(rel->r_info);
     2587                    addend = rel->r_addend;
     2588                    switch(type) {
     2589                      case R_IA64_IMM64:
     2590                          fprintf(outfile,
     2591                                  "    ia64_imm64(gen_code_ptr + %ld, "
     2592                                  "%s + %ld);\n",
     2593                                  code_offset, name, addend);
     2594                          break;
     2595                      case R_IA64_LTOFF22X:
     2596                      case R_IA64_LTOFF22:
     2597                          fprintf(outfile, "    IA64_LTOFF(gen_code_ptr + %ld,"
     2598                                  " %s + %ld, %d);\n",
     2599                                  code_offset, name, addend,
     2600                                  (type == R_IA64_LTOFF22X));
     2601                          break;
     2602                      case R_IA64_LDXMOV:
     2603                          fprintf(outfile,
     2604                                  "    ia64_ldxmov(gen_code_ptr + %ld,"
     2605                                  " %s + %ld);\n", code_offset, name, addend);
     2606                          break;
     2607
     2608                      case R_IA64_PCREL21B:
     2609                          if (strstart(sym_name, "__op_gen_label", NULL)) {
     2610                              fprintf(outfile,
     2611                                      "    ia64_imm21b(gen_code_ptr + %ld,"
     2612                                      " (long) (%s + %ld -\n\t\t"
     2613                                      "((long) gen_code_ptr + %ld)) >> 4);\n",
     2614                                      code_offset, name, addend,
     2615                                      code_offset & ~0xfUL);
     2616                          } else {
     2617                              fprintf(outfile,
     2618                                      "    IA64_PLT(gen_code_ptr + %ld, "
     2619                                      "%d);\t/* %s + %ld */\n",
     2620                                      code_offset,
     2621                                      get_plt_index(sym_name, addend),
     2622                                      sym_name, addend);
     2623                          }
     2624                          break;
     2625                      default:
     2626                          error("unsupported ia64 relocation (0x%x)",
     2627                                type);
     2628                    }
    22612629                }
     2630                fprintf(outfile, "    ia64_nop_b(gen_code_ptr + %d);\n",
     2631                        copy_size - 16 + 2);
    22622632            }
    22632633#elif defined(HOST_SPARC)
     
    22662636                int type;
    22672637                int addend;
     2638                int reloc_offset;
    22682639                for(i = 0, rel = relocs;i < nb_relocs; i++, rel++) {
    22692640                    if (rel->r_offset >= start_offset &&
     
    22732644                        type = ELF32_R_TYPE(rel->r_info);
    22742645                        addend = rel->r_addend;
     2646                        reloc_offset = rel->r_offset - start_offset;
    22752647                        switch(type) {
    22762648                        case R_SPARC_32:
    22772649                            fprintf(outfile, "    *(uint32_t *)(gen_code_ptr + %d) = %s + %d;\n",
    2278                                     rel->r_offset - start_offset, name, addend);
     2650                                    reloc_offset, name, addend);
    22792651                            break;
    22802652                        case R_SPARC_HI22:
     
    22842656                                    " & ~0x3fffff) "
    22852657                                    " | (((%s + %d) >> 10) & 0x3fffff);\n",
    2286                                     rel->r_offset - start_offset,
    2287                                     rel->r_offset - start_offset,
    2288                                     name, addend);
     2658                                    reloc_offset, reloc_offset, name, addend);
    22892659                            break;
    22902660                        case R_SPARC_LO10:
     
    22942664                                    " & ~0x3ff) "
    22952665                                    " | ((%s + %d) & 0x3ff);\n",
    2296                                     rel->r_offset - start_offset,
    2297                                     rel->r_offset - start_offset,
    2298                                     name, addend);
     2666                                    reloc_offset, reloc_offset, name, addend);
    22992667                            break;
    23002668                        case R_SPARC_WDISP30:
     
    23052673                                    " | ((((%s + %d) - (long)(gen_code_ptr + %d))>>2) "
    23062674                                    "    & 0x3fffffff);\n",
    2307                                     rel->r_offset - start_offset,
    2308                                     rel->r_offset - start_offset,
    2309                                     name, addend,
    2310                                     rel->r_offset - start_offset);
     2675                                    reloc_offset, reloc_offset, name, addend,
     2676                                    reloc_offset);
    23112677                            break;
     2678                        case R_SPARC_WDISP22:
     2679                            fprintf(outfile,
     2680                                    "    *(uint32_t *)(gen_code_ptr + %d) = "
     2681                                    "((*(uint32_t *)(gen_code_ptr + %d)) "
     2682                                    " & ~0x3fffff) "
     2683                                    " | ((((%s + %d) - (long)(gen_code_ptr + %d))>>2) "
     2684                                    "    & 0x3fffff);\n",
     2685                                    rel->r_offset - start_offset,
     2686                                    rel->r_offset - start_offset,
     2687                                    name, addend,
     2688                                    rel->r_offset - start_offset);
     2689                            break;
    23122690                        default:
    23132691                            error("unsupported sparc relocation (%d)", type);
     
    23212699                int type;
    23222700                int addend;
     2701                int reloc_offset;
    23232702                for(i = 0, rel = relocs;i < nb_relocs; i++, rel++) {
    23242703                    if (rel->r_offset >= start_offset &&
     
    23262705                        sym_name = strtab + symtab[ELF64_R_SYM(rel->r_info)].st_name;
    23272706                        get_reloc_expr(name, sizeof(name), sym_name);
    2328                         type = ELF64_R_TYPE(rel->r_info);
     2707                        type = ELF32_R_TYPE(rel->r_info);
    23292708                        addend = rel->r_addend;
     2709                        reloc_offset = rel->r_offset - start_offset;
    23302710                        switch(type) {
    23312711                        case R_SPARC_32:
    23322712                            fprintf(outfile, "    *(uint32_t *)(gen_code_ptr + %d) = %s + %d;\n",
    2333                                     rel->r_offset - start_offset, name, addend);
     2713                                    reloc_offset, name, addend);
    23342714                            break;
    23352715                        case R_SPARC_HI22:
     
    23392719                                    " & ~0x3fffff) "
    23402720                                    " | (((%s + %d) >> 10) & 0x3fffff);\n",
    2341                                     rel->r_offset - start_offset,
    2342                                     rel->r_offset - start_offset,
    2343                                     name, addend);
     2721                                    reloc_offset, reloc_offset, name, addend);
    23442722                            break;
    23452723                        case R_SPARC_LO10:
     
    23492727                                    " & ~0x3ff) "
    23502728                                    " | ((%s + %d) & 0x3ff);\n",
    2351                                     rel->r_offset - start_offset,
    2352                                     rel->r_offset - start_offset,
    2353                                     name, addend);
     2729                                    reloc_offset, reloc_offset, name, addend);
     2730                            break;
     2731                        case R_SPARC_OLO10:
     2732                            addend += ELF64_R_TYPE_DATA (rel->r_info);
     2733                            fprintf(outfile,
     2734                                    "    *(uint32_t *)(gen_code_ptr + %d) = "
     2735                                    "((*(uint32_t *)(gen_code_ptr + %d)) "
     2736                                    " & ~0x3ff) "
     2737                                    " | ((%s + %d) & 0x3ff);\n",
     2738                                    reloc_offset, reloc_offset, name, addend);
    23542739                            break;
    23552740                        case R_SPARC_WDISP30:
     
    23602745                                    " | ((((%s + %d) - (long)(gen_code_ptr + %d))>>2) "
    23612746                                    "    & 0x3fffffff);\n",
    2362                                     rel->r_offset - start_offset,
    2363                                     rel->r_offset - start_offset,
    2364                                     name, addend,
    2365                                     rel->r_offset - start_offset);
     2747                                    reloc_offset, reloc_offset, name, addend,
     2748                                    reloc_offset);
    23662749                            break;
     2750                        case R_SPARC_WDISP22:
     2751                            fprintf(outfile,
     2752                                    "    *(uint32_t *)(gen_code_ptr + %d) = "
     2753                                    "((*(uint32_t *)(gen_code_ptr + %d)) "
     2754                                    " & ~0x3fffff) "
     2755                                    " | ((((%s + %d) - (long)(gen_code_ptr + %d))>>2) "
     2756                                    "    & 0x3fffff);\n",
     2757                                    reloc_offset, reloc_offset, name, addend,
     2758                                    reloc_offset);
     2759                            break;
    23672760                        default:
    2368                             error("unsupported sparc64 relocation (%d)", type);
     2761                            error("unsupported sparc64 relocation (%d) for symbol %s", type, name);
    23692762                        }
    23702763                    }
     
    23762769                int type;
    23772770                int addend;
    2378 
     2771                int reloc_offset;
     2772                uint32_t insn;
     2773
     2774                insn = get32((uint32_t *)(p_start + 4));
     2775                /* If prologue ends in sub sp, sp, #const then assume
     2776                   op has a stack frame and needs the frame pointer.  */
     2777                if ((insn & 0xffffff00) == 0xe24dd000) {
     2778                    int i;
     2779                    uint32_t opcode;
     2780                    opcode = 0xe28db000; /* add fp, sp, #0.  */
     2781#if 0
     2782/* ??? Need to undo the extra stack adjustment at the end of the op.
     2783   For now just leave the stack misaligned and hope it doesn't break anything
     2784   too important.  */
     2785                    if ((insn & 4) != 0) {
     2786                        /* Preserve doubleword stack alignment.  */
     2787                        fprintf(outfile,
     2788                                "    *(uint32_t *)(gen_code_ptr + 4)= 0x%x;\n",
     2789                                insn + 4);
     2790                        opcode -= 4;
     2791                    }
     2792#endif
     2793                    insn = get32((uint32_t *)(p_start - 4));
     2794                    /* Calculate the size of the saved registers,
     2795                       excluding pc.  */
     2796                    for (i = 0; i < 15; i++) {
     2797                        if (insn & (1 << i))
     2798                            opcode += 4;
     2799                    }
     2800                    fprintf(outfile,
     2801                            "    *(uint32_t *)gen_code_ptr = 0x%x;\n", opcode);
     2802                }
    23792803                arm_emit_ldr_info(name, start_offset, outfile, p_start, p_end,
    23802804                                  relocs, nb_relocs);
     
    23902814                    type = ELF32_R_TYPE(rel->r_info);
    23912815                    addend = get32((uint32_t *)(text + rel->r_offset));
     2816                    reloc_offset = rel->r_offset - start_offset;
    23922817                    switch(type) {
    23932818                    case R_ARM_ABS32:
    23942819                        fprintf(outfile, "    *(uint32_t *)(gen_code_ptr + %d) = %s + %d;\n",
    2395                                 rel->r_offset - start_offset, name, addend);
     2820                                reloc_offset, name, addend);
    23962821                        break;
    23972822                    case R_ARM_PC24:
     2823                    case R_ARM_JUMP24:
     2824                    case R_ARM_CALL:
    23982825                        fprintf(outfile, "    arm_reloc_pc24((uint32_t *)(gen_code_ptr + %d), 0x%x, %s);\n",
    2399                                 rel->r_offset - start_offset, addend, name);
     2826                                reloc_offset, addend, name);
    24002827                        break;
    24012828                    default:
     
    24102837                int type;
    24112838                int addend;
     2839                int reloc_offset;
    24122840                Elf32_Sym *sym;
    24132841                for(i = 0, rel = relocs;i < nb_relocs; i++, rel++) {
     
    24192847                    type = ELF32_R_TYPE(rel->r_info);
    24202848                    addend = get32((uint32_t *)(text + rel->r_offset)) + rel->r_addend;
     2849                    reloc_offset = rel->r_offset - start_offset;
    24212850                    switch(type) {
    24222851                    case R_68K_32:
    24232852                        fprintf(outfile, "    /* R_68K_32 RELOC, offset %x */\n", rel->r_offset) ;
    24242853                        fprintf(outfile, "    *(uint32_t *)(gen_code_ptr + %d) = %s + %#x;\n",
    2425                                 rel->r_offset - start_offset, name, addend );
     2854                                reloc_offset, name, addend );
    24262855                        break;
    24272856                    case R_68K_PC32:
    24282857                        fprintf(outfile, "    /* R_68K_PC32 RELOC, offset %x */\n", rel->r_offset);
    24292858                        fprintf(outfile, "    *(uint32_t *)(gen_code_ptr + %d) = %s - (long)(gen_code_ptr + %#x) + %#x;\n",
    2430                                 rel->r_offset - start_offset, name, rel->r_offset - start_offset, /*sym->st_value+*/ addend);
     2859                                reloc_offset, name, reloc_offset, /*sym->st_value+*/ addend);
    24312860                        break;
    24322861                    default:
     
    24982927    } else {
    24992928        /* generate big code generation switch */
     2929
     2930#ifdef HOST_ARM
     2931        /* We need to know the size of all the ops so we can figure out when
     2932           to emit constant pools.  This must be consistent with opc.h.  */
     2933fprintf(outfile,
     2934"static const uint32_t arm_opc_size[] = {\n"
     2935"  0,\n" /* end */
     2936"  0,\n" /* nop */
     2937"  0,\n" /* nop1 */
     2938"  0,\n" /* nop2 */
     2939"  0,\n"); /* nop3 */
     2940        for(i = 0, sym = symtab; i < nb_syms; i++, sym++) {
     2941            const char *name;
     2942            name = get_sym_name(sym);
     2943            if (strstart(name, OP_PREFIX, NULL)) {
     2944                fprintf(outfile, "  %d,\n", sym->st_size);
     2945            }
     2946        }
     2947fprintf(outfile,
     2948"};\n");
     2949#endif
     2950
    25002951fprintf(outfile,
    25012952"int dyngen_code(uint8_t *gen_code_buf,\n"
     
    25082959
    25092960#ifdef HOST_ARM
     2961/* Arm is tricky because it uses constant pools for loading immediate values.
     2962   We assume (and require) each function is code followed by a constant pool.
     2963   All the ops are small so this should be ok.  For each op we figure
     2964   out how much "spare" range we have in the load instructions.  This allows
     2965   us to insert subsequent ops in between the op and the constant pool,
     2966   eliminating the neeed to jump around the pool.
     2967
     2968   We currently generate:
     2969   
     2970   [ For this example we assume merging would move op1_pool out of range.
     2971     In practice we should be able to combine many ops before the offset
     2972     limits are reached. ]
     2973   op1_code;
     2974   op2_code;
     2975   goto op3;
     2976   op2_pool;
     2977   op1_pool;
     2978op3:
     2979   op3_code;
     2980   ret;
     2981   op3_pool;
     2982
     2983   Ideally we'd put op1_pool before op2_pool, but that requires two passes.
     2984 */
    25102985fprintf(outfile,
    25112986"    uint8_t *last_gen_code_ptr = gen_code_buf;\n"
    25122987"    LDREntry *arm_ldr_ptr = arm_ldr_table;\n"
    2513 "    uint32_t *arm_data_ptr = arm_data_table;\n");
     2988"    uint32_t *arm_data_ptr = arm_data_table + ARM_LDR_TABLE_SIZE;\n"
     2989/* Initialise the parmissible pool offset to an arbitary large value.  */
     2990"    uint8_t *arm_pool_ptr = gen_code_buf + 0x1000000;\n");
     2991#endif
     2992#ifdef HOST_IA64
     2993    {
     2994        long addend, not_first = 0;
     2995        unsigned long sym_idx;
     2996        int index, max_index;
     2997        const char *sym_name;
     2998        EXE_RELOC *rel;
     2999
     3000        max_index = -1;
     3001        for (i = 0, rel = relocs;i < nb_relocs; i++, rel++) {
     3002            sym_idx = ELF64_R_SYM(rel->r_info);
     3003            sym_name = (strtab + symtab[sym_idx].st_name);
     3004            if (strstart(sym_name, "__op_gen_label", NULL))
     3005                continue;
     3006            if (ELF64_R_TYPE(rel->r_info) != R_IA64_PCREL21B)
     3007                continue;
     3008
     3009            addend = rel->r_addend;
     3010            index = get_plt_index(sym_name, addend);
     3011            if (index <= max_index)
     3012                continue;
     3013            max_index = index;
     3014            fprintf(outfile, "    extern void %s(void);\n", sym_name);
     3015        }
     3016
     3017        fprintf(outfile,
     3018                "    struct ia64_fixup *plt_fixes = NULL, "
     3019                "*ltoff_fixes = NULL;\n"
     3020                "    static long plt_target[] = {\n\t");
     3021
     3022        max_index = -1;
     3023        for (i = 0, rel = relocs;i < nb_relocs; i++, rel++) {
     3024            sym_idx = ELF64_R_SYM(rel->r_info);
     3025            sym_name = (strtab + symtab[sym_idx].st_name);
     3026            if (strstart(sym_name, "__op_gen_label", NULL))
     3027                continue;
     3028            if (ELF64_R_TYPE(rel->r_info) != R_IA64_PCREL21B)
     3029                continue;
     3030
     3031            addend = rel->r_addend;
     3032            index = get_plt_index(sym_name, addend);
     3033            if (index <= max_index)
     3034                continue;
     3035            max_index = index;
     3036
     3037            if (not_first)
     3038                fprintf(outfile, ",\n\t");
     3039            not_first = 1;
     3040            if (addend)
     3041                fprintf(outfile, "(long) &%s + %ld", sym_name, addend);
     3042            else
     3043                fprintf(outfile, "(long) &%s", sym_name);
     3044        }
     3045        fprintf(outfile, "\n    };\n"
     3046            "    unsigned int plt_offset[%u] = { 0 };\n", max_index + 1);
     3047    }
    25143048#endif
    25153049
     
    25233057
    25243058fprintf(outfile,
    2525 "    for(;;) {\n"
    2526 "        switch(*opc_ptr++) {\n"
    2527 );
     3059"    for(;;) {\n");
     3060
     3061#ifdef HOST_ARM
     3062/* Generate constant pool if needed */
     3063fprintf(outfile,
     3064"            if (gen_code_ptr + arm_opc_size[*opc_ptr] >= arm_pool_ptr) {\n"
     3065"                gen_code_ptr = arm_flush_ldr(gen_code_ptr, arm_ldr_table, "
     3066"arm_ldr_ptr, arm_data_ptr, arm_data_table + ARM_LDR_TABLE_SIZE, 1);\n"
     3067"                last_gen_code_ptr = gen_code_ptr;\n"
     3068"                arm_ldr_ptr = arm_ldr_table;\n"
     3069"                arm_data_ptr = arm_data_table + ARM_LDR_TABLE_SIZE;\n"
     3070"                arm_pool_ptr = gen_code_ptr + 0x1000000;\n"
     3071"            }\n");
     3072#endif
     3073
     3074fprintf(outfile,
     3075"        switch(*opc_ptr++) {\n");
    25283076
    25293077        for(i = 0, sym = symtab; i < nb_syms; i++, sym++) {
     
    25593107"        }\n");
    25603108
    2561 #ifdef HOST_ARM
    2562 /* generate constant table if needed */
    2563 fprintf(outfile,
    2564 "        if ((gen_code_ptr - last_gen_code_ptr) >= (MAX_FRAG_SIZE - MAX_OP_SIZE)) {\n"
    2565 "            gen_code_ptr = arm_flush_ldr(gen_code_ptr, arm_ldr_table, arm_ldr_ptr, arm_data_table, arm_data_ptr, 1);\n"
    2566 "            last_gen_code_ptr = gen_code_ptr;\n"
    2567 "            arm_ldr_ptr = arm_ldr_table;\n"
    2568 "            arm_data_ptr = arm_data_table;\n"
    2569 "        }\n");         
    2570 #endif
    2571 
    25723109
    25733110fprintf(outfile,
     
    25753112" the_end:\n"
    25763113);
     3114#ifdef HOST_IA64
     3115    fprintf(outfile,
     3116            "    {\n"
     3117            "      extern char code_gen_buffer[];\n"
     3118            "      ia64_apply_fixes(&gen_code_ptr, ltoff_fixes, "
     3119            "(uint64_t) code_gen_buffer + 2*(1<<20), plt_fixes,\n\t\t\t"
     3120            "sizeof(plt_target)/sizeof(plt_target[0]),\n\t\t\t"
     3121            "plt_target, plt_offset);\n    }\n");
     3122#endif
    25773123
    25783124/* generate some code patching */
    25793125#ifdef HOST_ARM
    2580 fprintf(outfile, "gen_code_ptr = arm_flush_ldr(gen_code_ptr, arm_ldr_table, arm_ldr_ptr, arm_data_table, arm_data_ptr, 0);\n");
     3126fprintf(outfile,
     3127"if (arm_data_ptr != arm_data_table + ARM_LDR_TABLE_SIZE)\n"
     3128"    gen_code_ptr = arm_flush_ldr(gen_code_ptr, arm_ldr_table, "
     3129"arm_ldr_ptr, arm_data_ptr, arm_data_table + ARM_LDR_TABLE_SIZE, 0);\n");
    25813130#endif
    25823131    /* flush instruction cache */
     
    26413190    return 0;
    26423191}
     3192
     3193/* bird added: */
     3194/*
     3195 * Local Variables:
     3196 *  mode: c
     3197 *  c-file-style: k&r
     3198 *  c-basic-offset: 4
     3199 *  tab-width: 4
     3200 *  indent-tabs-mode: t
     3201 * End:
     3202 */
     3203
  • trunk/src/recompiler/dyngen.h

    r1 r2422  
    2020
    2121int __op_param1, __op_param2, __op_param3;
    22 int __op_gen_label1, __op_gen_label2, __op_gen_label3;
     22#if defined(__sparc__) || defined(__arm__)
     23  void __op_gen_label1(){}
     24  void __op_gen_label2(){}
     25  void __op_gen_label3(){}
     26#else
     27  int __op_gen_label1, __op_gen_label2, __op_gen_label3;
     28#endif
    2329int __op_jmp0, __op_jmp1, __op_jmp2, __op_jmp3;
    2430
     
    4450static inline void flush_icache_range(unsigned long start, unsigned long stop)
    4551{
     52    while (start < stop) {
     53        asm volatile ("fc %0" :: "r"(start));
     54        start += 32;
     55    }
     56    asm volatile (";;sync.i;;srlz.i;;");
    4657}
    4758#endif
     
    5566    unsigned long p;
    5667
    57     p = start & ~(MIN_CACHE_LINE_SIZE - 1);
     68    start &= ~(MIN_CACHE_LINE_SIZE - 1);
    5869    stop = (stop + MIN_CACHE_LINE_SIZE - 1) & ~(MIN_CACHE_LINE_SIZE - 1);
    5970   
     
    135146#ifdef __arm__
    136147
    137 #define MAX_OP_SIZE    (128 * 4) /* in bytes */
    138 /* max size of the code that can be generated without calling arm_flush_ldr */
    139 #define MAX_FRAG_SIZE  (1024 * 4)
    140 //#define MAX_FRAG_SIZE  (135 * 4) /* for testing */
     148#define ARM_LDR_TABLE_SIZE 1024
    141149
    142150typedef struct LDREntry {
    143151    uint8_t *ptr;
    144152    uint32_t *data_ptr;
     153    unsigned type:2;
    145154} LDREntry;
    146155
    147156static LDREntry arm_ldr_table[1024];
    148 static uint32_t arm_data_table[1024];
     157static uint32_t arm_data_table[ARM_LDR_TABLE_SIZE];
    149158
    150159extern char exec_loop;
     
    165174    uint8_t *data_ptr;
    166175    uint32_t insn;
     176    uint32_t mask;
    167177 
    168     data_size = (uint8_t *)data_end - (uint8_t *)data_start;
     178    data_size = (data_end - data_start) << 2;
    169179
    170180    if (gen_jmp) {
     
    188198            (unsigned long)data_ptr -
    189199            (unsigned long)ptr - 8;
    190         insn = *ptr & ~(0xfff | 0x00800000);
    191200        if (offset < 0) {
    192             offset = - offset;
    193         } else {
    194             insn |= 0x00800000;
    195         }
    196         if (offset > 0xfff) {
    197             fprintf(stderr, "Error ldr offset\n");
     201            fprintf(stderr, "Negative constant pool offset\n");
    198202            abort();
    199203        }
    200         insn |= offset;
     204        switch (le->type) {
     205          case 0: /* ldr */
     206            mask = ~0x00800fff;
     207            if (offset >= 4096) {
     208                fprintf(stderr, "Bad ldr offset\n");
     209                abort();
     210            }
     211            break;
     212          case 1: /* ldc */
     213            mask = ~0x008000ff;
     214            if (offset >= 1024 ) {
     215                fprintf(stderr, "Bad ldc offset\n");
     216                abort();
     217            }
     218            break;
     219          case 2: /* add */
     220            mask = ~0xfff;
     221            if (offset >= 1024 ) {
     222                fprintf(stderr, "Bad add offset\n");
     223                abort();
     224            }
     225            break;
     226          default:
     227            fprintf(stderr, "Bad pc relative fixup\n");
     228            abort();
     229          }
     230        insn = *ptr & mask;
     231        switch (le->type) {
     232          case 0: /* ldr */
     233            insn |= offset | 0x00800000;
     234            break;
     235          case 1: /* ldc */
     236            insn |= (offset >> 2) | 0x00800000;
     237            break;
     238          case 2: /* add */
     239            insn |= (offset >> 2) | 0xf00;
     240            break;
     241          }
    201242        *ptr = insn;
    202243    }
     
    205246
    206247#endif /* __arm__ */
     248
     249#ifdef __ia64
     250
     251
     252/* Patch instruction with "val" where "mask" has 1 bits. */
     253static inline void ia64_patch (uint64_t insn_addr, uint64_t mask, uint64_t val)
     254{
     255    uint64_t m0, m1, v0, v1, b0, b1, *b = (uint64_t *) (insn_addr & -16);
     256#   define insn_mask ((1UL << 41) - 1)
     257    unsigned long shift;
     258
     259    b0 = b[0]; b1 = b[1];
     260    shift = 5 + 41 * (insn_addr % 16); /* 5 template, 3 x 41-bit insns */
     261    if (shift >= 64) {
     262        m1 = mask << (shift - 64);
     263        v1 = val << (shift - 64);
     264    } else {
     265        m0 = mask << shift; m1 = mask >> (64 - shift);
     266        v0 = val  << shift; v1 = val >> (64 - shift);
     267        b[0] = (b0 & ~m0) | (v0 & m0);
     268    }
     269    b[1] = (b1 & ~m1) | (v1 & m1);
     270}
     271
     272static inline void ia64_patch_imm60 (uint64_t insn_addr, uint64_t val)
     273{
     274        ia64_patch(insn_addr,
     275                   0x011ffffe000UL,
     276                   (  ((val & 0x0800000000000000UL) >> 23) /* bit 59 -> 36 */
     277                    | ((val & 0x00000000000fffffUL) << 13) /* bit 0 -> 13 */));
     278        ia64_patch(insn_addr - 1, 0x1fffffffffcUL, val >> 18);
     279}
     280
     281static inline void ia64_imm64 (void *insn, uint64_t val)
     282{
     283    /* Ignore the slot number of the relocation; GCC and Intel
     284       toolchains differed for some time on whether IMM64 relocs are
     285       against slot 1 (Intel) or slot 2 (GCC).  */
     286    uint64_t insn_addr = (uint64_t) insn & ~3UL;
     287
     288    ia64_patch(insn_addr + 2,
     289               0x01fffefe000UL,
     290               (  ((val & 0x8000000000000000UL) >> 27) /* bit 63 -> 36 */
     291                | ((val & 0x0000000000200000UL) <<  0) /* bit 21 -> 21 */
     292                | ((val & 0x00000000001f0000UL) <<  6) /* bit 16 -> 22 */
     293                | ((val & 0x000000000000ff80UL) << 20) /* bit  7 -> 27 */
     294                | ((val & 0x000000000000007fUL) << 13) /* bit  0 -> 13 */)
     295            );
     296    ia64_patch(insn_addr + 1, 0x1ffffffffffUL, val >> 22);
     297}
     298
     299static inline void ia64_imm60b (void *insn, uint64_t val)
     300{
     301    /* Ignore the slot number of the relocation; GCC and Intel
     302       toolchains differed for some time on whether IMM64 relocs are
     303       against slot 1 (Intel) or slot 2 (GCC).  */
     304    uint64_t insn_addr = (uint64_t) insn & ~3UL;
     305
     306    if (val + ((uint64_t) 1 << 59) >= (1UL << 60))
     307        fprintf(stderr, "%s: value %ld out of IMM60 range\n",
     308                __FUNCTION__, (int64_t) val);
     309    ia64_patch_imm60(insn_addr + 2, val);
     310}
     311
     312static inline void ia64_imm22 (void *insn, uint64_t val)
     313{
     314    if (val + (1 << 21) >= (1 << 22))
     315        fprintf(stderr, "%s: value %li out of IMM22 range\n",
     316                __FUNCTION__, (int64_t)val);
     317    ia64_patch((uint64_t) insn, 0x01fffcfe000UL,
     318               (  ((val & 0x200000UL) << 15) /* bit 21 -> 36 */
     319                | ((val & 0x1f0000UL) <<  6) /* bit 16 -> 22 */
     320                | ((val & 0x00ff80UL) << 20) /* bit  7 -> 27 */
     321                | ((val & 0x00007fUL) << 13) /* bit  0 -> 13 */));
     322}
     323
     324/* Like ia64_imm22(), but also clear bits 20-21.  For addl, this has
     325   the effect of turning "addl rX=imm22,rY" into "addl
     326   rX=imm22,r0".  */
     327static inline void ia64_imm22_r0 (void *insn, uint64_t val)
     328{
     329    if (val + (1 << 21) >= (1 << 22))
     330        fprintf(stderr, "%s: value %li out of IMM22 range\n",
     331                __FUNCTION__, (int64_t)val);
     332    ia64_patch((uint64_t) insn, 0x01fffcfe000UL | (0x3UL << 20),
     333               (  ((val & 0x200000UL) << 15) /* bit 21 -> 36 */
     334                | ((val & 0x1f0000UL) <<  6) /* bit 16 -> 22 */
     335                | ((val & 0x00ff80UL) << 20) /* bit  7 -> 27 */
     336                | ((val & 0x00007fUL) << 13) /* bit  0 -> 13 */));
     337}
     338
     339static inline void ia64_imm21b (void *insn, uint64_t val)
     340{
     341    if (val + (1 << 20) >= (1 << 21))
     342        fprintf(stderr, "%s: value %li out of IMM21b range\n",
     343                __FUNCTION__, (int64_t)val);
     344    ia64_patch((uint64_t) insn, 0x11ffffe000UL,
     345               (  ((val & 0x100000UL) << 16) /* bit 20 -> 36 */
     346                | ((val & 0x0fffffUL) << 13) /* bit  0 -> 13 */));
     347}
     348
     349static inline void ia64_nop_b (void *insn)
     350{
     351    ia64_patch((uint64_t) insn, (1UL << 41) - 1, 2UL << 37);
     352}
     353
     354static inline void ia64_ldxmov(void *insn, uint64_t val)
     355{
     356    if (val + (1 << 21) < (1 << 22))
     357        ia64_patch((uint64_t) insn, 0x1fff80fe000UL, 8UL << 37);
     358}
     359
     360static inline int ia64_patch_ltoff(void *insn, uint64_t val,
     361                                   int relaxable)
     362{
     363    if (relaxable && (val + (1 << 21) < (1 << 22))) {
     364        ia64_imm22_r0(insn, val);
     365        return 0;
     366    }
     367    return 1;
     368}
     369
     370struct ia64_fixup {
     371    struct ia64_fixup *next;
     372    void *addr;                 /* address that needs to be patched */
     373    long value;
     374};
     375
     376#define IA64_PLT(insn, plt_index)                       \
     377do {                                                    \
     378    struct ia64_fixup *fixup = alloca(sizeof(*fixup));  \
     379    fixup->next = plt_fixes;                            \
     380    plt_fixes = fixup;                                  \
     381    fixup->addr = (insn);                               \
     382    fixup->value = (plt_index);                         \
     383    plt_offset[(plt_index)] = 1;                        \
     384} while (0)
     385
     386#define IA64_LTOFF(insn, val, relaxable)                        \
     387do {                                                            \
     388    if (ia64_patch_ltoff(insn, val, relaxable)) {               \
     389        struct ia64_fixup *fixup = alloca(sizeof(*fixup));      \
     390        fixup->next = ltoff_fixes;                              \
     391        ltoff_fixes = fixup;                                    \
     392        fixup->addr = (insn);                                   \
     393        fixup->value = (val);                                   \
     394    }                                                           \
     395} while (0)
     396
     397static inline void ia64_apply_fixes (uint8_t **gen_code_pp,
     398                                     struct ia64_fixup *ltoff_fixes,
     399                                     uint64_t gp,
     400                                     struct ia64_fixup *plt_fixes,
     401                                     int num_plts,
     402                                     unsigned long *plt_target,
     403                                     unsigned int *plt_offset)
     404{
     405    static const uint8_t plt_bundle[] = {
     406        0x04, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, /* nop 0; movl r1=GP */
     407        0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x60,
     408
     409        0x05, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, /* nop 0; brl IP */
     410        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0
     411    };
     412    uint8_t *gen_code_ptr = *gen_code_pp, *plt_start, *got_start, *vp;
     413    struct ia64_fixup *fixup;
     414    unsigned int offset = 0;
     415    struct fdesc {
     416        long ip;
     417        long gp;
     418    } *fdesc;
     419    int i;
     420
     421    if (plt_fixes) {
     422        plt_start = gen_code_ptr;
     423
     424        for (i = 0; i < num_plts; ++i) {
     425            if (plt_offset[i]) {
     426                plt_offset[i] = offset;
     427                offset += sizeof(plt_bundle);
     428
     429                fdesc = (struct fdesc *) plt_target[i];
     430                memcpy(gen_code_ptr, plt_bundle, sizeof(plt_bundle));
     431                ia64_imm64 (gen_code_ptr + 0x02, fdesc->gp);
     432                ia64_imm60b(gen_code_ptr + 0x12,
     433                            (fdesc->ip - (long) (gen_code_ptr + 0x10)) >> 4);
     434                gen_code_ptr += sizeof(plt_bundle);
     435            }
     436        }
     437
     438        for (fixup = plt_fixes; fixup; fixup = fixup->next)
     439            ia64_imm21b(fixup->addr,
     440                        ((long) plt_start + plt_offset[fixup->value]
     441                         - ((long) fixup->addr & ~0xf)) >> 4);
     442    }
     443
     444    got_start = gen_code_ptr;
     445
     446    /* First, create the GOT: */
     447    for (fixup = ltoff_fixes; fixup; fixup = fixup->next) {
     448        /* first check if we already have this value in the GOT: */
     449        for (vp = got_start; vp < gen_code_ptr; ++vp)
     450            if (*(uint64_t *) vp == fixup->value)
     451                break;
     452        if (vp == gen_code_ptr) {
     453            /* Nope, we need to put the value in the GOT: */
     454            *(uint64_t *) vp = fixup->value;
     455            gen_code_ptr += 8;
     456        }
     457        ia64_imm22(fixup->addr, (long) vp - gp);
     458    }
     459    /* Keep code ptr aligned. */
     460    if ((long) gen_code_ptr & 15)
     461        gen_code_ptr += 8;
     462    *gen_code_pp = gen_code_ptr;
     463}
     464
     465#endif
  • trunk/src/recompiler/elf.h

    r1 r2422  
    3232#define PT_HIPROC  0x7fffffff
    3333#define PT_MIPS_REGINFO         0x70000000
     34#define PT_MIPS_OPTIONS         0x70000001
    3435
    3536/* Flags in the e_flags field of the header */
     37/* MIPS architecture level. */
     38#define EF_MIPS_ARCH_1          0x00000000      /* -mips1 code.  */
     39#define EF_MIPS_ARCH_2          0x10000000      /* -mips2 code.  */
     40#define EF_MIPS_ARCH_3          0x20000000      /* -mips3 code.  */
     41#define EF_MIPS_ARCH_4          0x30000000      /* -mips4 code.  */
     42#define EF_MIPS_ARCH_5          0x40000000      /* -mips5 code.  */
     43#define EF_MIPS_ARCH_32         0x50000000      /* MIPS32 code.  */
     44#define EF_MIPS_ARCH_64         0x60000000      /* MIPS64 code.  */
     45
     46/* The ABI of a file. */
     47#define EF_MIPS_ABI_O32         0x00001000      /* O32 ABI.  */
     48#define EF_MIPS_ABI_O64         0x00002000      /* O32 extended for 64 bit.  */
     49
    3650#define EF_MIPS_NOREORDER 0x00000001
    3751#define EF_MIPS_PIC       0x00000002
    3852#define EF_MIPS_CPIC      0x00000004
     53#define EF_MIPS_ABI2            0x00000020
     54#define EF_MIPS_OPTIONS_FIRST   0x00000080
     55#define EF_MIPS_32BITMODE       0x00000100
     56#define EF_MIPS_ABI             0x0000f000
    3957#define EF_MIPS_ARCH      0xf0000000
    4058
     
    210228#define ELF64_R_SYM(i)                  ((i) >> 32)
    211229#define ELF64_R_TYPE(i)                 ((i) & 0xffffffff)
     230#define ELF64_R_TYPE_DATA(i)            (((ELF64_R_TYPE(i) >> 8) ^ 0x00800000) - 0x00800000)
    212231
    213232#define R_386_NONE      0
     
    309328#define R_SPARC_11              31
    310329#define R_SPARC_64              32
     330#define R_SPARC_OLO10           33
    311331#define R_SPARC_WDISP16         40
    312332#define R_SPARC_WDISP19         41
     
    483503#define R_ARM_GOT32             26      /* 32 bit GOT entry */
    484504#define R_ARM_PLT32             27      /* 32 bit PLT address */
     505#define R_ARM_CALL              28
     506#define R_ARM_JUMP24            29
    485507#define R_ARM_GNU_VTENTRY       100
    486508#define R_ARM_GNU_VTINHERIT     101
  • trunk/src/recompiler/exec-all.h

    r1 r2422  
    2525
    2626#ifdef VBOX
    27 #include <VBox/tm.h>
    28 #ifndef LOG_GROUP
    29 #define LOG_GROUP LOG_GROUP_REM
    30 #endif
    31 #include <VBox/log.h>
    32 #include "REMInternal.h"
     27# include <VBox/tm.h>
     28# include <VBox/pgm.h> /* PGM_DYNAMIC_RAM_ALLOC */
     29# ifndef LOG_GROUP
     30#  define LOG_GROUP LOG_GROUP_REM
     31# endif
     32# include <VBox/log.h>
     33# include "REMInternal.h"
     34# include <VBox/vm.h>
    3335#endif /* VBOX */
    3436
     
    4042#endif
    4143
    42 #if GCC_MAJOR < 3
     44#if __GNUC__ < 3
    4345#define __builtin_expect(x, n) (x)
    4446#endif
     
    7375extern uint8_t gen_opc_cc_op[OPC_BUF_SIZE];
    7476extern uint8_t gen_opc_instr_start[OPC_BUF_SIZE];
     77extern target_ulong gen_opc_jump_pc[2];
     78extern uint32_t gen_opc_hflags[OPC_BUF_SIZE];
    7579
    7680typedef void (GenOpFunc)(void);
     
    102106                           void *puc);
    103107void cpu_resume_from_signal(CPUState *env1, void *puc);
    104 void cpu_exec_init(void);
    105 int page_unprotect(unsigned long address, unsigned long pc, void *puc);
     108void cpu_exec_init(CPUState *env);
     109int page_unprotect(target_ulong address, unsigned long pc, void *puc);
    106110void tb_invalidate_phys_page_range(target_ulong start, target_ulong end,
    107111                                   int is_cpu_write_access);
     
    109113void tlb_flush_page(CPUState *env, target_ulong addr);
    110114void tlb_flush(CPUState *env, int flush_global);
    111 int tlb_set_page(CPUState *env, target_ulong vaddr,
    112                  target_phys_addr_t paddr, int prot,
    113                  int is_user, int is_softmmu);
    114 
     115int tlb_set_page_exec(CPUState *env, target_ulong vaddr,
     116                      target_phys_addr_t paddr, int prot,
     117                      int is_user, int is_softmmu);
     118static inline int tlb_set_page(CPUState *env, target_ulong vaddr,
     119                               target_phys_addr_t paddr, int prot,
     120                               int is_user, int is_softmmu)
     121{
     122    if (prot & PAGE_READ)
     123        prot |= PAGE_EXEC;
     124    return tlb_set_page_exec(env, vaddr, paddr, prot, is_user, is_softmmu);
     125}
    115126
    116127#define CODE_GEN_MAX_SIZE        65536
    117128#define CODE_GEN_ALIGN           16 /* must be >= of the size of a icache line */
    118 
    119 #define CODE_GEN_HASH_BITS     15
    120 #define CODE_GEN_HASH_SIZE     (1 << CODE_GEN_HASH_BITS)
    121129
    122130#define CODE_GEN_PHYS_HASH_BITS     15
     
    138146#if defined(__alpha__)
    139147#define CODE_GEN_BUFFER_SIZE     (2 * 1024 * 1024)
     148#elif defined(__ia64)
     149#define CODE_GEN_BUFFER_SIZE     (4 * 1024 * 1024)      /* range of addl */
    140150#elif defined(__powerpc__)
    141151#define CODE_GEN_BUFFER_SIZE     (6 * 1024 * 1024)
    142152#else
    143 #define CODE_GEN_BUFFER_SIZE     (8 * 1024 * 1024)
     153#define CODE_GEN_BUFFER_SIZE     (16 * 1024 * 1024)
    144154#endif
    145155
     
    183193
    184194    uint8_t *tc_ptr;    /* pointer to the translated code */
    185     struct TranslationBlock *hash_next; /* next matching tb for virtual address */
    186195    /* next matching tb for physical address. */
    187196    struct TranslationBlock *phys_hash_next;
     
    197206    uint16_t tb_jmp_offset[4]; /* offset of jump instruction */
    198207#else
     208# if defined(VBOX) && defined(__DARWIN__) && defined(__AMD64__)
     209#  error "First 4GB aren't reachable. jmp dword [tb_next] wont work."
     210# endif
    199211    uint32_t tb_next[2]; /* address of jump generated code */
    200212#endif
     
    207219} TranslationBlock;
    208220
    209 static inline unsigned int tb_hash_func(target_ulong pc)
    210 {
    211     return pc & (CODE_GEN_HASH_SIZE - 1);
     221static inline unsigned int tb_jmp_cache_hash_page(target_ulong pc)
     222{
     223    target_ulong tmp;
     224    tmp = pc ^ (pc >> (TARGET_PAGE_BITS - TB_JMP_PAGE_BITS));
     225    return (tmp >> TB_JMP_PAGE_BITS) & TB_JMP_PAGE_MASK;
     226}
     227
     228static inline unsigned int tb_jmp_cache_hash_func(target_ulong pc)
     229{
     230    target_ulong tmp;
     231    tmp = pc ^ (pc >> (TARGET_PAGE_BITS - TB_JMP_PAGE_BITS));
     232    return (((tmp >> TB_JMP_PAGE_BITS) & TB_JMP_PAGE_MASK) |
     233            (tmp & TB_JMP_ADDR_MASK));
    212234}
    213235
     
    219241TranslationBlock *tb_alloc(target_ulong pc);
    220242void tb_flush(CPUState *env);
    221 void tb_link(TranslationBlock *tb);
    222243void tb_link_phys(TranslationBlock *tb,
    223244                  target_ulong phys_pc, target_ulong phys_page2);
    224245
    225 extern TranslationBlock *tb_hash[CODE_GEN_HASH_SIZE];
    226246extern TranslationBlock *tb_phys_hash[CODE_GEN_PHYS_HASH_SIZE];
    227247
    228248extern uint8_t code_gen_buffer[CODE_GEN_BUFFER_SIZE];
    229249extern uint8_t *code_gen_ptr;
    230 
    231 /* find a translation block in the translation cache. If not found,
    232    return NULL and the pointer to the last element of the list in pptb */
    233 static inline TranslationBlock *tb_find(TranslationBlock ***pptb,
    234                                         target_ulong pc,
    235                                         target_ulong cs_base,
    236                                         unsigned int flags)
    237 {
    238     TranslationBlock **ptb, *tb;
    239     unsigned int h;
    240  
    241     h = tb_hash_func(pc);
    242     ptb = &tb_hash[h];
    243     for(;;) {
    244         tb = *ptb;
    245         if (!tb)
    246             break;
    247         if (tb->pc == pc && tb->cs_base == cs_base && tb->flags == flags)
    248             return tb;
    249         ptb = &tb->hash_next;
    250     }
    251     *pptb = ptb;
    252     return NULL;
    253 }
    254 
    255250
    256251#if defined(USE_DIRECT_JUMP)
     
    336331#endif
    337332
     333#define ASM_OP_LABEL_NAME(n, opname) \
     334    ASM_NAME(__op_label) #n "." ASM_NAME(opname)
     335
    338336#if defined(__powerpc__)
    339337
     
    342340do {\
    343341    asm volatile (ASM_DATA_SECTION\
    344                   ASM_NAME(__op_label) #n "." ASM_NAME(opname) ":\n"\
     342                  ASM_OP_LABEL_NAME(n, opname) ":\n"\
    345343                  ".long 1f\n"\
    346344                  ASM_PREVIOUS_SECTION \
     
    355353do {\
    356354    asm volatile (".section .data\n"\
    357                   ASM_NAME(__op_label) #n "." ASM_NAME(opname) ":\n"\
     355                  ASM_OP_LABEL_NAME(n, opname) ":\n"\
    358356                  ".long 1f\n"\
    359357                  ASM_PREVIOUS_SECTION \
     
    366364/* jump to next block operations (more portable code, does not need
    367365   cache flushing, but slower because of indirect jump) */
     366# ifdef VBOX /* bird: GCC4 (and Ming 3.4.x?) will remove the two unused static
     367                variables. I've added a dummy __asm__ statement which reference
     368                the two variables to prevent this. */
     369#  if __GNUC__ >= 4
     370#   define GOTO_TB(opname, tbparam, n)\
     371    do {\
     372        static void __attribute__((unused)) *dummy ## n = &&dummy_label ## n;\
     373        static void __attribute__((unused)) *__op_label ## n \
     374            __asm__(ASM_OP_LABEL_NAME(n, opname)) = &&label ## n;\
     375        __asm__ ("" : : "m" (__op_label ## n), "m" (dummy ## n));\
     376        goto *(void *)(uintptr_t)(((TranslationBlock *)tbparam)->tb_next[n]);\
     377    label ## n: ;\
     378    dummy_label ## n: ;\
     379    } while (0)
     380#  else
     381#   define GOTO_TB(opname, tbparam, n)\
     382    do {\
     383        static void __attribute__((unused)) *dummy ## n = &&dummy_label ## n;\
     384        static void __attribute__((unused)) *__op_label ## n \
     385            __asm__(ASM_OP_LABEL_NAME(n, opname)) = &&label ## n;\
     386        goto *(void *)(uintptr_t)(((TranslationBlock *)tbparam)->tb_next[n]);\
     387    label ## n: ;\
     388    dummy_label ## n: ;\
     389    } while (0)
     390#  endif
     391# else /* !VBOX */
    368392#define GOTO_TB(opname, tbparam, n)\
    369393do {\
    370394    static void __attribute__((unused)) *dummy ## n = &&dummy_label ## n;\
    371     static void __attribute__((unused)) *__op_label ## n = &&label ## n;\
     395    static void __attribute__((unused)) *__op_label ## n \
     396        __asm__(ASM_OP_LABEL_NAME(n, opname)) = &&label ## n;\
    372397    goto *(void *)(((TranslationBlock *)tbparam)->tb_next[n]);\
    373398label ## n: ;\
    374399dummy_label ## n: ;\
    375400} while (0)
    376 
    377 #endif
    378 
    379 /* XXX: will be suppressed */
    380 #define JUMP_TB(opname, tbparam, n, eip)\
    381 do {\
    382     GOTO_TB(opname, tbparam, n);\
    383     T0 = (long)(tbparam) + (n);\
    384     EIP = (int32_t)eip;\
    385     EXIT_TB();\
    386 } while (0)
     401# endif /* !VBOX */
     402
     403#endif
    387404
    388405extern CPUWriteMemoryFunc *io_mem_write[IO_MEM_NB_ENTRIES][4];
     
    505522#endif
    506523
     524#ifdef __ia64
     525#include <ia64intrin.h>
     526
     527static inline int testandset (int *p)
     528{
     529    return __sync_lock_test_and_set (p, 1);
     530}
     531#endif
     532
    507533typedef int spinlock_t;
    508534
     
    578604# ifdef VBOX
    579605target_ulong remR3PhysGetPhysicalAddressCode(CPUState *env, target_ulong addr, CPUTLBEntry *pTLBEntry);
     606#  if defined(PGM_DYNAMIC_RAM_ALLOC) && !defined(REM_PHYS_ADDR_IN_TLB)
    580607target_ulong remR3HCVirt2GCPhys(void *env, void *addr);
    581 # endif
     608#  endif
     609# endif
    582610/* NOTE: this function can trigger an exception */
    583611/* NOTE2: the returned address is not exactly the physical address: it
    584612   is the offset relative to phys_ram_base */
    585 /* XXX: i386 target specific */
    586613static inline target_ulong get_phys_addr_code(CPUState *env, target_ulong addr)
    587614{
     
    593620#elif defined (TARGET_PPC)
    594621    is_user = msr_pr;
     622#elif defined (TARGET_MIPS)
     623    is_user = ((env->hflags & MIPS_HFLAG_MODE) == MIPS_HFLAG_UM);
    595624#elif defined (TARGET_SPARC)
    596625    is_user = (env->psrs == 0);
    597 #else
    598 #error "Unimplemented !"
    599 #endif
    600     if (__builtin_expect(env->tlb_read[is_user][index].address !=
     626#elif defined (TARGET_ARM)
     627    is_user = ((env->uncached_cpsr & CPSR_M) == ARM_CPU_MODE_USR);
     628#elif defined (TARGET_SH4)
     629    is_user = ((env->sr & SR_MD) == 0);
     630#else
     631#error unimplemented CPU
     632#endif
     633    if (__builtin_expect(env->tlb_table[is_user][index].addr_code !=
    601634                         (addr & TARGET_PAGE_MASK), 0)) {
    602635        ldub_code(addr);
    603636    }
    604     pd = env->tlb_read[is_user][index].address & ~TARGET_PAGE_MASK;
    605     if (pd > IO_MEM_ROM) {
    606 #ifdef VBOX
     637    pd = env->tlb_table[is_user][index].addr_code & ~TARGET_PAGE_MASK;
     638    if (pd > IO_MEM_ROM && !(pd & IO_MEM_ROMD)) {
     639# ifdef VBOX
    607640        /* deal with non-MMIO access handlers. */
    608         return remR3PhysGetPhysicalAddressCode(env, addr, &env->tlb_read[is_user][index]);
    609 #else
     641        return remR3PhysGetPhysicalAddressCode(env, addr, &env->tlb_table[is_user][index]);
     642# else
    610643        cpu_abort(env, "Trying to execute code outside RAM or ROM at 0x%08lx\n", addr);
    611 #endif
     644# endif
    612645    }
    613 #ifdef VBOX
    614     return remR3HCVirt2GCPhys(env, (void *)(addr + env->tlb_read[is_user][index].addend));
    615 #else
    616     return addr + env->tlb_read[is_user][index].addend - (unsigned long)phys_ram_base;
    617 #endif
    618 }
    619 #endif
     646# if defined(VBOX) && defined(REM_PHYS_ADDR_IN_TLB)
     647    return addr + env->tlb_table[is_user][index].addend;
     648# elif defined(VBOX) && defined(PGM_DYNAMIC_RAM_ALLOC)
     649    return remR3HCVirt2GCPhys(env, (void *)(addr + env->tlb_table[is_user][index].addend));
     650# else
     651    return addr + env->tlb_table[is_user][index].addend - (unsigned long)phys_ram_base;
     652# endif
     653}
     654#endif
     655
     656
     657#ifdef USE_KQEMU
     658#define KQEMU_MODIFY_PAGE_MASK (0xff & ~(VGA_DIRTY_FLAG | CODE_DIRTY_FLAG))
     659
     660int kqemu_init(CPUState *env);
     661int kqemu_cpu_exec(CPUState *env);
     662void kqemu_flush_page(CPUState *env, target_ulong addr);
     663void kqemu_flush(CPUState *env, int global);
     664void kqemu_set_notdirty(CPUState *env, ram_addr_t ram_addr);
     665void kqemu_modify_page(CPUState *env, ram_addr_t ram_addr);
     666void kqemu_cpu_interrupt(CPUState *env);
     667void kqemu_record_dump(void);
     668
     669static inline int kqemu_is_ok(CPUState *env)
     670{
     671    return(env->kqemu_enabled &&
     672           (env->cr[0] & CR0_PE_MASK) &&
     673           !(env->hflags & HF_INHIBIT_IRQ_MASK) &&
     674           (env->eflags & IF_MASK) &&
     675           !(env->eflags & VM_MASK) &&
     676           (env->kqemu_enabled == 2 ||
     677            ((env->hflags & HF_CPL_MASK) == 3 &&
     678             (env->eflags & IOPL_MASK) != IOPL_MASK)));
     679}
     680
     681#endif
  • trunk/src/recompiler/exec.c

    r55 r2422  
    1919 */
    2020#include "config.h"
     21#ifndef VBOX
    2122#ifdef _WIN32
    2223#include <windows.h>
     
    3233#include <unistd.h>
    3334#include <inttypes.h>
     35#else /* VBOX */
     36# include <stdlib.h>
     37# include <stdio.h>
     38# include <inttypes.h>
     39# include <iprt/alloc.h>
     40# include <iprt/string.h>
     41# include <iprt/param.h>
     42# include <VBox/pgm.h> /* PGM_DYNAMIC_RAM_ALLOC */
     43#endif /* VBOX */
    3444
    3545#include "cpu.h"
    3646#include "exec-all.h"
    37 
    38 #ifdef VBOX
    39 #include <VBox/vm.h>
     47#if defined(CONFIG_USER_ONLY)
     48#include <qemu.h>
    4049#endif
    4150
     
    4352//#define DEBUG_FLUSH
    4453//#define DEBUG_TLB
     54//#define DEBUG_UNASSIGNED
    4555
    4656/* make various TB consistency checks */
     
    4858//#define DEBUG_TLB_CHECK
    4959
     60#if !defined(CONFIG_USER_ONLY)
     61/* TB consistency checks only implemented for usermode emulation.  */
     62#undef DEBUG_TB_CHECK
     63#endif
     64
    5065/* threshold to flush the translated code buffer */
    5166#define CODE_GEN_BUFFER_MAX_SIZE (CODE_GEN_BUFFER_SIZE - CODE_GEN_MAX_SIZE)
     
    5671#define MMAP_AREA_END          0xa8000000
    5772
     73#if defined(TARGET_SPARC64)
     74#define TARGET_PHYS_ADDR_SPACE_BITS 41
     75#elif defined(TARGET_PPC64)
     76#define TARGET_PHYS_ADDR_SPACE_BITS 42
     77#else
     78/* Note: for compatibility with kqemu, we use 32 bits for x86_64 */
     79#define TARGET_PHYS_ADDR_SPACE_BITS 32
     80#endif
     81
    5882TranslationBlock tbs[CODE_GEN_MAX_BLOCKS];
    59 TranslationBlock *tb_hash[CODE_GEN_HASH_SIZE];
    6083TranslationBlock *tb_phys_hash[CODE_GEN_PHYS_HASH_SIZE];
    6184int nb_tbs;
     
    6386spinlock_t tb_lock = SPIN_LOCK_UNLOCKED;
    6487
    65 uint8_t code_gen_buffer[CODE_GEN_BUFFER_SIZE];
     88uint8_t code_gen_buffer[CODE_GEN_BUFFER_SIZE]
     89#if defined(__MINGW32__)
     90    __attribute__((aligned (16)));
     91#else
     92    __attribute__((aligned (32)));
     93#endif
    6694uint8_t *code_gen_ptr;
    6795
    68 #if !defined(VBOX)
     96#ifndef VBOX
     97int phys_ram_size;
    6998int phys_ram_fd;
    70 #endif /* !VBOX */
    71 uint32_t phys_ram_size;
     99int phys_ram_size;
     100#else /* VBOX */
     101RTGCPHYS phys_ram_size;
     102/* we have memory ranges (the high PC-BIOS mapping) which
     103   causes some pages to fall outside the dirty map here. */
     104uint32_t phys_ram_dirty_size;
     105#endif /* VBOX */
     106#if !defined(VBOX) || !(defined(PGM_DYNAMIC_RAM_ALLOC) || defined(REM_PHYS_ADDR_IN_TLB))
    72107uint8_t *phys_ram_base;
     108#endif
    73109uint8_t *phys_ram_dirty;
     110
     111CPUState *first_cpu;
     112/* current CPU in the current thread. It is only valid inside
     113   cpu_exec() */
     114CPUState *cpu_single_env;
    74115
    75116typedef struct PageDesc {
     
    87128typedef struct PhysPageDesc {
    88129    /* offset in host memory of the page + io_index in the low 12 bits */
    89     unsigned long phys_offset;
     130    uint32_t phys_offset;
    90131} PhysPageDesc;
    91 
    92 typedef struct VirtPageDesc {
    93     /* physical address of code page. It is valid only if 'valid_tag'
    94        matches 'virt_valid_tag' */
    95     target_ulong phys_addr;
    96     unsigned int valid_tag;
    97 #if !defined(CONFIG_SOFTMMU)
    98     /* original page access rights. It is valid only if 'valid_tag'
    99        matches 'virt_valid_tag' */
    100     unsigned int prot;
    101 #endif
    102 } VirtPageDesc;
    103132
    104133#define L2_BITS 10
     
    117146/* XXX: for system emulation, it could just be an array */
    118147static PageDesc *l1_map[L1_SIZE];
    119 static PhysPageDesc *l1_phys_map[L1_SIZE];
    120 
    121 #if !defined(CONFIG_USER_ONLY)
    122 static VirtPageDesc *l1_virt_map[L1_SIZE];
    123 static unsigned int virt_valid_tag;
    124 #endif
     148PhysPageDesc **l1_phys_map;
    125149
    126150/* io memory support */
     
    133157/* log support */
    134158char *logfilename = "/tmp/qemu.log";
     159#endif /* !VBOX */
    135160FILE *logfile;
    136161int loglevel;
    137 #endif
    138162
    139163/* statistics */
    140164static int tlb_flush_count;
    141165static int tb_flush_count;
     166#ifndef VBOX
    142167static int tb_phys_invalidate_count;
     168#endif /* !VBOX */
    143169
    144170static void page_init(void)
     
    146172    /* NOTE: we can always suppose that qemu_host_page_size >=
    147173       TARGET_PAGE_SIZE */
     174#ifdef VBOX
     175    RTMemProtect(code_gen_buffer, sizeof(code_gen_buffer),
     176                 RTMEM_PROT_EXEC | RTMEM_PROT_READ | RTMEM_PROT_WRITE);
     177    qemu_real_host_page_size = PAGE_SIZE;
     178#else /* !VBOX */
    148179#ifdef _WIN32
    149180    {
     
    173204    }
    174205#endif
     206#endif /* !VBOX */
    175207
    176208    if (qemu_host_page_size == 0)
     
    182214        qemu_host_page_bits++;
    183215    qemu_host_page_mask = ~(qemu_host_page_size - 1);
    184 #if !defined(CONFIG_USER_ONLY)
    185     virt_valid_tag = 1;
    186 #endif
     216    l1_phys_map = qemu_vmalloc(L1_SIZE * sizeof(void *));
     217    memset(l1_phys_map, 0, L1_SIZE * sizeof(void *));
    187218}
    188219
     
    212243}
    213244
    214 static inline PhysPageDesc *phys_page_find_alloc(unsigned int index)
    215 {
    216     PhysPageDesc **lp, *p;
    217 
    218     lp = &l1_phys_map[index >> L2_BITS];
     245static PhysPageDesc *phys_page_find_alloc(target_phys_addr_t index, int alloc)
     246{
     247    void **lp, **p;
     248    PhysPageDesc *pd;
     249
     250    p = (void **)l1_phys_map;
     251#if TARGET_PHYS_ADDR_SPACE_BITS > 32
     252
     253#if TARGET_PHYS_ADDR_SPACE_BITS > (32 + L1_BITS)
     254#error unsupported TARGET_PHYS_ADDR_SPACE_BITS
     255#endif
     256    lp = p + ((index >> (L1_BITS + L2_BITS)) & (L1_SIZE - 1));
    219257    p = *lp;
    220258    if (!p) {
    221259        /* allocate if not found */
    222         p = qemu_malloc(sizeof(PhysPageDesc) * L2_SIZE);
    223         memset(p, 0, sizeof(PhysPageDesc) * L2_SIZE);
     260        if (!alloc)
     261            return NULL;
     262        p = qemu_vmalloc(sizeof(void *) * L1_SIZE);
     263        memset(p, 0, sizeof(void *) * L1_SIZE);
    224264        *lp = p;
    225265    }
    226     return p + (index & (L2_SIZE - 1));
    227 }
    228 
    229 static inline PhysPageDesc *phys_page_find(unsigned int index)
    230 {
    231     PhysPageDesc *p;
    232 
    233     p = l1_phys_map[index >> L2_BITS];
    234     if (!p)
    235         return 0;
    236 #ifdef VBOX
    237     p = p + (index & (L2_SIZE - 1));
    238     if ((p->phys_offset & ~TARGET_PAGE_MASK) == IO_MEM_RAM_MISSING)
    239         remR3GrowDynRange(p->phys_offset & TARGET_PAGE_MASK);
    240     return p;
    241 #else
    242     return p + (index & (L2_SIZE - 1));
    243 #endif
     266#endif
     267    lp = p + ((index >> L2_BITS) & (L1_SIZE - 1));
     268    pd = *lp;
     269    if (!pd) {
     270        int i;
     271        /* allocate if not found */
     272        if (!alloc)
     273            return NULL;
     274        pd = qemu_vmalloc(sizeof(PhysPageDesc) * L2_SIZE);
     275        *lp = pd;
     276        for (i = 0; i < L2_SIZE; i++)
     277          pd[i].phys_offset = IO_MEM_UNASSIGNED;
     278    }
     279#if defined(VBOX) && defined(PGM_DYNAMIC_RAM_ALLOC)
     280    pd = ((PhysPageDesc *)pd) + (index & (L2_SIZE - 1));
     281    if (RT_UNLIKELY((pd->phys_offset & ~TARGET_PAGE_MASK) == IO_MEM_RAM_MISSING))
     282        remR3GrowDynRange(pd->phys_offset & TARGET_PAGE_MASK);
     283    return pd;
     284#else
     285    return ((PhysPageDesc *)pd) + (index & (L2_SIZE - 1));
     286#endif
     287}
     288
     289static inline PhysPageDesc *phys_page_find(target_phys_addr_t index)
     290{
     291    return phys_page_find_alloc(index, 0);
    244292}
    245293
    246294#if !defined(CONFIG_USER_ONLY)
    247 static void tlb_protect_code(CPUState *env, target_ulong addr);
    248 static void tlb_unprotect_code_phys(CPUState *env, unsigned long phys_addr, target_ulong vaddr);
    249 
    250 static inline VirtPageDesc *virt_page_find_alloc(unsigned int index)
    251 {
    252     VirtPageDesc **lp, *p;
    253 
    254     /* XXX: should not truncate for 64 bit addresses */
    255 #if TARGET_LONG_BITS > 32
    256     index &= (L1_SIZE - 1);
    257 #endif
    258     lp = &l1_virt_map[index >> L2_BITS];
    259     p = *lp;
    260     if (!p) {
    261         /* allocate if not found */
    262         p = qemu_malloc(sizeof(VirtPageDesc) * L2_SIZE);
    263         memset(p, 0, sizeof(VirtPageDesc) * L2_SIZE);
    264         *lp = p;
    265     }
    266     return p + (index & (L2_SIZE - 1));
    267 }
    268 
    269 static inline VirtPageDesc *virt_page_find(unsigned int index)
    270 {
    271     VirtPageDesc *p;
    272 
    273     p = l1_virt_map[index >> L2_BITS];
    274     if (!p)
    275         return 0;
    276     return p + (index & (L2_SIZE - 1));
    277 }
    278 
    279 static void virt_page_flush(void)
    280 {
    281     int i, j;
    282     VirtPageDesc *p;
    283    
    284     virt_valid_tag++;
    285 
    286     if (virt_valid_tag == 0) {
    287         virt_valid_tag = 1;
    288         for(i = 0; i < L1_SIZE; i++) {
    289             p = l1_virt_map[i];
    290             if (p) {
    291                 for(j = 0; j < L2_SIZE; j++)
    292                     p[j].valid_tag = 0;
    293             }
    294         }
    295     }
    296 }
    297 #else
    298 static void virt_page_flush(void)
    299 {
    300 }
    301 #endif
    302 
    303 void cpu_exec_init(void)
    304 {
     295static void tlb_protect_code(ram_addr_t ram_addr);
     296static void tlb_unprotect_code_phys(CPUState *env, ram_addr_t ram_addr,
     297                                    target_ulong vaddr);
     298#endif
     299
     300void cpu_exec_init(CPUState *env)
     301{
     302    CPUState **penv;
     303    int cpu_index;
     304
    305305    if (!code_gen_ptr) {
    306306        code_gen_ptr = code_gen_buffer;
     
    308308        io_mem_init();
    309309    }
     310    env->next_cpu = NULL;
     311    penv = &first_cpu;
     312    cpu_index = 0;
     313    while (*penv != NULL) {
     314        penv = (CPUState **)&(*penv)->next_cpu;
     315        cpu_index++;
     316    }
     317    env->cpu_index = cpu_index;
     318    *penv = env;
    310319}
    311320
     
    339348/* flush all the translation blocks */
    340349/* XXX: tb_flush is currently not thread safe */
    341 void tb_flush(CPUState *env)
    342 {
     350void tb_flush(CPUState *env1)
     351{
     352    CPUState *env;
    343353#if defined(DEBUG_FLUSH)
    344354    printf("qemu: flush code_size=%d nb_tbs=%d avg_tb_size=%d\n",
     
    348358#endif
    349359    nb_tbs = 0;
    350     memset (tb_hash, 0, CODE_GEN_HASH_SIZE * sizeof (void *));
    351     virt_page_flush();
     360   
     361    for(env = first_cpu; env != NULL; env = env->next_cpu) {
     362        memset (env->tb_jmp_cache, 0, TB_JMP_CACHE_SIZE * sizeof (void *));
     363    }
    352364
    353365    memset (tb_phys_hash, 0, CODE_GEN_PHYS_HASH_SIZE * sizeof (void *));
     
    367379    int i;
    368380    address &= TARGET_PAGE_MASK;
    369     for(i = 0;i < CODE_GEN_HASH_SIZE; i++) {
    370         for(tb = tb_hash[i]; tb != NULL; tb = tb->hash_next) {
     381    for(i = 0;i < CODE_GEN_PHYS_HASH_SIZE; i++) {
     382        for(tb = tb_phys_hash[i]; tb != NULL; tb = tb->phys_hash_next) {
    371383            if (!(address + TARGET_PAGE_SIZE <= tb->pc ||
    372384                  address >= tb->pc + tb->size)) {
    373385                printf("ERROR invalidate: address=%08lx PC=%08lx size=%04x\n",
    374                        address, tb->pc, tb->size);
     386                       address, (long)tb->pc, tb->size);
    375387            }
    376388        }
     
    384396    int i, flags1, flags2;
    385397   
    386     for(i = 0;i < CODE_GEN_HASH_SIZE; i++) {
    387         for(tb = tb_hash[i]; tb != NULL; tb = tb->hash_next) {
     398    for(i = 0;i < CODE_GEN_PHYS_HASH_SIZE; i++) {
     399        for(tb = tb_phys_hash[i]; tb != NULL; tb = tb->phys_hash_next) {
    388400            flags1 = page_get_flags(tb->pc);
    389401            flags2 = page_get_flags(tb->pc + tb->size - 1);
    390402            if ((flags1 & PAGE_WRITE) || (flags2 & PAGE_WRITE)) {
    391403                printf("ERROR page flags: PC=%08lx size=%04x f1=%x f2=%x\n",
    392                        tb->pc, tb->size, flags1, flags2);
     404                       (long)tb->pc, tb->size, flags1, flags2);
    393405            }
    394406        }
     
    485497}
    486498
    487 static inline void tb_invalidate(TranslationBlock *tb)
    488 {
     499static inline void tb_phys_invalidate(TranslationBlock *tb, unsigned int page_addr)
     500{
     501    CPUState *env;
     502    PageDesc *p;
    489503    unsigned int h, n1;
    490     TranslationBlock *tb1, *tb2, **ptb;
     504    target_ulong phys_pc;
     505    TranslationBlock *tb1, *tb2;
    491506   
     507    /* remove the TB from the hash list */
     508    phys_pc = tb->page_addr[0] + (tb->pc & ~TARGET_PAGE_MASK);
     509    h = tb_phys_hash_func(phys_pc);
     510    tb_remove(&tb_phys_hash[h], tb,
     511              offsetof(TranslationBlock, phys_hash_next));
     512
     513    /* remove the TB from the page list */
     514    if (tb->page_addr[0] != page_addr) {
     515        p = page_find(tb->page_addr[0] >> TARGET_PAGE_BITS);
     516        tb_page_remove(&p->first_tb, tb);
     517        invalidate_page_bitmap(p);
     518    }
     519    if (tb->page_addr[1] != -1 && tb->page_addr[1] != page_addr) {
     520        p = page_find(tb->page_addr[1] >> TARGET_PAGE_BITS);
     521        tb_page_remove(&p->first_tb, tb);
     522        invalidate_page_bitmap(p);
     523    }
     524
    492525    tb_invalidated_flag = 1;
    493526
    494527    /* remove the TB from the hash list */
    495     h = tb_hash_func(tb->pc);
    496     ptb = &tb_hash[h];
    497     for(;;) {
    498         tb1 = *ptb;
    499         /* NOTE: the TB is not necessarily linked in the hash. It
    500            indicates that it is not currently used */
    501         if (tb1 == NULL)
    502             return;
    503         if (tb1 == tb) {
    504             *ptb = tb1->hash_next;
    505             break;
    506         }
    507         ptb = &tb1->hash_next;
     528    h = tb_jmp_cache_hash_func(tb->pc);
     529    for(env = first_cpu; env != NULL; env = env->next_cpu) {
     530        if (env->tb_jmp_cache[h] == tb)
     531            env->tb_jmp_cache[h] = NULL;
    508532    }
    509533
     
    525549    }
    526550    tb->jmp_first = (TranslationBlock *)((long)tb | 2); /* fail safe */
     551
     552#ifndef VBOX
     553    tb_phys_invalidate_count++;
     554#endif /* !VBOX */
    527555}
    528556
     
    530558void tb_invalidate_virt(CPUState *env, uint32_t eip)
    531559{
    532 #if 1
     560# if 1
    533561    tb_flush(env);
    534 #else
     562# else
    535563    uint8_t *cs_base, *pc;
    536564    unsigned int flags, h, phys_pc;
     
    547575    if(tb)
    548576    {
    549 #ifdef DEBUG
     577#  ifdef DEBUG
    550578        printf("invalidating TB (%08X) at %08X\n", tb, eip);
    551 #endif
     579#  endif
    552580        tb_invalidate(tb);
    553581        //Note: this will leak TBs, but the whole cache will be flushed
     
    557585        tb->flags = 0;
    558586    }
    559 #endif
     587# endif
    560588}
    561589
     
    571599# endif /* VBOX_STRICT */
    572600#endif /* VBOX */
    573 
    574 static inline void tb_phys_invalidate(TranslationBlock *tb, unsigned int page_addr)
    575 {
    576     PageDesc *p;
    577     unsigned int h;
    578     target_ulong phys_pc;
    579    
    580     /* remove the TB from the hash list */
    581     phys_pc = tb->page_addr[0] + (tb->pc & ~TARGET_PAGE_MASK);
    582     h = tb_phys_hash_func(phys_pc);
    583     tb_remove(&tb_phys_hash[h], tb,
    584               offsetof(TranslationBlock, phys_hash_next));
    585 
    586     /* remove the TB from the page list */
    587     if (tb->page_addr[0] != page_addr) {
    588         p = page_find(tb->page_addr[0] >> TARGET_PAGE_BITS);
    589         tb_page_remove(&p->first_tb, tb);
    590         invalidate_page_bitmap(p);
    591     }
    592     if (tb->page_addr[1] != -1 && tb->page_addr[1] != page_addr) {
    593         p = page_find(tb->page_addr[1] >> TARGET_PAGE_BITS);
    594         tb_page_remove(&p->first_tb, tb);
    595         invalidate_page_bitmap(p);
    596     }
    597 
    598     tb_invalidate(tb);
    599     tb_phys_invalidate_count++;
    600 }
    601601
    602602static inline void set_bits(uint8_t *tab, int start, int len)
     
    774774            }
    775775#endif /* TARGET_HAS_PRECISE_SMC */
    776             saved_tb = env->current_tb;
    777             env->current_tb = NULL;
     776            /* we need to do that to handle the case where a signal
     777               occurs while doing tb_phys_invalidate() */
     778            saved_tb = NULL;
     779            if (env) {
     780                saved_tb = env->current_tb;
     781                env->current_tb = NULL;
     782            }
    778783            tb_phys_invalidate(tb, -1);
    779             env->current_tb = saved_tb;
    780             if (env->interrupt_request && env->current_tb)
    781                 cpu_interrupt(env, env->interrupt_request);
     784            if (env) {
     785                env->current_tb = saved_tb;
     786                if (env->interrupt_request && env->current_tb)
     787                    cpu_interrupt(env, env->interrupt_request);
     788            }
    782789        }
    783790        tb = tb_next;
     
    905912/* add the tb in the target page and protect it if necessary */
    906913static inline void tb_alloc_page(TranslationBlock *tb,
    907                                  unsigned int n, unsigned int page_addr)
     914                                 unsigned int n, target_ulong page_addr)
    908915{
    909916    PageDesc *p;
     
    911918
    912919    tb->page_addr[n] = page_addr;
    913     p = page_find(page_addr >> TARGET_PAGE_BITS);
     920    p = page_find_alloc(page_addr >> TARGET_PAGE_BITS);
    914921    tb->page_next[n] = p->first_tb;
    915922    last_first_tb = p->first_tb;
     
    921928#if defined(CONFIG_USER_ONLY)
    922929    if (p->flags & PAGE_WRITE) {
    923         unsigned long host_start, host_end, addr;
     930        target_ulong addr;
     931        PageDesc *p2;
    924932        int prot;
    925933
    926934        /* force the host page as non writable (writes will have a
    927935           page fault + mprotect overhead) */
    928         host_start = page_addr & qemu_host_page_mask;
    929         host_end = host_start + qemu_host_page_size;
     936        page_addr &= qemu_host_page_mask;
    930937        prot = 0;
    931         for(addr = host_start; addr < host_end; addr += TARGET_PAGE_SIZE)
    932             prot |= page_get_flags(addr);
    933         mprotect((void *)host_start, qemu_host_page_size,
     938        for(addr = page_addr; addr < page_addr + qemu_host_page_size;
     939            addr += TARGET_PAGE_SIZE) {
     940
     941            p2 = page_find (addr >> TARGET_PAGE_BITS);
     942            if (!p2)
     943                continue;
     944            prot |= p2->flags;
     945            p2->flags &= ~PAGE_WRITE;
     946            page_get_flags(addr);
     947          }
     948        mprotect(g2h(page_addr), qemu_host_page_size,
    934949                 (prot & PAGE_BITS) & ~PAGE_WRITE);
    935950#ifdef DEBUG_TB_INVALIDATE
    936951        printf("protecting code page: 0x%08lx\n",
    937                host_start);
    938 #endif
    939         p->flags &= ~PAGE_WRITE;
     952               page_addr);
     953#endif
    940954    }
    941955#else
     
    944958       allocated in a physical page */
    945959    if (!last_first_tb) {
    946         target_ulong virt_addr;
    947 
    948         virt_addr = (tb->pc & TARGET_PAGE_MASK) + (n << TARGET_PAGE_BITS);
    949         tlb_protect_code(cpu_single_env, virt_addr);       
     960        tlb_protect_code(page_addr);
    950961    }
    951962#endif
     
    9891000    else
    9901001        tb->page_addr[1] = -1;
    991 #ifdef DEBUG_TB_CHECK
    992     tb_page_check();
    993 #endif
    994 }
    995 
    996 /* link the tb with the other TBs */
    997 void tb_link(TranslationBlock *tb)
    998 {
    999 #if !defined(CONFIG_USER_ONLY)
    1000     {
    1001         VirtPageDesc *vp;
    1002         target_ulong addr;
    1003        
    1004         /* save the code memory mappings (needed to invalidate the code) */
    1005         addr = tb->pc & TARGET_PAGE_MASK;
    1006         vp = virt_page_find_alloc(addr >> TARGET_PAGE_BITS);
    1007 #ifdef DEBUG_TLB_CHECK
    1008         if (vp->valid_tag == virt_valid_tag &&
    1009             vp->phys_addr != tb->page_addr[0]) {
    1010             printf("Error tb addr=0x%x phys=0x%x vp->phys_addr=0x%x\n",
    1011                    addr, tb->page_addr[0], vp->phys_addr);
    1012         }
    1013 #endif
    1014         vp->phys_addr = tb->page_addr[0];
    1015         if (vp->valid_tag != virt_valid_tag) {
    1016             vp->valid_tag = virt_valid_tag;
    1017 #if !defined(CONFIG_SOFTMMU)
    1018             vp->prot = 0;
    1019 #endif
    1020         }
    1021        
    1022         if (tb->page_addr[1] != -1) {
    1023             addr += TARGET_PAGE_SIZE;
    1024             vp = virt_page_find_alloc(addr >> TARGET_PAGE_BITS);
    1025 #ifdef DEBUG_TLB_CHECK
    1026             if (vp->valid_tag == virt_valid_tag &&
    1027                 vp->phys_addr != tb->page_addr[1]) {
    1028                 printf("Error tb addr=0x%x phys=0x%x vp->phys_addr=0x%x\n",
    1029                        addr, tb->page_addr[1], vp->phys_addr);
    1030             }
    1031 #endif
    1032             vp->phys_addr = tb->page_addr[1];
    1033             if (vp->valid_tag != virt_valid_tag) {
    1034                 vp->valid_tag = virt_valid_tag;
    1035 #if !defined(CONFIG_SOFTMMU)
    1036                 vp->prot = 0;
    1037 #endif
    1038             }
    1039         }
    1040     }
    1041 #endif
    10421002
    10431003    tb->jmp_first = (TranslationBlock *)((long)tb | 2);
     
    10551015    if (tb->tb_next_offset[1] != 0xffff)
    10561016        tb_reset_jump(tb, 1);
     1017
     1018#ifdef DEBUG_TB_CHECK
     1019    tb_page_check();
     1020#endif
    10571021}
    10581022
     
    11351099}
    11361100
    1137 #if defined(TARGET_I386) || defined(TARGET_PPC) || defined(TARGET_SPARC)
     1101#if defined(TARGET_HAS_ICE)
    11381102static void breakpoint_invalidate(CPUState *env, target_ulong pc)
    11391103{
    1140     target_ulong phys_addr;
    1141 
    1142     phys_addr = cpu_get_phys_page_debug(env, pc);
    1143     tb_invalidate_phys_page_range(phys_addr, phys_addr + 1, 0);
     1104    target_ulong addr, pd;
     1105    ram_addr_t ram_addr;
     1106    PhysPageDesc *p;
     1107
     1108    addr = cpu_get_phys_page_debug(env, pc);
     1109    p = phys_page_find(addr >> TARGET_PAGE_BITS);
     1110    if (!p) {
     1111        pd = IO_MEM_UNASSIGNED;
     1112    } else {
     1113        pd = p->phys_offset;
     1114    }
     1115    ram_addr = (pd & TARGET_PAGE_MASK) | (pc & ~TARGET_PAGE_MASK);
     1116    tb_invalidate_phys_page_range(ram_addr, ram_addr + 1, 0);
    11441117}
    11451118#endif
     
    11491122int cpu_breakpoint_insert(CPUState *env, target_ulong pc)
    11501123{
    1151 #if defined(TARGET_I386) || defined(TARGET_PPC) || defined(TARGET_SPARC)
     1124#if defined(TARGET_HAS_ICE)
    11521125    int i;
    11531126   
     
    11711144int cpu_breakpoint_remove(CPUState *env, target_ulong pc)
    11721145{
    1173 #if defined(TARGET_I386) || defined(TARGET_PPC) || defined(TARGET_SPARC)
     1146#if defined(TARGET_HAS_ICE)
    11741147    int i;
    11751148    for(i = 0; i < env->nb_breakpoints; i++) {
     
    11791152    return -1;
    11801153 found:
    1181     memmove(&env->breakpoints[i], &env->breakpoints[i + 1],
    1182             (env->nb_breakpoints - (i + 1)) * sizeof(env->breakpoints[0]));
    11831154    env->nb_breakpoints--;
     1155    if (i < env->nb_breakpoints)
     1156      env->breakpoints[i] = env->breakpoints[env->nb_breakpoints];
    11841157
    11851158    breakpoint_invalidate(env, pc);
     
    11941167void cpu_single_step(CPUState *env, int enabled)
    11951168{
    1196 #if defined(TARGET_I386) || defined(TARGET_PPC) || defined(TARGET_SPARC)
     1169#if defined(TARGET_HAS_ICE)
    11971170    if (env->singlestep_enabled != enabled) {
    11981171        env->singlestep_enabled = enabled;
     
    12311204    logfilename = strdup(filename);
    12321205}
    1233 #endif
     1206#endif /* !VBOX */
    12341207
    12351208/* mask must never be zero, except for A20 change call */
     
    12391212    static int interrupt_lock;
    12401213
    1241 #if defined(VBOX)
     1214#ifdef VBOX
    12421215    VM_ASSERT_EMT(env->pVM);
    12431216    ASMAtomicOrS32(&env->interrupt_request, mask);
    1244 #else /* VBOX */
     1217#else /* !VBOX */
    12451218    env->interrupt_request |= mask;
    1246 #endif /* VBOX */
     1219#endif /* !VBOX */
    12471220    /* if the cpu is currently executing code, we must unlink it and
    12481221       all the potentially executing TB */
     
    12571230void cpu_reset_interrupt(CPUState *env, int mask)
    12581231{
    1259 #if defined(VBOX)
     1232#ifdef VBOX
    12601233    /*
    12611234     * Note: the current implementation can be executed by another thread without problems; make sure this remains true
     
    13381311#endif /* !VBOX */
    13391312
    1340 #if !defined(VBOX) /* VBOX: we have our own routine. */
     1313#ifndef VBOX /* VBOX: we have our own routine. */
    13411314void cpu_abort(CPUState *env, const char *fmt, ...)
    13421315{
     
    13731346
    13741347    for(i = 0; i < CPU_TLB_SIZE; i++) {
    1375         env->tlb_read[0][i].address = -1;
    1376         env->tlb_write[0][i].address = -1;
    1377         env->tlb_read[1][i].address = -1;
    1378         env->tlb_write[1][i].address = -1;
    1379     }
    1380 
    1381     virt_page_flush();
    1382     memset (tb_hash, 0, CODE_GEN_HASH_SIZE * sizeof (void *));
     1348        env->tlb_table[0][i].addr_read = -1;
     1349        env->tlb_table[0][i].addr_write = -1;
     1350        env->tlb_table[0][i].addr_code = -1;
     1351        env->tlb_table[1][i].addr_read = -1;
     1352        env->tlb_table[1][i].addr_write = -1;
     1353        env->tlb_table[1][i].addr_code = -1;
     1354    }
     1355
     1356    memset (env->tb_jmp_cache, 0, TB_JMP_CACHE_SIZE * sizeof (void *));
    13831357
    13841358#if !defined(CONFIG_SOFTMMU)
    13851359    munmap((void *)MMAP_AREA_START, MMAP_AREA_END - MMAP_AREA_START);
    1386 #elif defined(VBOX)
     1360#endif
     1361#ifdef VBOX
    13871362    /* inform raw mode about TLB flush */
    13881363    remR3FlushTLB(env, flush_global);
    13891364#endif
     1365#ifdef USE_KQEMU
     1366    if (env->kqemu_enabled) {
     1367        kqemu_flush(env, flush_global);
     1368    }
     1369#endif
    13901370    tlb_flush_count++;
    13911371}
     
    13931373static inline void tlb_flush_entry(CPUTLBEntry *tlb_entry, target_ulong addr)
    13941374{
    1395     if (addr == (tlb_entry->address &
    1396                  (TARGET_PAGE_MASK | TLB_INVALID_MASK)))
    1397         tlb_entry->address = -1;
     1375    if (addr == (tlb_entry->addr_read &
     1376                 (TARGET_PAGE_MASK | TLB_INVALID_MASK)) ||
     1377        addr == (tlb_entry->addr_write &
     1378                 (TARGET_PAGE_MASK | TLB_INVALID_MASK)) ||
     1379        addr == (tlb_entry->addr_code &
     1380                 (TARGET_PAGE_MASK | TLB_INVALID_MASK))) {
     1381        tlb_entry->addr_read = -1;
     1382        tlb_entry->addr_write = -1;
     1383        tlb_entry->addr_code = -1;
     1384    }
    13981385}
    13991386
    14001387void tlb_flush_page(CPUState *env, target_ulong addr)
    14011388{
    1402     int i, n;
    1403     VirtPageDesc *vp;
    1404     PageDesc *p;
     1389    int i;
    14051390    TranslationBlock *tb;
    14061391
    14071392#if defined(DEBUG_TLB)
    1408     printf("tlb_flush_page: 0x%08x\n", addr);
     1393    printf("tlb_flush_page: " TARGET_FMT_lx "\n", addr);
    14091394#endif
    14101395    /* must reset current TB so that interrupts cannot modify the
     
    14141399    addr &= TARGET_PAGE_MASK;
    14151400    i = (addr >> TARGET_PAGE_BITS) & (CPU_TLB_SIZE - 1);
    1416     tlb_flush_entry(&env->tlb_read[0][i], addr);
    1417     tlb_flush_entry(&env->tlb_write[0][i], addr);
    1418     tlb_flush_entry(&env->tlb_read[1][i], addr);
    1419     tlb_flush_entry(&env->tlb_write[1][i], addr);
    1420 
    1421     /* remove from the virtual pc hash table all the TB at this
    1422        virtual address */
    1423    
    1424     vp = virt_page_find(addr >> TARGET_PAGE_BITS);
    1425     if (vp && vp->valid_tag == virt_valid_tag) {
    1426         p = page_find(vp->phys_addr >> TARGET_PAGE_BITS);
    1427         if (p) {
    1428             /* we remove all the links to the TBs in this virtual page */
    1429             tb = p->first_tb;
    1430             while (tb != NULL) {
    1431                 n = (long)tb & 3;
    1432                 tb = (TranslationBlock *)((long)tb & ~3);
    1433                 if ((tb->pc & TARGET_PAGE_MASK) == addr ||
    1434                     ((tb->pc + tb->size - 1) & TARGET_PAGE_MASK) == addr) {
    1435                     tb_invalidate(tb);
    1436                 }
    1437                 tb = tb->page_next[n];
    1438             }
    1439         }
    1440         vp->valid_tag = 0;
    1441     }
     1401    tlb_flush_entry(&env->tlb_table[0][i], addr);
     1402    tlb_flush_entry(&env->tlb_table[1][i], addr);
     1403
     1404    /* Discard jump cache entries for any tb which might potentially
     1405       overlap the flushed page.  */
     1406    i = tb_jmp_cache_hash_page(addr - TARGET_PAGE_SIZE);
     1407    memset (&env->tb_jmp_cache[i], 0, TB_JMP_PAGE_SIZE * sizeof(tb));
     1408
     1409    i = tb_jmp_cache_hash_page(addr);
     1410    memset (&env->tb_jmp_cache[i], 0, TB_JMP_PAGE_SIZE * sizeof(tb));
    14421411
    14431412#if !defined(CONFIG_SOFTMMU)
    14441413    if (addr < MMAP_AREA_END)
    14451414        munmap((void *)addr, TARGET_PAGE_SIZE);
    1446 #elif defined(VBOX)
     1415#endif
     1416#ifdef VBOX
    14471417    /* inform raw mode about TLB page flush */
    14481418    remR3FlushPage(env, addr);
    1449 #endif
    1450 }
    1451 
    1452 static inline void tlb_protect_code1(CPUTLBEntry *tlb_entry, target_ulong addr)
    1453 {
    1454     if (addr == (tlb_entry->address &
    1455                  (TARGET_PAGE_MASK | TLB_INVALID_MASK)) &&
    1456         (tlb_entry->address & ~TARGET_PAGE_MASK) != IO_MEM_CODE &&
    1457         (tlb_entry->address & ~TARGET_PAGE_MASK) != IO_MEM_ROM) {
    1458         tlb_entry->address = (tlb_entry->address & TARGET_PAGE_MASK) | IO_MEM_CODE;
    1459     }
     1419#endif /* VBOX */
     1420#ifdef USE_KQEMU
     1421    if (env->kqemu_enabled) {
     1422        kqemu_flush_page(env, addr);
     1423    }
     1424#endif
    14601425}
    14611426
    14621427/* update the TLBs so that writes to code in the virtual page 'addr'
    14631428   can be detected */
    1464 static void tlb_protect_code(CPUState *env, target_ulong addr)
    1465 {
    1466     int i;
    1467 
    1468     addr &= TARGET_PAGE_MASK;
    1469     i = (addr >> TARGET_PAGE_BITS) & (CPU_TLB_SIZE - 1);
    1470     tlb_protect_code1(&env->tlb_write[0][i], addr);
    1471     tlb_protect_code1(&env->tlb_write[1][i], addr);
    1472 #if !defined(CONFIG_SOFTMMU)
    1473     /* NOTE: as we generated the code for this page, it is already at
    1474        least readable */
    1475     if (addr < MMAP_AREA_END)
    1476         mprotect((void *)addr, TARGET_PAGE_SIZE, PROT_READ);
    1477 #endif
    1478 
     1429static void tlb_protect_code(ram_addr_t ram_addr)
     1430{
     1431    cpu_physical_memory_reset_dirty(ram_addr,
     1432                                    ram_addr + TARGET_PAGE_SIZE,
     1433                                    CODE_DIRTY_FLAG);
    14791434#if defined(VBOX) && defined(REM_MONITOR_CODE_PAGES)
    1480     remR3ProtectCode(env, addr);
    1481 #endif
    1482 }
    1483 
    1484 static inline void tlb_unprotect_code2(CPUTLBEntry *tlb_entry,
    1485                                        unsigned long phys_addr)
    1486 {
    1487     if ((tlb_entry->address & ~TARGET_PAGE_MASK) == IO_MEM_CODE &&
    1488         ((tlb_entry->address & TARGET_PAGE_MASK) + tlb_entry->addend) == phys_addr) {
    1489         tlb_entry->address = (tlb_entry->address & TARGET_PAGE_MASK) | IO_MEM_NOTDIRTY;
    1490     }
     1435    /** @todo Retest this? This function has changed... */
     1436    remR3ProtectCode(cpu_single_env, ram_addr);
     1437#endif
    14911438}
    14921439
    14931440/* update the TLB so that writes in physical page 'phys_addr' are no longer
    1494    tested self modifying code */
    1495 static void tlb_unprotect_code_phys(CPUState *env, unsigned long phys_addr, target_ulong vaddr)
    1496 {
    1497     int i;
    1498 
    1499     phys_addr &= TARGET_PAGE_MASK;
     1441   tested for self modifying code */
     1442static void tlb_unprotect_code_phys(CPUState *env, ram_addr_t ram_addr,
     1443                                    target_ulong vaddr)
     1444{
    15001445#ifdef VBOX
    1501     phys_addr = (unsigned long)remR3GCPhys2HCVirt(env, phys_addr);
    1502 #else
    1503     phys_addr += (long)phys_ram_base;
    1504 #endif
    1505     i = (vaddr >> TARGET_PAGE_BITS) & (CPU_TLB_SIZE - 1);
    1506     tlb_unprotect_code2(&env->tlb_write[0][i], phys_addr);
    1507     tlb_unprotect_code2(&env->tlb_write[1][i], phys_addr);
     1446    if (RT_LIKELY((ram_addr >> TARGET_PAGE_BITS) < phys_ram_dirty_size))
     1447#endif
     1448    phys_ram_dirty[ram_addr >> TARGET_PAGE_BITS] |= CODE_DIRTY_FLAG;
    15081449}
    15091450
     
    15121453{
    15131454    unsigned long addr;
    1514     if ((tlb_entry->address & ~TARGET_PAGE_MASK) == IO_MEM_RAM) {
    1515         addr = (tlb_entry->address & TARGET_PAGE_MASK) + tlb_entry->addend;
     1455    if ((tlb_entry->addr_write & ~TARGET_PAGE_MASK) == IO_MEM_RAM) {
     1456        addr = (tlb_entry->addr_write & TARGET_PAGE_MASK) + tlb_entry->addend;
    15161457        if ((addr - start) < length) {
    1517             tlb_entry->address = (tlb_entry->address & TARGET_PAGE_MASK) | IO_MEM_NOTDIRTY;
    1518         }
    1519     }
    1520 }
    1521 
    1522 void cpu_physical_memory_reset_dirty(target_ulong start, target_ulong end)
     1458            tlb_entry->addr_write = (tlb_entry->addr_write & TARGET_PAGE_MASK) | IO_MEM_NOTDIRTY;
     1459        }
     1460    }
     1461}
     1462
     1463void cpu_physical_memory_reset_dirty(ram_addr_t start, ram_addr_t end,
     1464                                     int dirty_flags)
    15231465{
    15241466    CPUState *env;
    15251467    unsigned long length, start1;
    1526     int i;
     1468    int i, mask, len;
     1469    uint8_t *p;
    15271470
    15281471    start &= TARGET_PAGE_MASK;
     
    15321475    if (length == 0)
    15331476        return;
    1534     memset(phys_ram_dirty + (start >> TARGET_PAGE_BITS), 0, length >> TARGET_PAGE_BITS);
    1535 
    1536     env = cpu_single_env;
     1477    len = length >> TARGET_PAGE_BITS;
     1478#ifdef USE_KQEMU
     1479    /* XXX: should not depend on cpu context */
     1480    env = first_cpu;
     1481    if (env->kqemu_enabled) {
     1482        ram_addr_t addr;
     1483        addr = start;
     1484        for(i = 0; i < len; i++) {
     1485            kqemu_set_notdirty(env, addr);
     1486            addr += TARGET_PAGE_SIZE;
     1487        }
     1488    }
     1489#endif
     1490    mask = ~dirty_flags;
     1491    p = phys_ram_dirty + (start >> TARGET_PAGE_BITS);
     1492#ifdef VBOX
     1493    if (RT_LIKELY((start >> TARGET_PAGE_BITS) < phys_ram_dirty_size))
     1494#endif
     1495    for(i = 0; i < len; i++)
     1496        p[i] &= mask;
     1497
    15371498    /* we modify the TLB cache so that the dirty bit will be set again
    15381499       when accessing the range */
    1539 #ifdef VBOX
    1540     start1 = (unsigned long)remR3GCPhys2HCVirt(env, start);
    1541 #else
     1500#if defined(VBOX) && defined(REM_PHYS_ADDR_IN_TLB)
     1501    start1 = start;
     1502#elif !defined(VBOX) || !defined(PGM_DYNAMIC_RAM_ALLOC)
    15421503    start1 = start + (unsigned long)phys_ram_base;
    1543 #endif
    1544     for(i = 0; i < CPU_TLB_SIZE; i++)
    1545         tlb_reset_dirty_range(&env->tlb_write[0][i], start1, length);
    1546     for(i = 0; i < CPU_TLB_SIZE; i++)
    1547         tlb_reset_dirty_range(&env->tlb_write[1][i], start1, length);
    1548 
    1549 #if !defined(CONFIG_SOFTMMU) && !defined(VBOX)
     1504#else
     1505    start1 = (unsigned long)remR3GCPhys2HCVirt(first_cpu, start);
     1506#endif
     1507    for(env = first_cpu; env != NULL; env = env->next_cpu) {
     1508        for(i = 0; i < CPU_TLB_SIZE; i++)
     1509            tlb_reset_dirty_range(&env->tlb_table[0][i], start1, length);
     1510        for(i = 0; i < CPU_TLB_SIZE; i++)
     1511            tlb_reset_dirty_range(&env->tlb_table[1][i], start1, length);
     1512    }
     1513
     1514#if !defined(CONFIG_SOFTMMU)
     1515#ifdef VBOX /**@todo remove this check */
     1516# error "We shouldn't get here..."
     1517#endif
    15501518    /* XXX: this is expensive */
    15511519    {
     
    15761544}
    15771545
     1546static inline void tlb_update_dirty(CPUTLBEntry *tlb_entry)
     1547{
     1548    ram_addr_t ram_addr;
     1549
     1550    if ((tlb_entry->addr_write & ~TARGET_PAGE_MASK) == IO_MEM_RAM) {
     1551        /* RAM case */
     1552#if defined(VBOX) && defined(REM_PHYS_ADDR_IN_TLB)
     1553        ram_addr = (tlb_entry->addr_write & TARGET_PAGE_MASK) + tlb_entry->addend;
     1554#elif !defined(VBOX) || !defined(PGM_DYNAMIC_RAM_ALLOC)
     1555        ram_addr = (tlb_entry->addr_write & TARGET_PAGE_MASK) +
     1556            tlb_entry->addend - (unsigned long)phys_ram_base;
     1557#else
     1558        ram_addr = remR3HCVirt2GCPhys(first_cpu, (tlb_entry->addr_write & TARGET_PAGE_MASK) + tlb_entry->addend);
     1559#endif
     1560        if (!cpu_physical_memory_is_dirty(ram_addr)) {
     1561            tlb_entry->addr_write |= IO_MEM_NOTDIRTY;
     1562        }
     1563    }
     1564}
     1565
     1566/* update the TLB according to the current state of the dirty bits */
     1567void cpu_tlb_update_dirty(CPUState *env)
     1568{
     1569    int i;
     1570    for(i = 0; i < CPU_TLB_SIZE; i++)
     1571        tlb_update_dirty(&env->tlb_table[0][i]);
     1572    for(i = 0; i < CPU_TLB_SIZE; i++)
     1573        tlb_update_dirty(&env->tlb_table[1][i]);
     1574}
     1575
    15781576static inline void tlb_set_dirty1(CPUTLBEntry *tlb_entry,
    1579                                     unsigned long start)
     1577                                  unsigned long start)
    15801578{
    15811579    unsigned long addr;
    1582     if ((tlb_entry->address & ~TARGET_PAGE_MASK) == IO_MEM_NOTDIRTY) {
    1583         addr = (tlb_entry->address & TARGET_PAGE_MASK) + tlb_entry->addend;
     1580    if ((tlb_entry->addr_write & ~TARGET_PAGE_MASK) == IO_MEM_NOTDIRTY) {
     1581        addr = (tlb_entry->addr_write & TARGET_PAGE_MASK) + tlb_entry->addend;
    15841582        if (addr == start) {
    1585             tlb_entry->address = (tlb_entry->address & TARGET_PAGE_MASK) | IO_MEM_RAM;
     1583            tlb_entry->addr_write = (tlb_entry->addr_write & TARGET_PAGE_MASK) | IO_MEM_RAM;
    15861584        }
    15871585    }
     
    15901588/* update the TLB corresponding to virtual page vaddr and phys addr
    15911589   addr so that it is no longer dirty */
    1592 static inline void tlb_set_dirty(unsigned long addr, target_ulong vaddr)
    1593 {
    1594     CPUState *env = cpu_single_env;
     1590static inline void tlb_set_dirty(CPUState *env,
     1591                                 unsigned long addr, target_ulong vaddr)
     1592{
    15951593    int i;
    1596 
    1597 #ifdef VBOX
    1598     if (remR3HCVirt2GCPhys(env, (void *)addr) > phys_ram_size)
    1599     {
    1600         Log(("phys_ram_dirty exceeded at address %VGp, ignoring\n",
    1601              (RTGCPHYS)(addr - (uintptr_t)phys_ram_base)));
    1602         return;
    1603     }
    1604     phys_ram_dirty[(unsigned long)remR3HCVirt2GCPhys(env, (void *)addr) >> TARGET_PAGE_BITS] = 1;
    1605 #else
    1606     phys_ram_dirty[(addr - (unsigned long)phys_ram_base) >> TARGET_PAGE_BITS] = 1;
    1607 #endif
    1608 
    16091594
    16101595    addr &= TARGET_PAGE_MASK;
    16111596    i = (vaddr >> TARGET_PAGE_BITS) & (CPU_TLB_SIZE - 1);
    1612     tlb_set_dirty1(&env->tlb_write[0][i], addr);
    1613     tlb_set_dirty1(&env->tlb_write[1][i], addr);
     1597    tlb_set_dirty1(&env->tlb_table[0][i], addr);
     1598    tlb_set_dirty1(&env->tlb_table[1][i], addr);
    16141599}
    16151600
     
    16181603   (can only happen in non SOFTMMU mode for I/O pages or pages
    16191604   conflicting with the host address space). */
    1620 int tlb_set_page(CPUState *env, target_ulong vaddr,
    1621                  target_phys_addr_t paddr, int prot,
    1622                  int is_user, int is_softmmu)
     1605int tlb_set_page_exec(CPUState *env, target_ulong vaddr,
     1606                      target_phys_addr_t paddr, int prot,
     1607                      int is_user, int is_softmmu)
    16231608{
    16241609    PhysPageDesc *p;
    16251610    unsigned long pd;
    1626     TranslationBlock *first_tb;
    16271611    unsigned int index;
    16281612    target_ulong address;
    1629     unsigned long addend;
     1613    target_phys_addr_t addend;
    16301614    int ret;
     1615    CPUTLBEntry *te;
    16311616
    16321617    p = phys_page_find(paddr >> TARGET_PAGE_BITS);
    1633     first_tb = NULL;
    16341618    if (!p) {
    16351619        pd = IO_MEM_UNASSIGNED;
    16361620    } else {
    1637         PageDesc *p1;
    16381621        pd = p->phys_offset;
    1639         if ((pd & ~TARGET_PAGE_MASK) <= IO_MEM_ROM) {
    1640             /* NOTE: we also allocate the page at this stage */
    1641             p1 = page_find_alloc(pd >> TARGET_PAGE_BITS);
    1642             first_tb = p1->first_tb;
    1643         }
    16441622    }
    16451623#if defined(DEBUG_TLB)
    1646     printf("tlb_set_page: vaddr=0x%08x paddr=0x%08x prot=%x u=%d c=%d smmu=%d pd=0x%08x\n",
    1647            vaddr, paddr, prot, is_user, (first_tb != NULL), is_softmmu, pd);
     1624    printf("tlb_set_page: vaddr=" TARGET_FMT_lx " paddr=0x%08x prot=%x u=%d smmu=%d pd=0x%08lx\n",
     1625           vaddr, (int)paddr, prot, is_user, is_softmmu, pd);
    16481626#endif
    16491627
     
    16531631#endif
    16541632    {
    1655         if ((pd & ~TARGET_PAGE_MASK) > IO_MEM_ROM) {
     1633        if ((pd & ~TARGET_PAGE_MASK) > IO_MEM_ROM && !(pd & IO_MEM_ROMD)) {
    16561634            /* IO memory case */
    16571635            address = vaddr | pd;
     
    16601638            /* standard memory */
    16611639            address = vaddr;
    1662 #ifdef VBOX
     1640#if defined(VBOX) && defined(REM_PHYS_ADDR_IN_TLB)
     1641            addend = pd & TARGET_PAGE_MASK;
     1642#elif !defined(VBOX) || !defined(PGM_DYNAMIC_RAM_ALLOC)
     1643            addend = (unsigned long)phys_ram_base + (pd & TARGET_PAGE_MASK);
     1644#else
    16631645            addend = (unsigned long)remR3GCPhys2HCVirt(env, pd & TARGET_PAGE_MASK);
    1664 #else
    1665             addend = (unsigned long)phys_ram_base + (pd & TARGET_PAGE_MASK);
    1666 #endif
     1646#endif
    16671647        }
    16681648       
    1669         index = (vaddr >> 12) & (CPU_TLB_SIZE - 1);
     1649        index = (vaddr >> TARGET_PAGE_BITS) & (CPU_TLB_SIZE - 1);
    16701650        addend -= vaddr;
     1651        te = &env->tlb_table[is_user][index];
     1652        te->addend = addend;
    16711653        if (prot & PAGE_READ) {
    1672             env->tlb_read[is_user][index].address = address;
    1673             env->tlb_read[is_user][index].addend = addend;
     1654            te->addr_read = address;
    16741655        } else {
    1675             env->tlb_read[is_user][index].address = -1;
    1676             env->tlb_read[is_user][index].addend = -1;
     1656            te->addr_read = -1;
     1657        }
     1658        if (prot & PAGE_EXEC) {
     1659            te->addr_code = address;
     1660        } else {
     1661            te->addr_code = -1;
    16771662        }
    16781663        if (prot & PAGE_WRITE) {
    1679             if ((pd & ~TARGET_PAGE_MASK) == IO_MEM_ROM) {
    1680                 /* ROM: access is ignored (same as unassigned) */
    1681                 env->tlb_write[is_user][index].address = vaddr | IO_MEM_ROM;
    1682                 env->tlb_write[is_user][index].addend = addend;
    1683             } else
    1684                 /* XXX: the PowerPC code seems not ready to handle
    1685                    self modifying code with DCBI */
    1686 #if defined(TARGET_HAS_SMC) || 1
    1687             if (first_tb) {
    1688                 /* if code is present, we use a specific memory
    1689                    handler. It works only for physical memory access */
    1690                 env->tlb_write[is_user][index].address = vaddr | IO_MEM_CODE;
    1691                 env->tlb_write[is_user][index].addend = addend;
    1692             } else
    1693 #endif
    1694             if ((pd & ~TARGET_PAGE_MASK) == IO_MEM_RAM &&
     1664            if ((pd & ~TARGET_PAGE_MASK) == IO_MEM_ROM ||
     1665                (pd & IO_MEM_ROMD)) {
     1666                /* write access calls the I/O callback */
     1667                te->addr_write = vaddr |
     1668                    (pd & ~(TARGET_PAGE_MASK | IO_MEM_ROMD));
     1669            } else if ((pd & ~TARGET_PAGE_MASK) == IO_MEM_RAM &&
    16951670                       !cpu_physical_memory_is_dirty(pd)) {
    1696                 env->tlb_write[is_user][index].address = vaddr | IO_MEM_NOTDIRTY;
    1697                 env->tlb_write[is_user][index].addend = addend;
     1671                te->addr_write = vaddr | IO_MEM_NOTDIRTY;
    16981672            } else {
    1699                 env->tlb_write[is_user][index].address = address;
    1700                 env->tlb_write[is_user][index].addend = addend;
     1673                te->addr_write = address;
    17011674            }
    17021675        } else {
    1703             env->tlb_write[is_user][index].address = -1;
    1704             env->tlb_write[is_user][index].addend = -1;
     1676            te->addr_write = -1;
    17051677        }
    17061678#ifdef VBOX
    17071679        /* inform raw mode about TLB page change */
    1708         remR3SetPage(env, &env->tlb_read[is_user][index], &env->tlb_write[is_user][index], prot, is_user);
     1680        /** @todo double check and fix this interface. OLD: remR3SetPage(env, &env->tlb_read[is_user][index], &env->tlb_write[is_user][index], prot, is_user); */
     1681        remR3SetPage(env, te, te, prot, is_user);
    17091682#endif
    17101683    }
     
    17341707                        VirtPageDesc *vp;
    17351708                       
    1736                         vp = virt_page_find_alloc(vaddr >> TARGET_PAGE_BITS);
     1709                        vp = virt_page_find_alloc(vaddr >> TARGET_PAGE_BITS, 1);
    17371710                        vp->phys_addr = pd;
    17381711                        vp->prot = prot;
     
    17561729/* called from signal handler: invalidate the code and unprotect the
    17571730   page. Return TRUE if the fault was succesfully handled. */
    1758 int page_unprotect(unsigned long addr, unsigned long pc, void *puc)
     1731int page_unprotect(target_ulong addr, unsigned long pc, void *puc)
    17591732{
    17601733#if !defined(CONFIG_SOFTMMU)
     
    17861759                  (unsigned long)addr, vp->prot);
    17871760    /* set the dirty bit */
    1788     phys_ram_dirty[vp->phys_addr >> TARGET_PAGE_BITS] = 1;
     1761    phys_ram_dirty[vp->phys_addr >> TARGET_PAGE_BITS] = 0xff;
    17891762    /* flush the code inside */
    17901763    tb_invalidate_phys_page(vp->phys_addr, pc, puc);
     
    18121785}
    18131786
    1814 int tlb_set_page(CPUState *env, target_ulong vaddr,
    1815                  target_phys_addr_t paddr, int prot,
    1816                  int is_user, int is_softmmu)
     1787int tlb_set_page_exec(CPUState *env, target_ulong vaddr,
     1788                      target_phys_addr_t paddr, int prot,
     1789                      int is_user, int is_softmmu)
    18171790{
    18181791    return 0;
     
    18641837#endif /* !VBOX */
    18651838
    1866 int page_get_flags(unsigned long address)
     1839int page_get_flags(target_ulong address)
    18671840{
    18681841    PageDesc *p;
     
    18771850   necessary. The flag PAGE_WRITE_ORG is positionned automatically
    18781851   depending on PAGE_WRITE */
    1879 void page_set_flags(unsigned long start, unsigned long end, int flags)
     1852void page_set_flags(target_ulong start, target_ulong end, int flags)
    18801853{
    18811854    PageDesc *p;
    1882     unsigned long addr;
     1855    target_ulong addr;
    18831856
    18841857    start = start & TARGET_PAGE_MASK;
     
    18861859    if (flags & PAGE_WRITE)
    18871860        flags |= PAGE_WRITE_ORG;
    1888 #if defined(VBOX)
     1861#ifdef VBOX
    18891862    AssertMsgFailed(("We shouldn't be here, and if we should, we must have an env to do the proper locking!\n"));
    18901863#endif
     
    19061879/* called from signal handler: invalidate the code and unprotect the
    19071880   page. Return TRUE if the fault was succesfully handled. */
    1908 int page_unprotect(unsigned long address, unsigned long pc, void *puc)
     1881int page_unprotect(target_ulong address, unsigned long pc, void *puc)
    19091882{
    19101883    unsigned int page_index, prot, pindex;
    19111884    PageDesc *p, *p1;
    1912     unsigned long host_start, host_end, addr;
     1885    target_ulong host_start, host_end, addr;
    19131886
    19141887    host_start = address & qemu_host_page_mask;
     
    19291902        pindex = (address - host_start) >> TARGET_PAGE_BITS;
    19301903        if (!(p1[pindex].flags & PAGE_WRITE)) {
    1931             mprotect((void *)host_start, qemu_host_page_size,
     1904            mprotect((void *)g2h(host_start), qemu_host_page_size,
    19321905                     (prot & PAGE_BITS) | PAGE_WRITE);
    19331906            p1[pindex].flags |= PAGE_WRITE;
     
    19451918
    19461919/* call this function when system calls directly modify a memory area */
    1947 void page_unprotect_range(uint8_t *data, unsigned long data_size)
    1948 {
    1949     unsigned long start, end, addr;
    1950 
    1951     start = (unsigned long)data;
     1920/* ??? This should be redundant now we have lock_user.  */
     1921void page_unprotect_range(target_ulong data, target_ulong data_size)
     1922{
     1923    target_ulong start, end, addr;
     1924
     1925    start = data;
    19521926    end = start + data_size;
    19531927    start &= TARGET_PAGE_MASK;
     
    19581932}
    19591933
    1960 static inline void tlb_set_dirty(unsigned long addr, target_ulong vaddr)
     1934static inline void tlb_set_dirty(CPUState *env,
     1935                                 unsigned long addr, target_ulong vaddr)
    19611936{
    19621937}
     
    19701945                                  unsigned long phys_offset)
    19711946{
    1972     unsigned long addr, end_addr;
     1947    target_phys_addr_t addr, end_addr;
    19731948    PhysPageDesc *p;
     1949    CPUState *env;
    19741950
    19751951    size = (size + TARGET_PAGE_SIZE - 1) & TARGET_PAGE_MASK;
    19761952    end_addr = start_addr + size;
    19771953    for(addr = start_addr; addr != end_addr; addr += TARGET_PAGE_SIZE) {
    1978         p = phys_page_find_alloc(addr >> TARGET_PAGE_BITS);
     1954        p = phys_page_find_alloc(addr >> TARGET_PAGE_BITS, 1);
    19791955        p->phys_offset = phys_offset;
    1980 #ifdef VBOX
     1956#if !defined(VBOX) || !defined(PGM_DYNAMIC_RAM_ALLOC)
     1957        if ((phys_offset & ~TARGET_PAGE_MASK) <= IO_MEM_ROM ||
     1958            (phys_offset & IO_MEM_ROMD))
     1959#else
    19811960        if (   (phys_offset & ~TARGET_PAGE_MASK) <= IO_MEM_ROM
     1961            || (phys_offset & IO_MEM_ROMD)
    19821962            || (phys_offset & ~TARGET_PAGE_MASK) == IO_MEM_RAM_MISSING)
    1983 #else
    1984         if ((phys_offset & ~TARGET_PAGE_MASK) <= IO_MEM_ROM)
    1985 #endif
     1963#endif
     1964
    19861965            phys_offset += TARGET_PAGE_SIZE;
    19871966    }
     1967   
     1968    /* since each CPU stores ram addresses in its TLB cache, we must
     1969       reset the modified entries */
     1970    /* XXX: slow ! */
     1971    for(env = first_cpu; env != NULL; env = env->next_cpu) {
     1972        tlb_flush(env, 1);
     1973    }
     1974}
     1975
     1976/* XXX: temporary until new memory mapping API */
     1977uint32_t cpu_get_physical_page_desc(target_phys_addr_t addr)
     1978{
     1979    PhysPageDesc *p;
     1980
     1981    p = phys_page_find(addr >> TARGET_PAGE_BITS);
     1982    if (!p)
     1983        return IO_MEM_UNASSIGNED;
     1984    return p->phys_offset;
    19881985}
    19891986
    19901987static uint32_t unassigned_mem_readb(void *opaque, target_phys_addr_t addr)
    19911988{
     1989#ifdef DEBUG_UNASSIGNED
     1990    printf("Unassigned mem read  0x%08x\n", (int)addr);
     1991#endif
    19921992    return 0;
    19931993}
     
    19951995static void unassigned_mem_writeb(void *opaque, target_phys_addr_t addr, uint32_t val)
    19961996{
     1997#ifdef DEBUG_UNASSIGNED
     1998    printf("Unassigned mem write 0x%08x = 0x%x\n", (int)addr, val);
     1999#endif
    19972000}
    19982001
     
    20092012};
    20102013
    2011 /* self modifying code support in soft mmu mode : writing to a page
    2012    containing code comes to these functions */
    2013 
    2014 static void code_mem_writeb(void *opaque, target_phys_addr_t addr, uint32_t val)
    2015 {
    2016     unsigned long phys_addr;
    2017 
     2014static void notdirty_mem_writeb(void *opaque, target_phys_addr_t addr, uint32_t val)
     2015{
     2016    unsigned long ram_addr;
     2017    int dirty_flags;
     2018#if defined(VBOX) && defined(REM_PHYS_ADDR_IN_TLB)
     2019    ram_addr = addr;
     2020#elif !defined(VBOX) || !defined(PGM_DYNAMIC_RAM_ALLOC)
     2021    ram_addr = addr - (unsigned long)phys_ram_base;
     2022#else
     2023    ram_addr = remR3HCVirt2GCPhys(first_cpu, (void *)addr);
     2024#endif
    20182025#ifdef VBOX
    2019     phys_addr = remR3HCVirt2GCPhys(cpu_single_env, (void *)addr);
    2020 #else
    2021     phys_addr = addr - (unsigned long)phys_ram_base;
    2022 #endif
     2026    if (RT_UNLIKELY((ram_addr >> TARGET_PAGE_BITS) >= phys_ram_dirty_size))
     2027        dirty_flags = 0xff;
     2028    else
     2029#endif /* VBOX */
     2030    dirty_flags = phys_ram_dirty[ram_addr >> TARGET_PAGE_BITS];
     2031    if (!(dirty_flags & CODE_DIRTY_FLAG)) {
    20232032#if !defined(CONFIG_USER_ONLY)
    2024     tb_invalidate_phys_page_fast(phys_addr, 1);
    2025 #endif
     2033        tb_invalidate_phys_page_fast(ram_addr, 1);
     2034# ifdef VBOX
     2035        if (RT_UNLIKELY((ram_addr >> TARGET_PAGE_BITS) >= phys_ram_dirty_size))
     2036            dirty_flags = 0xff;
     2037        else
     2038# endif /* VBOX */
     2039        dirty_flags = phys_ram_dirty[ram_addr >> TARGET_PAGE_BITS];
     2040#endif
     2041    }
    20262042    stb_p((uint8_t *)(long)addr, val);
    2027     phys_ram_dirty[phys_addr >> TARGET_PAGE_BITS] = 1;
    2028 }
    2029 
    2030 static void code_mem_writew(void *opaque, target_phys_addr_t addr, uint32_t val)
    2031 {
    2032     unsigned long phys_addr;
    2033 
     2043#ifdef USE_KQEMU
     2044    if (cpu_single_env->kqemu_enabled &&
     2045        (dirty_flags & KQEMU_MODIFY_PAGE_MASK) != KQEMU_MODIFY_PAGE_MASK)
     2046        kqemu_modify_page(cpu_single_env, ram_addr);
     2047#endif
     2048    dirty_flags |= (0xff & ~CODE_DIRTY_FLAG);
    20342049#ifdef VBOX
    2035     phys_addr = remR3HCVirt2GCPhys(cpu_single_env, (void *)addr);
    2036 #else
    2037     phys_addr = addr - (unsigned long)phys_ram_base;
    2038 #endif
     2050    if (RT_LIKELY((ram_addr >> TARGET_PAGE_BITS) < phys_ram_dirty_size))
     2051#endif /* !VBOX */
     2052    phys_ram_dirty[ram_addr >> TARGET_PAGE_BITS] = dirty_flags;
     2053    /* we remove the notdirty callback only if the code has been
     2054       flushed */
     2055    if (dirty_flags == 0xff)
     2056        tlb_set_dirty(cpu_single_env, addr, cpu_single_env->mem_write_vaddr);
     2057}
     2058
     2059static void notdirty_mem_writew(void *opaque, target_phys_addr_t addr, uint32_t val)
     2060{
     2061    unsigned long ram_addr;
     2062    int dirty_flags;
     2063#if defined(VBOX) && defined(REM_PHYS_ADDR_IN_TLB)
     2064    ram_addr = addr;
     2065#elif !defined(VBOX) || !defined(PGM_DYNAMIC_RAM_ALLOC)
     2066    ram_addr = addr - (unsigned long)phys_ram_base;
     2067#else
     2068    ram_addr = remR3HCVirt2GCPhys(first_cpu, (void *)addr);
     2069#endif
     2070#ifdef VBOX
     2071    if (RT_UNLIKELY((ram_addr >> TARGET_PAGE_BITS) >= phys_ram_dirty_size))
     2072        dirty_flags = 0xff;
     2073    else
     2074#endif /* VBOX */
     2075    dirty_flags = phys_ram_dirty[ram_addr >> TARGET_PAGE_BITS];
     2076    if (!(dirty_flags & CODE_DIRTY_FLAG)) {
    20392077#if !defined(CONFIG_USER_ONLY)
    2040     tb_invalidate_phys_page_fast(phys_addr, 2);
    2041 #endif
     2078        tb_invalidate_phys_page_fast(ram_addr, 2);
     2079# ifdef VBOX
     2080        if (RT_UNLIKELY((ram_addr >> TARGET_PAGE_BITS) >= phys_ram_dirty_size))
     2081            dirty_flags = 0xff;
     2082        else
     2083# endif /* VBOX */
     2084        dirty_flags = phys_ram_dirty[ram_addr >> TARGET_PAGE_BITS];
     2085#endif
     2086    }
    20422087    stw_p((uint8_t *)(long)addr, val);
    2043     phys_ram_dirty[phys_addr >> TARGET_PAGE_BITS] = 1;
    2044 }
    2045 
    2046 static void code_mem_writel(void *opaque, target_phys_addr_t addr, uint32_t val)
    2047 {
    2048     unsigned long phys_addr;
    2049 
     2088#ifdef USE_KQEMU
     2089    if (cpu_single_env->kqemu_enabled &&
     2090        (dirty_flags & KQEMU_MODIFY_PAGE_MASK) != KQEMU_MODIFY_PAGE_MASK)
     2091        kqemu_modify_page(cpu_single_env, ram_addr);
     2092#endif
     2093    dirty_flags |= (0xff & ~CODE_DIRTY_FLAG);
    20502094#ifdef VBOX
    2051     phys_addr = remR3HCVirt2GCPhys(cpu_single_env, (void *)addr);
    2052 #else
    2053     phys_addr = addr - (unsigned long)phys_ram_base;
    2054 #endif
     2095    if (RT_LIKELY((ram_addr >> TARGET_PAGE_BITS) < phys_ram_dirty_size))
     2096#endif
     2097    phys_ram_dirty[ram_addr >> TARGET_PAGE_BITS] = dirty_flags;
     2098    /* we remove the notdirty callback only if the code has been
     2099       flushed */
     2100    if (dirty_flags == 0xff)
     2101        tlb_set_dirty(cpu_single_env, addr, cpu_single_env->mem_write_vaddr);
     2102}
     2103
     2104static void notdirty_mem_writel(void *opaque, target_phys_addr_t addr, uint32_t val)
     2105{
     2106    unsigned long ram_addr;
     2107    int dirty_flags;
     2108#if defined(VBOX) && defined(REM_PHYS_ADDR_IN_TLB)
     2109    ram_addr = addr;
     2110#elif !defined(VBOX) || !defined(PGM_DYNAMIC_RAM_ALLOC)
     2111    ram_addr = addr - (unsigned long)phys_ram_base;
     2112#else
     2113    ram_addr = remR3HCVirt2GCPhys(first_cpu, (void *)addr);
     2114#endif
     2115#ifdef VBOX
     2116    if (RT_UNLIKELY((ram_addr >> TARGET_PAGE_BITS) >= phys_ram_dirty_size))
     2117        dirty_flags = 0xff;
     2118    else
     2119#endif /* VBOX */
     2120    dirty_flags = phys_ram_dirty[ram_addr >> TARGET_PAGE_BITS];
     2121    if (!(dirty_flags & CODE_DIRTY_FLAG)) {
    20552122#if !defined(CONFIG_USER_ONLY)
    2056     tb_invalidate_phys_page_fast(phys_addr, 4);
    2057 #endif
     2123        tb_invalidate_phys_page_fast(ram_addr, 4);
     2124# ifdef VBOX
     2125        if (RT_UNLIKELY((ram_addr >> TARGET_PAGE_BITS) >= phys_ram_dirty_size))
     2126            dirty_flags = 0xff;
     2127        else
     2128# endif /* VBOX */
     2129        dirty_flags = phys_ram_dirty[ram_addr >> TARGET_PAGE_BITS];
     2130#endif
     2131    }
    20582132    stl_p((uint8_t *)(long)addr, val);
    2059     phys_ram_dirty[phys_addr >> TARGET_PAGE_BITS] = 1;
    2060 }
    2061 
    2062 static CPUReadMemoryFunc *code_mem_read[3] = {
     2133#ifdef USE_KQEMU
     2134    if (cpu_single_env->kqemu_enabled &&
     2135        (dirty_flags & KQEMU_MODIFY_PAGE_MASK) != KQEMU_MODIFY_PAGE_MASK)
     2136        kqemu_modify_page(cpu_single_env, ram_addr);
     2137#endif
     2138    dirty_flags |= (0xff & ~CODE_DIRTY_FLAG);
     2139#ifdef VBOX
     2140    if (RT_LIKELY((ram_addr >> TARGET_PAGE_BITS) < phys_ram_dirty_size))
     2141#endif
     2142    phys_ram_dirty[ram_addr >> TARGET_PAGE_BITS] = dirty_flags;
     2143    /* we remove the notdirty callback only if the code has been
     2144       flushed */
     2145    if (dirty_flags == 0xff)
     2146        tlb_set_dirty(cpu_single_env, addr, cpu_single_env->mem_write_vaddr);
     2147}
     2148
     2149static CPUReadMemoryFunc *error_mem_read[3] = {
    20632150    NULL, /* never used */
    20642151    NULL, /* never used */
    20652152    NULL, /* never used */
    20662153};
    2067 
    2068 static CPUWriteMemoryFunc *code_mem_write[3] = {
    2069     code_mem_writeb,
    2070     code_mem_writew,
    2071     code_mem_writel,
    2072 };
    2073 
    2074 static void notdirty_mem_writeb(void *opaque, target_phys_addr_t addr, uint32_t val)
    2075 {
    2076     stb_p((uint8_t *)(long)addr, val);
    2077     tlb_set_dirty(addr, cpu_single_env->mem_write_vaddr);
    2078 }
    2079 
    2080 static void notdirty_mem_writew(void *opaque, target_phys_addr_t addr, uint32_t val)
    2081 {
    2082     stw_p((uint8_t *)(long)addr, val);
    2083     tlb_set_dirty(addr, cpu_single_env->mem_write_vaddr);
    2084 }
    2085 
    2086 static void notdirty_mem_writel(void *opaque, target_phys_addr_t addr, uint32_t val)
    2087 {
    2088     stl_p((uint8_t *)(long)addr, val);
    2089     tlb_set_dirty(addr, cpu_single_env->mem_write_vaddr);
    2090 }
    20912154
    20922155static CPUWriteMemoryFunc *notdirty_mem_write[3] = {
     
    20982161static void io_mem_init(void)
    20992162{
    2100     cpu_register_io_memory(IO_MEM_ROM >> IO_MEM_SHIFT, code_mem_read, unassigned_mem_write, NULL);
     2163    cpu_register_io_memory(IO_MEM_ROM >> IO_MEM_SHIFT, error_mem_read, unassigned_mem_write, NULL);
    21012164    cpu_register_io_memory(IO_MEM_UNASSIGNED >> IO_MEM_SHIFT, unassigned_mem_read, unassigned_mem_write, NULL);
    2102     cpu_register_io_memory(IO_MEM_CODE >> IO_MEM_SHIFT, code_mem_read, code_mem_write, NULL);
    2103     cpu_register_io_memory(IO_MEM_NOTDIRTY >> IO_MEM_SHIFT, code_mem_read, notdirty_mem_write, NULL);
    2104 #ifdef VBOX
     2165    cpu_register_io_memory(IO_MEM_NOTDIRTY >> IO_MEM_SHIFT, error_mem_read, notdirty_mem_write, NULL);
     2166#if defined(VBOX) && defined(PGM_DYNAMIC_RAM_ALLOC)
    21052167    cpu_register_io_memory(IO_MEM_RAM_MISSING >> IO_MEM_SHIFT, unassigned_mem_read, unassigned_mem_write, NULL);
    21062168    io_mem_nb = 6;
     
    21092171#endif
    21102172
    2111 #if !defined(VBOX) /* VBOX: we do this later when the RAM is allocated. */
     2173#ifndef VBOX /* VBOX: we do this later when the RAM is allocated. */
    21122174    /* alloc dirty bits array */
    2113     phys_ram_dirty = qemu_malloc(phys_ram_size >> TARGET_PAGE_BITS);
     2175    phys_ram_dirty = qemu_vmalloc(phys_ram_size >> TARGET_PAGE_BITS);
     2176    memset(phys_ram_dirty, 0xff, phys_ram_size >> TARGET_PAGE_BITS);
    21142177#endif /* !VBOX */
    21152178}
     
    21292192
    21302193    if (io_index <= 0) {
    2131         if (io_index >= IO_MEM_NB_ENTRIES)
     2194        if (io_mem_nb >= IO_MEM_NB_ENTRIES)
    21322195            return -1;
    21332196        io_index = io_mem_nb++;
     
    21362199            return -1;
    21372200    }
    2138    
     2201
    21392202    for(i = 0;i < 3; i++) {
    21402203        io_mem_read[io_index][i] = mem_read[i];
     
    21622225    int l, flags;
    21632226    target_ulong page;
     2227    void * p;
    21642228
    21652229    while (len > 0) {
     
    21742238            if (!(flags & PAGE_WRITE))
    21752239                return;
    2176             memcpy((uint8_t *)addr, buf, len);
     2240            p = lock_user(addr, len, 0);
     2241            memcpy(p, buf, len);
     2242            unlock_user(p, addr, len);
    21772243        } else {
    21782244            if (!(flags & PAGE_READ))
    21792245                return;
    2180             memcpy(buf, (uint8_t *)addr, len);
     2246            p = lock_user(addr, len, 1);
     2247            memcpy(buf, p, len);
     2248            unlock_user(p, addr, 0);
    21812249        }
    21822250        len -= l;
     
    21842252        addr += l;
    21852253    }
    2186 }
    2187 
    2188 /* never used */
    2189 uint32_t ldl_phys(target_phys_addr_t addr)
    2190 {
    2191     return 0;
    2192 }
    2193 
    2194 void stl_phys_notdirty(target_phys_addr_t addr, uint32_t val)
    2195 {
    2196 }
    2197 
    2198 void stl_phys(target_phys_addr_t addr, uint32_t val)
    2199 {
    22002254}
    22012255
     
    22242278       
    22252279        if (is_write) {
    2226             if ((pd & ~TARGET_PAGE_MASK) != 0) {
     2280            if ((pd & ~TARGET_PAGE_MASK) != IO_MEM_RAM) {
    22272281                io_index = (pd >> IO_MEM_SHIFT) & (IO_MEM_NB_ENTRIES - 1);
     2282                /* XXX: could force cpu_single_env to NULL to avoid
     2283                   potential bugs */
    22282284                if (l >= 4 && ((addr & 3) == 0)) {
    2229                     /* 32 bit read access */
     2285                    /* 32 bit write access */
     2286#if !defined(VBOX) || !defined(REM_PHYS_ADDR_IN_TLB)
    22302287                    val = ldl_p(buf);
     2288#else
     2289                    val = *(const uint32_t *)buf;
     2290#endif
    22312291                    io_mem_write[io_index][2](io_mem_opaque[io_index], addr, val);
    22322292                    l = 4;
    22332293                } else if (l >= 2 && ((addr & 1) == 0)) {
    2234                     /* 16 bit read access */
     2294                    /* 16 bit write access */
     2295#if !defined(VBOX) || !defined(REM_PHYS_ADDR_IN_TLB)
    22352296                    val = lduw_p(buf);
     2297#else
     2298                    val = *(const uint16_t *)buf;
     2299#endif
    22362300                    io_mem_write[io_index][1](io_mem_opaque[io_index], addr, val);
    22372301                    l = 2;
    22382302                } else {
    2239                     /* 8 bit access */
     2303                    /* 8 bit write access */
     2304#if !defined(VBOX) || !defined(REM_PHYS_ADDR_IN_TLB)
    22402305                    val = ldub_p(buf);
     2306#else
     2307                    val = *(const uint8_t *)buf;
     2308#endif
    22412309                    io_mem_write[io_index][0](io_mem_opaque[io_index], addr, val);
    22422310                    l = 1;
     
    22472315                /* RAM case */
    22482316#ifdef VBOX
    2249                 ptr = remR3GCPhys2HCVirt(cpu_single_env, addr1);;
    2250                 remR3PhysWriteBytes(ptr, buf, l);
     2317                remR3PhysWrite(addr1, buf, l); NOREF(ptr);
    22512318#else
    22522319                ptr = phys_ram_base + addr1;
    22532320                memcpy(ptr, buf, l);
    22542321#endif
    2255                 /* invalidate code */
    2256                 tb_invalidate_phys_page_range(addr1, addr1 + l, 0);
    2257                 /* set dirty bit */
    2258                 phys_ram_dirty[addr1 >> TARGET_PAGE_BITS] = 1;               
     2322                if (!cpu_physical_memory_is_dirty(addr1)) {
     2323                    /* invalidate code */
     2324                    tb_invalidate_phys_page_range(addr1, addr1 + l, 0);
     2325                    /* set dirty bit */
     2326#ifdef VBOX
     2327                    if (RT_LIKELY((addr1 >> TARGET_PAGE_BITS) < phys_ram_dirty_size))
     2328#endif
     2329                    phys_ram_dirty[addr1 >> TARGET_PAGE_BITS] |=
     2330                        (0xff & ~CODE_DIRTY_FLAG);
     2331                }
    22592332            }
    22602333        } else {
    2261             if ((pd & ~TARGET_PAGE_MASK) > IO_MEM_ROM &&
    2262                 (pd & ~TARGET_PAGE_MASK) != IO_MEM_CODE) {
     2334            if ((pd & ~TARGET_PAGE_MASK) > IO_MEM_ROM && 
     2335                !(pd & IO_MEM_ROMD)) {
    22632336                /* I/O case */
    22642337                io_index = (pd >> IO_MEM_SHIFT) & (IO_MEM_NB_ENTRIES - 1);
     
    22662339                    /* 32 bit read access */
    22672340                    val = io_mem_read[io_index][2](io_mem_opaque[io_index], addr);
     2341#if !defined(VBOX) || !defined(REM_PHYS_ADDR_IN_TLB)
    22682342                    stl_p(buf, val);
     2343#else
     2344                    *(uint32_t *)buf = val;
     2345#endif
    22692346                    l = 4;
    22702347                } else if (l >= 2 && ((addr & 1) == 0)) {
    22712348                    /* 16 bit read access */
    22722349                    val = io_mem_read[io_index][1](io_mem_opaque[io_index], addr);
     2350#if !defined(VBOX) || !defined(REM_PHYS_ADDR_IN_TLB)
    22732351                    stw_p(buf, val);
     2352#else
     2353                    *(uint16_t *)buf = val;
     2354#endif
    22742355                    l = 2;
    22752356                } else {
    2276                     /* 8 bit access */
     2357                    /* 8 bit read access */
    22772358                    val = io_mem_read[io_index][0](io_mem_opaque[io_index], addr);
     2359#if !defined(VBOX) || !defined(REM_PHYS_ADDR_IN_TLB)
    22782360                    stb_p(buf, val);
     2361#else
     2362                    *(uint8_t *)buf = val;
     2363#endif
    22792364                    l = 1;
    22802365                }
     
    22822367                /* RAM case */
    22832368#ifdef VBOX
    2284                 ptr = remR3GCPhys2HCVirt(cpu_single_env, (pd & TARGET_PAGE_MASK) + (addr & ~TARGET_PAGE_MASK));
    2285                 remR3PhysReadBytes(ptr, buf, l);
     2369                remR3PhysRead((pd & TARGET_PAGE_MASK) + (addr & ~TARGET_PAGE_MASK), buf, l); NOREF(ptr);
    22862370#else
    22872371                ptr = phys_ram_base + (pd & TARGET_PAGE_MASK) +
     
    22962380    }
    22972381}
     2382
     2383#ifndef VBOX
     2384/* used for ROM loading : can write in RAM and ROM */
     2385void cpu_physical_memory_write_rom(target_phys_addr_t addr,
     2386                                   const uint8_t *buf, int len)
     2387{
     2388    int l;
     2389    uint8_t *ptr;
     2390    target_phys_addr_t page;
     2391    unsigned long pd;
     2392    PhysPageDesc *p;
     2393   
     2394    while (len > 0) {
     2395        page = addr & TARGET_PAGE_MASK;
     2396        l = (page + TARGET_PAGE_SIZE) - addr;
     2397        if (l > len)
     2398            l = len;
     2399        p = phys_page_find(page >> TARGET_PAGE_BITS);
     2400        if (!p) {
     2401            pd = IO_MEM_UNASSIGNED;
     2402        } else {
     2403            pd = p->phys_offset;
     2404        }
     2405       
     2406        if ((pd & ~TARGET_PAGE_MASK) != IO_MEM_RAM &&
     2407            (pd & ~TARGET_PAGE_MASK) != IO_MEM_ROM &&
     2408            !(pd & IO_MEM_ROMD)) {
     2409            /* do nothing */
     2410        } else {
     2411            unsigned long addr1;
     2412            addr1 = (pd & TARGET_PAGE_MASK) + (addr & ~TARGET_PAGE_MASK);
     2413            /* ROM/RAM case */
     2414            ptr = phys_ram_base + addr1;
     2415            memcpy(ptr, buf, l);
     2416        }
     2417        len -= l;
     2418        buf += l;
     2419        addr += l;
     2420    }
     2421}
     2422#endif /* !VBOX */
     2423
    22982424
    22992425/* warning: addr must be aligned */
     
    23132439    }
    23142440       
    2315     if ((pd & ~TARGET_PAGE_MASK) > IO_MEM_ROM &&
    2316         (pd & ~TARGET_PAGE_MASK) != IO_MEM_CODE) {
     2441    if ((pd & ~TARGET_PAGE_MASK) > IO_MEM_ROM && 
     2442        !(pd & IO_MEM_ROMD)) {
    23172443        /* I/O case */
    23182444        io_index = (pd >> IO_MEM_SHIFT) & (IO_MEM_NB_ENTRIES - 1);
     
    23202446    } else {
    23212447        /* RAM case */
    2322 #ifdef VBOX
    2323         ptr = remR3GCPhys2HCVirt(cpu_single_env, (pd & TARGET_PAGE_MASK) + (addr & ~TARGET_PAGE_MASK));
    2324 #else
     2448#ifndef VBOX
    23252449        ptr = phys_ram_base + (pd & TARGET_PAGE_MASK) +
    23262450            (addr & ~TARGET_PAGE_MASK);
    2327 #endif
    23282451        val = ldl_p(ptr);
     2452#else
     2453        val = remR3PhysReadU32((pd & TARGET_PAGE_MASK) + (addr & ~TARGET_PAGE_MASK)); NOREF(ptr);
     2454#endif
    23292455    }
    23302456    return val;
    23312457}
    23322458
    2333 /* warning: addr must be aligned. The ram page is not masked as dirty
    2334    and the code inside is not invalidated. It is useful if the dirty
    2335    bits are used to track modified PTEs */
    2336 void stl_phys_notdirty(target_phys_addr_t addr, uint32_t val)
     2459/* warning: addr must be aligned */
     2460uint64_t ldq_phys(target_phys_addr_t addr)
    23372461{
    23382462    int io_index;
    23392463    uint8_t *ptr;
     2464    uint64_t val;
    23402465    unsigned long pd;
    23412466    PhysPageDesc *p;
     
    23482473    }
    23492474       
    2350     if ((pd & ~TARGET_PAGE_MASK) != 0) {
     2475    if ((pd & ~TARGET_PAGE_MASK) > IO_MEM_ROM &&
     2476        !(pd & IO_MEM_ROMD)) {
     2477        /* I/O case */
    23512478        io_index = (pd >> IO_MEM_SHIFT) & (IO_MEM_NB_ENTRIES - 1);
    2352         io_mem_write[io_index][2](io_mem_opaque[io_index], addr, val);
     2479#ifdef TARGET_WORDS_BIGENDIAN
     2480        val = (uint64_t)io_mem_read[io_index][2](io_mem_opaque[io_index], addr) << 32;
     2481        val |= io_mem_read[io_index][2](io_mem_opaque[io_index], addr + 4);
     2482#else
     2483        val = io_mem_read[io_index][2](io_mem_opaque[io_index], addr);
     2484        val |= (uint64_t)io_mem_read[io_index][2](io_mem_opaque[io_index], addr + 4) << 32;
     2485#endif
    23532486    } else {
    2354 #ifdef VBOX
    2355         ptr = remR3GCPhys2HCVirt(cpu_single_env, (pd & TARGET_PAGE_MASK) + (addr & ~TARGET_PAGE_MASK));
    2356 #else
     2487        /* RAM case */
     2488#ifndef VBOX
    23572489        ptr = phys_ram_base + (pd & TARGET_PAGE_MASK) +
    23582490            (addr & ~TARGET_PAGE_MASK);
    2359 #endif
    2360         stl_p(ptr, val);
    2361     }
    2362 }
    2363 
    2364 /* warning: addr must be aligned */
    2365 /* XXX: optimize code invalidation test */
    2366 void stl_phys(target_phys_addr_t addr, uint32_t val)
     2491        val = ldq_p(ptr);
     2492#else
     2493        val = remR3PhysReadU64((pd & TARGET_PAGE_MASK) + (addr & ~TARGET_PAGE_MASK)); NOREF(ptr);
     2494#endif
     2495    }
     2496    return val;
     2497}
     2498
     2499/* XXX: optimize */
     2500uint32_t ldub_phys(target_phys_addr_t addr)
     2501{
     2502    uint8_t val;
     2503    cpu_physical_memory_read(addr, &val, 1);
     2504    return val;
     2505}
     2506
     2507/* XXX: optimize */
     2508uint32_t lduw_phys(target_phys_addr_t addr)
     2509{
     2510    uint16_t val;
     2511    cpu_physical_memory_read(addr, (uint8_t *)&val, 2);
     2512    return tswap16(val);
     2513}
     2514
     2515/* warning: addr must be aligned. The ram page is not masked as dirty
     2516   and the code inside is not invalidated. It is useful if the dirty
     2517   bits are used to track modified PTEs */
     2518void stl_phys_notdirty(target_phys_addr_t addr, uint32_t val)
    23672519{
    23682520    int io_index;
     
    23782530    }
    23792531       
    2380     if ((pd & ~TARGET_PAGE_MASK) != 0) {
     2532    if ((pd & ~TARGET_PAGE_MASK) != IO_MEM_RAM) {
     2533        io_index = (pd >> IO_MEM_SHIFT) & (IO_MEM_NB_ENTRIES - 1);
     2534        io_mem_write[io_index][2](io_mem_opaque[io_index], addr, val);
     2535    } else {
     2536#ifndef VBOX
     2537        ptr = phys_ram_base + (pd & TARGET_PAGE_MASK) +
     2538            (addr & ~TARGET_PAGE_MASK);
     2539        stl_p(ptr, val);
     2540#else
     2541        remR3PhysWriteU32((pd & TARGET_PAGE_MASK) + (addr & ~TARGET_PAGE_MASK), val); NOREF(ptr);
     2542#endif
     2543    }
     2544}
     2545
     2546/* warning: addr must be aligned */
     2547void stl_phys(target_phys_addr_t addr, uint32_t val)
     2548{
     2549    int io_index;
     2550    uint8_t *ptr;
     2551    unsigned long pd;
     2552    PhysPageDesc *p;
     2553
     2554    p = phys_page_find(addr >> TARGET_PAGE_BITS);
     2555    if (!p) {
     2556        pd = IO_MEM_UNASSIGNED;
     2557    } else {
     2558        pd = p->phys_offset;
     2559    }
     2560       
     2561    if ((pd & ~TARGET_PAGE_MASK) != IO_MEM_RAM) {
    23812562        io_index = (pd >> IO_MEM_SHIFT) & (IO_MEM_NB_ENTRIES - 1);
    23822563        io_mem_write[io_index][2](io_mem_opaque[io_index], addr, val);
     
    23852566        addr1 = (pd & TARGET_PAGE_MASK) + (addr & ~TARGET_PAGE_MASK);
    23862567        /* RAM case */
     2568#ifndef VBOX
     2569        ptr = phys_ram_base + addr1;
     2570        stl_p(ptr, val);
     2571#else
     2572        remR3PhysWriteU32((pd & TARGET_PAGE_MASK) + (addr & ~TARGET_PAGE_MASK), val); NOREF(ptr);
     2573#endif
     2574        if (!cpu_physical_memory_is_dirty(addr1)) {
     2575            /* invalidate code */
     2576            tb_invalidate_phys_page_range(addr1, addr1 + 4, 0);
     2577            /* set dirty bit */
    23872578#ifdef VBOX
    2388         ptr = remR3GCPhys2HCVirt(cpu_single_env, addr1);
    2389 #else
    2390         ptr = phys_ram_base + addr1;
    2391 #endif
    2392         stl_p(ptr, val);
    2393         /* invalidate code */
    2394         tb_invalidate_phys_page_range(addr1, addr1 + 4, 0);
    2395         /* set dirty bit */
    2396         phys_ram_dirty[addr1 >> TARGET_PAGE_BITS] = 1;
    2397     }
    2398 }
    2399 
    2400 #endif
    2401 
     2579            if (RT_LIKELY((addr1 >> TARGET_PAGE_BITS) < phys_ram_dirty_size))
     2580#endif
     2581            phys_ram_dirty[addr1 >> TARGET_PAGE_BITS] |=
     2582                (0xff & ~CODE_DIRTY_FLAG);
     2583        }
     2584    }
     2585}
     2586
     2587/* XXX: optimize */
     2588void stb_phys(target_phys_addr_t addr, uint32_t val)
     2589{
     2590    uint8_t v = val;
     2591    cpu_physical_memory_write(addr, &v, 1);
     2592}
     2593
     2594/* XXX: optimize */
     2595void stw_phys(target_phys_addr_t addr, uint32_t val)
     2596{
     2597    uint16_t v = tswap16(val);
     2598    cpu_physical_memory_write(addr, (const uint8_t *)&v, 2);
     2599}
     2600
     2601/* XXX: optimize */
     2602void stq_phys(target_phys_addr_t addr, uint64_t val)
     2603{
     2604    val = tswap64(val);
     2605    cpu_physical_memory_write(addr, (const uint8_t *)&val, 8);
     2606}
     2607
     2608#endif
     2609
     2610#ifndef VBOX
    24022611/* virtual memory access for debug */
    24032612int cpu_memory_rw_debug(CPUState *env, target_ulong addr,
     
    24252634}
    24262635
    2427 #ifndef VBOX
    24282636void dump_exec_info(FILE *f,
    24292637                    int (*cpu_fprintf)(FILE *f, const char *fmt, ...))
  • trunk/src/recompiler/osdep.h

    r1 r2422  
    22#define QEMU_OSDEP_H
    33
    4 #if defined(VBOX)
     4#ifdef VBOX
    55
    66#include <iprt/alloc.h>
     7#include <iprt/stdarg.h>
    78#include <iprt/string.h>
    89
    9 #define qemu_vsnprintf(pszBuf, cchBuf, pszFormat, args) \
    10                             RTStrPrintfV((pszBuf), (cchBuf), (pszFormat), (args))
     10#define qemu_snprintf(pszBuf, cbBuf, ...) RTStrPrintf((pszBuf), (cbBuf), __VA_ARGS__)
     11#define qemu_vsnprintf(pszBuf, cbBuf, pszFormat, args) \
     12                            RTStrPrintfV((pszBuf), (cbBuf), (pszFormat), (args))
    1113#define qemu_vprintf(pszFormat, args) \
    1214                            RTLogPrintfV((pszFormat), (args))
     
    1719#define qemu_strdup(psz)    RTStrDup(psz)
    1820
     21#define qemu_vmalloc(cb)    RTMemPageAlloc(cb)
     22#define qemu_vfree(pv)      RTMemPageFree(pv)
     23
     24#ifndef NULL
     25# define NULL 0
     26#endif
    1927
    2028#else /* !VBOX */
     
    2230#include <stdarg.h>
    2331
    24 int qemu_vsnprintf(char *buf, int buflen, const char *fmt, va_list args);
    25 void qemu_vprintf(const char *fmt, va_list ap);
    26 void qemu_printf(const char *fmt, ...);
     32#define qemu_snprintf snprintf   /* bird */
     33#define qemu_vsnprintf vsnprintf /* bird */
     34#define qemu_vprintf vprintf     /* bird */
     35
     36#define qemu_printf printf
    2737
    2838void *qemu_malloc(size_t size);
     
    3141char *qemu_strdup(const char *str);
    3242
     43void *qemu_vmalloc(size_t size);
     44void qemu_vfree(void *ptr);
     45
    3346void *get_mmap_addr(unsigned long size);
    34 
    35 /* specific kludges for OS compatibility (should be moved elsewhere) */
    36 #if defined(__i386__) && !defined(CONFIG_SOFTMMU) && !defined(CONFIG_USER_ONLY)
    37 
    38 /* disabled pthread version of longjmp which prevent us from using an
    39    alternative signal stack */
    40 extern void __longjmp(jmp_buf env, int val);
    41 #define longjmp __longjmp
    42 
    43 #include <signal.h>
    44 
    45 /* NOTE: it works only because the glibc sigset_t is >= kernel sigset_t */
    46 struct qemu_sigaction {
    47     union {
    48         void (*_sa_handler)(int);
    49         void (*_sa_sigaction)(int, struct siginfo *, void *);
    50     } _u;
    51     unsigned long sa_flags;
    52     void (*sa_restorer)(void);
    53     sigset_t sa_mask;           /* mask last for extensibility */
    54 };
    55 
    56 int qemu_sigaction(int signum, const struct qemu_sigaction *act,
    57                    struct qemu_sigaction *oldact);
    58 
    59 #undef sigaction
    60 #undef sa_handler
    61 #undef sa_sigaction
    62 #define sigaction qemu_sigaction
    63 #define sa_handler      _u._sa_handler
    64 #define sa_sigaction    _u._sa_sigaction
    65 
    66 #endif
    6747
    6848#endif /* !VBOX */
  • trunk/src/recompiler/softmmu_header.h

    r1 r2422  
    1818 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
    1919 */
    20 
    2120#if DATA_SIZE == 8
    2221#define SUFFIX q
     
    5756#elif defined (TARGET_PPC)
    5857#define CPU_MEM_INDEX (msr_pr)
     58#elif defined (TARGET_MIPS)
     59#define CPU_MEM_INDEX ((env->hflags & MIPS_HFLAG_MODE) == MIPS_HFLAG_UM)
    5960#elif defined (TARGET_SPARC)
    6061#define CPU_MEM_INDEX ((env->psrs) == 0)
     62#elif defined (TARGET_ARM)
     63#define CPU_MEM_INDEX ((env->uncached_cpsr & CPSR_M) == ARM_CPU_MODE_USR)
     64#elif defined (TARGET_SH4)
     65#define CPU_MEM_INDEX ((env->sr & SR_MD) == 0)
     66#else
     67#error unsupported CPU
    6168#endif
    6269#define MMUSUFFIX _mmu
     
    6875#elif defined (TARGET_PPC)
    6976#define CPU_MEM_INDEX (msr_pr)
     77#elif defined (TARGET_MIPS)
     78#define CPU_MEM_INDEX ((env->hflags & MIPS_HFLAG_MODE) == MIPS_HFLAG_UM)
    7079#elif defined (TARGET_SPARC)
    7180#define CPU_MEM_INDEX ((env->psrs) == 0)
     81#elif defined (TARGET_ARM)
     82#define CPU_MEM_INDEX ((env->uncached_cpsr & CPSR_M) == ARM_CPU_MODE_USR)
     83#elif defined (TARGET_SH4)
     84#define CPU_MEM_INDEX ((env->sr & SR_MD) == 0)
     85#else
     86#error unsupported CPU
    7287#endif
    7388#define MMUSUFFIX _cmmu
     
    8398#endif
    8499
     100#if ACCESS_TYPE == 3
     101#define ADDR_READ addr_code
     102#else
     103#define ADDR_READ addr_read
     104#endif
    85105
    86106DATA_TYPE REGPARM(1) glue(glue(__ld, SUFFIX), MMUSUFFIX)(target_ulong addr,
     
    89109
    90110#if (DATA_SIZE <= 4) && (TARGET_LONG_BITS == 32) && defined(__i386__) && \
    91     (ACCESS_TYPE <= 1) && defined(ASM_SOFTMMU)
     111    (ACCESS_TYPE <= 1) && defined(ASM_SOFTMMU) && (!defined(VBOX) || !defined(REM_PHYS_ADDR_IN_TLB))
     112
     113#define CPU_TLB_ENTRY_BITS 4
    92114
    93115static inline RES_TYPE glue(glue(ld, USUFFIX), MEMSUFFIX)(target_ulong ptr)
     
    110132                  "jmp 2f\n"
    111133                  "1:\n"
    112                   "addl 4(%%edx), %%eax\n"
     134                  "addl 12(%%edx), %%eax\n"
    113135#if DATA_SIZE == 1
    114136                  "movzbl (%%eax), %0\n"
     
    123145                  : "=r" (res)
    124146                  : "r" (ptr),
    125                   "i" ((CPU_TLB_SIZE - 1) << 3),
    126                   "i" (TARGET_PAGE_BITS - 3),
     147                  "i" ((CPU_TLB_SIZE - 1) << CPU_TLB_ENTRY_BITS),
     148                  "i" (TARGET_PAGE_BITS - CPU_TLB_ENTRY_BITS),
    127149                  "i" (TARGET_PAGE_MASK | (DATA_SIZE - 1)),
    128                   "m" (*(uint32_t *)offsetof(CPUState, tlb_read[CPU_MEM_INDEX][0].address)),
     150                  "m" (*(uint32_t *)offsetof(CPUState, tlb_table[CPU_MEM_INDEX][0].addr_read)),
    129151                  "i" (CPU_MEM_INDEX),
    130152                  "m" (*(uint8_t *)&glue(glue(__ld, SUFFIX), MMUSUFFIX))
     
    159181                  "jmp 2f\n"
    160182                  "1:\n"
    161                   "addl 4(%%edx), %%eax\n"
     183                  "addl 12(%%edx), %%eax\n"
    162184#if DATA_SIZE == 1
    163185                  "movsbl (%%eax), %0\n"
     
    170192                  : "=r" (res)
    171193                  : "r" (ptr),
    172                   "i" ((CPU_TLB_SIZE - 1) << 3),
    173                   "i" (TARGET_PAGE_BITS - 3),
     194                  "i" ((CPU_TLB_SIZE - 1) << CPU_TLB_ENTRY_BITS),
     195                  "i" (TARGET_PAGE_BITS - CPU_TLB_ENTRY_BITS),
    174196                  "i" (TARGET_PAGE_MASK | (DATA_SIZE - 1)),
    175                   "m" (*(uint32_t *)offsetof(CPUState, tlb_read[CPU_MEM_INDEX][0].address)),
     197                  "m" (*(uint32_t *)offsetof(CPUState, tlb_table[CPU_MEM_INDEX][0].addr_read)),
    176198                  "i" (CPU_MEM_INDEX),
    177199                  "m" (*(uint8_t *)&glue(glue(__ld, SUFFIX), MMUSUFFIX))
     
    194216    index = (addr >> TARGET_PAGE_BITS) & (CPU_TLB_SIZE - 1);
    195217    is_user = CPU_MEM_INDEX;
    196     if (__builtin_expect(env->tlb_write[is_user][index].address !=
     218    if (__builtin_expect(env->tlb_table[is_user][index].addr_write !=
    197219                         (addr & (TARGET_PAGE_MASK | (DATA_SIZE - 1))), 0)) {
    198220        glue(glue(__st, SUFFIX), MMUSUFFIX)(addr, v, is_user);
    199221    } else {
    200         physaddr = addr + env->tlb_write[is_user][index].addend;
     222        physaddr = addr + env->tlb_table[is_user][index].addend;
    201223        glue(glue(st, SUFFIX), _raw)((uint8_t *)physaddr, v);
    202224    }
    203225}
    204226
    205 #else
     227#else /* !VBOX */
    206228
    207229static inline void glue(glue(st, SUFFIX), MEMSUFFIX)(target_ulong ptr, RES_TYPE v)
     
    230252                  "jmp 2f\n"
    231253                  "1:\n"
    232                   "addl 4(%%edx), %%eax\n"
     254                  "addl 8(%%edx), %%eax\n"
    233255#if DATA_SIZE == 1
    234256                  "movb %b1, (%%eax)\n"
     
    246268   with T1 ! */
    247269                  "r" (v),
    248                   "i" ((CPU_TLB_SIZE - 1) << 3),
    249                   "i" (TARGET_PAGE_BITS - 3),
     270                  "i" ((CPU_TLB_SIZE - 1) << CPU_TLB_ENTRY_BITS),
     271                  "i" (TARGET_PAGE_BITS - CPU_TLB_ENTRY_BITS),
    250272                  "i" (TARGET_PAGE_MASK | (DATA_SIZE - 1)),
    251                   "m" (*(uint32_t *)offsetof(CPUState, tlb_write[CPU_MEM_INDEX][0].address)),
     273                  "m" (*(uint32_t *)offsetof(CPUState, tlb_table[CPU_MEM_INDEX][0].addr_write)),
    252274                  "i" (CPU_MEM_INDEX),
    253275                  "m" (*(uint8_t *)&glue(glue(__st, SUFFIX), MMUSUFFIX))
    254276                  : "%eax", "%ecx", "%edx", "memory", "cc");
    255277}
    256 #endif /* VBOX */
     278#endif /* !VBOX */
    257279
    258280#else
     
    271293    index = (addr >> TARGET_PAGE_BITS) & (CPU_TLB_SIZE - 1);
    272294    is_user = CPU_MEM_INDEX;
    273     if (__builtin_expect(env->tlb_read[is_user][index].address !=
     295    if (__builtin_expect(env->tlb_table[is_user][index].ADDR_READ !=
    274296                         (addr & (TARGET_PAGE_MASK | (DATA_SIZE - 1))), 0)) {
    275297        res = glue(glue(__ld, SUFFIX), MMUSUFFIX)(addr, is_user);
    276298    } else {
    277         physaddr = addr + env->tlb_read[is_user][index].addend;
     299        physaddr = addr + env->tlb_table[is_user][index].addend;
    278300        res = glue(glue(ld, USUFFIX), _raw)((uint8_t *)physaddr);
    279301    }
     
    292314    index = (addr >> TARGET_PAGE_BITS) & (CPU_TLB_SIZE - 1);
    293315    is_user = CPU_MEM_INDEX;
    294     if (__builtin_expect(env->tlb_read[is_user][index].address !=
     316    if (__builtin_expect(env->tlb_table[is_user][index].ADDR_READ !=
    295317                         (addr & (TARGET_PAGE_MASK | (DATA_SIZE - 1))), 0)) {
    296318        res = (DATA_STYPE)glue(glue(__ld, SUFFIX), MMUSUFFIX)(addr, is_user);
    297319    } else {
    298         physaddr = addr + env->tlb_read[is_user][index].addend;
     320        physaddr = addr + env->tlb_table[is_user][index].addend;
    299321        res = glue(glue(lds, SUFFIX), _raw)((uint8_t *)physaddr);
    300322    }
     
    302324}
    303325#endif
     326
     327#if ACCESS_TYPE != 3
    304328
    305329/* generic store macro */
     
    315339    index = (addr >> TARGET_PAGE_BITS) & (CPU_TLB_SIZE - 1);
    316340    is_user = CPU_MEM_INDEX;
    317     if (__builtin_expect(env->tlb_write[is_user][index].address !=
     341    if (__builtin_expect(env->tlb_table[is_user][index].addr_write !=
    318342                         (addr & (TARGET_PAGE_MASK | (DATA_SIZE - 1))), 0)) {
    319343        glue(glue(__st, SUFFIX), MMUSUFFIX)(addr, v, is_user);
    320344    } else {
    321         physaddr = addr + env->tlb_write[is_user][index].addend;
     345        physaddr = addr + env->tlb_table[is_user][index].addend;
    322346        glue(glue(st, SUFFIX), _raw)((uint8_t *)physaddr, v);
    323347    }
    324348}
    325349
    326 #endif
     350#endif /* ACCESS_TYPE != 3 */
     351
     352#endif /* !asm */
     353
     354#if ACCESS_TYPE != 3
    327355
    328356#if DATA_SIZE == 8
    329 static inline double glue(ldfq, MEMSUFFIX)(target_ulong ptr)
     357static inline float64 glue(ldfq, MEMSUFFIX)(target_ulong ptr)
    330358{
    331359    union {
    332         double d;
     360        float64 d;
    333361        uint64_t i;
    334362    } u;
     
    337365}
    338366
    339 static inline void glue(stfq, MEMSUFFIX)(target_ulong ptr, double v)
     367static inline void glue(stfq, MEMSUFFIX)(target_ulong ptr, float64 v)
    340368{
    341369    union {
    342         double d;
     370        float64 d;
    343371        uint64_t i;
    344372    } u;
     
    349377
    350378#if DATA_SIZE == 4
    351 static inline float glue(ldfl, MEMSUFFIX)(target_ulong ptr)
     379static inline float32 glue(ldfl, MEMSUFFIX)(target_ulong ptr)
    352380{
    353381    union {
    354         float f;
     382        float32 f;
    355383        uint32_t i;
    356384    } u;
     
    359387}
    360388
    361 static inline void glue(stfl, MEMSUFFIX)(target_ulong ptr, float v)
     389static inline void glue(stfl, MEMSUFFIX)(target_ulong ptr, float32 v)
    362390{
    363391    union {
    364         float f;
     392        float32 f;
    365393        uint32_t i;
    366394    } u;
     
    369397}
    370398#endif /* DATA_SIZE == 4 */
     399
     400#endif /* ACCESS_TYPE != 3 */
    371401
    372402#undef RES_TYPE
     
    378408#undef CPU_MEM_INDEX
    379409#undef MMUSUFFIX
     410#undef ADDR_READ
  • trunk/src/recompiler/softmmu_template.h

    r1 r2422  
    4242#ifdef SOFTMMU_CODE_ACCESS
    4343#define READ_ACCESS_TYPE 2
     44#define ADDR_READ addr_code
    4445#else
    4546#define READ_ACCESS_TYPE 0
     47#define ADDR_READ addr_read
    4648#endif
    4749
     
    4951                                                        int is_user,
    5052                                                        void *retaddr);
    51 static inline DATA_TYPE glue(io_read, SUFFIX)(unsigned long physaddr,
     53static inline DATA_TYPE glue(io_read, SUFFIX)(target_phys_addr_t physaddr,
    5254                                              target_ulong tlb_addr)
    5355{
     
    6769#endif
    6870#endif /* SHIFT > 2 */
     71#ifdef USE_KQEMU
     72    env->last_io_time = cpu_get_time_fast();
     73#endif
    6974    return res;
    7075}
     
    7782    int index;
    7883    target_ulong tlb_addr;
    79     unsigned long physaddr;
     84    target_phys_addr_t physaddr;
    8085    void *retaddr;
    8186   
     
    8489    index = (addr >> TARGET_PAGE_BITS) & (CPU_TLB_SIZE - 1);
    8590 redo:
    86     tlb_addr = env->tlb_read[is_user][index].address;
     91    tlb_addr = env->tlb_table[is_user][index].ADDR_READ;
    8792    if ((addr & TARGET_PAGE_MASK) == (tlb_addr & (TARGET_PAGE_MASK | TLB_INVALID_MASK))) {
    88         physaddr = addr + env->tlb_read[is_user][index].addend;
     93        physaddr = addr + env->tlb_table[is_user][index].addend;
    8994        if (tlb_addr & ~TARGET_PAGE_MASK) {
    9095            /* IO access */
     
    9297                goto do_unaligned_access;
    9398            res = glue(io_read, SUFFIX)(physaddr, tlb_addr);
    94         } else if (((addr & 0xfff) + DATA_SIZE - 1) >= TARGET_PAGE_SIZE) {
     99        } else if (((addr & ~TARGET_PAGE_MASK) + DATA_SIZE - 1) >= TARGET_PAGE_SIZE) {
    95100            /* slow unaligned access (it spans two pages or IO) */
    96101        do_unaligned_access:
    97102            retaddr = GETPC();
     103#ifdef ALIGNED_ONLY
     104            do_unaligned_access(addr, READ_ACCESS_TYPE, is_user, retaddr);
     105#endif
    98106            res = glue(glue(slow_ld, SUFFIX), MMUSUFFIX)(addr,
    99107                                                         is_user, retaddr);
    100108        } else {
    101             /* unaligned access in the same page */
    102             res = glue(glue(ld, USUFFIX), _raw)((uint8_t *)physaddr);
     109            /* unaligned/aligned access in the same page */
     110#ifdef ALIGNED_ONLY
     111            if ((addr & (DATA_SIZE - 1)) != 0) {
     112                retaddr = GETPC();
     113                do_unaligned_access(addr, READ_ACCESS_TYPE, is_user, retaddr);
     114            }
     115#endif
     116            res = glue(glue(ld, USUFFIX), _raw)((uint8_t *)(long)physaddr);
    103117        }
    104118    } else {
    105119        /* the page is not in the TLB : fill it */
    106120        retaddr = GETPC();
     121#ifdef ALIGNED_ONLY
     122        if ((addr & (DATA_SIZE - 1)) != 0)
     123            do_unaligned_access(addr, READ_ACCESS_TYPE, is_user, retaddr);
     124#endif
    107125        tlb_fill(addr, READ_ACCESS_TYPE, is_user, retaddr);
    108126        goto redo;
     
    118136    DATA_TYPE res, res1, res2;
    119137    int index, shift;
    120     unsigned long physaddr;
     138    target_phys_addr_t physaddr;
    121139    target_ulong tlb_addr, addr1, addr2;
    122140
    123141    index = (addr >> TARGET_PAGE_BITS) & (CPU_TLB_SIZE - 1);
    124142 redo:
    125     tlb_addr = env->tlb_read[is_user][index].address;
     143    tlb_addr = env->tlb_table[is_user][index].ADDR_READ;
    126144    if ((addr & TARGET_PAGE_MASK) == (tlb_addr & (TARGET_PAGE_MASK | TLB_INVALID_MASK))) {
    127         physaddr = addr + env->tlb_read[is_user][index].addend;
     145        physaddr = addr + env->tlb_table[is_user][index].addend;
    128146        if (tlb_addr & ~TARGET_PAGE_MASK) {
    129147            /* IO access */
     
    131149                goto do_unaligned_access;
    132150            res = glue(io_read, SUFFIX)(physaddr, tlb_addr);
    133         } else if (((addr & 0xfff) + DATA_SIZE - 1) >= TARGET_PAGE_SIZE) {
     151        } else if (((addr & ~TARGET_PAGE_MASK) + DATA_SIZE - 1) >= TARGET_PAGE_SIZE) {
    134152        do_unaligned_access:
    135153            /* slow unaligned access (it spans two pages) */
     
    149167        } else {
    150168            /* unaligned/aligned access in the same page */
    151             res = glue(glue(ld, USUFFIX), _raw)((uint8_t *)physaddr);
     169            res = glue(glue(ld, USUFFIX), _raw)((uint8_t *)(long)physaddr);
    152170        }
    153171    } else {
     
    166184                                                   void *retaddr);
    167185
    168 static inline void glue(io_write, SUFFIX)(unsigned long physaddr,
     186static inline void glue(io_write, SUFFIX)(target_phys_addr_t physaddr,
    169187                                          DATA_TYPE val,
    170188                                          target_ulong tlb_addr,
     
    187205#endif
    188206#endif /* SHIFT > 2 */
     207#ifdef USE_KQEMU
     208    env->last_io_time = cpu_get_time_fast();
     209#endif
    189210}
    190211
     
    193214                                                    int is_user)
    194215{
    195     unsigned long physaddr;
     216    target_phys_addr_t physaddr;
    196217    target_ulong tlb_addr;
    197218    void *retaddr;
     
    200221    index = (addr >> TARGET_PAGE_BITS) & (CPU_TLB_SIZE - 1);
    201222 redo:
    202     tlb_addr = env->tlb_write[is_user][index].address;
     223    tlb_addr = env->tlb_table[is_user][index].addr_write;
    203224    if ((addr & TARGET_PAGE_MASK) == (tlb_addr & (TARGET_PAGE_MASK | TLB_INVALID_MASK))) {
    204         physaddr = addr + env->tlb_write[is_user][index].addend;
     225        physaddr = addr + env->tlb_table[is_user][index].addend;
    205226        if (tlb_addr & ~TARGET_PAGE_MASK) {
    206227            /* IO access */
     
    209230            retaddr = GETPC();
    210231            glue(io_write, SUFFIX)(physaddr, val, tlb_addr, retaddr);
    211         } else if (((addr & 0xfff) + DATA_SIZE - 1) >= TARGET_PAGE_SIZE) {
     232        } else if (((addr & ~TARGET_PAGE_MASK) + DATA_SIZE - 1) >= TARGET_PAGE_SIZE) {
    212233        do_unaligned_access:
    213234            retaddr = GETPC();
     235#ifdef ALIGNED_ONLY
     236            do_unaligned_access(addr, 1, is_user, retaddr);
     237#endif
    214238            glue(glue(slow_st, SUFFIX), MMUSUFFIX)(addr, val,
    215239                                                   is_user, retaddr);
    216240        } else {
    217241            /* aligned/unaligned access in the same page */
    218             glue(glue(st, SUFFIX), _raw)((uint8_t *)physaddr, val);
     242#ifdef ALIGNED_ONLY
     243            if ((addr & (DATA_SIZE - 1)) != 0) {
     244                retaddr = GETPC();
     245                do_unaligned_access(addr, 1, is_user, retaddr);
     246            }
     247#endif
     248            glue(glue(st, SUFFIX), _raw)((uint8_t *)(long)physaddr, val);
    219249        }
    220250    } else {
    221251        /* the page is not in the TLB : fill it */
    222252        retaddr = GETPC();
     253#ifdef ALIGNED_ONLY
     254        if ((addr & (DATA_SIZE - 1)) != 0)
     255            do_unaligned_access(addr, 1, is_user, retaddr);
     256#endif
    223257        tlb_fill(addr, 1, is_user, retaddr);
    224258        goto redo;
     
    232266                                                   void *retaddr)
    233267{
    234     unsigned long physaddr;
     268    target_phys_addr_t physaddr;
    235269    target_ulong tlb_addr;
    236270    int index, i;
     
    238272    index = (addr >> TARGET_PAGE_BITS) & (CPU_TLB_SIZE - 1);
    239273 redo:
    240     tlb_addr = env->tlb_write[is_user][index].address;
     274    tlb_addr = env->tlb_table[is_user][index].addr_write;
    241275    if ((addr & TARGET_PAGE_MASK) == (tlb_addr & (TARGET_PAGE_MASK | TLB_INVALID_MASK))) {
    242         physaddr = addr + env->tlb_write[is_user][index].addend;
     276        physaddr = addr + env->tlb_table[is_user][index].addend;
    243277        if (tlb_addr & ~TARGET_PAGE_MASK) {
    244278            /* IO access */
     
    246280                goto do_unaligned_access;
    247281            glue(io_write, SUFFIX)(physaddr, val, tlb_addr, retaddr);
    248         } else if (((addr & 0xfff) + DATA_SIZE - 1) >= TARGET_PAGE_SIZE) {
     282        } else if (((addr & ~TARGET_PAGE_MASK) + DATA_SIZE - 1) >= TARGET_PAGE_SIZE) {
    249283        do_unaligned_access:
    250284            /* XXX: not efficient, but simple */
     
    260294        } else {
    261295            /* aligned/unaligned access in the same page */
    262             glue(glue(st, SUFFIX), _raw)((uint8_t *)physaddr, val);
     296            glue(glue(st, SUFFIX), _raw)((uint8_t *)(long)physaddr, val);
    263297        }
    264298    } else {
     
    277311#undef USUFFIX
    278312#undef DATA_SIZE
     313#undef ADDR_READ
  • trunk/src/recompiler/target-i386/cpu.h

    r1 r2422  
    3535#define TARGET_HAS_PRECISE_SMC
    3636
     37#define TARGET_HAS_ICE 1
     38
     39#ifdef TARGET_X86_64
     40#define ELF_MACHINE     EM_X86_64
     41#else
     42#define ELF_MACHINE     EM_386
     43#endif
     44
    3745#include "cpu-defs.h"
    3846
     47#include "softfloat.h"
     48
    3949#if defined(VBOX)
    40 #include <iprt/critsect.h>
    41 #include <iprt/thread.h>
    42 #include <iprt/assert.h>
    43 #include <iprt/asm.h>
    44 #include <VBox/vmm.h>
     50# include <iprt/critsect.h>
     51# include <iprt/thread.h>
     52# include <iprt/assert.h>
     53# include <iprt/asm.h>
     54# include <VBox/vmm.h>
    4555#endif /* VBOX */
    4656
     
    121131
    122132/* hidden flags - used internally by qemu to represent additionnal cpu
    123    states. Only the CPL and INHIBIT_IRQ are not redundant. We avoid
     133   states. Only the CPL, INHIBIT_IRQ and HALTED are not redundant. We avoid
    124134   using the IOPL_MASK, TF_MASK and VM_MASK bit position to ease oring
    125135   with eflags. */
     
    146156#define HF_OSFXSR_SHIFT     16 /* CR4.OSFXSR */
    147157#define HF_VM_SHIFT         17 /* must be same as eflags */
     158#define HF_HALTED_SHIFT     18 /* CPU halted */
     159#define HF_SMM_SHIFT        19 /* CPU in SMM mode */
    148160
    149161#define HF_CPL_MASK          (3 << HF_CPL_SHIFT)
     
    161173#define HF_CS64_MASK         (1 << HF_CS64_SHIFT)
    162174#define HF_OSFXSR_MASK       (1 << HF_OSFXSR_SHIFT)
     175#define HF_HALTED_MASK       (1 << HF_HALTED_SHIFT)
     176#define HF_SMM_MASK          (1 << HF_SMM_SHIFT)
    163177
    164178#define CR0_PE_MASK  (1 << 0)
     
    192206#define PG_PSE_BIT      7
    193207#define PG_GLOBAL_BIT   8
     208#define PG_NX_BIT       63
    194209
    195210#define PG_PRESENT_MASK  (1 << PG_PRESENT_BIT)
     
    202217#define PG_PSE_MASK      (1 << PG_PSE_BIT)
    203218#define PG_GLOBAL_MASK   (1 << PG_GLOBAL_BIT)
     219#define PG_NX_MASK       (1LL << PG_NX_BIT)
    204220
    205221#define PG_ERROR_W_BIT     1
     
    209225#define PG_ERROR_U_MASK    0x04
    210226#define PG_ERROR_RSVD_MASK 0x08
     227#define PG_ERROR_I_D_MASK  0x10
    211228
    212229#define MSR_IA32_APICBASE               0x1b
     
    220237#define MSR_IA32_SYSENTER_EIP           0x176
    221238#endif
     239
     240#define MSR_MCG_CAP                     0x179
     241#define MSR_MCG_STATUS                  0x17a
     242#define MSR_MCG_CTL                     0x17b
     243
     244#define MSR_PAT                         0x277
    222245
    223246#define MSR_EFER                        0xc0000080
     
    254277#define CPUID_CMOV (1 << 15)
    255278#define CPUID_PAT  (1 << 16)
     279#define CPUID_PSE36   (1 << 17)
    256280#define CPUID_CLFLUSH (1 << 19)
    257281/* ... */
     
    262286
    263287#ifdef VBOX
    264 #define CPUID_PSE36 (1 << 17)
    265288#define CPUID_HTT  (1 << 28)
    266289#endif
    267290
    268 #define CPUID_EXT_SS3      (1 << 0)
     291#define CPUID_EXT_SSE3     (1 << 0)
    269292#define CPUID_EXT_MONITOR  (1 << 3)
    270293#define CPUID_EXT_CX16     (1 << 13)
     
    272295#define CPUID_EXT2_SYSCALL (1 << 11)
    273296#define CPUID_EXT2_NX      (1 << 20)
     297#define CPUID_EXT2_FFXSR   (1 << 25)
    274298#define CPUID_EXT2_LM      (1 << 29)
    275299
     
    350374};
    351375
    352 #if (defined(__i386__) || defined(__x86_64__)) && !defined(_BSD)
     376#ifdef FLOATX80
    353377#define USE_X86LDOUBLE
    354378#endif
    355379
    356380#ifdef USE_X86LDOUBLE
    357 typedef long double CPU86_LDouble;
     381typedef floatx80 CPU86_LDouble;
    358382#else
    359 typedef double CPU86_LDouble;
     383typedef float64 CPU86_LDouble;
    360384#endif
    361385
     
    376400    uint32_t _l[4];
    377401    uint64_t _q[2];
    378     float _s[4];
    379     double _d[2];
     402    float32 _s[4];
     403    float64 _d[2];
    380404} XMMReg;
    381405
     
    463487
    464488    /* emulator internal variables */
     489    float_status fp_status;
     490#ifdef VBOX
     491    uint32_t alignment3[3]; /* force the long double to start a 16 byte line. */
     492#endif
    465493    CPU86_LDouble ft0;
     494#if defined(VBOX) && defined(__X86__) && !defined(__DARWIN__)
     495    uint32_t alignment4; /* long double is 12 byte, pad it to 16. */
     496#endif
    466497    union {
    467498        float f;
     
    471502    } fp_convert;
    472503   
     504    float_status sse_status;
    473505    uint32_t mxcsr;
    474506    XMMReg xmm_regs[CPU_NB_REGS];
     
    480512    uint32_t sysenter_esp;
    481513    uint32_t sysenter_eip;
     514#ifdef VBOX
     515    uint32_t alignment0;
     516#endif
    482517    uint64_t efer;
    483518    uint64_t star;
     
    489524#endif
    490525
     526    uint64_t pat;
     527
    491528    /* temporary data for USE_CODE_COPY mode */
    492529#ifdef USE_CODE_COPY
     
    498535    /* exception/interrupt handling */
    499536    jmp_buf jmp_env;
     537#if defined(VBOX) && defined(__WIN__) && defined(__X86__)
     538    /* This will be removed when switching to the no-crt code everywhere. */
     539    uint32_t alignment1[23];
     540#endif
    500541    int exception_index;
    501542    int error_code;
    502543    int exception_is_int;
    503544    target_ulong exception_next_eip;
    504 #if defined(VBOX)
    505     struct TranslationBlock * volatile current_tb; /* currently executing TB */
    506 #else
    507     struct TranslationBlock *current_tb; /* currently executing TB */
    508 #endif
    509545    target_ulong dr[8]; /* debug registers */
    510 #if defined(VBOX)
    511     volatile int32_t interrupt_request;
    512 #else
     546    uint32_t smbase;
    513547    int interrupt_request;
    514 #endif
    515548    int user_mode_only; /* user mode only simulation */
    516549
    517     /* soft mmu support */
    518     /* in order to avoid passing too many arguments to the memory
    519        write helpers, we store some rarely used information in the CPU
    520        context) */
    521     unsigned long mem_write_pc; /* host pc at which the memory was
    522                                    written */
    523     target_ulong mem_write_vaddr; /* target virtual addr at which the
    524                                      memory was written */
    525     /* 0 = kernel, 1 = user */
    526     CPUTLBEntry tlb_read[2][CPU_TLB_SIZE];
    527     CPUTLBEntry tlb_write[2][CPU_TLB_SIZE];
    528    
    529     /* from this point: preserved by CPU reset */
    530     /* ice debug support */
    531     target_ulong breakpoints[MAX_BREAKPOINTS];
    532     int nb_breakpoints;
    533     int singlestep_enabled;
     550    CPU_COMMON
    534551
    535552#ifdef VBOX
     
    546563    /* processor features (e.g. for CPUID insn) */
    547564#ifndef VBOX /* remR3CpuId deals with these */
     565    uint32_t cpuid_level;
    548566    uint32_t cpuid_vendor1;
    549567    uint32_t cpuid_vendor2;
     
    551569    uint32_t cpuid_version;
    552570#endif /* !VBOX */
     571    uint32_t cpuid_features;
    553572    uint32_t cpuid_ext_features;
    554     uint32_t cpuid_features;
    555 
    556573#ifndef VBOX
     574    uint32_t cpuid_xlevel;
     575    uint32_t cpuid_model[12];
     576#endif /* !VBOX */
     577    uint32_t cpuid_ext2_features;
     578
     579#ifndef VBOX
     580#ifdef USE_KQEMU
     581    int kqemu_enabled;
     582    int last_io_time;
     583#endif
    557584    /* in order to simplify APIC support, we leave this pointer to the
    558585       user */
    559586    struct APICState *apic_state;
    560     /* user data */
    561     void *opaque;
     587#else
     588    uint32_t alignment2[3];
    562589#endif
    563590} CPUX86State;
     
    588615static inline void cpu_x86_load_seg_cache(CPUX86State *env,
    589616                                          int seg_reg, unsigned int selector,
    590                                           uint32_t base, unsigned int limit,
     617                                          target_ulong base,
     618                                          unsigned int limit,
    591619                                          unsigned int flags)
    592620{
     
    668696   signal handlers to inform the virtual CPU of exceptions. non zero
    669697   is returned if the signal was handled by the virtual CPU.  */
    670 struct siginfo;
    671 int cpu_x86_signal_handler(int host_signum, struct siginfo *info,
     698int cpu_x86_signal_handler(int host_signum, void *pinfo,
    672699                           void *puc);
    673700void cpu_x86_set_a20(CPUX86State *env, int a20_state);
     
    681708uint8_t cpu_get_apic_tpr(CPUX86State *env);
    682709#endif
     710void cpu_smm_update(CPUX86State *env);
    683711
    684712/* will be suppressed */
     
    688716#define X86_DUMP_FPU  0x0001 /* dump FPU state too */
    689717#define X86_DUMP_CCOP 0x0002 /* dump qemu flag cache */
     718
     719#ifdef USE_KQEMU
     720static inline int cpu_get_time_fast(void)
     721{
     722    int low, high;
     723    asm volatile("rdtsc" : "=a" (low), "=d" (high));
     724    return low;
     725}
     726#endif
    690727
    691728#ifdef VBOX
  • trunk/src/recompiler/target-i386/exec.h

    r1478 r2422  
    11/*
    2  *  i386 execution defines 
     2 *  i386 execution defines
    33 *
    44 *  Copyright (c) 2003 Fabrice Bellard
     
    2222
    2323/* XXX: factorize this mess */
    24 #if defined(__alpha__) || defined (__ia64__) || defined(__x86_64__)
    25 #define HOST_LONG_BITS 64
    26 #else
    27 #define HOST_LONG_BITS 32
    28 #endif
    29 
    3024#ifdef TARGET_X86_64
    3125#define TARGET_LONG_BITS 64
     
    3428#endif
    3529
     30#include "cpu-defs.h"
     31
    3632/* at least 4 register variables are defined */
    3733register struct CPUX86State *env asm(AREG0);
    3834
    39 /* XXX: use 64 bit regs if HOST_LONG_BITS == 64 */
    40 #if TARGET_LONG_BITS == 32
    41 
    42 register uint32_t T0 asm(AREG1);
    43 register uint32_t T1 asm(AREG2);
    44 register uint32_t T2 asm(AREG3);
    45 
    46 /* if more registers are available, we define some registers too */
    47 #ifdef AREG4
    48 register uint32_t EAX asm(AREG4);
    49 #define reg_EAX
    50 #endif
    51 
    52 #ifdef AREG5
    53 register uint32_t ESP asm(AREG5);
    54 #define reg_ESP
    55 #endif
    56 
    57 #ifdef AREG6
    58 register uint32_t EBP asm(AREG6);
    59 #define reg_EBP
    60 #endif
    61 
    62 #ifdef AREG7
    63 register uint32_t ECX asm(AREG7);
    64 #define reg_ECX
    65 #endif
    66 
    67 #ifdef AREG8
    68 register uint32_t EDX asm(AREG8);
    69 #define reg_EDX
    70 #endif
    71 
    72 #ifdef AREG9
    73 register uint32_t EBX asm(AREG9);
    74 #define reg_EBX
    75 #endif
    76 
    77 #ifdef AREG10
    78 register uint32_t ESI asm(AREG10);
    79 #define reg_ESI
    80 #endif
    81 
    82 #ifdef AREG11
    83 register uint32_t EDI asm(AREG11);
    84 #define reg_EDI
    85 #endif
    86 
    87 #else
     35#if TARGET_LONG_BITS > HOST_LONG_BITS
    8836
    8937/* no registers can be used */
     
    9240#define T2 (env->t2)
    9341
    94 #endif
     42#else
     43
     44/* XXX: use unsigned long instead of target_ulong - better code will
     45   be generated for 64 bit CPUs */
     46register target_ulong T0 asm(AREG1);
     47register target_ulong T1 asm(AREG2);
     48register target_ulong T2 asm(AREG3);
     49
     50/* if more registers are available, we define some registers too */
     51#ifdef AREG4
     52register target_ulong EAX asm(AREG4);
     53#define reg_EAX
     54#endif
     55
     56#ifdef AREG5
     57register target_ulong ESP asm(AREG5);
     58#define reg_ESP
     59#endif
     60
     61#ifdef AREG6
     62register target_ulong EBP asm(AREG6);
     63#define reg_EBP
     64#endif
     65
     66#ifdef AREG7
     67register target_ulong ECX asm(AREG7);
     68#define reg_ECX
     69#endif
     70
     71#ifdef AREG8
     72register target_ulong EDX asm(AREG8);
     73#define reg_EDX
     74#endif
     75
     76#ifdef AREG9
     77register target_ulong EBX asm(AREG9);
     78#define reg_EBX
     79#endif
     80
     81#ifdef AREG10
     82register target_ulong ESI asm(AREG10);
     83#define reg_ESI
     84#endif
     85
     86#ifdef AREG11
     87register target_ulong EDI asm(AREG11);
     88#define reg_EDI
     89#endif
     90
     91#endif /* ! (TARGET_LONG_BITS > HOST_LONG_BITS) */
    9592
    9693#define A0 T2
     
    140137#endif
    141138
    142 #if defined(VBOX) && !defined(REMR3PHYSREADWRITE_DEFINED)
    143 #define REMR3PHYSREADWRITE_DEFINED
    144 /* Header sharing between vbox & qemu is rather ugly. */
    145 void     remR3PhysReadBytes(uint8_t *pbSrcPhys, void *pvDst, unsigned cb);
    146 uint8_t  remR3PhysReadUByte(uint8_t *pbSrcPhys);
    147 uint8_t  remR3PhysReadSByte(uint8_t *pbSrcPhys);
    148 uint16_t remR3PhysReadUWord(uint8_t *pbSrcPhys);
    149 int16_t  remR3PhysReadSWord(uint8_t *pbSrcPhys);
    150 uint32_t remR3PhysReadULong(uint8_t *pbSrcPhys);
    151 uint32_t remR3PhysReadSLong(uint8_t *pbSrcPhys);
    152 void     remR3PhysWriteBytes(uint8_t *pbDstPhys, const void *pvSrc, unsigned cb);
    153 void     remR3PhysWriteByte(uint8_t *pbDstPhys, uint8_t val);
    154 void     remR3PhysWriteWord(uint8_t *pbDstPhys, uint16_t val);
    155 void     remR3PhysWriteDword(uint8_t *pbDstPhys, uint32_t val);
    156 #endif
    157 
    158139#include "cpu.h"
    159140#include "exec-all.h"
    160 
    161 /* XXX: add a generic FPU library */
    162 
    163 static inline double float32_to_float64(float a)
    164 {
    165     return a;
    166 }
    167 
    168 static inline float float64_to_float32(double a)
    169 {
    170     return a;
    171 }
    172 
    173 #if defined(__powerpc__)
    174 /* better to call an helper on ppc */
    175 float int32_to_float32(int32_t a);
    176 double int32_to_float64(int32_t a);
    177 #else
    178 static inline float int32_to_float32(int32_t a)
    179 {
    180     return (float)a;
    181 }
    182 
    183 static inline double int32_to_float64(int32_t a)
    184 {
    185     return (double)a;
    186 }
    187 #endif
    188 
    189 static inline float int64_to_float32(int64_t a)
    190 {
    191     return (float)a;
    192 }
    193 
    194 static inline double int64_to_float64(int64_t a)
    195 {
    196     return (double)a;
    197 }
    198141
    199142typedef struct CCTable {
     
    215158void helper_movl_crN_T0(int reg);
    216159void helper_movl_drN_T0(int reg);
    217 void helper_invlpg(unsigned int addr);
     160void helper_invlpg(target_ulong addr);
    218161void cpu_x86_update_cr0(CPUX86State *env, uint32_t new_cr0);
    219162void cpu_x86_update_cr3(CPUX86State *env, target_ulong new_cr3);
    220163void cpu_x86_update_cr4(CPUX86State *env, uint32_t new_cr4);
    221 void cpu_x86_flush_tlb(CPUX86State *env, uint32_t addr);
     164void cpu_x86_flush_tlb(CPUX86State *env, target_ulong addr);
    222165int cpu_x86_handle_mmu_fault(CPUX86State *env, target_ulong addr,
    223166                             int is_write, int is_user, int is_softmmu);
     
    234177void raise_exception_err(int exception_index, int error_code);
    235178void raise_exception(int exception_index);
     179void do_smm_enter(void);
    236180void __hidden cpu_loop_exit(void);
    237181
     
    251195void helper_divq_EAX_T0(void);
    252196void helper_idivq_EAX_T0(void);
     197void helper_bswapq_T0(void);
    253198void helper_cmpxchg8b(void);
    254199void helper_cpuid(void);
    255200void helper_enter_level(int level, int data32);
     201void helper_enter64_level(int level, int data64);
    256202void helper_sysenter(void);
    257203void helper_sysexit(void);
     
    265211void helper_verr(void);
    266212void helper_verw(void);
     213void helper_rsm(void);
    267214
    268215#ifdef VBOX
    269216void helper_external_event(void);
    270 void helper_hlt(void);
    271 void helper_monitor(void);
    272 void helper_mwait(void);
    273217
    274218/* in helper.c */
     
    286230void check_iol_DX(void);
    287231
    288 /* XXX: move that to a generic header */
    289232#if !defined(CONFIG_USER_ONLY)
    290233
    291 #define ldul_user ldl_user
    292 #define ldul_kernel ldl_kernel
    293 
    294 #define ACCESS_TYPE 0
    295 #define MEMSUFFIX _kernel
    296 #define DATA_SIZE 1
    297 #include "softmmu_header.h"
    298 
    299 #define DATA_SIZE 2
    300 #include "softmmu_header.h"
    301 
    302 #define DATA_SIZE 4
    303 #include "softmmu_header.h"
    304 
    305 #define DATA_SIZE 8
    306 #include "softmmu_header.h"
    307 #undef ACCESS_TYPE
    308 #undef MEMSUFFIX
    309 
    310 #define ACCESS_TYPE 1
    311 #define MEMSUFFIX _user
    312 #define DATA_SIZE 1
    313 #include "softmmu_header.h"
    314 
    315 #define DATA_SIZE 2
    316 #include "softmmu_header.h"
    317 
    318 #define DATA_SIZE 4
    319 #include "softmmu_header.h"
    320 
    321 #define DATA_SIZE 8
    322 #include "softmmu_header.h"
    323 #undef ACCESS_TYPE
    324 #undef MEMSUFFIX
    325 
    326 /* these access are slower, they must be as rare as possible */
    327 #define ACCESS_TYPE 2
    328 #define MEMSUFFIX _data
    329 #define DATA_SIZE 1
    330 #include "softmmu_header.h"
    331 
    332 #define DATA_SIZE 2
    333 #include "softmmu_header.h"
    334 
    335 #define DATA_SIZE 4
    336 #include "softmmu_header.h"
    337 
    338 #define DATA_SIZE 8
    339 #include "softmmu_header.h"
    340 #undef ACCESS_TYPE
    341 #undef MEMSUFFIX
    342 
    343 #define ldub(p) ldub_data(p)
    344 #define ldsb(p) ldsb_data(p)
    345 #define lduw(p) lduw_data(p)
    346 #define ldsw(p) ldsw_data(p)
    347 #define ldl(p) ldl_data(p)
    348 #define ldq(p) ldq_data(p)
    349 
    350 #define stb(p, v) stb_data(p, v)
    351 #define stw(p, v) stw_data(p, v)
    352 #define stl(p, v) stl_data(p, v)
    353 #define stq(p, v) stq_data(p, v)
     234#include "softmmu_exec.h"
    354235
    355236static inline double ldfq(target_ulong ptr)
     
    397278#ifdef USE_X86LDOUBLE
    398279/* use long double functions */
    399 #define lrint lrintl
    400 #define llrint llrintl
    401 #define fabs fabsl
     280#define floatx_to_int32 floatx80_to_int32
     281#define floatx_to_int64 floatx80_to_int64
     282#define floatx_to_int32_round_to_zero floatx80_to_int32_round_to_zero
     283#define floatx_to_int64_round_to_zero floatx80_to_int64_round_to_zero
     284#define floatx_abs floatx80_abs
     285#define floatx_chs floatx80_chs
     286#define floatx_round_to_int floatx80_round_to_int
     287#define floatx_compare floatx80_compare
     288#define floatx_compare_quiet floatx80_compare_quiet
     289#ifdef VBOX
     290#undef sin
     291#undef cos
     292#undef sqrt
     293#undef pow
     294#undef log
     295#undef tan
     296#undef atan2
     297#undef floor
     298#undef ceil
     299#undef ldexp
     300#endif /* !VBOX */
    402301#define sin sinl
    403302#define cos cosl
     
    409308#define floor floorl
    410309#define ceil ceill
    411 #define rint rintl
    412 #endif
    413 
    414 #if !defined(_BSD)
    415 extern int lrint(CPU86_LDouble x);
    416 extern int64_t llrint(CPU86_LDouble x);
    417 #else
    418 #define lrint(d)                ((int)rint(d))
    419 #define llrint(d)               ((int)rint(d))
    420 #endif
    421 extern CPU86_LDouble fabs(CPU86_LDouble x);
     310#define ldexp ldexpl
     311#else
     312#define floatx_to_int32 float64_to_int32
     313#define floatx_to_int64 float64_to_int64
     314#define floatx_to_int32_round_to_zero float64_to_int32_round_to_zero
     315#define floatx_to_int64_round_to_zero float64_to_int64_round_to_zero
     316#define floatx_abs float64_abs
     317#define floatx_chs float64_chs
     318#define floatx_round_to_int float64_round_to_int
     319#define floatx_compare float64_compare
     320#define floatx_compare_quiet float64_compare_quiet
     321#endif
     322
    422323extern CPU86_LDouble sin(CPU86_LDouble x);
    423324extern CPU86_LDouble cos(CPU86_LDouble x);
     
    429330extern CPU86_LDouble floor(CPU86_LDouble x);
    430331extern CPU86_LDouble ceil(CPU86_LDouble x);
    431 extern CPU86_LDouble rint(CPU86_LDouble x);
    432332
    433333#define RC_MASK         0xc00
     
    438338
    439339#define MAXTAN 9223372036854775808.0
    440 
    441 #ifdef __arm__
    442 /* we have no way to do correct rounding - a FPU emulator is needed */
    443 #define FE_DOWNWARD   FE_TONEAREST
    444 #define FE_UPWARD     FE_TONEAREST
    445 #define FE_TOWARDZERO FE_TONEAREST
    446 #endif
    447340
    448341#ifdef USE_X86LDOUBLE
     
    633526float approx_rsqrt(float a);
    634527float approx_rcp(float a);
    635 double helper_sqrt(double a);
    636 int fpu_isnan(double a);
     528void update_fp_status(void);
     529void helper_hlt(void);
     530void helper_monitor(void);
     531void helper_mwait(void);
    637532
    638533extern const uint8_t parity_table[256];
  • trunk/src/recompiler/target-i386/helper2.c

    r1 r2422  
    2323#include <string.h>
    2424#include <inttypes.h>
     25#ifndef VBOX
    2526#include <signal.h>
    2627#include <assert.h>
     28#else
     29# include <VBox/pgm.h> /* PGM_DYNAMIC_RAM_ALLOC */
     30#endif
    2731
    2832#include "cpu.h"
     
    3640#include <linux/version.h>
    3741
    38 _syscall3(int, modify_ldt, int, func, void *, ptr, unsigned long, bytecount)
     42int modify_ldt(int func, void *ptr, unsigned long bytecount)
     43{
     44        return syscall(__NR_modify_ldt, func, ptr, bytecount);
     45}
    3946
    4047#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 5, 66)
     
    5360    static int inited;
    5461
    55     cpu_exec_init();
    56 
    5762#ifndef VBOX
    58     env = malloc(sizeof(CPUX86State));
     63    env = qemu_mallocz(sizeof(CPUX86State));
    5964    if (!env)
    6065        return NULL;
    61     memset(env, 0, sizeof(CPUX86State));
    6266#endif /* !VBOX */
     67    cpu_exec_init(env);
     68
    6369    /* init various static tables */
    6470    if (!inited) {
     
    111117#endif
    112118#endif
     119        env->cpuid_level = 2;
    113120        env->cpuid_version = (family << 8) | (model << 4) | stepping;
    114121        env->cpuid_features = (CPUID_FP87 | CPUID_DE | CPUID_PSE |
    115122                               CPUID_TSC | CPUID_MSR | CPUID_MCE |
    116                                CPUID_CX8 | CPUID_PGE | CPUID_CMOV);
    117         env->cpuid_ext_features = 0;
    118 
     123                               CPUID_CX8 | CPUID_PGE | CPUID_CMOV |
     124                               CPUID_PAT);
     125        env->pat = 0x0007040600070406ULL;
     126        env->cpuid_ext_features = CPUID_EXT_SSE3;
    119127        env->cpuid_features |= CPUID_FXSR | CPUID_MMX | CPUID_SSE | CPUID_SSE2 | CPUID_PAE | CPUID_SEP;
     128        env->cpuid_features |= CPUID_APIC;
     129        env->cpuid_xlevel = 0;
     130        {
     131            const char *model_id = "QEMU Virtual CPU version " QEMU_VERSION;
     132            int c, len, i;
     133            len = strlen(model_id);
     134            for(i = 0; i < 48; i++) {
     135                if (i >= len)
     136                    c = '\0';
     137                else
     138                    c = model_id[i];
     139                env->cpuid_model[i >> 2] |= c << (8 * (i & 3));
     140            }
     141        }
    120142#ifdef TARGET_X86_64
    121143        /* currently not enabled for std i386 because not fully tested */
    122         env->cpuid_features |= CPUID_APIC;
     144        env->cpuid_ext2_features = (env->cpuid_features & 0x0183F3FF);
     145        env->cpuid_ext2_features |= CPUID_EXT2_LM | CPUID_EXT2_SYSCALL | CPUID_EXT2_NX;
     146        env->cpuid_xlevel = 0x80000008;
     147
     148        /* these features are needed for Win64 and aren't fully implemented */
     149        env->cpuid_features |= CPUID_MTRR | CPUID_CLFLUSH | CPUID_MCA;
     150        /* this feature is needed for Solaris and isn't fully implemented */
     151        env->cpuid_features |= CPUID_PSE36;
    123152#endif
    124153    }
    125154#endif /* VBOX */
    126     cpu_single_env = env;
    127155    cpu_reset(env);
     156#ifdef USE_KQEMU
     157    kqemu_init(env);
     158#endif
    128159    return env;
    129160}
     
    146177    cpu_x86_update_cr0(env, 0x60000010);
    147178    env->a20_mask = 0xffffffff;
    148    
     179    env->smbase = 0x30000;
     180
    149181    env->idt.limit = 0xffff;
    150182    env->gdt.limit = 0xffff;
     
    243275                    int flags)
    244276{
    245     int eflags, i;
     277    int eflags, i, nb;
    246278    char cc_op_name[32];
    247279    static const char *seg_name[6] = { "ES", "CS", "SS", "DS", "FS", "GS" };
     
    251283    if (env->hflags & HF_CS64_MASK) {
    252284        cpu_fprintf(f,
    253                     "RAX=%016llx RBX=%016llx RCX=%016llx RDX=%016llx\n"
    254                     "RSI=%016llx RDI=%016llx RBP=%016llx RSP=%016llx\n"
    255                     "R8 =%016llx R9 =%016llx R10=%016llx R11=%016llx\n"
    256                     "R12=%016llx R13=%016llx R14=%016llx R15=%016llx\n"
    257                     "RIP=%016llx RFL=%08x [%c%c%c%c%c%c%c]    CPL=%d II=%d A20=%d\n",
     285                    "RAX=%016" PRIx64 " RBX=%016" PRIx64 " RCX=%016" PRIx64 " RDX=%016" PRIx64 "\n"
     286                    "RSI=%016" PRIx64 " RDI=%016" PRIx64 " RBP=%016" PRIx64 " RSP=%016" PRIx64 "\n"
     287                    "R8 =%016" PRIx64 " R9 =%016" PRIx64 " R10=%016" PRIx64 " R11=%016" PRIx64 "\n"
     288                    "R12=%016" PRIx64 " R13=%016" PRIx64 " R14=%016" PRIx64 " R15=%016" PRIx64 "\n"
     289                    "RIP=%016" PRIx64 " RFL=%08x [%c%c%c%c%c%c%c] CPL=%d II=%d A20=%d SMM=%d HLT=%d\n",
    258290                    env->regs[R_EAX],
    259291                    env->regs[R_EBX],
     
    282314                    env->hflags & HF_CPL_MASK,
    283315                    (env->hflags >> HF_INHIBIT_IRQ_SHIFT) & 1,
    284                     (env->a20_mask >> 20) & 1);
     316                    (env->a20_mask >> 20) & 1,
     317                    (env->hflags >> HF_SMM_SHIFT) & 1,
     318                    (env->hflags >> HF_HALTED_SHIFT) & 1);
    285319    } else
    286320#endif
     
    288322        cpu_fprintf(f, "EAX=%08x EBX=%08x ECX=%08x EDX=%08x\n"
    289323                    "ESI=%08x EDI=%08x EBP=%08x ESP=%08x\n"
    290                     "EIP=%08x EFL=%08x [%c%c%c%c%c%c%c]    CPL=%d II=%d A20=%d\n",
     324                    "EIP=%08x EFL=%08x [%c%c%c%c%c%c%c] CPL=%d II=%d A20=%d SMM=%d HLT=%d\n",
    291325                    (uint32_t)env->regs[R_EAX],
    292326                    (uint32_t)env->regs[R_EBX],
     
    307341                    env->hflags & HF_CPL_MASK,
    308342                    (env->hflags >> HF_INHIBIT_IRQ_SHIFT) & 1,
    309                     (env->a20_mask >> 20) & 1);
     343                    (env->a20_mask >> 20) & 1,
     344                    (env->hflags >> HF_SMM_SHIFT) & 1,
     345                    (env->hflags >> HF_HALTED_SHIFT) & 1);
    310346    }
    311347
     
    314350        for(i = 0; i < 6; i++) {
    315351            SegmentCache *sc = &env->segs[i];
    316             cpu_fprintf(f, "%s =%04x %016llx %08x %08x\n",
     352            cpu_fprintf(f, "%s =%04x %016" PRIx64 " %08x %08x\n",
    317353                        seg_name[i],
    318354                        sc->selector,
     
    321357                        sc->flags);
    322358        }
    323         cpu_fprintf(f, "LDT=%04x %016llx %08x %08x\n",
     359        cpu_fprintf(f, "LDT=%04x %016" PRIx64 " %08x %08x\n",
    324360                    env->ldt.selector,
    325361                    env->ldt.base,
    326362                    env->ldt.limit,
    327363                    env->ldt.flags);
    328         cpu_fprintf(f, "TR =%04x %016llx %08x %08x\n",
     364        cpu_fprintf(f, "TR =%04x %016" PRIx64 " %08x %08x\n",
    329365                    env->tr.selector,
    330366                    env->tr.base,
    331367                    env->tr.limit,
    332368                    env->tr.flags);
    333         cpu_fprintf(f, "GDT=     %016llx %08x\n",
     369        cpu_fprintf(f, "GDT=     %016" PRIx64 " %08x\n",
    334370                    env->gdt.base, env->gdt.limit);
    335         cpu_fprintf(f, "IDT=     %016llx %08x\n",
     371        cpu_fprintf(f, "IDT=     %016" PRIx64 " %08x\n",
    336372                    env->idt.base, env->idt.limit);
    337         cpu_fprintf(f, "CR0=%08x CR2=%016llx CR3=%016llx CR4=%08x\n",
     373        cpu_fprintf(f, "CR0=%08x CR2=%016" PRIx64 " CR3=%016" PRIx64 " CR4=%08x\n",
    338374                    (uint32_t)env->cr[0],
    339375                    env->cr[2],
     
    374410    if (flags & X86_DUMP_CCOP) {
    375411        if ((unsigned)env->cc_op < CC_OP_NB)
    376             snprintf(cc_op_name, sizeof(cc_op_name), "%s", cc_op_str[env->cc_op]);
     412            qemu_snprintf(cc_op_name, sizeof(cc_op_name), "%s", cc_op_str[env->cc_op]);
    377413        else
    378             snprintf(cc_op_name, sizeof(cc_op_name), "[%d]", env->cc_op);
     414            qemu_snprintf(cc_op_name, sizeof(cc_op_name), "[%d]", env->cc_op);
    379415#ifdef TARGET_X86_64
    380416        if (env->hflags & HF_CS64_MASK) {
    381             cpu_fprintf(f, "CCS=%016llx CCD=%016llx CCO=%-8s\n",
     417            cpu_fprintf(f, "CCS=%016" PRIx64 " CCD=%016" PRIx64 " CCO=%-8s\n",
    382418                        env->cc_src, env->cc_dst,
    383419                        cc_op_name);
     
    391427    }
    392428    if (flags & X86_DUMP_FPU) {
    393         cpu_fprintf(f, "ST0=%f ST1=%f ST2=%f ST3=%f\n",
    394                 (double)env->fpregs[0].d,
    395                 (double)env->fpregs[1].d,
    396                 (double)env->fpregs[2].d,
    397                 (double)env->fpregs[3].d);
    398         cpu_fprintf(f, "ST4=%f ST5=%f ST6=%f ST7=%f\n",
    399                 (double)env->fpregs[4].d,
    400                 (double)env->fpregs[5].d,
    401                 (double)env->fpregs[7].d,
    402                 (double)env->fpregs[8].d);
     429        int fptag;
     430        fptag = 0;
     431        for(i = 0; i < 8; i++) {
     432            fptag |= ((!env->fptags[i]) << i);
     433        }
     434        cpu_fprintf(f, "FCW=%04x FSW=%04x [ST=%d] FTW=%02x MXCSR=%08x\n",
     435                    env->fpuc,
     436                    (env->fpus & ~0x3800) | (env->fpstt & 0x7) << 11,
     437                    env->fpstt,
     438                    fptag,
     439                    env->mxcsr);
     440        for(i=0;i<8;i++) {
     441#if defined(USE_X86LDOUBLE)
     442            union {
     443                long double d;
     444                struct {
     445                    uint64_t lower;
     446                    uint16_t upper;
     447                } l;
     448            } tmp;
     449            tmp.d = env->fpregs[i].d;
     450            cpu_fprintf(f, "FPR%d=%016" PRIx64 " %04x",
     451                        i, tmp.l.lower, tmp.l.upper);
     452#else
     453            cpu_fprintf(f, "FPR%d=%016" PRIx64,
     454                        i, env->fpregs[i].mmx.q);
     455#endif
     456            if ((i & 1) == 1)
     457                cpu_fprintf(f, "\n");
     458            else
     459                cpu_fprintf(f, " ");
     460        }
     461        if (env->hflags & HF_CS64_MASK)
     462            nb = 16;
     463        else
     464            nb = 8;
     465        for(i=0;i<nb;i++) {
     466            cpu_fprintf(f, "XMM%02d=%08x%08x%08x%08x",
     467                        i,
     468                        env->xmm_regs[i].XMM_L(3),
     469                        env->xmm_regs[i].XMM_L(2),
     470                        env->xmm_regs[i].XMM_L(1),
     471                        env->xmm_regs[i].XMM_L(0));
     472            if ((i & 1) == 1)
     473                cpu_fprintf(f, "\n");
     474            else
     475                cpu_fprintf(f, " ");
     476        }
    403477    }
    404478}
     
    467541#ifdef VBOX
    468542    remR3ChangeCpuMode(env);
    469 #endif 
     543#endif
    470544}
    471545
     
    503577#ifdef VBOX
    504578    remR3ChangeCpuMode(env);
    505 #endif 
     579#endif
    506580}
    507581
    508582/* XXX: also flush 4MB pages */
    509 void cpu_x86_flush_tlb(CPUX86State *env, uint32_t addr)
     583void cpu_x86_flush_tlb(CPUX86State *env, target_ulong addr)
    510584{
    511585#if defined(DEBUG) && defined(VBOX)
    512586    uint32_t pde;
    513     uint8_t *pde_ptr;
    514587
    515588    /* page directory entry */
    516     pde_ptr = remR3GCPhys2HCVirt(env, (((env->cr[3] & ~0xfff) + ((addr >> 20) & ~3)) & env->a20_mask));
    517     pde = ldl_raw(pde_ptr);
     589    pde = remR3PhysReadU32(((env->cr[3] & ~0xfff) + ((addr >> 20) & ~3)) & env->a20_mask);
     590
    518591    /* if PSE bit is set, then we use a 4MB page */
    519592    if ((pde & PG_PSE_MASK) && (env->cr[4] & CR4_PSE_MASK)) {
     
    534607    env->error_code = (is_write << PG_ERROR_W_BIT);
    535608    env->error_code |= PG_ERROR_U_MASK;
     609    env->exception_index = EXCP0E_PAGE;
    536610    return 1;
    537611}
     
    543617
    544618#else
     619
     620#define PHYS_ADDR_MASK 0xfffff000
    545621
    546622/* return value:
     
    551627*/
    552628int cpu_x86_handle_mmu_fault(CPUX86State *env, target_ulong addr,
    553                              int is_write, int is_user, int is_softmmu)
    554 {
     629                             int is_write1, int is_user, int is_softmmu)
     630{
     631    uint64_t ptep, pte;
    555632    uint32_t pdpe_addr, pde_addr, pte_addr;
    556     uint32_t pde, pte, ptep, pdpe;
    557     int error_code, is_dirty, prot, page_size, ret;
     633    int error_code, is_dirty, prot, page_size, ret, is_write;
    558634    unsigned long paddr, page_offset;
    559635    target_ulong vaddr, virt_addr;
     
    561637#if defined(DEBUG_MMU)
    562638    printf("MMU fault: addr=" TARGET_FMT_lx " w=%d u=%d eip=" TARGET_FMT_lx "\n",
    563            addr, is_write, is_user, env->eip);
    564 #endif
    565     is_write &= 1;
     639           addr, is_write1, is_user, env->eip);
     640#endif
     641    is_write = is_write1 & 1;
    566642   
    567643    if (!(env->cr[0] & CR0_PG_MASK)) {
    568644        pte = addr;
    569645        virt_addr = addr & TARGET_PAGE_MASK;
    570         prot = PAGE_READ | PAGE_WRITE;
     646        prot = PAGE_READ | PAGE_WRITE | PAGE_EXEC;
    571647        page_size = 4096;
    572648        goto do_mapping;
     
    574650
    575651    if (env->cr[4] & CR4_PAE_MASK) {
     652        uint64_t pde, pdpe;
     653
    576654        /* XXX: we only use 32 bit physical addresses */
    577655#ifdef TARGET_X86_64
    578656        if (env->hflags & HF_LMA_MASK) {
    579             uint32_t pml4e_addr, pml4e;
     657            uint32_t pml4e_addr;
     658            uint64_t pml4e;
    580659            int32_t sext;
    581660
    582             /* XXX: handle user + rw rights */
    583             /* XXX: handle NX flag */
    584661            /* test virtual address sign extension */
    585662            sext = (int64_t)addr >> 47;
    586663            if (sext != 0 && sext != -1) {
    587                 error_code = 0;
    588                 goto do_fault;
     664                env->error_code = 0;
     665                env->exception_index = EXCP0D_GPF;
     666                return 1;
    589667            }
    590668           
    591669            pml4e_addr = ((env->cr[3] & ~0xfff) + (((addr >> 39) & 0x1ff) << 3)) &
    592670                env->a20_mask;
    593             pml4e = ldl_phys(pml4e_addr);
     671            pml4e = ldq_phys(pml4e_addr);
    594672            if (!(pml4e & PG_PRESENT_MASK)) {
    595673                error_code = 0;
    596674                goto do_fault;
    597675            }
     676            if (!(env->efer & MSR_EFER_NXE) && (pml4e & PG_NX_MASK)) {
     677                error_code = PG_ERROR_RSVD_MASK;
     678                goto do_fault;
     679            }
    598680            if (!(pml4e & PG_ACCESSED_MASK)) {
    599681                pml4e |= PG_ACCESSED_MASK;
    600682                stl_phys_notdirty(pml4e_addr, pml4e);
    601683            }
    602            
    603             pdpe_addr = ((pml4e & ~0xfff) + (((addr >> 30) & 0x1ff) << 3)) &
     684            ptep = pml4e ^ PG_NX_MASK;
     685            pdpe_addr = ((pml4e & PHYS_ADDR_MASK) + (((addr >> 30) & 0x1ff) << 3)) &
    604686                env->a20_mask;
    605             pdpe = ldl_phys(pdpe_addr);
     687            pdpe = ldq_phys(pdpe_addr);
    606688            if (!(pdpe & PG_PRESENT_MASK)) {
    607689                error_code = 0;
    608690                goto do_fault;
    609691            }
     692            if (!(env->efer & MSR_EFER_NXE) && (pdpe & PG_NX_MASK)) {
     693                error_code = PG_ERROR_RSVD_MASK;
     694                goto do_fault;
     695            }
     696            ptep &= pdpe ^ PG_NX_MASK;
    610697            if (!(pdpe & PG_ACCESSED_MASK)) {
    611698                pdpe |= PG_ACCESSED_MASK;
    612699                stl_phys_notdirty(pdpe_addr, pdpe);
    613700            }
    614         } else 
     701        } else
    615702#endif
    616703        {
     704            /* XXX: load them when cr3 is loaded ? */
    617705            pdpe_addr = ((env->cr[3] & ~0x1f) + ((addr >> 30) << 3)) &
    618706                env->a20_mask;
    619             pdpe = ldl_phys(pdpe_addr);
     707            pdpe = ldq_phys(pdpe_addr);
    620708            if (!(pdpe & PG_PRESENT_MASK)) {
    621709                error_code = 0;
    622710                goto do_fault;
    623711            }
    624         }
    625 
    626         pde_addr = ((pdpe & ~0xfff) + (((addr >> 21) & 0x1ff) << 3)) &
     712            ptep = PG_NX_MASK | PG_USER_MASK | PG_RW_MASK;
     713        }
     714
     715        pde_addr = ((pdpe & PHYS_ADDR_MASK) + (((addr >> 21) & 0x1ff) << 3)) &
    627716            env->a20_mask;
    628         pde = ldl_phys(pde_addr);
     717        pde = ldq_phys(pde_addr);
    629718        if (!(pde & PG_PRESENT_MASK)) {
    630719            error_code = 0;
    631720            goto do_fault;
    632721        }
     722        if (!(env->efer & MSR_EFER_NXE) && (pde & PG_NX_MASK)) {
     723            error_code = PG_ERROR_RSVD_MASK;
     724            goto do_fault;
     725        }
     726        ptep &= pde ^ PG_NX_MASK;
    633727        if (pde & PG_PSE_MASK) {
    634728            /* 2 MB page */
    635729            page_size = 2048 * 1024;
    636             goto handle_big_page;
     730            ptep ^= PG_NX_MASK;
     731            if ((ptep & PG_NX_MASK) && is_write1 == 2)
     732                goto do_fault_protect;
     733            if (is_user) {
     734                if (!(ptep & PG_USER_MASK))
     735                    goto do_fault_protect;
     736                if (is_write && !(ptep & PG_RW_MASK))
     737                    goto do_fault_protect;
     738            } else {
     739                if ((env->cr[0] & CR0_WP_MASK) &&
     740                    is_write && !(ptep & PG_RW_MASK))
     741                    goto do_fault_protect;
     742            }
     743            is_dirty = is_write && !(pde & PG_DIRTY_MASK);
     744            if (!(pde & PG_ACCESSED_MASK) || is_dirty) {
     745                pde |= PG_ACCESSED_MASK;
     746                if (is_dirty)
     747                    pde |= PG_DIRTY_MASK;
     748                stl_phys_notdirty(pde_addr, pde);
     749            }
     750            /* align to page_size */
     751            pte = pde & ((PHYS_ADDR_MASK & ~(page_size - 1)) | 0xfff);
     752            virt_addr = addr & ~(page_size - 1);
    637753        } else {
    638754            /* 4 KB page */
     
    641757                stl_phys_notdirty(pde_addr, pde);
    642758            }
    643             pte_addr = ((pde & ~0xfff) + (((addr >> 12) & 0x1ff) << 3)) &
     759            pte_addr = ((pde & PHYS_ADDR_MASK) + (((addr >> 12) & 0x1ff) << 3)) &
    644760                env->a20_mask;
    645             goto handle_4k_page;
     761            pte = ldq_phys(pte_addr);
     762            if (!(pte & PG_PRESENT_MASK)) {
     763                error_code = 0;
     764                goto do_fault;
     765            }
     766            if (!(env->efer & MSR_EFER_NXE) && (pte & PG_NX_MASK)) {
     767                error_code = PG_ERROR_RSVD_MASK;
     768                goto do_fault;
     769            }
     770            /* combine pde and pte nx, user and rw protections */
     771            ptep &= pte ^ PG_NX_MASK;
     772            ptep ^= PG_NX_MASK;
     773            if ((ptep & PG_NX_MASK) && is_write1 == 2)
     774                goto do_fault_protect;
     775            if (is_user) {
     776                if (!(ptep & PG_USER_MASK))
     777                    goto do_fault_protect;
     778                if (is_write && !(ptep & PG_RW_MASK))
     779                    goto do_fault_protect;
     780            } else {
     781                if ((env->cr[0] & CR0_WP_MASK) &&
     782                    is_write && !(ptep & PG_RW_MASK))
     783                    goto do_fault_protect;
     784            }
     785            is_dirty = is_write && !(pte & PG_DIRTY_MASK);
     786            if (!(pte & PG_ACCESSED_MASK) || is_dirty) {
     787                pte |= PG_ACCESSED_MASK;
     788                if (is_dirty)
     789                    pte |= PG_DIRTY_MASK;
     790                stl_phys_notdirty(pte_addr, pte);
     791            }
     792            page_size = 4096;
     793            virt_addr = addr & ~0xfff;
     794            pte = pte & (PHYS_ADDR_MASK | 0xfff);
    646795        }
    647796    } else {
     797        uint32_t pde;
     798
    648799        /* page directory entry */
    649800        pde_addr = ((env->cr[3] & ~0xfff) + ((addr >> 20) & ~3)) &
     
    657808        if ((pde & PG_PSE_MASK) && (env->cr[4] & CR4_PSE_MASK)) {
    658809            page_size = 4096 * 1024;
    659         handle_big_page:
    660810            if (is_user) {
    661811                if (!(pde & PG_USER_MASK))
     
    688838            pte_addr = ((pde & ~0xfff) + ((addr >> 10) & 0xffc)) &
    689839                env->a20_mask;
    690         handle_4k_page:
    691840            pte = ldl_phys(pte_addr);
    692841            if (!(pte & PG_PRESENT_MASK)) {
     
    716865            virt_addr = addr & ~0xfff;
    717866        }
    718 
    719         /* the page can be put in the TLB */
    720         prot = PAGE_READ;
    721         if (pte & PG_DIRTY_MASK) {
    722             /* only set write access if already dirty... otherwise wait
    723                for dirty access */
    724             if (is_user) {
    725                 if (ptep & PG_RW_MASK)
    726                     prot |= PAGE_WRITE;
    727             } else {
    728                 if (!(env->cr[0] & CR0_WP_MASK) ||
    729                     (ptep & PG_RW_MASK))
    730                     prot |= PAGE_WRITE;
    731             }
     867    }
     868    /* the page can be put in the TLB */
     869    prot = PAGE_READ;
     870    if (!(ptep & PG_NX_MASK))
     871        prot |= PAGE_EXEC;
     872    if (pte & PG_DIRTY_MASK) {
     873        /* only set write access if already dirty... otherwise wait
     874           for dirty access */
     875        if (is_user) {
     876            if (ptep & PG_RW_MASK)
     877                prot |= PAGE_WRITE;
     878        } else {
     879            if (!(env->cr[0] & CR0_WP_MASK) ||
     880                (ptep & PG_RW_MASK))
     881                prot |= PAGE_WRITE;
    732882        }
    733883    }
     
    741891    vaddr = virt_addr + page_offset;
    742892   
    743     ret = tlb_set_page(env, vaddr, paddr, prot, is_user, is_softmmu);
     893    ret = tlb_set_page_exec(env, vaddr, paddr, prot, is_user, is_softmmu);
    744894    return ret;
    745895 do_fault_protect:
     
    747897 do_fault:
    748898    env->cr[2] = addr;
    749     env->error_code = (is_write << PG_ERROR_W_BIT) | error_code;
     899    error_code |= (is_write << PG_ERROR_W_BIT);
    750900    if (is_user)
    751         env->error_code |= PG_ERROR_U_MASK;
     901        error_code |= PG_ERROR_U_MASK;
     902    if (is_write1 == 2 &&
     903        (env->efer & MSR_EFER_NXE) &&
     904        (env->cr[4] & CR4_PAE_MASK))
     905        error_code |= PG_ERROR_I_D_MASK;
     906    env->error_code = error_code;
     907    env->exception_index = EXCP0E_PAGE;
    752908    return 1;
    753909}
  • trunk/src/recompiler/target-i386/op.c

    r1514 r2422  
    226226void OPPROTO op_bswapq_T0(void)
    227227{
    228     T0 = bswap64(T0);
     228    helper_bswapq_T0();
    229229}
    230230#endif
     
    492492    uint32_t idx = (PARAM1 - offsetof(CPUX86State,segs[0].base)) / sizeof(SegmentCache);
    493493
    494     if (env->segs[idx].newselector && !(env->eflags & VM_MASK))
    495     {
     494    if (env->segs[idx].newselector && !(env->eflags & VM_MASK)) {
    496495        sync_seg(env, idx, env->segs[idx].newselector);
    497496    }
     
    499498    if (    (env->cr[0] & (CR0_PE_MASK|CR0_PG_MASK)) == (CR0_PE_MASK|CR0_PG_MASK)
    500499        &&  !(env->eflags & VM_MASK)
    501         &&  env->segs[idx].selector == 0
    502        )
    503     {
     500        &&  env->segs[idx].selector == 0) {
    504501        raise_exception(EXCP0D_GPF);
    505502    }
    506503    A0 = (uint32_t)env->segs[idx].base;
    507504    FORCE_RET();
    508 #else
     505#else  /* !VBOX */
    509506    A0 = (uint32_t)*(target_ulong *)((char *)env + PARAM1);
    510 #endif
     507#endif /* !VBOX */
    511508}
    512509
     
    516513    uint32_t idx = (PARAM1 - offsetof(CPUX86State,segs[0].base)) / sizeof(SegmentCache);
    517514
    518     if (env->segs[idx].newselector && !(env->eflags & VM_MASK))
    519     {
     515    if (env->segs[idx].newselector && !(env->eflags & VM_MASK)) {
    520516        sync_seg(env, idx, env->segs[idx].newselector);
    521517    }
     
    523519    if (    (env->cr[0] & (CR0_PE_MASK|CR0_PG_MASK)) == (CR0_PE_MASK|CR0_PG_MASK)
    524520        &&  !(env->eflags & VM_MASK)
    525         &&  env->segs[idx].selector == 0
    526        )
    527     {
     521        &&  env->segs[idx].selector == 0) {
    528522        raise_exception(EXCP0D_GPF);
    529523    }
    530524    A0 = (uint32_t)(A0 + env->segs[idx].base);
    531525    FORCE_RET();
    532 #else
     526#else  /* !VBOX */
    533527    A0 = (uint32_t)(A0 + *(target_ulong *)((char *)env + PARAM1));
    534 #endif
     528#endif /* !VBOX */
    535529}
    536530
     
    600594
    601595    if (env->segs[idx].newselector && !(env->eflags & VM_MASK))
    602     {
    603596        sync_seg(env, idx, env->segs[idx].newselector);
    604     }
    605597    A0 = (target_ulong)env->segs[idx].base;
    606 #else
     598#else  /* !VBOX */
    607599    A0 = *(target_ulong *)((char *)env + PARAM1);
    608 #endif
     600#endif /* !VBOX */
    609601}
    610602
     
    615607
    616608    if (env->segs[idx].newselector && !(env->eflags & VM_MASK))
    617     {
    618609        sync_seg(env, idx, env->segs[idx].newselector);
    619     }
    620610    A0 += (target_ulong)env->segs[idx].base;
    621 #else
     611#else  /* !VBOX */
    622612    A0 += *(target_ulong *)((char *)env + PARAM1);
    623 #endif
     613#endif /* !VBOX */
    624614}
    625615
     
    739729}
    740730
    741 #ifdef VBOX
     731void OPPROTO op_rsm(void)
     732{
     733    helper_rsm();
     734}
     735
     736#ifndef VBOX
     737#if 0
    742738/* vm86plus instructions */
     739void OPPROTO op_cli_vm(void)
     740{
     741    env->eflags &= ~VIF_MASK;
     742}
     743
     744void OPPROTO op_sti_vm(void)
     745{
     746    env->eflags |= VIF_MASK;
     747    if (env->eflags & VIP_MASK) {
     748        EIP = PARAM1;
     749        raise_exception(EXCP0D_GPF);
     750    }
     751    FORCE_RET();
     752}
     753#endif
     754
     755#else /* VBOX */
    743756void OPPROTO op_cli_vme(void)
    744757{
     
    755768    FORCE_RET();
    756769}
    757 #endif
     770#endif /* VBOX */
    758771
    759772void OPPROTO op_boundw(void)
     
    792805
    793806#ifdef VBOX
    794 
    795 /** @todo Ugly: Exit current TB to process an external interrupt request */
    796 #define CPU_INTERRUPT_EXTERNAL_EXIT  0x0200 /* also defined in cpu-all.h!! */
    797 #define CPU_INTERRUPT_EXTERNAL_HARD  0x0400 /* also defined in cpu-all.h!! */
    798 #define CPU_INTERRUPT_EXTERNAL_TIMER 0x0800 /* also defined in cpu-all.h!! */
    799 #define CPU_INTERRUPT_EXTERNAL_DMA   0x1000 /* also defined in cpu-all.h!! */
    800 
    801807void OPPROTO op_check_external_event(void)
    802808{
     
    866872void OPPROTO op_movswl_EAX_AX(void)
    867873{
    868     EAX = (int16_t)EAX;
     874    EAX = (uint32_t)((int16_t)EAX);
    869875}
    870876
     
    888894void OPPROTO op_movslq_EDX_EAX(void)
    889895{
    890     EDX = (int32_t)EAX >> 31;
     896    EDX = (uint32_t)((int32_t)EAX >> 31);
    891897}
    892898
     
    956962void op_addl_A0_SS(void)
    957963{
    958     A0 += (long)env->segs[R_SS].base;
     964    A0 = (uint32_t)(A0 + env->segs[R_SS].base);
    959965}
    960966
     
    10001006
    10011007#ifdef TARGET_X86_64
     1008void op_subq_A0_2(void)
     1009{
     1010    A0 -= 2;
     1011}
     1012
    10021013void op_subq_A0_8(void)
    10031014{
     
    10301041    helper_enter_level(PARAM1, PARAM2);
    10311042}
     1043
     1044#ifdef TARGET_X86_64
     1045void OPPROTO op_enter64_level(void)
     1046{
     1047    helper_enter64_level(PARAM1, PARAM2);
     1048}
     1049#endif
    10321050
    10331051void OPPROTO op_sysenter(void)
     
    15151533}
    15161534
     1535#ifndef VBOX
     1536#if 0
    15171537/* vm86plus version */
    1518 #ifdef VBOX
    1519 /* IOPL != 3, CR4.VME=1 */
    1520 void OPPROTO op_movw_eflags_T0_vme(void)
    1521 {
    1522     unsigned int new_eflags = T0;
    1523 
    1524     /* if virtual interrupt pending and (virtual) interrupts will be enabled -> #GP */
    1525     /* if TF will be set -> #GP */
    1526     if (    ((new_eflags & IF_MASK) && (env->eflags & VIP_MASK))
    1527         ||  (new_eflags & TF_MASK))
    1528     {
    1529         raise_exception(EXCP0D_GPF);
     1538void OPPROTO op_movw_eflags_T0_vm(void)
     1539{
     1540    int eflags;
     1541    eflags = T0;
     1542    CC_SRC = eflags & (CC_O | CC_S | CC_Z | CC_A | CC_P | CC_C);
     1543    DF = 1 - (2 * ((eflags >> 10) & 1));
     1544    /* we also update some system flags as in user mode */
     1545    env->eflags = (env->eflags & ~(FL_UPDATE_MASK16 | VIF_MASK)) |
     1546        (eflags & FL_UPDATE_MASK16);
     1547    if (eflags & IF_MASK) {
     1548        env->eflags |= VIF_MASK;
     1549        if (env->eflags & VIP_MASK) {
     1550            EIP = PARAM1;
     1551            raise_exception(EXCP0D_GPF);
     1552        }
    15301553    }
    1531     else
    1532     {
    1533         load_eflags(new_eflags, (TF_MASK | AC_MASK | ID_MASK | NT_MASK) & 0xffff);
    1534 
    1535         if (new_eflags & IF_MASK)
    1536             env->eflags |= VIF_MASK;
    1537         else
    1538             env->eflags &= ~VIF_MASK;
    1539     }
    1540 
    1541     FORCE_RET();
    1542 }
    1543 #endif
    1544 
    1545 #if 0
     1554    FORCE_RET();
     1555}
     1556
    15461557void OPPROTO op_movl_eflags_T0_vm(void)
    15471558{
     
    15641575#endif
    15651576
     1577#else /* VBOX */
     1578/* IOPL != 3, CR4.VME=1 */
     1579void OPPROTO op_movw_eflags_T0_vme(void)
     1580{
     1581    unsigned int new_eflags = T0;
     1582
     1583    /* if virtual interrupt pending and (virtual) interrupts will be enabled -> #GP */
     1584    /* if TF will be set -> #GP */
     1585    if (    ((new_eflags & IF_MASK) && (env->eflags & VIP_MASK))
     1586        ||  (new_eflags & TF_MASK)) {
     1587        raise_exception(EXCP0D_GPF);
     1588    } else {
     1589        load_eflags(new_eflags, (TF_MASK | AC_MASK | ID_MASK | NT_MASK) & 0xffff);
     1590
     1591        if (new_eflags & IF_MASK) {
     1592            env->eflags |= VIF_MASK;
     1593        } else {
     1594            env->eflags &= ~VIF_MASK;
     1595        }
     1596    }
     1597
     1598    FORCE_RET();
     1599}
     1600#endif /* VBOX */
     1601
    15661602/* XXX: compute only O flag */
    15671603void OPPROTO op_movb_eflags_T0(void)
     
    15821618
    15831619/* vm86plus version */
    1584 #ifdef VBOX
     1620#ifdef VBOX /* #if 0 */
    15851621void OPPROTO op_movl_T0_eflags_vme(void)
    15861622{
     
    15931629    T0 = eflags;
    15941630}
    1595 #endif
     1631#endif /* VBOX / 0 */
    15961632
    15971633void OPPROTO op_cld(void)
     
    19662002
    19672003    d = ST0;
    1968     val = lrint(d);
     2004    val = floatx_to_int32(d, &env->fp_status);
    19692005    if (val != (int16_t)val)
    19702006        val = -32768;
     
    19832019
    19842020    d = ST0;
    1985     val = lrint(d);
     2021    val = floatx_to_int32(d, &env->fp_status);
    19862022    stl(A0, val);
    19872023    FORCE_RET();
     
    19982034
    19992035    d = ST0;
    2000     val = llrint(d);
     2036    val = floatx_to_int64(d, &env->fp_status);
     2037    stq(A0, val);
     2038    FORCE_RET();
     2039}
     2040
     2041void OPPROTO op_fistt_ST0_A0(void)
     2042{
     2043#if defined(__sparc__) && !defined(__sparc_v9__)
     2044    register CPU86_LDouble d asm("o0");
     2045#else
     2046    CPU86_LDouble d;
     2047#endif
     2048    int val;
     2049
     2050    d = ST0;
     2051    val = floatx_to_int32_round_to_zero(d, &env->fp_status);
     2052    if (val != (int16_t)val)
     2053        val = -32768;
     2054    stw(A0, val);
     2055    FORCE_RET();
     2056}
     2057
     2058void OPPROTO op_fisttl_ST0_A0(void)
     2059{
     2060#if defined(__sparc__) && !defined(__sparc_v9__)
     2061    register CPU86_LDouble d asm("o0");
     2062#else
     2063    CPU86_LDouble d;
     2064#endif
     2065    int val;
     2066
     2067    d = ST0;
     2068    val = floatx_to_int32_round_to_zero(d, &env->fp_status);
     2069    stl(A0, val);
     2070    FORCE_RET();
     2071}
     2072
     2073void OPPROTO op_fisttll_ST0_A0(void)
     2074{
     2075#if defined(__sparc__) && !defined(__sparc_v9__)
     2076    register CPU86_LDouble d asm("o0");
     2077#else
     2078    CPU86_LDouble d;
     2079#endif
     2080    int64_t val;
     2081
     2082    d = ST0;
     2083    val = floatx_to_int64_round_to_zero(d, &env->fp_status);
    20012084    stq(A0, val);
    20022085    FORCE_RET();
     
    20722155/* FPU operations */
    20732156
    2074 /* XXX: handle nans */
     2157const int fcom_ccval[4] = {0x0100, 0x4000, 0x0000, 0x4500};
     2158
    20752159void OPPROTO op_fcom_ST0_FT0(void)
    20762160{
    2077     env->fpus &= (~0x4500);     /* (C3,C2,C0) <-- 000 */
    2078     if (ST0 < FT0)
    2079         env->fpus |= 0x100;     /* (C3,C2,C0) <-- 001 */
    2080     else if (ST0 == FT0)
    2081         env->fpus |= 0x4000; /* (C3,C2,C0) <-- 100 */
    2082     FORCE_RET();
    2083 }
    2084 
    2085 /* XXX: handle nans */
     2161    int ret;
     2162
     2163    ret = floatx_compare(ST0, FT0, &env->fp_status);
     2164    env->fpus = (env->fpus & ~0x4500) | fcom_ccval[ret + 1];
     2165    FORCE_RET();
     2166}
     2167
    20862168void OPPROTO op_fucom_ST0_FT0(void)
    20872169{
    2088     env->fpus &= (~0x4500);     /* (C3,C2,C0) <-- 000 */
    2089     if (ST0 < FT0)
    2090         env->fpus |= 0x100;     /* (C3,C2,C0) <-- 001 */
    2091     else if (ST0 == FT0)
    2092         env->fpus |= 0x4000; /* (C3,C2,C0) <-- 100 */
    2093     FORCE_RET();
    2094 }
    2095 
    2096 /* XXX: handle nans */
     2170    int ret;
     2171
     2172    ret = floatx_compare_quiet(ST0, FT0, &env->fp_status);
     2173    env->fpus = (env->fpus & ~0x4500) | fcom_ccval[ret+ 1];
     2174    FORCE_RET();
     2175}
     2176
     2177const int fcomi_ccval[4] = {CC_C, CC_Z, 0, CC_Z | CC_P | CC_C};
     2178
    20972179void OPPROTO op_fcomi_ST0_FT0(void)
    20982180{
    20992181    int eflags;
     2182    int ret;
     2183
     2184    ret = floatx_compare(ST0, FT0, &env->fp_status);
    21002185    eflags = cc_table[CC_OP].compute_all();
    2101     eflags &= ~(CC_Z | CC_P | CC_C);
    2102     if (ST0 < FT0)
    2103         eflags |= CC_C;
    2104     else if (ST0 == FT0)
    2105         eflags |= CC_Z;
     2186    eflags = (eflags & ~(CC_Z | CC_P | CC_C)) | fcomi_ccval[ret + 1];
    21062187    CC_SRC = eflags;
    21072188    FORCE_RET();
    21082189}
    21092190
    2110 /* XXX: handle nans */
    21112191void OPPROTO op_fucomi_ST0_FT0(void)
    21122192{
    21132193    int eflags;
     2194    int ret;
     2195
     2196    ret = floatx_compare_quiet(ST0, FT0, &env->fp_status);
    21142197    eflags = cc_table[CC_OP].compute_all();
    2115     eflags &= ~(CC_Z | CC_P | CC_C);
    2116     if (ST0 < FT0)
    2117         eflags |= CC_C;
    2118     else if (ST0 == FT0)
    2119         eflags |= CC_Z;
     2198    eflags = (eflags & ~(CC_Z | CC_P | CC_C)) | fcomi_ccval[ret + 1];
    21202199    CC_SRC = eflags;
    21212200    FORCE_RET();
     
    22012280void OPPROTO op_fchs_ST0(void)
    22022281{
    2203     ST0 = -ST0;
     2282    ST0 = floatx_chs(ST0);
    22042283}
    22052284
    22062285void OPPROTO op_fabs_ST0(void)
    22072286{
    2208     ST0 = fabs(ST0);
     2287    ST0 = floatx_abs(ST0);
    22092288}
    22102289
     
    23512430void OPPROTO op_fldcw_A0(void)
    23522431{
    2353     int rnd_type;
    23542432    env->fpuc = lduw(A0);
    2355     /* set rounding mode */
    2356     switch(env->fpuc & RC_MASK) {
    2357     default:
    2358     case RC_NEAR:
    2359         rnd_type = FE_TONEAREST;
    2360         break;
    2361     case RC_DOWN:
    2362         rnd_type = FE_DOWNWARD;
    2363         break;
    2364     case RC_UP:
    2365         rnd_type = FE_UPWARD;
    2366         break;
    2367     case RC_CHOP:
    2368         rnd_type = FE_TOWARDZERO;
    2369         break;
    2370     }
    2371     fesetround(rnd_type);
     2433    update_fp_status();
    23722434}
    23732435
     
    25012563#define SHIFT 1
    25022564#include "ops_sse.h"
     2565
     2566#ifdef VBOX
     2567/* Instantiate the structure signatures. */
     2568# define REM_STRUCT_OP 1
     2569# include "../InnoTek/structs.h"
     2570#endif
     2571
  • trunk/src/recompiler/target-i386/ops_sse.h

    r1 r2422  
    559559}
    560560
     561#ifdef TARGET_X86_64
     562void OPPROTO glue(op_movq_mm_T0, SUFFIX) (void)
     563{
     564    Reg *d;
     565    d = (Reg *)((char *)env + PARAM1);
     566    d->Q(0) = T0;
     567#if SHIFT == 1
     568    d->Q(1) = 0;
     569#endif
     570}
     571
     572void OPPROTO glue(op_movq_T0_mm, SUFFIX) (void)
     573{
     574    Reg *s;
     575    s = (Reg *)((char *)env + PARAM1);
     576    T0 = s->Q(0);
     577}
     578#endif
     579
    561580#if SHIFT == 0
    562581void OPPROTO glue(op_pshufw, SUFFIX) (void)
    563582{
     583#if __GCC__ == 3 || defined(__AMD64__)
    564584    Reg r, *d, *s;
    565585    int order;
     
    572592    r.W(3) = s->W((order >> 6) & 3);
    573593    *d = r;
     594#else
     595    Reg *s;
     596    int order;
     597    uint32_t l0, l1;
     598    s = (Reg *)((char *)env + PARAM2);
     599    order = PARAM3;
     600    l0 = s->W(order & 3);
     601    l0 |= (uint32_t)s->W((order >> 2) & 3) << 16;
     602    l1 = s->W((order >> 4) & 3);
     603    l1 |= (uint32_t)s->W((order >> 6) & 3) << 16;
     604
     605    s = (Reg *)((char *)env + PARAM1);
     606    s->_l[0] = l0;
     607    s->_l[1] = l1;
     608#endif
    574609}
    575610#else
     
    655690    d = (Reg *)((char *)env + PARAM1);\
    656691    s = (Reg *)((char *)env + PARAM2);\
    657     d->XMM_S(0) = F(d->XMM_S(0), s->XMM_S(0));\
    658     d->XMM_S(1) = F(d->XMM_S(1), s->XMM_S(1));\
    659     d->XMM_S(2) = F(d->XMM_S(2), s->XMM_S(2));\
    660     d->XMM_S(3) = F(d->XMM_S(3), s->XMM_S(3));\
     692    d->XMM_S(0) = F(32, d->XMM_S(0), s->XMM_S(0));\
     693    d->XMM_S(1) = F(32, d->XMM_S(1), s->XMM_S(1));\
     694    d->XMM_S(2) = F(32, d->XMM_S(2), s->XMM_S(2));\
     695    d->XMM_S(3) = F(32, d->XMM_S(3), s->XMM_S(3));\
    661696}\
    662697\
     
    666701    d = (Reg *)((char *)env + PARAM1);\
    667702    s = (Reg *)((char *)env + PARAM2);\
    668     d->XMM_S(0) = F(d->XMM_S(0), s->XMM_S(0));\
     703    d->XMM_S(0) = F(32, d->XMM_S(0), s->XMM_S(0));\
    669704}\
    670705void OPPROTO op_ ## name ## pd (void)\
     
    673708    d = (Reg *)((char *)env + PARAM1);\
    674709    s = (Reg *)((char *)env + PARAM2);\
    675     d->XMM_D(0) = F(d->XMM_D(0), s->XMM_D(0));\
    676     d->XMM_D(1) = F(d->XMM_D(1), s->XMM_D(1));\
     710    d->XMM_D(0) = F(64, d->XMM_D(0), s->XMM_D(0));\
     711    d->XMM_D(1) = F(64, d->XMM_D(1), s->XMM_D(1));\
    677712}\
    678713\
     
    682717    d = (Reg *)((char *)env + PARAM1);\
    683718    s = (Reg *)((char *)env + PARAM2);\
    684     d->XMM_D(0) = F(d->XMM_D(0), s->XMM_D(0));\
    685 }
    686 
    687 #define FPU_ADD(a, b) (a) + (b)
    688 #define FPU_SUB(a, b) (a) - (b)
    689 #define FPU_MUL(a, b) (a) * (b)
    690 #define FPU_DIV(a, b) (a) / (b)
    691 #define FPU_MIN(a, b) (a) < (b) ? (a) : (b)
    692 #define FPU_MAX(a, b) (a) > (b) ? (a) : (b)
    693 #define FPU_SQRT(a, b) helper_sqrt(b)
     719    d->XMM_D(0) = F(64, d->XMM_D(0), s->XMM_D(0));\
     720}
     721
     722#define FPU_ADD(size, a, b) float ## size ## _add(a, b, &env->sse_status)
     723#define FPU_SUB(size, a, b) float ## size ## _sub(a, b, &env->sse_status)
     724#define FPU_MUL(size, a, b) float ## size ## _mul(a, b, &env->sse_status)
     725#define FPU_DIV(size, a, b) float ## size ## _div(a, b, &env->sse_status)
     726#define FPU_MIN(size, a, b) (a) < (b) ? (a) : (b)
     727#define FPU_MAX(size, a, b) (a) > (b) ? (a) : (b)
     728#define FPU_SQRT(size, a, b) float ## size ## _sqrt(b, &env->sse_status)
    694729
    695730SSE_OP_S(add, FPU_ADD)
     
    705740void OPPROTO op_cvtps2pd(void)
    706741{
    707     float s0, s1;
     742    float32 s0, s1;
    708743    Reg *d, *s;
    709744    d = (Reg *)((char *)env + PARAM1);
     
    711746    s0 = s->XMM_S(0);
    712747    s1 = s->XMM_S(1);
    713     d->XMM_D(0) = float32_to_float64(s0);
    714     d->XMM_D(1) = float32_to_float64(s1);
     748    d->XMM_D(0) = float32_to_float64(s0, &env->sse_status);
     749    d->XMM_D(1) = float32_to_float64(s1, &env->sse_status);
    715750}
    716751
     
    720755    d = (Reg *)((char *)env + PARAM1);
    721756    s = (Reg *)((char *)env + PARAM2);
    722     d->XMM_S(0) = float64_to_float32(s->XMM_D(0));
    723     d->XMM_S(1) = float64_to_float32(s->XMM_D(1));
     757    d->XMM_S(0) = float64_to_float32(s->XMM_D(0), &env->sse_status);
     758    d->XMM_S(1) = float64_to_float32(s->XMM_D(1), &env->sse_status);
    724759    d->Q(1) = 0;
    725760}
     
    730765    d = (Reg *)((char *)env + PARAM1);
    731766    s = (Reg *)((char *)env + PARAM2);
    732     d->XMM_D(0) = float32_to_float64(s->XMM_S(0));
     767    d->XMM_D(0) = float32_to_float64(s->XMM_S(0), &env->sse_status);
    733768}
    734769
     
    738773    d = (Reg *)((char *)env + PARAM1);
    739774    s = (Reg *)((char *)env + PARAM2);
    740     d->XMM_S(0) = float64_to_float32(s->XMM_D(0));
     775    d->XMM_S(0) = float64_to_float32(s->XMM_D(0), &env->sse_status);
    741776}
    742777
     
    746781    XMMReg *d = (XMMReg *)((char *)env + PARAM1);
    747782    XMMReg *s = (XMMReg *)((char *)env + PARAM2);
    748     d->XMM_S(0) = int32_to_float32(s->XMM_L(0));
    749     d->XMM_S(1) = int32_to_float32(s->XMM_L(1));
    750     d->XMM_S(2) = int32_to_float32(s->XMM_L(2));
    751     d->XMM_S(3) = int32_to_float32(s->XMM_L(3));
     783    d->XMM_S(0) = int32_to_float32(s->XMM_L(0), &env->sse_status);
     784    d->XMM_S(1) = int32_to_float32(s->XMM_L(1), &env->sse_status);
     785    d->XMM_S(2) = int32_to_float32(s->XMM_L(2), &env->sse_status);
     786    d->XMM_S(3) = int32_to_float32(s->XMM_L(3), &env->sse_status);
    752787}
    753788
     
    759794    l0 = (int32_t)s->XMM_L(0);
    760795    l1 = (int32_t)s->XMM_L(1);
    761     d->XMM_D(0) = int32_to_float64(l0);
    762     d->XMM_D(1) = int32_to_float64(l1);
     796    d->XMM_D(0) = int32_to_float64(l0, &env->sse_status);
     797    d->XMM_D(1) = int32_to_float64(l1, &env->sse_status);
    763798}
    764799
     
    767802    XMMReg *d = (Reg *)((char *)env + PARAM1);
    768803    MMXReg *s = (MMXReg *)((char *)env + PARAM2);
    769     d->XMM_S(0) = int32_to_float32(s->MMX_L(0));
    770     d->XMM_S(1) = int32_to_float32(s->MMX_L(1));
     804    d->XMM_S(0) = int32_to_float32(s->MMX_L(0), &env->sse_status);
     805    d->XMM_S(1) = int32_to_float32(s->MMX_L(1), &env->sse_status);
    771806}
    772807
     
    775810    XMMReg *d = (Reg *)((char *)env + PARAM1);
    776811    MMXReg *s = (MMXReg *)((char *)env + PARAM2);
    777     d->XMM_D(0) = int32_to_float64(s->MMX_L(0));
    778     d->XMM_D(1) = int32_to_float64(s->MMX_L(1));
     812    d->XMM_D(0) = int32_to_float64(s->MMX_L(0), &env->sse_status);
     813    d->XMM_D(1) = int32_to_float64(s->MMX_L(1), &env->sse_status);
    779814}
    780815
     
    782817{
    783818    XMMReg *d = (Reg *)((char *)env + PARAM1);
    784     d->XMM_S(0) = int32_to_float32(T0);
     819    d->XMM_S(0) = int32_to_float32(T0, &env->sse_status);
    785820}
    786821
     
    788823{
    789824    XMMReg *d = (Reg *)((char *)env + PARAM1);
    790     d->XMM_D(0) = int32_to_float64(T0);
     825    d->XMM_D(0) = int32_to_float64(T0, &env->sse_status);
    791826}
    792827
     
    795830{
    796831    XMMReg *d = (Reg *)((char *)env + PARAM1);
    797     d->XMM_S(0) = int64_to_float32(T0);
     832    d->XMM_S(0) = int64_to_float32(T0, &env->sse_status);
    798833}
    799834
     
    801836{
    802837    XMMReg *d = (Reg *)((char *)env + PARAM1);
    803     d->XMM_D(0) = int64_to_float64(T0);
     838    d->XMM_D(0) = int64_to_float64(T0, &env->sse_status);
    804839}
    805840#endif
     
    810845    XMMReg *d = (XMMReg *)((char *)env + PARAM1);
    811846    XMMReg *s = (XMMReg *)((char *)env + PARAM2);
    812     d->XMM_L(0) = lrint(s->XMM_S(0));
    813     d->XMM_L(1) = lrint(s->XMM_S(1));
    814     d->XMM_L(2) = lrint(s->XMM_S(2));
    815     d->XMM_L(3) = lrint(s->XMM_S(3));
     847    d->XMM_L(0) = float32_to_int32(s->XMM_S(0), &env->sse_status);
     848    d->XMM_L(1) = float32_to_int32(s->XMM_S(1), &env->sse_status);
     849    d->XMM_L(2) = float32_to_int32(s->XMM_S(2), &env->sse_status);
     850    d->XMM_L(3) = float32_to_int32(s->XMM_S(3), &env->sse_status);
    816851}
    817852
     
    820855    XMMReg *d = (XMMReg *)((char *)env + PARAM1);
    821856    XMMReg *s = (XMMReg *)((char *)env + PARAM2);
    822     d->XMM_L(0) = lrint(s->XMM_D(0));
    823     d->XMM_L(1) = lrint(s->XMM_D(1));
     857    d->XMM_L(0) = float64_to_int32(s->XMM_D(0), &env->sse_status);
     858    d->XMM_L(1) = float64_to_int32(s->XMM_D(1), &env->sse_status);
    824859    d->XMM_Q(1) = 0;
    825860}
     
    829864    MMXReg *d = (MMXReg *)((char *)env + PARAM1);
    830865    XMMReg *s = (XMMReg *)((char *)env + PARAM2);
    831     d->MMX_L(0) = lrint(s->XMM_S(0));
    832     d->MMX_L(1) = lrint(s->XMM_S(1));
     866    d->MMX_L(0) = float32_to_int32(s->XMM_S(0), &env->sse_status);
     867    d->MMX_L(1) = float32_to_int32(s->XMM_S(1), &env->sse_status);
    833868}
    834869
     
    837872    MMXReg *d = (MMXReg *)((char *)env + PARAM1);
    838873    XMMReg *s = (XMMReg *)((char *)env + PARAM2);
    839     d->MMX_L(0) = lrint(s->XMM_D(0));
    840     d->MMX_L(1) = lrint(s->XMM_D(1));
     874    d->MMX_L(0) = float64_to_int32(s->XMM_D(0), &env->sse_status);
     875    d->MMX_L(1) = float64_to_int32(s->XMM_D(1), &env->sse_status);
    841876}
    842877
     
    844879{
    845880    XMMReg *s = (XMMReg *)((char *)env + PARAM1);
    846     T0 = (int32_t)lrint(s->XMM_S(0));
     881    T0 = float32_to_int32(s->XMM_S(0), &env->sse_status);
    847882}
    848883
     
    850885{
    851886    XMMReg *s = (XMMReg *)((char *)env + PARAM1);
    852     T0 = (int32_t)lrint(s->XMM_D(0));
     887    T0 = float64_to_int32(s->XMM_D(0), &env->sse_status);
    853888}
    854889
     
    857892{
    858893    XMMReg *s = (XMMReg *)((char *)env + PARAM1);
    859     T0 = llrint(s->XMM_S(0));
     894    T0 = float32_to_int64(s->XMM_S(0), &env->sse_status);
    860895}
    861896
     
    863898{
    864899    XMMReg *s = (XMMReg *)((char *)env + PARAM1);
    865     T0 = llrint(s->XMM_D(0));
     900    T0 = float64_to_int64(s->XMM_D(0), &env->sse_status);
    866901}
    867902#endif
     
    872907    XMMReg *d = (XMMReg *)((char *)env + PARAM1);
    873908    XMMReg *s = (XMMReg *)((char *)env + PARAM2);
    874     d->XMM_L(0) = (int32_t)s->XMM_S(0);
    875     d->XMM_L(1) = (int32_t)s->XMM_S(1);
    876     d->XMM_L(2) = (int32_t)s->XMM_S(2);
    877     d->XMM_L(3) = (int32_t)s->XMM_S(3);
     909    d->XMM_L(0) = float32_to_int32_round_to_zero(s->XMM_S(0), &env->sse_status);
     910    d->XMM_L(1) = float32_to_int32_round_to_zero(s->XMM_S(1), &env->sse_status);
     911    d->XMM_L(2) = float32_to_int32_round_to_zero(s->XMM_S(2), &env->sse_status);
     912    d->XMM_L(3) = float32_to_int32_round_to_zero(s->XMM_S(3), &env->sse_status);
    878913}
    879914
     
    882917    XMMReg *d = (XMMReg *)((char *)env + PARAM1);
    883918    XMMReg *s = (XMMReg *)((char *)env + PARAM2);
    884     d->XMM_L(0) = (int32_t)s->XMM_D(0);
    885     d->XMM_L(1) = (int32_t)s->XMM_D(1);
     919    d->XMM_L(0) = float64_to_int32_round_to_zero(s->XMM_D(0), &env->sse_status);
     920    d->XMM_L(1) = float64_to_int32_round_to_zero(s->XMM_D(1), &env->sse_status);
    886921    d->XMM_Q(1) = 0;
    887922}
     
    891926    MMXReg *d = (MMXReg *)((char *)env + PARAM1);
    892927    XMMReg *s = (XMMReg *)((char *)env + PARAM2);
    893     d->MMX_L(0) = (int32_t)(s->XMM_S(0));
    894     d->MMX_L(1) = (int32_t)(s->XMM_S(1));
     928    d->MMX_L(0) = float32_to_int32_round_to_zero(s->XMM_S(0), &env->sse_status);
     929    d->MMX_L(1) = float32_to_int32_round_to_zero(s->XMM_S(1), &env->sse_status);
    895930}
    896931
     
    899934    MMXReg *d = (MMXReg *)((char *)env + PARAM1);
    900935    XMMReg *s = (XMMReg *)((char *)env + PARAM2);
    901     d->MMX_L(0) = (int32_t)(s->XMM_D(0));
    902     d->MMX_L(1) = (int32_t)(s->XMM_D(1));
     936    d->MMX_L(0) = float64_to_int32_round_to_zero(s->XMM_D(0), &env->sse_status);
     937    d->MMX_L(1) = float64_to_int32_round_to_zero(s->XMM_D(1), &env->sse_status);
    903938}
    904939
     
    906941{
    907942    XMMReg *s = (XMMReg *)((char *)env + PARAM1);
    908     T0 = (int32_t)(s->XMM_S(0));
     943    T0 = float32_to_int32_round_to_zero(s->XMM_S(0), &env->sse_status);
    909944}
    910945
     
    912947{
    913948    XMMReg *s = (XMMReg *)((char *)env + PARAM1);
    914     T0 = (int32_t)(s->XMM_D(0));
     949    T0 = float64_to_int32_round_to_zero(s->XMM_D(0), &env->sse_status);
    915950}
    916951
     
    919954{
    920955    XMMReg *s = (XMMReg *)((char *)env + PARAM1);
    921     T0 = (int64_t)(s->XMM_S(0));
     956    T0 = float32_to_int64_round_to_zero(s->XMM_S(0), &env->sse_status);
    922957}
    923958
     
    925960{
    926961    XMMReg *s = (XMMReg *)((char *)env + PARAM1);
    927     T0 = (int64_t)(s->XMM_D(0));
     962    T0 = float64_to_int64_round_to_zero(s->XMM_D(0), &env->sse_status);
    928963}
    929964#endif
     
    10321067    d = (Reg *)((char *)env + PARAM1);\
    10331068    s = (Reg *)((char *)env + PARAM2);\
    1034     d->XMM_L(0) = F(d->XMM_S(0), s->XMM_S(0));\
    1035     d->XMM_L(1) = F(d->XMM_S(1), s->XMM_S(1));\
    1036     d->XMM_L(2) = F(d->XMM_S(2), s->XMM_S(2));\
    1037     d->XMM_L(3) = F(d->XMM_S(3), s->XMM_S(3));\
     1069    d->XMM_L(0) = F(32, d->XMM_S(0), s->XMM_S(0));\
     1070    d->XMM_L(1) = F(32, d->XMM_S(1), s->XMM_S(1));\
     1071    d->XMM_L(2) = F(32, d->XMM_S(2), s->XMM_S(2));\
     1072    d->XMM_L(3) = F(32, d->XMM_S(3), s->XMM_S(3));\
    10381073}\
    10391074\
     
    10431078    d = (Reg *)((char *)env + PARAM1);\
    10441079    s = (Reg *)((char *)env + PARAM2);\
    1045     d->XMM_L(0) = F(d->XMM_S(0), s->XMM_S(0));\
     1080    d->XMM_L(0) = F(32, d->XMM_S(0), s->XMM_S(0));\
    10461081}\
    10471082void OPPROTO op_ ## name ## pd (void)\
     
    10501085    d = (Reg *)((char *)env + PARAM1);\
    10511086    s = (Reg *)((char *)env + PARAM2);\
    1052     d->XMM_Q(0) = F(d->XMM_D(0), s->XMM_D(0));\
    1053     d->XMM_Q(1) = F(d->XMM_D(1), s->XMM_D(1));\
     1087    d->XMM_Q(0) = F(64, d->XMM_D(0), s->XMM_D(0));\
     1088    d->XMM_Q(1) = F(64, d->XMM_D(1), s->XMM_D(1));\
    10541089}\
    10551090\
     
    10591094    d = (Reg *)((char *)env + PARAM1);\
    10601095    s = (Reg *)((char *)env + PARAM2);\
    1061     d->XMM_Q(0) = F(d->XMM_D(0), s->XMM_D(0));\
    1062 }
    1063 
    1064 #define FPU_CMPEQ(a, b) (a) == (b) ? -1 : 0
    1065 #define FPU_CMPLT(a, b) (a) < (b) ? -1 : 0
    1066 #define FPU_CMPLE(a, b) (a) <= (b) ? -1 : 0
    1067 #define FPU_CMPUNORD(a, b) (fpu_isnan(a) || fpu_isnan(b)) ? - 1 : 0
    1068 #define FPU_CMPNEQ(a, b) (a) == (b) ? 0 : -1
    1069 #define FPU_CMPNLT(a, b) (a) < (b) ? 0 : -1
    1070 #define FPU_CMPNLE(a, b) (a) <= (b) ? 0 : -1
    1071 #define FPU_CMPORD(a, b) (!fpu_isnan(a) && !fpu_isnan(b)) ? - 1 : 0
     1096    d->XMM_Q(0) = F(64, d->XMM_D(0), s->XMM_D(0));\
     1097}
     1098
     1099#define FPU_CMPEQ(size, a, b) float ## size ## _eq(a, b, &env->sse_status) ? -1 : 0
     1100#define FPU_CMPLT(size, a, b) float ## size ## _lt(a, b, &env->sse_status) ? -1 : 0
     1101#define FPU_CMPLE(size, a, b) float ## size ## _le(a, b, &env->sse_status) ? -1 : 0
     1102#define FPU_CMPUNORD(size, a, b) float ## size ## _unordered(a, b, &env->sse_status) ? - 1 : 0
     1103#define FPU_CMPNEQ(size, a, b) float ## size ## _eq(a, b, &env->sse_status) ? 0 : -1
     1104#define FPU_CMPNLT(size, a, b) float ## size ## _lt(a, b, &env->sse_status) ? 0 : -1
     1105#define FPU_CMPNLE(size, a, b) float ## size ## _le(a, b, &env->sse_status) ? 0 : -1
     1106#define FPU_CMPORD(size, a, b) float ## size ## _unordered(a, b, &env->sse_status) ? 0 : -1
    10721107
    10731108SSE_OP_CMP(cmpeq, FPU_CMPEQ)
     
    10801115SSE_OP_CMP(cmpord, FPU_CMPORD)
    10811116
     1117const int comis_eflags[4] = {CC_C, CC_Z, 0, CC_Z | CC_P | CC_C};
     1118
    10821119void OPPROTO op_ucomiss(void)
    10831120{
    1084     int eflags;
    1085     float s0, s1;
     1121    int ret;
     1122    float32 s0, s1;
    10861123    Reg *d, *s;
    10871124    d = (Reg *)((char *)env + PARAM1);
     
    10901127    s0 = d->XMM_S(0);
    10911128    s1 = s->XMM_S(0);
    1092     if (s0 < s1)
    1093         eflags = CC_C;
    1094     else if (s0 == s1)
    1095         eflags = CC_Z;
    1096     else
    1097         eflags = 0;
    1098     CC_SRC = eflags;
     1129    ret = float32_compare_quiet(s0, s1, &env->sse_status);
     1130    CC_SRC = comis_eflags[ret + 1];
    10991131    FORCE_RET();
    11001132}
     
    11021134void OPPROTO op_comiss(void)
    11031135{
    1104     int eflags;
    1105     float s0, s1;
     1136    int ret;
     1137    float32 s0, s1;
    11061138    Reg *d, *s;
    11071139    d = (Reg *)((char *)env + PARAM1);
     
    11101142    s0 = d->XMM_S(0);
    11111143    s1 = s->XMM_S(0);
    1112     if (s0 < s1)
    1113         eflags = CC_C;
    1114     else if (s0 == s1)
    1115         eflags = CC_Z;
    1116     else
    1117         eflags = 0;
    1118     CC_SRC = eflags;
     1144    ret = float32_compare(s0, s1, &env->sse_status);
     1145    CC_SRC = comis_eflags[ret + 1];
    11191146    FORCE_RET();
    11201147}
     
    11221149void OPPROTO op_ucomisd(void)
    11231150{
    1124     int eflags;
    1125     double d0, d1;
     1151    int ret;
     1152    float64 d0, d1;
    11261153    Reg *d, *s;
    11271154    d = (Reg *)((char *)env + PARAM1);
     
    11301157    d0 = d->XMM_D(0);
    11311158    d1 = s->XMM_D(0);
    1132     if (d0 < d1)
    1133         eflags = CC_C;
    1134     else if (d0 == d1)
    1135         eflags = CC_Z;
    1136     else
    1137         eflags = 0;
    1138     CC_SRC = eflags;
     1159    ret = float64_compare_quiet(d0, d1, &env->sse_status);
     1160    CC_SRC = comis_eflags[ret + 1];
    11391161    FORCE_RET();
    11401162}
     
    11421164void OPPROTO op_comisd(void)
    11431165{
    1144     int eflags;
    1145     double d0, d1;
     1166    int ret;
     1167    float64 d0, d1;
    11461168    Reg *d, *s;
    11471169    d = (Reg *)((char *)env + PARAM1);
     
    11501172    d0 = d->XMM_D(0);
    11511173    d1 = s->XMM_D(0);
    1152     if (d0 < d1)
    1153         eflags = CC_C;
    1154     else if (d0 == d1)
    1155         eflags = CC_Z;
    1156     else
    1157         eflags = 0;
    1158     CC_SRC = eflags;
     1174    ret = float64_compare(d0, d1, &env->sse_status);
     1175    CC_SRC = comis_eflags[ret + 1];
    11591176    FORCE_RET();
    11601177}
  • trunk/src/recompiler/target-i386/ops_template_mem.h

    r1 r2422  
    7575
    7676    if (T1 & SHIFT1_MASK) {
    77         count = T1 & SHIFT_MASK;       
     77        count = T1 & SHIFT_MASK;
    7878        src = T0;
    7979        T0 &= DATA_MASK;
  • trunk/src/recompiler/target-i386/translate.c

    r1514 r2422  
    2323#include <string.h>
    2424#include <inttypes.h>
     25#ifndef VBOX
    2526#include <signal.h>
    2627#include <assert.h>
     28#endif /* !VBOX */
    2729
    2830#include "cpu.h"
     
    634636        gen_op_shldw ## SUFFIX ## _T0_T1_ ## op ## _cc,\
    635637        gen_op_shrdw ## SUFFIX ## _T0_T1_ ## op ## _cc,\
    636     },\
     638     },\
    637639    {\
    638640        gen_op_shldl ## SUFFIX ## _T0_T1_ ## op ## _cc,\
     
    855857#ifdef VBOX
    856858    gen_check_external_event();
    857 #endif
     859#endif /* VBOX */
    858860#ifdef TARGET_X86_64
    859861    if (pc == (uint32_t)pc) {
     
    16721674    *reg_ptr = opreg;
    16731675    *offset_ptr = disp;
     1676}
     1677
     1678static void gen_nop_modrm(DisasContext *s, int modrm)
     1679{
     1680    int mod, rm, base, code;
     1681
     1682    mod = (modrm >> 6) & 3;
     1683    if (mod == 3)
     1684        return;
     1685    rm = modrm & 7;
     1686
     1687    if (s->aflag) {
     1688
     1689        base = rm;
     1690       
     1691        if (base == 4) {
     1692            code = ldub_code(s->pc++);
     1693            base = (code & 7);
     1694        }
     1695       
     1696        switch (mod) {
     1697        case 0:
     1698            if (base == 5) {
     1699                s->pc += 4;
     1700            }
     1701            break;
     1702        case 1:
     1703            s->pc++;
     1704            break;
     1705        default:
     1706        case 2:
     1707            s->pc += 4;
     1708            break;
     1709        }
     1710    } else {
     1711        switch (mod) {
     1712        case 0:
     1713            if (rm == 6) {
     1714                s->pc += 2;
     1715            }
     1716            break;
     1717        case 1:
     1718            s->pc++;
     1719            break;
     1720        default:
     1721        case 2:
     1722            s->pc += 2;
     1723            break;
     1724        }
     1725    }
    16741726}
    16751727
     
    26302682        case 0x12b: /* movntps */
    26312683        case 0x3f0: /* lddqu */
    2632             if (mod == 3) 
     2684            if (mod == 3)
    26332685                goto illegal_op;
    26342686            gen_lea_modrm(s, modrm, &reg_addr, &offset_addr);
     
    26362688            break;
    26372689        case 0x6e: /* movd mm, ea */
    2638             gen_ldst_modrm(s, modrm, OT_LONG, OR_TMP0, 0);
    2639             gen_op_movl_mm_T0_mmx(offsetof(CPUX86State,fpregs[reg].mmx));
     2690#ifdef TARGET_X86_64
     2691            if (s->dflag == 2) {
     2692                gen_ldst_modrm(s, modrm, OT_QUAD, OR_TMP0, 0);
     2693                gen_op_movq_mm_T0_mmx(offsetof(CPUX86State,fpregs[reg].mmx));
     2694            } else
     2695#endif
     2696            {
     2697                gen_ldst_modrm(s, modrm, OT_LONG, OR_TMP0, 0);
     2698                gen_op_movl_mm_T0_mmx(offsetof(CPUX86State,fpregs[reg].mmx));
     2699            }
    26402700            break;
    26412701        case 0x16e: /* movd xmm, ea */
    2642             gen_ldst_modrm(s, modrm, OT_LONG, OR_TMP0, 0);
    2643             gen_op_movl_mm_T0_xmm(offsetof(CPUX86State,xmm_regs[reg]));
     2702#ifdef TARGET_X86_64
     2703            if (s->dflag == 2) {
     2704                gen_ldst_modrm(s, modrm, OT_QUAD, OR_TMP0, 0);
     2705                gen_op_movq_mm_T0_xmm(offsetof(CPUX86State,xmm_regs[reg]));
     2706            } else
     2707#endif
     2708            {
     2709                gen_ldst_modrm(s, modrm, OT_LONG, OR_TMP0, 0);
     2710                gen_op_movl_mm_T0_xmm(offsetof(CPUX86State,xmm_regs[reg]));
     2711            }
    26442712            break;
    26452713        case 0x6f: /* movq mm, ea */
     
    27652833            break;
    27662834        case 0x7e: /* movd ea, mm */
    2767             gen_op_movl_T0_mm_mmx(offsetof(CPUX86State,fpregs[reg].mmx));
    2768             gen_ldst_modrm(s, modrm, OT_LONG, OR_TMP0, 1);
     2835#ifdef TARGET_X86_64
     2836            if (s->dflag == 2) {
     2837                gen_op_movq_T0_mm_mmx(offsetof(CPUX86State,fpregs[reg].mmx));
     2838                gen_ldst_modrm(s, modrm, OT_QUAD, OR_TMP0, 1);
     2839            } else
     2840#endif
     2841            {
     2842                gen_op_movl_T0_mm_mmx(offsetof(CPUX86State,fpregs[reg].mmx));
     2843                gen_ldst_modrm(s, modrm, OT_LONG, OR_TMP0, 1);
     2844            }
    27692845            break;
    27702846        case 0x17e: /* movd ea, xmm */
    2771             gen_op_movl_T0_mm_xmm(offsetof(CPUX86State,xmm_regs[reg]));
    2772             gen_ldst_modrm(s, modrm, OT_LONG, OR_TMP0, 1);
     2847#ifdef TARGET_X86_64
     2848            if (s->dflag == 2) {
     2849                gen_op_movq_T0_mm_xmm(offsetof(CPUX86State,xmm_regs[reg]));
     2850                gen_ldst_modrm(s, modrm, OT_QUAD, OR_TMP0, 1);
     2851            } else
     2852#endif
     2853            {
     2854                gen_op_movl_T0_mm_xmm(offsetof(CPUX86State,xmm_regs[reg]));
     2855                gen_ldst_modrm(s, modrm, OT_LONG, OR_TMP0, 1);
     2856            }
    27732857            break;
    27742858        case 0x27e: /* movq xmm, ea */
     
    30123096        case 0x2d6: /* movq2dq */
    30133097            gen_op_enter_mmx();
    3014             rm = (modrm & 7) | REX_B(s);
    3015             gen_op_movq(offsetof(CPUX86State,xmm_regs[rm].XMM_Q(0)),
    3016                         offsetof(CPUX86State,fpregs[reg & 7].mmx));
    3017             gen_op_movq_env_0(offsetof(CPUX86State,xmm_regs[rm].XMM_Q(1)));
     3098            rm = (modrm & 7);
     3099            gen_op_movq(offsetof(CPUX86State,xmm_regs[reg].XMM_Q(0)),
     3100                        offsetof(CPUX86State,fpregs[rm].mmx));
     3101            gen_op_movq_env_0(offsetof(CPUX86State,xmm_regs[reg].XMM_Q(1)));
    30183102            break;
    30193103        case 0x3d6: /* movdq2q */
    30203104            gen_op_enter_mmx();
    3021             rm = (modrm & 7);
    3022             gen_op_movq(offsetof(CPUX86State,fpregs[rm].mmx),
    3023                         offsetof(CPUX86State,xmm_regs[reg].XMM_Q(0)));
     3105            rm = (modrm & 7) | REX_B(s);
     3106            gen_op_movq(offsetof(CPUX86State,fpregs[reg & 7].mmx),
     3107                        offsetof(CPUX86State,xmm_regs[rm].XMM_Q(0)));
    30243108            break;
    30253109        case 0xd7: /* pmovmskb */
     
    30723156                gen_lea_modrm(s, modrm, &reg_addr, &offset_addr);
    30733157                op2_offset = offsetof(CPUX86State,xmm_t0);
    3074                 if (b1 >= 2 && ((b >= 0x50 && b <= 0x5f) ||
     3158                if (b1 >= 2 && ((b >= 0x50 && b <= 0x5f && b != 0x5b) ||
    30753159                                b == 0xc2)) {
    30763160                    /* specific case for SSE single instructions */
     
    43884472            case 0x0a: /* fsts */
    43894473            case 0x0b: /* fstps */
    4390             case 0x18: /* fildl */
    4391             case 0x1a: /* fistl */
    4392             case 0x1b: /* fistpl */
    4393             case 0x28: /* fldl */
    4394             case 0x2a: /* fstl */
    4395             case 0x2b: /* fstpl */
    4396             case 0x38: /* filds */
    4397             case 0x3a: /* fists */
    4398             case 0x3b: /* fistps */
    4399                
     4474            case 0x18 ... 0x1b: /* fildl, fisttpl, fistl, fistpl */
     4475            case 0x28 ... 0x2b: /* fldl, fisttpll, fstl, fstpl */
     4476            case 0x38 ... 0x3b: /* filds, fisttps, fists, fistps */
    44004477                switch(op & 7) {
    44014478                case 0:
     
    44154492                        break;
    44164493                    }
     4494                    break;
     4495                case 1:
     4496                    switch(op >> 4) {
     4497                    case 1:
     4498                        gen_op_fisttl_ST0_A0();
     4499                        break;
     4500                    case 2:
     4501                        gen_op_fisttll_ST0_A0();
     4502                        break;
     4503                    case 3:
     4504                    default:
     4505                        gen_op_fistt_ST0_A0();
     4506                    }
     4507                    gen_op_fpop();
    44174508                    break;
    44184509                default:
     
    53675458        if (s->vm86 && s->iopl != 3 && !s->vme) {
    53685459            gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base);
    5369         }
    5370         else
     5460        } else
    53715461#endif
    53725462            gen_interrupt(s, EXCP03_INT3, pc_start - s->cs_base, s->pc - s->cs_base);
     
    53935483        break;
    53945484    case 0xf1: /* icebp (undocumented, exits to external debugger) */
     5485#if 1
    53955486        gen_debug(s, pc_start - s->cs_base);
     5487#else
     5488        /* start debug */
     5489        tb_flush(cpu_single_env);
     5490        cpu_set_log(CPU_LOG_INT | CPU_LOG_TB_IN_ASM);
     5491#endif
    53965492        break;
    53975493    case 0xfa: /* cli */
     
    54065502                gen_op_cli();
    54075503#ifdef VBOX
    5408             } else
    5409             if (s->iopl != 3 && s->vme) {
     5504            } else if (s->iopl != 3 && s->vme) {
    54105505                gen_op_cli_vme();
    54115506#endif
     
    54355530                goto gen_sti;
    54365531#ifdef VBOX
    5437             } else
    5438             if (s->iopl != 3 && s->vme) {
     5532            } else if (s->iopl != 3 && s->vme) {
    54395533                gen_op_sti_vme();
    54405534                /* give a chance to handle pending irqs */
     
    57805874                if (mod == 3) {
    57815875#ifdef TARGET_X86_64
    5782                     if (CODE64(s) && (modrm & 7) == 0) {
     5876                    if (CODE64(s) && rm == 0) {
    57835877                        /* swapgs */
    57845878                        gen_op_movtl_T0_env(offsetof(CPUX86State,segs[R_GS].base));
     
    58985992            /* nothing more to do */
    58995993            break;
    5900         default:
    5901             goto illegal_op;
    5902         }
     5994        default: /* nop (multi byte) */
     5995            gen_nop_modrm(s, modrm);
     5996            break;
     5997        }
     5998        break;
     5999    case 0x119 ... 0x11f: /* nop (multi byte) */
     6000        modrm = ldub_code(s->pc++);
     6001        gen_nop_modrm(s, modrm);
    59036002        break;
    59046003    case 0x120: /* mov reg, crN */
     
    60636162        gen_lea_modrm(s, modrm, &reg_addr, &offset_addr);
    60646163        /* ignore for now */
     6164        break;
     6165    case 0x1aa: /* rsm */
     6166        if (!(s->flags & HF_SMM_MASK))
     6167            goto illegal_op;
     6168        if (s->cc_op != CC_OP_DYNAMIC) {
     6169            gen_op_set_cc_op(s->cc_op);
     6170            s->cc_op = CC_OP_DYNAMIC;
     6171        }
     6172        gen_jmp_im(s->pc - s->cs_base);
     6173        gen_op_rsm();
     6174        gen_eob(s);
    60656175        break;
    60666176    case 0x110 ... 0x117:
     
    65716681            break;
    65726682        }
    6573 #endif
     6683#endif /* VBOX */
    65746684
    65756685        /* if single step mode, we generate only one instruction and
  • trunk/src/recompiler/translate-all.c

    r1 r2422  
    3131#include "disas.h"
    3232
     33extern int dyngen_code(uint8_t *gen_code_buf,
     34                       uint16_t *label_offsets, uint16_t *jmp_offsets,
     35                       const uint16_t *opc_buf, const uint32_t *opparam_buf, const long *gen_labels);
     36
    3337enum {
    3438#define DEF(s, n, copy_size) INDEX_op_ ## s,
     
    3842};
    3943
    40 #include "dyngen.h"
    41 #include "op.h"
    42 
    4344uint16_t gen_opc_buf[OPC_BUF_SIZE];
    4445uint32_t gen_opparam_buf[OPPARAM_BUF_SIZE];
     
    5253#elif defined(TARGET_SPARC)
    5354target_ulong gen_opc_npc[OPC_BUF_SIZE];
     55target_ulong gen_opc_jump_pc[2];
     56#elif defined(TARGET_MIPS)
     57uint32_t gen_opc_hflags[OPC_BUF_SIZE];
    5458#endif
    5559
     
    157161            return -1;
    158162        }
    159 #else
     163#else /* !VBOX */
    160164        if (gen_intermediate_code(env, tb) < 0)
    161165            return -1;
    162 #endif
     166#endif /* !VBOX */
     167
    163168        /* generate machine code */
    164169        tb->tb_next_offset[0] = 0xffff;
     
    179184#endif
    180185                                    gen_opc_buf, gen_opparam_buf, gen_labels);
    181 
    182186#ifdef VBOX
    183187        RAWEx_ProfileStop(env, STATS_QEMU_COMPILATION);
     
    258262    env->regs[15] = gen_opc_pc[j];
    259263#elif defined(TARGET_SPARC)
    260     /* XXX: restore npc too */
    261     env->pc = gen_opc_pc[j];
    262     env->npc = gen_opc_npc[j];
     264    {
     265        target_ulong npc;
     266        env->pc = gen_opc_pc[j];
     267        npc = gen_opc_npc[j];
     268        if (npc == 1) {
     269            /* dynamic NPC: already stored */
     270        } else if (npc == 2) {
     271            target_ulong t2 = (target_ulong)puc;
     272            /* jump PC: use T2 and the jump targets of the translation */
     273            if (t2)
     274                env->npc = gen_opc_jump_pc[0];
     275            else
     276                env->npc = gen_opc_jump_pc[1];
     277        } else {
     278            env->npc = npc;
     279        }
     280    }
    263281#elif defined(TARGET_PPC)
    264282    {
     
    299317        env->access_type = type;
    300318    }
     319#elif defined(TARGET_M68K)
     320    env->pc = gen_opc_pc[j];
     321#elif defined(TARGET_MIPS)
     322    env->PC = gen_opc_pc[j];
     323    env->hflags &= ~MIPS_HFLAG_BMASK;
     324    env->hflags |= gen_opc_hflags[j];
    301325#endif
    302326    return 0;
  • trunk/src/recompiler/vl.h

    r1 r2422  
    3131#include <string.h>
    3232#include <inttypes.h>
     33#ifndef VBOX
    3334#include <limits.h>
    3435#include <time.h>
     
    3839#include <fcntl.h>
    3940#include <sys/stat.h>
    40 #ifndef VBOX
    4141#include "audio/audio.h"
    42 #endif
     42#endif /* !VBOX */
    4343
    4444#ifndef O_LARGEFILE
     
    4949#endif
    5050
     51#ifndef ENOMEDIUM
     52#define ENOMEDIUM ENODEV
     53#endif
     54
    5155#ifdef _WIN32
     56#ifndef VBOX
     57#include <windows.h>
     58#define fsync _commit
    5259#define lseek _lseeki64
    5360#define ENOTSUP 4096
    54 /* XXX: find 64 bit version */
    55 #define ftruncate chsize
     61extern int qemu_ftruncate64(int, int64_t);
     62#define ftruncate qemu_ftruncate64
     63
    5664
    5765static inline char *realpath(const char *path, char *resolved_path)
     
    6068    return resolved_path;
    6169}
     70
     71#define PRId64 "I64d"
     72#define PRIx64 "I64x"
     73#define PRIu64 "I64u"
     74#define PRIo64 "I64o"
     75#endif /* !VBOX */
    6276#endif
    6377
     
    7387#else
    7488
     89#ifndef VBOX
     90#include "audio/audio.h"
     91#endif /* !VBOX */
    7592#include "cpu.h"
    7693
     
    8097# include <VBox/types.h>
    8198# include "REMInternal.h"
    82 # undef MIN
    83 # undef MAX
    8499#endif /* VBOX */
    85100
     
    91106#endif
    92107
    93 /* vl.c */
    94 uint64_t muldiv64(uint64_t a, uint32_t b, uint32_t c);
    95 
    96 void hw_error(const char *fmt, ...);
    97 
    98 int get_image_size(const char *filename);
    99 int load_image(const char *filename, uint8_t *addr);
    100 extern const char *bios_dir;
    101 
     108#ifndef MIN
     109#define MIN(a, b) (((a) < (b)) ? (a) : (b))
     110#endif
     111#ifndef MAX
     112#define MAX(a, b) (((a) > (b)) ? (a) : (b))
     113#endif
     114
     115/* cutils.c */
    102116void pstrcpy(char *buf, int buf_size, const char *str);
    103117char *pstrcat(char *buf, int buf_size, const char *s);
    104118int strstart(const char *str, const char *val, const char **ptr);
     119int stristart(const char *str, const char *val, const char **ptr);
     120
     121/* vl.c */
     122uint64_t muldiv64(uint64_t a, uint32_t b, uint32_t c);
     123
     124void hw_error(const char *fmt, ...);
     125
     126extern const char *bios_dir;
    105127
    106128extern int vm_running;
    107129
     130typedef struct vm_change_state_entry VMChangeStateEntry;
     131typedef void VMChangeStateHandler(void *opaque, int running);
    108132typedef void VMStopHandler(void *opaque, int reason);
     133
     134VMChangeStateEntry *qemu_add_vm_change_state_handler(VMChangeStateHandler *cb,
     135                                                     void *opaque);
     136void qemu_del_vm_change_state_handler(VMChangeStateEntry *e);
    109137
    110138int qemu_add_vm_stop_handler(VMStopHandler *cb, void *opaque);
     
    119147void qemu_system_reset_request(void);
    120148void qemu_system_shutdown_request(void);
     149void qemu_system_powerdown_request(void);
     150#if !defined(TARGET_SPARC)
     151// Please implement a power failure function to signal the OS
     152#define qemu_system_powerdown() do{}while(0)
     153#else
     154void qemu_system_powerdown(void);
     155#endif
    121156
    122157void main_loop_wait(int timeout);
    123158
    124 extern int audio_enabled;
    125 extern int sb16_enabled;
    126 extern int adlib_enabled;
    127 extern int gus_enabled;
    128159extern int ram_size;
    129160extern int bios_size;
    130161extern int rtc_utc;
    131 #ifndef VBOX
    132162extern int cirrus_vga_enabled;
    133 #endif
    134163extern int graphic_width;
    135164extern int graphic_height;
    136165extern int graphic_depth;
    137166extern const char *keyboard_layout;
     167extern int kqemu_allowed;
     168extern int win2k_install_hack;
     169extern int usb_enabled;
     170extern int smp_cpus;
     171extern int no_quit;
     172extern int semihosting_enabled;
     173extern int autostart;
     174
     175#ifndef VBOX
     176#define MAX_OPTION_ROMS 16
     177extern const char *option_rom[MAX_OPTION_ROMS];
     178extern int nb_option_roms;
    138179
    139180/* XXX: make it dynamic */
    140 #if defined (TARGET_PPC)
    141 #define BIOS_SIZE (512 * 1024)
     181#if defined (TARGET_PPC) || defined (TARGET_SPARC64)
     182#define BIOS_SIZE ((512 + 32) * 1024)
     183#elif defined(TARGET_MIPS)
     184#define BIOS_SIZE (4 * 1024 * 1024)
    142185#else
    143186#define BIOS_SIZE ((256 + 64) * 1024)
     
    153196typedef void QEMUPutMouseEvent(void *opaque, int dx, int dy, int dz, int buttons_state);
    154197
     198typedef struct QEMUPutMouseEntry {
     199    QEMUPutMouseEvent *qemu_put_mouse_event;
     200    void *qemu_put_mouse_event_opaque;
     201    int qemu_put_mouse_event_absolute;
     202    char *qemu_put_mouse_event_name;
     203
     204    /* used internally by qemu for handling mice */
     205    struct QEMUPutMouseEntry *next;
     206} QEMUPutMouseEntry;
     207
    155208void qemu_add_kbd_event_handler(QEMUPutKBDEvent *func, void *opaque);
    156 void qemu_add_mouse_event_handler(QEMUPutMouseEvent *func, void *opaque);
     209QEMUPutMouseEntry *qemu_add_mouse_event_handler(QEMUPutMouseEvent *func,
     210                                                void *opaque, int absolute,
     211                                                const char *name);
     212void qemu_remove_mouse_event_handler(QEMUPutMouseEntry *entry);
    157213
    158214void kbd_put_keycode(int keycode);
    159215void kbd_mouse_event(int dx, int dy, int dz, int buttons_state);
     216int kbd_mouse_is_absolute(void);
     217
     218void do_info_mice(void);
     219void do_mouse_set(int index);
    160220
    161221/* keysym is a unicode code except for special keys (see QEMU_KEY_xxx
     
    188248typedef void IOReadHandler(void *opaque, const uint8_t *buf, int size);
    189249typedef int IOCanRWHandler(void *opaque);
    190 
    191 int qemu_add_fd_read_handler(int fd, IOCanRWHandler *fd_can_read,
    192                              IOReadHandler *fd_read, void *opaque);
    193 void qemu_del_fd_read_handler(int fd);
     250typedef void IOHandler(void *opaque);
     251
     252int qemu_set_fd_handler2(int fd,
     253                         IOCanRWHandler *fd_read_poll,
     254                         IOHandler *fd_read,
     255                         IOHandler *fd_write,
     256                         void *opaque);
     257int qemu_set_fd_handler(int fd,
     258                        IOHandler *fd_read,
     259                        IOHandler *fd_write,
     260                        void *opaque);
     261
     262/* Polling handling */
     263
     264/* return TRUE if no sleep should be done afterwards */
     265typedef int PollingFunc(void *opaque);
     266
     267int qemu_add_polling_cb(PollingFunc *func, void *opaque);
     268void qemu_del_polling_cb(PollingFunc *func, void *opaque);
     269
     270#ifdef _WIN32
     271/* Wait objects handling */
     272typedef void WaitObjectFunc(void *opaque);
     273
     274int qemu_add_wait_object(HANDLE handle, WaitObjectFunc *func, void *opaque);
     275void qemu_del_wait_object(HANDLE handle, WaitObjectFunc *func, void *opaque);
     276#endif
     277
     278typedef struct QEMUBH QEMUBH;
    194279
    195280/* character device */
     
    197282#define CHR_EVENT_BREAK 0 /* serial break char */
    198283#define CHR_EVENT_FOCUS 1 /* focus to this terminal (modal input needed) */
     284#define CHR_EVENT_RESET 2 /* new connection established */
     285
     286
     287#define CHR_IOCTL_SERIAL_SET_PARAMS   1
     288typedef struct {
     289    int speed;
     290    int parity;
     291    int data_bits;
     292    int stop_bits;
     293} QEMUSerialSetParams;
     294
     295#define CHR_IOCTL_SERIAL_SET_BREAK    2
     296
     297#define CHR_IOCTL_PP_READ_DATA        3
     298#define CHR_IOCTL_PP_WRITE_DATA       4
     299#define CHR_IOCTL_PP_READ_CONTROL     5
     300#define CHR_IOCTL_PP_WRITE_CONTROL    6
     301#define CHR_IOCTL_PP_READ_STATUS      7
    199302
    200303typedef void IOEventHandler(void *opaque, int event);
     
    202305typedef struct CharDriverState {
    203306    int (*chr_write)(struct CharDriverState *s, const uint8_t *buf, int len);
    204     void (*chr_add_read_handler)(struct CharDriverState *s,
    205                                  IOCanRWHandler *fd_can_read,
    206                                  IOReadHandler *fd_read, void *opaque);
     307    void (*chr_update_read_handler)(struct CharDriverState *s);
     308    int (*chr_ioctl)(struct CharDriverState *s, int cmd, void *arg);
    207309    IOEventHandler *chr_event;
     310    IOCanRWHandler *chr_can_read;
     311    IOReadHandler *chr_read;
     312    void *handler_opaque;
    208313    void (*chr_send_event)(struct CharDriverState *chr, int event);
     314    void (*chr_close)(struct CharDriverState *chr);
    209315    void *opaque;
     316    QEMUBH *bh;
    210317} CharDriverState;
    211318
     319CharDriverState *qemu_chr_open(const char *filename);
    212320void qemu_chr_printf(CharDriverState *s, const char *fmt, ...);
    213321int qemu_chr_write(CharDriverState *s, const uint8_t *buf, int len);
    214322void qemu_chr_send_event(CharDriverState *s, int event);
    215 void qemu_chr_add_read_handler(CharDriverState *s,
    216                                IOCanRWHandler *fd_can_read,
    217                                IOReadHandler *fd_read, void *opaque);
    218 void qemu_chr_add_event_handler(CharDriverState *s, IOEventHandler *chr_event);
    219                                
     323void qemu_chr_add_handlers(CharDriverState *s,
     324                           IOCanRWHandler *fd_can_read,
     325                           IOReadHandler *fd_read,
     326                           IOEventHandler *fd_event,
     327                           void *opaque);
     328int qemu_chr_ioctl(CharDriverState *s, int cmd, void *arg);
     329void qemu_chr_reset(CharDriverState *s);
     330int qemu_chr_can_read(CharDriverState *s);
     331void qemu_chr_read(CharDriverState *s, uint8_t *buf, int len);
     332
    220333/* consoles */
    221334
     
    223336typedef struct TextConsole TextConsole;
    224337
    225 extern TextConsole *vga_console;
    226 
    227 TextConsole *graphic_console_init(DisplayState *ds);
    228 int is_active_console(TextConsole *s);
     338typedef void (*vga_hw_update_ptr)(void *);
     339typedef void (*vga_hw_invalidate_ptr)(void *);
     340typedef void (*vga_hw_screen_dump_ptr)(void *, const char *);
     341
     342TextConsole *graphic_console_init(DisplayState *ds, vga_hw_update_ptr update,
     343                                  vga_hw_invalidate_ptr invalidate,
     344                                  vga_hw_screen_dump_ptr screen_dump,
     345                                  void *opaque);
     346void vga_hw_update(void);
     347void vga_hw_invalidate(void);
     348void vga_hw_screen_dump(const char *filename);
     349
     350int is_graphic_console(void);
    229351CharDriverState *text_console_init(DisplayState *ds);
    230352void console_select(unsigned int index);
    231353
    232 #ifdef VBOX
    233 void console_init(void);
    234 #endif
    235 
    236354/* serial ports */
    237355
     
    246364extern CharDriverState *parallel_hds[MAX_PARALLEL_PORTS];
    247365
    248 /* network redirectors support */
     366/* VLANs support */
     367
     368typedef struct VLANClientState VLANClientState;
     369
     370struct VLANClientState {
     371    IOReadHandler *fd_read;
     372    /* Packets may still be sent if this returns zero.  It's used to
     373       rate-limit the slirp code.  */
     374    IOCanRWHandler *fd_can_read;
     375    void *opaque;
     376    struct VLANClientState *next;
     377    struct VLANState *vlan;
     378    char info_str[256];
     379};
     380
     381typedef struct VLANState {
     382    int id;
     383    VLANClientState *first_client;
     384    struct VLANState *next;
     385} VLANState;
     386
     387VLANState *qemu_find_vlan(int id);
     388VLANClientState *qemu_new_vlan_client(VLANState *vlan,
     389                                      IOReadHandler *fd_read,
     390                                      IOCanRWHandler *fd_can_read,
     391                                      void *opaque);
     392int qemu_can_send_packet(VLANClientState *vc);
     393void qemu_send_packet(VLANClientState *vc, const uint8_t *buf, int size);
     394void qemu_handler_true(void *opaque);
     395
     396void do_info_network(void);
     397
     398/* TAP win32 */
     399int tap_win32_init(VLANState *vlan, const char *ifname);
     400
     401/* NIC info */
    249402
    250403#define MAX_NICS 8
    251404
    252 typedef struct NetDriverState {
    253     int index; /* index number in QEMU */
     405typedef struct NICInfo {
    254406    uint8_t macaddr[6];
    255     char ifname[16];
    256     void (*send_packet)(struct NetDriverState *nd,
    257                         const uint8_t *buf, int size);
    258     void (*add_read_packet)(struct NetDriverState *nd,
    259                             IOCanRWHandler *fd_can_read,
    260                             IOReadHandler *fd_read, void *opaque);
    261     /* tun specific data */
    262     int fd;
    263     /* slirp specific data */
    264 } NetDriverState;
     407    const char *model;
     408    VLANState *vlan;
     409} NICInfo;
    265410
    266411extern int nb_nics;
    267 extern NetDriverState nd_table[MAX_NICS];
    268 
    269 void qemu_send_packet(NetDriverState *nd, const uint8_t *buf, int size);
    270 void qemu_add_read_packet(NetDriverState *nd, IOCanRWHandler *fd_can_read,
    271                           IOReadHandler *fd_read, void *opaque);
     412extern NICInfo nd_table[MAX_NICS];
    272413
    273414/* timers */
    274 
    275 #if defined(VBOX)
    276 
    277 #include <VBox/tm.h>
    278 
    279 /* VBox wrappers */
    280 #define QEMUTimerCB                             FNTMTIMERQEMU
    281 typedef struct TMTIMER QEMUTimer;
    282 #define rt_clock                                THIS_SHALL_NOT_BE_USED//TMCLOCK_REAL
    283 #define vm_clock                                THIS_SHALL_NOT_BE_USED//TMCLOCK_VIRTUAL
    284 #define ticks_per_sec                           THIS_SHALL_NOT_BE_USED//TMCpuTicksPerSecond((PVM)cpu_single_env->pVM)
    285 #define qemu_get_clock(enmClock)                THIS_SHALL_NOT_BE_USED//TMR3Clock((PVM)cpu_single_env->pVM, enmClock)
    286 #define qemu_new_timer(clock, callback, user)   THIS_SHALL_NOT_BE_USED//(QEMUTimer *)TMR3TimerCreateExternal((PVM)cpu_single_env->pVM, clock, callback, user, __FUNCTION__ )
    287 #define qemu_free_timer(timer)                  THIS_SHALL_NOT_BE_USED//TMTimerDestroy(timer)
    288 #define qemu_del_timer(timer)                   THIS_SHALL_NOT_BE_USED//TMTimerStop(timer)
    289 #define qemu_mod_timer(timer, expire)           THIS_SHALL_NOT_BE_USED//TMTimerSet(timer, (uint64_t)expire)
    290 #define qemu_timer_pending(timer)               THIS_SHALL_NOT_BE_USED//TMTimerIsActive(timer)
    291 #define cpu_disable_ticks()                     THIS_SHALL_NOT_BE_USED//TMCpuTickPause((PVM)cpu_single_env->pVM)
    292 #define cpu_enable_ticks()                      THIS_SHALL_NOT_BE_USED//TMCpuTickResume((PVM)cpu_single_env->pVM)
    293 #define cpu_calibrate_ticks()                   THIS_SHALL_NOT_BE_USED//do {} while (0)
    294 #define init_timers()                           THIS_SHALL_NOT_BE_USED//do {} while (0)
    295 #define quit_timers()                           THIS_SHALL_NOT_BE_USED//do {} while (0)
    296 
    297 #else /* !VBOX */
    298415
    299416typedef struct QEMUClock QEMUClock;
     
    323440extern int pit_min_timer_count;
    324441
     442int64_t cpu_get_ticks(void);
    325443void cpu_enable_ticks(void);
    326444void cpu_disable_ticks(void);
    327 #endif /* !VBOX */
    328445
    329446/* VM Load/Save */
    330447
    331 #if defined(VBOX)
    332 
    333 #include <VBox/ssm.h>
    334 #include <VBox/err.h>
    335 
    336 typedef struct SSMHANDLE QEMUFile;
    337 
    338 #define qemu_put_buffer(f, pv, cb)                  THIS_SHALL_NOT_BE_USED//SSMR3PutMem((f), (pv), (cb))
    339 #define qemu_put_byte(f, u8)                        THIS_SHALL_NOT_BE_USED//SSMR3PutU8((f), (uint8_t)(u8))
    340 #define qemu_put_8s(f, pu8)                         THIS_SHALL_NOT_BE_USED//SSMR3PutU8((f), *(pu8))
    341 #define qemu_put_be16s(f, pu16)                     THIS_SHALL_NOT_BE_USED//SSMR3PutU32((f), *(pu16))
    342 #define qemu_put_be32s(f, pu32)                     THIS_SHALL_NOT_BE_USED//SSMR3PutU32((f), *(pu32))
    343 #define qemu_put_be64s(f, pu64)                     THIS_SHALL_NOT_BE_USED//SSMR3PutU64((f), *(pu64))
    344 #define qemu_put_be16(f, u16)                       THIS_SHALL_NOT_BE_USED//SSMR3PutU16((f), (uint16_t)(u16))
    345 #define qemu_put_be32(f, u32)                       THIS_SHALL_NOT_BE_USED//SSMR3PutU32((f), (uint32_t)(u32))
    346 #define qemu_put_be64(f, u64)                       THIS_SHALL_NOT_BE_USED//SSMR3PutU64((f), (uint64_t)(u64))
    347 
    348 #define qemu_get_8s(f, pu8)                         THIS_SHALL_NOT_BE_USED//SSMR3GetU8((f), (pu8))
    349 #define qemu_get_be16s(f, pu16)                     THIS_SHALL_NOT_BE_USED//SSMR3GetU16((f), (pu16))
    350 #define qemu_get_be32s(f, pu32)                     THIS_SHALL_NOT_BE_USED//SSMR3GetU32((f), (pu32))
    351 #define qemu_get_be64s(f, pu64)                     THIS_SHALL_NOT_BE_USED//SSMR3GetU64((f), (pu64))
    352 
    353 #if 0
    354 static inline int qemu_get_buffer(QEMUFile *f, uint8_t *buf, int size)
    355 {
    356     int rc = SSMR3GetMem(f, buf, size);
    357     return VBOX_SUCCESS(rc) ? size : 0;
    358 }
    359 
    360 static inline int qemu_get_byte(QEMUFile *f)
    361 {
    362     uint8_t u8;
    363     int rc = SSMR3GetU8(f, &u8);
    364     return VBOX_SUCCESS(rc) ? (int)u8 : -1;
    365 }
    366 
    367 static inline unsigned int qemu_get_be16(QEMUFile *f)
    368 {
    369     uint16_t u16;
    370     int rc = SSMR3GetU16(f, &u16);
    371     return VBOX_SUCCESS(rc) ? u16 : ~0;
    372 }
    373 
    374 static inline unsigned int qemu_get_be32(QEMUFile *f)
    375 {
    376     uint32_t u32;
    377     int rc = SSMR3GetU32(f, &u32);
    378     return VBOX_SUCCESS(rc) ? u32 : ~0;
    379 }
    380 
    381 static inline uint64_t qemu_get_be64(QEMUFile *f)
    382 {
    383     uint64_t u64;
    384     int rc = SSMR3GetU64(f, &u64);
    385     return VBOX_SUCCESS(rc) ? u64 : ~0;
    386 }
    387 
    388 #define qemu_put_timer(f, ts)   TMR3TimerSave((ts), (f))
    389 #define qemu_get_timer(f, ts)   TMR3TimerLoad((ts), (f))
    390 
    391 typedef void SaveStateHandler(QEMUFile *f, void *opaque);
    392 typedef int LoadStateHandler(QEMUFile *f, void *opaque, int version_id);
    393 
    394 int register_savevm(const char *idstr,
    395                     int instance_id,
    396                     int version_id,
    397                     SaveStateHandler *save_state,
    398                     LoadStateHandler *load_state,
    399                     void *opaque);
    400 #endif /* not used */
    401 
    402 #else /* !VBOX */
    403 
    404 typedef FILE QEMUFile;
    405 
     448typedef struct QEMUFile QEMUFile;
     449
     450QEMUFile *qemu_fopen(const char *filename, const char *mode);
     451void qemu_fflush(QEMUFile *f);
     452void qemu_fclose(QEMUFile *f);
    406453void qemu_put_buffer(QEMUFile *f, const uint8_t *buf, int size);
    407454void qemu_put_byte(QEMUFile *f, int v);
     
    473520typedef int LoadStateHandler(QEMUFile *f, void *opaque, int version_id);
    474521
    475 int qemu_loadvm(const char *filename);
    476 int qemu_savevm(const char *filename);
    477522int register_savevm(const char *idstr,
    478523                    int instance_id,
     
    483528void qemu_get_timer(QEMUFile *f, QEMUTimer *ts);
    484529void qemu_put_timer(QEMUFile *f, QEMUTimer *ts);
    485 #endif /* !VBOX */
     530
     531void cpu_save(QEMUFile *f, void *opaque);
     532int cpu_load(QEMUFile *f, void *opaque, int version_id);
     533
     534void do_savevm(const char *name);
     535void do_loadvm(const char *name);
     536void do_delvm(const char *name);
     537void do_info_snapshots(void);
     538
     539/* bottom halves */
     540typedef void QEMUBHFunc(void *opaque);
     541
     542QEMUBH *qemu_bh_new(QEMUBHFunc *cb, void *opaque);
     543void qemu_bh_schedule(QEMUBH *bh);
     544void qemu_bh_cancel(QEMUBH *bh);
     545void qemu_bh_delete(QEMUBH *bh);
     546int qemu_bh_poll(void);
    486547
    487548/* block.c */
     
    489550typedef struct BlockDriver BlockDriver;
    490551
    491 #ifdef VBOX
    492 extern BlockDriver bdrv_vbox;
    493 /* @@@AH remove later */
    494 extern BlockDriver bdrv_qcow;
    495552extern BlockDriver bdrv_raw;
    496 #else /* !VBOX */
    497 extern BlockDriver bdrv_raw;
     553extern BlockDriver bdrv_host_device;
    498554extern BlockDriver bdrv_cow;
    499555extern BlockDriver bdrv_qcow;
     
    501557extern BlockDriver bdrv_cloop;
    502558extern BlockDriver bdrv_dmg;
    503 #endif /* !VBOX */
     559extern BlockDriver bdrv_bochs;
     560extern BlockDriver bdrv_vpc;
     561extern BlockDriver bdrv_vvfat;
     562extern BlockDriver bdrv_qcow2;
     563
     564typedef struct BlockDriverInfo {
     565    /* in bytes, 0 if irrelevant */
     566    int cluster_size;
     567    /* offset at which the VM state can be saved (0 if not possible) */
     568    int64_t vm_state_offset;
     569} BlockDriverInfo;
     570
     571typedef struct QEMUSnapshotInfo {
     572    char id_str[128]; /* unique snapshot id */
     573    /* the following fields are informative. They are not needed for
     574       the consistency of the snapshot */
     575    char name[256]; /* user choosen name */
     576    uint32_t vm_state_size; /* VM state info size */
     577    uint32_t date_sec; /* UTC date of the snapshot */
     578    uint32_t date_nsec;
     579    uint64_t vm_clock_nsec; /* VM clock relative to boot */
     580} QEMUSnapshotInfo;
     581
     582#define BDRV_O_RDONLY      0x0000
     583#define BDRV_O_RDWR        0x0002
     584#define BDRV_O_ACCESS      0x0003
     585#define BDRV_O_CREAT       0x0004 /* create an empty file */
     586#define BDRV_O_SNAPSHOT    0x0008 /* open the file read only and save writes in a snapshot */
     587#define BDRV_O_FILE        0x0010 /* open as a raw file (do not try to
     588                                     use a disk image format on top of
     589                                     it (default for
     590                                     bdrv_file_open()) */
    504591
    505592void bdrv_init(void);
     
    510597BlockDriverState *bdrv_new(const char *device_name);
    511598void bdrv_delete(BlockDriverState *bs);
    512 int bdrv_open(BlockDriverState *bs, const char *filename, int snapshot);
    513 int bdrv_open2(BlockDriverState *bs, const char *filename, int snapshot,
     599int bdrv_file_open(BlockDriverState **pbs, const char *filename, int flags);
     600int bdrv_open(BlockDriverState *bs, const char *filename, int flags);
     601int bdrv_open2(BlockDriverState *bs, const char *filename, int flags,
    514602               BlockDriver *drv);
    515603void bdrv_close(BlockDriverState *bs);
     
    518606int bdrv_write(BlockDriverState *bs, int64_t sector_num,
    519607               const uint8_t *buf, int nb_sectors);
     608int bdrv_pread(BlockDriverState *bs, int64_t offset,
     609               void *buf, int count);
     610int bdrv_pwrite(BlockDriverState *bs, int64_t offset,
     611                const void *buf, int count);
     612int bdrv_truncate(BlockDriverState *bs, int64_t offset);
     613int64_t bdrv_getlength(BlockDriverState *bs);
    520614void bdrv_get_geometry(BlockDriverState *bs, int64_t *nb_sectors_ptr);
    521615int bdrv_commit(BlockDriverState *bs);
    522616void bdrv_set_boot_sector(BlockDriverState *bs, const uint8_t *data, int size);
     617/* async block I/O */
     618typedef struct BlockDriverAIOCB BlockDriverAIOCB;
     619typedef void BlockDriverCompletionFunc(void *opaque, int ret);
     620
     621BlockDriverAIOCB *bdrv_aio_read(BlockDriverState *bs, int64_t sector_num,
     622                                uint8_t *buf, int nb_sectors,
     623                                BlockDriverCompletionFunc *cb, void *opaque);
     624BlockDriverAIOCB *bdrv_aio_write(BlockDriverState *bs, int64_t sector_num,
     625                                 const uint8_t *buf, int nb_sectors,
     626                                 BlockDriverCompletionFunc *cb, void *opaque);
     627void bdrv_aio_cancel(BlockDriverAIOCB *acb);
     628
     629void qemu_aio_init(void);
     630void qemu_aio_poll(void);
     631void qemu_aio_flush(void);
     632void qemu_aio_wait_start(void);
     633void qemu_aio_wait(void);
     634void qemu_aio_wait_end(void);
     635
     636/* Ensure contents are flushed to disk.  */
     637void bdrv_flush(BlockDriverState *bs);
    523638
    524639#define BDRV_TYPE_HD     0
    525640#define BDRV_TYPE_CDROM  1
    526641#define BDRV_TYPE_FLOPPY 2
    527 #define BIOS_ATA_TRANSLATION_AUTO 0
    528 #define BIOS_ATA_TRANSLATION_NONE 1
    529 #define BIOS_ATA_TRANSLATION_LBA  2
     642#define BIOS_ATA_TRANSLATION_AUTO   0
     643#define BIOS_ATA_TRANSLATION_NONE   1
     644#define BIOS_ATA_TRANSLATION_LBA    2
     645#define BIOS_ATA_TRANSLATION_LARGE  3
     646#define BIOS_ATA_TRANSLATION_RECHS  4
    530647
    531648void bdrv_set_geometry_hint(BlockDriverState *bs,
     
    540657int bdrv_is_read_only(BlockDriverState *bs);
    541658int bdrv_is_inserted(BlockDriverState *bs);
     659int bdrv_media_changed(BlockDriverState *bs);
    542660int bdrv_is_locked(BlockDriverState *bs);
    543661void bdrv_set_locked(BlockDriverState *bs, int locked);
     662void bdrv_eject(BlockDriverState *bs, int eject_flag);
    544663void bdrv_set_change_cb(BlockDriverState *bs,
    545664                        void (*change_cb)(void *opaque), void *opaque);
     
    553672                         void *opaque);
    554673const char *bdrv_get_device_name(BlockDriverState *bs);
    555 
    556 int qcow_get_cluster_size(BlockDriverState *bs);
    557 int qcow_compress_cluster(BlockDriverState *bs, int64_t sector_num,
    558                           const uint8_t *buf);
     674int bdrv_write_compressed(BlockDriverState *bs, int64_t sector_num,
     675                          const uint8_t *buf, int nb_sectors);
     676int bdrv_get_info(BlockDriverState *bs, BlockDriverInfo *bdi);
     677
     678void bdrv_get_backing_filename(BlockDriverState *bs,
     679                               char *filename, int filename_size);
     680int bdrv_snapshot_create(BlockDriverState *bs,
     681                         QEMUSnapshotInfo *sn_info);
     682int bdrv_snapshot_goto(BlockDriverState *bs,
     683                       const char *snapshot_id);
     684int bdrv_snapshot_delete(BlockDriverState *bs, const char *snapshot_id);
     685int bdrv_snapshot_list(BlockDriverState *bs,
     686                       QEMUSnapshotInfo **psn_info);
     687char *bdrv_snapshot_dump(char *buf, int buf_size, QEMUSnapshotInfo *sn);
     688
     689char *get_human_readable_size(char *buf, int buf_size, int64_t size);
     690int path_is_absolute(const char *path);
     691void path_combine(char *dest, int dest_size,
     692                  const char *base_path,
     693                  const char *filename);
    559694
    560695#ifndef QEMU_TOOL
     696
     697typedef void QEMUMachineInitFunc(int ram_size, int vga_ram_size,
     698                                 int boot_device,
     699             DisplayState *ds, const char **fd_filename, int snapshot,
     700             const char *kernel_filename, const char *kernel_cmdline,
     701             const char *initrd_filename);
     702
     703typedef struct QEMUMachine {
     704    const char *name;
     705    const char *desc;
     706    QEMUMachineInitFunc *init;
     707    struct QEMUMachine *next;
     708} QEMUMachine;
     709
     710int qemu_register_machine(QEMUMachine *m);
     711
     712typedef void SetIRQFunc(void *opaque, int irq_num, int level);
     713typedef void IRQRequestFunc(void *opaque, int level);
     714
    561715/* ISA bus */
    562 
    563 #if defined(VBOX)
    564 #define isa_mem_base    THIS_SHALL_NOT_BE_USED//0
    565 #else /* !VBOX */
    566716
    567717extern target_phys_addr_t isa_mem_base;
     
    575725                          IOPortWriteFunc *func, void *opaque);
    576726void isa_unassign_ioport(int start, int length);
    577 #endif /* !VBOX */
     727
     728void isa_mmio_init(target_phys_addr_t base, target_phys_addr_t size);
    578729
    579730/* PCI bus */
    580 
    581 #if defined(VBOX)
    582 typedef struct PCIBus PCIBus;
    583 typedef struct PCIDevice PCIDevice;
    584 typedef struct openpic_t openpic_t;
    585 #else /* !VBOX */
    586 extern int pci_enabled;
    587731
    588732extern target_phys_addr_t pci_mem_base;
     
    611755#define PCI_ROM_SLOT 6
    612756#define PCI_NUM_REGIONS 7
     757
     758#define PCI_DEVICES_MAX 64
     759
     760#define PCI_VENDOR_ID           0x00    /* 16 bits */
     761#define PCI_DEVICE_ID           0x02    /* 16 bits */
     762#define PCI_COMMAND             0x04    /* 16 bits */
     763#define  PCI_COMMAND_IO         0x1     /* Enable response in I/O space */
     764#define  PCI_COMMAND_MEMORY     0x2     /* Enable response in Memory space */
     765#define PCI_CLASS_DEVICE        0x0a    /* Device class */
     766#define PCI_INTERRUPT_LINE      0x3c    /* 8 bits */
     767#define PCI_INTERRUPT_PIN       0x3d    /* 8 bits */
     768#define PCI_MIN_GNT             0x3e    /* 8 bits */
     769#define PCI_MAX_LAT             0x3f    /* 8 bits */
     770
    613771struct PCIDevice {
    614772    /* PCI config space */
     
    624782    PCIConfigReadFunc *config_read;
    625783    PCIConfigWriteFunc *config_write;
     784    /* ??? This is a PC-specific hack, and should be removed.  */
    626785    int irq_index;
     786
     787    /* Current IRQ levels.  Used internally by the generic PCI code.  */
     788    int irq_state[4];
    627789};
    628790
     
    642804void pci_default_write_config(PCIDevice *d,
    643805                              uint32_t address, uint32_t val, int len);
    644 void generic_pci_save(QEMUFile* f, void *opaque);
    645 int generic_pci_load(QEMUFile* f, void *opaque, int version_id);
    646 
    647 extern struct PIIX3State *piix3_state;
    648 
    649 PCIBus *i440fx_init(void);
    650 void piix3_init(PCIBus *bus);
    651 void pci_bios_init(void);
     806void pci_device_save(PCIDevice *s, QEMUFile *f);
     807int pci_device_load(PCIDevice *s, QEMUFile *f);
     808
     809typedef void (*pci_set_irq_fn)(void *pic, int irq_num, int level);
     810typedef int (*pci_map_irq_fn)(PCIDevice *pci_dev, int irq_num);
     811PCIBus *pci_register_bus(pci_set_irq_fn set_irq, pci_map_irq_fn map_irq,
     812                         void *pic, int devfn_min, int nirq);
     813
     814void pci_nic_init(PCIBus *bus, NICInfo *nd, int devfn);
     815void pci_data_write(void *opaque, uint32_t addr, uint32_t val, int len);
     816uint32_t pci_data_read(void *opaque, uint32_t addr, int len);
     817int pci_bus_num(PCIBus *s);
     818void pci_for_each_device(int bus_num, void (*fn)(PCIDevice *d));
     819
    652820void pci_info(void);
    653 
    654 /* temporary: will be moved in platform specific file */
     821PCIBus *pci_bridge_init(PCIBus *bus, int devfn, uint32_t id,
     822                        pci_map_irq_fn map_irq, const char *name);
     823
     824/* prep_pci.c */
    655825PCIBus *pci_prep_init(void);
    656 struct openpic_t;
    657 void pci_pmac_set_openpic(PCIBus *bus, struct openpic_t *openpic);
    658 PCIBus *pci_pmac_init(void);
     826
     827/* grackle_pci.c */
     828PCIBus *pci_grackle_init(uint32_t base, void *pic);
     829
     830/* unin_pci.c */
     831PCIBus *pci_pmac_init(void *pic);
     832
     833/* apb_pci.c */
     834PCIBus *pci_apb_init(target_ulong special_base, target_ulong mem_base,
     835                     void *pic);
     836
     837PCIBus *pci_vpb_init(void *pic, int irq, int realview);
     838
     839/* piix_pci.c */
     840PCIBus *i440fx_init(PCIDevice **pi440fx_state);
     841void i440fx_set_smm(PCIDevice *d, int val);
     842int piix3_init(PCIBus *bus, int devfn);
     843void i440fx_init_memory_mappings(PCIDevice *d);
     844
     845int piix4_init(PCIBus *bus, int devfn);
    659846
    660847/* openpic.c */
    661848typedef struct openpic_t openpic_t;
    662 void openpic_set_irq (openpic_t *opp, int n_IRQ, int level);
    663 openpic_t *openpic_init (PCIBus *bus, int *pmem_index, int nb_cpus);
    664 #endif /* !VBOX */
     849void openpic_set_irq(void *opaque, int n_IRQ, int level);
     850openpic_t *openpic_init (PCIBus *bus, int *pmem_index, int nb_cpus,
     851                         CPUState **envp);
     852
     853/* heathrow_pic.c */
     854typedef struct HeathrowPICS HeathrowPICS;
     855void heathrow_pic_set_irq(void *opaque, int num, int level);
     856HeathrowPICS *heathrow_pic_init(int *pmem_index);
     857
     858/* gt64xxx.c */
     859PCIBus *pci_gt64120_init(void *pic);
     860
     861#ifdef HAS_AUDIO
     862struct soundhw {
     863    const char *name;
     864    const char *descr;
     865    int enabled;
     866    int isa;
     867    union {
     868        int (*init_isa) (AudioState *s);
     869        int (*init_pci) (PCIBus *bus, AudioState *s);
     870    } init;
     871};
     872
     873extern struct soundhw soundhw[];
     874#endif
    665875
    666876/* vga.c */
    667877
    668 #define VGA_RAM_SIZE (4096 * 1024)
     878#define VGA_RAM_SIZE (8192 * 1024)
    669879
    670880struct DisplayState {
     
    672882    int linesize;
    673883    int depth;
     884    int bgr; /* BGR color order instead of RGB. Only valid for depth == 32 */
    674885    int width;
    675886    int height;
     887    void *opaque;
     888
    676889    void (*dpy_update)(struct DisplayState *s, int x, int y, int w, int h);
    677890    void (*dpy_resize)(struct DisplayState *s, int w, int h);
    678891    void (*dpy_refresh)(struct DisplayState *s);
     892    void (*dpy_copy)(struct DisplayState *s, int src_x, int src_y, int dst_x, int dst_y, int w, int h);
    679893};
    680894
     
    689903}
    690904
    691 int vga_initialize(PCIBus *bus, DisplayState *ds, uint8_t *vga_ram_base,
    692                    unsigned long vga_ram_offset, int vga_ram_size);
    693 void vga_update_display(void);
    694 void vga_invalidate_display(void);
    695 void vga_screen_dump(const char *filename);
     905int isa_vga_init(DisplayState *ds, uint8_t *vga_ram_base,
     906                 unsigned long vga_ram_offset, int vga_ram_size);
     907int pci_vga_init(PCIBus *bus, DisplayState *ds, uint8_t *vga_ram_base,
     908                 unsigned long vga_ram_offset, int vga_ram_size,
     909                 unsigned long vga_bios_offset, int vga_bios_size);
    696910
    697911/* cirrus_vga.c */
     
    704918void sdl_display_init(DisplayState *ds, int full_screen);
    705919
     920/* cocoa.m */
     921void cocoa_display_init(DisplayState *ds, int full_screen);
     922
     923/* vnc.c */
     924void vnc_display_init(DisplayState *ds, const char *display);
     925
     926/* x_keymap.c */
     927extern uint8_t _translate_keycode(const int key);
     928
    706929/* ide.c */
    707930#define MAX_DISKS 4
    708931
    709 extern BlockDriverState *bs_table[MAX_DISKS];
     932extern BlockDriverState *bs_table[MAX_DISKS + 1];
    710933
    711934void isa_ide_init(int iobase, int iobase2, int irq,
    712935                  BlockDriverState *hd0, BlockDriverState *hd1);
    713 void pci_ide_init(PCIBus *bus, BlockDriverState **hd_table);
    714 void pci_piix3_ide_init(PCIBus *bus, BlockDriverState **hd_table);
     936void pci_cmd646_ide_init(PCIBus *bus, BlockDriverState **hd_table,
     937                         int secondary_ide_enabled);
     938void pci_piix3_ide_init(PCIBus *bus, BlockDriverState **hd_table, int devfn);
    715939int pmac_ide_init (BlockDriverState **hd_table,
    716                    openpic_t *openpic, int irq);
     940                   SetIRQFunc *set_irq, void *irq_opaque, int irq);
     941
     942/* cdrom.c */
     943int cdrom_read_toc(int nb_sectors, uint8_t *buf, int msf, int start_track);
     944int cdrom_read_toc_raw(int nb_sectors, uint8_t *buf, int msf, int session_num);
     945
     946/* es1370.c */
     947int es1370_init (PCIBus *bus, AudioState *s);
    717948
    718949/* sb16.c */
    719 void SB16_init (void);
     950int SB16_init (AudioState *s);
    720951
    721952/* adlib.c */
    722 void Adlib_init (void);
     953int Adlib_init (AudioState *s);
    723954
    724955/* gus.c */
    725 void GUS_init (void);
     956int GUS_init (AudioState *s);
    726957
    727958/* dma.c */
     
    751982/* ne2000.c */
    752983
    753 void isa_ne2000_init(int base, int irq, NetDriverState *nd);
    754 void pci_ne2000_init(PCIBus *bus, NetDriverState *nd);
     984void isa_ne2000_init(int base, int irq, NICInfo *nd);
     985void pci_ne2000_init(PCIBus *bus, NICInfo *nd, int devfn);
     986
     987/* rtl8139.c */
     988
     989void pci_rtl8139_init(PCIBus *bus, NICInfo *nd, int devfn);
     990
     991/* pcnet.c */
     992
     993void pci_pcnet_init(PCIBus *bus, NICInfo *nd, int devfn);
     994void pcnet_h_reset(void *opaque);
     995void *lance_init(NICInfo *nd, uint32_t leaddr, void *dma_opaque);
     996
    755997
    756998/* pckbd.c */
     
    7691011
    7701012typedef struct SerialState SerialState;
    771 SerialState *serial_init(int base, int irq, CharDriverState *chr);
     1013SerialState *serial_init(SetIRQFunc *set_irq, void *opaque,
     1014                         int base, int irq, CharDriverState *chr);
     1015SerialState *serial_mm_init (SetIRQFunc *set_irq, void *opaque,
     1016                             target_ulong base, int it_shift,
     1017                             int irq, CharDriverState *chr);
    7721018
    7731019/* parallel.c */
     
    7781024/* i8259.c */
    7791025
     1026typedef struct PicState2 PicState2;
     1027extern PicState2 *isa_pic;
    7801028void pic_set_irq(int irq, int level);
    781 void pic_init(void);
    782 uint32_t pic_intack_read(CPUState *env);
     1029void pic_set_irq_new(void *opaque, int irq, int level);
     1030PicState2 *pic_init(IRQRequestFunc *irq_request, void *irq_request_opaque);
     1031void pic_set_alt_irq_func(PicState2 *s, SetIRQFunc *alt_irq_func,
     1032                          void *alt_irq_opaque);
     1033int pic_read_irq(PicState2 *s);
     1034void pic_update_irq(PicState2 *s);
     1035uint32_t pic_intack_read(PicState2 *s);
    7831036void pic_info(void);
    7841037void irq_info(void);
    7851038
    7861039/* APIC */
     1040typedef struct IOAPICState IOAPICState;
     1041
    7871042int apic_init(CPUState *env);
    7881043int apic_get_interrupt(CPUState *env);
     1044IOAPICState *ioapic_init(void);
     1045void ioapic_set_irq(void *opaque, int vector, int level);
    7891046
    7901047/* i8254.c */
     
    7971054void pit_set_gate(PITState *pit, int channel, int val);
    7981055int pit_get_gate(PITState *pit, int channel);
     1056int pit_get_initial_count(PITState *pit, int channel);
     1057int pit_get_mode(PITState *pit, int channel);
    7991058int pit_get_out(PITState *pit, int channel, int64_t current_time);
    8001059
     1060/* pcspk.c */
     1061void pcspk_init(PITState *);
     1062int pcspk_audio_init(AudioState *);
     1063
     1064#include "hw/smbus.h"
     1065
     1066/* acpi.c */
     1067extern int acpi_enabled;
     1068void piix4_pm_init(PCIBus *bus, int devfn);
     1069void piix4_smbus_register_device(SMBusDevice *dev, uint8_t addr);
     1070void acpi_bios_init(void);
     1071
     1072/* smbus_eeprom.c */
     1073SMBusDevice *smbus_eeprom_device_init(uint8_t addr, uint8_t *buf);
     1074
    8011075/* pc.c */
    802 void pc_init(int ram_size, int vga_ram_size, int boot_device,
    803              DisplayState *ds, const char **fd_filename, int snapshot,
    804              const char *kernel_filename, const char *kernel_cmdline,
    805              const char *initrd_filename);
     1076extern QEMUMachine pc_machine;
     1077extern QEMUMachine isapc_machine;
     1078extern int fd_bootchk;
     1079
     1080void ioport_set_a20(int enable);
     1081int ioport_get_a20(void);
    8061082
    8071083/* ppc.c */
    808 void ppc_init (int ram_size, int vga_ram_size, int boot_device,
    809                DisplayState *ds, const char **fd_filename, int snapshot,
    810                const char *kernel_filename, const char *kernel_cmdline,
    811                const char *initrd_filename);
    812 void ppc_prep_init (int ram_size, int vga_ram_size, int boot_device,
    813                     DisplayState *ds, const char **fd_filename, int snapshot,
    814                     const char *kernel_filename, const char *kernel_cmdline,
    815                     const char *initrd_filename);
    816 void ppc_chrp_init(int ram_size, int vga_ram_size, int boot_device,
    817                    DisplayState *ds, const char **fd_filename, int snapshot,
    818                    const char *kernel_filename, const char *kernel_cmdline,
    819                    const char *initrd_filename);
     1084extern QEMUMachine prep_machine;
     1085extern QEMUMachine core99_machine;
     1086extern QEMUMachine heathrow_machine;
     1087
     1088/* mips_r4k.c */
     1089extern QEMUMachine mips_machine;
     1090
     1091/* mips_malta.c */
     1092extern QEMUMachine mips_malta_machine;
     1093
     1094/* mips_int */
     1095extern void cpu_mips_irq_request(void *opaque, int irq, int level);
     1096
     1097/* mips_timer.c */
     1098extern void cpu_mips_clock_init(CPUState *);
     1099extern void cpu_mips_irqctrl_init (void);
     1100
     1101/* shix.c */
     1102extern QEMUMachine shix_machine;
     1103
    8201104#ifdef TARGET_PPC
    8211105ppc_tb_t *cpu_ppc_tb_init (CPUState *env, uint32_t freq);
     
    8251109extern CPUWriteMemoryFunc *PPC_io_write[];
    8261110extern CPUReadMemoryFunc *PPC_io_read[];
    827 extern int prep_enabled;
    828 
    829 #ifndef VBOX
     1111void PPC_debug_write (void *opaque, uint32_t addr, uint32_t val);
     1112
    8301113/* sun4m.c */
    831 void sun4m_init(int ram_size, int vga_ram_size, int boot_device,
    832              DisplayState *ds, const char **fd_filename, int snapshot,
    833              const char *kernel_filename, const char *kernel_cmdline,
    834              const char *initrd_filename);
    835 uint32_t iommu_translate(uint32_t addr);
     1114extern QEMUMachine sun4m_machine;
     1115void pic_set_irq_cpu(int irq, int level, unsigned int cpu);
    8361116
    8371117/* iommu.c */
    8381118void *iommu_init(uint32_t addr);
    839 uint32_t iommu_translate_local(void *opaque, uint32_t addr);
    840 
    841 /* lance.c */
    842 void lance_init(NetDriverState *nd, int irq, uint32_t leaddr, uint32_t ledaddr);
     1119void sparc_iommu_memory_rw(void *opaque, target_phys_addr_t addr,
     1120                                 uint8_t *buf, int len, int is_write);
     1121static inline void sparc_iommu_memory_read(void *opaque,
     1122                                           target_phys_addr_t addr,
     1123                                           uint8_t *buf, int len)
     1124{
     1125    sparc_iommu_memory_rw(opaque, addr, buf, len, 0);
     1126}
     1127
     1128static inline void sparc_iommu_memory_write(void *opaque,
     1129                                            target_phys_addr_t addr,
     1130                                            uint8_t *buf, int len)
     1131{
     1132    sparc_iommu_memory_rw(opaque, addr, buf, len, 1);
     1133}
    8431134
    8441135/* tcx.c */
    845 void *tcx_init(DisplayState *ds, uint32_t addr, uint8_t *vram_base,
    846               unsigned long vram_offset, int vram_size);
    847 void tcx_update_display(void *opaque);
    848 void tcx_invalidate_display(void *opaque);
    849 void tcx_screen_dump(void *opaque, const char *filename);
     1136void tcx_init(DisplayState *ds, uint32_t addr, uint8_t *vram_base,
     1137               unsigned long vram_offset, int vram_size, int width, int height);
    8501138
    8511139/* slavio_intctl.c */
    8521140void *slavio_intctl_init();
     1141void slavio_intctl_set_cpu(void *opaque, unsigned int cpu, CPUState *env);
    8531142void slavio_pic_info(void *opaque);
    8541143void slavio_irq_info(void *opaque);
    8551144void slavio_pic_set_irq(void *opaque, int irq, int level);
    856 
    857 /* magic-load.c */
    858 int load_elf(const char *filename, uint8_t *addr);
     1145void slavio_pic_set_irq_cpu(void *opaque, int irq, int level, unsigned int cpu);
     1146
     1147/* loader.c */
     1148int get_image_size(const char *filename);
     1149int load_image(const char *filename, uint8_t *addr);
     1150int load_elf(const char *filename, int64_t virt_to_phys_addend, uint64_t *pentry);
    8591151int load_aout(const char *filename, uint8_t *addr);
    8601152
    8611153/* slavio_timer.c */
    862 void slavio_timer_init(uint32_t addr1, int irq1, uint32_t addr2, int irq2);
     1154void slavio_timer_init(uint32_t addr, int irq, int mode, unsigned int cpu);
    8631155
    8641156/* slavio_serial.c */
    8651157SerialState *slavio_serial_init(int base, int irq, CharDriverState *chr1, CharDriverState *chr2);
    8661158void slavio_serial_ms_kbd_init(int base, int irq);
     1159
     1160/* slavio_misc.c */
     1161void *slavio_misc_init(uint32_t base, int irq);
     1162void slavio_set_power_fail(void *opaque, int power_failing);
     1163
     1164/* esp.c */
     1165void esp_scsi_attach(void *opaque, BlockDriverState *bd, int id);
     1166void *esp_init(BlockDriverState **bd, uint32_t espaddr, void *dma_opaque);
     1167void esp_reset(void *opaque);
     1168
     1169/* sparc32_dma.c */
     1170void *sparc32_dma_init(uint32_t daddr, int espirq, int leirq, void *iommu,
     1171                       void *intctl);
     1172void ledma_set_irq(void *opaque, int isr);
     1173void ledma_memory_read(void *opaque, target_phys_addr_t addr,
     1174                       uint8_t *buf, int len, int do_bswap);
     1175void ledma_memory_write(void *opaque, target_phys_addr_t addr,
     1176                        uint8_t *buf, int len, int do_bswap);
     1177void espdma_raise_irq(void *opaque);
     1178void espdma_clear_irq(void *opaque);
     1179void espdma_memory_read(void *opaque, uint8_t *buf, int len);
     1180void espdma_memory_write(void *opaque, uint8_t *buf, int len);
     1181void sparc32_dma_set_reset_data(void *opaque, void *esp_opaque,
     1182                                void *lance_opaque);
     1183
     1184/* cs4231.c */
     1185void cs_init(target_phys_addr_t base, int irq, void *intctl);
     1186
     1187/* sun4u.c */
     1188extern QEMUMachine sun4u_machine;
    8671189
    8681190/* NVRAM helpers */
     
    8881210                          uint32_t NVRAM_image,
    8891211                          int width, int height, int depth);
    890 #endif
    8911212
    8921213/* adb.c */
     
    9321253
    9331254extern ADBBusState adb_bus;
    934 int cuda_init(openpic_t *openpic, int irq);
     1255int cuda_init(SetIRQFunc *set_irq, void *irq_opaque, int irq);
     1256
     1257#include "hw/usb.h"
     1258
     1259/* usb ports of the VM */
     1260
     1261void qemu_register_usb_port(USBPort *port, void *opaque, int index,
     1262                            usb_attachfn attach);
     1263
     1264#define VM_USB_HUB_SIZE 8
     1265
     1266void do_usb_add(const char *devname);
     1267void do_usb_del(const char *devname);
     1268void usb_info(void);
     1269
     1270/* scsi-disk.c */
     1271enum scsi_reason {
     1272    SCSI_REASON_DONE, /* Command complete.  */
     1273    SCSI_REASON_DATA  /* Transfer complete, more data required.  */
     1274};
     1275
     1276typedef struct SCSIDevice SCSIDevice;
     1277typedef void (*scsi_completionfn)(void *opaque, int reason, uint32_t tag,
     1278                                  uint32_t arg);
     1279
     1280SCSIDevice *scsi_disk_init(BlockDriverState *bdrv,
     1281                           int tcq,
     1282                           scsi_completionfn completion,
     1283                           void *opaque);
     1284void scsi_disk_destroy(SCSIDevice *s);
     1285
     1286int32_t scsi_send_command(SCSIDevice *s, uint32_t tag, uint8_t *buf, int lun);
     1287/* SCSI data transfers are asynchrnonous.  However, unlike the block IO
     1288   layer the completion routine may be called directly by
     1289   scsi_{read,write}_data.  */
     1290void scsi_read_data(SCSIDevice *s, uint32_t tag);
     1291int scsi_write_data(SCSIDevice *s, uint32_t tag);
     1292void scsi_cancel_io(SCSIDevice *s, uint32_t tag);
     1293uint8_t *scsi_get_buf(SCSIDevice *s, uint32_t tag);
     1294
     1295/* lsi53c895a.c */
     1296void lsi_scsi_attach(void *opaque, BlockDriverState *bd, int id);
     1297void *lsi_scsi_init(PCIBus *bus, int devfn);
     1298
     1299/* integratorcp.c */
     1300extern QEMUMachine integratorcp926_machine;
     1301extern QEMUMachine integratorcp1026_machine;
     1302
     1303/* versatilepb.c */
     1304extern QEMUMachine versatilepb_machine;
     1305extern QEMUMachine versatileab_machine;
     1306
     1307/* realview.c */
     1308extern QEMUMachine realview_machine;
     1309
     1310/* ps2.c */
     1311void *ps2_kbd_init(void (*update_irq)(void *, int), void *update_arg);
     1312void *ps2_mouse_init(void (*update_irq)(void *, int), void *update_arg);
     1313void ps2_write_mouse(void *, int val);
     1314void ps2_write_keyboard(void *, int val);
     1315uint32_t ps2_read_data(void *);
     1316void ps2_queue(void *, int b);
     1317void ps2_keyboard_set_translation(void *opaque, int mode);
     1318
     1319/* smc91c111.c */
     1320void smc91c111_init(NICInfo *, uint32_t, void *, int);
     1321
     1322/* pl110.c */
     1323void *pl110_init(DisplayState *ds, uint32_t base, void *pic, int irq, int);
     1324
     1325/* pl011.c */
     1326void pl011_init(uint32_t base, void *pic, int irq, CharDriverState *chr);
     1327
     1328/* pl050.c */
     1329void pl050_init(uint32_t base, void *pic, int irq, int is_mouse);
     1330
     1331/* pl080.c */
     1332void *pl080_init(uint32_t base, void *pic, int irq, int nchannels);
     1333
     1334/* pl190.c */
     1335void *pl190_init(uint32_t base, void *parent, int irq, int fiq);
     1336
     1337/* arm-timer.c */
     1338void sp804_init(uint32_t base, void *pic, int irq);
     1339void icp_pit_init(uint32_t base, void *pic, int irq);
     1340
     1341/* arm_sysctl.c */
     1342void arm_sysctl_init(uint32_t base, uint32_t sys_id);
     1343
     1344/* arm_gic.c */
     1345void *arm_gic_init(uint32_t base, void *parent, int parent_irq);
     1346
     1347/* arm_boot.c */
     1348
     1349void arm_load_kernel(CPUState *env, int ram_size, const char *kernel_filename,
     1350                     const char *kernel_cmdline, const char *initrd_filename,
     1351                     int board_id);
     1352
     1353/* sh7750.c */
     1354struct SH7750State;
     1355
     1356struct SH7750State *sh7750_init(CPUState * cpu);
     1357
     1358typedef struct {
     1359    /* The callback will be triggered if any of the designated lines change */
     1360    uint16_t portamask_trigger;
     1361    uint16_t portbmask_trigger;
     1362    /* Return 0 if no action was taken */
     1363    int (*port_change_cb) (uint16_t porta, uint16_t portb,
     1364                           uint16_t * periph_pdtra,
     1365                           uint16_t * periph_portdira,
     1366                           uint16_t * periph_pdtrb,
     1367                           uint16_t * periph_portdirb);
     1368} sh7750_io_device;
     1369
     1370int sh7750_register_io_device(struct SH7750State *s,
     1371                              sh7750_io_device * device);
     1372/* tc58128.c */
     1373int tc58128_init(struct SH7750State *s, char *zone1, char *zone2);
     1374
     1375/* NOR flash devices */
     1376typedef struct pflash_t pflash_t;
     1377
     1378pflash_t *pflash_register (target_ulong base, ram_addr_t off,
     1379                           BlockDriverState *bs,
     1380                           target_ulong sector_len, int nb_blocs, int width,
     1381                           uint16_t id0, uint16_t id1,
     1382                           uint16_t id2, uint16_t id3);
     1383
     1384#include "gdbstub.h"
    9351385
    9361386#endif /* defined(QEMU_TOOL) */
    9371387
    938 #ifndef VBOX
    9391388/* monitor.c */
    9401389void monitor_init(CharDriverState *hd, int show_banner);
     
    9421391void term_vprintf(const char *fmt, va_list ap);
    9431392void term_printf(const char *fmt, ...) __attribute__ ((__format__ (__printf__, 1, 2)));
     1393void term_print_filename(const char *filename);
    9441394void term_flush(void);
    9451395void term_print_help(void);
     
    9581408                    ReadLineFunc *readline_func, void *opaque);
    9591409
     1410void kqemu_record_dump(void);
     1411
    9601412#endif /* !VBOX */
    9611413
    962 /* gdbstub.c */
    963 
    964 #define DEFAULT_GDBSTUB_PORT 1234
    965 
    966 int gdbserver_start(int port);
    967 
    9681414#endif /* VL_H */
Note: See TracChangeset for help on using the changeset viewer.

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette