mirror of https://github.com/xemu-project/xemu.git
Enable building and installing rST docs with Sphinx
-----BEGIN PGP SIGNATURE----- iQJNBAABCAA3FiEE4aXFk81BneKOgxXPPCUl7RQ2DN4FAlyBMygZHHBldGVyLm1h eWRlbGxAbGluYXJvLm9yZwAKCRA8JSXtFDYM3hjeD/4nSnAT/dXIAQAbfJMDyKdd pywFyUb6ltmEwApw6NheM0C0Wxcr19QEFfLTSNDTjp6S3HSOF1eY5vPOt8sVThnB AQoPLt0pky2LVrLcb3Dereeh52fMxNnfwnFwvkz5ycxhFlIrTDaH9Gzu/2t/tX8r uTG5gSHUz0geA6LH1whn1R1dfcVhYNByC3Yn8+RwIckIPj10v6JC0YIeoMqaPAw/ ETr5Cbat0i47GQzcGvHE0nnyaCoXxWeOy+DUMZDncWmQcF3q4dSagniLgS3aIbKj AqhhO9QxaDkzo6yQ1Cl39hJWj2njANBrGQnUm8IPiUnGclIjhtq2x7OskxW2YYII SsZOyrBg7t3hmdaQMpb5/PG2wzApirRUo8pxlVUGVFGc2SR+3wS7a4blNHozjR53 w9doFoo3UeSqlFhN1Y359S+0qqZOMyOVotEbx48ElDBtKjV5IaouzickzbAfRpQh VrXSDhqtLwLDDeVrEpbl5uq/5P8KgVGlIc+Ll2XnH3OXsbfjH/juC1SdpsBtSASJ Ia2wi9wiuS+0kLQJwqfj/RtAmycEPGQWo1gxdZNyFA1FkhPTs7Mo+YMmwa96UGlC wzhh9vcdEfmZE3IEYU0+hf1VC9PXR69vqU66zIO4LllOXWmyea3q2DHRyxOaj0Ls 5XSKwN4lNX9hoVhEbJGfdg== =iyAU -----END PGP SIGNATURE----- Merge remote-tracking branch 'remotes/pmaydell/tags/pull-sphinx-20190307' into staging Enable building and installing rST docs with Sphinx # gpg: Signature made Thu 07 Mar 2019 15:05:12 GMT # gpg: using RSA key E1A5C593CD419DE28E8315CF3C2525ED14360CDE # gpg: issuer "peter.maydell@linaro.org" # gpg: Good signature from "Peter Maydell <peter.maydell@linaro.org>" [ultimate] # gpg: aka "Peter Maydell <pmaydell@gmail.com>" [ultimate] # gpg: aka "Peter Maydell <pmaydell@chiark.greenend.org.uk>" [ultimate] # Primary key fingerprint: E1A5 C593 CD41 9DE2 8E83 15CF 3C25 25ED 1436 0CDE * remotes/pmaydell/tags/pull-sphinx-20190307: MAINTAINERS: Add entry for Sphinx documentation infrastructure docs/conf.py: Don't hard-code QEMU version Makefile: Abstract out "identify the pkgversion" code Makefile, configure: Support building rST documentation docs: Provide separate conf.py for each manual we want docs/conf.py: Disable option warnings docs/conf.py: Don't include rST sources in HTML build docs/conf.py: Configure the 'alabaster' theme docs/conf.py: Disable unused _static directory docs: Commit initial files from sphinx-quickstart docs: Convert memory.txt to rst format docs/cpu-hotplug.rst: Fix rST markup issues Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
This commit is contained in:
commit
21afe115a4
|
@ -1,3 +1,4 @@
|
|||
/.doctrees
|
||||
/config-devices.*
|
||||
/config-all-devices.*
|
||||
/config-all-disas.*
|
||||
|
|
|
@ -2567,3 +2567,9 @@ GIT submodules
|
|||
M: Daniel P. Berrange <berrange@redhat.com>
|
||||
S: Odd Fixes
|
||||
F: scripts/git-submodule.sh
|
||||
|
||||
Sphinx documentation configuration and build machinery
|
||||
M: Peter Maydell <peter.maydell@linaro.org>
|
||||
S: Maintained
|
||||
F: docs/conf.py
|
||||
F: docs/*/conf.py
|
||||
|
|
78
Makefile
78
Makefile
|
@ -87,6 +87,20 @@ endif
|
|||
|
||||
include $(SRC_PATH)/rules.mak
|
||||
|
||||
# Create QEMU_PKGVERSION and FULL_VERSION strings
|
||||
# If PKGVERSION is set, use that; otherwise get version and -dirty status from git
|
||||
QEMU_PKGVERSION := $(if $(PKGVERSION),$(PKGVERSION),$(shell \
|
||||
cd $(SRC_PATH); \
|
||||
if test -e .git; then \
|
||||
git describe --match 'v*' 2>/dev/null | tr -d '\n'; \
|
||||
if ! git diff-index --quiet HEAD &>/dev/null; then \
|
||||
echo "-dirty"; \
|
||||
fi; \
|
||||
fi))
|
||||
|
||||
# Either "version (pkgversion)", or just "version" if pkgversion not set
|
||||
FULL_VERSION := $(if $(QEMU_PKGVERSION),$(VERSION) ($(QEMU_PKGVERSION)),$(VERSION))
|
||||
|
||||
GENERATED_FILES = qemu-version.h config-host.h qemu-options.def
|
||||
|
||||
GENERATED_QAPI_FILES = qapi/qapi-builtin-types.h qapi/qapi-builtin-types.c
|
||||
|
@ -388,27 +402,12 @@ dummy := $(call unnest-vars,, \
|
|||
|
||||
include $(SRC_PATH)/tests/Makefile.include
|
||||
|
||||
all: $(DOCS) $(TOOLS) $(HELPERS-y) recurse-all modules
|
||||
all: $(DOCS) $(if $(BUILD_DOCS),sphinxdocs) $(TOOLS) $(HELPERS-y) recurse-all modules
|
||||
|
||||
qemu-version.h: FORCE
|
||||
$(call quiet-command, \
|
||||
(cd $(SRC_PATH); \
|
||||
if test -n "$(PKGVERSION)"; then \
|
||||
pkgvers="$(PKGVERSION)"; \
|
||||
else \
|
||||
if test -d .git; then \
|
||||
pkgvers=$$(git describe --match 'v*' 2>/dev/null | tr -d '\n');\
|
||||
if ! git diff-index --quiet HEAD &>/dev/null; then \
|
||||
pkgvers="$${pkgvers}-dirty"; \
|
||||
fi; \
|
||||
fi; \
|
||||
fi; \
|
||||
printf "#define QEMU_PKGVERSION \"$${pkgvers}\"\n"; \
|
||||
if test -n "$${pkgvers}"; then \
|
||||
printf '#define QEMU_FULL_VERSION QEMU_VERSION " (" QEMU_PKGVERSION ")"\n'; \
|
||||
else \
|
||||
printf '#define QEMU_FULL_VERSION QEMU_VERSION\n'; \
|
||||
fi; \
|
||||
(printf '#define QEMU_PKGVERSION "$(QEMU_PKGVERSION)"\n'; \
|
||||
printf '#define QEMU_FULL_VERSION "$(FULL_VERSION)"\n'; \
|
||||
) > $@.tmp)
|
||||
$(call quiet-command, if ! cmp -s $@ $@.tmp; then \
|
||||
mv $@.tmp $@; \
|
||||
|
@ -637,6 +636,14 @@ dist: qemu-$(VERSION).tar.bz2
|
|||
qemu-%.tar.bz2:
|
||||
$(SRC_PATH)/scripts/make-release "$(SRC_PATH)" "$(patsubst qemu-%.tar.bz2,%,$@)"
|
||||
|
||||
# Note that these commands assume that there are no HTML files in
|
||||
# the docs subdir in the source tree! If there are then this will
|
||||
# blow them away for an in-source-tree 'make clean'.
|
||||
define clean-manual =
|
||||
rm -rf docs/$1/_static
|
||||
rm -f docs/$1/objects.inv docs/$1/searchindex.js docs/$1/*.html
|
||||
endef
|
||||
|
||||
distclean: clean
|
||||
rm -f config-host.mak config-host.h* config-host.ld $(DOCS) qemu-options.texi qemu-img-cmds.texi qemu-monitor.texi qemu-monitor-info.texi
|
||||
rm -f config-all-devices.mak config-all-disas.mak config.status
|
||||
|
@ -657,6 +664,9 @@ distclean: clean
|
|||
rm -f docs/interop/qemu-qmp-ref.html docs/interop/qemu-ga-ref.html
|
||||
rm -f docs/qemu-block-drivers.7
|
||||
rm -f docs/qemu-cpu-models.7
|
||||
rm -f .doctrees
|
||||
$(call clean-manual,devel)
|
||||
$(call clean-manual,interop)
|
||||
for d in $(TARGET_DIRS); do \
|
||||
rm -rf $$d || exit 1 ; \
|
||||
done
|
||||
|
@ -690,7 +700,18 @@ else
|
|||
BLOBS=
|
||||
endif
|
||||
|
||||
install-doc: $(DOCS)
|
||||
define install-manual =
|
||||
for d in $$(cd docs && find $1 -type d); do $(INSTALL_DIR) "$(DESTDIR)$(qemu_docdir)/$$d"; done
|
||||
for f in $$(cd docs && find $1 -type f); do $(INSTALL_DATA) "docs/$$f" "$(DESTDIR)$(qemu_docdir)/$$f"; done
|
||||
endef
|
||||
|
||||
# Note that we deliberately do not install the "devel" manual: it is
|
||||
# for QEMU developers, and not interesting to our users.
|
||||
.PHONY: install-sphinxdocs
|
||||
install-sphinxdocs: sphinxdocs
|
||||
$(call install-manual,interop)
|
||||
|
||||
install-doc: $(DOCS) install-sphinxdocs
|
||||
$(INSTALL_DIR) "$(DESTDIR)$(qemu_docdir)"
|
||||
$(INSTALL_DATA) qemu-doc.html "$(DESTDIR)$(qemu_docdir)"
|
||||
$(INSTALL_DATA) qemu-doc.txt "$(DESTDIR)$(qemu_docdir)"
|
||||
|
@ -841,6 +862,23 @@ docs/version.texi: $(SRC_PATH)/VERSION
|
|||
%.pdf: %.texi docs/version.texi
|
||||
$(call quiet-command,texi2pdf $(TEXI2PDFFLAGS) $< -o $@,"GEN","$@")
|
||||
|
||||
# Sphinx builds all its documentation at once in one invocation
|
||||
# and handles "don't rebuild things unless necessary" itself.
|
||||
# The '.doctrees' files are cached information to speed this up.
|
||||
.PHONY: sphinxdocs
|
||||
sphinxdocs: docs/devel/index.html docs/interop/index.html
|
||||
|
||||
# Canned command to build a single manual
|
||||
build-manual = $(call quiet-command,sphinx-build $(if $(V),,-q) -b html -D version=$(VERSION) -D release="$(FULL_VERSION)" -d .doctrees/$1 $(SRC_PATH)/docs/$1 docs/$1 ,"SPHINX","docs/$1")
|
||||
# We assume all RST files in the manual's directory are used in it
|
||||
manual-deps = $(wildcard $(SRC_PATH)/docs/$1/*.rst) $(SRC_PATH)/docs/$1/conf.py $(SRC_PATH)/docs/conf.py
|
||||
|
||||
docs/devel/index.html: $(call manual-deps,devel)
|
||||
$(call build-manual,devel)
|
||||
|
||||
docs/interop/index.html: $(call manual-deps,interop)
|
||||
$(call build-manual,interop)
|
||||
|
||||
qemu-options.texi: $(SRC_PATH)/qemu-options.hx $(SRC_PATH)/scripts/hxtool
|
||||
$(call quiet-command,sh $(SRC_PATH)/scripts/hxtool -t < $< > $@,"GEN","$@")
|
||||
|
||||
|
@ -869,7 +907,7 @@ docs/qemu-block-drivers.7: docs/qemu-block-drivers.texi
|
|||
docs/qemu-cpu-models.7: docs/qemu-cpu-models.texi
|
||||
scripts/qemu-trace-stap.1: scripts/qemu-trace-stap.texi
|
||||
|
||||
html: qemu-doc.html docs/interop/qemu-qmp-ref.html docs/interop/qemu-ga-ref.html
|
||||
html: qemu-doc.html docs/interop/qemu-qmp-ref.html docs/interop/qemu-ga-ref.html sphinxdocs
|
||||
info: qemu-doc.info docs/interop/qemu-qmp-ref.info docs/interop/qemu-ga-ref.info
|
||||
pdf: qemu-doc.pdf docs/interop/qemu-qmp-ref.pdf docs/interop/qemu-ga-ref.pdf
|
||||
txt: qemu-doc.txt docs/interop/qemu-qmp-ref.txt docs/interop/qemu-ga-ref.txt
|
||||
|
|
|
@ -4589,13 +4589,24 @@ if compile_prog "" "" ; then
|
|||
syncfs=yes
|
||||
fi
|
||||
|
||||
# Check we have a new enough version of sphinx-build
|
||||
has_sphinx_build() {
|
||||
# This is a bit awkward but works: create a trivial document and
|
||||
# try to run it with our configuration file (which enforces a
|
||||
# version requirement). This will fail if either
|
||||
# sphinx-build doesn't exist at all or if it is too old.
|
||||
mkdir -p "$TMPDIR1/sphinx"
|
||||
touch "$TMPDIR1/sphinx/index.rst"
|
||||
sphinx-build -c "$source_path/docs" -b html "$TMPDIR1/sphinx" "$TMPDIR1/sphinx/out" >/dev/null 2>&1
|
||||
}
|
||||
|
||||
# Check if tools are available to build documentation.
|
||||
if test "$docs" != "no" ; then
|
||||
if has makeinfo && has pod2man; then
|
||||
if has makeinfo && has pod2man && has_sphinx_build; then
|
||||
docs=yes
|
||||
else
|
||||
if test "$docs" = "yes" ; then
|
||||
feature_not_found "docs" "Install texinfo and Perl/perl-podlators"
|
||||
feature_not_found "docs" "Install texinfo, Perl/perl-podlators and python-sphinx"
|
||||
fi
|
||||
docs=no
|
||||
fi
|
||||
|
|
|
@ -0,0 +1,216 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
#
|
||||
# QEMU documentation build configuration file, created by
|
||||
# sphinx-quickstart on Thu Jan 31 16:40:14 2019.
|
||||
#
|
||||
# This config file can be used in one of two ways:
|
||||
# (1) as a common config file which is included by the conf.py
|
||||
# for each of QEMU's manuals: in this case sphinx-build is run multiple
|
||||
# times, once per subdirectory.
|
||||
# (2) as a top level conf file which will result in building all
|
||||
# the manuals into a single document: in this case sphinx-build is
|
||||
# run once, on the top-level docs directory.
|
||||
#
|
||||
# QEMU's makefiles take option (1), which allows us to install
|
||||
# only the ones the user cares about (in particular we don't want
|
||||
# to ship the 'devel' manual to end-users).
|
||||
# Third-party sites such as readthedocs.org will take option (2).
|
||||
#
|
||||
#
|
||||
# This file is execfile()d with the current directory set to its
|
||||
# containing dir.
|
||||
#
|
||||
# Note that not all possible configuration values are present in this
|
||||
# autogenerated file.
|
||||
#
|
||||
# All configuration values have a default; values that are commented out
|
||||
# serve to show the default.
|
||||
|
||||
import os
|
||||
import sys
|
||||
|
||||
# The per-manual conf.py will set qemu_docdir for a single-manual build;
|
||||
# otherwise set it here if this is an entire-manual-set build.
|
||||
# This is always the absolute path of the docs/ directory in the source tree.
|
||||
try:
|
||||
qemu_docdir
|
||||
except NameError:
|
||||
qemu_docdir = os.path.abspath(".")
|
||||
|
||||
# If extensions (or modules to document with autodoc) are in another directory,
|
||||
# add these directories to sys.path here. If the directory is relative to the
|
||||
# documentation root, use an absolute path starting from qemu_docdir.
|
||||
#
|
||||
# sys.path.insert(0, os.path.join(qemu_docdir, "my_subdir"))
|
||||
|
||||
|
||||
# -- General configuration ------------------------------------------------
|
||||
|
||||
# If your documentation needs a minimal Sphinx version, state it here.
|
||||
#
|
||||
# 1.3 is where the 'alabaster' theme was shipped with Sphinx.
|
||||
needs_sphinx = '1.3'
|
||||
|
||||
# Add any Sphinx extension module names here, as strings. They can be
|
||||
# extensions coming with Sphinx (named 'sphinx.ext.*') or your custom
|
||||
# ones.
|
||||
extensions = []
|
||||
|
||||
# Add any paths that contain templates here, relative to this directory.
|
||||
templates_path = ['_templates']
|
||||
|
||||
# The suffix(es) of source filenames.
|
||||
# You can specify multiple suffix as a list of string:
|
||||
#
|
||||
# source_suffix = ['.rst', '.md']
|
||||
source_suffix = '.rst'
|
||||
|
||||
# The master toctree document.
|
||||
master_doc = 'index'
|
||||
|
||||
# General information about the project.
|
||||
project = u'QEMU'
|
||||
copyright = u'2019, The QEMU Project Developers'
|
||||
author = u'The QEMU Project Developers'
|
||||
|
||||
# The version info for the project you're documenting, acts as replacement for
|
||||
# |version| and |release|, also used in various other places throughout the
|
||||
# built documents.
|
||||
|
||||
# Extract this information from the VERSION file, for the benefit of
|
||||
# standalone Sphinx runs as used by readthedocs.org. Builds run from
|
||||
# the Makefile will pass version and release on the sphinx-build
|
||||
# command line, which override this.
|
||||
try:
|
||||
extracted_version = None
|
||||
with open(os.path.join(qemu_docdir, '../VERSION')) as f:
|
||||
extracted_version = f.readline().strip()
|
||||
except:
|
||||
pass
|
||||
finally:
|
||||
if extracted_version:
|
||||
version = release = extracted_version
|
||||
else:
|
||||
version = release = "unknown version"
|
||||
|
||||
# The language for content autogenerated by Sphinx. Refer to documentation
|
||||
# for a list of supported languages.
|
||||
#
|
||||
# This is also used if you do content translation via gettext catalogs.
|
||||
# Usually you set "language" from the command line for these cases.
|
||||
language = None
|
||||
|
||||
# List of patterns, relative to source directory, that match files and
|
||||
# directories to ignore when looking for source files.
|
||||
# This patterns also effect to html_static_path and html_extra_path
|
||||
exclude_patterns = ['_build', 'Thumbs.db', '.DS_Store']
|
||||
|
||||
# The name of the Pygments (syntax highlighting) style to use.
|
||||
pygments_style = 'sphinx'
|
||||
|
||||
# If true, `todo` and `todoList` produce output, else they produce nothing.
|
||||
todo_include_todos = False
|
||||
|
||||
# Sphinx defaults to warning about use of :option: for options not defined
|
||||
# with "option::" in the document being processed. Turn that off.
|
||||
suppress_warnings = ["ref.option"]
|
||||
|
||||
# -- Options for HTML output ----------------------------------------------
|
||||
|
||||
# The theme to use for HTML and HTML Help pages. See the documentation for
|
||||
# a list of builtin themes.
|
||||
#
|
||||
html_theme = 'alabaster'
|
||||
|
||||
# Theme options are theme-specific and customize the look and feel of a theme
|
||||
# further. For a list of options available for each theme, see the
|
||||
# documentation.
|
||||
# We initialize this to empty here, so the per-manual conf.py can just
|
||||
# add individual key/value entries.
|
||||
html_theme_options = {
|
||||
}
|
||||
|
||||
# Add any paths that contain custom static files (such as style sheets) here,
|
||||
# relative to this directory. They are copied after the builtin static files,
|
||||
# so a file named "default.css" will overwrite the builtin "default.css".
|
||||
# QEMU doesn't yet have any static files, so comment this out so we don't
|
||||
# get a warning about a missing directory.
|
||||
# If we do ever add this then it would probably be better to call the
|
||||
# subdirectory sphinx_static, as the Linux kernel does.
|
||||
# html_static_path = ['_static']
|
||||
|
||||
# Custom sidebar templates, must be a dictionary that maps document names
|
||||
# to template names.
|
||||
#
|
||||
# This is required for the alabaster theme
|
||||
# refs: http://alabaster.readthedocs.io/en/latest/installation.html#sidebars
|
||||
html_sidebars = {
|
||||
'**': [
|
||||
'about.html',
|
||||
'navigation.html',
|
||||
'searchbox.html',
|
||||
]
|
||||
}
|
||||
|
||||
# Don't copy the rST source files to the HTML output directory,
|
||||
# and don't put links to the sources into the output HTML.
|
||||
html_copy_source = False
|
||||
|
||||
# -- Options for HTMLHelp output ------------------------------------------
|
||||
|
||||
# Output file base name for HTML help builder.
|
||||
htmlhelp_basename = 'QEMUdoc'
|
||||
|
||||
|
||||
# -- Options for LaTeX output ---------------------------------------------
|
||||
|
||||
latex_elements = {
|
||||
# The paper size ('letterpaper' or 'a4paper').
|
||||
#
|
||||
# 'papersize': 'letterpaper',
|
||||
|
||||
# The font size ('10pt', '11pt' or '12pt').
|
||||
#
|
||||
# 'pointsize': '10pt',
|
||||
|
||||
# Additional stuff for the LaTeX preamble.
|
||||
#
|
||||
# 'preamble': '',
|
||||
|
||||
# Latex figure (float) alignment
|
||||
#
|
||||
# 'figure_align': 'htbp',
|
||||
}
|
||||
|
||||
# Grouping the document tree into LaTeX files. List of tuples
|
||||
# (source start file, target name, title,
|
||||
# author, documentclass [howto, manual, or own class]).
|
||||
latex_documents = [
|
||||
(master_doc, 'QEMU.tex', u'QEMU Documentation',
|
||||
u'The QEMU Project Developers', 'manual'),
|
||||
]
|
||||
|
||||
|
||||
# -- Options for manual page output ---------------------------------------
|
||||
|
||||
# One entry per manual page. List of tuples
|
||||
# (source start file, name, description, authors, manual section).
|
||||
man_pages = [
|
||||
(master_doc, 'qemu', u'QEMU Documentation',
|
||||
[author], 1)
|
||||
]
|
||||
|
||||
|
||||
# -- Options for Texinfo output -------------------------------------------
|
||||
|
||||
# Grouping the document tree into Texinfo files. List of tuples
|
||||
# (source start file, target name, title, author,
|
||||
# dir menu entry, description, category)
|
||||
texinfo_documents = [
|
||||
(master_doc, 'QEMU', u'QEMU Documentation',
|
||||
author, 'QEMU', 'One line description of project.',
|
||||
'Miscellaneous'),
|
||||
]
|
||||
|
||||
|
||||
|
|
@ -60,7 +60,7 @@ vCPU hotplug
|
|||
hot-plugged (no "qom-path" member). From its output in step (3), we
|
||||
can see that ``IvyBridge-IBRS-x86_64-cpu`` is present in socket 0,
|
||||
while hot-plugging a CPU into socket 1 requires passing the listed
|
||||
properties to QMP ``device_add``:
|
||||
properties to QMP ``device_add``::
|
||||
|
||||
(QEMU) device_add id=cpu-2 driver=IvyBridge-IBRS-x86_64-cpu socket-id=1 core-id=0 thread-id=0
|
||||
{
|
||||
|
|
|
@ -0,0 +1,15 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
#
|
||||
# QEMU documentation build configuration file for the 'devel' manual.
|
||||
#
|
||||
# This includes the top level conf file and then makes any necessary tweaks.
|
||||
import sys
|
||||
import os
|
||||
|
||||
qemu_docdir = os.path.abspath("..")
|
||||
parent_config = os.path.join(qemu_docdir, "conf.py")
|
||||
exec(compile(open(parent_config, "rb").read(), parent_config, 'exec'))
|
||||
|
||||
# This slightly misuses the 'description', but is the best way to get
|
||||
# the manual title to appear in the sidebar.
|
||||
html_theme_options['description'] = u'Developer''s Guide'
|
|
@ -0,0 +1,21 @@
|
|||
.. This is the top level page for the 'devel' manual.
|
||||
|
||||
|
||||
QEMU Developer's Guide
|
||||
======================
|
||||
|
||||
This manual documents various parts of the internals of QEMU.
|
||||
You only need to read it if you are interested in reading or
|
||||
modifying QEMU's source code.
|
||||
|
||||
Contents:
|
||||
|
||||
.. toctree::
|
||||
:maxdepth: 2
|
||||
|
||||
loads-stores
|
||||
memory
|
||||
migration
|
||||
stable-process
|
||||
testing
|
||||
|
|
@ -1,19 +1,20 @@
|
|||
==============
|
||||
The memory API
|
||||
==============
|
||||
|
||||
The memory API models the memory and I/O buses and controllers of a QEMU
|
||||
machine. It attempts to allow modelling of:
|
||||
|
||||
- ordinary RAM
|
||||
- memory-mapped I/O (MMIO)
|
||||
- memory controllers that can dynamically reroute physical memory regions
|
||||
to different destinations
|
||||
- ordinary RAM
|
||||
- memory-mapped I/O (MMIO)
|
||||
- memory controllers that can dynamically reroute physical memory regions
|
||||
to different destinations
|
||||
|
||||
The memory model provides support for
|
||||
|
||||
- tracking RAM changes by the guest
|
||||
- setting up coalesced memory for kvm
|
||||
- setting up ioeventfd regions for kvm
|
||||
- tracking RAM changes by the guest
|
||||
- setting up coalesced memory for kvm
|
||||
- setting up ioeventfd regions for kvm
|
||||
|
||||
Memory is modelled as an acyclic graph of MemoryRegion objects. Sinks
|
||||
(leaves) are RAM and MMIO regions, while other nodes represent
|
||||
|
@ -98,25 +99,30 @@ ROM device memory region types), this host memory needs to be
|
|||
copied to the destination on migration. These APIs which allocate
|
||||
the host memory for you will also register the memory so it is
|
||||
migrated:
|
||||
- memory_region_init_ram()
|
||||
- memory_region_init_rom()
|
||||
- memory_region_init_rom_device()
|
||||
|
||||
- memory_region_init_ram()
|
||||
- memory_region_init_rom()
|
||||
- memory_region_init_rom_device()
|
||||
|
||||
For most devices and boards this is the correct thing. If you
|
||||
have a special case where you need to manage the migration of
|
||||
the backing memory yourself, you can call the functions:
|
||||
- memory_region_init_ram_nomigrate()
|
||||
- memory_region_init_rom_nomigrate()
|
||||
- memory_region_init_rom_device_nomigrate()
|
||||
|
||||
- memory_region_init_ram_nomigrate()
|
||||
- memory_region_init_rom_nomigrate()
|
||||
- memory_region_init_rom_device_nomigrate()
|
||||
|
||||
which only initialize the MemoryRegion and leave handling
|
||||
migration to the caller.
|
||||
|
||||
The functions:
|
||||
- memory_region_init_resizeable_ram()
|
||||
- memory_region_init_ram_from_file()
|
||||
- memory_region_init_ram_from_fd()
|
||||
- memory_region_init_ram_ptr()
|
||||
- memory_region_init_ram_device_ptr()
|
||||
|
||||
- memory_region_init_resizeable_ram()
|
||||
- memory_region_init_ram_from_file()
|
||||
- memory_region_init_ram_from_fd()
|
||||
- memory_region_init_ram_ptr()
|
||||
- memory_region_init_ram_device_ptr()
|
||||
|
||||
are for special cases only, and so they do not automatically
|
||||
register the backing memory for migration; the caller must
|
||||
manage migration if necessary.
|
||||
|
@ -218,7 +224,7 @@ For example, suppose we have a container A of size 0x8000 with two subregions
|
|||
B and C. B is a container mapped at 0x2000, size 0x4000, priority 2; C is
|
||||
an MMIO region mapped at 0x0, size 0x6000, priority 1. B currently has two
|
||||
of its own subregions: D of size 0x1000 at offset 0 and E of size 0x1000 at
|
||||
offset 0x2000. As a diagram:
|
||||
offset 0x2000. As a diagram::
|
||||
|
||||
0 1000 2000 3000 4000 5000 6000 7000 8000
|
||||
|------|------|------|------|------|------|------|------|
|
||||
|
@ -228,8 +234,9 @@ offset 0x2000. As a diagram:
|
|||
D: [DDDDD]
|
||||
E: [EEEEE]
|
||||
|
||||
The regions that will be seen within this address range then are:
|
||||
[CCCCCCCCCCCC][DDDDD][CCCCC][EEEEE][CCCCC]
|
||||
The regions that will be seen within this address range then are::
|
||||
|
||||
[CCCCCCCCCCCC][DDDDD][CCCCC][EEEEE][CCCCC]
|
||||
|
||||
Since B has higher priority than C, its subregions appear in the flat map
|
||||
even where they overlap with C. In ranges where B has not mapped anything
|
||||
|
@ -237,8 +244,9 @@ C's region appears.
|
|||
|
||||
If B had provided its own MMIO operations (ie it was not a pure container)
|
||||
then these would be used for any addresses in its range not handled by
|
||||
D or E, and the result would be:
|
||||
[CCCCCCCCCCCC][DDDDD][BBBBB][EEEEE][BBBBB]
|
||||
D or E, and the result would be::
|
||||
|
||||
[CCCCCCCCCCCC][DDDDD][BBBBB][EEEEE][BBBBB]
|
||||
|
||||
Priority values are local to a container, because the priorities of two
|
||||
regions are only compared when they are both children of the same container.
|
||||
|
@ -257,6 +265,7 @@ guest accesses an address:
|
|||
|
||||
- all direct subregions of the root region are matched against the address, in
|
||||
descending priority order
|
||||
|
||||
- if the address lies outside the region offset/size, the subregion is
|
||||
discarded
|
||||
- if the subregion is a leaf (RAM or MMIO), the search terminates, returning
|
||||
|
@ -270,36 +279,39 @@ guest accesses an address:
|
|||
address range), then if this is a container with its own MMIO or RAM
|
||||
backing the search terminates, returning the container itself. Otherwise
|
||||
we continue with the next subregion in priority order
|
||||
|
||||
- if none of the subregions match the address then the search terminates
|
||||
with no match found
|
||||
|
||||
Example memory map
|
||||
------------------
|
||||
|
||||
system_memory: container@0-2^48-1
|
||||
|
|
||||
+---- lomem: alias@0-0xdfffffff ---> #ram (0-0xdfffffff)
|
||||
|
|
||||
+---- himem: alias@0x100000000-0x11fffffff ---> #ram (0xe0000000-0xffffffff)
|
||||
|
|
||||
+---- vga-window: alias@0xa0000-0xbffff ---> #pci (0xa0000-0xbffff)
|
||||
| (prio 1)
|
||||
|
|
||||
+---- pci-hole: alias@0xe0000000-0xffffffff ---> #pci (0xe0000000-0xffffffff)
|
||||
::
|
||||
|
||||
pci (0-2^32-1)
|
||||
|
|
||||
+--- vga-area: container@0xa0000-0xbffff
|
||||
| |
|
||||
| +--- alias@0x00000-0x7fff ---> #vram (0x010000-0x017fff)
|
||||
| |
|
||||
| +--- alias@0x08000-0xffff ---> #vram (0x020000-0x027fff)
|
||||
|
|
||||
+---- vram: ram@0xe1000000-0xe1ffffff
|
||||
|
|
||||
+---- vga-mmio: mmio@0xe2000000-0xe200ffff
|
||||
system_memory: container@0-2^48-1
|
||||
|
|
||||
+---- lomem: alias@0-0xdfffffff ---> #ram (0-0xdfffffff)
|
||||
|
|
||||
+---- himem: alias@0x100000000-0x11fffffff ---> #ram (0xe0000000-0xffffffff)
|
||||
|
|
||||
+---- vga-window: alias@0xa0000-0xbffff ---> #pci (0xa0000-0xbffff)
|
||||
| (prio 1)
|
||||
|
|
||||
+---- pci-hole: alias@0xe0000000-0xffffffff ---> #pci (0xe0000000-0xffffffff)
|
||||
|
||||
ram: ram@0x00000000-0xffffffff
|
||||
pci (0-2^32-1)
|
||||
|
|
||||
+--- vga-area: container@0xa0000-0xbffff
|
||||
| |
|
||||
| +--- alias@0x00000-0x7fff ---> #vram (0x010000-0x017fff)
|
||||
| |
|
||||
| +--- alias@0x08000-0xffff ---> #vram (0x020000-0x027fff)
|
||||
|
|
||||
+---- vram: ram@0xe1000000-0xe1ffffff
|
||||
|
|
||||
+---- vga-mmio: mmio@0xe2000000-0xe200ffff
|
||||
|
||||
ram: ram@0x00000000-0xffffffff
|
||||
|
||||
This is a (simplified) PC memory map. The 4GB RAM block is mapped into the
|
||||
system address space via two aliases: "lomem" is a 1:1 mapping of the first
|
||||
|
@ -336,16 +348,16 @@ rather than completing successfully; those devices can use the
|
|||
In addition various constraints can be supplied to control how these
|
||||
callbacks are called:
|
||||
|
||||
- .valid.min_access_size, .valid.max_access_size define the access sizes
|
||||
(in bytes) which the device accepts; accesses outside this range will
|
||||
have device and bus specific behaviour (ignored, or machine check)
|
||||
- .valid.unaligned specifies that the *device being modelled* supports
|
||||
unaligned accesses; if false, unaligned accesses will invoke the
|
||||
appropriate bus or CPU specific behaviour.
|
||||
- .impl.min_access_size, .impl.max_access_size define the access sizes
|
||||
(in bytes) supported by the *implementation*; other access sizes will be
|
||||
emulated using the ones available. For example a 4-byte write will be
|
||||
emulated using four 1-byte writes, if .impl.max_access_size = 1.
|
||||
- .impl.unaligned specifies that the *implementation* supports unaligned
|
||||
accesses; if false, unaligned accesses will be emulated by two aligned
|
||||
accesses.
|
||||
- .valid.min_access_size, .valid.max_access_size define the access sizes
|
||||
(in bytes) which the device accepts; accesses outside this range will
|
||||
have device and bus specific behaviour (ignored, or machine check)
|
||||
- .valid.unaligned specifies that the *device being modelled* supports
|
||||
unaligned accesses; if false, unaligned accesses will invoke the
|
||||
appropriate bus or CPU specific behaviour.
|
||||
- .impl.min_access_size, .impl.max_access_size define the access sizes
|
||||
(in bytes) supported by the *implementation*; other access sizes will be
|
||||
emulated using the ones available. For example a 4-byte write will be
|
||||
emulated using four 1-byte writes, if .impl.max_access_size = 1.
|
||||
- .impl.unaligned specifies that the *implementation* supports unaligned
|
||||
accesses; if false, unaligned accesses will be emulated by two aligned
|
||||
accesses.
|
|
@ -0,0 +1,15 @@
|
|||
.. QEMU documentation master file, created by
|
||||
sphinx-quickstart on Thu Jan 31 16:40:14 2019.
|
||||
You can adapt this file completely to your liking, but it should at least
|
||||
contain the root `toctree` directive.
|
||||
|
||||
Welcome to QEMU's documentation!
|
||||
================================
|
||||
|
||||
.. toctree::
|
||||
:maxdepth: 2
|
||||
:caption: Contents:
|
||||
|
||||
interop/index
|
||||
devel/index
|
||||
|
|
@ -0,0 +1,15 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
#
|
||||
# QEMU documentation build configuration file for the 'interop' manual.
|
||||
#
|
||||
# This includes the top level conf file and then makes any necessary tweaks.
|
||||
import sys
|
||||
import os
|
||||
|
||||
qemu_docdir = os.path.abspath("..")
|
||||
parent_config = os.path.join(qemu_docdir, "conf.py")
|
||||
exec(compile(open(parent_config, "rb").read(), parent_config, 'exec'))
|
||||
|
||||
# This slightly misuses the 'description', but is the best way to get
|
||||
# the manual title to appear in the sidebar.
|
||||
html_theme_options['description'] = u'System Emulation Management and Interoperability Guide'
|
|
@ -0,0 +1,18 @@
|
|||
.. This is the top level page for the 'interop' manual.
|
||||
|
||||
|
||||
QEMU System Emulation Management and Interoperability Guide
|
||||
===========================================================
|
||||
|
||||
This manual contains documents and specifications that are useful
|
||||
for making QEMU interoperate with other software.
|
||||
|
||||
Contents:
|
||||
|
||||
.. toctree::
|
||||
:maxdepth: 2
|
||||
|
||||
bitmaps
|
||||
live-block-operations
|
||||
pr-helper
|
||||
|
Loading…
Reference in New Issue