slirp: cleanup for submission upstream back to qemu
Minimize the include file set and their contents to only provide the slirp referenced qemu includes and interfaces.
This commit is contained in:
parent
eff1ef12e7
commit
7ad57d7fa8
98 changed files with 386 additions and 15031 deletions
|
@ -41,8 +41,8 @@
|
||||||
<Tool
|
<Tool
|
||||||
Name="VCCLCompilerTool"
|
Name="VCCLCompilerTool"
|
||||||
Optimization="0"
|
Optimization="0"
|
||||||
AdditionalIncludeDirectories="./;../;../VAX/;../pdp11/;"../../windows-build/winpcap/Wpdpack/Include";"../../windows-build/PCRE/include/";"../../windows-build/pthreads";"../../windows-build/libSDL/SDL2-2.0.3/include";"../../windows-build/PCRE/include";"../../windows-build/libpng-1.6.18";../slirp;../slirp/simh;../slirp/simh/qemu;../slirp/simh/qemu/win32/include"
|
AdditionalIncludeDirectories="./;../;../VAX/;../pdp11/;"../../windows-build/winpcap/Wpdpack/Include";"../../windows-build/PCRE/include/";"../../windows-build/pthreads";"../../windows-build/libSDL/SDL2-2.0.3/include";"../../windows-build/PCRE/include";"../../windows-build/libpng-1.6.18";../slirp;../slirp_glue;../slirp_glue/qemu;../slirp_glue/qemu/win32/include"
|
||||||
PreprocessorDefinitions="USE_INT64;USE_ADDR64;VM_VAX;VAX_610;USE_SHARED;_CRT_NONSTDC_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;_WINSOCK_DEPRECATED_NO_WARNINGS;PTW32_STATIC_LIB;USE_READER_THREAD;USE_SIM_VIDEO;HAVE_LIBSDL;SIM_ASYNCH_IO;SIM_NEED_GIT_COMMIT_ID;HAVE_PCREPOSIX_H;PCRE_STATIC;HAVE_LIBPNG;HAVE_SLIRP_NETWORK"
|
PreprocessorDefinitions="USE_INT64;USE_ADDR64;VM_VAX;VAX_610;USE_SHARED;_CRT_NONSTDC_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;_WINSOCK_DEPRECATED_NO_WARNINGS;PTW32_STATIC_LIB;USE_READER_THREAD;USE_SIM_VIDEO;HAVE_LIBSDL;SIM_ASYNCH_IO;SIM_NEED_GIT_COMMIT_ID;HAVE_PCREPOSIX_H;PCRE_STATIC;HAVE_LIBPNG;HAVE_SLIRP_NETWORK;USE_SIMH_SLIRP_DEBUG"
|
||||||
KeepComments="false"
|
KeepComments="false"
|
||||||
MinimalRebuild="true"
|
MinimalRebuild="true"
|
||||||
BasicRuntimeChecks="0"
|
BasicRuntimeChecks="0"
|
||||||
|
@ -128,8 +128,8 @@
|
||||||
FavorSizeOrSpeed="1"
|
FavorSizeOrSpeed="1"
|
||||||
OmitFramePointers="true"
|
OmitFramePointers="true"
|
||||||
WholeProgramOptimization="true"
|
WholeProgramOptimization="true"
|
||||||
AdditionalIncludeDirectories="./;../;../VAX/;../pdp11/;"../../windows-build/winpcap/Wpdpack/Include";"../../windows-build/PCRE/include/";"../../windows-build/pthreads";"../../windows-build/libSDL/SDL2-2.0.3/include";"../../windows-build/PCRE/include";"../../windows-build/libpng-1.6.18";../slirp;../slirp/simh;../slirp/simh/qemu;../slirp/simh/qemu/win32/include"
|
AdditionalIncludeDirectories="./;../;../VAX/;../pdp11/;"../../windows-build/winpcap/Wpdpack/Include";"../../windows-build/PCRE/include/";"../../windows-build/pthreads";"../../windows-build/libSDL/SDL2-2.0.3/include";"../../windows-build/PCRE/include";"../../windows-build/libpng-1.6.18";../slirp;../slirp_glue;../slirp_glue/qemu;../slirp_glue/qemu/win32/include"
|
||||||
PreprocessorDefinitions="USE_INT64;USE_ADDR64;VM_VAX;VAX_610;USE_SHARED;_CRT_NONSTDC_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;_WINSOCK_DEPRECATED_NO_WARNINGS;PTW32_STATIC_LIB;USE_READER_THREAD;USE_SIM_VIDEO;HAVE_LIBSDL;SIM_ASYNCH_IO;SIM_NEED_GIT_COMMIT_ID;HAVE_PCREPOSIX_H;PCRE_STATIC;HAVE_LIBPNG;HAVE_SLIRP_NETWORK"
|
PreprocessorDefinitions="USE_INT64;USE_ADDR64;VM_VAX;VAX_610;USE_SHARED;_CRT_NONSTDC_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;_WINSOCK_DEPRECATED_NO_WARNINGS;PTW32_STATIC_LIB;USE_READER_THREAD;USE_SIM_VIDEO;HAVE_LIBSDL;SIM_ASYNCH_IO;SIM_NEED_GIT_COMMIT_ID;HAVE_PCREPOSIX_H;PCRE_STATIC;HAVE_LIBPNG;HAVE_SLIRP_NETWORK;USE_SIMH_SLIRP_DEBUG"
|
||||||
KeepComments="false"
|
KeepComments="false"
|
||||||
StringPooling="true"
|
StringPooling="true"
|
||||||
RuntimeLibrary="0"
|
RuntimeLibrary="0"
|
||||||
|
@ -405,7 +405,7 @@
|
||||||
>
|
>
|
||||||
</File>
|
</File>
|
||||||
<File
|
<File
|
||||||
RelativePath="..\slirp\simh\glib_qemu_stubs.c"
|
RelativePath="..\slirp_glue\glib_qemu_stubs.c"
|
||||||
>
|
>
|
||||||
</File>
|
</File>
|
||||||
<File
|
<File
|
||||||
|
@ -469,7 +469,7 @@
|
||||||
>
|
>
|
||||||
</File>
|
</File>
|
||||||
<File
|
<File
|
||||||
RelativePath="..\slirp\simh\sim_slirp.c"
|
RelativePath="..\slirp_glue\sim_slirp.c"
|
||||||
>
|
>
|
||||||
</File>
|
</File>
|
||||||
<File
|
<File
|
||||||
|
|
|
@ -41,8 +41,8 @@
|
||||||
<Tool
|
<Tool
|
||||||
Name="VCCLCompilerTool"
|
Name="VCCLCompilerTool"
|
||||||
Optimization="0"
|
Optimization="0"
|
||||||
AdditionalIncludeDirectories="./;../;../VAX/;../pdp11/;"../../windows-build/winpcap/Wpdpack/Include";"../../windows-build/PCRE/include/";"../../windows-build/pthreads";"../../windows-build/libSDL/SDL2-2.0.3/include";"../../windows-build/PCRE/include";"../../windows-build/libpng-1.6.18";../slirp;../slirp/simh;../slirp/simh/qemu;../slirp/simh/qemu/win32/include"
|
AdditionalIncludeDirectories="./;../;../VAX/;../pdp11/;"../../windows-build/winpcap/Wpdpack/Include";"../../windows-build/PCRE/include/";"../../windows-build/pthreads";"../../windows-build/libSDL/SDL2-2.0.3/include";"../../windows-build/PCRE/include";"../../windows-build/libpng-1.6.18";../slirp;../slirp_glue;../slirp_glue/qemu;../slirp_glue/qemu/win32/include"
|
||||||
PreprocessorDefinitions="USE_INT64;USE_ADDR64;VM_VAX;VAX_630;USE_SHARED;_CRT_NONSTDC_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;_WINSOCK_DEPRECATED_NO_WARNINGS;PTW32_STATIC_LIB;USE_READER_THREAD;USE_SIM_VIDEO;HAVE_LIBSDL;SIM_ASYNCH_IO;SIM_NEED_GIT_COMMIT_ID;HAVE_PCREPOSIX_H;PCRE_STATIC;HAVE_LIBPNG;HAVE_SLIRP_NETWORK"
|
PreprocessorDefinitions="USE_INT64;USE_ADDR64;VM_VAX;VAX_630;USE_SHARED;_CRT_NONSTDC_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;_WINSOCK_DEPRECATED_NO_WARNINGS;PTW32_STATIC_LIB;USE_READER_THREAD;USE_SIM_VIDEO;HAVE_LIBSDL;SIM_ASYNCH_IO;SIM_NEED_GIT_COMMIT_ID;HAVE_PCREPOSIX_H;PCRE_STATIC;HAVE_LIBPNG;HAVE_SLIRP_NETWORK;USE_SIMH_SLIRP_DEBUG"
|
||||||
KeepComments="false"
|
KeepComments="false"
|
||||||
MinimalRebuild="true"
|
MinimalRebuild="true"
|
||||||
BasicRuntimeChecks="0"
|
BasicRuntimeChecks="0"
|
||||||
|
@ -128,8 +128,8 @@
|
||||||
FavorSizeOrSpeed="1"
|
FavorSizeOrSpeed="1"
|
||||||
OmitFramePointers="true"
|
OmitFramePointers="true"
|
||||||
WholeProgramOptimization="true"
|
WholeProgramOptimization="true"
|
||||||
AdditionalIncludeDirectories="./;../;../VAX/;../pdp11/;"../../windows-build/winpcap/Wpdpack/Include";"../../windows-build/PCRE/include/";"../../windows-build/pthreads";"../../windows-build/libSDL/SDL2-2.0.3/include";"../../windows-build/PCRE/include";"../../windows-build/libpng-1.6.18";../slirp;../slirp/simh;../slirp/simh/qemu;../slirp/simh/qemu/win32/include"
|
AdditionalIncludeDirectories="./;../;../VAX/;../pdp11/;"../../windows-build/winpcap/Wpdpack/Include";"../../windows-build/PCRE/include/";"../../windows-build/pthreads";"../../windows-build/libSDL/SDL2-2.0.3/include";"../../windows-build/PCRE/include";"../../windows-build/libpng-1.6.18";../slirp;../slirp_glue;../slirp_glue/qemu;../slirp_glue/qemu/win32/include"
|
||||||
PreprocessorDefinitions="USE_INT64;USE_ADDR64;VM_VAX;VAX_630;USE_SHARED;_CRT_NONSTDC_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;_WINSOCK_DEPRECATED_NO_WARNINGS;PTW32_STATIC_LIB;USE_READER_THREAD;USE_SIM_VIDEO;HAVE_LIBSDL;SIM_ASYNCH_IO;SIM_NEED_GIT_COMMIT_ID;HAVE_PCREPOSIX_H;PCRE_STATIC;HAVE_LIBPNG;HAVE_SLIRP_NETWORK"
|
PreprocessorDefinitions="USE_INT64;USE_ADDR64;VM_VAX;VAX_630;USE_SHARED;_CRT_NONSTDC_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;_WINSOCK_DEPRECATED_NO_WARNINGS;PTW32_STATIC_LIB;USE_READER_THREAD;USE_SIM_VIDEO;HAVE_LIBSDL;SIM_ASYNCH_IO;SIM_NEED_GIT_COMMIT_ID;HAVE_PCREPOSIX_H;PCRE_STATIC;HAVE_LIBPNG;HAVE_SLIRP_NETWORK;USE_SIMH_SLIRP_DEBUG"
|
||||||
KeepComments="false"
|
KeepComments="false"
|
||||||
StringPooling="true"
|
StringPooling="true"
|
||||||
RuntimeLibrary="0"
|
RuntimeLibrary="0"
|
||||||
|
@ -405,7 +405,7 @@
|
||||||
>
|
>
|
||||||
</File>
|
</File>
|
||||||
<File
|
<File
|
||||||
RelativePath="..\slirp\simh\glib_qemu_stubs.c"
|
RelativePath="..\slirp_glue\glib_qemu_stubs.c"
|
||||||
>
|
>
|
||||||
</File>
|
</File>
|
||||||
<File
|
<File
|
||||||
|
@ -469,7 +469,7 @@
|
||||||
>
|
>
|
||||||
</File>
|
</File>
|
||||||
<File
|
<File
|
||||||
RelativePath="..\slirp\simh\sim_slirp.c"
|
RelativePath="..\slirp_glue\sim_slirp.c"
|
||||||
>
|
>
|
||||||
</File>
|
</File>
|
||||||
<File
|
<File
|
||||||
|
|
|
@ -41,8 +41,8 @@
|
||||||
<Tool
|
<Tool
|
||||||
Name="VCCLCompilerTool"
|
Name="VCCLCompilerTool"
|
||||||
Optimization="0"
|
Optimization="0"
|
||||||
AdditionalIncludeDirectories="./;../;../PDP11/;"../../windows-build/winpcap/Wpdpack/Include";"../../windows-build/PCRE/include/";"../../windows-build/pthreads";../slirp;../slirp/simh;../slirp/simh/qemu;../slirp/simh/qemu/win32/include"
|
AdditionalIncludeDirectories="./;../;../PDP11/;"../../windows-build/winpcap/Wpdpack/Include";"../../windows-build/PCRE/include/";"../../windows-build/pthreads";../slirp;../slirp_glue;../slirp_glue/qemu;../slirp_glue/qemu/win32/include"
|
||||||
PreprocessorDefinitions="USE_SHARED;USE_DISPLAY;VM_PDP11;_CRT_NONSTDC_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;_WINSOCK_DEPRECATED_NO_WARNINGS;PTW32_STATIC_LIB;SIM_ASYNCH_IO;USE_READER_THREAD;SIM_NEED_GIT_COMMIT_ID;HAVE_PCREPOSIX_H;PCRE_STATIC;HAVE_SLIRP_NETWORK"
|
PreprocessorDefinitions="USE_SHARED;USE_DISPLAY;VM_PDP11;_CRT_NONSTDC_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;_WINSOCK_DEPRECATED_NO_WARNINGS;PTW32_STATIC_LIB;SIM_ASYNCH_IO;USE_READER_THREAD;SIM_NEED_GIT_COMMIT_ID;HAVE_PCREPOSIX_H;PCRE_STATIC;HAVE_SLIRP_NETWORK;USE_SIMH_SLIRP_DEBUG"
|
||||||
KeepComments="false"
|
KeepComments="false"
|
||||||
MinimalRebuild="true"
|
MinimalRebuild="true"
|
||||||
BasicRuntimeChecks="0"
|
BasicRuntimeChecks="0"
|
||||||
|
@ -125,8 +125,8 @@
|
||||||
InlineFunctionExpansion="1"
|
InlineFunctionExpansion="1"
|
||||||
OmitFramePointers="true"
|
OmitFramePointers="true"
|
||||||
WholeProgramOptimization="false"
|
WholeProgramOptimization="false"
|
||||||
AdditionalIncludeDirectories="./;../;../PDP11/;"../../windows-build/winpcap/Wpdpack/Include";"../../windows-build/PCRE/include/";"../../windows-build/pthreads";../slirp;../slirp/simh;../slirp/simh/qemu;../slirp/simh/qemu/win32/include"
|
AdditionalIncludeDirectories="./;../;../PDP11/;"../../windows-build/winpcap/Wpdpack/Include";"../../windows-build/PCRE/include/";"../../windows-build/pthreads";../slirp;../slirp_glue;../slirp_glue/qemu;../slirp_glue/qemu/win32/include"
|
||||||
PreprocessorDefinitions="USE_SHARED;USE_DISPLAY;VM_PDP11;_CRT_NONSTDC_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;_WINSOCK_DEPRECATED_NO_WARNINGS;PTW32_STATIC_LIB;SIM_ASYNCH_IO;USE_READER_THREAD;SIM_NEED_GIT_COMMIT_ID;HAVE_PCREPOSIX_H;PCRE_STATIC;HAVE_SLIRP_NETWORK"
|
PreprocessorDefinitions="USE_SHARED;USE_DISPLAY;VM_PDP11;_CRT_NONSTDC_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;_WINSOCK_DEPRECATED_NO_WARNINGS;PTW32_STATIC_LIB;SIM_ASYNCH_IO;USE_READER_THREAD;SIM_NEED_GIT_COMMIT_ID;HAVE_PCREPOSIX_H;PCRE_STATIC;HAVE_SLIRP_NETWORK;USE_SIMH_SLIRP_DEBUG"
|
||||||
StringPooling="true"
|
StringPooling="true"
|
||||||
RuntimeLibrary="0"
|
RuntimeLibrary="0"
|
||||||
EnableFunctionLevelLinking="true"
|
EnableFunctionLevelLinking="true"
|
||||||
|
@ -458,7 +458,7 @@
|
||||||
>
|
>
|
||||||
</File>
|
</File>
|
||||||
<File
|
<File
|
||||||
RelativePath="..\slirp\simh\glib_qemu_stubs.c"
|
RelativePath="..\slirp_glue\glib_qemu_stubs.c"
|
||||||
>
|
>
|
||||||
</File>
|
</File>
|
||||||
<File
|
<File
|
||||||
|
@ -522,7 +522,7 @@
|
||||||
>
|
>
|
||||||
</File>
|
</File>
|
||||||
<File
|
<File
|
||||||
RelativePath="..\slirp\simh\sim_slirp.c"
|
RelativePath="..\slirp_glue\sim_slirp.c"
|
||||||
>
|
>
|
||||||
</File>
|
</File>
|
||||||
<File
|
<File
|
||||||
|
|
|
@ -41,8 +41,8 @@
|
||||||
<Tool
|
<Tool
|
||||||
Name="VCCLCompilerTool"
|
Name="VCCLCompilerTool"
|
||||||
Optimization="0"
|
Optimization="0"
|
||||||
AdditionalIncludeDirectories="./;../;../VAX/;../pdp11/;"../../windows-build/winpcap/Wpdpack/Include";"../../windows-build/PCRE/include/";"../../windows-build/pthreads";"../../windows-build/libSDL/SDL2-2.0.3/include";"../../windows-build/PCRE/include";"../../windows-build/libpng-1.6.18";../slirp;../slirp/simh;../slirp/simh/qemu;../slirp/simh/qemu/win32/include"
|
AdditionalIncludeDirectories="./;../;../VAX/;../pdp11/;"../../windows-build/winpcap/Wpdpack/Include";"../../windows-build/PCRE/include/";"../../windows-build/pthreads";"../../windows-build/libSDL/SDL2-2.0.3/include";"../../windows-build/PCRE/include";"../../windows-build/libpng-1.6.18";../slirp;../slirp_glue;../slirp_glue/qemu;../slirp_glue/qemu/win32/include"
|
||||||
PreprocessorDefinitions="USE_INT64;USE_ADDR64;VM_VAX;USE_SHARED;_CRT_NONSTDC_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;_WINSOCK_DEPRECATED_NO_WARNINGS;PTW32_STATIC_LIB;USE_READER_THREAD;USE_SIM_VIDEO;HAVE_LIBSDL;SIM_ASYNCH_IO;SIM_NEED_GIT_COMMIT_ID;HAVE_PCREPOSIX_H;PCRE_STATIC;HAVE_LIBPNG;HAVE_SLIRP_NETWORK"
|
PreprocessorDefinitions="USE_INT64;USE_ADDR64;VM_VAX;USE_SHARED;_CRT_NONSTDC_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;_WINSOCK_DEPRECATED_NO_WARNINGS;PTW32_STATIC_LIB;USE_READER_THREAD;USE_SIM_VIDEO;HAVE_LIBSDL;SIM_ASYNCH_IO;SIM_NEED_GIT_COMMIT_ID;HAVE_PCREPOSIX_H;PCRE_STATIC;HAVE_LIBPNG;HAVE_SLIRP_NETWORK;USE_SIMH_SLIRP_DEBUG"
|
||||||
KeepComments="false"
|
KeepComments="false"
|
||||||
MinimalRebuild="true"
|
MinimalRebuild="true"
|
||||||
BasicRuntimeChecks="0"
|
BasicRuntimeChecks="0"
|
||||||
|
@ -130,8 +130,8 @@
|
||||||
FavorSizeOrSpeed="1"
|
FavorSizeOrSpeed="1"
|
||||||
OmitFramePointers="true"
|
OmitFramePointers="true"
|
||||||
WholeProgramOptimization="true"
|
WholeProgramOptimization="true"
|
||||||
AdditionalIncludeDirectories="./;../;../VAX/;../pdp11/;"../../windows-build/winpcap/Wpdpack/Include";"../../windows-build/PCRE/include/";"../../windows-build/pthreads";"../../windows-build/libSDL/SDL2-2.0.3/include";"../../windows-build/PCRE/include";"../../windows-build/libpng-1.6.18";../slirp;../slirp/simh;../slirp/simh/qemu;../slirp/simh/qemu/win32/include"
|
AdditionalIncludeDirectories="./;../;../VAX/;../pdp11/;"../../windows-build/winpcap/Wpdpack/Include";"../../windows-build/PCRE/include/";"../../windows-build/pthreads";"../../windows-build/libSDL/SDL2-2.0.3/include";"../../windows-build/PCRE/include";"../../windows-build/libpng-1.6.18";../slirp;../slirp_glue;../slirp_glue/qemu;../slirp_glue/qemu/win32/include"
|
||||||
PreprocessorDefinitions="USE_INT64;USE_ADDR64;VM_VAX;USE_SHARED;_CRT_NONSTDC_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;_WINSOCK_DEPRECATED_NO_WARNINGS;PTW32_STATIC_LIB;USE_READER_THREAD;USE_SIM_VIDEO;HAVE_LIBSDL;SIM_ASYNCH_IO;SIM_NEED_GIT_COMMIT_ID;HAVE_PCREPOSIX_H;PCRE_STATIC;HAVE_LIBPNG;HAVE_SLIRP_NETWORK"
|
PreprocessorDefinitions="USE_INT64;USE_ADDR64;VM_VAX;USE_SHARED;_CRT_NONSTDC_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;_WINSOCK_DEPRECATED_NO_WARNINGS;PTW32_STATIC_LIB;USE_READER_THREAD;USE_SIM_VIDEO;HAVE_LIBSDL;SIM_ASYNCH_IO;SIM_NEED_GIT_COMMIT_ID;HAVE_PCREPOSIX_H;PCRE_STATIC;HAVE_LIBPNG;HAVE_SLIRP_NETWORK;USE_SIMH_SLIRP_DEBUG"
|
||||||
KeepComments="false"
|
KeepComments="false"
|
||||||
StringPooling="true"
|
StringPooling="true"
|
||||||
RuntimeLibrary="0"
|
RuntimeLibrary="0"
|
||||||
|
@ -405,7 +405,7 @@
|
||||||
>
|
>
|
||||||
</File>
|
</File>
|
||||||
<File
|
<File
|
||||||
RelativePath="..\slirp\simh\glib_qemu_stubs.c"
|
RelativePath="..\slirp_glue\glib_qemu_stubs.c"
|
||||||
>
|
>
|
||||||
</File>
|
</File>
|
||||||
<File
|
<File
|
||||||
|
@ -469,7 +469,7 @@
|
||||||
>
|
>
|
||||||
</File>
|
</File>
|
||||||
<File
|
<File
|
||||||
RelativePath="..\slirp\simh\sim_slirp.c"
|
RelativePath="..\slirp_glue\sim_slirp.c"
|
||||||
>
|
>
|
||||||
</File>
|
</File>
|
||||||
<File
|
<File
|
||||||
|
|
|
@ -41,8 +41,8 @@
|
||||||
<Tool
|
<Tool
|
||||||
Name="VCCLCompilerTool"
|
Name="VCCLCompilerTool"
|
||||||
Optimization="0"
|
Optimization="0"
|
||||||
AdditionalIncludeDirectories="./;../;../VAX/;../pdp11/;"../../windows-build/winpcap/Wpdpack/Include";"../../windows-build/PCRE/include/";"../../windows-build/pthreads";../slirp;../slirp/simh;../slirp/simh/qemu;../slirp/simh/qemu/win32/include"
|
AdditionalIncludeDirectories="./;../;../VAX/;../pdp11/;"../../windows-build/winpcap/Wpdpack/Include";"../../windows-build/PCRE/include/";"../../windows-build/pthreads";../slirp;../slirp_glue;../slirp_glue/qemu;../slirp_glue/qemu/win32/include"
|
||||||
PreprocessorDefinitions="USE_INT64;USE_ADDR64;VM_VAX;VAX_730;USE_SHARED;_CRT_NONSTDC_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;_WINSOCK_DEPRECATED_NO_WARNINGS;PTW32_STATIC_LIB;USE_READER_THREAD;SIM_ASYNCH_IO;SIM_NEED_GIT_COMMIT_ID;HAVE_PCREPOSIX_H;PCRE_STATIC;HAVE_SLIRP_NETWORK"
|
PreprocessorDefinitions="USE_INT64;USE_ADDR64;VM_VAX;VAX_730;USE_SHARED;_CRT_NONSTDC_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;_WINSOCK_DEPRECATED_NO_WARNINGS;PTW32_STATIC_LIB;USE_READER_THREAD;SIM_ASYNCH_IO;SIM_NEED_GIT_COMMIT_ID;HAVE_PCREPOSIX_H;PCRE_STATIC;HAVE_SLIRP_NETWORK;USE_SIMH_SLIRP_DEBUG"
|
||||||
MinimalRebuild="true"
|
MinimalRebuild="true"
|
||||||
BasicRuntimeChecks="0"
|
BasicRuntimeChecks="0"
|
||||||
RuntimeLibrary="1"
|
RuntimeLibrary="1"
|
||||||
|
@ -127,8 +127,8 @@
|
||||||
FavorSizeOrSpeed="1"
|
FavorSizeOrSpeed="1"
|
||||||
OmitFramePointers="true"
|
OmitFramePointers="true"
|
||||||
WholeProgramOptimization="true"
|
WholeProgramOptimization="true"
|
||||||
AdditionalIncludeDirectories="./;../;../VAX/;../pdp11/;"../../windows-build/winpcap/Wpdpack/Include";"../../windows-build/PCRE/include/";"../../windows-build/pthreads";../slirp;../slirp/simh;../slirp/simh/qemu;../slirp/simh/qemu/win32/include"
|
AdditionalIncludeDirectories="./;../;../VAX/;../pdp11/;"../../windows-build/winpcap/Wpdpack/Include";"../../windows-build/PCRE/include/";"../../windows-build/pthreads";../slirp;../slirp_glue;../slirp_glue/qemu;../slirp_glue/qemu/win32/include"
|
||||||
PreprocessorDefinitions="USE_INT64;USE_ADDR64;VM_VAX;VAX_730;USE_SHARED;_CRT_NONSTDC_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;_WINSOCK_DEPRECATED_NO_WARNINGS;PTW32_STATIC_LIB;USE_READER_THREAD;SIM_ASYNCH_IO;SIM_NEED_GIT_COMMIT_ID;HAVE_PCREPOSIX_H;PCRE_STATIC;HAVE_SLIRP_NETWORK"
|
PreprocessorDefinitions="USE_INT64;USE_ADDR64;VM_VAX;VAX_730;USE_SHARED;_CRT_NONSTDC_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;_WINSOCK_DEPRECATED_NO_WARNINGS;PTW32_STATIC_LIB;USE_READER_THREAD;SIM_ASYNCH_IO;SIM_NEED_GIT_COMMIT_ID;HAVE_PCREPOSIX_H;PCRE_STATIC;HAVE_SLIRP_NETWORK;USE_SIMH_SLIRP_DEBUG"
|
||||||
StringPooling="true"
|
StringPooling="true"
|
||||||
RuntimeLibrary="0"
|
RuntimeLibrary="0"
|
||||||
EnableFunctionLevelLinking="true"
|
EnableFunctionLevelLinking="true"
|
||||||
|
@ -397,7 +397,7 @@
|
||||||
>
|
>
|
||||||
</File>
|
</File>
|
||||||
<File
|
<File
|
||||||
RelativePath="..\slirp\simh\glib_qemu_stubs.c"
|
RelativePath="..\slirp_glue\glib_qemu_stubs.c"
|
||||||
>
|
>
|
||||||
</File>
|
</File>
|
||||||
<File
|
<File
|
||||||
|
@ -461,7 +461,7 @@
|
||||||
>
|
>
|
||||||
</File>
|
</File>
|
||||||
<File
|
<File
|
||||||
RelativePath="..\slirp\simh\sim_slirp.c"
|
RelativePath="..\slirp_glue\sim_slirp.c"
|
||||||
>
|
>
|
||||||
</File>
|
</File>
|
||||||
<File
|
<File
|
||||||
|
|
|
@ -41,8 +41,8 @@
|
||||||
<Tool
|
<Tool
|
||||||
Name="VCCLCompilerTool"
|
Name="VCCLCompilerTool"
|
||||||
Optimization="0"
|
Optimization="0"
|
||||||
AdditionalIncludeDirectories="./;../;../VAX/;../pdp11/;"../../windows-build/winpcap/Wpdpack/Include";"../../windows-build/PCRE/include/";"../../windows-build/pthreads";../slirp;../slirp/simh;../slirp/simh/qemu;../slirp/simh/qemu/win32/include"
|
AdditionalIncludeDirectories="./;../;../VAX/;../pdp11/;"../../windows-build/winpcap/Wpdpack/Include";"../../windows-build/PCRE/include/";"../../windows-build/pthreads";../slirp;../slirp_glue;../slirp_glue/qemu;../slirp_glue/qemu/win32/include"
|
||||||
PreprocessorDefinitions="USE_INT64;USE_ADDR64;VM_VAX;VAX_750;USE_SHARED;_CRT_NONSTDC_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;_WINSOCK_DEPRECATED_NO_WARNINGS;PTW32_STATIC_LIB;USE_READER_THREAD;SIM_ASYNCH_IO;SIM_NEED_GIT_COMMIT_ID;HAVE_PCREPOSIX_H;PCRE_STATIC;HAVE_SLIRP_NETWORK"
|
PreprocessorDefinitions="USE_INT64;USE_ADDR64;VM_VAX;VAX_750;USE_SHARED;_CRT_NONSTDC_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;_WINSOCK_DEPRECATED_NO_WARNINGS;PTW32_STATIC_LIB;USE_READER_THREAD;SIM_ASYNCH_IO;SIM_NEED_GIT_COMMIT_ID;HAVE_PCREPOSIX_H;PCRE_STATIC;HAVE_SLIRP_NETWORK;USE_SIMH_SLIRP_DEBUG"
|
||||||
MinimalRebuild="true"
|
MinimalRebuild="true"
|
||||||
BasicRuntimeChecks="0"
|
BasicRuntimeChecks="0"
|
||||||
RuntimeLibrary="1"
|
RuntimeLibrary="1"
|
||||||
|
@ -127,8 +127,8 @@
|
||||||
FavorSizeOrSpeed="1"
|
FavorSizeOrSpeed="1"
|
||||||
OmitFramePointers="true"
|
OmitFramePointers="true"
|
||||||
WholeProgramOptimization="true"
|
WholeProgramOptimization="true"
|
||||||
AdditionalIncludeDirectories="./;../;../VAX/;../pdp11/;"../../windows-build/winpcap/Wpdpack/Include";"../../windows-build/PCRE/include/";"../../windows-build/pthreads";../slirp;../slirp/simh;../slirp/simh/qemu;../slirp/simh/qemu/win32/include"
|
AdditionalIncludeDirectories="./;../;../VAX/;../pdp11/;"../../windows-build/winpcap/Wpdpack/Include";"../../windows-build/PCRE/include/";"../../windows-build/pthreads";../slirp;../slirp_glue;../slirp_glue/qemu;../slirp_glue/qemu/win32/include"
|
||||||
PreprocessorDefinitions="USE_INT64;USE_ADDR64;VM_VAX;VAX_750;USE_SHARED;_CRT_NONSTDC_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;_WINSOCK_DEPRECATED_NO_WARNINGS;PTW32_STATIC_LIB;USE_READER_THREAD;SIM_ASYNCH_IO;SIM_NEED_GIT_COMMIT_ID;HAVE_PCREPOSIX_H;PCRE_STATIC;HAVE_SLIRP_NETWORK"
|
PreprocessorDefinitions="USE_INT64;USE_ADDR64;VM_VAX;VAX_750;USE_SHARED;_CRT_NONSTDC_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;_WINSOCK_DEPRECATED_NO_WARNINGS;PTW32_STATIC_LIB;USE_READER_THREAD;SIM_ASYNCH_IO;SIM_NEED_GIT_COMMIT_ID;HAVE_PCREPOSIX_H;PCRE_STATIC;HAVE_SLIRP_NETWORK;USE_SIMH_SLIRP_DEBUG"
|
||||||
StringPooling="true"
|
StringPooling="true"
|
||||||
RuntimeLibrary="0"
|
RuntimeLibrary="0"
|
||||||
EnableFunctionLevelLinking="true"
|
EnableFunctionLevelLinking="true"
|
||||||
|
@ -405,7 +405,7 @@
|
||||||
>
|
>
|
||||||
</File>
|
</File>
|
||||||
<File
|
<File
|
||||||
RelativePath="..\slirp\simh\glib_qemu_stubs.c"
|
RelativePath="..\slirp_glue\glib_qemu_stubs.c"
|
||||||
>
|
>
|
||||||
</File>
|
</File>
|
||||||
<File
|
<File
|
||||||
|
@ -469,7 +469,7 @@
|
||||||
>
|
>
|
||||||
</File>
|
</File>
|
||||||
<File
|
<File
|
||||||
RelativePath="..\slirp\simh\sim_slirp.c"
|
RelativePath="..\slirp_glue\sim_slirp.c"
|
||||||
>
|
>
|
||||||
</File>
|
</File>
|
||||||
<File
|
<File
|
||||||
|
|
|
@ -41,8 +41,8 @@
|
||||||
<Tool
|
<Tool
|
||||||
Name="VCCLCompilerTool"
|
Name="VCCLCompilerTool"
|
||||||
Optimization="0"
|
Optimization="0"
|
||||||
AdditionalIncludeDirectories="./;../;../VAX/;../pdp11/;"../../windows-build/winpcap/Wpdpack/Include";"../../windows-build/PCRE/include/";"../../windows-build/pthreads";../slirp;../slirp/simh;../slirp/simh/qemu;../slirp/simh/qemu/win32/include"
|
AdditionalIncludeDirectories="./;../;../VAX/;../pdp11/;"../../windows-build/winpcap/Wpdpack/Include";"../../windows-build/PCRE/include/";"../../windows-build/pthreads";../slirp;../slirp_glue;../slirp_glue/qemu;../slirp_glue/qemu/win32/include"
|
||||||
PreprocessorDefinitions="USE_INT64;USE_ADDR64;VM_VAX;VAX_780;USE_SHARED;_CRT_NONSTDC_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;_WINSOCK_DEPRECATED_NO_WARNINGS;PTW32_STATIC_LIB;USE_READER_THREAD;SIM_ASYNCH_IO;SIM_NEED_GIT_COMMIT_ID;HAVE_PCREPOSIX_H;PCRE_STATIC;HAVE_SLIRP_NETWORK"
|
PreprocessorDefinitions="USE_INT64;USE_ADDR64;VM_VAX;VAX_780;USE_SHARED;_CRT_NONSTDC_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;_WINSOCK_DEPRECATED_NO_WARNINGS;PTW32_STATIC_LIB;USE_READER_THREAD;SIM_ASYNCH_IO;SIM_NEED_GIT_COMMIT_ID;HAVE_PCREPOSIX_H;PCRE_STATIC;HAVE_SLIRP_NETWORK;USE_SIMH_SLIRP_DEBUG"
|
||||||
MinimalRebuild="true"
|
MinimalRebuild="true"
|
||||||
BasicRuntimeChecks="0"
|
BasicRuntimeChecks="0"
|
||||||
RuntimeLibrary="1"
|
RuntimeLibrary="1"
|
||||||
|
@ -127,8 +127,8 @@
|
||||||
FavorSizeOrSpeed="1"
|
FavorSizeOrSpeed="1"
|
||||||
OmitFramePointers="true"
|
OmitFramePointers="true"
|
||||||
WholeProgramOptimization="true"
|
WholeProgramOptimization="true"
|
||||||
AdditionalIncludeDirectories="./;../;../VAX/;../pdp11/;"../../windows-build/winpcap/Wpdpack/Include";"../../windows-build/PCRE/include/";"../../windows-build/pthreads";../slirp;../slirp/simh;../slirp/simh/qemu;../slirp/simh/qemu/win32/include"
|
AdditionalIncludeDirectories="./;../;../VAX/;../pdp11/;"../../windows-build/winpcap/Wpdpack/Include";"../../windows-build/PCRE/include/";"../../windows-build/pthreads";../slirp;../slirp_glue;../slirp_glue/qemu;../slirp_glue/qemu/win32/include"
|
||||||
PreprocessorDefinitions="USE_INT64;USE_ADDR64;VM_VAX;VAX_780;USE_SHARED;_CRT_NONSTDC_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;_WINSOCK_DEPRECATED_NO_WARNINGS;PTW32_STATIC_LIB;USE_READER_THREAD;SIM_ASYNCH_IO;SIM_NEED_GIT_COMMIT_ID;HAVE_PCREPOSIX_H;PCRE_STATIC;HAVE_SLIRP_NETWORK"
|
PreprocessorDefinitions="USE_INT64;USE_ADDR64;VM_VAX;VAX_780;USE_SHARED;_CRT_NONSTDC_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;_WINSOCK_DEPRECATED_NO_WARNINGS;PTW32_STATIC_LIB;USE_READER_THREAD;SIM_ASYNCH_IO;SIM_NEED_GIT_COMMIT_ID;HAVE_PCREPOSIX_H;PCRE_STATIC;HAVE_SLIRP_NETWORK;USE_SIMH_SLIRP_DEBUG"
|
||||||
StringPooling="true"
|
StringPooling="true"
|
||||||
RuntimeLibrary="0"
|
RuntimeLibrary="0"
|
||||||
BufferSecurityCheck="false"
|
BufferSecurityCheck="false"
|
||||||
|
@ -415,7 +415,7 @@
|
||||||
>
|
>
|
||||||
</File>
|
</File>
|
||||||
<File
|
<File
|
||||||
RelativePath="..\slirp\simh\glib_qemu_stubs.c"
|
RelativePath="..\slirp_glue\glib_qemu_stubs.c"
|
||||||
>
|
>
|
||||||
</File>
|
</File>
|
||||||
<File
|
<File
|
||||||
|
@ -479,7 +479,7 @@
|
||||||
>
|
>
|
||||||
</File>
|
</File>
|
||||||
<File
|
<File
|
||||||
RelativePath="..\slirp\simh\sim_slirp.c"
|
RelativePath="..\slirp_glue\sim_slirp.c"
|
||||||
>
|
>
|
||||||
</File>
|
</File>
|
||||||
<File
|
<File
|
||||||
|
|
|
@ -41,8 +41,8 @@
|
||||||
<Tool
|
<Tool
|
||||||
Name="VCCLCompilerTool"
|
Name="VCCLCompilerTool"
|
||||||
Optimization="0"
|
Optimization="0"
|
||||||
AdditionalIncludeDirectories="./;../;../VAX/;../pdp11/;"../../windows-build/winpcap/Wpdpack/Include";"../../windows-build/PCRE/include/";"../../windows-build/pthreads";../slirp;../slirp/simh;../slirp/simh/qemu;../slirp/simh/qemu/win32/include"
|
AdditionalIncludeDirectories="./;../;../VAX/;../pdp11/;"../../windows-build/winpcap/Wpdpack/Include";"../../windows-build/PCRE/include/";"../../windows-build/pthreads";../slirp;../slirp_glue;../slirp_glue/qemu;../slirp_glue/qemu/win32/include"
|
||||||
PreprocessorDefinitions="USE_INT64;USE_ADDR64;VM_VAX;VAX_860;USE_SHARED;_CRT_NONSTDC_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;_WINSOCK_DEPRECATED_NO_WARNINGS;PTW32_STATIC_LIB;USE_READER_THREAD;SIM_ASYNCH_IO;SIM_NEED_GIT_COMMIT_ID;HAVE_PCREPOSIX_H;PCRE_STATIC;HAVE_SLIRP_NETWORK"
|
PreprocessorDefinitions="USE_INT64;USE_ADDR64;VM_VAX;VAX_860;USE_SHARED;_CRT_NONSTDC_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;_WINSOCK_DEPRECATED_NO_WARNINGS;PTW32_STATIC_LIB;USE_READER_THREAD;SIM_ASYNCH_IO;SIM_NEED_GIT_COMMIT_ID;HAVE_PCREPOSIX_H;PCRE_STATIC;HAVE_SLIRP_NETWORK;USE_SIMH_SLIRP_DEBUG"
|
||||||
MinimalRebuild="true"
|
MinimalRebuild="true"
|
||||||
BasicRuntimeChecks="0"
|
BasicRuntimeChecks="0"
|
||||||
RuntimeLibrary="1"
|
RuntimeLibrary="1"
|
||||||
|
@ -127,8 +127,8 @@
|
||||||
FavorSizeOrSpeed="1"
|
FavorSizeOrSpeed="1"
|
||||||
OmitFramePointers="true"
|
OmitFramePointers="true"
|
||||||
WholeProgramOptimization="true"
|
WholeProgramOptimization="true"
|
||||||
AdditionalIncludeDirectories="./;../;../VAX/;../pdp11/;"../../windows-build/winpcap/Wpdpack/Include";"../../windows-build/PCRE/include/";"../../windows-build/pthreads";../slirp;../slirp/simh;../slirp/simh/qemu;../slirp/simh/qemu/win32/include"
|
AdditionalIncludeDirectories="./;../;../VAX/;../pdp11/;"../../windows-build/winpcap/Wpdpack/Include";"../../windows-build/PCRE/include/";"../../windows-build/pthreads";../slirp;../slirp_glue;../slirp_glue/qemu;../slirp_glue/qemu/win32/include"
|
||||||
PreprocessorDefinitions="USE_INT64;USE_ADDR64;VM_VAX;VAX_860;USE_SHARED;_CRT_NONSTDC_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;_WINSOCK_DEPRECATED_NO_WARNINGS;PTW32_STATIC_LIB;USE_READER_THREAD;SIM_ASYNCH_IO;SIM_NEED_GIT_COMMIT_ID;HAVE_PCREPOSIX_H;PCRE_STATIC;HAVE_SLIRP_NETWORK"
|
PreprocessorDefinitions="USE_INT64;USE_ADDR64;VM_VAX;VAX_860;USE_SHARED;_CRT_NONSTDC_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;_WINSOCK_DEPRECATED_NO_WARNINGS;PTW32_STATIC_LIB;USE_READER_THREAD;SIM_ASYNCH_IO;SIM_NEED_GIT_COMMIT_ID;HAVE_PCREPOSIX_H;PCRE_STATIC;HAVE_SLIRP_NETWORK;USE_SIMH_SLIRP_DEBUG"
|
||||||
StringPooling="true"
|
StringPooling="true"
|
||||||
RuntimeLibrary="0"
|
RuntimeLibrary="0"
|
||||||
BufferSecurityCheck="false"
|
BufferSecurityCheck="false"
|
||||||
|
@ -411,7 +411,7 @@
|
||||||
>
|
>
|
||||||
</File>
|
</File>
|
||||||
<File
|
<File
|
||||||
RelativePath="..\slirp\simh\glib_qemu_stubs.c"
|
RelativePath="..\slirp_glue\glib_qemu_stubs.c"
|
||||||
>
|
>
|
||||||
</File>
|
</File>
|
||||||
<File
|
<File
|
||||||
|
@ -475,7 +475,7 @@
|
||||||
>
|
>
|
||||||
</File>
|
</File>
|
||||||
<File
|
<File
|
||||||
RelativePath="..\slirp\simh\sim_slirp.c"
|
RelativePath="..\slirp_glue\sim_slirp.c"
|
||||||
>
|
>
|
||||||
</File>
|
</File>
|
||||||
<File
|
<File
|
||||||
|
|
|
@ -41,8 +41,8 @@
|
||||||
<Tool
|
<Tool
|
||||||
Name="VCCLCompilerTool"
|
Name="VCCLCompilerTool"
|
||||||
Optimization="0"
|
Optimization="0"
|
||||||
AdditionalIncludeDirectories="./;../;../VAX/;../pdp11/;"../../windows-build/winpcap/Wpdpack/Include";"../../windows-build/PCRE/include/";"../../windows-build/pthreads";../slirp;../slirp/simh;../slirp/simh/qemu;../slirp/simh/qemu/win32/include"
|
AdditionalIncludeDirectories="./;../;../VAX/;../pdp11/;"../../windows-build/winpcap/Wpdpack/Include";"../../windows-build/PCRE/include/";"../../windows-build/pthreads";../slirp;../slirp_glue;../slirp_glue/qemu;../slirp_glue/qemu/win32/include"
|
||||||
PreprocessorDefinitions="USE_INT64;USE_ADDR64;VM_VAX;VAX_620;USE_SHARED;_CRT_NONSTDC_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;_WINSOCK_DEPRECATED_NO_WARNINGS;PTW32_STATIC_LIB;USE_READER_THREAD;SIM_ASYNCH_IO;SIM_NEED_GIT_COMMIT_ID;HAVE_PCREPOSIX_H;PCRE_STATIC;HAVE_SLIRP_NETWORK"
|
PreprocessorDefinitions="USE_INT64;USE_ADDR64;VM_VAX;VAX_620;USE_SHARED;_CRT_NONSTDC_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;_WINSOCK_DEPRECATED_NO_WARNINGS;PTW32_STATIC_LIB;USE_READER_THREAD;SIM_ASYNCH_IO;SIM_NEED_GIT_COMMIT_ID;HAVE_PCREPOSIX_H;PCRE_STATIC;HAVE_SLIRP_NETWORK;USE_SIMH_SLIRP_DEBUG"
|
||||||
KeepComments="false"
|
KeepComments="false"
|
||||||
MinimalRebuild="true"
|
MinimalRebuild="true"
|
||||||
BasicRuntimeChecks="0"
|
BasicRuntimeChecks="0"
|
||||||
|
@ -128,8 +128,8 @@
|
||||||
FavorSizeOrSpeed="1"
|
FavorSizeOrSpeed="1"
|
||||||
OmitFramePointers="true"
|
OmitFramePointers="true"
|
||||||
WholeProgramOptimization="true"
|
WholeProgramOptimization="true"
|
||||||
AdditionalIncludeDirectories="./;../;../VAX/;../pdp11/;"../../windows-build/winpcap/Wpdpack/Include";"../../windows-build/PCRE/include/";"../../windows-build/pthreads";../slirp;../slirp/simh;../slirp/simh/qemu;../slirp/simh/qemu/win32/include"
|
AdditionalIncludeDirectories="./;../;../VAX/;../pdp11/;"../../windows-build/winpcap/Wpdpack/Include";"../../windows-build/PCRE/include/";"../../windows-build/pthreads";../slirp;../slirp_glue;../slirp_glue/qemu;../slirp_glue/qemu/win32/include"
|
||||||
PreprocessorDefinitions="USE_INT64;USE_ADDR64;VM_VAX;VAX_620;USE_SHARED;_CRT_NONSTDC_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;_WINSOCK_DEPRECATED_NO_WARNINGS;PTW32_STATIC_LIB;USE_READER_THREAD;SIM_ASYNCH_IO;SIM_NEED_GIT_COMMIT_ID;HAVE_PCREPOSIX_H;PCRE_STATIC;HAVE_SLIRP_NETWORK"
|
PreprocessorDefinitions="USE_INT64;USE_ADDR64;VM_VAX;VAX_620;USE_SHARED;_CRT_NONSTDC_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;_WINSOCK_DEPRECATED_NO_WARNINGS;PTW32_STATIC_LIB;USE_READER_THREAD;SIM_ASYNCH_IO;SIM_NEED_GIT_COMMIT_ID;HAVE_PCREPOSIX_H;PCRE_STATIC;HAVE_SLIRP_NETWORK;USE_SIMH_SLIRP_DEBUG"
|
||||||
KeepComments="false"
|
KeepComments="false"
|
||||||
StringPooling="true"
|
StringPooling="true"
|
||||||
RuntimeLibrary="0"
|
RuntimeLibrary="0"
|
||||||
|
@ -405,7 +405,7 @@
|
||||||
>
|
>
|
||||||
</File>
|
</File>
|
||||||
<File
|
<File
|
||||||
RelativePath="..\slirp\simh\glib_qemu_stubs.c"
|
RelativePath="..\slirp_glue\glib_qemu_stubs.c"
|
||||||
>
|
>
|
||||||
</File>
|
</File>
|
||||||
<File
|
<File
|
||||||
|
@ -469,7 +469,7 @@
|
||||||
>
|
>
|
||||||
</File>
|
</File>
|
||||||
<File
|
<File
|
||||||
RelativePath="..\slirp\simh\sim_slirp.c"
|
RelativePath="..\slirp_glue\sim_slirp.c"
|
||||||
>
|
>
|
||||||
</File>
|
</File>
|
||||||
<File
|
<File
|
||||||
|
|
6
makefile
6
makefile
|
@ -653,8 +653,8 @@ ifeq ($(WIN32),) #*nix Environments (&& cygwin)
|
||||||
NETWORK_CCDEFS += -DUSE_NETWORK
|
NETWORK_CCDEFS += -DUSE_NETWORK
|
||||||
endif
|
endif
|
||||||
endif
|
endif
|
||||||
ifeq (slirp,$(shell if $(TEST) -e slirp/simh/sim_slirp.c; then echo slirp; fi))
|
ifeq (slirp,$(shell if $(TEST) -e slirp_glue/sim_slirp.c; then echo slirp; fi))
|
||||||
NETWORK_CCDEFS += -Islirp -Islirp/simh -Islirp/simh/qemu -DHAVE_SLIRP_NETWORK slirp/*.c slirp/simh/*.c
|
NETWORK_CCDEFS += -Islirp -Islirp_glue -Islirp_glue/qemu -DHAVE_SLIRP_NETWORK -DUSE_SIMH_SLIRP_DEBUG slirp/*.c slirp_glue/*.c
|
||||||
NETWORK_LAN_FEATURES += NAT(SLiRP)
|
NETWORK_LAN_FEATURES += NAT(SLiRP)
|
||||||
endif
|
endif
|
||||||
ifeq (,$(findstring USE_NETWORK,$(NETWORK_CCDEFS))$(findstring USE_SHARED,$(NETWORK_CCDEFS))$(findstring HAVE_VDE_NETWORK,$(NETWORK_CCDEFS)))
|
ifeq (,$(findstring USE_NETWORK,$(NETWORK_CCDEFS))$(findstring USE_SHARED,$(NETWORK_CCDEFS))$(findstring HAVE_VDE_NETWORK,$(NETWORK_CCDEFS)))
|
||||||
|
@ -802,7 +802,7 @@ else
|
||||||
$(info using libpcreposix: $(abspath ../windows-build/PCRE/lib/pcreposix.a) $(abspath ../windows-build/PCRE/include/pcreposix.h))
|
$(info using libpcreposix: $(abspath ../windows-build/PCRE/lib/pcreposix.a) $(abspath ../windows-build/PCRE/include/pcreposix.h))
|
||||||
endif
|
endif
|
||||||
ifeq (slirp,slirp)
|
ifeq (slirp,slirp)
|
||||||
NETWORK_OPT += -Islirp -Islirp/simh -Islirp/simh/qemu -DHAVE_SLIRP_NETWORK slirp/*.c slirp/simh/*.c -lIphlpapi
|
NETWORK_OPT += -Islirp -Islirp_glue -Islirp_glue/qemu -DHAVE_SLIRP_NETWORK -DUSE_SIMH_SLIRP_DEBUG slirp/*.c slirp_glue/*.c -lIphlpapi
|
||||||
NETWORK_LAN_FEATURES += NAT(SLiRP)
|
NETWORK_LAN_FEATURES += NAT(SLiRP)
|
||||||
endif
|
endif
|
||||||
endif
|
endif
|
||||||
|
|
|
@ -1,14 +1,14 @@
|
||||||
October 6, 2015
|
October 6, 2015
|
||||||
|
|
||||||
This version of slirp is a fork from QEMU Version 2.4.0.1 slirp implementation
|
This version of slirp is a fork from QEMU Version 2.4.0.1 slirp implementation
|
||||||
Taken from commit 474590efc51f262fb5d81ca417d510cb7fb7a914
|
Taken from commit 83c92b45140be773f0c5545dddea35a89db1ad03
|
||||||
in the qemu repository git://repo.or.cz/qemu/ar7.git
|
in the qemu repository git://git.qemu.orgu/qemu.git
|
||||||
|
|
||||||
The goal being to absolutely mininize changes from the base qemu provided code
|
The goal being to absolutely mininize changes from the base qemu provided code
|
||||||
so that the more active changes being done by the qemu folks can easily be
|
so that the more active changes being done by the qemu folks can easily be
|
||||||
adopted in the future by directly replacing the revised modules. This is
|
adopted in the future by directly replacing the revised modules. This is
|
||||||
achieved by careful manipulation of the include files provided in the
|
achieved by careful manipulation of the include files provided in the
|
||||||
slirp/qemu directory so that things are stubbed out locally and the minimal
|
../slirp_glue directory so that things are stubbed out locally and the minimal
|
||||||
capabilities needed for sim_ether integration are provided.
|
capabilities needed for sim_ether integration are provided.
|
||||||
|
|
||||||
Thanks to Fabrice Bellard.
|
Thanks to Fabrice Bellard.
|
||||||
|
|
|
@ -13,23 +13,7 @@
|
||||||
|
|
||||||
extern int slirp_debug;
|
extern int slirp_debug;
|
||||||
|
|
||||||
#if defined(HAVE_SLIRP_NETWORK) /* simh build indicator */
|
#ifndef USE_SIMH_SLIRP_DEBUG /* simh build indicator */
|
||||||
#include <stdio.h>
|
|
||||||
#define DEVICE void
|
|
||||||
|
|
||||||
extern void *slirp_dptr;
|
|
||||||
extern int slirp_dbit;
|
|
||||||
|
|
||||||
extern void _sim_debug (int dbits, DEVICE* dptr, const char* fmt, ...);
|
|
||||||
|
|
||||||
#define DEBUG_CALL(x) do {if (slirp_debug & DBG_CALL) { _sim_debug (slirp_dbit, slirp_dptr, "%s...\n", x); };} while (0)
|
|
||||||
#define DEBUG_ARG(x, y) do {if (slirp_debug & DBG_CALL) {_sim_debug (slirp_dbit, slirp_dptr, x, y); _sim_debug (slirp_dbit, slirp_dptr, "\n"); };} while (0)
|
|
||||||
#define DEBUG_ARGS(...) do {if (slirp_debug & DBG_CALL) { _sim_debug (slirp_dbit, slirp_dptr, ## __VA_ARGS__); };} while (0)
|
|
||||||
#define DEBUG_MISC(...) do {if (slirp_debug & DBG_MISC) { _sim_debug (slirp_dbit, slirp_dptr, ## __VA_ARGS__); };} while (0)
|
|
||||||
#define DEBUG_ERROR(...) do {if (slirp_debug & DBG_ERROR) { _sim_debug (slirp_dbit, slirp_dptr, ## __VA_ARGS__); };} while (0)
|
|
||||||
#define DPRINTF(fmt, ...) do {if (slirp_debug & DBG_CALL) { _sim_debug (slirp_dbit, slirp_dptr, fmt, ## __VA_ARGS__); };} while (0)
|
|
||||||
|
|
||||||
#else /* !defined(HAVE_SLIRP_NETWORK) */
|
|
||||||
|
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
|
|
||||||
|
@ -52,6 +36,24 @@ extern void _sim_debug (int dbits, DEVICE* dptr, const char* fmt, ...);
|
||||||
#define DPRINTF(fmt, ...) do {} while (0)
|
#define DPRINTF(fmt, ...) do {} while (0)
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#else /* defined(USE_SIMH_SLIRP_DEBUG) */
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
#define DEVICE void
|
||||||
|
|
||||||
|
extern void *slirp_dptr;
|
||||||
|
extern int slirp_dbit;
|
||||||
|
|
||||||
|
extern void _sim_debug (int dbits, DEVICE* dptr, const char* fmt, ...);
|
||||||
|
|
||||||
|
#define DEBUG_CALL(x) do {if (slirp_debug & DBG_CALL) { _sim_debug (slirp_dbit, slirp_dptr, "%s...\n", x); };} while (0)
|
||||||
|
#define DEBUG_ARG(x, y) do {if (slirp_debug & DBG_CALL) {_sim_debug (slirp_dbit, slirp_dptr, x, y); _sim_debug (slirp_dbit, slirp_dptr, "\n"); };} while (0)
|
||||||
|
#define DEBUG_ARGS(...) do {if (slirp_debug & DBG_CALL) { _sim_debug (slirp_dbit, slirp_dptr, ## __VA_ARGS__); };} while (0)
|
||||||
|
#define DEBUG_MISC(...) do {if (slirp_debug & DBG_MISC) { _sim_debug (slirp_dbit, slirp_dptr, ## __VA_ARGS__); };} while (0)
|
||||||
|
#define DEBUG_ERROR(...) do {if (slirp_debug & DBG_ERROR) { _sim_debug (slirp_dbit, slirp_dptr, ## __VA_ARGS__); };} while (0)
|
||||||
|
#define DPRINTF(fmt, ...) do {if (slirp_debug & DBG_CALL) { _sim_debug (slirp_dbit, slirp_dptr, fmt, ## __VA_ARGS__); };} while (0)
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -1,269 +0,0 @@
|
||||||
/*
|
|
||||||
* Simple interface for atomic operations.
|
|
||||||
*
|
|
||||||
* Copyright (C) 2013 Red Hat, Inc.
|
|
||||||
*
|
|
||||||
* Author: Paolo Bonzini <pbonzini@redhat.com>
|
|
||||||
*
|
|
||||||
* This work is licensed under the terms of the GNU GPL, version 2 or later.
|
|
||||||
* See the COPYING file in the top-level directory.
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef __QEMU_ATOMIC_H
|
|
||||||
#define __QEMU_ATOMIC_H 1
|
|
||||||
|
|
||||||
#include "qemu/compiler.h"
|
|
||||||
|
|
||||||
/* For C11 atomic ops */
|
|
||||||
|
|
||||||
/* Compiler barrier */
|
|
||||||
#define barrier() ({ asm volatile("" ::: "memory"); (void)0; })
|
|
||||||
|
|
||||||
#ifndef __ATOMIC_RELAXED
|
|
||||||
|
|
||||||
/*
|
|
||||||
* We use GCC builtin if it's available, as that can use mfence on
|
|
||||||
* 32-bit as well, e.g. if built with -march=pentium-m. However, on
|
|
||||||
* i386 the spec is buggy, and the implementation followed it until
|
|
||||||
* 4.3 (http://gcc.gnu.org/bugzilla/show_bug.cgi?id=36793).
|
|
||||||
*/
|
|
||||||
#if defined(__i386__) || defined(__x86_64__)
|
|
||||||
#if !QEMU_GNUC_PREREQ(4, 4)
|
|
||||||
#if defined __x86_64__
|
|
||||||
#define smp_mb() ({ asm volatile("mfence" ::: "memory"); (void)0; })
|
|
||||||
#else
|
|
||||||
#define smp_mb() ({ asm volatile("lock; addl $0,0(%%esp) " ::: "memory"); (void)0; })
|
|
||||||
#endif
|
|
||||||
#endif
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
#ifdef __alpha__
|
|
||||||
#define smp_read_barrier_depends() asm volatile("mb":::"memory")
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if defined(__i386__) || defined(__x86_64__) || defined(__s390x__)
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Because of the strongly ordered storage model, wmb() and rmb() are nops
|
|
||||||
* here (a compiler barrier only). QEMU doesn't do accesses to write-combining
|
|
||||||
* qemu memory or non-temporal load/stores from C code.
|
|
||||||
*/
|
|
||||||
#define smp_wmb() barrier()
|
|
||||||
#define smp_rmb() barrier()
|
|
||||||
|
|
||||||
/*
|
|
||||||
* __sync_lock_test_and_set() is documented to be an acquire barrier only,
|
|
||||||
* but it is a full barrier at the hardware level. Add a compiler barrier
|
|
||||||
* to make it a full barrier also at the compiler level.
|
|
||||||
*/
|
|
||||||
#define atomic_xchg(ptr, i) (barrier(), __sync_lock_test_and_set(ptr, i))
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Load/store with Java volatile semantics.
|
|
||||||
*/
|
|
||||||
#define atomic_mb_set(ptr, i) ((void)atomic_xchg(ptr, i))
|
|
||||||
|
|
||||||
#elif defined(_ARCH_PPC)
|
|
||||||
|
|
||||||
/*
|
|
||||||
* We use an eieio() for wmb() on powerpc. This assumes we don't
|
|
||||||
* need to order cacheable and non-cacheable stores with respect to
|
|
||||||
* each other.
|
|
||||||
*
|
|
||||||
* smp_mb has the same problem as on x86 for not-very-new GCC
|
|
||||||
* (http://patchwork.ozlabs.org/patch/126184/, Nov 2011).
|
|
||||||
*/
|
|
||||||
#define smp_wmb() ({ asm volatile("eieio" ::: "memory"); (void)0; })
|
|
||||||
#if defined(__powerpc64__)
|
|
||||||
#define smp_rmb() ({ asm volatile("lwsync" ::: "memory"); (void)0; })
|
|
||||||
#else
|
|
||||||
#define smp_rmb() ({ asm volatile("sync" ::: "memory"); (void)0; })
|
|
||||||
#endif
|
|
||||||
#define smp_mb() ({ asm volatile("sync" ::: "memory"); (void)0; })
|
|
||||||
|
|
||||||
#endif /* _ARCH_PPC */
|
|
||||||
|
|
||||||
#endif /* C11 atomics */
|
|
||||||
|
|
||||||
/*
|
|
||||||
* For (host) platforms we don't have explicit barrier definitions
|
|
||||||
* for, we use the gcc __sync_synchronize() primitive to generate a
|
|
||||||
* full barrier. This should be safe on all platforms, though it may
|
|
||||||
* be overkill for smp_wmb() and smp_rmb().
|
|
||||||
*/
|
|
||||||
#ifndef smp_mb
|
|
||||||
#define smp_mb() __sync_synchronize()
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifndef smp_wmb
|
|
||||||
#ifdef __ATOMIC_RELEASE
|
|
||||||
/* __atomic_thread_fence does not include a compiler barrier; instead,
|
|
||||||
* the barrier is part of __atomic_load/__atomic_store's "volatile-like"
|
|
||||||
* semantics. If smp_wmb() is a no-op, absence of the barrier means that
|
|
||||||
* the compiler is free to reorder stores on each side of the barrier.
|
|
||||||
* Add one here, and similarly in smp_rmb() and smp_read_barrier_depends().
|
|
||||||
*/
|
|
||||||
#define smp_wmb() ({ barrier(); __atomic_thread_fence(__ATOMIC_RELEASE); barrier(); })
|
|
||||||
#else
|
|
||||||
#define smp_wmb() __sync_synchronize()
|
|
||||||
#endif
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifndef smp_rmb
|
|
||||||
#ifdef __ATOMIC_ACQUIRE
|
|
||||||
#define smp_rmb() ({ barrier(); __atomic_thread_fence(__ATOMIC_ACQUIRE); barrier(); })
|
|
||||||
#else
|
|
||||||
#define smp_rmb() __sync_synchronize()
|
|
||||||
#endif
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifndef smp_read_barrier_depends
|
|
||||||
#ifdef __ATOMIC_CONSUME
|
|
||||||
#define smp_read_barrier_depends() ({ barrier(); __atomic_thread_fence(__ATOMIC_CONSUME); barrier(); })
|
|
||||||
#else
|
|
||||||
#define smp_read_barrier_depends() barrier()
|
|
||||||
#endif
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifndef atomic_read
|
|
||||||
#define atomic_read(ptr) (*(__typeof__(*ptr) volatile*) (ptr))
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifndef atomic_set
|
|
||||||
#define atomic_set(ptr, i) ((*(__typeof__(*ptr) volatile*) (ptr)) = (i))
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/**
|
|
||||||
* atomic_rcu_read - reads a RCU-protected pointer to a local variable
|
|
||||||
* into a RCU read-side critical section. The pointer can later be safely
|
|
||||||
* dereferenced within the critical section.
|
|
||||||
*
|
|
||||||
* This ensures that the pointer copy is invariant thorough the whole critical
|
|
||||||
* section.
|
|
||||||
*
|
|
||||||
* Inserts memory barriers on architectures that require them (currently only
|
|
||||||
* Alpha) and documents which pointers are protected by RCU.
|
|
||||||
*
|
|
||||||
* Unless the __ATOMIC_CONSUME memory order is available, atomic_rcu_read also
|
|
||||||
* includes a compiler barrier to ensure that value-speculative optimizations
|
|
||||||
* (e.g. VSS: Value Speculation Scheduling) does not perform the data read
|
|
||||||
* before the pointer read by speculating the value of the pointer. On new
|
|
||||||
* enough compilers, atomic_load takes care of such concern about
|
|
||||||
* dependency-breaking optimizations.
|
|
||||||
*
|
|
||||||
* Should match atomic_rcu_set(), atomic_xchg(), atomic_cmpxchg().
|
|
||||||
*/
|
|
||||||
#ifndef atomic_rcu_read
|
|
||||||
#ifdef __ATOMIC_CONSUME
|
|
||||||
#define atomic_rcu_read(ptr) ({ \
|
|
||||||
typeof(*ptr) _val; \
|
|
||||||
__atomic_load(ptr, &_val, __ATOMIC_CONSUME); \
|
|
||||||
_val; \
|
|
||||||
})
|
|
||||||
#else
|
|
||||||
#define atomic_rcu_read(ptr) ({ \
|
|
||||||
typeof(*ptr) _val = atomic_read(ptr); \
|
|
||||||
smp_read_barrier_depends(); \
|
|
||||||
_val; \
|
|
||||||
})
|
|
||||||
#endif
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/**
|
|
||||||
* atomic_rcu_set - assigns (publicizes) a pointer to a new data structure
|
|
||||||
* meant to be read by RCU read-side critical sections.
|
|
||||||
*
|
|
||||||
* Documents which pointers will be dereferenced by RCU read-side critical
|
|
||||||
* sections and adds the required memory barriers on architectures requiring
|
|
||||||
* them. It also makes sure the compiler does not reorder code initializing the
|
|
||||||
* data structure before its publication.
|
|
||||||
*
|
|
||||||
* Should match atomic_rcu_read().
|
|
||||||
*/
|
|
||||||
#ifndef atomic_rcu_set
|
|
||||||
#ifdef __ATOMIC_RELEASE
|
|
||||||
#define atomic_rcu_set(ptr, i) do { \
|
|
||||||
typeof(*ptr) _val = (i); \
|
|
||||||
__atomic_store(ptr, &_val, __ATOMIC_RELEASE); \
|
|
||||||
} while(0)
|
|
||||||
#else
|
|
||||||
#define atomic_rcu_set(ptr, i) do { \
|
|
||||||
smp_wmb(); \
|
|
||||||
atomic_set(ptr, i); \
|
|
||||||
} while (0)
|
|
||||||
#endif
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* These have the same semantics as Java volatile variables.
|
|
||||||
* See http://gee.cs.oswego.edu/dl/jmm/cookbook.html:
|
|
||||||
* "1. Issue a StoreStore barrier (wmb) before each volatile store."
|
|
||||||
* 2. Issue a StoreLoad barrier after each volatile store.
|
|
||||||
* Note that you could instead issue one before each volatile load, but
|
|
||||||
* this would be slower for typical programs using volatiles in which
|
|
||||||
* reads greatly outnumber writes. Alternatively, if available, you
|
|
||||||
* can implement volatile store as an atomic instruction (for example
|
|
||||||
* XCHG on x86) and omit the barrier. This may be more efficient if
|
|
||||||
* atomic instructions are cheaper than StoreLoad barriers.
|
|
||||||
* 3. Issue LoadLoad and LoadStore barriers after each volatile load."
|
|
||||||
*
|
|
||||||
* If you prefer to think in terms of "pairing" of memory barriers,
|
|
||||||
* an atomic_mb_read pairs with an atomic_mb_set.
|
|
||||||
*
|
|
||||||
* And for the few ia64 lovers that exist, an atomic_mb_read is a ld.acq,
|
|
||||||
* while an atomic_mb_set is a st.rel followed by a memory barrier.
|
|
||||||
*
|
|
||||||
* These are a bit weaker than __atomic_load/store with __ATOMIC_SEQ_CST
|
|
||||||
* (see docs/atomics.txt), and I'm not sure that __ATOMIC_ACQ_REL is enough.
|
|
||||||
* Just always use the barriers manually by the rules above.
|
|
||||||
*/
|
|
||||||
#ifndef atomic_mb_read
|
|
||||||
#define atomic_mb_read(ptr) ({ \
|
|
||||||
typeof(*ptr) _val = atomic_read(ptr); \
|
|
||||||
smp_rmb(); \
|
|
||||||
_val; \
|
|
||||||
})
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifndef atomic_mb_set
|
|
||||||
#define atomic_mb_set(ptr, i) do { \
|
|
||||||
smp_wmb(); \
|
|
||||||
atomic_set(ptr, i); \
|
|
||||||
smp_mb(); \
|
|
||||||
} while (0)
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifndef atomic_xchg
|
|
||||||
#if defined(__clang__)
|
|
||||||
#define atomic_xchg(ptr, i) __sync_swap(ptr, i)
|
|
||||||
#elif defined(__ATOMIC_SEQ_CST)
|
|
||||||
#define atomic_xchg(ptr, i) ({ \
|
|
||||||
typeof(*ptr) _new = (i), _old; \
|
|
||||||
__atomic_exchange(ptr, &_new, &_old, __ATOMIC_SEQ_CST); \
|
|
||||||
_old; \
|
|
||||||
})
|
|
||||||
#else
|
|
||||||
/* __sync_lock_test_and_set() is documented to be an acquire barrier only. */
|
|
||||||
#define atomic_xchg(ptr, i) (smp_mb(), __sync_lock_test_and_set(ptr, i))
|
|
||||||
#endif
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* Provide shorter names for GCC atomic builtins. */
|
|
||||||
#define atomic_fetch_inc(ptr) __sync_fetch_and_add(ptr, 1)
|
|
||||||
#define atomic_fetch_dec(ptr) __sync_fetch_and_add(ptr, -1)
|
|
||||||
#define atomic_fetch_add __sync_fetch_and_add
|
|
||||||
#define atomic_fetch_sub __sync_fetch_and_sub
|
|
||||||
#define atomic_fetch_and __sync_fetch_and_and
|
|
||||||
#define atomic_fetch_or __sync_fetch_and_or
|
|
||||||
#define atomic_cmpxchg __sync_val_compare_and_swap
|
|
||||||
|
|
||||||
/* And even shorter names that return void. */
|
|
||||||
#define atomic_inc(ptr) ((void) __sync_fetch_and_add(ptr, 1))
|
|
||||||
#define atomic_dec(ptr) ((void) __sync_fetch_and_add(ptr, -1))
|
|
||||||
#define atomic_add(ptr, n) ((void) __sync_fetch_and_add(ptr, n))
|
|
||||||
#define atomic_sub(ptr, n) ((void) __sync_fetch_and_sub(ptr, n))
|
|
||||||
#define atomic_and(ptr, n) ((void) __sync_fetch_and_and(ptr, n))
|
|
||||||
#define atomic_or(ptr, n) ((void) __sync_fetch_and_or(ptr, n))
|
|
||||||
|
|
||||||
#endif
|
|
|
@ -1,64 +0,0 @@
|
||||||
/*
|
|
||||||
* QEMU System Emulator block accounting
|
|
||||||
*
|
|
||||||
* Copyright (c) 2011 Christoph Hellwig
|
|
||||||
*
|
|
||||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
||||||
* of this software and associated documentation files (the "Software"), to deal
|
|
||||||
* in the Software without restriction, including without limitation the rights
|
|
||||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
||||||
* copies of the Software, and to permit persons to whom the Software is
|
|
||||||
* furnished to do so, subject to the following conditions:
|
|
||||||
*
|
|
||||||
* The above copyright notice and this permission notice shall be included in
|
|
||||||
* all copies or substantial portions of the Software.
|
|
||||||
*
|
|
||||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
||||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
||||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
|
||||||
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
||||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
||||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
|
||||||
* THE SOFTWARE.
|
|
||||||
*/
|
|
||||||
#ifndef BLOCK_ACCOUNTING_H
|
|
||||||
#define BLOCK_ACCOUNTING_H
|
|
||||||
|
|
||||||
#ifdef _MSC_VER
|
|
||||||
#include <win32/stdint.h>
|
|
||||||
#else
|
|
||||||
#include <stdint.h>
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#include "qemu/typedefs.h"
|
|
||||||
|
|
||||||
enum BlockAcctType {
|
|
||||||
BLOCK_ACCT_READ,
|
|
||||||
BLOCK_ACCT_WRITE,
|
|
||||||
BLOCK_ACCT_FLUSH,
|
|
||||||
BLOCK_MAX_IOTYPE,
|
|
||||||
};
|
|
||||||
|
|
||||||
typedef struct BlockAcctStats {
|
|
||||||
uint64_t nr_bytes[BLOCK_MAX_IOTYPE];
|
|
||||||
uint64_t nr_ops[BLOCK_MAX_IOTYPE];
|
|
||||||
uint64_t total_time_ns[BLOCK_MAX_IOTYPE];
|
|
||||||
uint64_t merged[BLOCK_MAX_IOTYPE];
|
|
||||||
uint64_t wr_highest_sector;
|
|
||||||
} BlockAcctStats;
|
|
||||||
|
|
||||||
typedef struct BlockAcctCookie {
|
|
||||||
int64_t bytes;
|
|
||||||
int64_t start_time_ns;
|
|
||||||
enum BlockAcctType type;
|
|
||||||
} BlockAcctCookie;
|
|
||||||
|
|
||||||
void block_acct_start(BlockAcctStats *stats, BlockAcctCookie *cookie,
|
|
||||||
int64_t bytes, enum BlockAcctType type);
|
|
||||||
void block_acct_done(BlockAcctStats *stats, BlockAcctCookie *cookie);
|
|
||||||
void block_acct_highest_sector(BlockAcctStats *stats, int64_t sector_num,
|
|
||||||
unsigned int nb_sectors);
|
|
||||||
void block_acct_merge_done(BlockAcctStats *stats, enum BlockAcctType type,
|
|
||||||
int num_requests);
|
|
||||||
|
|
||||||
#endif
|
|
|
@ -1,376 +0,0 @@
|
||||||
/*
|
|
||||||
* QEMU aio implementation
|
|
||||||
*
|
|
||||||
* Copyright IBM, Corp. 2008
|
|
||||||
*
|
|
||||||
* Authors:
|
|
||||||
* Anthony Liguori <aliguori@us.ibm.com>
|
|
||||||
*
|
|
||||||
* This work is licensed under the terms of the GNU GPL, version 2. See
|
|
||||||
* the COPYING file in the top-level directory.
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef QEMU_AIO_H
|
|
||||||
#define QEMU_AIO_H
|
|
||||||
|
|
||||||
#include "qemu/typedefs.h"
|
|
||||||
#include "qemu-common.h"
|
|
||||||
#include "qemu/queue.h"
|
|
||||||
#include "qemu/event_notifier.h"
|
|
||||||
#include "qemu/thread.h"
|
|
||||||
#include "qemu/rfifolock.h"
|
|
||||||
#include "qemu/timer.h"
|
|
||||||
|
|
||||||
typedef struct BlockAIOCB BlockAIOCB;
|
|
||||||
typedef void BlockCompletionFunc(void *opaque, int ret);
|
|
||||||
|
|
||||||
typedef struct AIOCBInfo {
|
|
||||||
void (*cancel_async)(BlockAIOCB *acb);
|
|
||||||
AioContext *(*get_aio_context)(BlockAIOCB *acb);
|
|
||||||
size_t aiocb_size;
|
|
||||||
} AIOCBInfo;
|
|
||||||
|
|
||||||
struct BlockAIOCB {
|
|
||||||
const AIOCBInfo *aiocb_info;
|
|
||||||
BlockDriverState *bs;
|
|
||||||
BlockCompletionFunc *cb;
|
|
||||||
void *opaque;
|
|
||||||
int refcnt;
|
|
||||||
};
|
|
||||||
|
|
||||||
void *qemu_aio_get(const AIOCBInfo *aiocb_info, BlockDriverState *bs,
|
|
||||||
BlockCompletionFunc *cb, void *opaque);
|
|
||||||
void qemu_aio_unref(void *p);
|
|
||||||
void qemu_aio_ref(void *p);
|
|
||||||
|
|
||||||
typedef struct AioHandler AioHandler;
|
|
||||||
typedef void QEMUBHFunc(void *opaque);
|
|
||||||
typedef void IOHandler(void *opaque);
|
|
||||||
|
|
||||||
struct AioContext {
|
|
||||||
GSource source;
|
|
||||||
|
|
||||||
/* Protects all fields from multi-threaded access */
|
|
||||||
RFifoLock lock;
|
|
||||||
|
|
||||||
/* The list of registered AIO handlers */
|
|
||||||
QLIST_HEAD(, AioHandler) aio_handlers;
|
|
||||||
|
|
||||||
/* This is a simple lock used to protect the aio_handlers list.
|
|
||||||
* Specifically, it's used to ensure that no callbacks are removed while
|
|
||||||
* we're walking and dispatching callbacks.
|
|
||||||
*/
|
|
||||||
int walking_handlers;
|
|
||||||
|
|
||||||
/* Used to avoid unnecessary event_notifier_set calls in aio_notify;
|
|
||||||
* accessed with atomic primitives. If this field is 0, everything
|
|
||||||
* (file descriptors, bottom halves, timers) will be re-evaluated
|
|
||||||
* before the next blocking poll(), thus the event_notifier_set call
|
|
||||||
* can be skipped. If it is non-zero, you may need to wake up a
|
|
||||||
* concurrent aio_poll or the glib main event loop, making
|
|
||||||
* event_notifier_set necessary.
|
|
||||||
*
|
|
||||||
* Bit 0 is reserved for GSource usage of the AioContext, and is 1
|
|
||||||
* between a call to aio_ctx_check and the next call to aio_ctx_dispatch.
|
|
||||||
* Bits 1-31 simply count the number of active calls to aio_poll
|
|
||||||
* that are in the prepare or poll phase.
|
|
||||||
*
|
|
||||||
* The GSource and aio_poll must use a different mechanism because
|
|
||||||
* there is no certainty that a call to GSource's prepare callback
|
|
||||||
* (via g_main_context_prepare) is indeed followed by check and
|
|
||||||
* dispatch. It's not clear whether this would be a bug, but let's
|
|
||||||
* play safe and allow it---it will just cause extra calls to
|
|
||||||
* event_notifier_set until the next call to dispatch.
|
|
||||||
*
|
|
||||||
* Instead, the aio_poll calls include both the prepare and the
|
|
||||||
* dispatch phase, hence a simple counter is enough for them.
|
|
||||||
*/
|
|
||||||
uint32_t notify_me;
|
|
||||||
|
|
||||||
/* lock to protect between bh's adders and deleter */
|
|
||||||
QemuMutex bh_lock;
|
|
||||||
|
|
||||||
/* Anchor of the list of Bottom Halves belonging to the context */
|
|
||||||
struct QEMUBH *first_bh;
|
|
||||||
|
|
||||||
/* A simple lock used to protect the first_bh list, and ensure that
|
|
||||||
* no callbacks are removed while we're walking and dispatching callbacks.
|
|
||||||
*/
|
|
||||||
int walking_bh;
|
|
||||||
|
|
||||||
/* Used by aio_notify.
|
|
||||||
*
|
|
||||||
* "notified" is used to avoid expensive event_notifier_test_and_clear
|
|
||||||
* calls. When it is clear, the EventNotifier is clear, or one thread
|
|
||||||
* is going to clear "notified" before processing more events. False
|
|
||||||
* positives are possible, i.e. "notified" could be set even though the
|
|
||||||
* EventNotifier is clear.
|
|
||||||
*
|
|
||||||
* Note that event_notifier_set *cannot* be optimized the same way. For
|
|
||||||
* more information on the problem that would result, see "#ifdef BUG2"
|
|
||||||
* in the docs/aio_notify_accept.promela formal model.
|
|
||||||
*/
|
|
||||||
bool notified;
|
|
||||||
EventNotifier notifier;
|
|
||||||
|
|
||||||
/* Scheduling this BH forces the event loop it iterate */
|
|
||||||
QEMUBH *notify_dummy_bh;
|
|
||||||
|
|
||||||
/* Thread pool for performing work and receiving completion callbacks */
|
|
||||||
struct ThreadPool *thread_pool;
|
|
||||||
|
|
||||||
/* TimerLists for calling timers - one per clock type */
|
|
||||||
QEMUTimerListGroup tlg;
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* aio_context_new: Allocate a new AioContext.
|
|
||||||
*
|
|
||||||
* AioContext provide a mini event-loop that can be waited on synchronously.
|
|
||||||
* They also provide bottom halves, a service to execute a piece of code
|
|
||||||
* as soon as possible.
|
|
||||||
*/
|
|
||||||
AioContext *aio_context_new(Error **errp);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* aio_context_ref:
|
|
||||||
* @ctx: The AioContext to operate on.
|
|
||||||
*
|
|
||||||
* Add a reference to an AioContext.
|
|
||||||
*/
|
|
||||||
void aio_context_ref(AioContext *ctx);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* aio_context_unref:
|
|
||||||
* @ctx: The AioContext to operate on.
|
|
||||||
*
|
|
||||||
* Drop a reference to an AioContext.
|
|
||||||
*/
|
|
||||||
void aio_context_unref(AioContext *ctx);
|
|
||||||
|
|
||||||
/* Take ownership of the AioContext. If the AioContext will be shared between
|
|
||||||
* threads, and a thread does not want to be interrupted, it will have to
|
|
||||||
* take ownership around calls to aio_poll(). Otherwise, aio_poll()
|
|
||||||
* automatically takes care of calling aio_context_acquire and
|
|
||||||
* aio_context_release.
|
|
||||||
*
|
|
||||||
* Access to timers and BHs from a thread that has not acquired AioContext
|
|
||||||
* is possible. Access to callbacks for now must be done while the AioContext
|
|
||||||
* is owned by the thread (FIXME).
|
|
||||||
*/
|
|
||||||
void aio_context_acquire(AioContext *ctx);
|
|
||||||
|
|
||||||
/* Relinquish ownership of the AioContext. */
|
|
||||||
void aio_context_release(AioContext *ctx);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* aio_bh_new: Allocate a new bottom half structure.
|
|
||||||
*
|
|
||||||
* Bottom halves are lightweight callbacks whose invocation is guaranteed
|
|
||||||
* to be wait-free, thread-safe and signal-safe. The #QEMUBH structure
|
|
||||||
* is opaque and must be allocated prior to its use.
|
|
||||||
*/
|
|
||||||
QEMUBH *aio_bh_new(AioContext *ctx, QEMUBHFunc *cb, void *opaque);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* aio_notify: Force processing of pending events.
|
|
||||||
*
|
|
||||||
* Similar to signaling a condition variable, aio_notify forces
|
|
||||||
* aio_wait to exit, so that the next call will re-examine pending events.
|
|
||||||
* The caller of aio_notify will usually call aio_wait again very soon,
|
|
||||||
* or go through another iteration of the GLib main loop. Hence, aio_notify
|
|
||||||
* also has the side effect of recalculating the sets of file descriptors
|
|
||||||
* that the main loop waits for.
|
|
||||||
*
|
|
||||||
* Calling aio_notify is rarely necessary, because for example scheduling
|
|
||||||
* a bottom half calls it already.
|
|
||||||
*/
|
|
||||||
void aio_notify(AioContext *ctx);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* aio_notify_accept: Acknowledge receiving an aio_notify.
|
|
||||||
*
|
|
||||||
* aio_notify() uses an EventNotifier in order to wake up a sleeping
|
|
||||||
* aio_poll() or g_main_context_iteration(). Calls to aio_notify() are
|
|
||||||
* usually rare, but the AioContext has to clear the EventNotifier on
|
|
||||||
* every aio_poll() or g_main_context_iteration() in order to avoid
|
|
||||||
* busy waiting. This event_notifier_test_and_clear() cannot be done
|
|
||||||
* using the usual aio_context_set_event_notifier(), because it must
|
|
||||||
* be done before processing all events (file descriptors, bottom halves,
|
|
||||||
* timers).
|
|
||||||
*
|
|
||||||
* aio_notify_accept() is an optimized event_notifier_test_and_clear()
|
|
||||||
* that is specific to an AioContext's notifier; it is used internally
|
|
||||||
* to clear the EventNotifier only if aio_notify() had been called.
|
|
||||||
*/
|
|
||||||
void aio_notify_accept(AioContext *ctx);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* aio_bh_poll: Poll bottom halves for an AioContext.
|
|
||||||
*
|
|
||||||
* These are internal functions used by the QEMU main loop.
|
|
||||||
* And notice that multiple occurrences of aio_bh_poll cannot
|
|
||||||
* be called concurrently
|
|
||||||
*/
|
|
||||||
int aio_bh_poll(AioContext *ctx);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* qemu_bh_schedule: Schedule a bottom half.
|
|
||||||
*
|
|
||||||
* Scheduling a bottom half interrupts the main loop and causes the
|
|
||||||
* execution of the callback that was passed to qemu_bh_new.
|
|
||||||
*
|
|
||||||
* Bottom halves that are scheduled from a bottom half handler are instantly
|
|
||||||
* invoked. This can create an infinite loop if a bottom half handler
|
|
||||||
* schedules itself.
|
|
||||||
*
|
|
||||||
* @bh: The bottom half to be scheduled.
|
|
||||||
*/
|
|
||||||
void qemu_bh_schedule(QEMUBH *bh);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* qemu_bh_cancel: Cancel execution of a bottom half.
|
|
||||||
*
|
|
||||||
* Canceling execution of a bottom half undoes the effect of calls to
|
|
||||||
* qemu_bh_schedule without freeing its resources yet. While cancellation
|
|
||||||
* itself is also wait-free and thread-safe, it can of course race with the
|
|
||||||
* loop that executes bottom halves unless you are holding the iothread
|
|
||||||
* mutex. This makes it mostly useless if you are not holding the mutex.
|
|
||||||
*
|
|
||||||
* @bh: The bottom half to be canceled.
|
|
||||||
*/
|
|
||||||
void qemu_bh_cancel(QEMUBH *bh);
|
|
||||||
|
|
||||||
/**
|
|
||||||
*qemu_bh_delete: Cancel execution of a bottom half and free its resources.
|
|
||||||
*
|
|
||||||
* Deleting a bottom half frees the memory that was allocated for it by
|
|
||||||
* qemu_bh_new. It also implies canceling the bottom half if it was
|
|
||||||
* scheduled.
|
|
||||||
* This func is async. The bottom half will do the delete action at the finial
|
|
||||||
* end.
|
|
||||||
*
|
|
||||||
* @bh: The bottom half to be deleted.
|
|
||||||
*/
|
|
||||||
void qemu_bh_delete(QEMUBH *bh);
|
|
||||||
|
|
||||||
/* Return whether there are any pending callbacks from the GSource
|
|
||||||
* attached to the AioContext, before g_poll is invoked.
|
|
||||||
*
|
|
||||||
* This is used internally in the implementation of the GSource.
|
|
||||||
*/
|
|
||||||
bool aio_prepare(AioContext *ctx);
|
|
||||||
|
|
||||||
/* Return whether there are any pending callbacks from the GSource
|
|
||||||
* attached to the AioContext, after g_poll is invoked.
|
|
||||||
*
|
|
||||||
* This is used internally in the implementation of the GSource.
|
|
||||||
*/
|
|
||||||
bool aio_pending(AioContext *ctx);
|
|
||||||
|
|
||||||
/* Dispatch any pending callbacks from the GSource attached to the AioContext.
|
|
||||||
*
|
|
||||||
* This is used internally in the implementation of the GSource.
|
|
||||||
*/
|
|
||||||
bool aio_dispatch(AioContext *ctx);
|
|
||||||
|
|
||||||
/* Progress in completing AIO work to occur. This can issue new pending
|
|
||||||
* aio as a result of executing I/O completion or bh callbacks.
|
|
||||||
*
|
|
||||||
* Return whether any progress was made by executing AIO or bottom half
|
|
||||||
* handlers. If @blocking == true, this should always be true except
|
|
||||||
* if someone called aio_notify.
|
|
||||||
*
|
|
||||||
* If there are no pending bottom halves, but there are pending AIO
|
|
||||||
* operations, it may not be possible to make any progress without
|
|
||||||
* blocking. If @blocking is true, this function will wait until one
|
|
||||||
* or more AIO events have completed, to ensure something has moved
|
|
||||||
* before returning.
|
|
||||||
*/
|
|
||||||
bool aio_poll(AioContext *ctx, bool blocking);
|
|
||||||
|
|
||||||
/* Register a file descriptor and associated callbacks. Behaves very similarly
|
|
||||||
* to qemu_set_fd_handler. Unlike qemu_set_fd_handler, these callbacks will
|
|
||||||
* be invoked when using aio_poll().
|
|
||||||
*
|
|
||||||
* Code that invokes AIO completion functions should rely on this function
|
|
||||||
* instead of qemu_set_fd_handler[2].
|
|
||||||
*/
|
|
||||||
void aio_set_fd_handler(AioContext *ctx,
|
|
||||||
int fd,
|
|
||||||
IOHandler *io_read,
|
|
||||||
IOHandler *io_write,
|
|
||||||
void *opaque);
|
|
||||||
|
|
||||||
/* Register an event notifier and associated callbacks. Behaves very similarly
|
|
||||||
* to event_notifier_set_handler. Unlike event_notifier_set_handler, these callbacks
|
|
||||||
* will be invoked when using aio_poll().
|
|
||||||
*
|
|
||||||
* Code that invokes AIO completion functions should rely on this function
|
|
||||||
* instead of event_notifier_set_handler.
|
|
||||||
*/
|
|
||||||
void aio_set_event_notifier(AioContext *ctx,
|
|
||||||
EventNotifier *notifier,
|
|
||||||
EventNotifierHandler *io_read);
|
|
||||||
|
|
||||||
/* Return a GSource that lets the main loop poll the file descriptors attached
|
|
||||||
* to this AioContext.
|
|
||||||
*/
|
|
||||||
GSource *aio_get_g_source(AioContext *ctx);
|
|
||||||
|
|
||||||
/* Return the ThreadPool bound to this AioContext */
|
|
||||||
struct ThreadPool *aio_get_thread_pool(AioContext *ctx);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* aio_timer_new:
|
|
||||||
* @ctx: the aio context
|
|
||||||
* @type: the clock type
|
|
||||||
* @scale: the scale
|
|
||||||
* @cb: the callback to call on timer expiry
|
|
||||||
* @opaque: the opaque pointer to pass to the callback
|
|
||||||
*
|
|
||||||
* Allocate a new timer attached to the context @ctx.
|
|
||||||
* The function is responsible for memory allocation.
|
|
||||||
*
|
|
||||||
* The preferred interface is aio_timer_init. Use that
|
|
||||||
* unless you really need dynamic memory allocation.
|
|
||||||
*
|
|
||||||
* Returns: a pointer to the new timer
|
|
||||||
*/
|
|
||||||
static inline QEMUTimer *aio_timer_new(AioContext *ctx, QEMUClockType type,
|
|
||||||
int scale,
|
|
||||||
QEMUTimerCB *cb, void *opaque)
|
|
||||||
{
|
|
||||||
return timer_new_tl(ctx->tlg.tl[type], scale, cb, opaque);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* aio_timer_init:
|
|
||||||
* @ctx: the aio context
|
|
||||||
* @ts: the timer
|
|
||||||
* @type: the clock type
|
|
||||||
* @scale: the scale
|
|
||||||
* @cb: the callback to call on timer expiry
|
|
||||||
* @opaque: the opaque pointer to pass to the callback
|
|
||||||
*
|
|
||||||
* Initialise a new timer attached to the context @ctx.
|
|
||||||
* The caller is responsible for memory allocation.
|
|
||||||
*/
|
|
||||||
static inline void aio_timer_init(AioContext *ctx,
|
|
||||||
QEMUTimer *ts, QEMUClockType type,
|
|
||||||
int scale,
|
|
||||||
QEMUTimerCB *cb, void *opaque)
|
|
||||||
{
|
|
||||||
timer_init_tl(ts, ctx->tlg.tl[type], scale, cb, opaque);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* aio_compute_timeout:
|
|
||||||
* @ctx: the aio context
|
|
||||||
*
|
|
||||||
* Compute the timeout that a blocking aio_poll should use.
|
|
||||||
*/
|
|
||||||
int64_t aio_compute_timeout(AioContext *ctx);
|
|
||||||
|
|
||||||
#endif
|
|
|
@ -1,619 +0,0 @@
|
||||||
#ifndef BLOCK_H
|
|
||||||
#define BLOCK_H
|
|
||||||
|
|
||||||
#include "block/aio.h"
|
|
||||||
#include "qemu-common.h"
|
|
||||||
#include "qemu/option.h"
|
|
||||||
#include "block/coroutine.h"
|
|
||||||
#include "block/accounting.h"
|
|
||||||
#include "qapi/qmp/qobject.h"
|
|
||||||
#include "qapi-types.h"
|
|
||||||
|
|
||||||
/* block.c */
|
|
||||||
typedef struct BlockDriver BlockDriver;
|
|
||||||
typedef struct BlockJob BlockJob;
|
|
||||||
typedef struct BdrvChild BdrvChild;
|
|
||||||
typedef struct BdrvChildRole BdrvChildRole;
|
|
||||||
|
|
||||||
typedef struct BlockDriverInfo {
|
|
||||||
/* in bytes, 0 if irrelevant */
|
|
||||||
int cluster_size;
|
|
||||||
/* offset at which the VM state can be saved (0 if not possible) */
|
|
||||||
int64_t vm_state_offset;
|
|
||||||
bool is_dirty;
|
|
||||||
/*
|
|
||||||
* True if unallocated blocks read back as zeroes. This is equivalent
|
|
||||||
* to the LBPRZ flag in the SCSI logical block provisioning page.
|
|
||||||
*/
|
|
||||||
bool unallocated_blocks_are_zero;
|
|
||||||
/*
|
|
||||||
* True if the driver can optimize writing zeroes by unmapping
|
|
||||||
* sectors. This is equivalent to the BLKDISCARDZEROES ioctl in Linux
|
|
||||||
* with the difference that in qemu a discard is allowed to silently
|
|
||||||
* fail. Therefore we have to use bdrv_write_zeroes with the
|
|
||||||
* BDRV_REQ_MAY_UNMAP flag for an optimized zero write with unmapping.
|
|
||||||
* After this call the driver has to guarantee that the contents read
|
|
||||||
* back as zero. It is additionally required that the block device is
|
|
||||||
* opened with BDRV_O_UNMAP flag for this to work.
|
|
||||||
*/
|
|
||||||
bool can_write_zeroes_with_unmap;
|
|
||||||
/*
|
|
||||||
* True if this block driver only supports compressed writes
|
|
||||||
*/
|
|
||||||
bool needs_compressed_writes;
|
|
||||||
} BlockDriverInfo;
|
|
||||||
|
|
||||||
typedef struct BlockFragInfo {
|
|
||||||
uint64_t allocated_clusters;
|
|
||||||
uint64_t total_clusters;
|
|
||||||
uint64_t fragmented_clusters;
|
|
||||||
uint64_t compressed_clusters;
|
|
||||||
} BlockFragInfo;
|
|
||||||
|
|
||||||
typedef enum {
|
|
||||||
BDRV_REQ_COPY_ON_READ = 0x1,
|
|
||||||
BDRV_REQ_ZERO_WRITE = 0x2,
|
|
||||||
/* The BDRV_REQ_MAY_UNMAP flag is used to indicate that the block driver
|
|
||||||
* is allowed to optimize a write zeroes request by unmapping (discarding)
|
|
||||||
* blocks if it is guaranteed that the result will read back as
|
|
||||||
* zeroes. The flag is only passed to the driver if the block device is
|
|
||||||
* opened with BDRV_O_UNMAP.
|
|
||||||
*/
|
|
||||||
BDRV_REQ_MAY_UNMAP = 0x4,
|
|
||||||
} BdrvRequestFlags;
|
|
||||||
|
|
||||||
typedef struct BlockSizes {
|
|
||||||
uint32_t phys;
|
|
||||||
uint32_t log;
|
|
||||||
} BlockSizes;
|
|
||||||
|
|
||||||
typedef struct HDGeometry {
|
|
||||||
uint32_t heads;
|
|
||||||
uint32_t sectors;
|
|
||||||
uint32_t cylinders;
|
|
||||||
} HDGeometry;
|
|
||||||
|
|
||||||
#define BDRV_O_RDWR 0x0002
|
|
||||||
#define BDRV_O_SNAPSHOT 0x0008 /* open the file read only and save writes in a snapshot */
|
|
||||||
#define BDRV_O_TEMPORARY 0x0010 /* delete the file after use */
|
|
||||||
#define BDRV_O_NOCACHE 0x0020 /* do not use the host page cache */
|
|
||||||
#define BDRV_O_CACHE_WB 0x0040 /* use write-back caching */
|
|
||||||
#define BDRV_O_NATIVE_AIO 0x0080 /* use native AIO instead of the thread pool */
|
|
||||||
#define BDRV_O_NO_BACKING 0x0100 /* don't open the backing file */
|
|
||||||
#define BDRV_O_NO_FLUSH 0x0200 /* disable flushing on this disk */
|
|
||||||
#define BDRV_O_COPY_ON_READ 0x0400 /* copy read backing sectors into image */
|
|
||||||
#define BDRV_O_INCOMING 0x0800 /* consistency hint for incoming migration */
|
|
||||||
#define BDRV_O_CHECK 0x1000 /* open solely for consistency check */
|
|
||||||
#define BDRV_O_ALLOW_RDWR 0x2000 /* allow reopen to change from r/o to r/w */
|
|
||||||
#define BDRV_O_UNMAP 0x4000 /* execute guest UNMAP/TRIM operations */
|
|
||||||
#define BDRV_O_PROTOCOL 0x8000 /* if no block driver is explicitly given:
|
|
||||||
select an appropriate protocol driver,
|
|
||||||
ignoring the format layer */
|
|
||||||
|
|
||||||
#define BDRV_O_CACHE_MASK (BDRV_O_NOCACHE | BDRV_O_CACHE_WB | BDRV_O_NO_FLUSH)
|
|
||||||
|
|
||||||
|
|
||||||
/* Option names of options parsed by the block layer */
|
|
||||||
|
|
||||||
#define BDRV_OPT_CACHE_WB "cache.writeback"
|
|
||||||
#define BDRV_OPT_CACHE_DIRECT "cache.direct"
|
|
||||||
#define BDRV_OPT_CACHE_NO_FLUSH "cache.no-flush"
|
|
||||||
|
|
||||||
|
|
||||||
#define BDRV_SECTOR_BITS 9
|
|
||||||
#define BDRV_SECTOR_SIZE (1ULL << BDRV_SECTOR_BITS)
|
|
||||||
#define BDRV_SECTOR_MASK ~(BDRV_SECTOR_SIZE - 1)
|
|
||||||
|
|
||||||
#define BDRV_REQUEST_MAX_SECTORS MIN(SIZE_MAX >> BDRV_SECTOR_BITS, \
|
|
||||||
INT_MAX >> BDRV_SECTOR_BITS)
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Allocation status flags
|
|
||||||
* BDRV_BLOCK_DATA: data is read from bs->file or another file
|
|
||||||
* BDRV_BLOCK_ZERO: sectors read as zero
|
|
||||||
* BDRV_BLOCK_OFFSET_VALID: sector stored in bs->file as raw data
|
|
||||||
* BDRV_BLOCK_ALLOCATED: the content of the block is determined by this
|
|
||||||
* layer (as opposed to the backing file)
|
|
||||||
* BDRV_BLOCK_RAW: used internally to indicate that the request
|
|
||||||
* was answered by the raw driver and that one
|
|
||||||
* should look in bs->file directly.
|
|
||||||
*
|
|
||||||
* If BDRV_BLOCK_OFFSET_VALID is set, bits 9-62 represent the offset in
|
|
||||||
* bs->file where sector data can be read from as raw data.
|
|
||||||
*
|
|
||||||
* DATA == 0 && ZERO == 0 means that data is read from backing_hd if present.
|
|
||||||
*
|
|
||||||
* DATA ZERO OFFSET_VALID
|
|
||||||
* t t t sectors read as zero, bs->file is zero at offset
|
|
||||||
* t f t sectors read as valid from bs->file at offset
|
|
||||||
* f t t sectors preallocated, read as zero, bs->file not
|
|
||||||
* necessarily zero at offset
|
|
||||||
* f f t sectors preallocated but read from backing_hd,
|
|
||||||
* bs->file contains garbage at offset
|
|
||||||
* t t f sectors preallocated, read as zero, unknown offset
|
|
||||||
* t f f sectors read from unknown file or offset
|
|
||||||
* f t f not allocated or unknown offset, read as zero
|
|
||||||
* f f f not allocated or unknown offset, read from backing_hd
|
|
||||||
*/
|
|
||||||
#define BDRV_BLOCK_DATA 0x01
|
|
||||||
#define BDRV_BLOCK_ZERO 0x02
|
|
||||||
#define BDRV_BLOCK_OFFSET_VALID 0x04
|
|
||||||
#define BDRV_BLOCK_RAW 0x08
|
|
||||||
#define BDRV_BLOCK_ALLOCATED 0x10
|
|
||||||
#define BDRV_BLOCK_OFFSET_MASK BDRV_SECTOR_MASK
|
|
||||||
|
|
||||||
typedef QSIMPLEQ_HEAD(BlockReopenQueue, BlockReopenQueueEntry) BlockReopenQueue;
|
|
||||||
|
|
||||||
typedef struct BDRVReopenState {
|
|
||||||
BlockDriverState *bs;
|
|
||||||
int flags;
|
|
||||||
QDict *options;
|
|
||||||
void *opaque;
|
|
||||||
} BDRVReopenState;
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Block operation types
|
|
||||||
*/
|
|
||||||
typedef enum BlockOpType {
|
|
||||||
BLOCK_OP_TYPE_BACKUP_SOURCE,
|
|
||||||
BLOCK_OP_TYPE_BACKUP_TARGET,
|
|
||||||
BLOCK_OP_TYPE_CHANGE,
|
|
||||||
BLOCK_OP_TYPE_COMMIT_SOURCE,
|
|
||||||
BLOCK_OP_TYPE_COMMIT_TARGET,
|
|
||||||
BLOCK_OP_TYPE_DATAPLANE,
|
|
||||||
BLOCK_OP_TYPE_DRIVE_DEL,
|
|
||||||
BLOCK_OP_TYPE_EJECT,
|
|
||||||
BLOCK_OP_TYPE_EXTERNAL_SNAPSHOT,
|
|
||||||
BLOCK_OP_TYPE_INTERNAL_SNAPSHOT,
|
|
||||||
BLOCK_OP_TYPE_INTERNAL_SNAPSHOT_DELETE,
|
|
||||||
BLOCK_OP_TYPE_MIRROR,
|
|
||||||
BLOCK_OP_TYPE_RESIZE,
|
|
||||||
BLOCK_OP_TYPE_STREAM,
|
|
||||||
BLOCK_OP_TYPE_REPLACE,
|
|
||||||
BLOCK_OP_TYPE_MAX,
|
|
||||||
} BlockOpType;
|
|
||||||
|
|
||||||
void bdrv_iostatus_enable(BlockDriverState *bs);
|
|
||||||
void bdrv_iostatus_reset(BlockDriverState *bs);
|
|
||||||
void bdrv_iostatus_disable(BlockDriverState *bs);
|
|
||||||
bool bdrv_iostatus_is_enabled(const BlockDriverState *bs);
|
|
||||||
void bdrv_iostatus_set_err(BlockDriverState *bs, int error);
|
|
||||||
void bdrv_info_print(Monitor *mon, const QObject *data);
|
|
||||||
void bdrv_info(Monitor *mon, QObject **ret_data);
|
|
||||||
void bdrv_stats_print(Monitor *mon, const QObject *data);
|
|
||||||
void bdrv_info_stats(Monitor *mon, QObject **ret_data);
|
|
||||||
|
|
||||||
/* disk I/O throttling */
|
|
||||||
void bdrv_io_limits_enable(BlockDriverState *bs, const char *group);
|
|
||||||
void bdrv_io_limits_disable(BlockDriverState *bs);
|
|
||||||
void bdrv_io_limits_update_group(BlockDriverState *bs, const char *group);
|
|
||||||
|
|
||||||
void bdrv_init(void);
|
|
||||||
void bdrv_init_with_whitelist(void);
|
|
||||||
BlockDriver *bdrv_find_protocol(const char *filename,
|
|
||||||
bool allow_protocol_prefix,
|
|
||||||
Error **errp);
|
|
||||||
BlockDriver *bdrv_find_format(const char *format_name);
|
|
||||||
int bdrv_create(BlockDriver *drv, const char* filename,
|
|
||||||
QemuOpts *opts, Error **errp);
|
|
||||||
int bdrv_create_file(const char *filename, QemuOpts *opts, Error **errp);
|
|
||||||
BlockDriverState *bdrv_new_root(void);
|
|
||||||
BlockDriverState *bdrv_new(void);
|
|
||||||
void bdrv_make_anon(BlockDriverState *bs);
|
|
||||||
void bdrv_swap(BlockDriverState *bs_new, BlockDriverState *bs_old);
|
|
||||||
void bdrv_append(BlockDriverState *bs_new, BlockDriverState *bs_top);
|
|
||||||
int bdrv_parse_cache_flags(const char *mode, int *flags);
|
|
||||||
int bdrv_parse_discard_flags(const char *mode, int *flags);
|
|
||||||
int bdrv_open_image(BlockDriverState **pbs, const char *filename,
|
|
||||||
QDict *options, const char *bdref_key,
|
|
||||||
BlockDriverState* parent, const BdrvChildRole *child_role,
|
|
||||||
bool allow_none, Error **errp);
|
|
||||||
BdrvChild *bdrv_open_child(const char *filename,
|
|
||||||
QDict *options, const char *bdref_key,
|
|
||||||
BlockDriverState* parent,
|
|
||||||
const BdrvChildRole *child_role,
|
|
||||||
bool allow_none, Error **errp);
|
|
||||||
void bdrv_set_backing_hd(BlockDriverState *bs, BlockDriverState *backing_hd);
|
|
||||||
int bdrv_open_backing_file(BlockDriverState *bs, QDict *options, Error **errp);
|
|
||||||
int bdrv_append_temp_snapshot(BlockDriverState *bs, int flags, Error **errp);
|
|
||||||
int bdrv_open(BlockDriverState **pbs, const char *filename,
|
|
||||||
const char *reference, QDict *options, int flags, Error **errp);
|
|
||||||
BlockReopenQueue *bdrv_reopen_queue(BlockReopenQueue *bs_queue,
|
|
||||||
BlockDriverState *bs,
|
|
||||||
QDict *options, int flags);
|
|
||||||
int bdrv_reopen_multiple(BlockReopenQueue *bs_queue, Error **errp);
|
|
||||||
int bdrv_reopen(BlockDriverState *bs, int bdrv_flags, Error **errp);
|
|
||||||
int bdrv_reopen_prepare(BDRVReopenState *reopen_state,
|
|
||||||
BlockReopenQueue *queue, Error **errp);
|
|
||||||
void bdrv_reopen_commit(BDRVReopenState *reopen_state);
|
|
||||||
void bdrv_reopen_abort(BDRVReopenState *reopen_state);
|
|
||||||
void bdrv_close(BlockDriverState *bs);
|
|
||||||
void bdrv_add_close_notifier(BlockDriverState *bs, Notifier *notify);
|
|
||||||
int bdrv_read(BlockDriverState *bs, int64_t sector_num,
|
|
||||||
uint8_t *buf, int nb_sectors);
|
|
||||||
int bdrv_read_unthrottled(BlockDriverState *bs, int64_t sector_num,
|
|
||||||
uint8_t *buf, int nb_sectors);
|
|
||||||
int bdrv_write(BlockDriverState *bs, int64_t sector_num,
|
|
||||||
const uint8_t *buf, int nb_sectors);
|
|
||||||
int bdrv_write_zeroes(BlockDriverState *bs, int64_t sector_num,
|
|
||||||
int nb_sectors, BdrvRequestFlags flags);
|
|
||||||
BlockAIOCB *bdrv_aio_write_zeroes(BlockDriverState *bs, int64_t sector_num,
|
|
||||||
int nb_sectors, BdrvRequestFlags flags,
|
|
||||||
BlockCompletionFunc *cb, void *opaque);
|
|
||||||
int bdrv_make_zero(BlockDriverState *bs, BdrvRequestFlags flags);
|
|
||||||
int bdrv_pread(BlockDriverState *bs, int64_t offset,
|
|
||||||
void *buf, int count);
|
|
||||||
int bdrv_pwrite(BlockDriverState *bs, int64_t offset,
|
|
||||||
const void *buf, int count);
|
|
||||||
int bdrv_pwritev(BlockDriverState *bs, int64_t offset, QEMUIOVector *qiov);
|
|
||||||
int bdrv_pwrite_sync(BlockDriverState *bs, int64_t offset,
|
|
||||||
const void *buf, int count);
|
|
||||||
int coroutine_fn bdrv_co_readv(BlockDriverState *bs, int64_t sector_num,
|
|
||||||
int nb_sectors, QEMUIOVector *qiov);
|
|
||||||
int coroutine_fn bdrv_co_copy_on_readv(BlockDriverState *bs,
|
|
||||||
int64_t sector_num, int nb_sectors, QEMUIOVector *qiov);
|
|
||||||
int coroutine_fn bdrv_co_writev(BlockDriverState *bs, int64_t sector_num,
|
|
||||||
int nb_sectors, QEMUIOVector *qiov);
|
|
||||||
/*
|
|
||||||
* Efficiently zero a region of the disk image. Note that this is a regular
|
|
||||||
* I/O request like read or write and should have a reasonable size. This
|
|
||||||
* function is not suitable for zeroing the entire image in a single request
|
|
||||||
* because it may allocate memory for the entire region.
|
|
||||||
*/
|
|
||||||
int coroutine_fn bdrv_co_write_zeroes(BlockDriverState *bs, int64_t sector_num,
|
|
||||||
int nb_sectors, BdrvRequestFlags flags);
|
|
||||||
BlockDriverState *bdrv_find_backing_image(BlockDriverState *bs,
|
|
||||||
const char *backing_file);
|
|
||||||
int bdrv_get_backing_file_depth(BlockDriverState *bs);
|
|
||||||
void bdrv_refresh_filename(BlockDriverState *bs);
|
|
||||||
int bdrv_truncate(BlockDriverState *bs, int64_t offset);
|
|
||||||
int64_t bdrv_nb_sectors(BlockDriverState *bs);
|
|
||||||
int64_t bdrv_getlength(BlockDriverState *bs);
|
|
||||||
int64_t bdrv_get_allocated_file_size(BlockDriverState *bs);
|
|
||||||
void bdrv_get_geometry(BlockDriverState *bs, uint64_t *nb_sectors_ptr);
|
|
||||||
void bdrv_refresh_limits(BlockDriverState *bs, Error **errp);
|
|
||||||
int bdrv_commit(BlockDriverState *bs);
|
|
||||||
int bdrv_commit_all(void);
|
|
||||||
int bdrv_change_backing_file(BlockDriverState *bs,
|
|
||||||
const char *backing_file, const char *backing_fmt);
|
|
||||||
void bdrv_register(BlockDriver *bdrv);
|
|
||||||
int bdrv_drop_intermediate(BlockDriverState *active, BlockDriverState *top,
|
|
||||||
BlockDriverState *base,
|
|
||||||
const char *backing_file_str);
|
|
||||||
BlockDriverState *bdrv_find_overlay(BlockDriverState *active,
|
|
||||||
BlockDriverState *bs);
|
|
||||||
BlockDriverState *bdrv_find_base(BlockDriverState *bs);
|
|
||||||
|
|
||||||
|
|
||||||
typedef struct BdrvCheckResult {
|
|
||||||
int corruptions;
|
|
||||||
int leaks;
|
|
||||||
int check_errors;
|
|
||||||
int corruptions_fixed;
|
|
||||||
int leaks_fixed;
|
|
||||||
int64_t image_end_offset;
|
|
||||||
BlockFragInfo bfi;
|
|
||||||
} BdrvCheckResult;
|
|
||||||
|
|
||||||
typedef enum {
|
|
||||||
BDRV_FIX_LEAKS = 1,
|
|
||||||
BDRV_FIX_ERRORS = 2,
|
|
||||||
} BdrvCheckMode;
|
|
||||||
|
|
||||||
int bdrv_check(BlockDriverState *bs, BdrvCheckResult *res, BdrvCheckMode fix);
|
|
||||||
|
|
||||||
/* The units of offset and total_work_size may be chosen arbitrarily by the
|
|
||||||
* block driver; total_work_size may change during the course of the amendment
|
|
||||||
* operation */
|
|
||||||
typedef void BlockDriverAmendStatusCB(BlockDriverState *bs, int64_t offset,
|
|
||||||
int64_t total_work_size);
|
|
||||||
int bdrv_amend_options(BlockDriverState *bs_new, QemuOpts *opts,
|
|
||||||
BlockDriverAmendStatusCB *status_cb);
|
|
||||||
|
|
||||||
/* external snapshots */
|
|
||||||
bool bdrv_recurse_is_first_non_filter(BlockDriverState *bs,
|
|
||||||
BlockDriverState *candidate);
|
|
||||||
bool bdrv_is_first_non_filter(BlockDriverState *candidate);
|
|
||||||
|
|
||||||
/* check if a named node can be replaced when doing drive-mirror */
|
|
||||||
BlockDriverState *check_to_replace_node(BlockDriverState *parent_bs,
|
|
||||||
const char *node_name, Error **errp);
|
|
||||||
|
|
||||||
/* async block I/O */
|
|
||||||
typedef void BlockDriverDirtyHandler(BlockDriverState *bs, int64_t sector,
|
|
||||||
int sector_num);
|
|
||||||
BlockAIOCB *bdrv_aio_readv(BlockDriverState *bs, int64_t sector_num,
|
|
||||||
QEMUIOVector *iov, int nb_sectors,
|
|
||||||
BlockCompletionFunc *cb, void *opaque);
|
|
||||||
BlockAIOCB *bdrv_aio_writev(BlockDriverState *bs, int64_t sector_num,
|
|
||||||
QEMUIOVector *iov, int nb_sectors,
|
|
||||||
BlockCompletionFunc *cb, void *opaque);
|
|
||||||
BlockAIOCB *bdrv_aio_flush(BlockDriverState *bs,
|
|
||||||
BlockCompletionFunc *cb, void *opaque);
|
|
||||||
BlockAIOCB *bdrv_aio_discard(BlockDriverState *bs,
|
|
||||||
int64_t sector_num, int nb_sectors,
|
|
||||||
BlockCompletionFunc *cb, void *opaque);
|
|
||||||
void bdrv_aio_cancel(BlockAIOCB *acb);
|
|
||||||
void bdrv_aio_cancel_async(BlockAIOCB *acb);
|
|
||||||
|
|
||||||
typedef struct BlockRequest {
|
|
||||||
/* Fields to be filled by multiwrite caller */
|
|
||||||
int64_t sector;
|
|
||||||
int nb_sectors;
|
|
||||||
int flags;
|
|
||||||
QEMUIOVector *qiov;
|
|
||||||
BlockCompletionFunc *cb;
|
|
||||||
void *opaque;
|
|
||||||
|
|
||||||
/* Filled by multiwrite implementation */
|
|
||||||
int error;
|
|
||||||
} BlockRequest;
|
|
||||||
|
|
||||||
int bdrv_aio_multiwrite(BlockDriverState *bs, BlockRequest *reqs,
|
|
||||||
int num_reqs);
|
|
||||||
|
|
||||||
/* sg packet commands */
|
|
||||||
int bdrv_ioctl(BlockDriverState *bs, unsigned long int req, void *buf);
|
|
||||||
BlockAIOCB *bdrv_aio_ioctl(BlockDriverState *bs,
|
|
||||||
unsigned long int req, void *buf,
|
|
||||||
BlockCompletionFunc *cb, void *opaque);
|
|
||||||
|
|
||||||
/* Invalidate any cached metadata used by image formats */
|
|
||||||
void bdrv_invalidate_cache(BlockDriverState *bs, Error **errp);
|
|
||||||
void bdrv_invalidate_cache_all(Error **errp);
|
|
||||||
|
|
||||||
/* Ensure contents are flushed to disk. */
|
|
||||||
int bdrv_flush(BlockDriverState *bs);
|
|
||||||
int coroutine_fn bdrv_co_flush(BlockDriverState *bs);
|
|
||||||
int bdrv_flush_all(void);
|
|
||||||
void bdrv_close_all(void);
|
|
||||||
void bdrv_drain(BlockDriverState *bs);
|
|
||||||
void bdrv_drain_all(void);
|
|
||||||
|
|
||||||
int bdrv_discard(BlockDriverState *bs, int64_t sector_num, int nb_sectors);
|
|
||||||
int bdrv_co_discard(BlockDriverState *bs, int64_t sector_num, int nb_sectors);
|
|
||||||
int bdrv_has_zero_init_1(BlockDriverState *bs);
|
|
||||||
int bdrv_has_zero_init(BlockDriverState *bs);
|
|
||||||
bool bdrv_unallocated_blocks_are_zero(BlockDriverState *bs);
|
|
||||||
bool bdrv_can_write_zeroes_with_unmap(BlockDriverState *bs);
|
|
||||||
int64_t bdrv_get_block_status(BlockDriverState *bs, int64_t sector_num,
|
|
||||||
int nb_sectors, int *pnum);
|
|
||||||
int64_t bdrv_get_block_status_above(BlockDriverState *bs,
|
|
||||||
BlockDriverState *base,
|
|
||||||
int64_t sector_num,
|
|
||||||
int nb_sectors, int *pnum);
|
|
||||||
int bdrv_is_allocated(BlockDriverState *bs, int64_t sector_num, int nb_sectors,
|
|
||||||
int *pnum);
|
|
||||||
int bdrv_is_allocated_above(BlockDriverState *top, BlockDriverState *base,
|
|
||||||
int64_t sector_num, int nb_sectors, int *pnum);
|
|
||||||
|
|
||||||
void bdrv_set_on_error(BlockDriverState *bs, BlockdevOnError on_read_error,
|
|
||||||
BlockdevOnError on_write_error);
|
|
||||||
BlockdevOnError bdrv_get_on_error(BlockDriverState *bs, bool is_read);
|
|
||||||
BlockErrorAction bdrv_get_error_action(BlockDriverState *bs, bool is_read, int error);
|
|
||||||
void bdrv_error_action(BlockDriverState *bs, BlockErrorAction action,
|
|
||||||
bool is_read, int error);
|
|
||||||
int bdrv_is_read_only(BlockDriverState *bs);
|
|
||||||
int bdrv_is_sg(BlockDriverState *bs);
|
|
||||||
int bdrv_enable_write_cache(BlockDriverState *bs);
|
|
||||||
void bdrv_set_enable_write_cache(BlockDriverState *bs, bool wce);
|
|
||||||
int bdrv_is_inserted(BlockDriverState *bs);
|
|
||||||
int bdrv_media_changed(BlockDriverState *bs);
|
|
||||||
void bdrv_lock_medium(BlockDriverState *bs, bool locked);
|
|
||||||
void bdrv_eject(BlockDriverState *bs, bool eject_flag);
|
|
||||||
const char *bdrv_get_format_name(BlockDriverState *bs);
|
|
||||||
BlockDriverState *bdrv_find_node(const char *node_name);
|
|
||||||
BlockDeviceInfoList *bdrv_named_nodes_list(Error **errp);
|
|
||||||
BlockDriverState *bdrv_lookup_bs(const char *device,
|
|
||||||
const char *node_name,
|
|
||||||
Error **errp);
|
|
||||||
bool bdrv_chain_contains(BlockDriverState *top, BlockDriverState *base);
|
|
||||||
BlockDriverState *bdrv_next_node(BlockDriverState *bs);
|
|
||||||
BlockDriverState *bdrv_next(BlockDriverState *bs);
|
|
||||||
int bdrv_is_encrypted(BlockDriverState *bs);
|
|
||||||
int bdrv_key_required(BlockDriverState *bs);
|
|
||||||
int bdrv_set_key(BlockDriverState *bs, const char *key);
|
|
||||||
void bdrv_add_key(BlockDriverState *bs, const char *key, Error **errp);
|
|
||||||
int bdrv_query_missing_keys(void);
|
|
||||||
void bdrv_iterate_format(void (*it)(void *opaque, const char *name),
|
|
||||||
void *opaque);
|
|
||||||
const char *bdrv_get_node_name(const BlockDriverState *bs);
|
|
||||||
const char *bdrv_get_device_name(const BlockDriverState *bs);
|
|
||||||
const char *bdrv_get_device_or_node_name(const BlockDriverState *bs);
|
|
||||||
int bdrv_get_flags(BlockDriverState *bs);
|
|
||||||
int bdrv_write_compressed(BlockDriverState *bs, int64_t sector_num,
|
|
||||||
const uint8_t *buf, int nb_sectors);
|
|
||||||
int bdrv_get_info(BlockDriverState *bs, BlockDriverInfo *bdi);
|
|
||||||
ImageInfoSpecific *bdrv_get_specific_info(BlockDriverState *bs);
|
|
||||||
void bdrv_round_to_clusters(BlockDriverState *bs,
|
|
||||||
int64_t sector_num, int nb_sectors,
|
|
||||||
int64_t *cluster_sector_num,
|
|
||||||
int *cluster_nb_sectors);
|
|
||||||
|
|
||||||
const char *bdrv_get_encrypted_filename(BlockDriverState *bs);
|
|
||||||
void bdrv_get_backing_filename(BlockDriverState *bs,
|
|
||||||
char *filename, int filename_size);
|
|
||||||
void bdrv_get_full_backing_filename(BlockDriverState *bs,
|
|
||||||
char *dest, size_t sz, Error **errp);
|
|
||||||
void bdrv_get_full_backing_filename_from_filename(const char *backed,
|
|
||||||
const char *backing,
|
|
||||||
char *dest, size_t sz,
|
|
||||||
Error **errp);
|
|
||||||
int bdrv_is_snapshot(BlockDriverState *bs);
|
|
||||||
|
|
||||||
int path_has_protocol(const char *path);
|
|
||||||
int path_is_absolute(const char *path);
|
|
||||||
void path_combine(char *dest, int dest_size,
|
|
||||||
const char *base_path,
|
|
||||||
const char *filename);
|
|
||||||
|
|
||||||
int bdrv_writev_vmstate(BlockDriverState *bs, QEMUIOVector *qiov, int64_t pos);
|
|
||||||
int bdrv_save_vmstate(BlockDriverState *bs, const uint8_t *buf,
|
|
||||||
int64_t pos, int size);
|
|
||||||
|
|
||||||
int bdrv_load_vmstate(BlockDriverState *bs, uint8_t *buf,
|
|
||||||
int64_t pos, int size);
|
|
||||||
|
|
||||||
void bdrv_img_create(const char *filename, const char *fmt,
|
|
||||||
const char *base_filename, const char *base_fmt,
|
|
||||||
char *options, uint64_t img_size, int flags,
|
|
||||||
Error **errp, bool quiet);
|
|
||||||
|
|
||||||
/* Returns the alignment in bytes that is required so that no bounce buffer
|
|
||||||
* is required throughout the stack */
|
|
||||||
size_t bdrv_min_mem_align(BlockDriverState *bs);
|
|
||||||
/* Returns optimal alignment in bytes for bounce buffer */
|
|
||||||
size_t bdrv_opt_mem_align(BlockDriverState *bs);
|
|
||||||
void bdrv_set_guest_block_size(BlockDriverState *bs, int align);
|
|
||||||
void *qemu_blockalign(BlockDriverState *bs, size_t size);
|
|
||||||
void *qemu_blockalign0(BlockDriverState *bs, size_t size);
|
|
||||||
void *qemu_try_blockalign(BlockDriverState *bs, size_t size);
|
|
||||||
void *qemu_try_blockalign0(BlockDriverState *bs, size_t size);
|
|
||||||
bool bdrv_qiov_is_aligned(BlockDriverState *bs, QEMUIOVector *qiov);
|
|
||||||
|
|
||||||
struct HBitmapIter;
|
|
||||||
typedef struct BdrvDirtyBitmap BdrvDirtyBitmap;
|
|
||||||
BdrvDirtyBitmap *bdrv_create_dirty_bitmap(BlockDriverState *bs,
|
|
||||||
uint32_t granularity,
|
|
||||||
const char *name,
|
|
||||||
Error **errp);
|
|
||||||
int bdrv_dirty_bitmap_create_successor(BlockDriverState *bs,
|
|
||||||
BdrvDirtyBitmap *bitmap,
|
|
||||||
Error **errp);
|
|
||||||
BdrvDirtyBitmap *bdrv_dirty_bitmap_abdicate(BlockDriverState *bs,
|
|
||||||
BdrvDirtyBitmap *bitmap,
|
|
||||||
Error **errp);
|
|
||||||
BdrvDirtyBitmap *bdrv_reclaim_dirty_bitmap(BlockDriverState *bs,
|
|
||||||
BdrvDirtyBitmap *bitmap,
|
|
||||||
Error **errp);
|
|
||||||
BdrvDirtyBitmap *bdrv_find_dirty_bitmap(BlockDriverState *bs,
|
|
||||||
const char *name);
|
|
||||||
void bdrv_dirty_bitmap_make_anon(BdrvDirtyBitmap *bitmap);
|
|
||||||
void bdrv_release_dirty_bitmap(BlockDriverState *bs, BdrvDirtyBitmap *bitmap);
|
|
||||||
void bdrv_disable_dirty_bitmap(BdrvDirtyBitmap *bitmap);
|
|
||||||
void bdrv_enable_dirty_bitmap(BdrvDirtyBitmap *bitmap);
|
|
||||||
BlockDirtyInfoList *bdrv_query_dirty_bitmaps(BlockDriverState *bs);
|
|
||||||
uint32_t bdrv_get_default_bitmap_granularity(BlockDriverState *bs);
|
|
||||||
uint32_t bdrv_dirty_bitmap_granularity(BdrvDirtyBitmap *bitmap);
|
|
||||||
bool bdrv_dirty_bitmap_enabled(BdrvDirtyBitmap *bitmap);
|
|
||||||
bool bdrv_dirty_bitmap_frozen(BdrvDirtyBitmap *bitmap);
|
|
||||||
DirtyBitmapStatus bdrv_dirty_bitmap_status(BdrvDirtyBitmap *bitmap);
|
|
||||||
int bdrv_get_dirty(BlockDriverState *bs, BdrvDirtyBitmap *bitmap, int64_t sector);
|
|
||||||
void bdrv_set_dirty_bitmap(BdrvDirtyBitmap *bitmap,
|
|
||||||
int64_t cur_sector, int nr_sectors);
|
|
||||||
void bdrv_reset_dirty_bitmap(BdrvDirtyBitmap *bitmap,
|
|
||||||
int64_t cur_sector, int nr_sectors);
|
|
||||||
void bdrv_clear_dirty_bitmap(BdrvDirtyBitmap *bitmap);
|
|
||||||
void bdrv_dirty_iter_init(BdrvDirtyBitmap *bitmap, struct HBitmapIter *hbi);
|
|
||||||
void bdrv_set_dirty_iter(struct HBitmapIter *hbi, int64_t offset);
|
|
||||||
int64_t bdrv_get_dirty_count(BdrvDirtyBitmap *bitmap);
|
|
||||||
|
|
||||||
void bdrv_enable_copy_on_read(BlockDriverState *bs);
|
|
||||||
void bdrv_disable_copy_on_read(BlockDriverState *bs);
|
|
||||||
|
|
||||||
void bdrv_ref(BlockDriverState *bs);
|
|
||||||
void bdrv_unref(BlockDriverState *bs);
|
|
||||||
void bdrv_unref_child(BlockDriverState *parent, BdrvChild *child);
|
|
||||||
|
|
||||||
bool bdrv_op_is_blocked(BlockDriverState *bs, BlockOpType op, Error **errp);
|
|
||||||
void bdrv_op_block(BlockDriverState *bs, BlockOpType op, Error *reason);
|
|
||||||
void bdrv_op_unblock(BlockDriverState *bs, BlockOpType op, Error *reason);
|
|
||||||
void bdrv_op_block_all(BlockDriverState *bs, Error *reason);
|
|
||||||
void bdrv_op_unblock_all(BlockDriverState *bs, Error *reason);
|
|
||||||
bool bdrv_op_blocker_is_empty(BlockDriverState *bs);
|
|
||||||
|
|
||||||
typedef enum {
|
|
||||||
BLKDBG_L1_UPDATE,
|
|
||||||
|
|
||||||
BLKDBG_L1_GROW_ALLOC_TABLE,
|
|
||||||
BLKDBG_L1_GROW_WRITE_TABLE,
|
|
||||||
BLKDBG_L1_GROW_ACTIVATE_TABLE,
|
|
||||||
|
|
||||||
BLKDBG_L2_LOAD,
|
|
||||||
BLKDBG_L2_UPDATE,
|
|
||||||
BLKDBG_L2_UPDATE_COMPRESSED,
|
|
||||||
BLKDBG_L2_ALLOC_COW_READ,
|
|
||||||
BLKDBG_L2_ALLOC_WRITE,
|
|
||||||
|
|
||||||
BLKDBG_READ_AIO,
|
|
||||||
BLKDBG_READ_BACKING_AIO,
|
|
||||||
BLKDBG_READ_COMPRESSED,
|
|
||||||
|
|
||||||
BLKDBG_WRITE_AIO,
|
|
||||||
BLKDBG_WRITE_COMPRESSED,
|
|
||||||
|
|
||||||
BLKDBG_VMSTATE_LOAD,
|
|
||||||
BLKDBG_VMSTATE_SAVE,
|
|
||||||
|
|
||||||
BLKDBG_COW_READ,
|
|
||||||
BLKDBG_COW_WRITE,
|
|
||||||
|
|
||||||
BLKDBG_REFTABLE_LOAD,
|
|
||||||
BLKDBG_REFTABLE_GROW,
|
|
||||||
BLKDBG_REFTABLE_UPDATE,
|
|
||||||
|
|
||||||
BLKDBG_REFBLOCK_LOAD,
|
|
||||||
BLKDBG_REFBLOCK_UPDATE,
|
|
||||||
BLKDBG_REFBLOCK_UPDATE_PART,
|
|
||||||
BLKDBG_REFBLOCK_ALLOC,
|
|
||||||
BLKDBG_REFBLOCK_ALLOC_HOOKUP,
|
|
||||||
BLKDBG_REFBLOCK_ALLOC_WRITE,
|
|
||||||
BLKDBG_REFBLOCK_ALLOC_WRITE_BLOCKS,
|
|
||||||
BLKDBG_REFBLOCK_ALLOC_WRITE_TABLE,
|
|
||||||
BLKDBG_REFBLOCK_ALLOC_SWITCH_TABLE,
|
|
||||||
|
|
||||||
BLKDBG_CLUSTER_ALLOC,
|
|
||||||
BLKDBG_CLUSTER_ALLOC_BYTES,
|
|
||||||
BLKDBG_CLUSTER_FREE,
|
|
||||||
|
|
||||||
BLKDBG_FLUSH_TO_OS,
|
|
||||||
BLKDBG_FLUSH_TO_DISK,
|
|
||||||
|
|
||||||
BLKDBG_PWRITEV_RMW_HEAD,
|
|
||||||
BLKDBG_PWRITEV_RMW_AFTER_HEAD,
|
|
||||||
BLKDBG_PWRITEV_RMW_TAIL,
|
|
||||||
BLKDBG_PWRITEV_RMW_AFTER_TAIL,
|
|
||||||
BLKDBG_PWRITEV,
|
|
||||||
BLKDBG_PWRITEV_ZERO,
|
|
||||||
BLKDBG_PWRITEV_DONE,
|
|
||||||
|
|
||||||
BLKDBG_EMPTY_IMAGE_PREPARE,
|
|
||||||
|
|
||||||
BLKDBG_EVENT_MAX,
|
|
||||||
} BlkDebugEvent;
|
|
||||||
|
|
||||||
#define BLKDBG_EVENT(bs, evt) bdrv_debug_event(bs, evt)
|
|
||||||
void bdrv_debug_event(BlockDriverState *bs, BlkDebugEvent event);
|
|
||||||
|
|
||||||
int bdrv_debug_breakpoint(BlockDriverState *bs, const char *event,
|
|
||||||
const char *tag);
|
|
||||||
int bdrv_debug_remove_breakpoint(BlockDriverState *bs, const char *tag);
|
|
||||||
int bdrv_debug_resume(BlockDriverState *bs, const char *tag);
|
|
||||||
bool bdrv_debug_is_suspended(BlockDriverState *bs, const char *tag);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* bdrv_get_aio_context:
|
|
||||||
*
|
|
||||||
* Returns: the currently bound #AioContext
|
|
||||||
*/
|
|
||||||
AioContext *bdrv_get_aio_context(BlockDriverState *bs);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* bdrv_set_aio_context:
|
|
||||||
*
|
|
||||||
* Changes the #AioContext used for fd handlers, timers, and BHs by this
|
|
||||||
* BlockDriverState and all its children.
|
|
||||||
*
|
|
||||||
* This function must be called with iothread lock held.
|
|
||||||
*/
|
|
||||||
void bdrv_set_aio_context(BlockDriverState *bs, AioContext *new_context);
|
|
||||||
int bdrv_probe_blocksizes(BlockDriverState *bs, BlockSizes *bsz);
|
|
||||||
int bdrv_probe_geometry(BlockDriverState *bs, HDGeometry *geo);
|
|
||||||
|
|
||||||
void bdrv_io_plug(BlockDriverState *bs);
|
|
||||||
void bdrv_io_unplug(BlockDriverState *bs);
|
|
||||||
void bdrv_flush_io_queue(BlockDriverState *bs);
|
|
||||||
|
|
||||||
BlockAcctStats *bdrv_get_stats(BlockDriverState *bs);
|
|
||||||
|
|
||||||
#endif
|
|
|
@ -1,218 +0,0 @@
|
||||||
/*
|
|
||||||
* QEMU coroutine implementation
|
|
||||||
*
|
|
||||||
* Copyright IBM, Corp. 2011
|
|
||||||
*
|
|
||||||
* Authors:
|
|
||||||
* Stefan Hajnoczi <stefanha@linux.vnet.ibm.com>
|
|
||||||
* Kevin Wolf <kwolf@redhat.com>
|
|
||||||
*
|
|
||||||
* This work is licensed under the terms of the GNU LGPL, version 2 or later.
|
|
||||||
* See the COPYING.LIB file in the top-level directory.
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef QEMU_COROUTINE_H
|
|
||||||
#define QEMU_COROUTINE_H
|
|
||||||
|
|
||||||
#include "qemu/typedefs.h"
|
|
||||||
#include "qemu/queue.h"
|
|
||||||
#include "qemu/timer.h"
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Coroutines are a mechanism for stack switching and can be used for
|
|
||||||
* cooperative userspace threading. These functions provide a simple but
|
|
||||||
* useful flavor of coroutines that is suitable for writing sequential code,
|
|
||||||
* rather than callbacks, for operations that need to give up control while
|
|
||||||
* waiting for events to complete.
|
|
||||||
*
|
|
||||||
* These functions are re-entrant and may be used outside the global mutex.
|
|
||||||
*/
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Mark a function that executes in coroutine context
|
|
||||||
*
|
|
||||||
* Functions that execute in coroutine context cannot be called directly from
|
|
||||||
* normal functions. In the future it would be nice to enable compiler or
|
|
||||||
* static checker support for catching such errors. This annotation might make
|
|
||||||
* it possible and in the meantime it serves as documentation.
|
|
||||||
*
|
|
||||||
* For example:
|
|
||||||
*
|
|
||||||
* static void coroutine_fn foo(void) {
|
|
||||||
* ....
|
|
||||||
* }
|
|
||||||
*/
|
|
||||||
#define coroutine_fn
|
|
||||||
|
|
||||||
typedef struct Coroutine Coroutine;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Coroutine entry point
|
|
||||||
*
|
|
||||||
* When the coroutine is entered for the first time, opaque is passed in as an
|
|
||||||
* argument.
|
|
||||||
*
|
|
||||||
* When this function returns, the coroutine is destroyed automatically and
|
|
||||||
* execution continues in the caller who last entered the coroutine.
|
|
||||||
*/
|
|
||||||
typedef void coroutine_fn CoroutineEntry(void *opaque);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Create a new coroutine
|
|
||||||
*
|
|
||||||
* Use qemu_coroutine_enter() to actually transfer control to the coroutine.
|
|
||||||
*/
|
|
||||||
Coroutine *qemu_coroutine_create(CoroutineEntry *entry);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Transfer control to a coroutine
|
|
||||||
*
|
|
||||||
* The opaque argument is passed as the argument to the entry point when
|
|
||||||
* entering the coroutine for the first time. It is subsequently ignored.
|
|
||||||
*/
|
|
||||||
void qemu_coroutine_enter(Coroutine *coroutine, void *opaque);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Transfer control back to a coroutine's caller
|
|
||||||
*
|
|
||||||
* This function does not return until the coroutine is re-entered using
|
|
||||||
* qemu_coroutine_enter().
|
|
||||||
*/
|
|
||||||
void coroutine_fn qemu_coroutine_yield(void);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get the currently executing coroutine
|
|
||||||
*/
|
|
||||||
Coroutine *coroutine_fn qemu_coroutine_self(void);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Return whether or not currently inside a coroutine
|
|
||||||
*
|
|
||||||
* This can be used to write functions that work both when in coroutine context
|
|
||||||
* and when not in coroutine context. Note that such functions cannot use the
|
|
||||||
* coroutine_fn annotation since they work outside coroutine context.
|
|
||||||
*/
|
|
||||||
bool qemu_in_coroutine(void);
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* CoQueues are a mechanism to queue coroutines in order to continue executing
|
|
||||||
* them later. They provide the fundamental primitives on which coroutine locks
|
|
||||||
* are built.
|
|
||||||
*/
|
|
||||||
typedef struct CoQueue {
|
|
||||||
QTAILQ_HEAD(, Coroutine) entries;
|
|
||||||
} CoQueue;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Initialise a CoQueue. This must be called before any other operation is used
|
|
||||||
* on the CoQueue.
|
|
||||||
*/
|
|
||||||
void qemu_co_queue_init(CoQueue *queue);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Adds the current coroutine to the CoQueue and transfers control to the
|
|
||||||
* caller of the coroutine.
|
|
||||||
*/
|
|
||||||
void coroutine_fn qemu_co_queue_wait(CoQueue *queue);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Restarts the next coroutine in the CoQueue and removes it from the queue.
|
|
||||||
*
|
|
||||||
* Returns true if a coroutine was restarted, false if the queue is empty.
|
|
||||||
*/
|
|
||||||
bool coroutine_fn qemu_co_queue_next(CoQueue *queue);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Restarts all coroutines in the CoQueue and leaves the queue empty.
|
|
||||||
*/
|
|
||||||
void coroutine_fn qemu_co_queue_restart_all(CoQueue *queue);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Enter the next coroutine in the queue
|
|
||||||
*/
|
|
||||||
bool qemu_co_enter_next(CoQueue *queue);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Checks if the CoQueue is empty.
|
|
||||||
*/
|
|
||||||
bool qemu_co_queue_empty(CoQueue *queue);
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Provides a mutex that can be used to synchronise coroutines
|
|
||||||
*/
|
|
||||||
typedef struct CoMutex {
|
|
||||||
bool locked;
|
|
||||||
CoQueue queue;
|
|
||||||
} CoMutex;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Initialises a CoMutex. This must be called before any other operation is used
|
|
||||||
* on the CoMutex.
|
|
||||||
*/
|
|
||||||
void qemu_co_mutex_init(CoMutex *mutex);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Locks the mutex. If the lock cannot be taken immediately, control is
|
|
||||||
* transferred to the caller of the current coroutine.
|
|
||||||
*/
|
|
||||||
void coroutine_fn qemu_co_mutex_lock(CoMutex *mutex);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Unlocks the mutex and schedules the next coroutine that was waiting for this
|
|
||||||
* lock to be run.
|
|
||||||
*/
|
|
||||||
void coroutine_fn qemu_co_mutex_unlock(CoMutex *mutex);
|
|
||||||
|
|
||||||
typedef struct CoRwlock {
|
|
||||||
bool writer;
|
|
||||||
int reader;
|
|
||||||
CoQueue queue;
|
|
||||||
} CoRwlock;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Initialises a CoRwlock. This must be called before any other operation
|
|
||||||
* is used on the CoRwlock
|
|
||||||
*/
|
|
||||||
void qemu_co_rwlock_init(CoRwlock *lock);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Read locks the CoRwlock. If the lock cannot be taken immediately because
|
|
||||||
* of a parallel writer, control is transferred to the caller of the current
|
|
||||||
* coroutine.
|
|
||||||
*/
|
|
||||||
void qemu_co_rwlock_rdlock(CoRwlock *lock);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Write Locks the mutex. If the lock cannot be taken immediately because
|
|
||||||
* of a parallel reader, control is transferred to the caller of the current
|
|
||||||
* coroutine.
|
|
||||||
*/
|
|
||||||
void qemu_co_rwlock_wrlock(CoRwlock *lock);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Unlocks the read/write lock and schedules the next coroutine that was
|
|
||||||
* waiting for this lock to be run.
|
|
||||||
*/
|
|
||||||
void qemu_co_rwlock_unlock(CoRwlock *lock);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Yield the coroutine for a given duration
|
|
||||||
*
|
|
||||||
* Behaves similarly to co_sleep_ns(), but the sleeping coroutine will be
|
|
||||||
* resumed when using aio_poll().
|
|
||||||
*/
|
|
||||||
void coroutine_fn co_aio_sleep_ns(AioContext *ctx, QEMUClockType type,
|
|
||||||
int64_t ns);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Yield until a file descriptor becomes readable
|
|
||||||
*
|
|
||||||
* Note that this function clobbers the handlers for the file descriptor.
|
|
||||||
*/
|
|
||||||
void coroutine_fn yield_until_fd_readable(int fd);
|
|
||||||
|
|
||||||
#endif /* QEMU_COROUTINE_H */
|
|
|
@ -1,444 +0,0 @@
|
||||||
#define BSWAP_H
|
|
||||||
#ifndef BSWAP_H
|
|
||||||
#define BSWAP_H
|
|
||||||
|
|
||||||
#include "config-host.h"
|
|
||||||
#include <inttypes.h>
|
|
||||||
#include <limits.h>
|
|
||||||
#include <string.h>
|
|
||||||
#include "fpu/softfloat.h"
|
|
||||||
|
|
||||||
#ifdef CONFIG_MACHINE_BSWAP_H
|
|
||||||
# include <sys/endian.h>
|
|
||||||
# include <sys/types.h>
|
|
||||||
# include <machine/bswap.h>
|
|
||||||
#elif defined(__FreeBSD__)
|
|
||||||
# include <sys/endian.h>
|
|
||||||
#elif defined(CONFIG_BYTESWAP_H)
|
|
||||||
# include <byteswap.h>
|
|
||||||
|
|
||||||
static inline uint16_t bswap16(uint16_t x)
|
|
||||||
{
|
|
||||||
return bswap_16(x);
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline uint32_t bswap32(uint32_t x)
|
|
||||||
{
|
|
||||||
return bswap_32(x);
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline uint64_t bswap64(uint64_t x)
|
|
||||||
{
|
|
||||||
return bswap_64(x);
|
|
||||||
}
|
|
||||||
# else
|
|
||||||
static inline uint16_t bswap16(uint16_t x)
|
|
||||||
{
|
|
||||||
return (((x & 0x00ff) << 8) |
|
|
||||||
((x & 0xff00) >> 8));
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline uint32_t bswap32(uint32_t x)
|
|
||||||
{
|
|
||||||
return (((x & 0x000000ffU) << 24) |
|
|
||||||
((x & 0x0000ff00U) << 8) |
|
|
||||||
((x & 0x00ff0000U) >> 8) |
|
|
||||||
((x & 0xff000000U) >> 24));
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline uint64_t bswap64(uint64_t x)
|
|
||||||
{
|
|
||||||
return (((x & 0x00000000000000ffULL) << 56) |
|
|
||||||
((x & 0x000000000000ff00ULL) << 40) |
|
|
||||||
((x & 0x0000000000ff0000ULL) << 24) |
|
|
||||||
((x & 0x00000000ff000000ULL) << 8) |
|
|
||||||
((x & 0x000000ff00000000ULL) >> 8) |
|
|
||||||
((x & 0x0000ff0000000000ULL) >> 24) |
|
|
||||||
((x & 0x00ff000000000000ULL) >> 40) |
|
|
||||||
((x & 0xff00000000000000ULL) >> 56));
|
|
||||||
}
|
|
||||||
#endif /* ! CONFIG_MACHINE_BSWAP_H */
|
|
||||||
|
|
||||||
static inline void bswap16s(uint16_t *s)
|
|
||||||
{
|
|
||||||
*s = bswap16(*s);
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline void bswap32s(uint32_t *s)
|
|
||||||
{
|
|
||||||
*s = bswap32(*s);
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline void bswap64s(uint64_t *s)
|
|
||||||
{
|
|
||||||
*s = bswap64(*s);
|
|
||||||
}
|
|
||||||
|
|
||||||
#if defined(HOST_WORDS_BIGENDIAN)
|
|
||||||
#define be_bswap(v, size) (v)
|
|
||||||
#define le_bswap(v, size) glue(bswap, size)(v)
|
|
||||||
#define be_bswaps(v, size)
|
|
||||||
#define le_bswaps(p, size) do { *p = glue(bswap, size)(*p); } while(0)
|
|
||||||
#else
|
|
||||||
#define le_bswap(v, size) (v)
|
|
||||||
#define be_bswap(v, size) glue(bswap, size)(v)
|
|
||||||
#define le_bswaps(v, size)
|
|
||||||
#define be_bswaps(p, size) do { *p = glue(bswap, size)(*p); } while(0)
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#define CPU_CONVERT(endian, size, type)\
|
|
||||||
static inline type endian ## size ## _to_cpu(type v)\
|
|
||||||
{\
|
|
||||||
return glue(endian, _bswap)(v, size);\
|
|
||||||
}\
|
|
||||||
\
|
|
||||||
static inline type cpu_to_ ## endian ## size(type v)\
|
|
||||||
{\
|
|
||||||
return glue(endian, _bswap)(v, size);\
|
|
||||||
}\
|
|
||||||
\
|
|
||||||
static inline void endian ## size ## _to_cpus(type *p)\
|
|
||||||
{\
|
|
||||||
glue(endian, _bswaps)(p, size);\
|
|
||||||
}\
|
|
||||||
\
|
|
||||||
static inline void cpu_to_ ## endian ## size ## s(type *p)\
|
|
||||||
{\
|
|
||||||
glue(endian, _bswaps)(p, size);\
|
|
||||||
}\
|
|
||||||
\
|
|
||||||
static inline type endian ## size ## _to_cpup(const type *p)\
|
|
||||||
{\
|
|
||||||
return glue(glue(endian, size), _to_cpu)(*p);\
|
|
||||||
}\
|
|
||||||
\
|
|
||||||
static inline void cpu_to_ ## endian ## size ## w(type *p, type v)\
|
|
||||||
{\
|
|
||||||
*p = glue(glue(cpu_to_, endian), size)(v);\
|
|
||||||
}
|
|
||||||
|
|
||||||
CPU_CONVERT(be, 16, uint16_t)
|
|
||||||
CPU_CONVERT(be, 32, uint32_t)
|
|
||||||
CPU_CONVERT(be, 64, uint64_t)
|
|
||||||
|
|
||||||
CPU_CONVERT(le, 16, uint16_t)
|
|
||||||
CPU_CONVERT(le, 32, uint32_t)
|
|
||||||
CPU_CONVERT(le, 64, uint64_t)
|
|
||||||
|
|
||||||
/* len must be one of 1, 2, 4 */
|
|
||||||
static inline uint32_t qemu_bswap_len(uint32_t value, int len)
|
|
||||||
{
|
|
||||||
return bswap32(value) >> (32 - 8 * len);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Unions for reinterpreting between floats and integers. */
|
|
||||||
|
|
||||||
typedef union {
|
|
||||||
float32 f;
|
|
||||||
uint32_t l;
|
|
||||||
} CPU_FloatU;
|
|
||||||
|
|
||||||
typedef union {
|
|
||||||
float64 d;
|
|
||||||
#if defined(HOST_WORDS_BIGENDIAN)
|
|
||||||
struct {
|
|
||||||
uint32_t upper;
|
|
||||||
uint32_t lower;
|
|
||||||
} l;
|
|
||||||
#else
|
|
||||||
struct {
|
|
||||||
uint32_t lower;
|
|
||||||
uint32_t upper;
|
|
||||||
} l;
|
|
||||||
#endif
|
|
||||||
uint64_t ll;
|
|
||||||
} CPU_DoubleU;
|
|
||||||
|
|
||||||
typedef union {
|
|
||||||
floatx80 d;
|
|
||||||
struct {
|
|
||||||
uint64_t lower;
|
|
||||||
uint16_t upper;
|
|
||||||
} l;
|
|
||||||
} CPU_LDoubleU;
|
|
||||||
|
|
||||||
typedef union {
|
|
||||||
float128 q;
|
|
||||||
#if defined(HOST_WORDS_BIGENDIAN)
|
|
||||||
struct {
|
|
||||||
uint32_t upmost;
|
|
||||||
uint32_t upper;
|
|
||||||
uint32_t lower;
|
|
||||||
uint32_t lowest;
|
|
||||||
} l;
|
|
||||||
struct {
|
|
||||||
uint64_t upper;
|
|
||||||
uint64_t lower;
|
|
||||||
} ll;
|
|
||||||
#else
|
|
||||||
struct {
|
|
||||||
uint32_t lowest;
|
|
||||||
uint32_t lower;
|
|
||||||
uint32_t upper;
|
|
||||||
uint32_t upmost;
|
|
||||||
} l;
|
|
||||||
struct {
|
|
||||||
uint64_t lower;
|
|
||||||
uint64_t upper;
|
|
||||||
} ll;
|
|
||||||
#endif
|
|
||||||
} CPU_QuadU;
|
|
||||||
|
|
||||||
/* unaligned/endian-independent pointer access */
|
|
||||||
|
|
||||||
/*
|
|
||||||
* the generic syntax is:
|
|
||||||
*
|
|
||||||
* load: ld{type}{sign}{size}{endian}_p(ptr)
|
|
||||||
*
|
|
||||||
* store: st{type}{size}{endian}_p(ptr, val)
|
|
||||||
*
|
|
||||||
* Note there are small differences with the softmmu access API!
|
|
||||||
*
|
|
||||||
* type is:
|
|
||||||
* (empty): integer access
|
|
||||||
* f : float access
|
|
||||||
*
|
|
||||||
* sign is:
|
|
||||||
* (empty): for 32 or 64 bit sizes (including floats and doubles)
|
|
||||||
* u : unsigned
|
|
||||||
* s : signed
|
|
||||||
*
|
|
||||||
* size is:
|
|
||||||
* b: 8 bits
|
|
||||||
* w: 16 bits
|
|
||||||
* l: 32 bits
|
|
||||||
* q: 64 bits
|
|
||||||
*
|
|
||||||
* endian is:
|
|
||||||
* he : host endian
|
|
||||||
* be : big endian
|
|
||||||
* le : little endian
|
|
||||||
* te : target endian
|
|
||||||
* (except for byte accesses, which have no endian infix).
|
|
||||||
*
|
|
||||||
* The target endian accessors are obviously only available to source
|
|
||||||
* files which are built per-target; they are defined in cpu-all.h.
|
|
||||||
*
|
|
||||||
* In all cases these functions take a host pointer.
|
|
||||||
* For accessors that take a guest address rather than a
|
|
||||||
* host address, see the cpu_{ld,st}_* accessors defined in
|
|
||||||
* cpu_ldst.h.
|
|
||||||
*/
|
|
||||||
|
|
||||||
static inline int ldub_p(const void *ptr)
|
|
||||||
{
|
|
||||||
return *(uint8_t *)ptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline int ldsb_p(const void *ptr)
|
|
||||||
{
|
|
||||||
return *(int8_t *)ptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline void stb_p(void *ptr, uint8_t v)
|
|
||||||
{
|
|
||||||
*(uint8_t *)ptr = v;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Any compiler worth its salt will turn these memcpy into native unaligned
|
|
||||||
operations. Thus we don't need to play games with packed attributes, or
|
|
||||||
inline byte-by-byte stores. */
|
|
||||||
|
|
||||||
static inline int lduw_he_p(const void *ptr)
|
|
||||||
{
|
|
||||||
uint16_t r;
|
|
||||||
memcpy(&r, ptr, sizeof(r));
|
|
||||||
return r;
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline int ldsw_he_p(const void *ptr)
|
|
||||||
{
|
|
||||||
int16_t r;
|
|
||||||
memcpy(&r, ptr, sizeof(r));
|
|
||||||
return r;
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline void stw_he_p(void *ptr, uint16_t v)
|
|
||||||
{
|
|
||||||
memcpy(ptr, &v, sizeof(v));
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline int ldl_he_p(const void *ptr)
|
|
||||||
{
|
|
||||||
int32_t r;
|
|
||||||
memcpy(&r, ptr, sizeof(r));
|
|
||||||
return r;
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline void stl_he_p(void *ptr, uint32_t v)
|
|
||||||
{
|
|
||||||
memcpy(ptr, &v, sizeof(v));
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline uint64_t ldq_he_p(const void *ptr)
|
|
||||||
{
|
|
||||||
uint64_t r;
|
|
||||||
memcpy(&r, ptr, sizeof(r));
|
|
||||||
return r;
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline void stq_he_p(void *ptr, uint64_t v)
|
|
||||||
{
|
|
||||||
memcpy(ptr, &v, sizeof(v));
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline int lduw_le_p(const void *ptr)
|
|
||||||
{
|
|
||||||
return (uint16_t)le_bswap(lduw_he_p(ptr), 16);
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline int ldsw_le_p(const void *ptr)
|
|
||||||
{
|
|
||||||
return (int16_t)le_bswap(lduw_he_p(ptr), 16);
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline int ldl_le_p(const void *ptr)
|
|
||||||
{
|
|
||||||
return le_bswap(ldl_he_p(ptr), 32);
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline uint64_t ldq_le_p(const void *ptr)
|
|
||||||
{
|
|
||||||
return le_bswap(ldq_he_p(ptr), 64);
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline void stw_le_p(void *ptr, uint16_t v)
|
|
||||||
{
|
|
||||||
stw_he_p(ptr, le_bswap(v, 16));
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline void stl_le_p(void *ptr, uint32_t v)
|
|
||||||
{
|
|
||||||
stl_he_p(ptr, le_bswap(v, 32));
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline void stq_le_p(void *ptr, uint64_t v)
|
|
||||||
{
|
|
||||||
stq_he_p(ptr, le_bswap(v, 64));
|
|
||||||
}
|
|
||||||
|
|
||||||
/* float access */
|
|
||||||
|
|
||||||
static inline float32 ldfl_le_p(const void *ptr)
|
|
||||||
{
|
|
||||||
CPU_FloatU u;
|
|
||||||
u.l = ldl_le_p(ptr);
|
|
||||||
return u.f;
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline void stfl_le_p(void *ptr, float32 v)
|
|
||||||
{
|
|
||||||
CPU_FloatU u;
|
|
||||||
u.f = v;
|
|
||||||
stl_le_p(ptr, u.l);
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline float64 ldfq_le_p(const void *ptr)
|
|
||||||
{
|
|
||||||
CPU_DoubleU u;
|
|
||||||
u.ll = ldq_le_p(ptr);
|
|
||||||
return u.d;
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline void stfq_le_p(void *ptr, float64 v)
|
|
||||||
{
|
|
||||||
CPU_DoubleU u;
|
|
||||||
u.d = v;
|
|
||||||
stq_le_p(ptr, u.ll);
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline int lduw_be_p(const void *ptr)
|
|
||||||
{
|
|
||||||
return (uint16_t)be_bswap(lduw_he_p(ptr), 16);
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline int ldsw_be_p(const void *ptr)
|
|
||||||
{
|
|
||||||
return (int16_t)be_bswap(lduw_he_p(ptr), 16);
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline int ldl_be_p(const void *ptr)
|
|
||||||
{
|
|
||||||
return be_bswap(ldl_he_p(ptr), 32);
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline uint64_t ldq_be_p(const void *ptr)
|
|
||||||
{
|
|
||||||
return be_bswap(ldq_he_p(ptr), 64);
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline void stw_be_p(void *ptr, uint16_t v)
|
|
||||||
{
|
|
||||||
stw_he_p(ptr, be_bswap(v, 16));
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline void stl_be_p(void *ptr, uint32_t v)
|
|
||||||
{
|
|
||||||
stl_he_p(ptr, be_bswap(v, 32));
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline void stq_be_p(void *ptr, uint64_t v)
|
|
||||||
{
|
|
||||||
stq_he_p(ptr, be_bswap(v, 64));
|
|
||||||
}
|
|
||||||
|
|
||||||
/* float access */
|
|
||||||
|
|
||||||
static inline float32 ldfl_be_p(const void *ptr)
|
|
||||||
{
|
|
||||||
CPU_FloatU u;
|
|
||||||
u.l = ldl_be_p(ptr);
|
|
||||||
return u.f;
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline void stfl_be_p(void *ptr, float32 v)
|
|
||||||
{
|
|
||||||
CPU_FloatU u;
|
|
||||||
u.f = v;
|
|
||||||
stl_be_p(ptr, u.l);
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline float64 ldfq_be_p(const void *ptr)
|
|
||||||
{
|
|
||||||
CPU_DoubleU u;
|
|
||||||
u.ll = ldq_be_p(ptr);
|
|
||||||
return u.d;
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline void stfq_be_p(void *ptr, float64 v)
|
|
||||||
{
|
|
||||||
CPU_DoubleU u;
|
|
||||||
u.d = v;
|
|
||||||
stq_be_p(ptr, u.ll);
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline unsigned long leul_to_cpu(unsigned long v)
|
|
||||||
{
|
|
||||||
/* In order to break an include loop between here and
|
|
||||||
qemu-common.h, don't rely on HOST_LONG_BITS. */
|
|
||||||
#if ULONG_MAX == UINT32_MAX
|
|
||||||
return le_bswap(v, 32);
|
|
||||||
#elif ULONG_MAX == UINT64_MAX
|
|
||||||
return le_bswap(v, 64);
|
|
||||||
#else
|
|
||||||
# error Unknown sizeof long
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
#undef le_bswap
|
|
||||||
#undef be_bswap
|
|
||||||
#undef le_bswaps
|
|
||||||
#undef be_bswaps
|
|
||||||
|
|
||||||
#endif /* BSWAP_H */
|
|
|
@ -1,33 +0,0 @@
|
||||||
#ifndef QEMU_CONFIG_H
|
|
||||||
#define QEMU_CONFIG_H
|
|
||||||
|
|
||||||
#include <stdio.h>
|
|
||||||
#include "qemu/option.h"
|
|
||||||
#include "qapi/error.h"
|
|
||||||
#include "qapi/qmp/qdict.h"
|
|
||||||
|
|
||||||
QemuOptsList *qemu_find_opts(const char *group);
|
|
||||||
QemuOptsList *qemu_find_opts_err(const char *group, Error **errp);
|
|
||||||
QemuOpts *qemu_find_opts_singleton(const char *group);
|
|
||||||
|
|
||||||
void qemu_add_opts(QemuOptsList *list);
|
|
||||||
void qemu_add_drive_opts(QemuOptsList *list);
|
|
||||||
int qemu_set_option(const char *str);
|
|
||||||
int qemu_global_option(const char *str);
|
|
||||||
void qemu_add_globals(void);
|
|
||||||
|
|
||||||
void qemu_config_write(FILE *fp);
|
|
||||||
int qemu_config_parse(FILE *fp, QemuOptsList **lists, const char *fname);
|
|
||||||
|
|
||||||
int qemu_read_config_file(const char *filename);
|
|
||||||
|
|
||||||
/* Parse QDict options as a replacement for a config file (allowing multiple
|
|
||||||
enumerated (0..(n-1)) configuration "sections") */
|
|
||||||
void qemu_config_parse_qdict(QDict *options, QemuOptsList **lists,
|
|
||||||
Error **errp);
|
|
||||||
|
|
||||||
/* Read default QEMU config files
|
|
||||||
*/
|
|
||||||
int qemu_read_default_config_files(bool userconfig);
|
|
||||||
|
|
||||||
#endif /* QEMU_CONFIG_H */
|
|
|
@ -1,45 +0,0 @@
|
||||||
/*
|
|
||||||
* Error reporting
|
|
||||||
*
|
|
||||||
* Copyright (C) 2010 Red Hat Inc.
|
|
||||||
*
|
|
||||||
* Authors:
|
|
||||||
* Markus Armbruster <armbru@redhat.com>,
|
|
||||||
*
|
|
||||||
* This work is licensed under the terms of the GNU GPL, version 2 or later.
|
|
||||||
* See the COPYING file in the top-level directory.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef QEMU_ERROR_H
|
|
||||||
#define QEMU_ERROR_H
|
|
||||||
|
|
||||||
#include <stdarg.h>
|
|
||||||
#include "qemu/compiler.h"
|
|
||||||
|
|
||||||
typedef struct Location {
|
|
||||||
/* all members are private to qemu-error.c */
|
|
||||||
enum { LOC_NONE, LOC_CMDLINE, LOC_FILE } kind;
|
|
||||||
int num;
|
|
||||||
const void *ptr;
|
|
||||||
struct Location *prev;
|
|
||||||
} Location;
|
|
||||||
|
|
||||||
Location *loc_push_restore(Location *loc);
|
|
||||||
Location *loc_push_none(Location *loc);
|
|
||||||
Location *loc_pop(Location *loc);
|
|
||||||
Location *loc_save(Location *loc);
|
|
||||||
void loc_restore(Location *loc);
|
|
||||||
void loc_set_none(void);
|
|
||||||
void loc_set_cmdline(char **argv, int idx, int cnt);
|
|
||||||
void loc_set_file(const char *fname, int lno);
|
|
||||||
|
|
||||||
void error_vprintf(const char *fmt, va_list ap) GCC_FMT_ATTR(1, 0);
|
|
||||||
void error_printf(const char *fmt, ...) GCC_FMT_ATTR(1, 2);
|
|
||||||
void error_printf_unless_qmp(const char *fmt, ...) GCC_FMT_ATTR(1, 2);
|
|
||||||
void error_set_progname(const char *argv0);
|
|
||||||
void error_vreport(const char *fmt, va_list ap) GCC_FMT_ATTR(1, 0);
|
|
||||||
//void error_report(const char *fmt, ...) GCC_FMT_ATTR(1, 2);
|
|
||||||
const char *error_get_progname(void);
|
|
||||||
extern bool enable_timestamp_msg;
|
|
||||||
|
|
||||||
#endif
|
|
|
@ -1,49 +0,0 @@
|
||||||
/*
|
|
||||||
* event notifier support
|
|
||||||
*
|
|
||||||
* Copyright Red Hat, Inc. 2010
|
|
||||||
*
|
|
||||||
* Authors:
|
|
||||||
* Michael S. Tsirkin <mst@redhat.com>
|
|
||||||
*
|
|
||||||
* This work is licensed under the terms of the GNU GPL, version 2 or later.
|
|
||||||
* See the COPYING file in the top-level directory.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef QEMU_EVENT_NOTIFIER_H
|
|
||||||
#define QEMU_EVENT_NOTIFIER_H
|
|
||||||
|
|
||||||
#include "qemu-common.h"
|
|
||||||
|
|
||||||
#ifdef _WIN32
|
|
||||||
#include <winsock2.h>
|
|
||||||
#include <windows.h>
|
|
||||||
#endif
|
|
||||||
|
|
||||||
struct EventNotifier {
|
|
||||||
#ifdef _WIN32
|
|
||||||
HANDLE event;
|
|
||||||
#else
|
|
||||||
int rfd;
|
|
||||||
int wfd;
|
|
||||||
#endif
|
|
||||||
};
|
|
||||||
|
|
||||||
typedef void EventNotifierHandler(EventNotifier *);
|
|
||||||
|
|
||||||
int event_notifier_init(EventNotifier *, int active);
|
|
||||||
void event_notifier_cleanup(EventNotifier *);
|
|
||||||
int event_notifier_set(EventNotifier *);
|
|
||||||
int event_notifier_test_and_clear(EventNotifier *);
|
|
||||||
int event_notifier_set_handler(EventNotifier *, EventNotifierHandler *);
|
|
||||||
|
|
||||||
#if 0
|
|
||||||
#ifdef CONFIG_POSIX
|
|
||||||
void event_notifier_init_fd(EventNotifier *, int fd);
|
|
||||||
int event_notifier_get_fd(EventNotifier *);
|
|
||||||
#else
|
|
||||||
HANDLE event_notifier_get_handle(EventNotifier *);
|
|
||||||
#endif
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#endif
|
|
|
@ -1,138 +0,0 @@
|
||||||
#ifndef CPU_COMMON_H
|
|
||||||
#define CPU_COMMON_H 1
|
|
||||||
|
|
||||||
/* CPU interfaces that are target independent. */
|
|
||||||
|
|
||||||
#ifndef CONFIG_USER_ONLY
|
|
||||||
#include "exec/hwaddr.h"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifndef NEED_CPU_H
|
|
||||||
#include "exec/poison.h"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#include "qemu/bswap.h"
|
|
||||||
#include "qemu/queue.h"
|
|
||||||
#include "qemu/fprintf-fn.h"
|
|
||||||
#include "qemu/typedefs.h"
|
|
||||||
|
|
||||||
/**
|
|
||||||
* CPUListState:
|
|
||||||
* @cpu_fprintf: Print function.
|
|
||||||
* @file: File to print to using @cpu_fprint.
|
|
||||||
*
|
|
||||||
* State commonly used for iterating over CPU models.
|
|
||||||
*/
|
|
||||||
typedef struct CPUListState {
|
|
||||||
fprintf_function cpu_fprintf;
|
|
||||||
FILE *file;
|
|
||||||
} CPUListState;
|
|
||||||
|
|
||||||
typedef enum MMUAccessType {
|
|
||||||
MMU_DATA_LOAD = 0,
|
|
||||||
MMU_DATA_STORE = 1,
|
|
||||||
MMU_INST_FETCH = 2
|
|
||||||
} MMUAccessType;
|
|
||||||
|
|
||||||
#if !defined(CONFIG_USER_ONLY)
|
|
||||||
|
|
||||||
enum device_endian {
|
|
||||||
DEVICE_NATIVE_ENDIAN,
|
|
||||||
DEVICE_BIG_ENDIAN,
|
|
||||||
DEVICE_LITTLE_ENDIAN,
|
|
||||||
};
|
|
||||||
|
|
||||||
/* address in the RAM (different from a physical address) */
|
|
||||||
#if defined(CONFIG_XEN_BACKEND)
|
|
||||||
typedef uint64_t ram_addr_t;
|
|
||||||
# define RAM_ADDR_MAX UINT64_MAX
|
|
||||||
# define RAM_ADDR_FMT "%" PRIx64
|
|
||||||
#else
|
|
||||||
typedef uintptr_t ram_addr_t;
|
|
||||||
# define RAM_ADDR_MAX UINTPTR_MAX
|
|
||||||
# define RAM_ADDR_FMT "%" PRIxPTR
|
|
||||||
#endif
|
|
||||||
|
|
||||||
extern ram_addr_t ram_size;
|
|
||||||
ram_addr_t get_current_ram_size(void);
|
|
||||||
|
|
||||||
/* memory API */
|
|
||||||
|
|
||||||
typedef void CPUWriteMemoryFunc(void *opaque, hwaddr addr, uint32_t value);
|
|
||||||
typedef uint32_t CPUReadMemoryFunc(void *opaque, hwaddr addr);
|
|
||||||
|
|
||||||
void qemu_ram_remap(ram_addr_t addr, ram_addr_t length);
|
|
||||||
/* This should not be used by devices. */
|
|
||||||
MemoryRegion *qemu_ram_addr_from_host(void *ptr, ram_addr_t *ram_addr);
|
|
||||||
void qemu_ram_set_idstr(ram_addr_t addr, const char *name, DeviceState *dev);
|
|
||||||
void qemu_ram_unset_idstr(ram_addr_t addr);
|
|
||||||
|
|
||||||
void cpu_physical_memory_rw(hwaddr addr, uint8_t *buf,
|
|
||||||
int len, int is_write);
|
|
||||||
static inline void cpu_physical_memory_read(hwaddr addr,
|
|
||||||
void *buf, int len)
|
|
||||||
{
|
|
||||||
cpu_physical_memory_rw(addr, buf, len, 0);
|
|
||||||
}
|
|
||||||
static inline void cpu_physical_memory_write(hwaddr addr,
|
|
||||||
const void *buf, int len)
|
|
||||||
{
|
|
||||||
cpu_physical_memory_rw(addr, (void *)buf, len, 1);
|
|
||||||
}
|
|
||||||
void *cpu_physical_memory_map(hwaddr addr,
|
|
||||||
hwaddr *plen,
|
|
||||||
int is_write);
|
|
||||||
void cpu_physical_memory_unmap(void *buffer, hwaddr len,
|
|
||||||
int is_write, hwaddr access_len);
|
|
||||||
void cpu_register_map_client(QEMUBH *bh);
|
|
||||||
void cpu_unregister_map_client(QEMUBH *bh);
|
|
||||||
|
|
||||||
bool cpu_physical_memory_is_io(hwaddr phys_addr);
|
|
||||||
|
|
||||||
/* Coalesced MMIO regions are areas where write operations can be reordered.
|
|
||||||
* This usually implies that write operations are side-effect free. This allows
|
|
||||||
* batching which can make a major impact on performance when using
|
|
||||||
* virtualization.
|
|
||||||
*/
|
|
||||||
void qemu_flush_coalesced_mmio_buffer(void);
|
|
||||||
|
|
||||||
uint32_t ldub_phys(AddressSpace *as, hwaddr addr);
|
|
||||||
uint32_t lduw_le_phys(AddressSpace *as, hwaddr addr);
|
|
||||||
uint32_t lduw_be_phys(AddressSpace *as, hwaddr addr);
|
|
||||||
uint32_t ldl_le_phys(AddressSpace *as, hwaddr addr);
|
|
||||||
uint32_t ldl_be_phys(AddressSpace *as, hwaddr addr);
|
|
||||||
uint64_t ldq_le_phys(AddressSpace *as, hwaddr addr);
|
|
||||||
uint64_t ldq_be_phys(AddressSpace *as, hwaddr addr);
|
|
||||||
void stb_phys(AddressSpace *as, hwaddr addr, uint32_t val);
|
|
||||||
void stw_le_phys(AddressSpace *as, hwaddr addr, uint32_t val);
|
|
||||||
void stw_be_phys(AddressSpace *as, hwaddr addr, uint32_t val);
|
|
||||||
void stl_le_phys(AddressSpace *as, hwaddr addr, uint32_t val);
|
|
||||||
void stl_be_phys(AddressSpace *as, hwaddr addr, uint32_t val);
|
|
||||||
void stq_le_phys(AddressSpace *as, hwaddr addr, uint64_t val);
|
|
||||||
void stq_be_phys(AddressSpace *as, hwaddr addr, uint64_t val);
|
|
||||||
|
|
||||||
#ifdef NEED_CPU_H
|
|
||||||
uint32_t lduw_phys(AddressSpace *as, hwaddr addr);
|
|
||||||
uint32_t ldl_phys(AddressSpace *as, hwaddr addr);
|
|
||||||
uint64_t ldq_phys(AddressSpace *as, hwaddr addr);
|
|
||||||
void stl_phys_notdirty(AddressSpace *as, hwaddr addr, uint32_t val);
|
|
||||||
void stw_phys(AddressSpace *as, hwaddr addr, uint32_t val);
|
|
||||||
void stl_phys(AddressSpace *as, hwaddr addr, uint32_t val);
|
|
||||||
void stq_phys(AddressSpace *as, hwaddr addr, uint64_t val);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
void cpu_physical_memory_write_rom(AddressSpace *as, hwaddr addr,
|
|
||||||
const uint8_t *buf, int len);
|
|
||||||
void cpu_flush_icache_range(hwaddr start, int len);
|
|
||||||
|
|
||||||
extern struct MemoryRegion io_mem_rom;
|
|
||||||
extern struct MemoryRegion io_mem_notdirty;
|
|
||||||
|
|
||||||
typedef int (RAMBlockIterFunc)(const char *block_name, void *host_addr,
|
|
||||||
ram_addr_t offset, ram_addr_t length, void *opaque);
|
|
||||||
|
|
||||||
int qemu_ram_foreach_block(RAMBlockIterFunc func, void *opaque);
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#endif /* !CPU_COMMON_H */
|
|
|
@ -1,20 +0,0 @@
|
||||||
/* Define hwaddr if it exists. */
|
|
||||||
|
|
||||||
#ifndef HWADDR_H
|
|
||||||
#define HWADDR_H
|
|
||||||
|
|
||||||
#define HWADDR_BITS 64
|
|
||||||
/* hwaddr is the type of a physical address (its size can
|
|
||||||
be different from 'target_ulong'). */
|
|
||||||
|
|
||||||
typedef uint64_t hwaddr;
|
|
||||||
#define HWADDR_MAX UINT64_MAX
|
|
||||||
#define TARGET_FMT_plx "%016" PRIx64
|
|
||||||
#define HWADDR_PRId PRId64
|
|
||||||
#define HWADDR_PRIi PRIi64
|
|
||||||
#define HWADDR_PRIo PRIo64
|
|
||||||
#define HWADDR_PRIu PRIu64
|
|
||||||
#define HWADDR_PRIx PRIx64
|
|
||||||
#define HWADDR_PRIX PRIX64
|
|
||||||
|
|
||||||
#endif
|
|
|
@ -1,80 +0,0 @@
|
||||||
/*
|
|
||||||
* defines ioport related functions
|
|
||||||
*
|
|
||||||
* Copyright (c) 2003 Fabrice Bellard
|
|
||||||
*
|
|
||||||
* This library is free software; you can redistribute it and/or
|
|
||||||
* modify it under the terms of the GNU Lesser General Public
|
|
||||||
* License as published by the Free Software Foundation; either
|
|
||||||
* version 2 of the License, or (at your option) any later version.
|
|
||||||
*
|
|
||||||
* This library is distributed in the hope that it will be useful,
|
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
||||||
* Lesser General Public License for more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU Lesser General Public
|
|
||||||
* License along with this library; if not, see <http://www.gnu.org/licenses/>.
|
|
||||||
*/
|
|
||||||
|
|
||||||
/**************************************************************************
|
|
||||||
* IO ports API
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef IOPORT_H
|
|
||||||
#define IOPORT_H
|
|
||||||
|
|
||||||
#include "qemu-common.h"
|
|
||||||
//#include "qom/object.h"
|
|
||||||
//#include "exec/memory.h"
|
|
||||||
|
|
||||||
typedef uint32_t pio_addr_t;
|
|
||||||
#define FMT_pioaddr PRIx32
|
|
||||||
|
|
||||||
#define MAX_IOPORTS (64 * 1024)
|
|
||||||
#define IOPORTS_MASK (MAX_IOPORTS - 1)
|
|
||||||
|
|
||||||
typedef struct MemoryRegionPortio {
|
|
||||||
uint32_t offset;
|
|
||||||
uint32_t len;
|
|
||||||
unsigned size;
|
|
||||||
uint32_t (*read)(void *opaque, uint32_t address);
|
|
||||||
void (*write)(void *opaque, uint32_t address, uint32_t data);
|
|
||||||
uint32_t base; /* private field */
|
|
||||||
} MemoryRegionPortio;
|
|
||||||
|
|
||||||
#define PORTIO_END_OF_LIST() { }
|
|
||||||
|
|
||||||
#ifndef CONFIG_USER_ONLY
|
|
||||||
extern const MemoryRegionOps unassigned_io_ops;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
void cpu_outb(pio_addr_t addr, uint8_t val);
|
|
||||||
void cpu_outw(pio_addr_t addr, uint16_t val);
|
|
||||||
void cpu_outl(pio_addr_t addr, uint32_t val);
|
|
||||||
uint8_t cpu_inb(pio_addr_t addr);
|
|
||||||
uint16_t cpu_inw(pio_addr_t addr);
|
|
||||||
uint32_t cpu_inl(pio_addr_t addr);
|
|
||||||
|
|
||||||
typedef struct PortioList {
|
|
||||||
const struct MemoryRegionPortio *ports;
|
|
||||||
Object *owner;
|
|
||||||
struct MemoryRegion *address_space;
|
|
||||||
unsigned nr;
|
|
||||||
struct MemoryRegion **regions;
|
|
||||||
void *opaque;
|
|
||||||
const char *name;
|
|
||||||
bool flush_coalesced_mmio;
|
|
||||||
} PortioList;
|
|
||||||
|
|
||||||
void portio_list_init(PortioList *piolist, Object *owner,
|
|
||||||
const struct MemoryRegionPortio *callbacks,
|
|
||||||
void *opaque, const char *name);
|
|
||||||
void portio_list_set_flush_coalesced(PortioList *piolist);
|
|
||||||
void portio_list_destroy(PortioList *piolist);
|
|
||||||
void portio_list_add(PortioList *piolist,
|
|
||||||
struct MemoryRegion *address_space,
|
|
||||||
uint32_t addr);
|
|
||||||
void portio_list_del(PortioList *piolist);
|
|
||||||
|
|
||||||
#endif /* IOPORT_H */
|
|
|
@ -1,49 +0,0 @@
|
||||||
/*
|
|
||||||
* Memory transaction attributes
|
|
||||||
*
|
|
||||||
* Copyright (c) 2015 Linaro Limited.
|
|
||||||
*
|
|
||||||
* Authors:
|
|
||||||
* Peter Maydell <peter.maydell@linaro.org>
|
|
||||||
*
|
|
||||||
* This work is licensed under the terms of the GNU GPL, version 2 or later.
|
|
||||||
* See the COPYING file in the top-level directory.
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef MEMATTRS_H
|
|
||||||
#define MEMATTRS_H
|
|
||||||
|
|
||||||
/* Every memory transaction has associated with it a set of
|
|
||||||
* attributes. Some of these are generic (such as the ID of
|
|
||||||
* the bus master); some are specific to a particular kind of
|
|
||||||
* bus (such as the ARM Secure/NonSecure bit). We define them
|
|
||||||
* all as non-overlapping bitfields in a single struct to avoid
|
|
||||||
* confusion if different parts of QEMU used the same bit for
|
|
||||||
* different semantics.
|
|
||||||
*/
|
|
||||||
typedef struct MemTxAttrs {
|
|
||||||
/* Bus masters which don't specify any attributes will get this
|
|
||||||
* (via the MEMTXATTRS_UNSPECIFIED constant), so that we can
|
|
||||||
* distinguish "all attributes deliberately clear" from
|
|
||||||
* "didn't specify" if necessary.
|
|
||||||
*/
|
|
||||||
unsigned int unspecified:1;
|
|
||||||
/* ARM/AMBA: TrustZone Secure access
|
|
||||||
* x86: System Management Mode access
|
|
||||||
*/
|
|
||||||
unsigned int secure:1;
|
|
||||||
/* Memory access is usermode (unprivileged) */
|
|
||||||
unsigned int user:1;
|
|
||||||
/* Stream ID (for MSI for example) */
|
|
||||||
unsigned int stream_id:16;
|
|
||||||
} MemTxAttrs;
|
|
||||||
|
|
||||||
/* Bus masters which don't specify any attributes will get this,
|
|
||||||
* which has all attribute bits clear except the topmost one
|
|
||||||
* (so that we can distinguish "all attributes deliberately clear"
|
|
||||||
* from "didn't specify" if necessary).
|
|
||||||
*/
|
|
||||||
#define MEMTXATTRS_UNSPECIFIED ((MemTxAttrs) { .unspecified = 1 })
|
|
||||||
|
|
||||||
#endif
|
|
File diff suppressed because it is too large
Load diff
|
@ -1,62 +0,0 @@
|
||||||
/* Poison identifiers that should not be used when building
|
|
||||||
target independent device code. */
|
|
||||||
|
|
||||||
#ifndef HW_POISON_H
|
|
||||||
#define HW_POISON_H
|
|
||||||
#ifdef __GNUC__
|
|
||||||
|
|
||||||
#pragma GCC poison TARGET_I386
|
|
||||||
#pragma GCC poison TARGET_X86_64
|
|
||||||
#pragma GCC poison TARGET_ALPHA
|
|
||||||
#pragma GCC poison TARGET_ARM
|
|
||||||
#pragma GCC poison TARGET_CRIS
|
|
||||||
#pragma GCC poison TARGET_LM32
|
|
||||||
#pragma GCC poison TARGET_M68K
|
|
||||||
#pragma GCC poison TARGET_MIPS
|
|
||||||
#pragma GCC poison TARGET_MIPS64
|
|
||||||
#pragma GCC poison TARGET_OPENRISC
|
|
||||||
#pragma GCC poison TARGET_PPC
|
|
||||||
#pragma GCC poison TARGET_PPCEMB
|
|
||||||
#pragma GCC poison TARGET_PPC64
|
|
||||||
#pragma GCC poison TARGET_ABI32
|
|
||||||
#pragma GCC poison TARGET_SH4
|
|
||||||
#pragma GCC poison TARGET_SPARC
|
|
||||||
#pragma GCC poison TARGET_SPARC64
|
|
||||||
|
|
||||||
#pragma GCC poison TARGET_WORDS_BIGENDIAN
|
|
||||||
#pragma GCC poison BSWAP_NEEDED
|
|
||||||
|
|
||||||
#pragma GCC poison TARGET_LONG_BITS
|
|
||||||
#pragma GCC poison TARGET_FMT_lx
|
|
||||||
#pragma GCC poison TARGET_FMT_ld
|
|
||||||
|
|
||||||
#pragma GCC poison TARGET_PAGE_SIZE
|
|
||||||
#pragma GCC poison TARGET_PAGE_MASK
|
|
||||||
#pragma GCC poison TARGET_PAGE_BITS
|
|
||||||
#pragma GCC poison TARGET_PAGE_ALIGN
|
|
||||||
|
|
||||||
#pragma GCC poison CPUArchState
|
|
||||||
|
|
||||||
#pragma GCC poison lduw_phys
|
|
||||||
#pragma GCC poison ldl_phys
|
|
||||||
#pragma GCC poison ldq_phys
|
|
||||||
#pragma GCC poison stl_phys_notdirty
|
|
||||||
#pragma GCC poison stw_phys
|
|
||||||
#pragma GCC poison stl_phys
|
|
||||||
#pragma GCC poison stq_phys
|
|
||||||
|
|
||||||
#pragma GCC poison CPU_INTERRUPT_HARD
|
|
||||||
#pragma GCC poison CPU_INTERRUPT_EXITTB
|
|
||||||
#pragma GCC poison CPU_INTERRUPT_HALT
|
|
||||||
#pragma GCC poison CPU_INTERRUPT_DEBUG
|
|
||||||
#pragma GCC poison CPU_INTERRUPT_TGT_EXT_0
|
|
||||||
#pragma GCC poison CPU_INTERRUPT_TGT_EXT_1
|
|
||||||
#pragma GCC poison CPU_INTERRUPT_TGT_EXT_2
|
|
||||||
#pragma GCC poison CPU_INTERRUPT_TGT_EXT_3
|
|
||||||
#pragma GCC poison CPU_INTERRUPT_TGT_EXT_4
|
|
||||||
#pragma GCC poison CPU_INTERRUPT_TGT_INT_0
|
|
||||||
#pragma GCC poison CPU_INTERRUPT_TGT_INT_1
|
|
||||||
#pragma GCC poison CPU_INTERRUPT_TGT_INT_2
|
|
||||||
|
|
||||||
#endif
|
|
||||||
#endif
|
|
|
@ -1,17 +0,0 @@
|
||||||
/*
|
|
||||||
* Typedef for fprintf-alike function pointers.
|
|
||||||
*
|
|
||||||
* This work is licensed under the terms of the GNU GPL, version 2 or later.
|
|
||||||
* See the COPYING file in the top-level directory.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef QEMU_FPRINTF_FN_H
|
|
||||||
#define QEMU_FPRINTF_FN_H 1
|
|
||||||
|
|
||||||
#include "qemu/compiler.h"
|
|
||||||
#include <stdio.h>
|
|
||||||
|
|
||||||
typedef int (*fprintf_function)(FILE *f, const char *fmt, ...)
|
|
||||||
GCC_FMT_ATTR(2, 3);
|
|
||||||
|
|
||||||
#endif
|
|
|
@ -1,762 +0,0 @@
|
||||||
/*
|
|
||||||
* QEMU float support
|
|
||||||
*
|
|
||||||
* The code in this source file is derived from release 2a of the SoftFloat
|
|
||||||
* IEC/IEEE Floating-point Arithmetic Package. Those parts of the code (and
|
|
||||||
* some later contributions) are provided under that license, as detailed below.
|
|
||||||
* It has subsequently been modified by contributors to the QEMU Project,
|
|
||||||
* so some portions are provided under:
|
|
||||||
* the SoftFloat-2a license
|
|
||||||
* the BSD license
|
|
||||||
* GPL-v2-or-later
|
|
||||||
*
|
|
||||||
* Any future contributions to this file after December 1st 2014 will be
|
|
||||||
* taken to be licensed under the Softfloat-2a license unless specifically
|
|
||||||
* indicated otherwise.
|
|
||||||
*/
|
|
||||||
|
|
||||||
/*
|
|
||||||
===============================================================================
|
|
||||||
This C header file is part of the SoftFloat IEC/IEEE Floating-point
|
|
||||||
Arithmetic Package, Release 2a.
|
|
||||||
|
|
||||||
Written by John R. Hauser. This work was made possible in part by the
|
|
||||||
International Computer Science Institute, located at Suite 600, 1947 Center
|
|
||||||
Street, Berkeley, California 94704. Funding was partially provided by the
|
|
||||||
National Science Foundation under grant MIP-9311980. The original version
|
|
||||||
of this code was written as part of a project to build a fixed-point vector
|
|
||||||
processor in collaboration with the University of California at Berkeley,
|
|
||||||
overseen by Profs. Nelson Morgan and John Wawrzynek. More information
|
|
||||||
is available through the Web page `http://HTTP.CS.Berkeley.EDU/~jhauser/
|
|
||||||
arithmetic/SoftFloat.html'.
|
|
||||||
|
|
||||||
THIS SOFTWARE IS DISTRIBUTED AS IS, FOR FREE. Although reasonable effort
|
|
||||||
has been made to avoid it, THIS SOFTWARE MAY CONTAIN FAULTS THAT WILL AT
|
|
||||||
TIMES RESULT IN INCORRECT BEHAVIOR. USE OF THIS SOFTWARE IS RESTRICTED TO
|
|
||||||
PERSONS AND ORGANIZATIONS WHO CAN AND WILL TAKE FULL RESPONSIBILITY FOR ANY
|
|
||||||
AND ALL LOSSES, COSTS, OR OTHER PROBLEMS ARISING FROM ITS USE.
|
|
||||||
|
|
||||||
Derivative works are acceptable, even for commercial purposes, so long as
|
|
||||||
(1) they include prominent notice that the work is derivative, and (2) they
|
|
||||||
include prominent notice akin to these four paragraphs for those parts of
|
|
||||||
this code that are retained.
|
|
||||||
|
|
||||||
===============================================================================
|
|
||||||
*/
|
|
||||||
|
|
||||||
/* BSD licensing:
|
|
||||||
* Copyright (c) 2006, Fabrice Bellard
|
|
||||||
* All rights reserved.
|
|
||||||
*
|
|
||||||
* Redistribution and use in source and binary forms, with or without
|
|
||||||
* modification, are permitted provided that the following conditions are met:
|
|
||||||
*
|
|
||||||
* 1. Redistributions of source code must retain the above copyright notice,
|
|
||||||
* this list of conditions and the following disclaimer.
|
|
||||||
*
|
|
||||||
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
|
||||||
* this list of conditions and the following disclaimer in the documentation
|
|
||||||
* and/or other materials provided with the distribution.
|
|
||||||
*
|
|
||||||
* 3. Neither the name of the copyright holder nor the names of its contributors
|
|
||||||
* may be used to endorse or promote products derived from this software without
|
|
||||||
* specific prior written permission.
|
|
||||||
*
|
|
||||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
|
||||||
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
|
||||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
|
||||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
|
|
||||||
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
|
||||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
|
||||||
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
|
||||||
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
|
||||||
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
|
||||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
|
|
||||||
* THE POSSIBILITY OF SUCH DAMAGE.
|
|
||||||
*/
|
|
||||||
|
|
||||||
/* Portions of this work are licensed under the terms of the GNU GPL,
|
|
||||||
* version 2 or later. See the COPYING file in the top-level directory.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef SOFTFLOAT_H
|
|
||||||
#define SOFTFLOAT_H
|
|
||||||
|
|
||||||
#if defined(CONFIG_SOLARIS) && defined(CONFIG_NEEDS_LIBSUNMATH)
|
|
||||||
#include <sunmath.h>
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#include <inttypes.h>
|
|
||||||
#include "config-host.h"
|
|
||||||
#include "qemu/osdep.h"
|
|
||||||
|
|
||||||
/*----------------------------------------------------------------------------
|
|
||||||
| Each of the following `typedef's defines the most convenient type that holds
|
|
||||||
| integers of at least as many bits as specified. For example, `uint8' should
|
|
||||||
| be the most convenient type that can hold unsigned integers of as many as
|
|
||||||
| 8 bits. The `flag' type must be able to hold either a 0 or 1. For most
|
|
||||||
| implementations of C, `flag', `uint8', and `int8' should all be `typedef'ed
|
|
||||||
| to the same as `int'.
|
|
||||||
*----------------------------------------------------------------------------*/
|
|
||||||
typedef uint8_t flag;
|
|
||||||
typedef uint8_t uint8;
|
|
||||||
typedef int8_t int8;
|
|
||||||
typedef unsigned int uint32;
|
|
||||||
typedef signed int int32;
|
|
||||||
typedef uint64_t uint64;
|
|
||||||
typedef int64_t int64;
|
|
||||||
|
|
||||||
#define LIT64( a ) a##LL
|
|
||||||
|
|
||||||
/*----------------------------------------------------------------------------
|
|
||||||
| Software IEC/IEEE floating-point ordering relations
|
|
||||||
*----------------------------------------------------------------------------*/
|
|
||||||
enum {
|
|
||||||
float_relation_less = -1,
|
|
||||||
float_relation_equal = 0,
|
|
||||||
float_relation_greater = 1,
|
|
||||||
float_relation_unordered = 2
|
|
||||||
};
|
|
||||||
|
|
||||||
/*----------------------------------------------------------------------------
|
|
||||||
| Software IEC/IEEE floating-point types.
|
|
||||||
*----------------------------------------------------------------------------*/
|
|
||||||
/* Use structures for soft-float types. This prevents accidentally mixing
|
|
||||||
them with native int/float types. A sufficiently clever compiler and
|
|
||||||
sane ABI should be able to see though these structs. However
|
|
||||||
x86/gcc 3.x seems to struggle a bit, so leave them disabled by default. */
|
|
||||||
//#define USE_SOFTFLOAT_STRUCT_TYPES
|
|
||||||
#ifdef USE_SOFTFLOAT_STRUCT_TYPES
|
|
||||||
typedef struct {
|
|
||||||
uint16_t v;
|
|
||||||
} float16;
|
|
||||||
#define float16_val(x) (((float16)(x)).v)
|
|
||||||
#define make_float16(x) __extension__ ({ float16 f16_val = {x}; f16_val; })
|
|
||||||
#define const_float16(x) { x }
|
|
||||||
typedef struct {
|
|
||||||
uint32_t v;
|
|
||||||
} float32;
|
|
||||||
/* The cast ensures an error if the wrong type is passed. */
|
|
||||||
#define float32_val(x) (((float32)(x)).v)
|
|
||||||
#define make_float32(x) __extension__ ({ float32 f32_val = {x}; f32_val; })
|
|
||||||
#define const_float32(x) { x }
|
|
||||||
typedef struct {
|
|
||||||
uint64_t v;
|
|
||||||
} float64;
|
|
||||||
#define float64_val(x) (((float64)(x)).v)
|
|
||||||
#define make_float64(x) __extension__ ({ float64 f64_val = {x}; f64_val; })
|
|
||||||
#define const_float64(x) { x }
|
|
||||||
#else
|
|
||||||
typedef uint16_t float16;
|
|
||||||
typedef uint32_t float32;
|
|
||||||
typedef uint64_t float64;
|
|
||||||
#define float16_val(x) (x)
|
|
||||||
#define float32_val(x) (x)
|
|
||||||
#define float64_val(x) (x)
|
|
||||||
#define make_float16(x) (x)
|
|
||||||
#define make_float32(x) (x)
|
|
||||||
#define make_float64(x) (x)
|
|
||||||
#define const_float16(x) (x)
|
|
||||||
#define const_float32(x) (x)
|
|
||||||
#define const_float64(x) (x)
|
|
||||||
#endif
|
|
||||||
typedef struct {
|
|
||||||
uint64_t low;
|
|
||||||
uint16_t high;
|
|
||||||
} floatx80;
|
|
||||||
#define make_floatx80(exp, mant) ((floatx80) { mant, exp })
|
|
||||||
#define make_floatx80_init(exp, mant) { .low = mant, .high = exp }
|
|
||||||
typedef struct {
|
|
||||||
#ifdef HOST_WORDS_BIGENDIAN
|
|
||||||
uint64_t high, low;
|
|
||||||
#else
|
|
||||||
uint64_t low, high;
|
|
||||||
#endif
|
|
||||||
} float128;
|
|
||||||
#define make_float128(high_, low_) ((float128) { .high = high_, .low = low_ })
|
|
||||||
#define make_float128_init(high_, low_) { .high = high_, .low = low_ }
|
|
||||||
|
|
||||||
/*----------------------------------------------------------------------------
|
|
||||||
| Software IEC/IEEE floating-point underflow tininess-detection mode.
|
|
||||||
*----------------------------------------------------------------------------*/
|
|
||||||
enum {
|
|
||||||
float_tininess_after_rounding = 0,
|
|
||||||
float_tininess_before_rounding = 1
|
|
||||||
};
|
|
||||||
|
|
||||||
/*----------------------------------------------------------------------------
|
|
||||||
| Software IEC/IEEE floating-point rounding mode.
|
|
||||||
*----------------------------------------------------------------------------*/
|
|
||||||
enum {
|
|
||||||
float_round_nearest_even = 0,
|
|
||||||
float_round_down = 1,
|
|
||||||
float_round_up = 2,
|
|
||||||
float_round_to_zero = 3,
|
|
||||||
float_round_ties_away = 4,
|
|
||||||
};
|
|
||||||
|
|
||||||
/*----------------------------------------------------------------------------
|
|
||||||
| Software IEC/IEEE floating-point exception flags.
|
|
||||||
*----------------------------------------------------------------------------*/
|
|
||||||
enum {
|
|
||||||
float_flag_invalid = 1,
|
|
||||||
float_flag_divbyzero = 4,
|
|
||||||
float_flag_overflow = 8,
|
|
||||||
float_flag_underflow = 16,
|
|
||||||
float_flag_inexact = 32,
|
|
||||||
float_flag_input_denormal = 64,
|
|
||||||
float_flag_output_denormal = 128
|
|
||||||
};
|
|
||||||
|
|
||||||
typedef struct float_status {
|
|
||||||
signed char float_detect_tininess;
|
|
||||||
signed char float_rounding_mode;
|
|
||||||
signed char float_exception_flags;
|
|
||||||
signed char floatx80_rounding_precision;
|
|
||||||
/* should denormalised results go to zero and set the inexact flag? */
|
|
||||||
flag flush_to_zero;
|
|
||||||
/* should denormalised inputs go to zero and set the input_denormal flag? */
|
|
||||||
flag flush_inputs_to_zero;
|
|
||||||
flag default_nan_mode;
|
|
||||||
} float_status;
|
|
||||||
|
|
||||||
static inline void set_float_detect_tininess(int val, float_status *status)
|
|
||||||
{
|
|
||||||
status->float_detect_tininess = val;
|
|
||||||
}
|
|
||||||
static inline void set_float_rounding_mode(int val, float_status *status)
|
|
||||||
{
|
|
||||||
status->float_rounding_mode = val;
|
|
||||||
}
|
|
||||||
static inline void set_float_exception_flags(int val, float_status *status)
|
|
||||||
{
|
|
||||||
status->float_exception_flags = val;
|
|
||||||
}
|
|
||||||
static inline void set_floatx80_rounding_precision(int val,
|
|
||||||
float_status *status)
|
|
||||||
{
|
|
||||||
status->floatx80_rounding_precision = val;
|
|
||||||
}
|
|
||||||
static inline void set_flush_to_zero(flag val, float_status *status)
|
|
||||||
{
|
|
||||||
status->flush_to_zero = val;
|
|
||||||
}
|
|
||||||
static inline void set_flush_inputs_to_zero(flag val, float_status *status)
|
|
||||||
{
|
|
||||||
status->flush_inputs_to_zero = val;
|
|
||||||
}
|
|
||||||
static inline void set_default_nan_mode(flag val, float_status *status)
|
|
||||||
{
|
|
||||||
status->default_nan_mode = val;
|
|
||||||
}
|
|
||||||
static inline int get_float_detect_tininess(float_status *status)
|
|
||||||
{
|
|
||||||
return status->float_detect_tininess;
|
|
||||||
}
|
|
||||||
static inline int get_float_rounding_mode(float_status *status)
|
|
||||||
{
|
|
||||||
return status->float_rounding_mode;
|
|
||||||
}
|
|
||||||
static inline int get_float_exception_flags(float_status *status)
|
|
||||||
{
|
|
||||||
return status->float_exception_flags;
|
|
||||||
}
|
|
||||||
static inline int get_floatx80_rounding_precision(float_status *status)
|
|
||||||
{
|
|
||||||
return status->floatx80_rounding_precision;
|
|
||||||
}
|
|
||||||
static inline flag get_flush_to_zero(float_status *status)
|
|
||||||
{
|
|
||||||
return status->flush_to_zero;
|
|
||||||
}
|
|
||||||
static inline flag get_flush_inputs_to_zero(float_status *status)
|
|
||||||
{
|
|
||||||
return status->flush_inputs_to_zero;
|
|
||||||
}
|
|
||||||
static inline flag get_default_nan_mode(float_status *status)
|
|
||||||
{
|
|
||||||
return status->default_nan_mode;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*----------------------------------------------------------------------------
|
|
||||||
| Routine to raise any or all of the software IEC/IEEE floating-point
|
|
||||||
| exception flags.
|
|
||||||
*----------------------------------------------------------------------------*/
|
|
||||||
void float_raise(int8 flags, float_status *status);
|
|
||||||
|
|
||||||
/*----------------------------------------------------------------------------
|
|
||||||
| If `a' is denormal and we are in flush-to-zero mode then set the
|
|
||||||
| input-denormal exception and return zero. Otherwise just return the value.
|
|
||||||
*----------------------------------------------------------------------------*/
|
|
||||||
float32 float32_squash_input_denormal(float32 a, float_status *status);
|
|
||||||
float64 float64_squash_input_denormal(float64 a, float_status *status);
|
|
||||||
|
|
||||||
/*----------------------------------------------------------------------------
|
|
||||||
| Options to indicate which negations to perform in float*_muladd()
|
|
||||||
| Using these differs from negating an input or output before calling
|
|
||||||
| the muladd function in that this means that a NaN doesn't have its
|
|
||||||
| sign bit inverted before it is propagated.
|
|
||||||
| We also support halving the result before rounding, as a special
|
|
||||||
| case to support the ARM fused-sqrt-step instruction FRSQRTS.
|
|
||||||
*----------------------------------------------------------------------------*/
|
|
||||||
enum {
|
|
||||||
float_muladd_negate_c = 1,
|
|
||||||
float_muladd_negate_product = 2,
|
|
||||||
float_muladd_negate_result = 4,
|
|
||||||
float_muladd_halve_result = 8,
|
|
||||||
};
|
|
||||||
|
|
||||||
/*----------------------------------------------------------------------------
|
|
||||||
| Software IEC/IEEE integer-to-floating-point conversion routines.
|
|
||||||
*----------------------------------------------------------------------------*/
|
|
||||||
float32 int32_to_float32(int32_t, float_status *status);
|
|
||||||
float64 int32_to_float64(int32_t, float_status *status);
|
|
||||||
float32 uint32_to_float32(uint32_t, float_status *status);
|
|
||||||
float64 uint32_to_float64(uint32_t, float_status *status);
|
|
||||||
floatx80 int32_to_floatx80(int32_t, float_status *status);
|
|
||||||
float128 int32_to_float128(int32_t, float_status *status);
|
|
||||||
float32 int64_to_float32(int64_t, float_status *status);
|
|
||||||
float64 int64_to_float64(int64_t, float_status *status);
|
|
||||||
floatx80 int64_to_floatx80(int64_t, float_status *status);
|
|
||||||
float128 int64_to_float128(int64_t, float_status *status);
|
|
||||||
float32 uint64_to_float32(uint64_t, float_status *status);
|
|
||||||
float64 uint64_to_float64(uint64_t, float_status *status);
|
|
||||||
float128 uint64_to_float128(uint64_t, float_status *status);
|
|
||||||
|
|
||||||
/* We provide the int16 versions for symmetry of API with float-to-int */
|
|
||||||
static inline float32 int16_to_float32(int16_t v, float_status *status)
|
|
||||||
{
|
|
||||||
return int32_to_float32(v, status);
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline float32 uint16_to_float32(uint16_t v, float_status *status)
|
|
||||||
{
|
|
||||||
return uint32_to_float32(v, status);
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline float64 int16_to_float64(int16_t v, float_status *status)
|
|
||||||
{
|
|
||||||
return int32_to_float64(v, status);
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline float64 uint16_to_float64(uint16_t v, float_status *status)
|
|
||||||
{
|
|
||||||
return uint32_to_float64(v, status);
|
|
||||||
}
|
|
||||||
|
|
||||||
/*----------------------------------------------------------------------------
|
|
||||||
| Software half-precision conversion routines.
|
|
||||||
*----------------------------------------------------------------------------*/
|
|
||||||
float16 float32_to_float16(float32, flag, float_status *status);
|
|
||||||
float32 float16_to_float32(float16, flag, float_status *status);
|
|
||||||
float16 float64_to_float16(float64 a, flag ieee, float_status *status);
|
|
||||||
float64 float16_to_float64(float16 a, flag ieee, float_status *status);
|
|
||||||
|
|
||||||
/*----------------------------------------------------------------------------
|
|
||||||
| Software half-precision operations.
|
|
||||||
*----------------------------------------------------------------------------*/
|
|
||||||
int float16_is_quiet_nan( float16 );
|
|
||||||
int float16_is_signaling_nan( float16 );
|
|
||||||
float16 float16_maybe_silence_nan( float16 );
|
|
||||||
|
|
||||||
static inline int float16_is_any_nan(float16 a)
|
|
||||||
{
|
|
||||||
return ((float16_val(a) & ~0x8000) > 0x7c00);
|
|
||||||
}
|
|
||||||
|
|
||||||
/*----------------------------------------------------------------------------
|
|
||||||
| The pattern for a default generated half-precision NaN.
|
|
||||||
*----------------------------------------------------------------------------*/
|
|
||||||
extern const float16 float16_default_nan;
|
|
||||||
|
|
||||||
/*----------------------------------------------------------------------------
|
|
||||||
| Software IEC/IEEE single-precision conversion routines.
|
|
||||||
*----------------------------------------------------------------------------*/
|
|
||||||
int_fast16_t float32_to_int16(float32, float_status *status);
|
|
||||||
uint_fast16_t float32_to_uint16(float32, float_status *status);
|
|
||||||
int_fast16_t float32_to_int16_round_to_zero(float32, float_status *status);
|
|
||||||
uint_fast16_t float32_to_uint16_round_to_zero(float32, float_status *status);
|
|
||||||
int32 float32_to_int32(float32, float_status *status);
|
|
||||||
int32 float32_to_int32_round_to_zero(float32, float_status *status);
|
|
||||||
uint32 float32_to_uint32(float32, float_status *status);
|
|
||||||
uint32 float32_to_uint32_round_to_zero(float32, float_status *status);
|
|
||||||
int64 float32_to_int64(float32, float_status *status);
|
|
||||||
uint64 float32_to_uint64(float32, float_status *status);
|
|
||||||
uint64 float32_to_uint64_round_to_zero(float32, float_status *status);
|
|
||||||
int64 float32_to_int64_round_to_zero(float32, float_status *status);
|
|
||||||
float64 float32_to_float64(float32, float_status *status);
|
|
||||||
floatx80 float32_to_floatx80(float32, float_status *status);
|
|
||||||
float128 float32_to_float128(float32, float_status *status);
|
|
||||||
|
|
||||||
/*----------------------------------------------------------------------------
|
|
||||||
| Software IEC/IEEE single-precision operations.
|
|
||||||
*----------------------------------------------------------------------------*/
|
|
||||||
float32 float32_round_to_int(float32, float_status *status);
|
|
||||||
float32 float32_add(float32, float32, float_status *status);
|
|
||||||
float32 float32_sub(float32, float32, float_status *status);
|
|
||||||
float32 float32_mul(float32, float32, float_status *status);
|
|
||||||
float32 float32_div(float32, float32, float_status *status);
|
|
||||||
float32 float32_rem(float32, float32, float_status *status);
|
|
||||||
float32 float32_muladd(float32, float32, float32, int, float_status *status);
|
|
||||||
float32 float32_sqrt(float32, float_status *status);
|
|
||||||
float32 float32_exp2(float32, float_status *status);
|
|
||||||
float32 float32_log2(float32, float_status *status);
|
|
||||||
int float32_eq(float32, float32, float_status *status);
|
|
||||||
int float32_le(float32, float32, float_status *status);
|
|
||||||
int float32_lt(float32, float32, float_status *status);
|
|
||||||
int float32_unordered(float32, float32, float_status *status);
|
|
||||||
int float32_eq_quiet(float32, float32, float_status *status);
|
|
||||||
int float32_le_quiet(float32, float32, float_status *status);
|
|
||||||
int float32_lt_quiet(float32, float32, float_status *status);
|
|
||||||
int float32_unordered_quiet(float32, float32, float_status *status);
|
|
||||||
int float32_compare(float32, float32, float_status *status);
|
|
||||||
int float32_compare_quiet(float32, float32, float_status *status);
|
|
||||||
float32 float32_min(float32, float32, float_status *status);
|
|
||||||
float32 float32_max(float32, float32, float_status *status);
|
|
||||||
float32 float32_minnum(float32, float32, float_status *status);
|
|
||||||
float32 float32_maxnum(float32, float32, float_status *status);
|
|
||||||
float32 float32_minnummag(float32, float32, float_status *status);
|
|
||||||
float32 float32_maxnummag(float32, float32, float_status *status);
|
|
||||||
int float32_is_quiet_nan( float32 );
|
|
||||||
int float32_is_signaling_nan( float32 );
|
|
||||||
float32 float32_maybe_silence_nan( float32 );
|
|
||||||
float32 float32_scalbn(float32, int, float_status *status);
|
|
||||||
|
|
||||||
static inline float32 float32_abs(float32 a)
|
|
||||||
{
|
|
||||||
/* Note that abs does *not* handle NaN specially, nor does
|
|
||||||
* it flush denormal inputs to zero.
|
|
||||||
*/
|
|
||||||
return make_float32(float32_val(a) & 0x7fffffff);
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline float32 float32_chs(float32 a)
|
|
||||||
{
|
|
||||||
/* Note that chs does *not* handle NaN specially, nor does
|
|
||||||
* it flush denormal inputs to zero.
|
|
||||||
*/
|
|
||||||
return make_float32(float32_val(a) ^ 0x80000000);
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline int float32_is_infinity(float32 a)
|
|
||||||
{
|
|
||||||
return (float32_val(a) & 0x7fffffff) == 0x7f800000;
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline int float32_is_neg(float32 a)
|
|
||||||
{
|
|
||||||
return float32_val(a) >> 31;
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline int float32_is_zero(float32 a)
|
|
||||||
{
|
|
||||||
return (float32_val(a) & 0x7fffffff) == 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline int float32_is_any_nan(float32 a)
|
|
||||||
{
|
|
||||||
return ((float32_val(a) & ~(1 << 31)) > 0x7f800000UL);
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline int float32_is_zero_or_denormal(float32 a)
|
|
||||||
{
|
|
||||||
return (float32_val(a) & 0x7f800000) == 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline float32 float32_set_sign(float32 a, int sign)
|
|
||||||
{
|
|
||||||
return make_float32((float32_val(a) & 0x7fffffff) | (sign << 31));
|
|
||||||
}
|
|
||||||
|
|
||||||
#define float32_zero make_float32(0)
|
|
||||||
#define float32_one make_float32(0x3f800000)
|
|
||||||
#define float32_ln2 make_float32(0x3f317218)
|
|
||||||
#define float32_pi make_float32(0x40490fdb)
|
|
||||||
#define float32_half make_float32(0x3f000000)
|
|
||||||
#define float32_infinity make_float32(0x7f800000)
|
|
||||||
|
|
||||||
|
|
||||||
/*----------------------------------------------------------------------------
|
|
||||||
| The pattern for a default generated single-precision NaN.
|
|
||||||
*----------------------------------------------------------------------------*/
|
|
||||||
extern const float32 float32_default_nan;
|
|
||||||
|
|
||||||
/*----------------------------------------------------------------------------
|
|
||||||
| Software IEC/IEEE double-precision conversion routines.
|
|
||||||
*----------------------------------------------------------------------------*/
|
|
||||||
int_fast16_t float64_to_int16(float64, float_status *status);
|
|
||||||
uint_fast16_t float64_to_uint16(float64, float_status *status);
|
|
||||||
int_fast16_t float64_to_int16_round_to_zero(float64, float_status *status);
|
|
||||||
uint_fast16_t float64_to_uint16_round_to_zero(float64, float_status *status);
|
|
||||||
int32 float64_to_int32(float64, float_status *status);
|
|
||||||
int32 float64_to_int32_round_to_zero(float64, float_status *status);
|
|
||||||
uint32 float64_to_uint32(float64, float_status *status);
|
|
||||||
uint32 float64_to_uint32_round_to_zero(float64, float_status *status);
|
|
||||||
int64 float64_to_int64(float64, float_status *status);
|
|
||||||
int64 float64_to_int64_round_to_zero(float64, float_status *status);
|
|
||||||
uint64 float64_to_uint64(float64 a, float_status *status);
|
|
||||||
uint64 float64_to_uint64_round_to_zero(float64 a, float_status *status);
|
|
||||||
float32 float64_to_float32(float64, float_status *status);
|
|
||||||
floatx80 float64_to_floatx80(float64, float_status *status);
|
|
||||||
float128 float64_to_float128(float64, float_status *status);
|
|
||||||
|
|
||||||
/*----------------------------------------------------------------------------
|
|
||||||
| Software IEC/IEEE double-precision operations.
|
|
||||||
*----------------------------------------------------------------------------*/
|
|
||||||
float64 float64_round_to_int(float64, float_status *status);
|
|
||||||
float64 float64_trunc_to_int(float64, float_status *status);
|
|
||||||
float64 float64_add(float64, float64, float_status *status);
|
|
||||||
float64 float64_sub(float64, float64, float_status *status);
|
|
||||||
float64 float64_mul(float64, float64, float_status *status);
|
|
||||||
float64 float64_div(float64, float64, float_status *status);
|
|
||||||
float64 float64_rem(float64, float64, float_status *status);
|
|
||||||
float64 float64_muladd(float64, float64, float64, int, float_status *status);
|
|
||||||
float64 float64_sqrt(float64, float_status *status);
|
|
||||||
float64 float64_log2(float64, float_status *status);
|
|
||||||
int float64_eq(float64, float64, float_status *status);
|
|
||||||
int float64_le(float64, float64, float_status *status);
|
|
||||||
int float64_lt(float64, float64, float_status *status);
|
|
||||||
int float64_unordered(float64, float64, float_status *status);
|
|
||||||
int float64_eq_quiet(float64, float64, float_status *status);
|
|
||||||
int float64_le_quiet(float64, float64, float_status *status);
|
|
||||||
int float64_lt_quiet(float64, float64, float_status *status);
|
|
||||||
int float64_unordered_quiet(float64, float64, float_status *status);
|
|
||||||
int float64_compare(float64, float64, float_status *status);
|
|
||||||
int float64_compare_quiet(float64, float64, float_status *status);
|
|
||||||
float64 float64_min(float64, float64, float_status *status);
|
|
||||||
float64 float64_max(float64, float64, float_status *status);
|
|
||||||
float64 float64_minnum(float64, float64, float_status *status);
|
|
||||||
float64 float64_maxnum(float64, float64, float_status *status);
|
|
||||||
float64 float64_minnummag(float64, float64, float_status *status);
|
|
||||||
float64 float64_maxnummag(float64, float64, float_status *status);
|
|
||||||
int float64_is_quiet_nan( float64 a );
|
|
||||||
int float64_is_signaling_nan( float64 );
|
|
||||||
float64 float64_maybe_silence_nan( float64 );
|
|
||||||
float64 float64_scalbn(float64, int, float_status *status);
|
|
||||||
|
|
||||||
static inline float64 float64_abs(float64 a)
|
|
||||||
{
|
|
||||||
/* Note that abs does *not* handle NaN specially, nor does
|
|
||||||
* it flush denormal inputs to zero.
|
|
||||||
*/
|
|
||||||
return make_float64(float64_val(a) & 0x7fffffffffffffffLL);
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline float64 float64_chs(float64 a)
|
|
||||||
{
|
|
||||||
/* Note that chs does *not* handle NaN specially, nor does
|
|
||||||
* it flush denormal inputs to zero.
|
|
||||||
*/
|
|
||||||
return make_float64(float64_val(a) ^ 0x8000000000000000LL);
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline int float64_is_infinity(float64 a)
|
|
||||||
{
|
|
||||||
return (float64_val(a) & 0x7fffffffffffffffLL ) == 0x7ff0000000000000LL;
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline int float64_is_neg(float64 a)
|
|
||||||
{
|
|
||||||
return float64_val(a) >> 63;
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline int float64_is_zero(float64 a)
|
|
||||||
{
|
|
||||||
return (float64_val(a) & 0x7fffffffffffffffLL) == 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline int float64_is_any_nan(float64 a)
|
|
||||||
{
|
|
||||||
return ((float64_val(a) & ~(1ULL << 63)) > 0x7ff0000000000000ULL);
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline int float64_is_zero_or_denormal(float64 a)
|
|
||||||
{
|
|
||||||
return (float64_val(a) & 0x7ff0000000000000LL) == 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline float64 float64_set_sign(float64 a, int sign)
|
|
||||||
{
|
|
||||||
return make_float64((float64_val(a) & 0x7fffffffffffffffULL)
|
|
||||||
| ((int64_t)sign << 63));
|
|
||||||
}
|
|
||||||
|
|
||||||
#define float64_zero make_float64(0)
|
|
||||||
#define float64_one make_float64(0x3ff0000000000000LL)
|
|
||||||
#define float64_ln2 make_float64(0x3fe62e42fefa39efLL)
|
|
||||||
#define float64_pi make_float64(0x400921fb54442d18LL)
|
|
||||||
#define float64_half make_float64(0x3fe0000000000000LL)
|
|
||||||
#define float64_infinity make_float64(0x7ff0000000000000LL)
|
|
||||||
|
|
||||||
/*----------------------------------------------------------------------------
|
|
||||||
| The pattern for a default generated double-precision NaN.
|
|
||||||
*----------------------------------------------------------------------------*/
|
|
||||||
extern const float64 float64_default_nan;
|
|
||||||
|
|
||||||
/*----------------------------------------------------------------------------
|
|
||||||
| Software IEC/IEEE extended double-precision conversion routines.
|
|
||||||
*----------------------------------------------------------------------------*/
|
|
||||||
int32 floatx80_to_int32(floatx80, float_status *status);
|
|
||||||
int32 floatx80_to_int32_round_to_zero(floatx80, float_status *status);
|
|
||||||
int64 floatx80_to_int64(floatx80, float_status *status);
|
|
||||||
int64 floatx80_to_int64_round_to_zero(floatx80, float_status *status);
|
|
||||||
float32 floatx80_to_float32(floatx80, float_status *status);
|
|
||||||
float64 floatx80_to_float64(floatx80, float_status *status);
|
|
||||||
float128 floatx80_to_float128(floatx80, float_status *status);
|
|
||||||
|
|
||||||
/*----------------------------------------------------------------------------
|
|
||||||
| Software IEC/IEEE extended double-precision operations.
|
|
||||||
*----------------------------------------------------------------------------*/
|
|
||||||
floatx80 floatx80_round_to_int(floatx80, float_status *status);
|
|
||||||
floatx80 floatx80_add(floatx80, floatx80, float_status *status);
|
|
||||||
floatx80 floatx80_sub(floatx80, floatx80, float_status *status);
|
|
||||||
floatx80 floatx80_mul(floatx80, floatx80, float_status *status);
|
|
||||||
floatx80 floatx80_div(floatx80, floatx80, float_status *status);
|
|
||||||
floatx80 floatx80_rem(floatx80, floatx80, float_status *status);
|
|
||||||
floatx80 floatx80_sqrt(floatx80, float_status *status);
|
|
||||||
int floatx80_eq(floatx80, floatx80, float_status *status);
|
|
||||||
int floatx80_le(floatx80, floatx80, float_status *status);
|
|
||||||
int floatx80_lt(floatx80, floatx80, float_status *status);
|
|
||||||
int floatx80_unordered(floatx80, floatx80, float_status *status);
|
|
||||||
int floatx80_eq_quiet(floatx80, floatx80, float_status *status);
|
|
||||||
int floatx80_le_quiet(floatx80, floatx80, float_status *status);
|
|
||||||
int floatx80_lt_quiet(floatx80, floatx80, float_status *status);
|
|
||||||
int floatx80_unordered_quiet(floatx80, floatx80, float_status *status);
|
|
||||||
int floatx80_compare(floatx80, floatx80, float_status *status);
|
|
||||||
int floatx80_compare_quiet(floatx80, floatx80, float_status *status);
|
|
||||||
int floatx80_is_quiet_nan( floatx80 );
|
|
||||||
int floatx80_is_signaling_nan( floatx80 );
|
|
||||||
floatx80 floatx80_maybe_silence_nan( floatx80 );
|
|
||||||
floatx80 floatx80_scalbn(floatx80, int, float_status *status);
|
|
||||||
|
|
||||||
static inline floatx80 floatx80_abs(floatx80 a)
|
|
||||||
{
|
|
||||||
a.high &= 0x7fff;
|
|
||||||
return a;
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline floatx80 floatx80_chs(floatx80 a)
|
|
||||||
{
|
|
||||||
a.high ^= 0x8000;
|
|
||||||
return a;
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline int floatx80_is_infinity(floatx80 a)
|
|
||||||
{
|
|
||||||
return (a.high & 0x7fff) == 0x7fff && a.low == 0x8000000000000000LL;
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline int floatx80_is_neg(floatx80 a)
|
|
||||||
{
|
|
||||||
return a.high >> 15;
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline int floatx80_is_zero(floatx80 a)
|
|
||||||
{
|
|
||||||
return (a.high & 0x7fff) == 0 && a.low == 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline int floatx80_is_zero_or_denormal(floatx80 a)
|
|
||||||
{
|
|
||||||
return (a.high & 0x7fff) == 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline int floatx80_is_any_nan(floatx80 a)
|
|
||||||
{
|
|
||||||
return ((a.high & 0x7fff) == 0x7fff) && (a.low<<1);
|
|
||||||
}
|
|
||||||
|
|
||||||
#define floatx80_zero make_floatx80(0x0000, 0x0000000000000000LL)
|
|
||||||
#define floatx80_one make_floatx80(0x3fff, 0x8000000000000000LL)
|
|
||||||
#define floatx80_ln2 make_floatx80(0x3ffe, 0xb17217f7d1cf79acLL)
|
|
||||||
#define floatx80_pi make_floatx80(0x4000, 0xc90fdaa22168c235LL)
|
|
||||||
#define floatx80_half make_floatx80(0x3ffe, 0x8000000000000000LL)
|
|
||||||
#define floatx80_infinity make_floatx80(0x7fff, 0x8000000000000000LL)
|
|
||||||
|
|
||||||
/*----------------------------------------------------------------------------
|
|
||||||
| The pattern for a default generated extended double-precision NaN.
|
|
||||||
*----------------------------------------------------------------------------*/
|
|
||||||
extern const floatx80 floatx80_default_nan;
|
|
||||||
|
|
||||||
/*----------------------------------------------------------------------------
|
|
||||||
| Software IEC/IEEE quadruple-precision conversion routines.
|
|
||||||
*----------------------------------------------------------------------------*/
|
|
||||||
int32 float128_to_int32(float128, float_status *status);
|
|
||||||
int32 float128_to_int32_round_to_zero(float128, float_status *status);
|
|
||||||
int64 float128_to_int64(float128, float_status *status);
|
|
||||||
int64 float128_to_int64_round_to_zero(float128, float_status *status);
|
|
||||||
float32 float128_to_float32(float128, float_status *status);
|
|
||||||
float64 float128_to_float64(float128, float_status *status);
|
|
||||||
floatx80 float128_to_floatx80(float128, float_status *status);
|
|
||||||
|
|
||||||
/*----------------------------------------------------------------------------
|
|
||||||
| Software IEC/IEEE quadruple-precision operations.
|
|
||||||
*----------------------------------------------------------------------------*/
|
|
||||||
float128 float128_round_to_int(float128, float_status *status);
|
|
||||||
float128 float128_add(float128, float128, float_status *status);
|
|
||||||
float128 float128_sub(float128, float128, float_status *status);
|
|
||||||
float128 float128_mul(float128, float128, float_status *status);
|
|
||||||
float128 float128_div(float128, float128, float_status *status);
|
|
||||||
float128 float128_rem(float128, float128, float_status *status);
|
|
||||||
float128 float128_sqrt(float128, float_status *status);
|
|
||||||
int float128_eq(float128, float128, float_status *status);
|
|
||||||
int float128_le(float128, float128, float_status *status);
|
|
||||||
int float128_lt(float128, float128, float_status *status);
|
|
||||||
int float128_unordered(float128, float128, float_status *status);
|
|
||||||
int float128_eq_quiet(float128, float128, float_status *status);
|
|
||||||
int float128_le_quiet(float128, float128, float_status *status);
|
|
||||||
int float128_lt_quiet(float128, float128, float_status *status);
|
|
||||||
int float128_unordered_quiet(float128, float128, float_status *status);
|
|
||||||
int float128_compare(float128, float128, float_status *status);
|
|
||||||
int float128_compare_quiet(float128, float128, float_status *status);
|
|
||||||
int float128_is_quiet_nan( float128 );
|
|
||||||
int float128_is_signaling_nan( float128 );
|
|
||||||
float128 float128_maybe_silence_nan( float128 );
|
|
||||||
float128 float128_scalbn(float128, int, float_status *status);
|
|
||||||
|
|
||||||
static inline float128 float128_abs(float128 a)
|
|
||||||
{
|
|
||||||
a.high &= 0x7fffffffffffffffLL;
|
|
||||||
return a;
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline float128 float128_chs(float128 a)
|
|
||||||
{
|
|
||||||
a.high ^= 0x8000000000000000LL;
|
|
||||||
return a;
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline int float128_is_infinity(float128 a)
|
|
||||||
{
|
|
||||||
return (a.high & 0x7fffffffffffffffLL) == 0x7fff000000000000LL && a.low == 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline int float128_is_neg(float128 a)
|
|
||||||
{
|
|
||||||
return a.high >> 63;
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline int float128_is_zero(float128 a)
|
|
||||||
{
|
|
||||||
return (a.high & 0x7fffffffffffffffLL) == 0 && a.low == 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline int float128_is_zero_or_denormal(float128 a)
|
|
||||||
{
|
|
||||||
return (a.high & 0x7fff000000000000LL) == 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline int float128_is_any_nan(float128 a)
|
|
||||||
{
|
|
||||||
return ((a.high >> 48) & 0x7fff) == 0x7fff &&
|
|
||||||
((a.low != 0) || ((a.high & 0xffffffffffffLL) != 0));
|
|
||||||
}
|
|
||||||
|
|
||||||
#define float128_zero make_float128(0, 0)
|
|
||||||
|
|
||||||
/*----------------------------------------------------------------------------
|
|
||||||
| The pattern for a default generated quadruple-precision NaN.
|
|
||||||
*----------------------------------------------------------------------------*/
|
|
||||||
extern const float128 float128_default_nan;
|
|
||||||
|
|
||||||
#endif /* !SOFTFLOAT_H */
|
|
|
@ -1,168 +0,0 @@
|
||||||
/*
|
|
||||||
* GLIB Compatibility Functions
|
|
||||||
*
|
|
||||||
* Copyright IBM, Corp. 2013
|
|
||||||
*
|
|
||||||
* Authors:
|
|
||||||
* Anthony Liguori <aliguori@us.ibm.com>
|
|
||||||
* Michael Tokarev <mjt@tls.msk.ru>
|
|
||||||
* Paolo Bonzini <pbonzini@redhat.com>
|
|
||||||
*
|
|
||||||
* This work is licensed under the terms of the GNU GPL, version 2 or later.
|
|
||||||
* See the COPYING file in the top-level directory.
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef QEMU_GLIB_COMPAT_H
|
|
||||||
#define QEMU_GLIB_COMPAT_H
|
|
||||||
|
|
||||||
#include <glib.h>
|
|
||||||
|
|
||||||
/* GLIB version compatibility flags */
|
|
||||||
#if !GLIB_CHECK_VERSION(2, 26, 0)
|
|
||||||
#define G_TIME_SPAN_SECOND (G_GINT64_CONSTANT(1000000))
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if !GLIB_CHECK_VERSION(2, 28, 0)
|
|
||||||
static inline gint64 qemu_g_get_monotonic_time(void)
|
|
||||||
{
|
|
||||||
/* g_get_monotonic_time() is best-effort so we can use the wall clock as a
|
|
||||||
* fallback.
|
|
||||||
*/
|
|
||||||
|
|
||||||
GTimeVal time;
|
|
||||||
g_get_current_time(&time);
|
|
||||||
|
|
||||||
return time.tv_sec * G_TIME_SPAN_SECOND + time.tv_usec;
|
|
||||||
}
|
|
||||||
/* work around distro backports of this interface */
|
|
||||||
#define g_get_monotonic_time() qemu_g_get_monotonic_time()
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef _WIN32
|
|
||||||
/*
|
|
||||||
* g_poll has a problem on Windows when using
|
|
||||||
* timeouts < 10ms, so use wrapper.
|
|
||||||
*/
|
|
||||||
#define g_poll(fds, nfds, timeout) g_poll_fixed(fds, nfds, timeout)
|
|
||||||
gint g_poll_fixed(GPollFD *fds, guint nfds, gint timeout);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if !GLIB_CHECK_VERSION(2, 31, 0)
|
|
||||||
/* before glib-2.31, GMutex and GCond was dynamic-only (there was a separate
|
|
||||||
* GStaticMutex, but it didn't work with condition variables).
|
|
||||||
*
|
|
||||||
* Our implementation uses GOnce to fake a static implementation that does
|
|
||||||
* not require separate initialization.
|
|
||||||
* We need to rename the types to avoid passing our CompatGMutex/CompatGCond
|
|
||||||
* by mistake to a function that expects GMutex/GCond. However, for ease
|
|
||||||
* of use we keep the GLib function names. GLib uses macros for the
|
|
||||||
* implementation, we use inline functions instead and undefine the macros.
|
|
||||||
*/
|
|
||||||
|
|
||||||
typedef struct CompatGMutex {
|
|
||||||
GOnce once;
|
|
||||||
} CompatGMutex;
|
|
||||||
|
|
||||||
typedef struct CompatGCond {
|
|
||||||
GOnce once;
|
|
||||||
} CompatGCond;
|
|
||||||
|
|
||||||
static inline gpointer do_g_mutex_new(gpointer unused)
|
|
||||||
{
|
|
||||||
return (gpointer) g_mutex_new();
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline void g_mutex_init(CompatGMutex *mutex)
|
|
||||||
{
|
|
||||||
mutex->once = (GOnce) G_ONCE_INIT;
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline void g_mutex_clear(CompatGMutex *mutex)
|
|
||||||
{
|
|
||||||
g_assert(mutex->once.status != G_ONCE_STATUS_PROGRESS);
|
|
||||||
if (mutex->once.retval) {
|
|
||||||
g_mutex_free((GMutex *) mutex->once.retval);
|
|
||||||
}
|
|
||||||
mutex->once = (GOnce) G_ONCE_INIT;
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline void (g_mutex_lock)(CompatGMutex *mutex)
|
|
||||||
{
|
|
||||||
g_once(&mutex->once, do_g_mutex_new, NULL);
|
|
||||||
g_mutex_lock((GMutex *) mutex->once.retval);
|
|
||||||
}
|
|
||||||
#undef g_mutex_lock
|
|
||||||
|
|
||||||
static inline gboolean (g_mutex_trylock)(CompatGMutex *mutex)
|
|
||||||
{
|
|
||||||
g_once(&mutex->once, do_g_mutex_new, NULL);
|
|
||||||
return g_mutex_trylock((GMutex *) mutex->once.retval);
|
|
||||||
}
|
|
||||||
#undef g_mutex_trylock
|
|
||||||
|
|
||||||
|
|
||||||
static inline void (g_mutex_unlock)(CompatGMutex *mutex)
|
|
||||||
{
|
|
||||||
g_mutex_unlock((GMutex *) mutex->once.retval);
|
|
||||||
}
|
|
||||||
#undef g_mutex_unlock
|
|
||||||
|
|
||||||
static inline gpointer do_g_cond_new(gpointer unused)
|
|
||||||
{
|
|
||||||
return (gpointer) g_cond_new();
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline void g_cond_init(CompatGCond *cond)
|
|
||||||
{
|
|
||||||
cond->once = (GOnce) G_ONCE_INIT;
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline void g_cond_clear(CompatGCond *cond)
|
|
||||||
{
|
|
||||||
g_assert(cond->once.status != G_ONCE_STATUS_PROGRESS);
|
|
||||||
if (cond->once.retval) {
|
|
||||||
g_cond_free((GCond *) cond->once.retval);
|
|
||||||
}
|
|
||||||
cond->once = (GOnce) G_ONCE_INIT;
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline void (g_cond_wait)(CompatGCond *cond, CompatGMutex *mutex)
|
|
||||||
{
|
|
||||||
g_assert(mutex->once.status != G_ONCE_STATUS_PROGRESS);
|
|
||||||
g_once(&cond->once, do_g_cond_new, NULL);
|
|
||||||
g_cond_wait((GCond *) cond->once.retval, (GMutex *) mutex->once.retval);
|
|
||||||
}
|
|
||||||
#undef g_cond_wait
|
|
||||||
|
|
||||||
static inline void (g_cond_broadcast)(CompatGCond *cond)
|
|
||||||
{
|
|
||||||
g_once(&cond->once, do_g_cond_new, NULL);
|
|
||||||
g_cond_broadcast((GCond *) cond->once.retval);
|
|
||||||
}
|
|
||||||
#undef g_cond_broadcast
|
|
||||||
|
|
||||||
static inline void (g_cond_signal)(CompatGCond *cond)
|
|
||||||
{
|
|
||||||
g_once(&cond->once, do_g_cond_new, NULL);
|
|
||||||
g_cond_signal((GCond *) cond->once.retval);
|
|
||||||
}
|
|
||||||
#undef g_cond_signal
|
|
||||||
|
|
||||||
|
|
||||||
/* before 2.31 there was no g_thread_new() */
|
|
||||||
static inline GThread *g_thread_new(const char *name,
|
|
||||||
GThreadFunc func, gpointer data)
|
|
||||||
{
|
|
||||||
GThread *thread = g_thread_create(func, data, TRUE, NULL);
|
|
||||||
if (!thread) {
|
|
||||||
g_error("creating thread");
|
|
||||||
}
|
|
||||||
return thread;
|
|
||||||
}
|
|
||||||
#else
|
|
||||||
#define CompatGMutex GMutex
|
|
||||||
#define CompatGCond GCond
|
|
||||||
#endif /* glib 2.31 */
|
|
||||||
|
|
||||||
#endif
|
|
|
@ -1,71 +0,0 @@
|
||||||
/* Declarations for use by hardware emulation. */
|
|
||||||
#if 0
|
|
||||||
#ifndef QEMU_HW_H
|
|
||||||
#define QEMU_HW_H
|
|
||||||
|
|
||||||
#include "qemu-common.h"
|
|
||||||
|
|
||||||
#if !defined(CONFIG_USER_ONLY) && !defined(NEED_CPU_H)
|
|
||||||
#include "exec/cpu-common.h"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#include "exec/ioport.h"
|
|
||||||
#include "hw/irq.h"
|
|
||||||
#include "block/aio.h"
|
|
||||||
#include "migration/vmstate.h"
|
|
||||||
#include "qemu/log.h"
|
|
||||||
|
|
||||||
#ifdef NEED_CPU_H
|
|
||||||
#if TARGET_LONG_BITS == 64
|
|
||||||
#define qemu_put_betl qemu_put_be64
|
|
||||||
#define qemu_get_betl qemu_get_be64
|
|
||||||
#define qemu_put_betls qemu_put_be64s
|
|
||||||
#define qemu_get_betls qemu_get_be64s
|
|
||||||
#define qemu_put_sbetl qemu_put_sbe64
|
|
||||||
#define qemu_get_sbetl qemu_get_sbe64
|
|
||||||
#define qemu_put_sbetls qemu_put_sbe64s
|
|
||||||
#define qemu_get_sbetls qemu_get_sbe64s
|
|
||||||
#else
|
|
||||||
#define qemu_put_betl qemu_put_be32
|
|
||||||
#define qemu_get_betl qemu_get_be32
|
|
||||||
#define qemu_put_betls qemu_put_be32s
|
|
||||||
#define qemu_get_betls qemu_get_be32s
|
|
||||||
#define qemu_put_sbetl qemu_put_sbe32
|
|
||||||
#define qemu_get_sbetl qemu_get_sbe32
|
|
||||||
#define qemu_put_sbetls qemu_put_sbe32s
|
|
||||||
#define qemu_get_sbetls qemu_get_sbe32s
|
|
||||||
#endif
|
|
||||||
#endif
|
|
||||||
|
|
||||||
typedef void QEMUResetHandler(void *opaque);
|
|
||||||
|
|
||||||
void qemu_register_reset(QEMUResetHandler *func, void *opaque);
|
|
||||||
void qemu_unregister_reset(QEMUResetHandler *func, void *opaque);
|
|
||||||
|
|
||||||
#ifdef NEED_CPU_H
|
|
||||||
#if TARGET_LONG_BITS == 64
|
|
||||||
#define VMSTATE_UINTTL_V(_f, _s, _v) \
|
|
||||||
VMSTATE_UINT64_V(_f, _s, _v)
|
|
||||||
#define VMSTATE_UINTTL_EQUAL_V(_f, _s, _v) \
|
|
||||||
VMSTATE_UINT64_EQUAL_V(_f, _s, _v)
|
|
||||||
#define VMSTATE_UINTTL_ARRAY_V(_f, _s, _n, _v) \
|
|
||||||
VMSTATE_UINT64_ARRAY_V(_f, _s, _n, _v)
|
|
||||||
#else
|
|
||||||
#define VMSTATE_UINTTL_V(_f, _s, _v) \
|
|
||||||
VMSTATE_UINT32_V(_f, _s, _v)
|
|
||||||
#define VMSTATE_UINTTL_EQUAL_V(_f, _s, _v) \
|
|
||||||
VMSTATE_UINT32_EQUAL_V(_f, _s, _v)
|
|
||||||
#define VMSTATE_UINTTL_ARRAY_V(_f, _s, _n, _v) \
|
|
||||||
VMSTATE_UINT32_ARRAY_V(_f, _s, _n, _v)
|
|
||||||
#endif
|
|
||||||
#define VMSTATE_UINTTL(_f, _s) \
|
|
||||||
VMSTATE_UINTTL_V(_f, _s, 0)
|
|
||||||
#define VMSTATE_UINTTL_EQUAL(_f, _s) \
|
|
||||||
VMSTATE_UINTTL_EQUAL_V(_f, _s, 0)
|
|
||||||
#define VMSTATE_UINTTL_ARRAY(_f, _s, _n) \
|
|
||||||
VMSTATE_UINTTL_ARRAY_V(_f, _s, _n, 0)
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#endif
|
|
||||||
#endif
|
|
|
@ -1,154 +0,0 @@
|
||||||
#ifndef INT128_H
|
|
||||||
#define INT128_H
|
|
||||||
|
|
||||||
#include <assert.h>
|
|
||||||
#ifdef _MSC_VER
|
|
||||||
#include <win32/stdint.h>
|
|
||||||
#include <win32/stdbool.h>
|
|
||||||
#else
|
|
||||||
#include <stdint.h>
|
|
||||||
#include <stdbool.h>
|
|
||||||
#endif
|
|
||||||
|
|
||||||
typedef struct Int128 Int128;
|
|
||||||
|
|
||||||
struct Int128 {
|
|
||||||
uint64_t lo;
|
|
||||||
int64_t hi;
|
|
||||||
};
|
|
||||||
|
|
||||||
static inline Int128 int128_make64(uint64_t a)
|
|
||||||
{
|
|
||||||
return (Int128) { a, 0 };
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline uint64_t int128_get64(Int128 a)
|
|
||||||
{
|
|
||||||
assert(!a.hi);
|
|
||||||
return a.lo;
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline Int128 int128_zero(void)
|
|
||||||
{
|
|
||||||
return int128_make64(0);
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline Int128 int128_one(void)
|
|
||||||
{
|
|
||||||
return int128_make64(1);
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline Int128 int128_2_64(void)
|
|
||||||
{
|
|
||||||
return (Int128) { 0, 1 };
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline Int128 int128_exts64(int64_t a)
|
|
||||||
{
|
|
||||||
return (Int128) { .lo = a, .hi = (a < 0) ? -1 : 0 };
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline Int128 int128_and(Int128 a, Int128 b)
|
|
||||||
{
|
|
||||||
return (Int128) { a.lo & b.lo, a.hi & b.hi };
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline Int128 int128_rshift(Int128 a, int n)
|
|
||||||
{
|
|
||||||
int64_t h;
|
|
||||||
if (!n) {
|
|
||||||
return a;
|
|
||||||
}
|
|
||||||
h = a.hi >> (n & 63);
|
|
||||||
if (n >= 64) {
|
|
||||||
return (Int128) { h, h >> 63 };
|
|
||||||
} else {
|
|
||||||
return (Int128) { (a.lo >> n) | ((uint64_t)a.hi << (64 - n)), h };
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline Int128 int128_add(Int128 a, Int128 b)
|
|
||||||
{
|
|
||||||
uint64_t lo = a.lo + b.lo;
|
|
||||||
|
|
||||||
/* a.lo <= a.lo + b.lo < a.lo + k (k is the base, 2^64). Hence,
|
|
||||||
* a.lo + b.lo >= k implies 0 <= lo = a.lo + b.lo - k < a.lo.
|
|
||||||
* Similarly, a.lo + b.lo < k implies a.lo <= lo = a.lo + b.lo < k.
|
|
||||||
*
|
|
||||||
* So the carry is lo < a.lo.
|
|
||||||
*/
|
|
||||||
return (Int128) { lo, (uint64_t)a.hi + b.hi + (lo < a.lo) };
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline Int128 int128_neg(Int128 a)
|
|
||||||
{
|
|
||||||
uint64_t lo = -a.lo;
|
|
||||||
return (Int128) { lo, ~(uint64_t)a.hi + !lo };
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline Int128 int128_sub(Int128 a, Int128 b)
|
|
||||||
{
|
|
||||||
return (Int128){ a.lo - b.lo, (uint64_t)a.hi - b.hi - (a.lo < b.lo) };
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline bool int128_nonneg(Int128 a)
|
|
||||||
{
|
|
||||||
return a.hi >= 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline bool int128_eq(Int128 a, Int128 b)
|
|
||||||
{
|
|
||||||
return a.lo == b.lo && a.hi == b.hi;
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline bool int128_ne(Int128 a, Int128 b)
|
|
||||||
{
|
|
||||||
return !int128_eq(a, b);
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline bool int128_ge(Int128 a, Int128 b)
|
|
||||||
{
|
|
||||||
return a.hi > b.hi || (a.hi == b.hi && a.lo >= b.lo);
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline bool int128_lt(Int128 a, Int128 b)
|
|
||||||
{
|
|
||||||
return !int128_ge(a, b);
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline bool int128_le(Int128 a, Int128 b)
|
|
||||||
{
|
|
||||||
return int128_ge(b, a);
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline bool int128_gt(Int128 a, Int128 b)
|
|
||||||
{
|
|
||||||
return !int128_le(a, b);
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline bool int128_nz(Int128 a)
|
|
||||||
{
|
|
||||||
return a.lo || a.hi;
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline Int128 int128_min(Int128 a, Int128 b)
|
|
||||||
{
|
|
||||||
return int128_le(a, b) ? a : b;
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline Int128 int128_max(Int128 a, Int128 b)
|
|
||||||
{
|
|
||||||
return int128_ge(a, b) ? a : b;
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline void int128_addto(Int128 *a, Int128 b)
|
|
||||||
{
|
|
||||||
*a = int128_add(*a, b);
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline void int128_subfrom(Int128 *a, Int128 b)
|
|
||||||
{
|
|
||||||
*a = int128_sub(*a, b);
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif
|
|
|
@ -1,273 +0,0 @@
|
||||||
/*
|
|
||||||
* QEMU System Emulator
|
|
||||||
*
|
|
||||||
* Copyright (c) 2003-2008 Fabrice Bellard
|
|
||||||
*
|
|
||||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
||||||
* of this software and associated documentation files (the "Software"), to deal
|
|
||||||
* in the Software without restriction, including without limitation the rights
|
|
||||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
||||||
* copies of the Software, and to permit persons to whom the Software is
|
|
||||||
* furnished to do so, subject to the following conditions:
|
|
||||||
*
|
|
||||||
* The above copyright notice and this permission notice shall be included in
|
|
||||||
* all copies or substantial portions of the Software.
|
|
||||||
*
|
|
||||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
||||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
||||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
|
||||||
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
||||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
||||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
|
||||||
* THE SOFTWARE.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef QEMU_MAIN_LOOP_H
|
|
||||||
#define QEMU_MAIN_LOOP_H 1
|
|
||||||
|
|
||||||
#include "block/aio.h"
|
|
||||||
|
|
||||||
#define SIG_IPI SIGUSR1
|
|
||||||
|
|
||||||
/**
|
|
||||||
* qemu_init_main_loop: Set up the process so that it can run the main loop.
|
|
||||||
*
|
|
||||||
* This includes setting up signal handlers. It should be called before
|
|
||||||
* any other threads are created. In addition, threads other than the
|
|
||||||
* main one should block signals that are trapped by the main loop.
|
|
||||||
* For simplicity, you can consider these signals to be safe: SIGUSR1,
|
|
||||||
* SIGUSR2, thread signals (SIGFPE, SIGILL, SIGSEGV, SIGBUS) and real-time
|
|
||||||
* signals if available. Remember that Windows in practice does not have
|
|
||||||
* signals, though.
|
|
||||||
*
|
|
||||||
* In the case of QEMU tools, this will also start/initialize timers.
|
|
||||||
*/
|
|
||||||
int qemu_init_main_loop(Error **errp);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* main_loop_wait: Run one iteration of the main loop.
|
|
||||||
*
|
|
||||||
* If @nonblocking is true, poll for events, otherwise suspend until
|
|
||||||
* one actually occurs. The main loop usually consists of a loop that
|
|
||||||
* repeatedly calls main_loop_wait(false).
|
|
||||||
*
|
|
||||||
* Main loop services include file descriptor callbacks, bottom halves
|
|
||||||
* and timers (defined in qemu/timer.h). Bottom halves are similar to timers
|
|
||||||
* that execute immediately, but have a lower overhead and scheduling them
|
|
||||||
* is wait-free, thread-safe and signal-safe.
|
|
||||||
*
|
|
||||||
* It is sometimes useful to put a whole program in a coroutine. In this
|
|
||||||
* case, the coroutine actually should be started from within the main loop,
|
|
||||||
* so that the main loop can run whenever the coroutine yields. To do this,
|
|
||||||
* you can use a bottom half to enter the coroutine as soon as the main loop
|
|
||||||
* starts:
|
|
||||||
*
|
|
||||||
* void enter_co_bh(void *opaque) {
|
|
||||||
* QEMUCoroutine *co = opaque;
|
|
||||||
* qemu_coroutine_enter(co, NULL);
|
|
||||||
* }
|
|
||||||
*
|
|
||||||
* ...
|
|
||||||
* QEMUCoroutine *co = qemu_coroutine_create(coroutine_entry);
|
|
||||||
* QEMUBH *start_bh = qemu_bh_new(enter_co_bh, co);
|
|
||||||
* qemu_bh_schedule(start_bh);
|
|
||||||
* while (...) {
|
|
||||||
* main_loop_wait(false);
|
|
||||||
* }
|
|
||||||
*
|
|
||||||
* (In the future we may provide a wrapper for this).
|
|
||||||
*
|
|
||||||
* @nonblocking: Whether the caller should block until an event occurs.
|
|
||||||
*/
|
|
||||||
int main_loop_wait(int nonblocking);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* qemu_get_aio_context: Return the main loop's AioContext
|
|
||||||
*/
|
|
||||||
AioContext *qemu_get_aio_context(void);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* qemu_notify_event: Force processing of pending events.
|
|
||||||
*
|
|
||||||
* Similar to signaling a condition variable, qemu_notify_event forces
|
|
||||||
* main_loop_wait to look at pending events and exit. The caller of
|
|
||||||
* main_loop_wait will usually call it again very soon, so qemu_notify_event
|
|
||||||
* also has the side effect of recalculating the sets of file descriptors
|
|
||||||
* that the main loop waits for.
|
|
||||||
*
|
|
||||||
* Calling qemu_notify_event is rarely necessary, because main loop
|
|
||||||
* services (bottom halves and timers) call it themselves.
|
|
||||||
*/
|
|
||||||
void qemu_notify_event(void);
|
|
||||||
|
|
||||||
#ifdef _WIN32
|
|
||||||
/* return TRUE if no sleep should be done afterwards */
|
|
||||||
typedef int PollingFunc(void *opaque);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* qemu_add_polling_cb: Register a Windows-specific polling callback
|
|
||||||
*
|
|
||||||
* Currently, under Windows some events are polled rather than waited for.
|
|
||||||
* Polling callbacks do not ensure that @func is called timely, because
|
|
||||||
* the main loop might wait for an arbitrarily long time. If possible,
|
|
||||||
* you should instead create a separate thread that does a blocking poll
|
|
||||||
* and set a Win32 event object. The event can then be passed to
|
|
||||||
* qemu_add_wait_object.
|
|
||||||
*
|
|
||||||
* Polling callbacks really have nothing Windows specific in them, but
|
|
||||||
* as they are a hack and are currently not necessary under POSIX systems,
|
|
||||||
* they are only available when QEMU is running under Windows.
|
|
||||||
*
|
|
||||||
* @func: The function that does the polling, and returns 1 to force
|
|
||||||
* immediate completion of main_loop_wait.
|
|
||||||
* @opaque: A pointer-size value that is passed to @func.
|
|
||||||
*/
|
|
||||||
int qemu_add_polling_cb(PollingFunc *func, void *opaque);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* qemu_del_polling_cb: Unregister a Windows-specific polling callback
|
|
||||||
*
|
|
||||||
* This function removes a callback that was registered with
|
|
||||||
* qemu_add_polling_cb.
|
|
||||||
*
|
|
||||||
* @func: The function that was passed to qemu_add_polling_cb.
|
|
||||||
* @opaque: A pointer-size value that was passed to qemu_add_polling_cb.
|
|
||||||
*/
|
|
||||||
void qemu_del_polling_cb(PollingFunc *func, void *opaque);
|
|
||||||
|
|
||||||
/* Wait objects handling */
|
|
||||||
typedef void WaitObjectFunc(void *opaque);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* qemu_add_wait_object: Register a callback for a Windows handle
|
|
||||||
*
|
|
||||||
* Under Windows, the iohandler mechanism can only be used with sockets.
|
|
||||||
* QEMU must use the WaitForMultipleObjects API to wait on other handles.
|
|
||||||
* This function registers a #HANDLE with QEMU, so that it will be included
|
|
||||||
* in the main loop's calls to WaitForMultipleObjects. When the handle
|
|
||||||
* is in a signaled state, QEMU will call @func.
|
|
||||||
*
|
|
||||||
* @handle: The Windows handle to be observed.
|
|
||||||
* @func: A function to be called when @handle is in a signaled state.
|
|
||||||
* @opaque: A pointer-size value that is passed to @func.
|
|
||||||
*/
|
|
||||||
int qemu_add_wait_object(HANDLE handle, WaitObjectFunc *func, void *opaque);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* qemu_del_wait_object: Unregister a callback for a Windows handle
|
|
||||||
*
|
|
||||||
* This function removes a callback that was registered with
|
|
||||||
* qemu_add_wait_object.
|
|
||||||
*
|
|
||||||
* @func: The function that was passed to qemu_add_wait_object.
|
|
||||||
* @opaque: A pointer-size value that was passed to qemu_add_wait_object.
|
|
||||||
*/
|
|
||||||
void qemu_del_wait_object(HANDLE handle, WaitObjectFunc *func, void *opaque);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* async I/O support */
|
|
||||||
|
|
||||||
typedef void IOReadHandler(void *opaque, const uint8_t *buf, int size);
|
|
||||||
typedef int IOCanReadHandler(void *opaque);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* qemu_set_fd_handler: Register a file descriptor with the main loop
|
|
||||||
*
|
|
||||||
* This function tells the main loop to wake up whenever one of the
|
|
||||||
* following conditions is true:
|
|
||||||
*
|
|
||||||
* 1) if @fd_write is not %NULL, when the file descriptor is writable;
|
|
||||||
*
|
|
||||||
* 2) if @fd_read is not %NULL, when the file descriptor is readable.
|
|
||||||
*
|
|
||||||
* The callbacks that are set up by qemu_set_fd_handler are level-triggered.
|
|
||||||
* If @fd_read does not read from @fd, or @fd_write does not write to @fd
|
|
||||||
* until its buffers are full, they will be called again on the next
|
|
||||||
* iteration.
|
|
||||||
*
|
|
||||||
* @fd: The file descriptor to be observed. Under Windows it must be
|
|
||||||
* a #SOCKET.
|
|
||||||
*
|
|
||||||
* @fd_read: A level-triggered callback that is fired if @fd is readable
|
|
||||||
* at the beginning of a main loop iteration, or if it becomes readable
|
|
||||||
* during one.
|
|
||||||
*
|
|
||||||
* @fd_write: A level-triggered callback that is fired when @fd is writable
|
|
||||||
* at the beginning of a main loop iteration, or if it becomes writable
|
|
||||||
* during one.
|
|
||||||
*
|
|
||||||
* @opaque: A pointer-sized value that is passed to @fd_read and @fd_write.
|
|
||||||
*/
|
|
||||||
void qemu_set_fd_handler(int fd,
|
|
||||||
IOHandler *fd_read,
|
|
||||||
IOHandler *fd_write,
|
|
||||||
void *opaque);
|
|
||||||
|
|
||||||
GSource *iohandler_get_g_source(void);
|
|
||||||
#ifdef CONFIG_POSIX
|
|
||||||
/**
|
|
||||||
* qemu_add_child_watch: Register a child process for reaping.
|
|
||||||
*
|
|
||||||
* Under POSIX systems, a parent process must read the exit status of
|
|
||||||
* its child processes using waitpid, or the operating system will not
|
|
||||||
* free some of the resources attached to that process.
|
|
||||||
*
|
|
||||||
* This function directs the QEMU main loop to observe a child process
|
|
||||||
* and call waitpid as soon as it exits; the watch is then removed
|
|
||||||
* automatically. It is useful whenever QEMU forks a child process
|
|
||||||
* but will find out about its termination by other means such as a
|
|
||||||
* "broken pipe".
|
|
||||||
*
|
|
||||||
* @pid: The pid that QEMU should observe.
|
|
||||||
*/
|
|
||||||
int qemu_add_child_watch(pid_t pid);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/**
|
|
||||||
* qemu_mutex_iothread_locked: Return lock status of the main loop mutex.
|
|
||||||
*
|
|
||||||
* The main loop mutex is the coarsest lock in QEMU, and as such it
|
|
||||||
* must always be taken outside other locks. This function helps
|
|
||||||
* functions take different paths depending on whether the current
|
|
||||||
* thread is running within the main loop mutex.
|
|
||||||
*/
|
|
||||||
bool qemu_mutex_iothread_locked(void);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* qemu_mutex_lock_iothread: Lock the main loop mutex.
|
|
||||||
*
|
|
||||||
* This function locks the main loop mutex. The mutex is taken by
|
|
||||||
* qemu_init_main_loop and always taken except while waiting on
|
|
||||||
* external events (such as with select). The mutex should be taken
|
|
||||||
* by threads other than the main loop thread when calling
|
|
||||||
* qemu_bh_new(), qemu_set_fd_handler() and basically all other
|
|
||||||
* functions documented in this file.
|
|
||||||
*
|
|
||||||
* NOTE: tools currently are single-threaded and qemu_mutex_lock_iothread
|
|
||||||
* is a no-op there.
|
|
||||||
*/
|
|
||||||
void qemu_mutex_lock_iothread(void);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* qemu_mutex_unlock_iothread: Unlock the main loop mutex.
|
|
||||||
*
|
|
||||||
* This function unlocks the main loop mutex. The mutex is taken by
|
|
||||||
* qemu_init_main_loop and always taken except while waiting on
|
|
||||||
* external events (such as with select). The mutex should be unlocked
|
|
||||||
* as soon as possible by threads other than the main loop thread,
|
|
||||||
* because it prevents the main loop from processing callbacks,
|
|
||||||
* including timers and bottom halves.
|
|
||||||
*
|
|
||||||
* NOTE: tools currently are single-threaded and qemu_mutex_unlock_iothread
|
|
||||||
* is a no-op there.
|
|
||||||
*/
|
|
||||||
void qemu_mutex_unlock_iothread(void);
|
|
||||||
|
|
||||||
/* internal interfaces */
|
|
||||||
|
|
||||||
void qemu_fd_register(int fd);
|
|
||||||
|
|
||||||
QEMUBH *qemu_bh_new(QEMUBHFunc *cb, void *opaque);
|
|
||||||
void qemu_bh_schedule_idle(QEMUBH *bh);
|
|
||||||
|
|
||||||
#endif
|
|
|
@ -1,61 +0,0 @@
|
||||||
/*
|
|
||||||
* QEMU Module Infrastructure
|
|
||||||
*
|
|
||||||
* Copyright IBM, Corp. 2009
|
|
||||||
*
|
|
||||||
* Authors:
|
|
||||||
* Anthony Liguori <aliguori@us.ibm.com>
|
|
||||||
*
|
|
||||||
* This work is licensed under the terms of the GNU GPL, version 2. See
|
|
||||||
* the COPYING file in the top-level directory.
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef QEMU_MODULE_H
|
|
||||||
#define QEMU_MODULE_H
|
|
||||||
|
|
||||||
#include "qemu/osdep.h"
|
|
||||||
|
|
||||||
#define DSO_STAMP_FUN glue(qemu_stamp, CONFIG_STAMP)
|
|
||||||
#define DSO_STAMP_FUN_STR stringify(DSO_STAMP_FUN)
|
|
||||||
|
|
||||||
#ifdef BUILD_DSO
|
|
||||||
void DSO_STAMP_FUN(void);
|
|
||||||
/* This is a dummy symbol to identify a loaded DSO as a QEMU module, so we can
|
|
||||||
* distinguish "version mismatch" from "not a QEMU module", when the stamp
|
|
||||||
* check fails during module loading */
|
|
||||||
void qemu_module_dummy(void);
|
|
||||||
|
|
||||||
#define module_init(function, type) \
|
|
||||||
static void __attribute__((constructor)) do_qemu_init_ ## function(void) \
|
|
||||||
{ \
|
|
||||||
register_dso_module_init(function, type); \
|
|
||||||
}
|
|
||||||
#else
|
|
||||||
/* This should not be used directly. Use block_init etc. instead. */
|
|
||||||
#define module_init(function, type) \
|
|
||||||
static void __attribute__((constructor)) do_qemu_init_ ## function(void) \
|
|
||||||
{ \
|
|
||||||
register_module_init(function, type); \
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
typedef enum {
|
|
||||||
MODULE_INIT_BLOCK,
|
|
||||||
MODULE_INIT_MACHINE,
|
|
||||||
MODULE_INIT_QAPI,
|
|
||||||
MODULE_INIT_QOM,
|
|
||||||
MODULE_INIT_MAX
|
|
||||||
} module_init_type;
|
|
||||||
|
|
||||||
#define block_init(function) module_init(function, MODULE_INIT_BLOCK)
|
|
||||||
#define machine_init(function) module_init(function, MODULE_INIT_MACHINE)
|
|
||||||
#define qapi_init(function) module_init(function, MODULE_INIT_QAPI)
|
|
||||||
#define type_init(function) module_init(function, MODULE_INIT_QOM)
|
|
||||||
|
|
||||||
void register_module_init(void (*fn)(void), module_init_type type);
|
|
||||||
void register_dso_module_init(void (*fn)(void), module_init_type type);
|
|
||||||
|
|
||||||
void module_call_init(module_init_type type);
|
|
||||||
|
|
||||||
#endif
|
|
|
@ -1,56 +0,0 @@
|
||||||
#ifndef MONITOR_H
|
|
||||||
#define MONITOR_H
|
|
||||||
|
|
||||||
#include "qemu-common.h"
|
|
||||||
#include "qapi/qmp/qdict.h"
|
|
||||||
#include "block/block.h"
|
|
||||||
//#include "qemu/readline.h"
|
|
||||||
|
|
||||||
extern Monitor *cur_mon;
|
|
||||||
|
|
||||||
/* flags for monitor_init */
|
|
||||||
#define MONITOR_IS_DEFAULT 0x01
|
|
||||||
#define MONITOR_USE_READLINE 0x02
|
|
||||||
#define MONITOR_USE_CONTROL 0x04
|
|
||||||
#define MONITOR_USE_PRETTY 0x08
|
|
||||||
|
|
||||||
bool monitor_cur_is_qmp(void);
|
|
||||||
|
|
||||||
void monitor_init(CharDriverState *chr, int flags);
|
|
||||||
|
|
||||||
int monitor_suspend(Monitor *mon);
|
|
||||||
void monitor_resume(Monitor *mon);
|
|
||||||
|
|
||||||
int monitor_read_bdrv_key_start(Monitor *mon, BlockDriverState *bs,
|
|
||||||
BlockCompletionFunc *completion_cb,
|
|
||||||
void *opaque);
|
|
||||||
int monitor_read_block_device_key(Monitor *mon, const char *device,
|
|
||||||
BlockCompletionFunc *completion_cb,
|
|
||||||
void *opaque);
|
|
||||||
|
|
||||||
int monitor_get_fd(Monitor *mon, const char *fdname, Error **errp);
|
|
||||||
int monitor_fd_param(Monitor *mon, const char *fdname, Error **errp);
|
|
||||||
|
|
||||||
void monitor_vprintf(Monitor *mon, const char *fmt, va_list ap)
|
|
||||||
GCC_FMT_ATTR(2, 0);
|
|
||||||
void monitor_printf(Monitor *mon, const char *fmt, ...) GCC_FMT_ATTR(2, 3);
|
|
||||||
void monitor_flush(Monitor *mon);
|
|
||||||
int monitor_set_cpu(int cpu_index);
|
|
||||||
int monitor_get_cpu_index(void);
|
|
||||||
|
|
||||||
void monitor_read_command(Monitor *mon, int show_prompt);
|
|
||||||
//int monitor_read_password(Monitor *mon, ReadLineFunc *readline_func,
|
|
||||||
// void *opaque);
|
|
||||||
|
|
||||||
void object_add(const char *type, const char *id, const QDict *qdict,
|
|
||||||
Visitor *v, Error **errp);
|
|
||||||
|
|
||||||
AddfdInfo *monitor_fdset_add_fd(int fd, bool has_fdset_id, int64_t fdset_id,
|
|
||||||
bool has_opaque, const char *opaque,
|
|
||||||
Error **errp);
|
|
||||||
int monitor_fdset_get_fd(int64_t fdset_id, int flags);
|
|
||||||
int monitor_fdset_dup_fd_add(int64_t fdset_id, int dup_fd);
|
|
||||||
void monitor_fdset_dup_fd_remove(int dup_fd);
|
|
||||||
int monitor_fdset_dup_fd_find(int dup_fd);
|
|
||||||
|
|
||||||
#endif /* !MONITOR_H */
|
|
|
@ -1,72 +0,0 @@
|
||||||
/*
|
|
||||||
* Notifier lists
|
|
||||||
*
|
|
||||||
* Copyright IBM, Corp. 2010
|
|
||||||
*
|
|
||||||
* Authors:
|
|
||||||
* Anthony Liguori <aliguori@us.ibm.com>
|
|
||||||
*
|
|
||||||
* This work is licensed under the terms of the GNU GPL, version 2. See
|
|
||||||
* the COPYING file in the top-level directory.
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef QEMU_NOTIFY_H
|
|
||||||
#define QEMU_NOTIFY_H
|
|
||||||
|
|
||||||
#include "qemu/queue.h"
|
|
||||||
|
|
||||||
typedef struct Notifier Notifier;
|
|
||||||
|
|
||||||
struct Notifier
|
|
||||||
{
|
|
||||||
void (*notify)(Notifier *notifier, void *data);
|
|
||||||
QLIST_ENTRY(Notifier) node;
|
|
||||||
};
|
|
||||||
|
|
||||||
typedef struct NotifierList
|
|
||||||
{
|
|
||||||
QLIST_HEAD(, Notifier) notifiers;
|
|
||||||
} NotifierList;
|
|
||||||
|
|
||||||
#define NOTIFIER_LIST_INITIALIZER(head) \
|
|
||||||
{ QLIST_HEAD_INITIALIZER((head).notifiers) }
|
|
||||||
|
|
||||||
void notifier_list_init(NotifierList *list);
|
|
||||||
|
|
||||||
void notifier_list_add(NotifierList *list, Notifier *notifier);
|
|
||||||
|
|
||||||
void notifier_remove(Notifier *notifier);
|
|
||||||
|
|
||||||
void notifier_list_notify(NotifierList *list, void *data);
|
|
||||||
|
|
||||||
/* Same as Notifier but allows .notify() to return errors */
|
|
||||||
typedef struct NotifierWithReturn NotifierWithReturn;
|
|
||||||
|
|
||||||
struct NotifierWithReturn {
|
|
||||||
/**
|
|
||||||
* Return 0 on success (next notifier will be invoked), otherwise
|
|
||||||
* notifier_with_return_list_notify() will stop and return the value.
|
|
||||||
*/
|
|
||||||
int (*notify)(NotifierWithReturn *notifier, void *data);
|
|
||||||
QLIST_ENTRY(NotifierWithReturn) node;
|
|
||||||
};
|
|
||||||
|
|
||||||
typedef struct NotifierWithReturnList {
|
|
||||||
QLIST_HEAD(, NotifierWithReturn) notifiers;
|
|
||||||
} NotifierWithReturnList;
|
|
||||||
|
|
||||||
#define NOTIFIER_WITH_RETURN_LIST_INITIALIZER(head) \
|
|
||||||
{ QLIST_HEAD_INITIALIZER((head).notifiers) }
|
|
||||||
|
|
||||||
void notifier_with_return_list_init(NotifierWithReturnList *list);
|
|
||||||
|
|
||||||
void notifier_with_return_list_add(NotifierWithReturnList *list,
|
|
||||||
NotifierWithReturn *notifier);
|
|
||||||
|
|
||||||
void notifier_with_return_remove(NotifierWithReturn *notifier);
|
|
||||||
|
|
||||||
int notifier_with_return_list_notify(NotifierWithReturnList *list,
|
|
||||||
void *data);
|
|
||||||
|
|
||||||
#endif
|
|
|
@ -1,142 +0,0 @@
|
||||||
/*
|
|
||||||
* Commandline option parsing functions
|
|
||||||
*
|
|
||||||
* Copyright (c) 2003-2008 Fabrice Bellard
|
|
||||||
* Copyright (c) 2009 Kevin Wolf <kwolf@redhat.com>
|
|
||||||
*
|
|
||||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
||||||
* of this software and associated documentation files (the "Software"), to deal
|
|
||||||
* in the Software without restriction, including without limitation the rights
|
|
||||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
||||||
* copies of the Software, and to permit persons to whom the Software is
|
|
||||||
* furnished to do so, subject to the following conditions:
|
|
||||||
*
|
|
||||||
* The above copyright notice and this permission notice shall be included in
|
|
||||||
* all copies or substantial portions of the Software.
|
|
||||||
*
|
|
||||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
||||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
||||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
|
||||||
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
||||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
||||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
|
||||||
* THE SOFTWARE.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef QEMU_OPTIONS_H
|
|
||||||
#define QEMU_OPTIONS_H
|
|
||||||
|
|
||||||
#ifdef _MSC_VER
|
|
||||||
#include <win32/stdint.h>
|
|
||||||
#else
|
|
||||||
#include <stdint.h>
|
|
||||||
#endif
|
|
||||||
#include "qemu/queue.h"
|
|
||||||
#include "qapi/error.h"
|
|
||||||
#include "qapi/qmp/qdict.h"
|
|
||||||
#include "qemu/typedefs.h"
|
|
||||||
|
|
||||||
const char *get_opt_name(char *buf, int buf_size, const char *p, char delim);
|
|
||||||
const char *get_opt_value(char *buf, int buf_size, const char *p);
|
|
||||||
int get_next_param_value(char *buf, int buf_size,
|
|
||||||
const char *tag, const char **pstr);
|
|
||||||
int get_param_value(char *buf, int buf_size,
|
|
||||||
const char *tag, const char *str);
|
|
||||||
|
|
||||||
|
|
||||||
void parse_option_size(const char *name, const char *value,
|
|
||||||
uint64_t *ret, Error **errp);
|
|
||||||
bool has_help_option(const char *param);
|
|
||||||
bool is_valid_option_list(const char *param);
|
|
||||||
|
|
||||||
enum QemuOptType {
|
|
||||||
QEMU_OPT_STRING = 0, /* no parsing (use string as-is) */
|
|
||||||
QEMU_OPT_BOOL, /* on/off */
|
|
||||||
QEMU_OPT_NUMBER, /* simple number */
|
|
||||||
QEMU_OPT_SIZE, /* size, accepts (K)ilo, (M)ega, (G)iga, (T)era postfix */
|
|
||||||
};
|
|
||||||
|
|
||||||
typedef struct QemuOptDesc {
|
|
||||||
const char *name;
|
|
||||||
enum QemuOptType type;
|
|
||||||
const char *help;
|
|
||||||
const char *def_value_str;
|
|
||||||
} QemuOptDesc;
|
|
||||||
|
|
||||||
struct QemuOptsList {
|
|
||||||
const char *name;
|
|
||||||
const char *implied_opt_name;
|
|
||||||
bool merge_lists; /* Merge multiple uses of option into a single list? */
|
|
||||||
QTAILQ_HEAD(, QemuOpts) head;
|
|
||||||
QemuOptDesc desc[];
|
|
||||||
};
|
|
||||||
|
|
||||||
const char *qemu_opt_get(QemuOpts *opts, const char *name);
|
|
||||||
char *qemu_opt_get_del(QemuOpts *opts, const char *name);
|
|
||||||
/**
|
|
||||||
* qemu_opt_has_help_opt:
|
|
||||||
* @opts: options to search for a help request
|
|
||||||
*
|
|
||||||
* Check whether the options specified by @opts include one of the
|
|
||||||
* standard strings which indicate that the user is asking for a
|
|
||||||
* list of the valid values for a command line option (as defined
|
|
||||||
* by is_help_option()).
|
|
||||||
*
|
|
||||||
* Returns: true if @opts includes 'help' or equivalent.
|
|
||||||
*/
|
|
||||||
bool qemu_opt_has_help_opt(QemuOpts *opts);
|
|
||||||
QemuOpt *qemu_opt_find(QemuOpts *opts, const char *name);
|
|
||||||
bool qemu_opt_get_bool(QemuOpts *opts, const char *name, bool defval);
|
|
||||||
uint64_t qemu_opt_get_number(QemuOpts *opts, const char *name, uint64_t defval);
|
|
||||||
uint64_t qemu_opt_get_size(QemuOpts *opts, const char *name, uint64_t defval);
|
|
||||||
bool qemu_opt_get_bool_del(QemuOpts *opts, const char *name, bool defval);
|
|
||||||
uint64_t qemu_opt_get_number_del(QemuOpts *opts, const char *name,
|
|
||||||
uint64_t defval);
|
|
||||||
uint64_t qemu_opt_get_size_del(QemuOpts *opts, const char *name,
|
|
||||||
uint64_t defval);
|
|
||||||
int qemu_opt_unset(QemuOpts *opts, const char *name);
|
|
||||||
void qemu_opt_set(QemuOpts *opts, const char *name, const char *value,
|
|
||||||
Error **errp);
|
|
||||||
void qemu_opt_set_bool(QemuOpts *opts, const char *name, bool val,
|
|
||||||
Error **errp);
|
|
||||||
void qemu_opt_set_number(QemuOpts *opts, const char *name, int64_t val,
|
|
||||||
Error **errp);
|
|
||||||
typedef int (*qemu_opt_loopfunc)(void *opaque,
|
|
||||||
const char *name, const char *value,
|
|
||||||
Error **errp);
|
|
||||||
int qemu_opt_foreach(QemuOpts *opts, qemu_opt_loopfunc func, void *opaque,
|
|
||||||
Error **errp);
|
|
||||||
|
|
||||||
QemuOpts *qemu_opts_find(QemuOptsList *list, const char *id);
|
|
||||||
QemuOpts *qemu_opts_create(QemuOptsList *list, const char *id,
|
|
||||||
int fail_if_exists, Error **errp);
|
|
||||||
void qemu_opts_reset(QemuOptsList *list);
|
|
||||||
void qemu_opts_loc_restore(QemuOpts *opts);
|
|
||||||
void qemu_opts_set(QemuOptsList *list, const char *id,
|
|
||||||
const char *name, const char *value, Error **errp);
|
|
||||||
const char *qemu_opts_id(QemuOpts *opts);
|
|
||||||
void qemu_opts_set_id(QemuOpts *opts, char *id);
|
|
||||||
void qemu_opts_del(QemuOpts *opts);
|
|
||||||
void qemu_opts_validate(QemuOpts *opts, const QemuOptDesc *desc, Error **errp);
|
|
||||||
void qemu_opts_do_parse(QemuOpts *opts, const char *params,
|
|
||||||
const char *firstname, Error **errp);
|
|
||||||
QemuOpts *qemu_opts_parse_noisily(QemuOptsList *list, const char *params,
|
|
||||||
bool permit_abbrev);
|
|
||||||
QemuOpts *qemu_opts_parse(QemuOptsList *list, const char *params,
|
|
||||||
bool permit_abbrev, Error **errp);
|
|
||||||
void qemu_opts_set_defaults(QemuOptsList *list, const char *params,
|
|
||||||
int permit_abbrev);
|
|
||||||
QemuOpts *qemu_opts_from_qdict(QemuOptsList *list, const QDict *qdict,
|
|
||||||
Error **errp);
|
|
||||||
QDict *qemu_opts_to_qdict(QemuOpts *opts, QDict *qdict);
|
|
||||||
void qemu_opts_absorb_qdict(QemuOpts *opts, QDict *qdict, Error **errp);
|
|
||||||
|
|
||||||
typedef int (*qemu_opts_loopfunc)(void *opaque, QemuOpts *opts, Error **errp);
|
|
||||||
int qemu_opts_foreach(QemuOptsList *list, qemu_opts_loopfunc func,
|
|
||||||
void *opaque, Error **errp);
|
|
||||||
void qemu_opts_print(QemuOpts *opts, const char *sep);
|
|
||||||
void qemu_opts_print_help(QemuOptsList *list);
|
|
||||||
void qemu_opts_free(QemuOptsList *list);
|
|
||||||
QemuOptsList *qemu_opts_append(QemuOptsList *dst, QemuOptsList *list);
|
|
||||||
|
|
||||||
#endif
|
|
File diff suppressed because it is too large
Load diff
|
@ -1,26 +0,0 @@
|
||||||
/*
|
|
||||||
* Dealloc Visitor
|
|
||||||
*
|
|
||||||
* Copyright IBM, Corp. 2011
|
|
||||||
*
|
|
||||||
* Authors:
|
|
||||||
* Michael Roth <mdroth@linux.vnet.ibm.com>
|
|
||||||
*
|
|
||||||
* This work is licensed under the terms of the GNU LGPL, version 2.1 or later.
|
|
||||||
* See the COPYING.LIB file in the top-level directory.
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef QAPI_DEALLOC_VISITOR_H
|
|
||||||
#define QAPI_DEALLOC_VISITOR_H
|
|
||||||
|
|
||||||
#include "qapi/visitor.h"
|
|
||||||
|
|
||||||
typedef struct QapiDeallocVisitor QapiDeallocVisitor;
|
|
||||||
|
|
||||||
QapiDeallocVisitor *qapi_dealloc_visitor_new(void);
|
|
||||||
void qapi_dealloc_visitor_cleanup(QapiDeallocVisitor *d);
|
|
||||||
|
|
||||||
Visitor *qapi_dealloc_get_visitor(QapiDeallocVisitor *v);
|
|
||||||
|
|
||||||
#endif
|
|
|
@ -1,219 +0,0 @@
|
||||||
/*
|
|
||||||
* QEMU Error Objects
|
|
||||||
*
|
|
||||||
* Copyright IBM, Corp. 2011
|
|
||||||
* Copyright (C) 2011-2015 Red Hat, Inc.
|
|
||||||
*
|
|
||||||
* Authors:
|
|
||||||
* Anthony Liguori <aliguori@us.ibm.com>
|
|
||||||
* Markus Armbruster <armbru@redhat.com>
|
|
||||||
*
|
|
||||||
* This work is licensed under the terms of the GNU LGPL, version 2. See
|
|
||||||
* the COPYING.LIB file in the top-level directory.
|
|
||||||
*/
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Error reporting system loosely patterned after Glib's GError.
|
|
||||||
*
|
|
||||||
* Create an error:
|
|
||||||
* error_setg(&err, "situation normal, all fouled up");
|
|
||||||
*
|
|
||||||
* Report an error to stderr:
|
|
||||||
* error_report_err(err);
|
|
||||||
* This frees the error object.
|
|
||||||
*
|
|
||||||
* Report an error somewhere else:
|
|
||||||
* const char *msg = error_get_pretty(err);
|
|
||||||
* do with msg what needs to be done...
|
|
||||||
* error_free(err);
|
|
||||||
*
|
|
||||||
* Handle an error without reporting it (just for completeness):
|
|
||||||
* error_free(err);
|
|
||||||
*
|
|
||||||
* Pass an existing error to the caller:
|
|
||||||
* error_propagate(errp, err);
|
|
||||||
* where Error **errp is a parameter, by convention the last one.
|
|
||||||
*
|
|
||||||
* Create a new error and pass it to the caller:
|
|
||||||
* error_setg(errp, "situation normal, all fouled up");
|
|
||||||
*
|
|
||||||
* Call a function and receive an error from it:
|
|
||||||
* Error *err = NULL;
|
|
||||||
* foo(arg, &err);
|
|
||||||
* if (err) {
|
|
||||||
* handle the error...
|
|
||||||
* }
|
|
||||||
*
|
|
||||||
* Call a function ignoring errors:
|
|
||||||
* foo(arg, NULL);
|
|
||||||
*
|
|
||||||
* Call a function aborting on errors:
|
|
||||||
* foo(arg, &error_abort);
|
|
||||||
*
|
|
||||||
* Call a function treating errors as fatal:
|
|
||||||
* foo(arg, &error_fatal);
|
|
||||||
*
|
|
||||||
* Receive an error and pass it on to the caller:
|
|
||||||
* Error *err = NULL;
|
|
||||||
* foo(arg, &err);
|
|
||||||
* if (err) {
|
|
||||||
* handle the error...
|
|
||||||
* error_propagate(errp, err);
|
|
||||||
* }
|
|
||||||
* where Error **errp is a parameter, by convention the last one.
|
|
||||||
*
|
|
||||||
* Do *not* "optimize" this to
|
|
||||||
* foo(arg, errp);
|
|
||||||
* if (*errp) { // WRONG!
|
|
||||||
* handle the error...
|
|
||||||
* }
|
|
||||||
* because errp may be NULL!
|
|
||||||
*
|
|
||||||
* But when all you do with the error is pass it on, please use
|
|
||||||
* foo(arg, errp);
|
|
||||||
* for readability.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef ERROR_H
|
|
||||||
#define ERROR_H
|
|
||||||
|
|
||||||
#include "qemu/compiler.h"
|
|
||||||
#include "qapi-types.h"
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Opaque error object.
|
|
||||||
*/
|
|
||||||
typedef struct Error Error;
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Get @err's human-readable error message.
|
|
||||||
*/
|
|
||||||
const char *error_get_pretty(Error *err);
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Get @err's error class.
|
|
||||||
* Note: use of error classes other than ERROR_CLASS_GENERIC_ERROR is
|
|
||||||
* strongly discouraged.
|
|
||||||
*/
|
|
||||||
ErrorClass error_get_class(const Error *err);
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Create a new error object and assign it to *@errp.
|
|
||||||
* If @errp is NULL, the error is ignored. Don't bother creating one
|
|
||||||
* then.
|
|
||||||
* If @errp is &error_abort, print a suitable message and abort().
|
|
||||||
* If @errp is &error_fatal, print a suitable message and exit(1).
|
|
||||||
* If @errp is anything else, *@errp must be NULL.
|
|
||||||
* The new error's class is ERROR_CLASS_GENERIC_ERROR, and its
|
|
||||||
* human-readable error message is made from printf-style @fmt, ...
|
|
||||||
*/
|
|
||||||
#define error_setg(errp, fmt, ...) \
|
|
||||||
error_setg_internal((errp), __FILE__, __LINE__, __func__, \
|
|
||||||
(fmt), ## __VA_ARGS__)
|
|
||||||
void error_setg_internal(Error **errp,
|
|
||||||
const char *src, int line, const char *func,
|
|
||||||
const char *fmt, ...)
|
|
||||||
GCC_FMT_ATTR(5, 6);
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Just like error_setg(), with @os_error info added to the message.
|
|
||||||
* If @os_error is non-zero, ": " + strerror(os_error) is appended to
|
|
||||||
* the human-readable error message.
|
|
||||||
*/
|
|
||||||
#define error_setg_errno(errp, os_error, fmt, ...) \
|
|
||||||
error_setg_errno_internal((errp), __FILE__, __LINE__, __func__, \
|
|
||||||
(os_error), (fmt), ## __VA_ARGS__)
|
|
||||||
void error_setg_errno_internal(Error **errp,
|
|
||||||
const char *fname, int line, const char *func,
|
|
||||||
int os_error, const char *fmt, ...)
|
|
||||||
GCC_FMT_ATTR(6, 7);
|
|
||||||
|
|
||||||
#ifdef _WIN32
|
|
||||||
/*
|
|
||||||
* Just like error_setg(), with @win32_error info added to the message.
|
|
||||||
* If @win32_error is non-zero, ": " + g_win32_error_message(win32_err)
|
|
||||||
* is appended to the human-readable error message.
|
|
||||||
*/
|
|
||||||
#define error_setg_win32(errp, win32_err, fmt, ...) \
|
|
||||||
error_setg_win32_internal((errp), __FILE__, __LINE__, __func__, \
|
|
||||||
(win32_err), (fmt), ## __VA_ARGS__)
|
|
||||||
void error_setg_win32_internal(Error **errp,
|
|
||||||
const char *src, int line, const char *func,
|
|
||||||
int win32_err, const char *fmt, ...)
|
|
||||||
GCC_FMT_ATTR(6, 7);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Propagate error object (if any) from @local_err to @dst_errp.
|
|
||||||
* If @local_err is NULL, do nothing (because there's nothing to
|
|
||||||
* propagate).
|
|
||||||
* Else, if @dst_errp is NULL, errors are being ignored. Free the
|
|
||||||
* error object.
|
|
||||||
* Else, if @dst_errp is &error_abort, print a suitable message and
|
|
||||||
* abort().
|
|
||||||
* Else, if @dst_errp is &error_fatal, print a suitable message and
|
|
||||||
* exit(1).
|
|
||||||
* Else, if @dst_errp already contains an error, ignore this one: free
|
|
||||||
* the error object.
|
|
||||||
* Else, move the error object from @local_err to *@dst_errp.
|
|
||||||
* On return, @local_err is invalid.
|
|
||||||
*/
|
|
||||||
void error_propagate(Error **dst_errp, Error *local_err);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Append a printf-style human-readable explanation to an existing error.
|
|
||||||
* May be called multiple times, and safe if @errp is NULL.
|
|
||||||
*/
|
|
||||||
void error_append_hint(Error **errp, const char *fmt, ...)
|
|
||||||
GCC_FMT_ATTR(2, 3);
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Convenience function to report open() failure.
|
|
||||||
*/
|
|
||||||
#define error_setg_file_open(errp, os_errno, filename) \
|
|
||||||
error_setg_file_open_internal((errp), __FILE__, __LINE__, __func__, \
|
|
||||||
(os_errno), (filename))
|
|
||||||
void error_setg_file_open_internal(Error **errp,
|
|
||||||
const char *src, int line, const char *func,
|
|
||||||
int os_errno, const char *filename);
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Return an exact copy of @err.
|
|
||||||
*/
|
|
||||||
Error *error_copy(const Error *err);
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Free @err.
|
|
||||||
* @err may be NULL.
|
|
||||||
*/
|
|
||||||
void error_free(Error *err);
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Convenience function to error_report() and free @err.
|
|
||||||
*/
|
|
||||||
void error_report_err(Error *);
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Just like error_setg(), except you get to specify the error class.
|
|
||||||
* Note: use of error classes other than ERROR_CLASS_GENERIC_ERROR is
|
|
||||||
* strongly discouraged.
|
|
||||||
*/
|
|
||||||
#define error_set(errp, err_class, fmt, ...) \
|
|
||||||
error_set_internal((errp), __FILE__, __LINE__, __func__, \
|
|
||||||
(err_class), (fmt), ## __VA_ARGS__)
|
|
||||||
void error_set_internal(Error **errp,
|
|
||||||
const char *src, int line, const char *func,
|
|
||||||
ErrorClass err_class, const char *fmt, ...)
|
|
||||||
GCC_FMT_ATTR(6, 7);
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Pass to error_setg() & friends to abort() on error.
|
|
||||||
*/
|
|
||||||
extern Error *error_abort;
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Pass to error_setg() & friends to exit(1) on error.
|
|
||||||
*/
|
|
||||||
extern Error *error_fatal;
|
|
||||||
|
|
||||||
#endif
|
|
|
@ -1,37 +0,0 @@
|
||||||
/*
|
|
||||||
* Options Visitor
|
|
||||||
*
|
|
||||||
* Copyright Red Hat, Inc. 2012
|
|
||||||
*
|
|
||||||
* Author: Laszlo Ersek <lersek@redhat.com>
|
|
||||||
*
|
|
||||||
* This work is licensed under the terms of the GNU LGPL, version 2.1 or later.
|
|
||||||
* See the COPYING.LIB file in the top-level directory.
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef OPTS_VISITOR_H
|
|
||||||
#define OPTS_VISITOR_H
|
|
||||||
|
|
||||||
#include "qapi/visitor.h"
|
|
||||||
#include "qemu/option.h"
|
|
||||||
|
|
||||||
/* Inclusive upper bound on the size of any flattened range. This is a safety
|
|
||||||
* (= anti-annoyance) measure; wrong ranges should not cause long startup
|
|
||||||
* delays nor exhaust virtual memory.
|
|
||||||
*/
|
|
||||||
#define OPTS_VISITOR_RANGE_MAX 65536
|
|
||||||
|
|
||||||
typedef struct OptsVisitor OptsVisitor;
|
|
||||||
|
|
||||||
/* Contrarily to qemu-option.c::parse_option_number(), OptsVisitor's "int"
|
|
||||||
* parser relies on strtoll() instead of strtoull(). Consequences:
|
|
||||||
* - string representations of negative numbers yield negative values,
|
|
||||||
* - values below INT64_MIN or LLONG_MIN are rejected,
|
|
||||||
* - values above INT64_MAX or LLONG_MAX are rejected.
|
|
||||||
*/
|
|
||||||
OptsVisitor *opts_visitor_new(const QemuOpts *opts);
|
|
||||||
void opts_visitor_cleanup(OptsVisitor *nv);
|
|
||||||
Visitor *opts_get_visitor(OptsVisitor *nv);
|
|
||||||
|
|
||||||
#endif
|
|
|
@ -1,27 +0,0 @@
|
||||||
/*
|
|
||||||
* QMP Event related
|
|
||||||
*
|
|
||||||
* Copyright (c) 2014 Wenchao Xia
|
|
||||||
*
|
|
||||||
* Authors:
|
|
||||||
* Wenchao Xia <wenchaoqemu@gmail.com>
|
|
||||||
*
|
|
||||||
* This work is licensed under the terms of the GNU LGPL, version 2.1 or later.
|
|
||||||
* See the COPYING.LIB file in the top-level directory.
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef QMP_EVENT_H
|
|
||||||
#define QMP_EVENT_H
|
|
||||||
|
|
||||||
#include "qapi/error.h"
|
|
||||||
#include "qapi/qmp/qdict.h"
|
|
||||||
|
|
||||||
typedef void (*QMPEventFuncEmit)(unsigned event, QDict *dict, Error **errp);
|
|
||||||
|
|
||||||
void qmp_event_set_func_emit(QMPEventFuncEmit emit);
|
|
||||||
|
|
||||||
QMPEventFuncEmit qmp_event_get_func_emit(void);
|
|
||||||
|
|
||||||
QDict *qmp_event_build_dict(const char *event_name);
|
|
||||||
#endif
|
|
|
@ -1,29 +0,0 @@
|
||||||
/*
|
|
||||||
* Input Visitor
|
|
||||||
*
|
|
||||||
* Copyright IBM, Corp. 2011
|
|
||||||
*
|
|
||||||
* Authors:
|
|
||||||
* Anthony Liguori <aliguori@us.ibm.com>
|
|
||||||
*
|
|
||||||
* This work is licensed under the terms of the GNU LGPL, version 2.1 or later.
|
|
||||||
* See the COPYING.LIB file in the top-level directory.
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef QMP_INPUT_VISITOR_H
|
|
||||||
#define QMP_INPUT_VISITOR_H
|
|
||||||
|
|
||||||
#include "qapi/visitor.h"
|
|
||||||
#include "qapi/qmp/qobject.h"
|
|
||||||
|
|
||||||
typedef struct QmpInputVisitor QmpInputVisitor;
|
|
||||||
|
|
||||||
QmpInputVisitor *qmp_input_visitor_new(QObject *obj);
|
|
||||||
QmpInputVisitor *qmp_input_visitor_new_strict(QObject *obj);
|
|
||||||
|
|
||||||
void qmp_input_visitor_cleanup(QmpInputVisitor *v);
|
|
||||||
|
|
||||||
Visitor *qmp_input_get_visitor(QmpInputVisitor *v);
|
|
||||||
|
|
||||||
#endif
|
|
|
@ -1,28 +0,0 @@
|
||||||
/*
|
|
||||||
* Output Visitor
|
|
||||||
*
|
|
||||||
* Copyright IBM, Corp. 2011
|
|
||||||
*
|
|
||||||
* Authors:
|
|
||||||
* Anthony Liguori <aliguori@us.ibm.com>
|
|
||||||
*
|
|
||||||
* This work is licensed under the terms of the GNU LGPL, version 2.1 or later.
|
|
||||||
* See the COPYING.LIB file in the top-level directory.
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef QMP_OUTPUT_VISITOR_H
|
|
||||||
#define QMP_OUTPUT_VISITOR_H
|
|
||||||
|
|
||||||
#include "qapi/visitor.h"
|
|
||||||
#include "qapi/qmp/qobject.h"
|
|
||||||
|
|
||||||
typedef struct QmpOutputVisitor QmpOutputVisitor;
|
|
||||||
|
|
||||||
QmpOutputVisitor *qmp_output_visitor_new(void);
|
|
||||||
void qmp_output_visitor_cleanup(QmpOutputVisitor *v);
|
|
||||||
|
|
||||||
QObject *qmp_output_get_qobject(QmpOutputVisitor *v);
|
|
||||||
Visitor *qmp_output_get_visitor(QmpOutputVisitor *v);
|
|
||||||
|
|
||||||
#endif
|
|
|
@ -1,58 +0,0 @@
|
||||||
/*
|
|
||||||
* Core Definitions for QAPI/QMP Dispatch
|
|
||||||
*
|
|
||||||
* Copyright IBM, Corp. 2011
|
|
||||||
*
|
|
||||||
* Authors:
|
|
||||||
* Anthony Liguori <aliguori@us.ibm.com>
|
|
||||||
*
|
|
||||||
* This work is licensed under the terms of the GNU LGPL, version 2.1 or later.
|
|
||||||
* See the COPYING.LIB file in the top-level directory.
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef QMP_CORE_H
|
|
||||||
#define QMP_CORE_H
|
|
||||||
|
|
||||||
#include "qapi/qmp/qobject.h"
|
|
||||||
#include "qapi/qmp/qdict.h"
|
|
||||||
#include "qapi/error.h"
|
|
||||||
|
|
||||||
typedef void (QmpCommandFunc)(QDict *, QObject **, Error **);
|
|
||||||
|
|
||||||
typedef enum QmpCommandType
|
|
||||||
{
|
|
||||||
QCT_NORMAL,
|
|
||||||
} QmpCommandType;
|
|
||||||
|
|
||||||
typedef enum QmpCommandOptions
|
|
||||||
{
|
|
||||||
QCO_NO_OPTIONS = 0x0,
|
|
||||||
QCO_NO_SUCCESS_RESP = 0x1,
|
|
||||||
} QmpCommandOptions;
|
|
||||||
|
|
||||||
typedef struct QmpCommand
|
|
||||||
{
|
|
||||||
const char *name;
|
|
||||||
QmpCommandType type;
|
|
||||||
QmpCommandFunc *fn;
|
|
||||||
QmpCommandOptions options;
|
|
||||||
QTAILQ_ENTRY(QmpCommand) node;
|
|
||||||
bool enabled;
|
|
||||||
} QmpCommand;
|
|
||||||
|
|
||||||
void qmp_register_command(const char *name, QmpCommandFunc *fn,
|
|
||||||
QmpCommandOptions options);
|
|
||||||
QmpCommand *qmp_find_command(const char *name);
|
|
||||||
QObject *qmp_dispatch(QObject *request);
|
|
||||||
void qmp_disable_command(const char *name);
|
|
||||||
void qmp_enable_command(const char *name);
|
|
||||||
bool qmp_command_is_enabled(const QmpCommand *cmd);
|
|
||||||
const char *qmp_command_name(const QmpCommand *cmd);
|
|
||||||
bool qmp_has_success_response(const QmpCommand *cmd);
|
|
||||||
QObject *qmp_build_error_object(Error *err);
|
|
||||||
typedef void (*qmp_cmd_callback_fn)(QmpCommand *cmd, void *opaque);
|
|
||||||
void qmp_for_each_command(qmp_cmd_callback_fn fn, void *opaque);
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
|
@ -1,51 +0,0 @@
|
||||||
/*
|
|
||||||
* JSON lexer
|
|
||||||
*
|
|
||||||
* Copyright IBM, Corp. 2009
|
|
||||||
*
|
|
||||||
* Authors:
|
|
||||||
* Anthony Liguori <aliguori@us.ibm.com>
|
|
||||||
*
|
|
||||||
* This work is licensed under the terms of the GNU LGPL, version 2.1 or later.
|
|
||||||
* See the COPYING.LIB file in the top-level directory.
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef QEMU_JSON_LEXER_H
|
|
||||||
#define QEMU_JSON_LEXER_H
|
|
||||||
|
|
||||||
#include "qapi/qmp/qstring.h"
|
|
||||||
#include "qapi/qmp/qlist.h"
|
|
||||||
|
|
||||||
typedef enum json_token_type {
|
|
||||||
JSON_OPERATOR = 100,
|
|
||||||
JSON_INTEGER,
|
|
||||||
JSON_FLOAT,
|
|
||||||
JSON_KEYWORD,
|
|
||||||
JSON_STRING,
|
|
||||||
JSON_ESCAPE,
|
|
||||||
JSON_SKIP,
|
|
||||||
JSON_ERROR,
|
|
||||||
} JSONTokenType;
|
|
||||||
|
|
||||||
typedef struct JSONLexer JSONLexer;
|
|
||||||
|
|
||||||
typedef void (JSONLexerEmitter)(JSONLexer *, QString *, JSONTokenType, int x, int y);
|
|
||||||
|
|
||||||
struct JSONLexer
|
|
||||||
{
|
|
||||||
JSONLexerEmitter *emit;
|
|
||||||
int state;
|
|
||||||
QString *token;
|
|
||||||
int x, y;
|
|
||||||
};
|
|
||||||
|
|
||||||
void json_lexer_init(JSONLexer *lexer, JSONLexerEmitter func);
|
|
||||||
|
|
||||||
int json_lexer_feed(JSONLexer *lexer, const char *buffer, size_t size);
|
|
||||||
|
|
||||||
int json_lexer_flush(JSONLexer *lexer);
|
|
||||||
|
|
||||||
void json_lexer_destroy(JSONLexer *lexer);
|
|
||||||
|
|
||||||
#endif
|
|
|
@ -1,24 +0,0 @@
|
||||||
/*
|
|
||||||
* JSON Parser
|
|
||||||
*
|
|
||||||
* Copyright IBM, Corp. 2009
|
|
||||||
*
|
|
||||||
* Authors:
|
|
||||||
* Anthony Liguori <aliguori@us.ibm.com>
|
|
||||||
*
|
|
||||||
* This work is licensed under the terms of the GNU LGPL, version 2.1 or later.
|
|
||||||
* See the COPYING.LIB file in the top-level directory.
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef QEMU_JSON_PARSER_H
|
|
||||||
#define QEMU_JSON_PARSER_H
|
|
||||||
|
|
||||||
#include "qemu-common.h"
|
|
||||||
#include "qapi/qmp/qlist.h"
|
|
||||||
#include "qapi/error.h"
|
|
||||||
|
|
||||||
QObject *json_parser_parse(QList *tokens, va_list *ap);
|
|
||||||
QObject *json_parser_parse_err(QList *tokens, va_list *ap, Error **errp);
|
|
||||||
|
|
||||||
#endif
|
|
|
@ -1,40 +0,0 @@
|
||||||
/*
|
|
||||||
* JSON streaming support
|
|
||||||
*
|
|
||||||
* Copyright IBM, Corp. 2009
|
|
||||||
*
|
|
||||||
* Authors:
|
|
||||||
* Anthony Liguori <aliguori@us.ibm.com>
|
|
||||||
*
|
|
||||||
* This work is licensed under the terms of the GNU LGPL, version 2.1 or later.
|
|
||||||
* See the COPYING.LIB file in the top-level directory.
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef QEMU_JSON_STREAMER_H
|
|
||||||
#define QEMU_JSON_STREAMER_H
|
|
||||||
|
|
||||||
#include "qapi/qmp/qlist.h"
|
|
||||||
#include "qapi/qmp/json-lexer.h"
|
|
||||||
|
|
||||||
typedef struct JSONMessageParser
|
|
||||||
{
|
|
||||||
void (*emit)(struct JSONMessageParser *parser, QList *tokens);
|
|
||||||
JSONLexer lexer;
|
|
||||||
int brace_count;
|
|
||||||
int bracket_count;
|
|
||||||
QList *tokens;
|
|
||||||
uint64_t token_size;
|
|
||||||
} JSONMessageParser;
|
|
||||||
|
|
||||||
void json_message_parser_init(JSONMessageParser *parser,
|
|
||||||
void (*func)(JSONMessageParser *, QList *));
|
|
||||||
|
|
||||||
int json_message_parser_feed(JSONMessageParser *parser,
|
|
||||||
const char *buffer, size_t size);
|
|
||||||
|
|
||||||
int json_message_parser_flush(JSONMessageParser *parser);
|
|
||||||
|
|
||||||
void json_message_parser_destroy(JSONMessageParser *parser);
|
|
||||||
|
|
||||||
#endif
|
|
|
@ -1,29 +0,0 @@
|
||||||
/*
|
|
||||||
* QBool Module
|
|
||||||
*
|
|
||||||
* Copyright IBM, Corp. 2009
|
|
||||||
*
|
|
||||||
* Authors:
|
|
||||||
* Anthony Liguori <aliguori@us.ibm.com>
|
|
||||||
*
|
|
||||||
* This work is licensed under the terms of the GNU LGPL, version 2.1 or later.
|
|
||||||
* See the COPYING.LIB file in the top-level directory.
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef QBOOL_H
|
|
||||||
#define QBOOL_H
|
|
||||||
|
|
||||||
#include <stdbool.h>
|
|
||||||
#include "qapi/qmp/qobject.h"
|
|
||||||
|
|
||||||
typedef struct QBool {
|
|
||||||
QObject_HEAD;
|
|
||||||
bool value;
|
|
||||||
} QBool;
|
|
||||||
|
|
||||||
QBool *qbool_from_bool(bool value);
|
|
||||||
bool qbool_get_bool(const QBool *qb);
|
|
||||||
QBool *qobject_to_qbool(const QObject *obj);
|
|
||||||
|
|
||||||
#endif /* QBOOL_H */
|
|
|
@ -1,79 +0,0 @@
|
||||||
/*
|
|
||||||
* QDict Module
|
|
||||||
*
|
|
||||||
* Copyright (C) 2009 Red Hat Inc.
|
|
||||||
*
|
|
||||||
* Authors:
|
|
||||||
* Luiz Capitulino <lcapitulino@redhat.com>
|
|
||||||
*
|
|
||||||
* This work is licensed under the terms of the GNU LGPL, version 2.1 or later.
|
|
||||||
* See the COPYING.LIB file in the top-level directory.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef QDICT_H
|
|
||||||
#define QDICT_H
|
|
||||||
|
|
||||||
#include "qapi/qmp/qobject.h"
|
|
||||||
#include "qapi/qmp/qlist.h"
|
|
||||||
#include "qemu/queue.h"
|
|
||||||
//#include <stdint.h>
|
|
||||||
|
|
||||||
#define QDICT_BUCKET_MAX 512
|
|
||||||
|
|
||||||
typedef struct QDictEntry {
|
|
||||||
char *key;
|
|
||||||
QObject *value;
|
|
||||||
QLIST_ENTRY(QDictEntry) next;
|
|
||||||
} QDictEntry;
|
|
||||||
|
|
||||||
typedef struct QDict {
|
|
||||||
QObject_HEAD;
|
|
||||||
size_t size;
|
|
||||||
QLIST_HEAD(,QDictEntry) table[QDICT_BUCKET_MAX];
|
|
||||||
} QDict;
|
|
||||||
|
|
||||||
/* Object API */
|
|
||||||
QDict *qdict_new(void);
|
|
||||||
const char *qdict_entry_key(const QDictEntry *entry);
|
|
||||||
QObject *qdict_entry_value(const QDictEntry *entry);
|
|
||||||
size_t qdict_size(const QDict *qdict);
|
|
||||||
void qdict_put_obj(QDict *qdict, const char *key, QObject *value);
|
|
||||||
void qdict_del(QDict *qdict, const char *key);
|
|
||||||
int qdict_haskey(const QDict *qdict, const char *key);
|
|
||||||
QObject *qdict_get(const QDict *qdict, const char *key);
|
|
||||||
QDict *qobject_to_qdict(const QObject *obj);
|
|
||||||
void qdict_iter(const QDict *qdict,
|
|
||||||
void (*iter)(const char *key, QObject *obj, void *opaque),
|
|
||||||
void *opaque);
|
|
||||||
const QDictEntry *qdict_first(const QDict *qdict);
|
|
||||||
const QDictEntry *qdict_next(const QDict *qdict, const QDictEntry *entry);
|
|
||||||
|
|
||||||
/* Helper to qdict_put_obj(), accepts any object */
|
|
||||||
#define qdict_put(qdict, key, obj) \
|
|
||||||
qdict_put_obj(qdict, key, QOBJECT(obj))
|
|
||||||
|
|
||||||
/* High level helpers */
|
|
||||||
double qdict_get_double(const QDict *qdict, const char *key);
|
|
||||||
int64_t qdict_get_int(const QDict *qdict, const char *key);
|
|
||||||
bool qdict_get_bool(const QDict *qdict, const char *key);
|
|
||||||
QList *qdict_get_qlist(const QDict *qdict, const char *key);
|
|
||||||
QDict *qdict_get_qdict(const QDict *qdict, const char *key);
|
|
||||||
const char *qdict_get_str(const QDict *qdict, const char *key);
|
|
||||||
int64_t qdict_get_try_int(const QDict *qdict, const char *key,
|
|
||||||
int64_t def_value);
|
|
||||||
bool qdict_get_try_bool(const QDict *qdict, const char *key, bool def_value);
|
|
||||||
const char *qdict_get_try_str(const QDict *qdict, const char *key);
|
|
||||||
|
|
||||||
void qdict_copy_default(QDict *dst, QDict *src, const char *key);
|
|
||||||
void qdict_set_default_str(QDict *dst, const char *key, const char *val);
|
|
||||||
|
|
||||||
QDict *qdict_clone_shallow(const QDict *src);
|
|
||||||
void qdict_flatten(QDict *qdict);
|
|
||||||
|
|
||||||
void qdict_extract_subqdict(QDict *src, QDict **dst, const char *start);
|
|
||||||
void qdict_array_split(QDict *src, QList **dst);
|
|
||||||
int qdict_array_entries(QDict *src, const char *subqdict);
|
|
||||||
|
|
||||||
void qdict_join(QDict *dest, QDict *src, bool overwrite);
|
|
||||||
|
|
||||||
#endif /* QDICT_H */
|
|
|
@ -1,109 +0,0 @@
|
||||||
/*
|
|
||||||
* QError Module
|
|
||||||
*
|
|
||||||
* Copyright (C) 2009 Red Hat Inc.
|
|
||||||
*
|
|
||||||
* Authors:
|
|
||||||
* Luiz Capitulino <lcapitulino@redhat.com>
|
|
||||||
*
|
|
||||||
* This work is licensed under the terms of the GNU LGPL, version 2.1 or later.
|
|
||||||
* See the COPYING.LIB file in the top-level directory.
|
|
||||||
*/
|
|
||||||
#ifndef QERROR_H
|
|
||||||
#define QERROR_H
|
|
||||||
|
|
||||||
/*
|
|
||||||
* These macros will go away, please don't use in new code, and do not
|
|
||||||
* add new ones!
|
|
||||||
*/
|
|
||||||
#define QERR_BASE_NOT_FOUND \
|
|
||||||
"Base '%s' not found"
|
|
||||||
|
|
||||||
#define QERR_BLOCK_JOB_NOT_READY \
|
|
||||||
"The active block job for device '%s' cannot be completed"
|
|
||||||
|
|
||||||
#define QERR_BUS_NO_HOTPLUG \
|
|
||||||
"Bus '%s' does not support hotplugging"
|
|
||||||
|
|
||||||
#define QERR_DEVICE_HAS_NO_MEDIUM \
|
|
||||||
"Device '%s' has no medium"
|
|
||||||
|
|
||||||
#define QERR_DEVICE_INIT_FAILED \
|
|
||||||
"Device '%s' could not be initialized"
|
|
||||||
|
|
||||||
#define QERR_DEVICE_IN_USE \
|
|
||||||
"Device '%s' is in use"
|
|
||||||
|
|
||||||
#define QERR_DEVICE_NO_HOTPLUG \
|
|
||||||
"Device '%s' does not support hotplugging"
|
|
||||||
|
|
||||||
#define QERR_FD_NOT_FOUND \
|
|
||||||
"File descriptor named '%s' not found"
|
|
||||||
|
|
||||||
#define QERR_FD_NOT_SUPPLIED \
|
|
||||||
"No file descriptor supplied via SCM_RIGHTS"
|
|
||||||
|
|
||||||
#define QERR_FEATURE_DISABLED \
|
|
||||||
"The feature '%s' is not enabled"
|
|
||||||
|
|
||||||
#define QERR_INVALID_BLOCK_FORMAT \
|
|
||||||
"Invalid block format '%s'"
|
|
||||||
|
|
||||||
#define QERR_INVALID_PARAMETER \
|
|
||||||
"Invalid parameter '%s'"
|
|
||||||
|
|
||||||
#define QERR_INVALID_PARAMETER_TYPE \
|
|
||||||
"Invalid parameter type for '%s', expected: %s"
|
|
||||||
|
|
||||||
#define QERR_INVALID_PARAMETER_VALUE \
|
|
||||||
"Parameter '%s' expects %s"
|
|
||||||
|
|
||||||
#define QERR_INVALID_PASSWORD \
|
|
||||||
"Password incorrect"
|
|
||||||
|
|
||||||
#define QERR_IO_ERROR \
|
|
||||||
"An IO error has occurred"
|
|
||||||
|
|
||||||
#define QERR_JSON_PARSING \
|
|
||||||
"Invalid JSON syntax"
|
|
||||||
|
|
||||||
#define QERR_MIGRATION_ACTIVE \
|
|
||||||
"There's a migration process in progress"
|
|
||||||
|
|
||||||
#define QERR_MISSING_PARAMETER \
|
|
||||||
"Parameter '%s' is missing"
|
|
||||||
|
|
||||||
#define QERR_PERMISSION_DENIED \
|
|
||||||
"Insufficient permission to perform this operation"
|
|
||||||
|
|
||||||
#define QERR_PROPERTY_VALUE_BAD \
|
|
||||||
"Property '%s.%s' doesn't take value '%s'"
|
|
||||||
|
|
||||||
#define QERR_PROPERTY_VALUE_OUT_OF_RANGE \
|
|
||||||
"Property %s.%s doesn't take value %" PRId64 " (minimum: %" PRId64 ", maximum: %" PRId64 ")"
|
|
||||||
|
|
||||||
#define QERR_QGA_COMMAND_FAILED \
|
|
||||||
"Guest agent command failed, error was '%s'"
|
|
||||||
|
|
||||||
#define QERR_QMP_BAD_INPUT_OBJECT \
|
|
||||||
"Expected '%s' in QMP input"
|
|
||||||
|
|
||||||
#define QERR_QMP_BAD_INPUT_OBJECT_MEMBER \
|
|
||||||
"QMP input object member '%s' expects '%s'"
|
|
||||||
|
|
||||||
#define QERR_QMP_EXTRA_MEMBER \
|
|
||||||
"QMP input object member '%s' is unexpected"
|
|
||||||
|
|
||||||
#define QERR_SET_PASSWD_FAILED \
|
|
||||||
"Could not set password"
|
|
||||||
|
|
||||||
#define QERR_UNDEFINED_ERROR \
|
|
||||||
"An undefined error has occurred"
|
|
||||||
|
|
||||||
#define QERR_UNKNOWN_BLOCK_FORMAT_FEATURE \
|
|
||||||
"'%s' uses a %s feature which is not supported by this qemu version: %s"
|
|
||||||
|
|
||||||
#define QERR_UNSUPPORTED \
|
|
||||||
"this feature or command is not currently supported"
|
|
||||||
|
|
||||||
#endif /* QERROR_H */
|
|
|
@ -1,29 +0,0 @@
|
||||||
/*
|
|
||||||
* QFloat Module
|
|
||||||
*
|
|
||||||
* Copyright IBM, Corp. 2009
|
|
||||||
*
|
|
||||||
* Authors:
|
|
||||||
* Anthony Liguori <aliguori@us.ibm.com>
|
|
||||||
*
|
|
||||||
* This work is licensed under the terms of the GNU LGPL, version 2.1 or later.
|
|
||||||
* See the COPYING.LIB file in the top-level directory.
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef QFLOAT_H
|
|
||||||
#define QFLOAT_H
|
|
||||||
|
|
||||||
#include <stdint.h>
|
|
||||||
#include "qapi/qmp/qobject.h"
|
|
||||||
|
|
||||||
typedef struct QFloat {
|
|
||||||
QObject_HEAD;
|
|
||||||
double value;
|
|
||||||
} QFloat;
|
|
||||||
|
|
||||||
QFloat *qfloat_from_double(double value);
|
|
||||||
double qfloat_get_double(const QFloat *qi);
|
|
||||||
QFloat *qobject_to_qfloat(const QObject *obj);
|
|
||||||
|
|
||||||
#endif /* QFLOAT_H */
|
|
|
@ -1,28 +0,0 @@
|
||||||
/*
|
|
||||||
* QInt Module
|
|
||||||
*
|
|
||||||
* Copyright (C) 2009 Red Hat Inc.
|
|
||||||
*
|
|
||||||
* Authors:
|
|
||||||
* Luiz Capitulino <lcapitulino@redhat.com>
|
|
||||||
*
|
|
||||||
* This work is licensed under the terms of the GNU LGPL, version 2.1 or later.
|
|
||||||
* See the COPYING.LIB file in the top-level directory.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef QINT_H
|
|
||||||
#define QINT_H
|
|
||||||
|
|
||||||
#include <stdint.h>
|
|
||||||
#include "qapi/qmp/qobject.h"
|
|
||||||
|
|
||||||
typedef struct QInt {
|
|
||||||
QObject_HEAD;
|
|
||||||
int64_t value;
|
|
||||||
} QInt;
|
|
||||||
|
|
||||||
QInt *qint_from_int(int64_t value);
|
|
||||||
int64_t qint_get_int(const QInt *qi);
|
|
||||||
QInt *qobject_to_qint(const QObject *obj);
|
|
||||||
|
|
||||||
#endif /* QINT_H */
|
|
|
@ -1,29 +0,0 @@
|
||||||
/*
|
|
||||||
* QObject JSON integration
|
|
||||||
*
|
|
||||||
* Copyright IBM, Corp. 2009
|
|
||||||
*
|
|
||||||
* Authors:
|
|
||||||
* Anthony Liguori <aliguori@us.ibm.com>
|
|
||||||
*
|
|
||||||
* This work is licensed under the terms of the GNU LGPL, version 2.1 or later.
|
|
||||||
* See the COPYING.LIB file in the top-level directory.
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef QJSON_H
|
|
||||||
#define QJSON_H
|
|
||||||
|
|
||||||
#include <stdarg.h>
|
|
||||||
#include "qemu/compiler.h"
|
|
||||||
#include "qapi/qmp/qobject.h"
|
|
||||||
#include "qapi/qmp/qstring.h"
|
|
||||||
|
|
||||||
QObject *qobject_from_json(const char *string);
|
|
||||||
QObject *qobject_from_jsonf(const char *string, ...);
|
|
||||||
QObject *qobject_from_jsonv(const char *string, va_list *ap);
|
|
||||||
|
|
||||||
QString *qobject_to_json(const QObject *obj);
|
|
||||||
QString *qobject_to_json_pretty(const QObject *obj);
|
|
||||||
|
|
||||||
#endif /* QJSON_H */
|
|
|
@ -1,63 +0,0 @@
|
||||||
/*
|
|
||||||
* QList Module
|
|
||||||
*
|
|
||||||
* Copyright (C) 2009 Red Hat Inc.
|
|
||||||
*
|
|
||||||
* Authors:
|
|
||||||
* Luiz Capitulino <lcapitulino@redhat.com>
|
|
||||||
*
|
|
||||||
* This work is licensed under the terms of the GNU LGPL, version 2.1 or later.
|
|
||||||
* See the COPYING.LIB file in the top-level directory.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef QLIST_H
|
|
||||||
#define QLIST_H
|
|
||||||
|
|
||||||
#include "qapi/qmp/qobject.h"
|
|
||||||
#include "qemu/queue.h"
|
|
||||||
|
|
||||||
typedef struct QListEntry {
|
|
||||||
QObject *value;
|
|
||||||
QTAILQ_ENTRY(QListEntry) next;
|
|
||||||
} QListEntry;
|
|
||||||
|
|
||||||
typedef struct QList {
|
|
||||||
QObject_HEAD;
|
|
||||||
QTAILQ_HEAD(,QListEntry) head;
|
|
||||||
} QList;
|
|
||||||
|
|
||||||
#define qlist_append(qlist, obj) \
|
|
||||||
qlist_append_obj(qlist, QOBJECT(obj))
|
|
||||||
|
|
||||||
#define QLIST_FOREACH_ENTRY(qlist, var) \
|
|
||||||
for ((var) = ((qlist)->head.tqh_first); \
|
|
||||||
(var); \
|
|
||||||
(var) = ((var)->next.tqe_next))
|
|
||||||
|
|
||||||
static inline QObject *qlist_entry_obj(const QListEntry *entry)
|
|
||||||
{
|
|
||||||
return entry->value;
|
|
||||||
}
|
|
||||||
|
|
||||||
QList *qlist_new(void);
|
|
||||||
QList *qlist_copy(QList *src);
|
|
||||||
void qlist_append_obj(QList *qlist, QObject *obj);
|
|
||||||
void qlist_iter(const QList *qlist,
|
|
||||||
void (*iter)(QObject *obj, void *opaque), void *opaque);
|
|
||||||
QObject *qlist_pop(QList *qlist);
|
|
||||||
QObject *qlist_peek(QList *qlist);
|
|
||||||
int qlist_empty(const QList *qlist);
|
|
||||||
size_t qlist_size(const QList *qlist);
|
|
||||||
QList *qobject_to_qlist(const QObject *obj);
|
|
||||||
|
|
||||||
static inline const QListEntry *qlist_first(const QList *qlist)
|
|
||||||
{
|
|
||||||
return QTAILQ_FIRST(&qlist->head);
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline const QListEntry *qlist_next(const QListEntry *entry)
|
|
||||||
{
|
|
||||||
return QTAILQ_NEXT(entry, next);
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif /* QLIST_H */
|
|
|
@ -1,121 +0,0 @@
|
||||||
/*
|
|
||||||
* QEMU Object Model.
|
|
||||||
*
|
|
||||||
* Based on ideas by Avi Kivity <avi@redhat.com>
|
|
||||||
*
|
|
||||||
* Copyright (C) 2009, 2015 Red Hat Inc.
|
|
||||||
*
|
|
||||||
* Authors:
|
|
||||||
* Luiz Capitulino <lcapitulino@redhat.com>
|
|
||||||
*
|
|
||||||
* This work is licensed under the terms of the GNU LGPL, version 2.1 or later.
|
|
||||||
* See the COPYING.LIB file in the top-level directory.
|
|
||||||
*
|
|
||||||
* QObject Reference Counts Terminology
|
|
||||||
* ------------------------------------
|
|
||||||
*
|
|
||||||
* - Returning references: A function that returns an object may
|
|
||||||
* return it as either a weak or a strong reference. If the reference
|
|
||||||
* is strong, you are responsible for calling QDECREF() on the reference
|
|
||||||
* when you are done.
|
|
||||||
*
|
|
||||||
* If the reference is weak, the owner of the reference may free it at
|
|
||||||
* any time in the future. Before storing the reference anywhere, you
|
|
||||||
* should call QINCREF() to make the reference strong.
|
|
||||||
*
|
|
||||||
* - Transferring ownership: when you transfer ownership of a reference
|
|
||||||
* by calling a function, you are no longer responsible for calling
|
|
||||||
* QDECREF() when the reference is no longer needed. In other words,
|
|
||||||
* when the function returns you must behave as if the reference to the
|
|
||||||
* passed object was weak.
|
|
||||||
*/
|
|
||||||
#ifndef QOBJECT_H
|
|
||||||
#define QOBJECT_H
|
|
||||||
|
|
||||||
#include <stddef.h>
|
|
||||||
#include <assert.h>
|
|
||||||
|
|
||||||
typedef enum {
|
|
||||||
QTYPE_NONE, /* sentinel value, no QObject has this type code */
|
|
||||||
QTYPE_QNULL,
|
|
||||||
QTYPE_QINT,
|
|
||||||
QTYPE_QSTRING,
|
|
||||||
QTYPE_QDICT,
|
|
||||||
QTYPE_QLIST,
|
|
||||||
QTYPE_QFLOAT,
|
|
||||||
QTYPE_QBOOL,
|
|
||||||
QTYPE_MAX,
|
|
||||||
} qtype_code;
|
|
||||||
|
|
||||||
struct QObject;
|
|
||||||
|
|
||||||
typedef struct QType {
|
|
||||||
qtype_code code;
|
|
||||||
void (*destroy)(struct QObject *);
|
|
||||||
} QType;
|
|
||||||
|
|
||||||
typedef struct QObject {
|
|
||||||
const QType *type;
|
|
||||||
size_t refcnt;
|
|
||||||
} QObject;
|
|
||||||
|
|
||||||
/* Objects definitions must include this */
|
|
||||||
#define QObject_HEAD \
|
|
||||||
QObject base
|
|
||||||
|
|
||||||
/* Get the 'base' part of an object */
|
|
||||||
#define QOBJECT(obj) (&(obj)->base)
|
|
||||||
|
|
||||||
/* High-level interface for qobject_incref() */
|
|
||||||
#define QINCREF(obj) \
|
|
||||||
qobject_incref(QOBJECT(obj))
|
|
||||||
|
|
||||||
/* High-level interface for qobject_decref() */
|
|
||||||
#define QDECREF(obj) \
|
|
||||||
qobject_decref(obj ? QOBJECT(obj) : NULL)
|
|
||||||
|
|
||||||
/* Initialize an object to default values */
|
|
||||||
#define QOBJECT_INIT(obj, qtype_type) \
|
|
||||||
obj->base.refcnt = 1; \
|
|
||||||
obj->base.type = qtype_type
|
|
||||||
|
|
||||||
/**
|
|
||||||
* qobject_incref(): Increment QObject's reference count
|
|
||||||
*/
|
|
||||||
static inline void qobject_incref(QObject *obj)
|
|
||||||
{
|
|
||||||
if (obj)
|
|
||||||
obj->refcnt++;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* qobject_decref(): Decrement QObject's reference count, deallocate
|
|
||||||
* when it reaches zero
|
|
||||||
*/
|
|
||||||
static inline void qobject_decref(QObject *obj)
|
|
||||||
{
|
|
||||||
if (obj && --obj->refcnt == 0) {
|
|
||||||
assert(obj->type != NULL);
|
|
||||||
assert(obj->type->destroy != NULL);
|
|
||||||
obj->type->destroy(obj);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* qobject_type(): Return the QObject's type
|
|
||||||
*/
|
|
||||||
static inline qtype_code qobject_type(const QObject *obj)
|
|
||||||
{
|
|
||||||
assert(obj->type != NULL);
|
|
||||||
return obj->type->code;
|
|
||||||
}
|
|
||||||
|
|
||||||
extern QObject qnull_;
|
|
||||||
|
|
||||||
static inline QObject *qnull(void)
|
|
||||||
{
|
|
||||||
qobject_incref(&qnull_);
|
|
||||||
return &qnull_;
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif /* QOBJECT_H */
|
|
|
@ -1,35 +0,0 @@
|
||||||
/*
|
|
||||||
* QString Module
|
|
||||||
*
|
|
||||||
* Copyright (C) 2009 Red Hat Inc.
|
|
||||||
*
|
|
||||||
* Authors:
|
|
||||||
* Luiz Capitulino <lcapitulino@redhat.com>
|
|
||||||
*
|
|
||||||
* This work is licensed under the terms of the GNU LGPL, version 2.1 or later.
|
|
||||||
* See the COPYING.LIB file in the top-level directory.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef QSTRING_H
|
|
||||||
#define QSTRING_H
|
|
||||||
|
|
||||||
#include "qapi/qmp/qobject.h"
|
|
||||||
|
|
||||||
typedef struct QString {
|
|
||||||
QObject_HEAD;
|
|
||||||
char *string;
|
|
||||||
size_t length;
|
|
||||||
size_t capacity;
|
|
||||||
} QString;
|
|
||||||
|
|
||||||
QString *qstring_new(void);
|
|
||||||
QString *qstring_from_str(const char *str);
|
|
||||||
QString *qstring_from_substr(const char *str, int start, int end);
|
|
||||||
size_t qstring_get_length(const QString *qstring);
|
|
||||||
const char *qstring_get_str(const QString *qstring);
|
|
||||||
void qstring_append_int(QString *qstring, int64_t value);
|
|
||||||
void qstring_append(QString *qstring, const char *str);
|
|
||||||
void qstring_append_chr(QString *qstring, int c);
|
|
||||||
QString *qobject_to_qstring(const QObject *obj);
|
|
||||||
|
|
||||||
#endif /* QSTRING_H */
|
|
|
@ -1,25 +0,0 @@
|
||||||
/*
|
|
||||||
* Include all QEMU objects.
|
|
||||||
*
|
|
||||||
* Copyright (C) 2009 Red Hat Inc.
|
|
||||||
*
|
|
||||||
* Authors:
|
|
||||||
* Luiz Capitulino <lcapitulino@redhat.com>
|
|
||||||
*
|
|
||||||
* This work is licensed under the terms of the GNU LGPL, version 2.1 or later.
|
|
||||||
* See the COPYING.LIB file in the top-level directory.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef QEMU_OBJECTS_H
|
|
||||||
#define QEMU_OBJECTS_H
|
|
||||||
|
|
||||||
#include "qapi/qmp/qobject.h"
|
|
||||||
#include "qapi/qmp/qint.h"
|
|
||||||
#include "qapi/qmp/qfloat.h"
|
|
||||||
#include "qapi/qmp/qbool.h"
|
|
||||||
#include "qapi/qmp/qstring.h"
|
|
||||||
#include "qapi/qmp/qdict.h"
|
|
||||||
#include "qapi/qmp/qlist.h"
|
|
||||||
#include "qapi/qmp/qjson.h"
|
|
||||||
|
|
||||||
#endif /* QEMU_OBJECTS_H */
|
|
|
@ -1,25 +0,0 @@
|
||||||
/*
|
|
||||||
* String parsing Visitor
|
|
||||||
*
|
|
||||||
* Copyright Red Hat, Inc. 2012
|
|
||||||
*
|
|
||||||
* Author: Paolo Bonzini <pbonzini@redhat.com>
|
|
||||||
*
|
|
||||||
* This work is licensed under the terms of the GNU LGPL, version 2.1 or later.
|
|
||||||
* See the COPYING.LIB file in the top-level directory.
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef STRING_INPUT_VISITOR_H
|
|
||||||
#define STRING_INPUT_VISITOR_H
|
|
||||||
|
|
||||||
#include "qapi/visitor.h"
|
|
||||||
|
|
||||||
typedef struct StringInputVisitor StringInputVisitor;
|
|
||||||
|
|
||||||
StringInputVisitor *string_input_visitor_new(const char *str);
|
|
||||||
void string_input_visitor_cleanup(StringInputVisitor *v);
|
|
||||||
|
|
||||||
Visitor *string_input_get_visitor(StringInputVisitor *v);
|
|
||||||
|
|
||||||
#endif
|
|
|
@ -1,26 +0,0 @@
|
||||||
/*
|
|
||||||
* String printing Visitor
|
|
||||||
*
|
|
||||||
* Copyright Red Hat, Inc. 2012
|
|
||||||
*
|
|
||||||
* Author: Paolo Bonzini <pbonzini@redhat.com>
|
|
||||||
*
|
|
||||||
* This work is licensed under the terms of the GNU LGPL, version 2.1 or later.
|
|
||||||
* See the COPYING.LIB file in the top-level directory.
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef STRING_OUTPUT_VISITOR_H
|
|
||||||
#define STRING_OUTPUT_VISITOR_H
|
|
||||||
|
|
||||||
#include "qapi/visitor.h"
|
|
||||||
|
|
||||||
typedef struct StringOutputVisitor StringOutputVisitor;
|
|
||||||
|
|
||||||
StringOutputVisitor *string_output_visitor_new(bool human);
|
|
||||||
void string_output_visitor_cleanup(StringOutputVisitor *v);
|
|
||||||
|
|
||||||
char *string_output_get_string(StringOutputVisitor *v);
|
|
||||||
Visitor *string_output_get_visitor(StringOutputVisitor *v);
|
|
||||||
|
|
||||||
#endif
|
|
|
@ -1,17 +0,0 @@
|
||||||
/*
|
|
||||||
* QAPI util functions
|
|
||||||
*
|
|
||||||
* Copyright Fujitsu, Inc. 2014
|
|
||||||
*
|
|
||||||
* This work is licensed under the terms of the GNU LGPL, version 2.1 or later.
|
|
||||||
* See the COPYING.LIB file in the top-level directory.
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef QAPI_UTIL_H
|
|
||||||
#define QAPI_UTIL_H
|
|
||||||
|
|
||||||
int qapi_enum_parse(const char * const lookup[], const char *buf,
|
|
||||||
int max, int def, Error **errp);
|
|
||||||
|
|
||||||
#endif
|
|
|
@ -1,69 +0,0 @@
|
||||||
/*
|
|
||||||
* Core Definitions for QAPI Visitor implementations
|
|
||||||
*
|
|
||||||
* Copyright (C) 2012 Red Hat, Inc.
|
|
||||||
*
|
|
||||||
* Author: Paolo Bonizni <pbonzini@redhat.com>
|
|
||||||
*
|
|
||||||
* This work is licensed under the terms of the GNU LGPL, version 2.1 or later.
|
|
||||||
* See the COPYING.LIB file in the top-level directory.
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
#ifndef QAPI_VISITOR_IMPL_H
|
|
||||||
#define QAPI_VISITOR_IMPL_H
|
|
||||||
|
|
||||||
#include "qapi/error.h"
|
|
||||||
#include "qapi/visitor.h"
|
|
||||||
|
|
||||||
struct Visitor
|
|
||||||
{
|
|
||||||
/* Must be set */
|
|
||||||
void (*start_struct)(Visitor *v, void **obj, const char *kind,
|
|
||||||
const char *name, size_t size, Error **errp);
|
|
||||||
void (*end_struct)(Visitor *v, Error **errp);
|
|
||||||
|
|
||||||
void (*start_implicit_struct)(Visitor *v, void **obj, size_t size,
|
|
||||||
Error **errp);
|
|
||||||
void (*end_implicit_struct)(Visitor *v, Error **errp);
|
|
||||||
|
|
||||||
void (*start_list)(Visitor *v, const char *name, Error **errp);
|
|
||||||
GenericList *(*next_list)(Visitor *v, GenericList **list, Error **errp);
|
|
||||||
void (*end_list)(Visitor *v, Error **errp);
|
|
||||||
|
|
||||||
void (*type_enum)(Visitor *v, int *obj, const char * const strings[],
|
|
||||||
const char *kind, const char *name, Error **errp);
|
|
||||||
void (*get_next_type)(Visitor *v, int *kind, const int *qobjects,
|
|
||||||
const char *name, Error **errp);
|
|
||||||
|
|
||||||
void (*type_int)(Visitor *v, int64_t *obj, const char *name, Error **errp);
|
|
||||||
void (*type_bool)(Visitor *v, bool *obj, const char *name, Error **errp);
|
|
||||||
void (*type_str)(Visitor *v, char **obj, const char *name, Error **errp);
|
|
||||||
void (*type_number)(Visitor *v, double *obj, const char *name,
|
|
||||||
Error **errp);
|
|
||||||
void (*type_any)(Visitor *v, QObject **obj, const char *name,
|
|
||||||
Error **errp);
|
|
||||||
|
|
||||||
/* May be NULL */
|
|
||||||
void (*optional)(Visitor *v, bool *present, const char *name,
|
|
||||||
Error **errp);
|
|
||||||
|
|
||||||
void (*type_uint8)(Visitor *v, uint8_t *obj, const char *name, Error **errp);
|
|
||||||
void (*type_uint16)(Visitor *v, uint16_t *obj, const char *name, Error **errp);
|
|
||||||
void (*type_uint32)(Visitor *v, uint32_t *obj, const char *name, Error **errp);
|
|
||||||
void (*type_uint64)(Visitor *v, uint64_t *obj, const char *name, Error **errp);
|
|
||||||
void (*type_int8)(Visitor *v, int8_t *obj, const char *name, Error **errp);
|
|
||||||
void (*type_int16)(Visitor *v, int16_t *obj, const char *name, Error **errp);
|
|
||||||
void (*type_int32)(Visitor *v, int32_t *obj, const char *name, Error **errp);
|
|
||||||
void (*type_int64)(Visitor *v, int64_t *obj, const char *name, Error **errp);
|
|
||||||
/* visit_type_size() falls back to (*type_uint64)() if type_size is unset */
|
|
||||||
void (*type_size)(Visitor *v, uint64_t *obj, const char *name, Error **errp);
|
|
||||||
bool (*start_union)(Visitor *v, bool data_present, Error **errp);
|
|
||||||
void (*end_union)(Visitor *v, bool data_present, Error **errp);
|
|
||||||
};
|
|
||||||
|
|
||||||
void input_type_enum(Visitor *v, int *obj, const char * const strings[],
|
|
||||||
const char *kind, const char *name, Error **errp);
|
|
||||||
void output_type_enum(Visitor *v, int *obj, const char * const strings[],
|
|
||||||
const char *kind, const char *name, Error **errp);
|
|
||||||
|
|
||||||
#endif
|
|
|
@ -1,65 +0,0 @@
|
||||||
/*
|
|
||||||
* Core Definitions for QAPI Visitor Classes
|
|
||||||
*
|
|
||||||
* Copyright IBM, Corp. 2011
|
|
||||||
*
|
|
||||||
* Authors:
|
|
||||||
* Anthony Liguori <aliguori@us.ibm.com>
|
|
||||||
*
|
|
||||||
* This work is licensed under the terms of the GNU LGPL, version 2.1 or later.
|
|
||||||
* See the COPYING.LIB file in the top-level directory.
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
#ifndef QAPI_VISITOR_CORE_H
|
|
||||||
#define QAPI_VISITOR_CORE_H
|
|
||||||
|
|
||||||
#include "qemu/typedefs.h"
|
|
||||||
#include "qapi/qmp/qobject.h"
|
|
||||||
#include "qapi/error.h"
|
|
||||||
#include <stdlib.h>
|
|
||||||
|
|
||||||
typedef struct GenericList
|
|
||||||
{
|
|
||||||
union {
|
|
||||||
void *value;
|
|
||||||
uint64_t padding;
|
|
||||||
};
|
|
||||||
struct GenericList *next;
|
|
||||||
} GenericList;
|
|
||||||
|
|
||||||
void visit_start_handle(Visitor *v, void **obj, const char *kind,
|
|
||||||
const char *name, Error **errp);
|
|
||||||
void visit_end_handle(Visitor *v, Error **errp);
|
|
||||||
void visit_start_struct(Visitor *v, void **obj, const char *kind,
|
|
||||||
const char *name, size_t size, Error **errp);
|
|
||||||
void visit_end_struct(Visitor *v, Error **errp);
|
|
||||||
void visit_start_implicit_struct(Visitor *v, void **obj, size_t size,
|
|
||||||
Error **errp);
|
|
||||||
void visit_end_implicit_struct(Visitor *v, Error **errp);
|
|
||||||
void visit_start_list(Visitor *v, const char *name, Error **errp);
|
|
||||||
GenericList *visit_next_list(Visitor *v, GenericList **list, Error **errp);
|
|
||||||
void visit_end_list(Visitor *v, Error **errp);
|
|
||||||
void visit_optional(Visitor *v, bool *present, const char *name,
|
|
||||||
Error **errp);
|
|
||||||
void visit_get_next_type(Visitor *v, int *obj, const int *qtypes,
|
|
||||||
const char *name, Error **errp);
|
|
||||||
void visit_type_enum(Visitor *v, int *obj, const char * const strings[],
|
|
||||||
const char *kind, const char *name, Error **errp);
|
|
||||||
void visit_type_int(Visitor *v, int64_t *obj, const char *name, Error **errp);
|
|
||||||
void visit_type_uint8(Visitor *v, uint8_t *obj, const char *name, Error **errp);
|
|
||||||
void visit_type_uint16(Visitor *v, uint16_t *obj, const char *name, Error **errp);
|
|
||||||
void visit_type_uint32(Visitor *v, uint32_t *obj, const char *name, Error **errp);
|
|
||||||
void visit_type_uint64(Visitor *v, uint64_t *obj, const char *name, Error **errp);
|
|
||||||
void visit_type_int8(Visitor *v, int8_t *obj, const char *name, Error **errp);
|
|
||||||
void visit_type_int16(Visitor *v, int16_t *obj, const char *name, Error **errp);
|
|
||||||
void visit_type_int32(Visitor *v, int32_t *obj, const char *name, Error **errp);
|
|
||||||
void visit_type_int64(Visitor *v, int64_t *obj, const char *name, Error **errp);
|
|
||||||
void visit_type_size(Visitor *v, uint64_t *obj, const char *name, Error **errp);
|
|
||||||
void visit_type_bool(Visitor *v, bool *obj, const char *name, Error **errp);
|
|
||||||
void visit_type_str(Visitor *v, char **obj, const char *name, Error **errp);
|
|
||||||
void visit_type_number(Visitor *v, double *obj, const char *name, Error **errp);
|
|
||||||
void visit_type_any(Visitor *v, QObject **obj, const char *name, Error **errp);
|
|
||||||
bool visit_start_union(Visitor *v, bool data_present, Error **errp);
|
|
||||||
void visit_end_union(Visitor *v, bool data_present, Error **errp);
|
|
||||||
|
|
||||||
#endif
|
|
|
@ -1,482 +0,0 @@
|
||||||
|
|
||||||
/* Common header file that is included by all of QEMU.
|
|
||||||
*
|
|
||||||
* This file is supposed to be included only by .c files. No header file should
|
|
||||||
* depend on qemu-common.h, as this would easily lead to circular header
|
|
||||||
* dependencies.
|
|
||||||
*
|
|
||||||
* If a header file uses a definition from qemu-common.h, that definition
|
|
||||||
* must be moved to a separate header file, and the header that uses it
|
|
||||||
* must include that header.
|
|
||||||
*/
|
|
||||||
#ifndef QEMU_COMMON_H
|
|
||||||
#define QEMU_COMMON_H
|
|
||||||
|
|
||||||
#include "qemu/osdep.h"
|
|
||||||
#include "qemu/typedefs.h"
|
|
||||||
#include "qemu/fprintf-fn.h"
|
|
||||||
|
|
||||||
#if defined(__arm__) || defined(__sparc__) || defined(__mips__) || defined(__hppa__) || defined(__ia64__)
|
|
||||||
#define WORDS_ALIGNED
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#define TFR(expr) do { if ((expr) != -1) break; } while (errno == EINTR)
|
|
||||||
|
|
||||||
#include "glib.h"
|
|
||||||
#include "config-host.h"
|
|
||||||
#include "qemu/option.h"
|
|
||||||
#include "qemu/host-utils.h"
|
|
||||||
|
|
||||||
/* HOST_LONG_BITS is the size of a native pointer in bits. */
|
|
||||||
#if UINTPTR_MAX == UINT32_MAX
|
|
||||||
# define HOST_LONG_BITS 32
|
|
||||||
#elif UINTPTR_MAX == UINT64_MAX
|
|
||||||
# define HOST_LONG_BITS 64
|
|
||||||
#else
|
|
||||||
# error Unknown pointer size
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#define KiB 1024
|
|
||||||
#define MiB (KiB * KiB)
|
|
||||||
|
|
||||||
/* Trace unassigned memory or i/o accesses. */
|
|
||||||
extern bool trace_unassigned;
|
|
||||||
|
|
||||||
void cpu_ticks_init(void);
|
|
||||||
|
|
||||||
/* icount */
|
|
||||||
void configure_icount(QemuOpts *opts, Error **errp);
|
|
||||||
extern int use_icount;
|
|
||||||
extern int icount_align_option;
|
|
||||||
/* drift information for info jit command */
|
|
||||||
extern int64_t max_delay;
|
|
||||||
extern int64_t max_advance;
|
|
||||||
void dump_drift_info(FILE *f, fprintf_function cpu_fprintf);
|
|
||||||
|
|
||||||
#include "qemu/bswap.h"
|
|
||||||
|
|
||||||
/* FIXME: Remove NEED_CPU_H. */
|
|
||||||
#ifdef NEED_CPU_H
|
|
||||||
#include "cpu.h"
|
|
||||||
#endif /* !defined(NEED_CPU_H) */
|
|
||||||
|
|
||||||
/* main function, renamed */
|
|
||||||
#if defined(CONFIG_COCOA)
|
|
||||||
int qemu_main(int argc, char **argv, char **envp);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
void qemu_get_timedate(struct tm *tm, int offset);
|
|
||||||
int qemu_timedate_diff(struct tm *tm);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* is_help_option:
|
|
||||||
* @s: string to test
|
|
||||||
*
|
|
||||||
* Check whether @s is one of the standard strings which indicate
|
|
||||||
* that the user is asking for a list of the valid values for a
|
|
||||||
* command option like -cpu or -M. The current accepted strings
|
|
||||||
* are 'help' and '?'. '?' is deprecated (it is a shell wildcard
|
|
||||||
* which makes it annoying to use in a reliable way) but provided
|
|
||||||
* for backwards compatibility.
|
|
||||||
*
|
|
||||||
* Returns: true if @s is a request for a list.
|
|
||||||
*/
|
|
||||||
static inline bool is_help_option(const char *s)
|
|
||||||
{
|
|
||||||
return !strcmp(s, "?") || !strcmp(s, "help");
|
|
||||||
}
|
|
||||||
|
|
||||||
/* util/cutils.c */
|
|
||||||
/**
|
|
||||||
* pstrcpy:
|
|
||||||
* @buf: buffer to copy string into
|
|
||||||
* @buf_size: size of @buf in bytes
|
|
||||||
* @str: string to copy
|
|
||||||
*
|
|
||||||
* Copy @str into @buf, including the trailing NUL, but do not
|
|
||||||
* write more than @buf_size bytes. The resulting buffer is
|
|
||||||
* always NUL terminated (even if the source string was too long).
|
|
||||||
* If @buf_size is zero or negative then no bytes are copied.
|
|
||||||
*
|
|
||||||
* This function is similar to strncpy(), but avoids two of that
|
|
||||||
* function's problems:
|
|
||||||
* * if @str fits in the buffer, pstrcpy() does not zero-fill the
|
|
||||||
* remaining space at the end of @buf
|
|
||||||
* * if @str is too long, pstrcpy() will copy the first @buf_size-1
|
|
||||||
* bytes and then add a NUL
|
|
||||||
*/
|
|
||||||
void pstrcpy(char *buf, int buf_size, const char *str);
|
|
||||||
/**
|
|
||||||
* strpadcpy:
|
|
||||||
* @buf: buffer to copy string into
|
|
||||||
* @buf_size: size of @buf in bytes
|
|
||||||
* @str: string to copy
|
|
||||||
* @pad: character to pad the remainder of @buf with
|
|
||||||
*
|
|
||||||
* Copy @str into @buf (but *not* its trailing NUL!), and then pad the
|
|
||||||
* rest of the buffer with the @pad character. If @str is too large
|
|
||||||
* for the buffer then it is truncated, so that @buf contains the
|
|
||||||
* first @buf_size characters of @str, with no terminator.
|
|
||||||
*/
|
|
||||||
void strpadcpy(char *buf, int buf_size, const char *str, char pad);
|
|
||||||
/**
|
|
||||||
* pstrcat:
|
|
||||||
* @buf: buffer containing existing string
|
|
||||||
* @buf_size: size of @buf in bytes
|
|
||||||
* @s: string to concatenate to @buf
|
|
||||||
*
|
|
||||||
* Append a copy of @s to the string already in @buf, but do not
|
|
||||||
* allow the buffer to overflow. If the existing contents of @buf
|
|
||||||
* plus @str would total more than @buf_size bytes, then write
|
|
||||||
* as much of @str as will fit followed by a NUL terminator.
|
|
||||||
*
|
|
||||||
* @buf must already contain a NUL-terminated string, or the
|
|
||||||
* behaviour is undefined.
|
|
||||||
*
|
|
||||||
* Returns: @buf.
|
|
||||||
*/
|
|
||||||
char *pstrcat(char *buf, int buf_size, const char *s);
|
|
||||||
/**
|
|
||||||
* strstart:
|
|
||||||
* @str: string to test
|
|
||||||
* @val: prefix string to look for
|
|
||||||
* @ptr: NULL, or pointer to be written to indicate start of
|
|
||||||
* the remainder of the string
|
|
||||||
*
|
|
||||||
* Test whether @str starts with the prefix @val.
|
|
||||||
* If it does (including the degenerate case where @str and @val
|
|
||||||
* are equal) then return true. If @ptr is not NULL then a
|
|
||||||
* pointer to the first character following the prefix is written
|
|
||||||
* to it. If @val is not a prefix of @str then return false (and
|
|
||||||
* @ptr is not written to).
|
|
||||||
*
|
|
||||||
* Returns: true if @str starts with prefix @val, false otherwise.
|
|
||||||
*/
|
|
||||||
int strstart(const char *str, const char *val, const char **ptr);
|
|
||||||
/**
|
|
||||||
* stristart:
|
|
||||||
* @str: string to test
|
|
||||||
* @val: prefix string to look for
|
|
||||||
* @ptr: NULL, or pointer to be written to indicate start of
|
|
||||||
* the remainder of the string
|
|
||||||
*
|
|
||||||
* Test whether @str starts with the case-insensitive prefix @val.
|
|
||||||
* This function behaves identically to strstart(), except that the
|
|
||||||
* comparison is made after calling qemu_toupper() on each pair of
|
|
||||||
* characters.
|
|
||||||
*
|
|
||||||
* Returns: true if @str starts with case-insensitive prefix @val,
|
|
||||||
* false otherwise.
|
|
||||||
*/
|
|
||||||
int stristart(const char *str, const char *val, const char **ptr);
|
|
||||||
/**
|
|
||||||
* qemu_strnlen:
|
|
||||||
* @s: string
|
|
||||||
* @max_len: maximum number of bytes in @s to scan
|
|
||||||
*
|
|
||||||
* Return the length of the string @s, like strlen(), but do not
|
|
||||||
* examine more than @max_len bytes of the memory pointed to by @s.
|
|
||||||
* If no NUL terminator is found within @max_len bytes, then return
|
|
||||||
* @max_len instead.
|
|
||||||
*
|
|
||||||
* This function has the same behaviour as the POSIX strnlen()
|
|
||||||
* function.
|
|
||||||
*
|
|
||||||
* Returns: length of @s in bytes, or @max_len, whichever is smaller.
|
|
||||||
*/
|
|
||||||
int qemu_strnlen(const char *s, int max_len);
|
|
||||||
/**
|
|
||||||
* qemu_strsep:
|
|
||||||
* @input: pointer to string to parse
|
|
||||||
* @delim: string containing delimiter characters to search for
|
|
||||||
*
|
|
||||||
* Locate the first occurrence of any character in @delim within
|
|
||||||
* the string referenced by @input, and replace it with a NUL.
|
|
||||||
* The location of the next character after the delimiter character
|
|
||||||
* is stored into @input.
|
|
||||||
* If the end of the string was reached without finding a delimiter
|
|
||||||
* character, then NULL is stored into @input.
|
|
||||||
* If @input points to a NULL pointer on entry, return NULL.
|
|
||||||
* The return value is always the original value of *@input (and
|
|
||||||
* so now points to a NUL-terminated string corresponding to the
|
|
||||||
* part of the input up to the first delimiter).
|
|
||||||
*
|
|
||||||
* This function has the same behaviour as the BSD strsep() function.
|
|
||||||
*
|
|
||||||
* Returns: the pointer originally in @input.
|
|
||||||
*/
|
|
||||||
char *qemu_strsep(char **input, const char *delim);
|
|
||||||
time_t mktimegm(struct tm *tm);
|
|
||||||
int qemu_fdatasync(int fd);
|
|
||||||
int fcntl_setfl(int fd, int flag);
|
|
||||||
int qemu_parse_fd(const char *param);
|
|
||||||
int qemu_strtol(const char *nptr, const char **endptr, int base,
|
|
||||||
long *result);
|
|
||||||
int qemu_strtoul(const char *nptr, const char **endptr, int base,
|
|
||||||
unsigned long *result);
|
|
||||||
int qemu_strtoll(const char *nptr, const char **endptr, int base,
|
|
||||||
int64_t *result);
|
|
||||||
int qemu_strtoull(const char *nptr, const char **endptr, int base,
|
|
||||||
uint64_t *result);
|
|
||||||
|
|
||||||
int parse_uint(const char *s, unsigned long long *value, char **endptr,
|
|
||||||
int base);
|
|
||||||
int parse_uint_full(const char *s, unsigned long long *value, int base);
|
|
||||||
|
|
||||||
/*
|
|
||||||
* strtosz() suffixes used to specify the default treatment of an
|
|
||||||
* argument passed to strtosz() without an explicit suffix.
|
|
||||||
* These should be defined using upper case characters in the range
|
|
||||||
* A-Z, as strtosz() will use qemu_toupper() on the given argument
|
|
||||||
* prior to comparison.
|
|
||||||
*/
|
|
||||||
#define STRTOSZ_DEFSUFFIX_EB 'E'
|
|
||||||
#define STRTOSZ_DEFSUFFIX_PB 'P'
|
|
||||||
#define STRTOSZ_DEFSUFFIX_TB 'T'
|
|
||||||
#define STRTOSZ_DEFSUFFIX_GB 'G'
|
|
||||||
#define STRTOSZ_DEFSUFFIX_MB 'M'
|
|
||||||
#define STRTOSZ_DEFSUFFIX_KB 'K'
|
|
||||||
#define STRTOSZ_DEFSUFFIX_B 'B'
|
|
||||||
int64_t strtosz(const char *nptr, char **end);
|
|
||||||
int64_t strtosz_suffix(const char *nptr, char **end, const char default_suffix);
|
|
||||||
int64_t strtosz_suffix_unit(const char *nptr, char **end,
|
|
||||||
const char default_suffix, int64_t unit);
|
|
||||||
#define K_BYTE (1ULL << 10)
|
|
||||||
#define M_BYTE (1ULL << 20)
|
|
||||||
#define G_BYTE (1ULL << 30)
|
|
||||||
#define T_BYTE (1ULL << 40)
|
|
||||||
#define P_BYTE (1ULL << 50)
|
|
||||||
#define E_BYTE (1ULL << 60)
|
|
||||||
|
|
||||||
/* used to print char* safely */
|
|
||||||
#define STR_OR_NULL(str) ((str) ? (str) : "null")
|
|
||||||
|
|
||||||
/* id.c */
|
|
||||||
bool id_wellformed(const char *id);
|
|
||||||
|
|
||||||
/* path.c */
|
|
||||||
void init_paths(const char *prefix);
|
|
||||||
const char *path(const char *pathname);
|
|
||||||
|
|
||||||
#define qemu_isalnum(c) isalnum((unsigned char)(c))
|
|
||||||
#define qemu_isalpha(c) isalpha((unsigned char)(c))
|
|
||||||
#define qemu_iscntrl(c) iscntrl((unsigned char)(c))
|
|
||||||
#define qemu_isdigit(c) isdigit((unsigned char)(c))
|
|
||||||
#define qemu_isgraph(c) isgraph((unsigned char)(c))
|
|
||||||
#define qemu_islower(c) islower((unsigned char)(c))
|
|
||||||
#define qemu_isprint(c) isprint((unsigned char)(c))
|
|
||||||
#define qemu_ispunct(c) ispunct((unsigned char)(c))
|
|
||||||
#define qemu_isspace(c) isspace((unsigned char)(c))
|
|
||||||
#define qemu_isupper(c) isupper((unsigned char)(c))
|
|
||||||
#define qemu_isxdigit(c) isxdigit((unsigned char)(c))
|
|
||||||
#define qemu_tolower(c) tolower((unsigned char)(c))
|
|
||||||
#define qemu_toupper(c) toupper((unsigned char)(c))
|
|
||||||
#define qemu_isascii(c) isascii((unsigned char)(c))
|
|
||||||
#define qemu_toascii(c) toascii((unsigned char)(c))
|
|
||||||
|
|
||||||
void *qemu_oom_check(void *ptr);
|
|
||||||
|
|
||||||
ssize_t qemu_write_full(int fd, const void *buf, size_t count)
|
|
||||||
QEMU_WARN_UNUSED_RESULT;
|
|
||||||
|
|
||||||
#ifndef _WIN32
|
|
||||||
int qemu_pipe(int pipefd[2]);
|
|
||||||
/* like openpty() but also makes it raw; return master fd */
|
|
||||||
int qemu_openpty_raw(int *aslave, char *pty_name);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* Error handling. */
|
|
||||||
|
|
||||||
void QEMU_NORETURN hw_error(const char *fmt, ...) GCC_FMT_ATTR(1, 2);
|
|
||||||
|
|
||||||
struct ParallelIOArg {
|
|
||||||
void *buffer;
|
|
||||||
int count;
|
|
||||||
};
|
|
||||||
|
|
||||||
typedef int (*DMA_transfer_handler) (void *opaque, int nchan, int pos, int size);
|
|
||||||
|
|
||||||
typedef uint64_t pcibus_t;
|
|
||||||
|
|
||||||
typedef struct PCIHostDeviceAddress {
|
|
||||||
unsigned int domain;
|
|
||||||
unsigned int bus;
|
|
||||||
unsigned int slot;
|
|
||||||
unsigned int function;
|
|
||||||
} PCIHostDeviceAddress;
|
|
||||||
|
|
||||||
void tcg_exec_init(uintptr_t tb_size);
|
|
||||||
bool tcg_enabled(void);
|
|
||||||
|
|
||||||
void cpu_exec_init_all(void);
|
|
||||||
|
|
||||||
/* CPU save/load. */
|
|
||||||
#ifdef CPU_SAVE_VERSION
|
|
||||||
void cpu_save(QEMUFile *f, void *opaque);
|
|
||||||
int cpu_load(QEMUFile *f, void *opaque, int version_id);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* Unblock cpu */
|
|
||||||
void qemu_cpu_kick_self(void);
|
|
||||||
|
|
||||||
/* work queue */
|
|
||||||
struct qemu_work_item {
|
|
||||||
struct qemu_work_item *next;
|
|
||||||
void (*func)(void *data);
|
|
||||||
void *data;
|
|
||||||
int done;
|
|
||||||
bool free;
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Sends a (part of) iovec down a socket, yielding when the socket is full, or
|
|
||||||
* Receives data into a (part of) iovec from a socket,
|
|
||||||
* yielding when there is no data in the socket.
|
|
||||||
* The same interface as qemu_sendv_recvv(), with added yielding.
|
|
||||||
* XXX should mark these as coroutine_fn
|
|
||||||
*/
|
|
||||||
ssize_t qemu_co_sendv_recvv(int sockfd, struct iovec *iov, unsigned iov_cnt,
|
|
||||||
size_t offset, size_t bytes, bool do_send);
|
|
||||||
#define qemu_co_recvv(sockfd, iov, iov_cnt, offset, bytes) \
|
|
||||||
qemu_co_sendv_recvv(sockfd, iov, iov_cnt, offset, bytes, false)
|
|
||||||
#define qemu_co_sendv(sockfd, iov, iov_cnt, offset, bytes) \
|
|
||||||
qemu_co_sendv_recvv(sockfd, iov, iov_cnt, offset, bytes, true)
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The same as above, but with just a single buffer
|
|
||||||
*/
|
|
||||||
ssize_t qemu_co_send_recv(int sockfd, void *buf, size_t bytes, bool do_send);
|
|
||||||
#define qemu_co_recv(sockfd, buf, bytes) \
|
|
||||||
qemu_co_send_recv(sockfd, buf, bytes, false)
|
|
||||||
#define qemu_co_send(sockfd, buf, bytes) \
|
|
||||||
qemu_co_send_recv(sockfd, buf, bytes, true)
|
|
||||||
|
|
||||||
typedef struct QEMUIOVector {
|
|
||||||
struct iovec *iov;
|
|
||||||
int niov;
|
|
||||||
int nalloc;
|
|
||||||
size_t size;
|
|
||||||
} QEMUIOVector;
|
|
||||||
|
|
||||||
void qemu_iovec_init(QEMUIOVector *qiov, int alloc_hint);
|
|
||||||
void qemu_iovec_init_external(QEMUIOVector *qiov, struct iovec *iov, int niov);
|
|
||||||
void qemu_iovec_add(QEMUIOVector *qiov, void *base, size_t len);
|
|
||||||
void qemu_iovec_concat(QEMUIOVector *dst,
|
|
||||||
QEMUIOVector *src, size_t soffset, size_t sbytes);
|
|
||||||
size_t qemu_iovec_concat_iov(QEMUIOVector *dst,
|
|
||||||
struct iovec *src_iov, unsigned int src_cnt,
|
|
||||||
size_t soffset, size_t sbytes);
|
|
||||||
bool qemu_iovec_is_zero(QEMUIOVector *qiov);
|
|
||||||
void qemu_iovec_destroy(QEMUIOVector *qiov);
|
|
||||||
void qemu_iovec_reset(QEMUIOVector *qiov);
|
|
||||||
size_t qemu_iovec_to_buf(QEMUIOVector *qiov, size_t offset,
|
|
||||||
void *buf, size_t bytes);
|
|
||||||
size_t qemu_iovec_from_buf(QEMUIOVector *qiov, size_t offset,
|
|
||||||
const void *buf, size_t bytes);
|
|
||||||
size_t qemu_iovec_memset(QEMUIOVector *qiov, size_t offset,
|
|
||||||
int fillc, size_t bytes);
|
|
||||||
ssize_t qemu_iovec_compare(QEMUIOVector *a, QEMUIOVector *b);
|
|
||||||
void qemu_iovec_clone(QEMUIOVector *dest, const QEMUIOVector *src, void *buf);
|
|
||||||
void qemu_iovec_discard_back(QEMUIOVector *qiov, size_t bytes);
|
|
||||||
|
|
||||||
bool buffer_is_zero(const void *buf, size_t len);
|
|
||||||
|
|
||||||
void qemu_progress_init(int enabled, float min_skip);
|
|
||||||
void qemu_progress_end(void);
|
|
||||||
void qemu_progress_print(float delta, int max);
|
|
||||||
const char *qemu_get_vm_name(void);
|
|
||||||
|
|
||||||
#define QEMU_FILE_TYPE_BIOS 0
|
|
||||||
#define QEMU_FILE_TYPE_KEYMAP 1
|
|
||||||
char *qemu_find_file(int type, const char *name);
|
|
||||||
|
|
||||||
/* OS specific functions */
|
|
||||||
void os_setup_early_signal_handling(void);
|
|
||||||
char *os_find_datadir(void);
|
|
||||||
void os_parse_cmd_args(int index, const char *optarg);
|
|
||||||
|
|
||||||
/* Convert a byte between binary and BCD. */
|
|
||||||
static inline uint8_t to_bcd(uint8_t val)
|
|
||||||
{
|
|
||||||
return ((val / 10) << 4) | (val % 10);
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline uint8_t from_bcd(uint8_t val)
|
|
||||||
{
|
|
||||||
return ((val >> 4) * 10) + (val & 0x0f);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Round number down to multiple */
|
|
||||||
#define QEMU_ALIGN_DOWN(n, m) ((n) / (m) * (m))
|
|
||||||
|
|
||||||
/* Round number up to multiple */
|
|
||||||
#define QEMU_ALIGN_UP(n, m) QEMU_ALIGN_DOWN((n) + (m) - 1, (m))
|
|
||||||
|
|
||||||
#include "qemu/module.h"
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Implementation of ULEB128 (http://en.wikipedia.org/wiki/LEB128)
|
|
||||||
* Input is limited to 14-bit numbers
|
|
||||||
*/
|
|
||||||
|
|
||||||
int uleb128_encode_small(uint8_t *out, uint32_t n);
|
|
||||||
int uleb128_decode_small(const uint8_t *in, uint32_t *n);
|
|
||||||
|
|
||||||
/* unicode.c */
|
|
||||||
int mod_utf8_codepoint(const char *s, size_t n, char **end);
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Hexdump a buffer to a file. An optional string prefix is added to every line
|
|
||||||
*/
|
|
||||||
|
|
||||||
void qemu_hexdump(const char *buf, FILE *fp, const char *prefix, size_t size);
|
|
||||||
|
|
||||||
/* vector definitions */
|
|
||||||
#ifdef __ALTIVEC__
|
|
||||||
#include <altivec.h>
|
|
||||||
/* The altivec.h header says we're allowed to undef these for
|
|
||||||
* C++ compatibility. Here we don't care about C++, but we
|
|
||||||
* undef them anyway to avoid namespace pollution.
|
|
||||||
*/
|
|
||||||
#undef vector
|
|
||||||
#undef pixel
|
|
||||||
#undef bool
|
|
||||||
#define VECTYPE __vector unsigned char
|
|
||||||
#define SPLAT(p) vec_splat(vec_ld(0, p), 0)
|
|
||||||
#define ALL_EQ(v1, v2) vec_all_eq(v1, v2)
|
|
||||||
#define VEC_OR(v1, v2) ((v1) | (v2))
|
|
||||||
/* altivec.h may redefine the bool macro as vector type.
|
|
||||||
* Reset it to POSIX semantics. */
|
|
||||||
#define bool _Bool
|
|
||||||
#elif defined __SSE2__
|
|
||||||
#include <emmintrin.h>
|
|
||||||
#define VECTYPE __m128i
|
|
||||||
#define SPLAT(p) _mm_set1_epi8(*(p))
|
|
||||||
#define ALL_EQ(v1, v2) (_mm_movemask_epi8(_mm_cmpeq_epi8(v1, v2)) == 0xFFFF)
|
|
||||||
#define VEC_OR(v1, v2) (_mm_or_si128(v1, v2))
|
|
||||||
#else
|
|
||||||
#define VECTYPE unsigned long
|
|
||||||
#define SPLAT(p) (*(p) * (~0UL / 255))
|
|
||||||
#define ALL_EQ(v1, v2) ((v1) == (v2))
|
|
||||||
#define VEC_OR(v1, v2) ((v1) | (v2))
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#define BUFFER_FIND_NONZERO_OFFSET_UNROLL_FACTOR 8
|
|
||||||
static inline bool
|
|
||||||
can_use_buffer_find_nonzero_offset(const void *buf, size_t len)
|
|
||||||
{
|
|
||||||
return (len % (BUFFER_FIND_NONZERO_OFFSET_UNROLL_FACTOR
|
|
||||||
* sizeof(VECTYPE)) == 0
|
|
||||||
&& ((uintptr_t) buf) % sizeof(VECTYPE) == 0);
|
|
||||||
}
|
|
||||||
size_t buffer_find_nonzero_offset(const void *buf, size_t len);
|
|
||||||
|
|
||||||
/*
|
|
||||||
* helper to parse debug environment variables
|
|
||||||
*/
|
|
||||||
int parse_debug_env(const char *name, int max, int initial);
|
|
||||||
|
|
||||||
const char *qemu_ether_ntoa(const MACAddr *mac);
|
|
||||||
|
|
||||||
#endif
|
|
|
@ -1,54 +0,0 @@
|
||||||
/*
|
|
||||||
* Recursive FIFO lock
|
|
||||||
*
|
|
||||||
* Copyright Red Hat, Inc. 2013
|
|
||||||
*
|
|
||||||
* Authors:
|
|
||||||
* Stefan Hajnoczi <stefanha@redhat.com>
|
|
||||||
*
|
|
||||||
* This work is licensed under the terms of the GNU GPL, version 2 or later.
|
|
||||||
* See the COPYING file in the top-level directory.
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef QEMU_RFIFOLOCK_H
|
|
||||||
#define QEMU_RFIFOLOCK_H
|
|
||||||
|
|
||||||
#include "qemu/thread.h"
|
|
||||||
|
|
||||||
/* Recursive FIFO lock
|
|
||||||
*
|
|
||||||
* This lock provides more features than a plain mutex:
|
|
||||||
*
|
|
||||||
* 1. Fairness - enforces FIFO order.
|
|
||||||
* 2. Nesting - can be taken recursively.
|
|
||||||
* 3. Contention callback - optional, called when thread must wait.
|
|
||||||
*
|
|
||||||
* The recursive FIFO lock is heavyweight so prefer other synchronization
|
|
||||||
* primitives if you do not need its features.
|
|
||||||
*/
|
|
||||||
typedef struct {
|
|
||||||
QemuMutex lock; /* protects all fields */
|
|
||||||
|
|
||||||
/* FIFO order */
|
|
||||||
unsigned int head; /* active ticket number */
|
|
||||||
unsigned int tail; /* waiting ticket number */
|
|
||||||
QemuCond cond; /* used to wait for our ticket number */
|
|
||||||
|
|
||||||
/* Nesting */
|
|
||||||
QemuThread owner_thread; /* thread that currently has ownership */
|
|
||||||
unsigned int nesting; /* amount of nesting levels */
|
|
||||||
|
|
||||||
/* Contention callback */
|
|
||||||
void (*cb)(void *); /* called when thread must wait, with ->lock
|
|
||||||
* held so it may not recursively lock/unlock
|
|
||||||
*/
|
|
||||||
void *cb_opaque;
|
|
||||||
} RFifoLock;
|
|
||||||
|
|
||||||
void rfifolock_init(RFifoLock *r, void (*cb)(void *), void *opaque);
|
|
||||||
void rfifolock_destroy(RFifoLock *r);
|
|
||||||
void rfifolock_lock(RFifoLock *r);
|
|
||||||
void rfifolock_unlock(RFifoLock *r);
|
|
||||||
|
|
||||||
#endif /* QEMU_RFIFOLOCK_H */
|
|
|
@ -1,94 +0,0 @@
|
||||||
/* headers to use the BSD sockets */
|
|
||||||
#ifndef QEMU_SOCKET_H
|
|
||||||
#define QEMU_SOCKET_H
|
|
||||||
|
|
||||||
#ifdef _WIN32
|
|
||||||
#include <windows.h>
|
|
||||||
#include <winsock2.h>
|
|
||||||
#include <ws2tcpip.h>
|
|
||||||
|
|
||||||
#define socket_error() WSAGetLastError()
|
|
||||||
|
|
||||||
int inet_aton(const char *cp, struct in_addr *ia);
|
|
||||||
|
|
||||||
#else
|
|
||||||
|
|
||||||
#include <sys/types.h>
|
|
||||||
#include <sys/socket.h>
|
|
||||||
#include <netinet/in.h>
|
|
||||||
#include <netinet/tcp.h>
|
|
||||||
#include <arpa/inet.h>
|
|
||||||
#include <netdb.h>
|
|
||||||
#include <sys/un.h>
|
|
||||||
|
|
||||||
#define socket_error() errno
|
|
||||||
|
|
||||||
#endif /* !_WIN32 */
|
|
||||||
|
|
||||||
#include "qemu/option.h"
|
|
||||||
#include "qapi/error.h"
|
|
||||||
#include "qapi-types.h"
|
|
||||||
|
|
||||||
extern QemuOptsList socket_optslist;
|
|
||||||
|
|
||||||
/* misc helpers */
|
|
||||||
int qemu_socket(int domain, int type, int protocol);
|
|
||||||
int qemu_accept(int s, struct sockaddr *addr, socklen_t *addrlen);
|
|
||||||
int socket_set_cork(int fd, int v);
|
|
||||||
int socket_set_nodelay(int fd);
|
|
||||||
void qemu_set_block(int fd);
|
|
||||||
void qemu_set_nonblock(int fd);
|
|
||||||
int socket_set_fast_reuse(int fd);
|
|
||||||
int send_all(int fd, const void *buf, int len1);
|
|
||||||
int recv_all(int fd, void *buf, int len1, bool single_read);
|
|
||||||
|
|
||||||
#ifdef _WIN32
|
|
||||||
/* MinGW needs type casts for the 'buf' and 'optval' arguments. */
|
|
||||||
#define qemu_sendto(sockfd, buf, len, flags, destaddr, addrlen) \
|
|
||||||
sendto(sockfd, (const void *)buf, len, flags, destaddr, addrlen)
|
|
||||||
|
|
||||||
/* Windows has different names for the same constants with the same values */
|
|
||||||
#define SHUT_RD 0
|
|
||||||
#define SHUT_WR 1
|
|
||||||
#define SHUT_RDWR 2
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* callback function for nonblocking connect
|
|
||||||
* valid fd on success, negative error code on failure
|
|
||||||
*/
|
|
||||||
typedef void NonBlockingConnectHandler(int fd, Error *errp, void *opaque);
|
|
||||||
|
|
||||||
InetSocketAddress *inet_parse(const char *str, Error **errp);
|
|
||||||
int inet_listen_opts(QemuOpts *opts, int port_offset, Error **errp);
|
|
||||||
int inet_listen(const char *str, char *ostr, int olen,
|
|
||||||
int socktype, int port_offset, Error **errp);
|
|
||||||
int inet_connect_opts(QemuOpts *opts, Error **errp,
|
|
||||||
NonBlockingConnectHandler *callback, void *opaque);
|
|
||||||
int inet_connect(const char *str, Error **errp);
|
|
||||||
int inet_nonblocking_connect(const char *str,
|
|
||||||
NonBlockingConnectHandler *callback,
|
|
||||||
void *opaque, Error **errp);
|
|
||||||
|
|
||||||
int inet_dgram_opts(QemuOpts *opts, Error **errp);
|
|
||||||
NetworkAddressFamily inet_netfamily(int family);
|
|
||||||
|
|
||||||
int unix_listen_opts(QemuOpts *opts, Error **errp);
|
|
||||||
int unix_listen(const char *path, char *ostr, int olen, Error **errp);
|
|
||||||
int unix_connect_opts(QemuOpts *opts, Error **errp,
|
|
||||||
NonBlockingConnectHandler *callback, void *opaque);
|
|
||||||
int unix_connect(const char *path, Error **errp);
|
|
||||||
int unix_nonblocking_connect(const char *str,
|
|
||||||
NonBlockingConnectHandler *callback,
|
|
||||||
void *opaque, Error **errp);
|
|
||||||
|
|
||||||
SocketAddress *socket_parse(const char *str, Error **errp);
|
|
||||||
int socket_connect(SocketAddress *addr, Error **errp,
|
|
||||||
NonBlockingConnectHandler *callback, void *opaque);
|
|
||||||
int socket_listen(SocketAddress *addr, Error **errp);
|
|
||||||
int socket_dgram(SocketAddress *remote, SocketAddress *local, Error **errp);
|
|
||||||
|
|
||||||
/* Old, ipv4 only bits. Don't use for new code. */
|
|
||||||
int parse_host_port(struct sockaddr_in *saddr, const char *str);
|
|
||||||
int socket_init(void);
|
|
||||||
|
|
||||||
#endif /* QEMU_SOCKET_H */
|
|
|
@ -1,371 +0,0 @@
|
||||||
#ifndef QEMU_CHAR_H
|
|
||||||
#define QEMU_CHAR_H
|
|
||||||
|
|
||||||
#include "qemu-common.h"
|
|
||||||
#include "qemu/queue.h"
|
|
||||||
#include "qemu/option.h"
|
|
||||||
#include "qemu/config-file.h"
|
|
||||||
#include "block/aio.h"
|
|
||||||
#include "qapi/qmp/qobject.h"
|
|
||||||
#include "qapi/qmp/qstring.h"
|
|
||||||
#include "qemu/main-loop.h"
|
|
||||||
|
|
||||||
/* character device */
|
|
||||||
|
|
||||||
#define CHR_EVENT_BREAK 0 /* serial break char */
|
|
||||||
#define CHR_EVENT_FOCUS 1 /* focus to this terminal (modal input needed) */
|
|
||||||
#define CHR_EVENT_OPENED 2 /* new connection established */
|
|
||||||
#define CHR_EVENT_MUX_IN 3 /* mux-focus was set to this terminal */
|
|
||||||
#define CHR_EVENT_MUX_OUT 4 /* mux-focus will move on */
|
|
||||||
#define CHR_EVENT_CLOSED 5 /* connection closed */
|
|
||||||
|
|
||||||
|
|
||||||
#define CHR_IOCTL_SERIAL_SET_PARAMS 1
|
|
||||||
typedef struct {
|
|
||||||
int speed;
|
|
||||||
int parity;
|
|
||||||
int data_bits;
|
|
||||||
int stop_bits;
|
|
||||||
} QEMUSerialSetParams;
|
|
||||||
|
|
||||||
#define CHR_IOCTL_SERIAL_SET_BREAK 2
|
|
||||||
|
|
||||||
#define CHR_IOCTL_PP_READ_DATA 3
|
|
||||||
#define CHR_IOCTL_PP_WRITE_DATA 4
|
|
||||||
#define CHR_IOCTL_PP_READ_CONTROL 5
|
|
||||||
#define CHR_IOCTL_PP_WRITE_CONTROL 6
|
|
||||||
#define CHR_IOCTL_PP_READ_STATUS 7
|
|
||||||
#define CHR_IOCTL_PP_EPP_READ_ADDR 8
|
|
||||||
#define CHR_IOCTL_PP_EPP_READ 9
|
|
||||||
#define CHR_IOCTL_PP_EPP_WRITE_ADDR 10
|
|
||||||
#define CHR_IOCTL_PP_EPP_WRITE 11
|
|
||||||
#define CHR_IOCTL_PP_DATA_DIR 12
|
|
||||||
|
|
||||||
#define CHR_IOCTL_SERIAL_SET_TIOCM 13
|
|
||||||
#define CHR_IOCTL_SERIAL_GET_TIOCM 14
|
|
||||||
|
|
||||||
#define CHR_TIOCM_CTS 0x020
|
|
||||||
#define CHR_TIOCM_CAR 0x040
|
|
||||||
#define CHR_TIOCM_DSR 0x100
|
|
||||||
#define CHR_TIOCM_RI 0x080
|
|
||||||
#define CHR_TIOCM_DTR 0x002
|
|
||||||
#define CHR_TIOCM_RTS 0x004
|
|
||||||
|
|
||||||
typedef void IOEventHandler(void *opaque, int event);
|
|
||||||
|
|
||||||
struct CharDriverState {
|
|
||||||
QemuMutex chr_write_lock;
|
|
||||||
void (*init)(struct CharDriverState *s);
|
|
||||||
int (*chr_write)(struct CharDriverState *s, const uint8_t *buf, int len);
|
|
||||||
int (*chr_sync_read)(struct CharDriverState *s,
|
|
||||||
const uint8_t *buf, int len);
|
|
||||||
GSource *(*chr_add_watch)(struct CharDriverState *s, GIOCondition cond);
|
|
||||||
void (*chr_update_read_handler)(struct CharDriverState *s);
|
|
||||||
int (*chr_ioctl)(struct CharDriverState *s, int cmd, void *arg);
|
|
||||||
int (*get_msgfds)(struct CharDriverState *s, int* fds, int num);
|
|
||||||
int (*set_msgfds)(struct CharDriverState *s, int *fds, int num);
|
|
||||||
int (*chr_add_client)(struct CharDriverState *chr, int fd);
|
|
||||||
IOEventHandler *chr_event;
|
|
||||||
IOCanReadHandler *chr_can_read;
|
|
||||||
IOReadHandler *chr_read;
|
|
||||||
void *handler_opaque;
|
|
||||||
void (*chr_close)(struct CharDriverState *chr);
|
|
||||||
void (*chr_accept_input)(struct CharDriverState *chr);
|
|
||||||
void (*chr_set_echo)(struct CharDriverState *chr, bool echo);
|
|
||||||
void (*chr_set_fe_open)(struct CharDriverState *chr, int fe_open);
|
|
||||||
void (*chr_fe_event)(struct CharDriverState *chr, int event);
|
|
||||||
void *opaque;
|
|
||||||
char *label;
|
|
||||||
char *filename;
|
|
||||||
int be_open;
|
|
||||||
int fe_open;
|
|
||||||
int explicit_fe_open;
|
|
||||||
int explicit_be_open;
|
|
||||||
int avail_connections;
|
|
||||||
int is_mux;
|
|
||||||
guint fd_in_tag;
|
|
||||||
QemuOpts *opts;
|
|
||||||
QTAILQ_ENTRY(CharDriverState) next;
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @qemu_chr_alloc:
|
|
||||||
*
|
|
||||||
* Allocate and initialize a new CharDriverState.
|
|
||||||
*
|
|
||||||
* Returns: a newly allocated CharDriverState.
|
|
||||||
*/
|
|
||||||
CharDriverState *qemu_chr_alloc(void);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @qemu_chr_new_from_opts:
|
|
||||||
*
|
|
||||||
* Create a new character backend from a QemuOpts list.
|
|
||||||
*
|
|
||||||
* @opts see qemu-config.c for a list of valid options
|
|
||||||
* @init not sure..
|
|
||||||
*
|
|
||||||
* Returns: a new character backend
|
|
||||||
*/
|
|
||||||
CharDriverState *qemu_chr_new_from_opts(QemuOpts *opts,
|
|
||||||
void (*init)(struct CharDriverState *s),
|
|
||||||
Error **errp);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @qemu_chr_new:
|
|
||||||
*
|
|
||||||
* Create a new character backend from a URI.
|
|
||||||
*
|
|
||||||
* @label the name of the backend
|
|
||||||
* @filename the URI
|
|
||||||
* @init not sure..
|
|
||||||
*
|
|
||||||
* Returns: a new character backend
|
|
||||||
*/
|
|
||||||
CharDriverState *qemu_chr_new(const char *label, const char *filename,
|
|
||||||
void (*init)(struct CharDriverState *s));
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @qemu_chr_delete:
|
|
||||||
*
|
|
||||||
* Destroy a character backend.
|
|
||||||
*/
|
|
||||||
void qemu_chr_delete(CharDriverState *chr);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @qemu_chr_fe_set_echo:
|
|
||||||
*
|
|
||||||
* Ask the backend to override its normal echo setting. This only really
|
|
||||||
* applies to the stdio backend and is used by the QMP server such that you
|
|
||||||
* can see what you type if you try to type QMP commands.
|
|
||||||
*
|
|
||||||
* @echo true to enable echo, false to disable echo
|
|
||||||
*/
|
|
||||||
void qemu_chr_fe_set_echo(struct CharDriverState *chr, bool echo);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @qemu_chr_fe_set_open:
|
|
||||||
*
|
|
||||||
* Set character frontend open status. This is an indication that the
|
|
||||||
* front end is ready (or not) to begin doing I/O.
|
|
||||||
*/
|
|
||||||
void qemu_chr_fe_set_open(struct CharDriverState *chr, int fe_open);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @qemu_chr_fe_event:
|
|
||||||
*
|
|
||||||
* Send an event from the front end to the back end.
|
|
||||||
*
|
|
||||||
* @event the event to send
|
|
||||||
*/
|
|
||||||
void qemu_chr_fe_event(CharDriverState *s, int event);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @qemu_chr_fe_printf:
|
|
||||||
*
|
|
||||||
* Write to a character backend using a printf style interface.
|
|
||||||
* This function is thread-safe.
|
|
||||||
*
|
|
||||||
* @fmt see #printf
|
|
||||||
*/
|
|
||||||
void qemu_chr_fe_printf(CharDriverState *s, const char *fmt, ...)
|
|
||||||
GCC_FMT_ATTR(2, 3);
|
|
||||||
|
|
||||||
//int qemu_chr_fe_add_watch(CharDriverState *s, GIOCondition cond,
|
|
||||||
// GIOFunc func, void *user_data);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @qemu_chr_fe_write:
|
|
||||||
*
|
|
||||||
* Write data to a character backend from the front end. This function
|
|
||||||
* will send data from the front end to the back end. This function
|
|
||||||
* is thread-safe.
|
|
||||||
*
|
|
||||||
* @buf the data
|
|
||||||
* @len the number of bytes to send
|
|
||||||
*
|
|
||||||
* Returns: the number of bytes consumed
|
|
||||||
*/
|
|
||||||
int qemu_chr_fe_write(CharDriverState *s, const uint8_t *buf, int len);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @qemu_chr_fe_write_all:
|
|
||||||
*
|
|
||||||
* Write data to a character backend from the front end. This function will
|
|
||||||
* send data from the front end to the back end. Unlike @qemu_chr_fe_write,
|
|
||||||
* this function will block if the back end cannot consume all of the data
|
|
||||||
* attempted to be written. This function is thread-safe.
|
|
||||||
*
|
|
||||||
* @buf the data
|
|
||||||
* @len the number of bytes to send
|
|
||||||
*
|
|
||||||
* Returns: the number of bytes consumed
|
|
||||||
*/
|
|
||||||
int qemu_chr_fe_write_all(CharDriverState *s, const uint8_t *buf, int len);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @qemu_chr_fe_read_all:
|
|
||||||
*
|
|
||||||
* Read data to a buffer from the back end.
|
|
||||||
*
|
|
||||||
* @buf the data buffer
|
|
||||||
* @len the number of bytes to read
|
|
||||||
*
|
|
||||||
* Returns: the number of bytes read
|
|
||||||
*/
|
|
||||||
int qemu_chr_fe_read_all(CharDriverState *s, uint8_t *buf, int len);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @qemu_chr_fe_ioctl:
|
|
||||||
*
|
|
||||||
* Issue a device specific ioctl to a backend. This function is thread-safe.
|
|
||||||
*
|
|
||||||
* @cmd see CHR_IOCTL_*
|
|
||||||
* @arg the data associated with @cmd
|
|
||||||
*
|
|
||||||
* Returns: if @cmd is not supported by the backend, -ENOTSUP, otherwise the
|
|
||||||
* return value depends on the semantics of @cmd
|
|
||||||
*/
|
|
||||||
int qemu_chr_fe_ioctl(CharDriverState *s, int cmd, void *arg);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @qemu_chr_fe_get_msgfd:
|
|
||||||
*
|
|
||||||
* For backends capable of fd passing, return the latest file descriptor passed
|
|
||||||
* by a client.
|
|
||||||
*
|
|
||||||
* Returns: -1 if fd passing isn't supported or there is no pending file
|
|
||||||
* descriptor. If a file descriptor is returned, subsequent calls to
|
|
||||||
* this function will return -1 until a client sends a new file
|
|
||||||
* descriptor.
|
|
||||||
*/
|
|
||||||
int qemu_chr_fe_get_msgfd(CharDriverState *s);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @qemu_chr_fe_get_msgfds:
|
|
||||||
*
|
|
||||||
* For backends capable of fd passing, return the number of file received
|
|
||||||
* descriptors and fills the fds array up to num elements
|
|
||||||
*
|
|
||||||
* Returns: -1 if fd passing isn't supported or there are no pending file
|
|
||||||
* descriptors. If file descriptors are returned, subsequent calls to
|
|
||||||
* this function will return -1 until a client sends a new set of file
|
|
||||||
* descriptors.
|
|
||||||
*/
|
|
||||||
int qemu_chr_fe_get_msgfds(CharDriverState *s, int *fds, int num);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @qemu_chr_fe_set_msgfds:
|
|
||||||
*
|
|
||||||
* For backends capable of fd passing, set an array of fds to be passed with
|
|
||||||
* the next send operation.
|
|
||||||
* A subsequent call to this function before calling a write function will
|
|
||||||
* result in overwriting the fd array with the new value without being send.
|
|
||||||
* Upon writing the message the fd array is freed.
|
|
||||||
*
|
|
||||||
* Returns: -1 if fd passing isn't supported.
|
|
||||||
*/
|
|
||||||
int qemu_chr_fe_set_msgfds(CharDriverState *s, int *fds, int num);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @qemu_chr_fe_claim:
|
|
||||||
*
|
|
||||||
* Claim a backend before using it, should be called before calling
|
|
||||||
* qemu_chr_add_handlers().
|
|
||||||
*
|
|
||||||
* Returns: -1 if the backend is already in use by another frontend, 0 on
|
|
||||||
* success.
|
|
||||||
*/
|
|
||||||
int qemu_chr_fe_claim(CharDriverState *s);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @qemu_chr_fe_claim_no_fail:
|
|
||||||
*
|
|
||||||
* Like qemu_chr_fe_claim, but will exit qemu with an error when the
|
|
||||||
* backend is already in use.
|
|
||||||
*/
|
|
||||||
void qemu_chr_fe_claim_no_fail(CharDriverState *s);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @qemu_chr_fe_claim:
|
|
||||||
*
|
|
||||||
* Release a backend for use by another frontend.
|
|
||||||
*
|
|
||||||
* Returns: -1 if the backend is already in use by another frontend, 0 on
|
|
||||||
* success.
|
|
||||||
*/
|
|
||||||
void qemu_chr_fe_release(CharDriverState *s);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @qemu_chr_be_can_write:
|
|
||||||
*
|
|
||||||
* Determine how much data the front end can currently accept. This function
|
|
||||||
* returns the number of bytes the front end can accept. If it returns 0, the
|
|
||||||
* front end cannot receive data at the moment. The function must be polled
|
|
||||||
* to determine when data can be received.
|
|
||||||
*
|
|
||||||
* Returns: the number of bytes the front end can receive via @qemu_chr_be_write
|
|
||||||
*/
|
|
||||||
int qemu_chr_be_can_write(CharDriverState *s);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @qemu_chr_be_write:
|
|
||||||
*
|
|
||||||
* Write data from the back end to the front end. Before issuing this call,
|
|
||||||
* the caller should call @qemu_chr_be_can_write to determine how much data
|
|
||||||
* the front end can currently accept.
|
|
||||||
*
|
|
||||||
* @buf a buffer to receive data from the front end
|
|
||||||
* @len the number of bytes to receive from the front end
|
|
||||||
*/
|
|
||||||
void qemu_chr_be_write(CharDriverState *s, uint8_t *buf, int len);
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @qemu_chr_be_event:
|
|
||||||
*
|
|
||||||
* Send an event from the back end to the front end.
|
|
||||||
*
|
|
||||||
* @event the event to send
|
|
||||||
*/
|
|
||||||
void qemu_chr_be_event(CharDriverState *s, int event);
|
|
||||||
|
|
||||||
void qemu_chr_add_handlers(CharDriverState *s,
|
|
||||||
IOCanReadHandler *fd_can_read,
|
|
||||||
IOReadHandler *fd_read,
|
|
||||||
IOEventHandler *fd_event,
|
|
||||||
void *opaque);
|
|
||||||
|
|
||||||
void qemu_chr_be_generic_open(CharDriverState *s);
|
|
||||||
void qemu_chr_accept_input(CharDriverState *s);
|
|
||||||
int qemu_chr_add_client(CharDriverState *s, int fd);
|
|
||||||
CharDriverState *qemu_chr_find(const char *name);
|
|
||||||
bool chr_is_ringbuf(const CharDriverState *chr);
|
|
||||||
|
|
||||||
QemuOpts *qemu_chr_parse_compat(const char *label, const char *filename);
|
|
||||||
|
|
||||||
void register_char_driver(const char *name, ChardevBackendKind kind,
|
|
||||||
void (*parse)(QemuOpts *opts, ChardevBackend *backend, Error **errp));
|
|
||||||
|
|
||||||
/* add an eventfd to the qemu devices that are polled */
|
|
||||||
CharDriverState *qemu_chr_open_eventfd(int eventfd);
|
|
||||||
|
|
||||||
extern int term_escape_char;
|
|
||||||
|
|
||||||
CharDriverState *qemu_char_get_next_serial(void);
|
|
||||||
|
|
||||||
/* msmouse */
|
|
||||||
CharDriverState *qemu_chr_open_msmouse(void);
|
|
||||||
|
|
||||||
/* testdev.c */
|
|
||||||
CharDriverState *chr_testdev_init(void);
|
|
||||||
|
|
||||||
/* baum.c */
|
|
||||||
CharDriverState *chr_baum_init(void);
|
|
||||||
|
|
||||||
/* console.c */
|
|
||||||
typedef CharDriverState *(VcHandler)(ChardevVC *vc);
|
|
||||||
|
|
||||||
void register_vc_handler(VcHandler *handler);
|
|
||||||
CharDriverState *vc_init(ChardevVC *vc);
|
|
||||||
#endif
|
|
|
@ -1,36 +0,0 @@
|
||||||
#ifndef __QEMU_THREAD_POSIX_H
|
|
||||||
#define __QEMU_THREAD_POSIX_H 1
|
|
||||||
#include "pthread.h"
|
|
||||||
#include <semaphore.h>
|
|
||||||
|
|
||||||
struct QemuMutex {
|
|
||||||
pthread_mutex_t lock;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct QemuCond {
|
|
||||||
pthread_cond_t cond;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct QemuSemaphore {
|
|
||||||
#if defined(__APPLE__) || defined(__NetBSD__)
|
|
||||||
pthread_mutex_t lock;
|
|
||||||
pthread_cond_t cond;
|
|
||||||
unsigned int count;
|
|
||||||
#else
|
|
||||||
sem_t sem;
|
|
||||||
#endif
|
|
||||||
};
|
|
||||||
|
|
||||||
struct QemuEvent {
|
|
||||||
#ifndef __linux__
|
|
||||||
pthread_mutex_t lock;
|
|
||||||
pthread_cond_t cond;
|
|
||||||
#endif
|
|
||||||
unsigned value;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct QemuThread {
|
|
||||||
pthread_t thread;
|
|
||||||
};
|
|
||||||
|
|
||||||
#endif
|
|
|
@ -1,34 +0,0 @@
|
||||||
#ifndef __QEMU_THREAD_WIN32_H
|
|
||||||
#define __QEMU_THREAD_WIN32_H 1
|
|
||||||
#include "windows.h"
|
|
||||||
|
|
||||||
struct QemuMutex {
|
|
||||||
CRITICAL_SECTION lock;
|
|
||||||
LONG owner;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct QemuCond {
|
|
||||||
LONG waiters, target;
|
|
||||||
HANDLE sema;
|
|
||||||
HANDLE continue_event;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct QemuSemaphore {
|
|
||||||
HANDLE sema;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct QemuEvent {
|
|
||||||
int value;
|
|
||||||
HANDLE event;
|
|
||||||
};
|
|
||||||
|
|
||||||
typedef struct QemuThreadData QemuThreadData;
|
|
||||||
struct QemuThread {
|
|
||||||
QemuThreadData *data;
|
|
||||||
unsigned tid;
|
|
||||||
};
|
|
||||||
|
|
||||||
/* Only valid for joinable threads. */
|
|
||||||
HANDLE qemu_thread_get_handle(QemuThread *thread);
|
|
||||||
|
|
||||||
#endif
|
|
|
@ -1,62 +0,0 @@
|
||||||
#ifndef __QEMU_THREAD_H
|
|
||||||
#define __QEMU_THREAD_H 1
|
|
||||||
|
|
||||||
typedef struct QemuMutex QemuMutex;
|
|
||||||
typedef struct QemuCond QemuCond;
|
|
||||||
typedef struct QemuSemaphore QemuSemaphore;
|
|
||||||
typedef struct QemuEvent QemuEvent;
|
|
||||||
typedef struct QemuThread QemuThread;
|
|
||||||
|
|
||||||
#if defined(_WIN32) && !defined(_MSC_VER)
|
|
||||||
#include "qemu/thread-win32.h"
|
|
||||||
#else
|
|
||||||
#include "qemu/thread-posix.h"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#define QEMU_THREAD_JOINABLE 0
|
|
||||||
#define QEMU_THREAD_DETACHED 1
|
|
||||||
|
|
||||||
void qemu_mutex_init(QemuMutex *mutex);
|
|
||||||
void qemu_mutex_destroy(QemuMutex *mutex);
|
|
||||||
void qemu_mutex_lock(QemuMutex *mutex);
|
|
||||||
int qemu_mutex_trylock(QemuMutex *mutex);
|
|
||||||
void qemu_mutex_unlock(QemuMutex *mutex);
|
|
||||||
|
|
||||||
void qemu_cond_init(QemuCond *cond);
|
|
||||||
void qemu_cond_destroy(QemuCond *cond);
|
|
||||||
|
|
||||||
/*
|
|
||||||
* IMPORTANT: The implementation does not guarantee that pthread_cond_signal
|
|
||||||
* and pthread_cond_broadcast can be called except while the same mutex is
|
|
||||||
* held as in the corresponding pthread_cond_wait calls!
|
|
||||||
*/
|
|
||||||
void qemu_cond_signal(QemuCond *cond);
|
|
||||||
void qemu_cond_broadcast(QemuCond *cond);
|
|
||||||
void qemu_cond_wait(QemuCond *cond, QemuMutex *mutex);
|
|
||||||
|
|
||||||
void qemu_sem_init(QemuSemaphore *sem, int init);
|
|
||||||
void qemu_sem_post(QemuSemaphore *sem);
|
|
||||||
void qemu_sem_wait(QemuSemaphore *sem);
|
|
||||||
int qemu_sem_timedwait(QemuSemaphore *sem, int ms);
|
|
||||||
void qemu_sem_destroy(QemuSemaphore *sem);
|
|
||||||
|
|
||||||
void qemu_event_init(QemuEvent *ev, bool init);
|
|
||||||
void qemu_event_set(QemuEvent *ev);
|
|
||||||
void qemu_event_reset(QemuEvent *ev);
|
|
||||||
void qemu_event_wait(QemuEvent *ev);
|
|
||||||
void qemu_event_destroy(QemuEvent *ev);
|
|
||||||
|
|
||||||
void qemu_thread_create(QemuThread *thread, const char *name,
|
|
||||||
void *(*start_routine)(void *),
|
|
||||||
void *arg, int mode);
|
|
||||||
void *qemu_thread_join(QemuThread *thread);
|
|
||||||
void qemu_thread_get_self(QemuThread *thread);
|
|
||||||
bool qemu_thread_is_self(QemuThread *thread);
|
|
||||||
void qemu_thread_exit(void *retval);
|
|
||||||
void qemu_thread_naming(bool enable);
|
|
||||||
|
|
||||||
struct Notifier;
|
|
||||||
void qemu_thread_atexit_add(struct Notifier *notifier);
|
|
||||||
void qemu_thread_atexit_remove(struct Notifier *notifier);
|
|
||||||
|
|
||||||
#endif
|
|
File diff suppressed because it is too large
Load diff
|
@ -1,87 +0,0 @@
|
||||||
#ifndef QEMU_TYPEDEFS_H
|
|
||||||
#define QEMU_TYPEDEFS_H
|
|
||||||
|
|
||||||
/* A load of opaque types so that device init declarations don't have to
|
|
||||||
pull in all the real definitions. */
|
|
||||||
struct Monitor;
|
|
||||||
|
|
||||||
/* Please keep this list in alphabetical order */
|
|
||||||
typedef struct AdapterInfo AdapterInfo;
|
|
||||||
typedef struct AddressSpace AddressSpace;
|
|
||||||
typedef struct AioContext AioContext;
|
|
||||||
typedef struct AudioState AudioState;
|
|
||||||
typedef struct BlockBackend BlockBackend;
|
|
||||||
typedef struct BlockDriverState BlockDriverState;
|
|
||||||
typedef struct BusClass BusClass;
|
|
||||||
typedef struct BusState BusState;
|
|
||||||
typedef struct CharDriverState CharDriverState;
|
|
||||||
typedef struct CompatProperty CompatProperty;
|
|
||||||
typedef struct DeviceState DeviceState;
|
|
||||||
typedef struct DeviceListener DeviceListener;
|
|
||||||
typedef struct DisplayChangeListener DisplayChangeListener;
|
|
||||||
typedef struct DisplayState DisplayState;
|
|
||||||
typedef struct DisplaySurface DisplaySurface;
|
|
||||||
typedef struct DriveInfo DriveInfo;
|
|
||||||
typedef struct EventNotifier EventNotifier;
|
|
||||||
typedef struct FWCfgIoState FWCfgIoState;
|
|
||||||
typedef struct FWCfgMemState FWCfgMemState;
|
|
||||||
typedef struct FWCfgState FWCfgState;
|
|
||||||
typedef struct HCIInfo HCIInfo;
|
|
||||||
typedef struct I2CBus I2CBus;
|
|
||||||
typedef struct I2SCodec I2SCodec;
|
|
||||||
typedef struct ISABus ISABus;
|
|
||||||
typedef struct ISADevice ISADevice;
|
|
||||||
typedef struct LoadStateEntry LoadStateEntry;
|
|
||||||
typedef struct MACAddr MACAddr;
|
|
||||||
typedef struct MachineClass MachineClass;
|
|
||||||
typedef struct MachineState MachineState;
|
|
||||||
typedef struct MemoryListener MemoryListener;
|
|
||||||
typedef struct MemoryMappingList MemoryMappingList;
|
|
||||||
typedef struct MemoryRegion MemoryRegion;
|
|
||||||
typedef struct MemoryRegionSection MemoryRegionSection;
|
|
||||||
typedef struct MigrationIncomingState MigrationIncomingState;
|
|
||||||
typedef struct MigrationParams MigrationParams;
|
|
||||||
typedef struct Monitor Monitor;
|
|
||||||
typedef struct MouseTransformInfo MouseTransformInfo;
|
|
||||||
typedef struct MSIMessage MSIMessage;
|
|
||||||
typedef struct NetClientState NetClientState;
|
|
||||||
typedef struct NICInfo NICInfo;
|
|
||||||
typedef struct PcGuestInfo PcGuestInfo;
|
|
||||||
typedef struct PCIBridge PCIBridge;
|
|
||||||
typedef struct PCIBus PCIBus;
|
|
||||||
typedef struct PCIDevice PCIDevice;
|
|
||||||
typedef struct PCIEAERErr PCIEAERErr;
|
|
||||||
typedef struct PCIEAERLog PCIEAERLog;
|
|
||||||
typedef struct PCIEAERMsg PCIEAERMsg;
|
|
||||||
typedef struct PCIEPort PCIEPort;
|
|
||||||
typedef struct PCIESlot PCIESlot;
|
|
||||||
typedef struct PCIExpressDevice PCIExpressDevice;
|
|
||||||
typedef struct PCIExpressHost PCIExpressHost;
|
|
||||||
typedef struct PCIHostState PCIHostState;
|
|
||||||
typedef struct PCMachineState PCMachineState;
|
|
||||||
typedef struct PCMachineClass PCMachineClass;
|
|
||||||
typedef struct PCMCIACardState PCMCIACardState;
|
|
||||||
typedef struct PixelFormat PixelFormat;
|
|
||||||
typedef struct PropertyInfo PropertyInfo;
|
|
||||||
typedef struct Property Property;
|
|
||||||
typedef struct QEMUBH QEMUBH;
|
|
||||||
typedef struct QemuConsole QemuConsole;
|
|
||||||
typedef struct QEMUFile QEMUFile;
|
|
||||||
typedef struct QemuOpt QemuOpt;
|
|
||||||
typedef struct QemuOpts QemuOpts;
|
|
||||||
typedef struct QemuOptsList QemuOptsList;
|
|
||||||
typedef struct QEMUSGList QEMUSGList;
|
|
||||||
typedef struct QEMUSizedBuffer QEMUSizedBuffer;
|
|
||||||
typedef struct QEMUTimerListGroup QEMUTimerListGroup;
|
|
||||||
typedef struct QEMUTimer QEMUTimer;
|
|
||||||
typedef struct Range Range;
|
|
||||||
typedef struct SerialState SerialState;
|
|
||||||
typedef struct SHPCDevice SHPCDevice;
|
|
||||||
typedef struct SMBusDevice SMBusDevice;
|
|
||||||
typedef struct SSIBus SSIBus;
|
|
||||||
typedef struct uWireSlave uWireSlave;
|
|
||||||
typedef struct VirtIODevice VirtIODevice;
|
|
||||||
typedef struct Visitor Visitor;
|
|
||||||
typedef struct MonitorDef MonitorDef;
|
|
||||||
|
|
||||||
#endif /* QEMU_TYPEDEFS_H */
|
|
|
@ -11,8 +11,8 @@
|
||||||
|
|
||||||
typedef char *caddr_t;
|
typedef char *caddr_t;
|
||||||
|
|
||||||
# include <winsock2.h>
|
|
||||||
# include <windows.h>
|
# include <windows.h>
|
||||||
|
# include <winsock2.h>
|
||||||
# include <ws2tcpip.h>
|
# include <ws2tcpip.h>
|
||||||
# include <sys/timeb.h>
|
# include <sys/timeb.h>
|
||||||
# include <iphlpapi.h>
|
# include <iphlpapi.h>
|
||||||
|
|
|
@ -634,7 +634,7 @@ tcp_listen(Slirp *slirp, uint32_t haddr, u_int hport, uint32_t laddr,
|
||||||
|
|
||||||
closesocket(s);
|
closesocket(s);
|
||||||
sofree(so);
|
sofree(so);
|
||||||
fprintf (stderr, "\r\nSocket Error %d\r\n", tmperrno);
|
fprintf (stderr, "Socket Error %d", tmperrno);
|
||||||
/* Restore the real errno */
|
/* Restore the real errno */
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
WSASetLastError(tmperrno);
|
WSASetLastError(tmperrno);
|
||||||
|
|
|
@ -57,12 +57,12 @@ typedef enum {
|
||||||
#define GLIB_SYSDEF_POLLNVAL =32
|
#define GLIB_SYSDEF_POLLNVAL =32
|
||||||
|
|
||||||
typedef enum {
|
typedef enum {
|
||||||
G_IO_IN GLIB_SYSDEF_POLLIN, // There is data to read.
|
G_IO_IN GLIB_SYSDEF_POLLIN, /* There is data to read. */
|
||||||
G_IO_OUT GLIB_SYSDEF_POLLOUT, // Data can be written (without blocking).
|
G_IO_OUT GLIB_SYSDEF_POLLOUT, /* Data can be written (without blocking). */
|
||||||
G_IO_PRI GLIB_SYSDEF_POLLPRI, // There is urgent data to read.
|
G_IO_PRI GLIB_SYSDEF_POLLPRI, /* There is urgent data to read. */
|
||||||
G_IO_ERR GLIB_SYSDEF_POLLERR, // Error condition.
|
G_IO_ERR GLIB_SYSDEF_POLLERR, /* Error condition. */
|
||||||
G_IO_HUP GLIB_SYSDEF_POLLHUP, // Hung up (the connection has been broken, usually for pipes and sockets).
|
G_IO_HUP GLIB_SYSDEF_POLLHUP, /* Hung up (the connection has been broken, usually for pipes and sockets). */
|
||||||
G_IO_NVAL GLIB_SYSDEF_POLLNVAL // Invalid request. The file descriptor is not open.
|
G_IO_NVAL GLIB_SYSDEF_POLLNVAL /* Invalid request. The file descriptor is not open. */
|
||||||
} GIOCondition;
|
} GIOCondition;
|
||||||
void g_log (const gchar *log_domain, GLogLevelFlags log_level, const gchar *format, ...);
|
void g_log (const gchar *log_domain, GLogLevelFlags log_level, const gchar *format, ...);
|
||||||
#if !defined(G_LOG_DOMAIN)
|
#if !defined(G_LOG_DOMAIN)
|
|
@ -39,6 +39,8 @@
|
||||||
#include <winsock2.h>
|
#include <winsock2.h>
|
||||||
#include <windows.h>
|
#include <windows.h>
|
||||||
#endif
|
#endif
|
||||||
|
#include "qemu/compiler.h"
|
||||||
|
#include "qemu/typedefs.h"
|
||||||
#include <sockets.h>
|
#include <sockets.h>
|
||||||
#include <stdarg.h>
|
#include <stdarg.h>
|
||||||
#include "glib.h"
|
#include "glib.h"
|
||||||
|
@ -160,9 +162,6 @@ int socket_set_fast_reuse(int fd)
|
||||||
|
|
||||||
ret = setsockopt(fd, SOL_SOCKET, SO_REUSEADDR,
|
ret = setsockopt(fd, SOL_SOCKET, SO_REUSEADDR,
|
||||||
(const char *)&val, sizeof(val));
|
(const char *)&val, sizeof(val));
|
||||||
|
|
||||||
assert(ret == 0);
|
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -352,3 +351,15 @@ GArrayInternal *ar = (GArrayInternal *)array;
|
||||||
|
|
||||||
return ar->_element_size;
|
return ar->_element_size;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if defined(_WIN32)
|
||||||
|
char *socket_strerror(int errnum)
|
||||||
|
{
|
||||||
|
static char buf[512];
|
||||||
|
|
||||||
|
if (!FormatMessageA(FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS,
|
||||||
|
NULL, errnum, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), (LPSTR)buf, sizeof(buf), NULL))
|
||||||
|
sprintf(buf, "Error Code: %d", errno);
|
||||||
|
return buf;
|
||||||
|
}
|
||||||
|
#endif
|
|
@ -16,64 +16,11 @@
|
||||||
# define QEMU_GNUC_PREREQ(maj, min) 0
|
# define QEMU_GNUC_PREREQ(maj, min) 0
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if defined(__GNUC__)
|
|
||||||
#define QEMU_NORETURN __attribute__ ((__noreturn__))
|
|
||||||
#else
|
|
||||||
#define QEMU_NORETURN
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if QEMU_GNUC_PREREQ(3, 4)
|
|
||||||
#define QEMU_WARN_UNUSED_RESULT __attribute__((warn_unused_result))
|
|
||||||
#else
|
|
||||||
#define QEMU_WARN_UNUSED_RESULT
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if QEMU_GNUC_PREREQ(4, 0)
|
|
||||||
#define QEMU_SENTINEL __attribute__((sentinel))
|
|
||||||
#else
|
|
||||||
#define QEMU_SENTINEL
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if QEMU_GNUC_PREREQ(4, 3)
|
|
||||||
#define QEMU_ARTIFICIAL __attribute__((always_inline, artificial))
|
|
||||||
#else
|
|
||||||
#define QEMU_ARTIFICIAL
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifndef glue
|
|
||||||
#define xglue(x, y) x ## y
|
|
||||||
#define glue(x, y) xglue(x, y)
|
|
||||||
#define stringify(s) tostring(s)
|
|
||||||
#define tostring(s) #s
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifndef likely
|
|
||||||
#if __GNUC__ < 3
|
|
||||||
#define __builtin_expect(x, n) (x)
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#define likely(x) __builtin_expect(!!(x), 1)
|
|
||||||
#define unlikely(x) __builtin_expect(!!(x), 0)
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifndef container_of
|
#ifndef container_of
|
||||||
#define container_of(ptr, type, member) \
|
#define container_of(ptr, type, member) \
|
||||||
((type *) ((char *)(ptr) - offsetof(type, member)))
|
((type *) ((char *)(ptr) - offsetof(type, member)))
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* Convert from a base type to a parent type, with compile time checking. */
|
|
||||||
#ifdef __GNUC__
|
|
||||||
#define DO_UPCAST(type, field, dev) ( __extension__ ( { \
|
|
||||||
char __attribute__((unused)) offset_must_be_zero[ \
|
|
||||||
-offsetof(type, field)]; \
|
|
||||||
container_of(dev, type, field);}))
|
|
||||||
#else
|
|
||||||
#define DO_UPCAST(type, field, dev) container_of(dev, type, field)
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#define typeof_field(type, field) typeof(((type *)0)->field)
|
|
||||||
#define type_check(t1,t2) ((t1*)0 - (t2*)0)
|
|
||||||
|
|
||||||
#ifndef always_inline
|
#ifndef always_inline
|
||||||
#if !((__GNUC__ < 3) || defined(__APPLE__))
|
#if !((__GNUC__ < 3) || defined(__APPLE__))
|
||||||
#ifdef __OPTIMIZE__
|
#ifdef __OPTIMIZE__
|
||||||
|
@ -90,8 +37,6 @@
|
||||||
#define inline __inline
|
#define inline __inline
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#define QEMU_BUILD_BUG_ON(x) \
|
|
||||||
typedef char glue(qemu_build_bug_on__,__LINE__)[(x)?-1:1] __attribute__((unused));
|
|
||||||
|
|
||||||
#if defined __GNUC__
|
#if defined __GNUC__
|
||||||
# if !QEMU_GNUC_PREREQ(4, 4)
|
# if !QEMU_GNUC_PREREQ(4, 4)
|
0
slirp_glue/qemu/hw/hw.h
Normal file
0
slirp_glue/qemu/hw/hw.h
Normal file
43
slirp_glue/qemu/main-loop.h
Normal file
43
slirp_glue/qemu/main-loop.h
Normal file
|
@ -0,0 +1,43 @@
|
||||||
|
/*
|
||||||
|
* QEMU System Emulator
|
||||||
|
*
|
||||||
|
* Copyright (c) 2003-2008 Fabrice Bellard
|
||||||
|
*
|
||||||
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
* of this software and associated documentation files (the "Software"), to deal
|
||||||
|
* in the Software without restriction, including without limitation the rights
|
||||||
|
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
* copies of the Software, and to permit persons to whom the Software is
|
||||||
|
* furnished to do so, subject to the following conditions:
|
||||||
|
*
|
||||||
|
* The above copyright notice and this permission notice shall be included in
|
||||||
|
* all copies or substantial portions of the Software.
|
||||||
|
*
|
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||||
|
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||||
|
* THE SOFTWARE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef QEMU_MAIN_LOOP_H
|
||||||
|
#define QEMU_MAIN_LOOP_H 1
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* qemu_notify_event: Force processing of pending events.
|
||||||
|
*
|
||||||
|
* Similar to signaling a condition variable, qemu_notify_event forces
|
||||||
|
* main_loop_wait to look at pending events and exit. The caller of
|
||||||
|
* main_loop_wait will usually call it again very soon, so qemu_notify_event
|
||||||
|
* also has the side effect of recalculating the sets of file descriptors
|
||||||
|
* that the main loop waits for.
|
||||||
|
*
|
||||||
|
* Calling qemu_notify_event is rarely necessary, because main loop
|
||||||
|
* services (bottom halves and timers) call it themselves.
|
||||||
|
*/
|
||||||
|
void qemu_notify_event(void);
|
||||||
|
|
||||||
|
#endif
|
8
slirp_glue/qemu/monitor/monitor.h
Normal file
8
slirp_glue/qemu/monitor/monitor.h
Normal file
|
@ -0,0 +1,8 @@
|
||||||
|
#ifndef MONITOR_H
|
||||||
|
#define MONITOR_H
|
||||||
|
|
||||||
|
#include "qemu-common.h"
|
||||||
|
|
||||||
|
void monitor_printf(Monitor *mon, const char *fmt, ...) GCC_FMT_ATTR(2, 3);
|
||||||
|
|
||||||
|
#endif /* !MONITOR_H */
|
|
@ -136,90 +136,6 @@ typedef signed int int_fast16_t;
|
||||||
#define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0]))
|
#define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0]))
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
int qemu_daemon(int nochdir, int noclose);
|
|
||||||
void *qemu_try_memalign(size_t alignment, size_t size);
|
|
||||||
void *qemu_memalign(size_t alignment, size_t size);
|
|
||||||
void *qemu_anon_ram_alloc(size_t size, uint64_t *align);
|
|
||||||
void qemu_vfree(void *ptr);
|
|
||||||
void qemu_anon_ram_free(void *ptr, size_t size);
|
|
||||||
|
|
||||||
#define QEMU_MADV_INVALID -1
|
|
||||||
|
|
||||||
#if defined(CONFIG_MADVISE)
|
|
||||||
|
|
||||||
#define QEMU_MADV_WILLNEED MADV_WILLNEED
|
|
||||||
#define QEMU_MADV_DONTNEED MADV_DONTNEED
|
|
||||||
#ifdef MADV_DONTFORK
|
|
||||||
#define QEMU_MADV_DONTFORK MADV_DONTFORK
|
|
||||||
#else
|
|
||||||
#define QEMU_MADV_DONTFORK QEMU_MADV_INVALID
|
|
||||||
#endif
|
|
||||||
#ifdef MADV_MERGEABLE
|
|
||||||
#define QEMU_MADV_MERGEABLE MADV_MERGEABLE
|
|
||||||
#else
|
|
||||||
#define QEMU_MADV_MERGEABLE QEMU_MADV_INVALID
|
|
||||||
#endif
|
|
||||||
#ifdef MADV_UNMERGEABLE
|
|
||||||
#define QEMU_MADV_UNMERGEABLE MADV_UNMERGEABLE
|
|
||||||
#else
|
|
||||||
#define QEMU_MADV_UNMERGEABLE QEMU_MADV_INVALID
|
|
||||||
#endif
|
|
||||||
#ifdef MADV_DODUMP
|
|
||||||
#define QEMU_MADV_DODUMP MADV_DODUMP
|
|
||||||
#else
|
|
||||||
#define QEMU_MADV_DODUMP QEMU_MADV_INVALID
|
|
||||||
#endif
|
|
||||||
#ifdef MADV_DONTDUMP
|
|
||||||
#define QEMU_MADV_DONTDUMP MADV_DONTDUMP
|
|
||||||
#else
|
|
||||||
#define QEMU_MADV_DONTDUMP QEMU_MADV_INVALID
|
|
||||||
#endif
|
|
||||||
#ifdef MADV_HUGEPAGE
|
|
||||||
#define QEMU_MADV_HUGEPAGE MADV_HUGEPAGE
|
|
||||||
#else
|
|
||||||
#define QEMU_MADV_HUGEPAGE QEMU_MADV_INVALID
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#elif defined(CONFIG_POSIX_MADVISE)
|
|
||||||
|
|
||||||
#define QEMU_MADV_WILLNEED POSIX_MADV_WILLNEED
|
|
||||||
#define QEMU_MADV_DONTNEED POSIX_MADV_DONTNEED
|
|
||||||
#define QEMU_MADV_DONTFORK QEMU_MADV_INVALID
|
|
||||||
#define QEMU_MADV_MERGEABLE QEMU_MADV_INVALID
|
|
||||||
#define QEMU_MADV_UNMERGEABLE QEMU_MADV_INVALID
|
|
||||||
#define QEMU_MADV_DODUMP QEMU_MADV_INVALID
|
|
||||||
#define QEMU_MADV_DONTDUMP QEMU_MADV_INVALID
|
|
||||||
#define QEMU_MADV_HUGEPAGE QEMU_MADV_INVALID
|
|
||||||
|
|
||||||
#else /* no-op */
|
|
||||||
|
|
||||||
#define QEMU_MADV_WILLNEED QEMU_MADV_INVALID
|
|
||||||
#define QEMU_MADV_DONTNEED QEMU_MADV_INVALID
|
|
||||||
#define QEMU_MADV_DONTFORK QEMU_MADV_INVALID
|
|
||||||
#define QEMU_MADV_MERGEABLE QEMU_MADV_INVALID
|
|
||||||
#define QEMU_MADV_UNMERGEABLE QEMU_MADV_INVALID
|
|
||||||
#define QEMU_MADV_DODUMP QEMU_MADV_INVALID
|
|
||||||
#define QEMU_MADV_DONTDUMP QEMU_MADV_INVALID
|
|
||||||
#define QEMU_MADV_HUGEPAGE QEMU_MADV_INVALID
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
int qemu_madvise(void *addr, size_t len, int advice);
|
|
||||||
|
|
||||||
int qemu_open(const char *name, int flags, ...);
|
|
||||||
int qemu_close(int fd);
|
|
||||||
|
|
||||||
#if defined(__HAIKU__) && defined(__i386__)
|
|
||||||
#define FMT_pid "%ld"
|
|
||||||
#elif defined(WIN64)
|
|
||||||
#define FMT_pid "%" PRId64
|
|
||||||
#else
|
|
||||||
#define FMT_pid "%d"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
int qemu_create_pidfile(const char *filename);
|
|
||||||
int qemu_get_thread_id(void);
|
|
||||||
|
|
||||||
#ifndef CONFIG_IOVEC
|
#ifndef CONFIG_IOVEC
|
||||||
struct iovec {
|
struct iovec {
|
||||||
void *iov_base;
|
void *iov_base;
|
||||||
|
@ -253,47 +169,4 @@ static inline void qemu_timersub(const struct timeval *val1,
|
||||||
#define qemu_timersub timersub
|
#define qemu_timersub timersub
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
void qemu_set_cloexec(int fd);
|
|
||||||
|
|
||||||
void qemu_set_version(const char *);
|
|
||||||
const char *qemu_get_version(void);
|
|
||||||
|
|
||||||
void fips_set_state(bool requested);
|
|
||||||
bool fips_get_state(void);
|
|
||||||
|
|
||||||
/* Return a dynamically allocated pathname denoting a file or directory that is
|
|
||||||
* appropriate for storing local state.
|
|
||||||
*
|
|
||||||
* @relative_pathname need not start with a directory separator; one will be
|
|
||||||
* added automatically.
|
|
||||||
*
|
|
||||||
* The caller is responsible for releasing the value returned with g_free()
|
|
||||||
* after use.
|
|
||||||
*/
|
|
||||||
char *qemu_get_local_state_pathname(const char *relative_pathname);
|
|
||||||
|
|
||||||
/* Find program directory, and save it for later usage with
|
|
||||||
* qemu_get_exec_dir().
|
|
||||||
* Try OS specific API first, if not working, parse from argv0. */
|
|
||||||
void qemu_init_exec_dir(const char *argv0);
|
|
||||||
|
|
||||||
/* Get the saved exec dir.
|
|
||||||
* Caller needs to release the returned string by g_free() */
|
|
||||||
char *qemu_get_exec_dir(void);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* qemu_getauxval:
|
|
||||||
* @type: the auxiliary vector key to lookup
|
|
||||||
*
|
|
||||||
* Search the auxiliary vector for @type, returning the value
|
|
||||||
* or 0 if @type is not present.
|
|
||||||
*/
|
|
||||||
unsigned long qemu_getauxval(unsigned long type);
|
|
||||||
|
|
||||||
void qemu_set_tty_echo(int fd, bool echo);
|
|
||||||
|
|
||||||
void os_mem_prealloc(int fd, char *area, size_t sz);
|
|
||||||
|
|
||||||
int qemu_read_password(char *buf, int buf_size);
|
|
||||||
|
|
||||||
#endif
|
#endif
|
50
slirp_glue/qemu/qemu-common.h
Normal file
50
slirp_glue/qemu/qemu-common.h
Normal file
|
@ -0,0 +1,50 @@
|
||||||
|
|
||||||
|
/* Common header file that is included by all of QEMU.
|
||||||
|
*
|
||||||
|
* This file is supposed to be included only by .c files. No header file should
|
||||||
|
* depend on qemu-common.h, as this would easily lead to circular header
|
||||||
|
* dependencies.
|
||||||
|
*
|
||||||
|
* If a header file uses a definition from qemu-common.h, that definition
|
||||||
|
* must be moved to a separate header file, and the header that uses it
|
||||||
|
* must include that header.
|
||||||
|
*/
|
||||||
|
#ifndef QEMU_COMMON_H
|
||||||
|
#define QEMU_COMMON_H
|
||||||
|
|
||||||
|
#include "qemu/osdep.h"
|
||||||
|
#include "qemu/typedefs.h"
|
||||||
|
|
||||||
|
#include "glib.h"
|
||||||
|
#include "config-host.h"
|
||||||
|
|
||||||
|
/* HOST_LONG_BITS is the size of a native pointer in bits. */
|
||||||
|
#if UINTPTR_MAX == UINT32_MAX
|
||||||
|
# define HOST_LONG_BITS 32
|
||||||
|
#elif UINTPTR_MAX == UINT64_MAX
|
||||||
|
# define HOST_LONG_BITS 64
|
||||||
|
#else
|
||||||
|
# error Unknown pointer size
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* util/cutils.c */
|
||||||
|
/**
|
||||||
|
* pstrcpy:
|
||||||
|
* @buf: buffer to copy string into
|
||||||
|
* @buf_size: size of @buf in bytes
|
||||||
|
* @str: string to copy
|
||||||
|
*
|
||||||
|
* Copy @str into @buf, including the trailing NUL, but do not
|
||||||
|
* write more than @buf_size bytes. The resulting buffer is
|
||||||
|
* always NUL terminated (even if the source string was too long).
|
||||||
|
* If @buf_size is zero or negative then no bytes are copied.
|
||||||
|
*
|
||||||
|
* This function is similar to strncpy(), but avoids two of that
|
||||||
|
* function's problems:
|
||||||
|
* * if @str fits in the buffer, pstrcpy() does not zero-fill the
|
||||||
|
* remaining space at the end of @buf
|
||||||
|
* * if @str is too long, pstrcpy() will copy the first @buf_size-1
|
||||||
|
* bytes and then add a NUL
|
||||||
|
*/
|
||||||
|
void pstrcpy(char *buf, int buf_size, const char *str);
|
||||||
|
#endif
|
|
@ -78,8 +78,6 @@
|
||||||
* For details on the use of these macros, see the queue(3) manual page.
|
* For details on the use of these macros, see the queue(3) manual page.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "qemu/atomic.h" /* for smp_wmb() */
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* List definitions.
|
* List definitions.
|
||||||
*/
|
*/
|
||||||
|
@ -203,18 +201,6 @@ struct { \
|
||||||
(head)->slh_first = (elm); \
|
(head)->slh_first = (elm); \
|
||||||
} while (/*CONSTCOND*/0)
|
} while (/*CONSTCOND*/0)
|
||||||
|
|
||||||
#define QSLIST_INSERT_HEAD_ATOMIC(head, elm, field) do { \
|
|
||||||
typeof(elm) save_sle_next; \
|
|
||||||
do { \
|
|
||||||
save_sle_next = (elm)->field.sle_next = (head)->slh_first; \
|
|
||||||
} while (atomic_cmpxchg(&(head)->slh_first, save_sle_next, (elm)) != \
|
|
||||||
save_sle_next); \
|
|
||||||
} while (/*CONSTCOND*/0)
|
|
||||||
|
|
||||||
#define QSLIST_MOVE_ATOMIC(dest, src) do { \
|
|
||||||
(dest)->slh_first = atomic_xchg(&(src)->slh_first, NULL); \
|
|
||||||
} while (/*CONSTCOND*/0)
|
|
||||||
|
|
||||||
#define QSLIST_REMOVE_HEAD(head, field) do { \
|
#define QSLIST_REMOVE_HEAD(head, field) do { \
|
||||||
(head)->slh_first = (head)->slh_first->field.sle_next; \
|
(head)->slh_first = (head)->slh_first->field.sle_next; \
|
||||||
} while (/*CONSTCOND*/0)
|
} while (/*CONSTCOND*/0)
|
52
slirp_glue/qemu/sockets.h
Normal file
52
slirp_glue/qemu/sockets.h
Normal file
|
@ -0,0 +1,52 @@
|
||||||
|
/* headers to use the BSD sockets */
|
||||||
|
#ifndef QEMU_SOCKET_H
|
||||||
|
#define QEMU_SOCKET_H
|
||||||
|
|
||||||
|
#ifdef _WIN32
|
||||||
|
#include <windows.h>
|
||||||
|
#include <winsock2.h>
|
||||||
|
#include <ws2tcpip.h>
|
||||||
|
|
||||||
|
#define socket_error() WSAGetLastError()
|
||||||
|
|
||||||
|
extern char *socket_strerror(int errcode);
|
||||||
|
#define strerror socket_strerror
|
||||||
|
|
||||||
|
int inet_aton(const char *cp, struct in_addr *ia);
|
||||||
|
|
||||||
|
#else
|
||||||
|
|
||||||
|
#include <sys/types.h>
|
||||||
|
#include <sys/socket.h>
|
||||||
|
#include <netinet/in.h>
|
||||||
|
#include <netinet/tcp.h>
|
||||||
|
#include <arpa/inet.h>
|
||||||
|
#include <netdb.h>
|
||||||
|
#include <sys/un.h>
|
||||||
|
|
||||||
|
#define socket_error() errno
|
||||||
|
|
||||||
|
#endif /* !_WIN32 */
|
||||||
|
|
||||||
|
/* misc helpers */
|
||||||
|
int qemu_socket(int domain, int type, int protocol);
|
||||||
|
int qemu_accept(int s, struct sockaddr *addr, socklen_t *addrlen);
|
||||||
|
int socket_set_cork(int fd, int v);
|
||||||
|
int socket_set_nodelay(int fd);
|
||||||
|
void qemu_set_block(int fd);
|
||||||
|
void qemu_set_nonblock(int fd);
|
||||||
|
int socket_set_fast_reuse(int fd);
|
||||||
|
|
||||||
|
#ifdef _WIN32
|
||||||
|
/* MinGW needs type casts for the 'buf' and 'optval' arguments. */
|
||||||
|
#define qemu_sendto(sockfd, buf, len, flags, destaddr, addrlen) \
|
||||||
|
sendto(sockfd, (const void *)buf, len, flags, destaddr, addrlen)
|
||||||
|
|
||||||
|
/* Windows has different names for the same constants with the same values */
|
||||||
|
#define SHUT_RD 0
|
||||||
|
#define SHUT_WR 1
|
||||||
|
#define SHUT_RDWR 2
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
#endif /* QEMU_SOCKET_H */
|
21
slirp_glue/qemu/sysemu/char.h
Normal file
21
slirp_glue/qemu/sysemu/char.h
Normal file
|
@ -0,0 +1,21 @@
|
||||||
|
#ifndef QEMU_CHAR_H
|
||||||
|
#define QEMU_CHAR_H
|
||||||
|
|
||||||
|
#include "qemu-common.h"
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @qemu_chr_fe_write:
|
||||||
|
*
|
||||||
|
* Write data to a character backend from the front end. This function
|
||||||
|
* will send data from the front end to the back end. This function
|
||||||
|
* is thread-safe.
|
||||||
|
*
|
||||||
|
* @buf the data
|
||||||
|
* @len the number of bytes to send
|
||||||
|
*
|
||||||
|
* Returns: the number of bytes consumed
|
||||||
|
*/
|
||||||
|
int qemu_chr_fe_write(CharDriverState *s, const uint8_t *buf, int len);
|
||||||
|
|
||||||
|
|
||||||
|
#endif
|
89
slirp_glue/qemu/timer.h
Normal file
89
slirp_glue/qemu/timer.h
Normal file
|
@ -0,0 +1,89 @@
|
||||||
|
#ifndef QEMU_TIMER_H
|
||||||
|
#define QEMU_TIMER_H
|
||||||
|
|
||||||
|
#include "qemu/typedefs.h"
|
||||||
|
#include "qemu-common.h"
|
||||||
|
|
||||||
|
#define NANOSECONDS_PER_SECOND 1000000000LL
|
||||||
|
|
||||||
|
/* timers */
|
||||||
|
|
||||||
|
#define SCALE_MS 1000000
|
||||||
|
#define SCALE_US 1000
|
||||||
|
#define SCALE_NS 1
|
||||||
|
|
||||||
|
/**
|
||||||
|
* QEMUClockType:
|
||||||
|
*
|
||||||
|
* The following clock types are available:
|
||||||
|
*
|
||||||
|
* @QEMU_CLOCK_REALTIME: Real time clock
|
||||||
|
*
|
||||||
|
* The real time clock should be used only for stuff which does not
|
||||||
|
* change the virtual machine state, as it is run even if the virtual
|
||||||
|
* machine is stopped. The real time clock has a frequency of 1000
|
||||||
|
* Hz.
|
||||||
|
*
|
||||||
|
* @QEMU_CLOCK_VIRTUAL: virtual clock
|
||||||
|
*
|
||||||
|
* The virtual clock is only run during the emulation. It is stopped
|
||||||
|
* when the virtual machine is stopped. Virtual timers use a high
|
||||||
|
* precision clock, usually cpu cycles (use ticks_per_sec).
|
||||||
|
*
|
||||||
|
* @QEMU_CLOCK_HOST: host clock
|
||||||
|
*
|
||||||
|
* The host clock should be use for device models that emulate accurate
|
||||||
|
* real time sources. It will continue to run when the virtual machine
|
||||||
|
* is suspended, and it will reflect system time changes the host may
|
||||||
|
* undergo (e.g. due to NTP). The host clock has the same precision as
|
||||||
|
* the virtual clock.
|
||||||
|
*
|
||||||
|
* @QEMU_CLOCK_VIRTUAL_RT: realtime clock used for icount warp
|
||||||
|
*
|
||||||
|
* Outside icount mode, this clock is the same as @QEMU_CLOCK_VIRTUAL.
|
||||||
|
* In icount mode, this clock counts nanoseconds while the virtual
|
||||||
|
* machine is running. It is used to increase @QEMU_CLOCK_VIRTUAL
|
||||||
|
* while the CPUs are sleeping and thus not executing instructions.
|
||||||
|
*/
|
||||||
|
|
||||||
|
typedef enum {
|
||||||
|
QEMU_CLOCK_REALTIME = 0,
|
||||||
|
QEMU_CLOCK_VIRTUAL = 1,
|
||||||
|
QEMU_CLOCK_HOST = 2,
|
||||||
|
QEMU_CLOCK_VIRTUAL_RT = 3,
|
||||||
|
QEMU_CLOCK_MAX
|
||||||
|
} QEMUClockType;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* QEMUClockType
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* qemu_clock_get_ns;
|
||||||
|
* @type: the clock type
|
||||||
|
*
|
||||||
|
* Get the nanosecond value of a clock with
|
||||||
|
* type @type
|
||||||
|
*
|
||||||
|
* Returns: the clock value in nanoseconds
|
||||||
|
*/
|
||||||
|
int64_t qemu_clock_get_ns(QEMUClockType type);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* qemu_clock_get_ms;
|
||||||
|
* @type: the clock type
|
||||||
|
*
|
||||||
|
* Get the millisecond value of a clock with
|
||||||
|
* type @type
|
||||||
|
*
|
||||||
|
* Returns: the clock value in milliseconds
|
||||||
|
*/
|
||||||
|
static inline int64_t qemu_clock_get_ms(QEMUClockType type)
|
||||||
|
{
|
||||||
|
return qemu_clock_get_ns(type) / SCALE_MS;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
11
slirp_glue/qemu/typedefs.h
Normal file
11
slirp_glue/qemu/typedefs.h
Normal file
|
@ -0,0 +1,11 @@
|
||||||
|
#ifndef QEMU_TYPEDEFS_H
|
||||||
|
#define QEMU_TYPEDEFS_H
|
||||||
|
|
||||||
|
/* A load of opaque types so that device init declarations don't have to
|
||||||
|
pull in all the real definitions. */
|
||||||
|
struct Monitor;
|
||||||
|
typedef struct Monitor Monitor;
|
||||||
|
typedef struct CharDriverState CharDriverState;
|
||||||
|
typedef struct QEMUFile QEMUFile;
|
||||||
|
|
||||||
|
#endif /* QEMU_TYPEDEFS_H */
|
|
@ -137,7 +137,6 @@ struct sim_slirp {
|
||||||
struct redir_tcp_udp *rtcp;
|
struct redir_tcp_udp *rtcp;
|
||||||
GArray *gpollfds;
|
GArray *gpollfds;
|
||||||
SOCKET db_chime; /* write packet doorbell */
|
SOCKET db_chime; /* write packet doorbell */
|
||||||
struct sockaddr_in db_addr; /* doorbell address */
|
|
||||||
struct write_request {
|
struct write_request {
|
||||||
struct write_request *next;
|
struct write_request *next;
|
||||||
char msg[1518];
|
char msg[1518];
|
||||||
|
@ -171,6 +170,7 @@ slirp->opaque = opaque;
|
||||||
slirp->callback = callback;
|
slirp->callback = callback;
|
||||||
slirp->maskbits = 24;
|
slirp->maskbits = 24;
|
||||||
slirp->dhcpmgmt = 1;
|
slirp->dhcpmgmt = 1;
|
||||||
|
slirp->db_chime = INVALID_SOCKET;
|
||||||
inet_aton(DEFAULT_IP_ADDR,&slirp->vgateway);
|
inet_aton(DEFAULT_IP_ADDR,&slirp->vgateway);
|
||||||
|
|
||||||
err = 0;
|
err = 0;
|
||||||
|
@ -320,21 +320,17 @@ if (_do_redirects (slirp->slirp, slirp->rtcp)) {
|
||||||
else {
|
else {
|
||||||
char db_host[32];
|
char db_host[32];
|
||||||
GPollFD pfd;
|
GPollFD pfd;
|
||||||
int ret;
|
|
||||||
int64_t rnd_val = qemu_clock_get_ns (0) / 1000000;
|
int64_t rnd_val = qemu_clock_get_ns (0) / 1000000;
|
||||||
|
|
||||||
pthread_mutex_init (&slirp->write_buffer_lock, NULL);
|
pthread_mutex_init (&slirp->write_buffer_lock, NULL);
|
||||||
slirp->gpollfds = g_array_new(FALSE, FALSE, sizeof(GPollFD));
|
slirp->gpollfds = g_array_new(FALSE, FALSE, sizeof(GPollFD));
|
||||||
/* setup transmit packet wakeup doorbell */
|
/* setup transmit packet wakeup doorbell */
|
||||||
slirp->db_chime = socket (AF_INET, SOCK_DGRAM, IPPROTO_UDP);
|
do {
|
||||||
ret = socket_set_fast_reuse(slirp->db_chime);
|
if ((rnd_val & 0xFFFF) == 0)
|
||||||
memset (&slirp->db_addr, 0, sizeof (slirp->db_addr));
|
++rnd_val;
|
||||||
slirp->db_addr.sin_family = AF_INET;
|
sprintf (db_host, "localhost:%d", (int)(rnd_val & 0xFFFF));
|
||||||
sprintf (db_host, "127.%d.%d.%d", (int)((rnd_val>>16) & 0xFF), (int)((rnd_val>>8) & 0xFF), (int)(rnd_val & 0xFF));
|
slirp->db_chime = sim_connect_sock_ex (db_host, db_host, NULL, NULL, SIM_SOCK_OPT_DATAGRAM);
|
||||||
slirp->db_addr.sin_port = (rnd_val >> 24) & 0xFFFF;
|
} while (slirp->db_chime == INVALID_SOCKET);
|
||||||
inet_aton (db_host, &slirp->db_addr.sin_addr);
|
|
||||||
ret = bind(slirp->db_chime, (struct sockaddr *)&slirp->db_addr, sizeof(slirp->db_addr));
|
|
||||||
qemu_set_nonblock(slirp->db_chime);
|
|
||||||
memset (&pfd, 0, sizeof (pfd));
|
memset (&pfd, 0, sizeof (pfd));
|
||||||
pfd.fd = slirp->db_chime;
|
pfd.fd = slirp->db_chime;
|
||||||
pfd.events = G_IO_IN;
|
pfd.events = G_IO_IN;
|
||||||
|
@ -368,6 +364,7 @@ if (slirp) {
|
||||||
g_free (rtmp);
|
g_free (rtmp);
|
||||||
}
|
}
|
||||||
g_array_free(slirp->gpollfds, true);
|
g_array_free(slirp->gpollfds, true);
|
||||||
|
if (slirp->db_chime != INVALID_SOCKET)
|
||||||
closesocket (slirp->db_chime);
|
closesocket (slirp->db_chime);
|
||||||
if (1) {
|
if (1) {
|
||||||
struct write_request *buffer;
|
struct write_request *buffer;
|
||||||
|
@ -448,7 +445,7 @@ else {
|
||||||
pthread_mutex_unlock (&slirp->write_buffer_lock);
|
pthread_mutex_unlock (&slirp->write_buffer_lock);
|
||||||
|
|
||||||
if (wake_needed)
|
if (wake_needed)
|
||||||
sendto (slirp->db_chime, msg, 0, 0, (struct sockaddr *)&slirp->db_addr, sizeof(slirp->db_addr));
|
sim_write_sock (slirp->db_chime, msg, 0);
|
||||||
return len;
|
return len;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Reference in a new issue