:p
atchew
Login
Hi; here's a target-arm pullreq. Most of the patches in it are actually docs and similar tidyups, though... thanks -- PMM The following changes since commit 2339d0a1cfac6ecc667e6e062a593865c1541c35: Merge tag 'hw-misc-20260120' of https://github.com/philmd/qemu into staging (2026-01-21 07:39:57 +1100) are available in the Git repository at: https://gitlab.com/pm215/qemu.git tags/pull-target-arm-20260123 for you to fetch changes up to 62580edc02ae16ba520d220f6fd7556999504a84: qemu-options.hx: Improve formatting in colo-compare docs (2026-01-23 14:08:57 +0000) ---------------------------------------------------------------- target-arm queue: * hw/arm/imx8mp-evk: Provide some defaults matching real hardware * hw/intc: endianness fixes * various: Clean up includes * kernel-doc.py: sync with upstream Kernel v6.19-rc4 * scripts/clean-includes: Minor improvements; exclude list update * docs/system/arm/imx8mp-evk: Avoid suggesting redundant CLI parameters * docs/system/arm/xlnx-zynq.rst: Improve docs rendering * docs: Be consistent about capitalization of 'Arm' (again) * docs: Avoid unintended mailto: hyperlinks * qemu-options.hx: Drop uses of @var * qemu-options.hx: Improve formatting in colo-compare docs ---------------------------------------------------------------- Alex Bennée (4): hw/intc: declare NVIC regions as little endian hw/intc: declare GIC regions as little endian hw/intc: declare GICv3 regions as little endian hw/intc: avoid byte swap fiddling in gicv3 its path Bernhard Beschow (2): hw/arm/imx8mp-evk: Provide some defaults matching real hardware docs/system/arm/imx8mp-evk: Avoid suggesting redundant CLI parameters Mauro Carvalho Chehab (1): kernel-doc.py: sync with upstream Kernel v6.19-rc4 Peter Maydell (15): docs: Be consistent about capitalization of 'Arm' (again) scripts/clean-includes: Allow directories on command line scripts/clean-includes: Remove outdated comment scripts/clean-includes: Make ignore-regexes one per line scripts/clean-includes: Do all our exclusions with REGEXFILE scripts/clean-includes: Give the args in git commit messages scripts/clean-includes: Update exclude list mshv: Clean up includes bsd-user: Clean up includes misc: Clean up includes all: Clean up includes docs/system/arm/xlnx-zynq.rst: Improve docs rendering docs: avoid unintended mailto: hyperlinks qemu-options.hx: Drop uses of @var qemu-options.hx: Improve formatting in colo-compare docs accel/mshv/irq.c | 3 +- accel/mshv/mshv-all.c | 1 - bsd-user/bsd-mem.h | 3 - bsd-user/bsd-proc.c | 1 - bsd-user/freebsd/os-proc.h | 2 - bsd-user/qemu-bsd.h | 1 - docs/devel/submitting-a-patch.rst | 2 +- docs/devel/testing/qgraph.rst | 8 +- docs/devel/vfio-iommufd.rst | 2 +- docs/specs/fsi.rst | 2 +- docs/system/arm/aspeed.rst | 6 +- docs/system/arm/b-l475e-iot01a.rst | 2 +- docs/system/arm/imx8mp-evk.rst | 4 +- docs/system/arm/nrf.rst | 4 +- docs/system/arm/stm32.rst | 12 +- docs/system/arm/xlnx-versal-virt.rst | 16 +- docs/system/arm/xlnx-zynq.rst | 51 +- docs/system/device-url-syntax.rst.inc | 4 +- docs/system/guest-loader.rst | 2 +- docs/system/replay.rst | 2 +- docs/system/vnc-security.rst | 6 +- hw/arm/imx8mp-evk.c | 2 + hw/core/machine-qmp-cmds.c | 1 - hw/intc/arm_gic.c | 12 +- hw/intc/arm_gicv3.c | 4 +- hw/intc/arm_gicv3_its.c | 4 +- hw/intc/arm_gicv3_its_common.c | 4 +- hw/intc/arm_gicv3_its_kvm.c | 2 +- hw/intc/armv7m_nvic.c | 2 +- hw/scsi/lasi_ncr710.h | 1 - hw/scsi/ncr53c710.h | 1 - include/hw/core/loader.h | 1 - include/hw/i386/tdvf.h | 1 - include/hw/ppc/spapr_fadump.h | 1 - include/hw/riscv/iommu.h | 1 - include/system/accel-irq.h | 1 - include/system/mshv.h | 1 - linux-user/alpha/target_proc.h | 1 - qemu-options.hx | 51 +- qga/commands-windows-ssh.h | 1 - qga/vss-win32/vss-debug.h | 1 - scripts/clean-includes | 103 ++-- scripts/lib/kdoc/kdoc_files.py | 11 +- scripts/lib/kdoc/kdoc_item.py | 3 +- scripts/lib/kdoc/kdoc_output.py | 93 +++- scripts/lib/kdoc/kdoc_parser.py | 901 +++++++++++++++++----------------- scripts/lib/kdoc/kdoc_re.py | 24 +- semihosting/arm-compat-semi-stub.c | 1 - target/arm/cpu32-stubs.c | 1 - target/i386/kvm/kvm.c | 1 - target/i386/kvm/vmsr_energy.h | 2 - target/i386/mshv/mshv-cpu.c | 1 - target/i386/mshv/x86.c | 1 - target/loongarch/csr.c | 1 - target/riscv/csr.c | 1 - tools/i386/qemu-vmsr-helper.c | 1 - util/cpuinfo-aarch64.c | 1 - 57 files changed, 738 insertions(+), 635 deletions(-)
From: Bernhard Beschow <shentey@gmail.com> Having four CPUs and 6 GiB of RAM matches real hardware. Fix the machine defaults to make its use more ergonomic and less error-prone. Signed-off-by: Bernhard Beschow <shentey@gmail.com> Message-id: 20260114213227.3812-2-shentey@gmail.com Reviewed-by: Peter Maydell <peter.maydell@linaro.org> Signed-off-by: Peter Maydell <peter.maydell@linaro.org> --- docs/system/arm/imx8mp-evk.rst | 2 +- hw/arm/imx8mp-evk.c | 2 ++ 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/docs/system/arm/imx8mp-evk.rst b/docs/system/arm/imx8mp-evk.rst index XXXXXXX..XXXXXXX 100644 --- a/docs/system/arm/imx8mp-evk.rst +++ b/docs/system/arm/imx8mp-evk.rst @@ -XXX,XX +XXX,XX @@ Now that everything is prepared the machine can be started as follows: .. code-block:: bash - $ qemu-system-aarch64 -M imx8mp-evk -smp 4 -m 3G \ + $ qemu-system-aarch64 -M imx8mp-evk \ -display none -serial null -serial stdio \ -kernel Image \ -dtb imx8mp-evk.dtb \ diff --git a/hw/arm/imx8mp-evk.c b/hw/arm/imx8mp-evk.c index XXXXXXX..XXXXXXX 100644 --- a/hw/arm/imx8mp-evk.c +++ b/hw/arm/imx8mp-evk.c @@ -XXX,XX +XXX,XX @@ static void imx8mp_evk_machine_init(MachineClass *mc) { mc->desc = "NXP i.MX 8M Plus EVK Board"; mc->init = imx8mp_evk_init; + mc->default_cpus = 4; mc->max_cpus = FSL_IMX8MP_NUM_CPUS; mc->default_ram_id = "imx8mp-evk.ram"; + mc->default_ram_size = 6 * GiB; mc->get_default_cpu_type = imx8mp_evk_get_default_cpu_type; } -- 2.47.3
From: Bernhard Beschow <shentey@gmail.com> Commit 094fd7d36f2a ("hw/arm/imx8mp-evk: Add KVM support") introduced KVM support for the imx8mp-evk machine. KVM only works with the "host" CPU type such that it has been made the default CPU type for KVM. No need to repeat that on the command line. Fixes: 094fd7d36f2a ("hw/arm/imx8mp-evk: Add KVM support") Signed-off-by: Bernhard Beschow <shentey@gmail.com> Message-id: 20260114213227.3812-3-shentey@gmail.com Reviewed-by: Peter Maydell <peter.maydell@linaro.org> Signed-off-by: Peter Maydell <peter.maydell@linaro.org> --- docs/system/arm/imx8mp-evk.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/system/arm/imx8mp-evk.rst b/docs/system/arm/imx8mp-evk.rst index XXXXXXX..XXXXXXX 100644 --- a/docs/system/arm/imx8mp-evk.rst +++ b/docs/system/arm/imx8mp-evk.rst @@ -XXX,XX +XXX,XX @@ KVM Acceleration ---------------- To enable hardware-assisted acceleration via KVM, append -``-accel kvm -cpu host`` to the command line. While this speeds up performance +``-accel kvm`` to the command line. While this speeds up performance significantly, be aware of the following limitations: * The ``imx8mp-evk`` machine is not included under the "virtualization use case" -- 2.47.3
From: Mauro Carvalho Chehab <mchehab+huawei@kernel.org> The changes here are aligned up to this Linux changeset: f64c7e113dc9 ("scripts: docs: kdoc_files.py: don't consider symlinks as directories") On other words, everything that it is there, except for the patch moving the library to tools/lib/python. Signed-off-by: Mauro Carvalho Chehab <mchehab+huawei@kernel.org> Reviewed-by: Peter Maydell <peter.maydell@linaro.org> Message-id: 54dec248994abf37c4b5b9e48d5ab8f0f8df6f2d.1767716928.git.mchehab+huawei@kernel.org Acked-by: Michael S. Tsirkin <mst@redhat.com> Signed-off-by: Peter Maydell <peter.maydell@linaro.org> --- scripts/lib/kdoc/kdoc_files.py | 11 +- scripts/lib/kdoc/kdoc_item.py | 3 +- scripts/lib/kdoc/kdoc_output.py | 93 +++- scripts/lib/kdoc/kdoc_parser.py | 901 ++++++++++++++++---------------- scripts/lib/kdoc/kdoc_re.py | 24 +- 5 files changed, 556 insertions(+), 476 deletions(-) diff --git a/scripts/lib/kdoc/kdoc_files.py b/scripts/lib/kdoc/kdoc_files.py index XXXXXXX..XXXXXXX 100644 --- a/scripts/lib/kdoc/kdoc_files.py +++ b/scripts/lib/kdoc/kdoc_files.py @@ -XXX,XX +XXX,XX @@ def _parse_dir(self, dirname): for entry in obj: name = os.path.join(dirname, entry.name) - if entry.is_dir(): + if entry.is_dir(follow_symlinks=False): yield from self._parse_dir(name) if not entry.is_file(): @@ -XXX,XX +XXX,XX @@ def _parse_dir(self, dirname): def parse_files(self, file_list, file_not_found_cb): """ - Define an interator to parse all source files from file_list, + Define an iterator to parse all source files from file_list, handling directories if any """ @@ -XXX,XX +XXX,XX @@ def out_msg(self, fname, name, arg): Return output messages from a file name using the output style filtering. - If output type was not handled by the syler, return None. + If output type was not handled by the styler, return None. """ # NOTE: we can add rules here to filter out unwanted parts, @@ -XXX,XX +XXX,XX @@ def msg(self, enable_lineno=False, export=False, internal=False, self.config.log.warning("No kernel-doc for file %s", fname) continue - for arg in self.results[fname]: + symbols = self.results[fname] + self.out_style.set_symbols(symbols) + + for arg in symbols: m = self.out_msg(fname, arg.name, arg) if m is None: diff --git a/scripts/lib/kdoc/kdoc_item.py b/scripts/lib/kdoc/kdoc_item.py index XXXXXXX..XXXXXXX 100644 --- a/scripts/lib/kdoc/kdoc_item.py +++ b/scripts/lib/kdoc/kdoc_item.py @@ -XXX,XX +XXX,XX @@ # class KdocItem: - def __init__(self, name, type, start_line, **other_stuff): + def __init__(self, name, fname, type, start_line, **other_stuff): self.name = name + self.fname = fname self.type = type self.declaration_start_line = start_line self.sections = {} diff --git a/scripts/lib/kdoc/kdoc_output.py b/scripts/lib/kdoc/kdoc_output.py index XXXXXXX..XXXXXXX 100644 --- a/scripts/lib/kdoc/kdoc_output.py +++ b/scripts/lib/kdoc/kdoc_output.py @@ -XXX,XX +XXX,XX @@ Implement output filters to print kernel-doc documentation. The implementation uses a virtual base class (OutputFormat) which -contains a dispatches to virtual methods, and some code to filter +contains dispatches to virtual methods, and some code to filter out output messages. The actual implementation is done on one separate class per each type @@ -XXX,XX +XXX,XX @@ class OutputFormat: OUTPUT_EXPORTED = 2 # output exported symbols OUTPUT_INTERNAL = 3 # output non-exported symbols - # Virtual member to be overriden at the inherited classes + # Virtual member to be overridden at the inherited classes highlights = [] def __init__(self): @@ -XXX,XX +XXX,XX @@ def set_config(self, config): def set_filter(self, export, internal, symbol, nosymbol, function_table, enable_lineno, no_doc_sections): """ - Initialize filter variables according with the requested mode. + Initialize filter variables according to the requested mode. Only one choice is valid between export, internal and symbol. @@ -XXX,XX +XXX,XX @@ def msg(self, fname, name, args): return self.data # Warn if some type requires an output logic - self.config.log.warning("doesn't now how to output '%s' block", + self.config.log.warning("doesn't know how to output '%s' block", dtype) return None # Virtual methods to be overridden by inherited classes # At the base class, those do nothing. + def set_symbols(self, symbols): + """Get a list of all symbols from kernel_doc""" + def out_doc(self, fname, name, args): """Outputs a DOC block""" @@ -XXX,XX +XXX,XX @@ def __init__(self, modulename): super().__init__() self.modulename = modulename + self.symbols = [] dt = None tstamp = os.environ.get("KBUILD_BUILD_TIMESTAMP") @@ -XXX,XX +XXX,XX @@ def __init__(self, modulename): self.man_date = dt.strftime("%B %Y") + def arg_name(self, args, name): + """ + Return the name that will be used for the man page. + + As we may have the same name on different namespaces, + prepend the data type for all types except functions and typedefs. + + The doc section is special: it uses the modulename. + """ + + dtype = args.type + + if dtype == "doc": + return self.modulename + + if dtype in ["function", "typedef"]: + return name + + return f"{dtype} {name}" + + def set_symbols(self, symbols): + """ + Get a list of all symbols from kernel_doc. + + Man pages will uses it to add a SEE ALSO section with other + symbols at the same file. + """ + self.symbols = symbols + + def out_tail(self, fname, name, args): + """Adds a tail for all man pages""" + + # SEE ALSO section + self.data += f'.SH "SEE ALSO"' + "\n.PP\n" + self.data += (f"Kernel file \\fB{args.fname}\\fR\n") + if len(self.symbols) >= 2: + cur_name = self.arg_name(args, name) + + related = [] + for arg in self.symbols: + out_name = self.arg_name(arg, arg.name) + + if cur_name == out_name: + continue + + related.append(f"\\fB{out_name}\\fR(9)") + + self.data += ",\n".join(related) + "\n" + + # TODO: does it make sense to add other sections? Maybe + # REPORTING ISSUES? LICENSE? + + def msg(self, fname, name, args): + """ + Handles a single entry from kernel-doc parser. + + Add a tail at the end of man pages output. + """ + super().msg(fname, name, args) + self.out_tail(fname, name, args) + + return self.data + def output_highlight(self, block): """ Outputs a C symbol that may require being highlighted with @@ -XXX,XX +XXX,XX @@ def out_doc(self, fname, name, args): if not self.check_doc(name, args): return - self.data += f'.TH "{self.modulename}" 9 "{self.modulename}" "{self.man_date}" "API Manual" LINUX' + "\n" + out_name = self.arg_name(args, name) + + self.data += f'.TH "{self.modulename}" 9 "{out_name}" "{self.man_date}" "API Manual" LINUX' + "\n" for section, text in args.sections.items(): self.data += f'.SH "{section}"' + "\n" @@ -XXX,XX +XXX,XX @@ def out_doc(self, fname, name, args): def out_function(self, fname, name, args): """output function in man""" - self.data += f'.TH "{name}" 9 "{name}" "{self.man_date}" "Kernel Hacker\'s Manual" LINUX' + "\n" + out_name = self.arg_name(args, name) + + self.data += f'.TH "{name}" 9 "{out_name}" "{self.man_date}" "Kernel Hacker\'s Manual" LINUX' + "\n" self.data += ".SH NAME\n" self.data += f"{name} \\- {args['purpose']}\n" @@ -XXX,XX +XXX,XX @@ def out_function(self, fname, name, args): self.output_highlight(text) def out_enum(self, fname, name, args): - self.data += f'.TH "{self.modulename}" 9 "enum {name}" "{self.man_date}" "API Manual" LINUX' + "\n" + out_name = self.arg_name(args, name) + + self.data += f'.TH "{self.modulename}" 9 "{out_name}" "{self.man_date}" "API Manual" LINUX' + "\n" self.data += ".SH NAME\n" self.data += f"enum {name} \\- {args['purpose']}\n" @@ -XXX,XX +XXX,XX @@ def out_enum(self, fname, name, args): def out_typedef(self, fname, name, args): module = self.modulename purpose = args.get('purpose') + out_name = self.arg_name(args, name) - self.data += f'.TH "{module}" 9 "{name}" "{self.man_date}" "API Manual" LINUX' + "\n" + self.data += f'.TH "{module}" 9 "{out_name}" "{self.man_date}" "API Manual" LINUX' + "\n" self.data += ".SH NAME\n" self.data += f"typedef {name} \\- {purpose}\n" @@ -XXX,XX +XXX,XX @@ def out_struct(self, fname, name, args): module = self.modulename purpose = args.get('purpose') definition = args.get('definition') + out_name = self.arg_name(args, name) - self.data += f'.TH "{module}" 9 "{args.type} {name}" "{self.man_date}" "API Manual" LINUX' + "\n" + self.data += f'.TH "{module}" 9 "{out_name}" "{self.man_date}" "API Manual" LINUX' + "\n" self.data += ".SH NAME\n" self.data += f"{args.type} {name} \\- {purpose}\n" diff --git a/scripts/lib/kdoc/kdoc_parser.py b/scripts/lib/kdoc/kdoc_parser.py index XXXXXXX..XXXXXXX 100644 --- a/scripts/lib/kdoc/kdoc_parser.py +++ b/scripts/lib/kdoc/kdoc_parser.py @@ -XXX,XX +XXX,XX @@ # # Regular expressions used to parse kernel-doc markups at KernelDoc class. # -# Let's declare them in lowercase outside any class to make easier to -# convert from the python script. +# Let's declare them in lowercase outside any class to make it easier to +# convert from the Perl script. # # As those are evaluated at the beginning, no need to cache them # @@ -XXX,XX +XXX,XX @@ known_section_names = 'description|context|returns?|notes?|examples?' known_sections = KernRe(known_section_names, flags = re.I) doc_sect = doc_com + \ - KernRe(r'\s*(\@[.\w]+|\@\.\.\.|' + known_section_names + r')\s*:([^:].*)?$', + KernRe(r'\s*(@[.\w]+|@\.\.\.|' + known_section_names + r')\s*:([^:].*)?$', flags=re.I, cache=False) doc_content = doc_com_body + KernRe(r'(.*)', cache=False) @@ -XXX,XX +XXX,XX @@ doc_inline_sect = KernRe(r'\s*\*\s*(@\s*[\w][\w\.]*\s*):(.*)', cache=False) doc_inline_end = KernRe(r'^\s*\*/\s*$', cache=False) doc_inline_oneline = KernRe(r'^\s*/\*\*\s*(@[\w\s]+):\s*(.*)\s*\*/\s*$', cache=False) -attribute = KernRe(r"__attribute__\s*\(\([a-z0-9,_\*\s\(\)]*\)\)", - flags=re.I | re.S, cache=False) export_symbol = KernRe(r'^\s*EXPORT_SYMBOL(_GPL)?\s*\(\s*(\w+)\s*\)\s*', cache=False) export_symbol_ns = KernRe(r'^\s*EXPORT_SYMBOL_NS(_GPL)?\s*\(\s*(\w+)\s*,\s*"\S+"\)\s*', cache=False) -type_param = KernRe(r"\@(\w*((\.\w+)|(->\w+))*(\.\.\.)?)", cache=False) +type_param = KernRe(r"@(\w*((\.\w+)|(->\w+))*(\.\.\.)?)", cache=False) # # Tests for the beginning of a kerneldoc block in its various forms. @@ -XXX,XX +XXX,XX @@ r'(?:[-:].*)?$', # description (not captured) cache = False) +# +# Here begins a long set of transformations to turn structure member prefixes +# and macro invocations into something we can parse and generate kdoc for. +# +struct_args_pattern = r'([^,)]+)' + +struct_xforms = [ + # Strip attributes + (KernRe(r"__attribute__\s*\(\([a-z0-9,_\*\s\(\)]*\)\)", flags=re.I | re.S, cache=False), ' '), + (KernRe(r'\s*__aligned\s*\([^;]*\)', re.S), ' '), + (KernRe(r'\s*__counted_by\s*\([^;]*\)', re.S), ' '), + (KernRe(r'\s*__counted_by_(le|be)\s*\([^;]*\)', re.S), ' '), + (KernRe(r'\s*__packed\s*', re.S), ' '), + (KernRe(r'\s*CRYPTO_MINALIGN_ATTR', re.S), ' '), + (KernRe(r'\s*__private', re.S), ' '), + (KernRe(r'\s*__rcu', re.S), ' '), + (KernRe(r'\s*____cacheline_aligned_in_smp', re.S), ' '), + (KernRe(r'\s*____cacheline_aligned', re.S), ' '), + (KernRe(r'\s*__cacheline_group_(begin|end)\([^\)]+\);'), ''), + # + # Unwrap struct_group macros based on this definition: + # __struct_group(TAG, NAME, ATTRS, MEMBERS...) + # which has variants like: struct_group(NAME, MEMBERS...) + # Only MEMBERS arguments require documentation. + # + # Parsing them happens on two steps: + # + # 1. drop struct group arguments that aren't at MEMBERS, + # storing them as STRUCT_GROUP(MEMBERS) + # + # 2. remove STRUCT_GROUP() ancillary macro. + # + # The original logic used to remove STRUCT_GROUP() using an + # advanced regex: + # + # \bSTRUCT_GROUP(\(((?:(?>[^)(]+)|(?1))*)\))[^;]*; + # + # with two patterns that are incompatible with + # Python re module, as it has: + # + # - a recursive pattern: (?1) + # - an atomic grouping: (?>...) + # + # I tried a simpler version: but it didn't work either: + # \bSTRUCT_GROUP\(([^\)]+)\)[^;]*; + # + # As it doesn't properly match the end parenthesis on some cases. + # + # So, a better solution was crafted: there's now a NestedMatch + # class that ensures that delimiters after a search are properly + # matched. So, the implementation to drop STRUCT_GROUP() will be + # handled in separate. + # + (KernRe(r'\bstruct_group\s*\(([^,]*,)', re.S), r'STRUCT_GROUP('), + (KernRe(r'\bstruct_group_attr\s*\(([^,]*,){2}', re.S), r'STRUCT_GROUP('), + (KernRe(r'\bstruct_group_tagged\s*\(([^,]*),([^,]*),', re.S), r'struct \1 \2; STRUCT_GROUP('), + (KernRe(r'\b__struct_group\s*\(([^,]*,){3}', re.S), r'STRUCT_GROUP('), + # + # Replace macros + # + # TODO: use NestedMatch for FOO($1, $2, ...) matches + # + # it is better to also move those to the NestedMatch logic, + # to ensure that parentheses will be properly matched. + # + (KernRe(r'__ETHTOOL_DECLARE_LINK_MODE_MASK\s*\(([^\)]+)\)', re.S), + r'DECLARE_BITMAP(\1, __ETHTOOL_LINK_MODE_MASK_NBITS)'), + (KernRe(r'DECLARE_PHY_INTERFACE_MASK\s*\(([^\)]+)\)', re.S), + r'DECLARE_BITMAP(\1, PHY_INTERFACE_MODE_MAX)'), + (KernRe(r'DECLARE_BITMAP\s*\(' + struct_args_pattern + r',\s*' + struct_args_pattern + r'\)', + re.S), r'unsigned long \1[BITS_TO_LONGS(\2)]'), + (KernRe(r'DECLARE_HASHTABLE\s*\(' + struct_args_pattern + r',\s*' + struct_args_pattern + r'\)', + re.S), r'unsigned long \1[1 << ((\2) - 1)]'), + (KernRe(r'DECLARE_KFIFO\s*\(' + struct_args_pattern + r',\s*' + struct_args_pattern + + r',\s*' + struct_args_pattern + r'\)', re.S), r'\2 *\1'), + (KernRe(r'DECLARE_KFIFO_PTR\s*\(' + struct_args_pattern + r',\s*' + + struct_args_pattern + r'\)', re.S), r'\2 *\1'), + (KernRe(r'(?:__)?DECLARE_FLEX_ARRAY\s*\(' + struct_args_pattern + r',\s*' + + struct_args_pattern + r'\)', re.S), r'\1 \2[]'), + (KernRe(r'DEFINE_DMA_UNMAP_ADDR\s*\(' + struct_args_pattern + r'\)', re.S), r'dma_addr_t \1'), + (KernRe(r'DEFINE_DMA_UNMAP_LEN\s*\(' + struct_args_pattern + r'\)', re.S), r'__u32 \1'), +] +# +# Regexes here are guaranteed to have the end delimiter matching +# the start delimiter. Yet, right now, only one replace group +# is allowed. +# +struct_nested_prefixes = [ + (re.compile(r'\bSTRUCT_GROUP\('), r'\1'), +] + +# +# Transforms for function prototypes +# +function_xforms = [ + (KernRe(r"^static +"), ""), + (KernRe(r"^extern +"), ""), + (KernRe(r"^asmlinkage +"), ""), + (KernRe(r"^inline +"), ""), + (KernRe(r"^__inline__ +"), ""), + (KernRe(r"^__inline +"), ""), + (KernRe(r"^__always_inline +"), ""), + (KernRe(r"^noinline +"), ""), + (KernRe(r"^__FORTIFY_INLINE +"), ""), + (KernRe(r"QEMU_[A-Z_]+ +"), ""), + (KernRe(r"__init +"), ""), + (KernRe(r"__init_or_module +"), ""), + (KernRe(r"__deprecated +"), ""), + (KernRe(r"__flatten +"), ""), + (KernRe(r"__meminit +"), ""), + (KernRe(r"__must_check +"), ""), + (KernRe(r"__weak +"), ""), + (KernRe(r"__sched +"), ""), + (KernRe(r"_noprof"), ""), + (KernRe(r"__always_unused *"), ""), + (KernRe(r"__printf\s*\(\s*\d*\s*,\s*\d*\s*\) +"), ""), + (KernRe(r"__(?:re)?alloc_size\s*\(\s*\d+\s*(?:,\s*\d+\s*)?\) +"), ""), + (KernRe(r"__diagnose_as\s*\(\s*\S+\s*(?:,\s*\d+\s*)*\) +"), ""), + (KernRe(r"DECL_BUCKET_PARAMS\s*\(\s*(\S+)\s*,\s*(\S+)\s*\)"), r"\1, \2"), + (KernRe(r"__attribute_const__ +"), ""), + (KernRe(r"__attribute__\s*\(\((?:[\w\s]+(?:\([^)]*\))?\s*,?)+\)\)\s+"), ""), +] + +# +# Apply a set of transforms to a block of text. +# +def apply_transforms(xforms, text): + for search, subst in xforms: + text = search.sub(subst, text) + return text + # # A little helper to get rid of excess white space # @@ -XXX,XX +XXX,XX @@ def trim_whitespace(s): return multi_space.sub(' ', s.strip()) +# +# Remove struct/enum members that have been marked "private". +# +def trim_private_members(text): + # + # First look for a "public:" block that ends a private region, then + # handle the "private until the end" case. + # + text = KernRe(r'/\*\s*private:.*?/\*\s*public:.*?\*/', flags=re.S).sub('', text) + text = KernRe(r'/\*\s*private:.*', flags=re.S).sub('', text) + # + # We needed the comments to do the above, but now we can take them out. + # + return KernRe(r'\s*/\*.*?\*/\s*', flags=re.S).sub('', text).strip() + class state: """ State machine enums @@ -XXX,XX +XXX,XX @@ class state: class KernelEntry: - def __init__(self, config, ln): + def __init__(self, config, fname, ln): self.config = config + self.fname = fname self._contents = [] self.prototype = "" @@ -XXX,XX +XXX,XX @@ def __init__(self, config, ln): self.leading_space = None + self.fname = fname + # State flags self.brcount = 0 self.declaration_start_line = ln + 1 @@ -XXX,XX +XXX,XX @@ def contents(self): return '\n'.join(self._contents) + '\n' # TODO: rename to emit_message after removal of kernel-doc.pl - def emit_msg(self, log_msg, warning=True): + def emit_msg(self, ln, msg, *, warning=True): """Emit a message""" + log_msg = f"{self.fname}:{ln} {msg}" + if not warning: self.config.log.info(log_msg) return @@ -XXX,XX +XXX,XX @@ def dump_section(self, start_new=True): # Only warn on user-specified duplicate section names if name != SECTION_DEFAULT: self.emit_msg(self.new_start_line, - f"duplicate section name '{name}'\n") + f"duplicate section name '{name}'") # Treat as a new paragraph - add a blank line self.sections[name] += '\n' + contents else: @@ -XXX,XX +XXX,XX @@ def dump_section(self, start_new=True): self.section = SECTION_DEFAULT self._contents = [] +python_warning = False class KernelDoc: """ @@ -XXX,XX +XXX,XX @@ def __init__(self, config, fname): # We need Python 3.7 for its "dicts remember the insertion # order" guarantee # - if sys.version_info.major == 3 and sys.version_info.minor < 7: + global python_warning + if (not python_warning and + sys.version_info.major == 3 and sys.version_info.minor < 7): + self.emit_msg(0, 'Python 3.7 or later is required for correct results') + python_warning = True - def emit_msg(self, ln, msg, warning=True): + def emit_msg(self, ln, msg, *, warning=True): """Emit a message""" - log_msg = f"{self.fname}:{ln} {msg}" - if self.entry: - self.entry.emit_msg(log_msg, warning) + self.entry.emit_msg(ln, msg, warning=warning) return + log_msg = f"{self.fname}:{ln} {msg}" + if warning: self.config.log.warning(log_msg) else: @@ -XXX,XX +XXX,XX @@ def output_declaration(self, dtype, name, **args): The actual output and output filters will be handled elsewhere """ - item = KdocItem(name, dtype, self.entry.declaration_start_line, **args) + item = KdocItem(name, self.fname, dtype, + self.entry.declaration_start_line, **args) item.warnings = self.entry.warnings # Drop empty sections @@ -XXX,XX +XXX,XX @@ def reset_state(self, ln): variables used by the state machine. """ - self.entry = KernelEntry(self.config, ln) + # + # Flush the warnings out before we proceed further + # + if self.entry and self.entry not in self.entries: + for log_msg in self.entry.warnings: + self.config.log.warning(log_msg) + + self.entry = KernelEntry(self.config, self.fname, ln) # State flags self.state = state.NORMAL @@ -XXX,XX +XXX,XX @@ def push_parameter(self, ln, decl_type, param, dtype, param = KernRe(r'[\[\)].*').sub('', param, count=1) - if dtype == "" and param.endswith("..."): - if KernRe(r'\w\.\.\.$').search(param): - # For named variable parameters of the form `x...`, - # remove the dots - param = param[:-3] - else: - # Handles unnamed variable parameters - param = "..." - - if param not in self.entry.parameterdescs or \ - not self.entry.parameterdescs[param]: - - self.entry.parameterdescs[param] = "variable arguments" - - elif dtype == "" and (not param or param == "void"): - param = "void" - self.entry.parameterdescs[param] = "no arguments" - - elif dtype == "" and param in ["struct", "union"]: - # Handle unnamed (anonymous) union or struct - dtype = param - param = "{unnamed_" + param + "}" - self.entry.parameterdescs[param] = "anonymous\n" - self.entry.anon_struct_union = True - - # Handle cache group enforcing variables: they do not need - # to be described in header files - elif "__cacheline_group" in param: - # Ignore __cacheline_group_begin and __cacheline_group_end - return + # + # Look at various "anonymous type" cases. + # + if dtype == '': + if param.endswith("..."): + if len(param) > 3: # there is a name provided, use that + param = param[:-3] + if not self.entry.parameterdescs.get(param): + self.entry.parameterdescs[param] = "variable arguments" + + elif (not param) or param == "void": + param = "void" + self.entry.parameterdescs[param] = "no arguments" + + elif param in ["struct", "union"]: + # Handle unnamed (anonymous) union or struct + dtype = param + param = "{unnamed_" + param + "}" + self.entry.parameterdescs[param] = "anonymous\n" + self.entry.anon_struct_union = True # Warn if parameter has no description # (but ignore ones starting with # as these are not parameters @@ -XXX,XX +XXX,XX @@ def create_parameter_list(self, ln, decl_type, args, args = arg_expr.sub(r"\1#", args) for arg in args.split(splitter): - # Strip comments - arg = KernRe(r'\/\*.*\*\/').sub('', arg) - # Ignore argument attributes arg = KernRe(r'\sPOS0?\s').sub(' ', arg) @@ -XXX,XX +XXX,XX @@ def create_parameter_list(self, ln, decl_type, args, # Treat preprocessor directive as a typeless variable self.push_parameter(ln, decl_type, arg, "", "", declaration_name) - + # + # The pointer-to-function case. + # elif KernRe(r'\(.+\)\s*\(').search(arg): - # Pointer-to-function - arg = arg.replace('#', ',') - - r = KernRe(r'[^\(]+\(\*?\s*([\w\[\]\.]*)\s*\)') + r = KernRe(r'[^\(]+\(\*?\s*' # Everything up to "(*" + r'([\w\[\].]*)' # Capture the name and possible [array] + r'\s*\)') # Make sure the trailing ")" is there if r.match(arg): param = r.group(1) else: self.emit_msg(ln, f"Invalid param: {arg}") param = arg - - dtype = KernRe(r'([^\(]+\(\*?)\s*' + re.escape(param)).sub(r'\1', arg) - self.push_parameter(ln, decl_type, param, dtype, - arg, declaration_name) - + dtype = arg.replace(param, '') + self.push_parameter(ln, decl_type, param, dtype, arg, declaration_name) + # + # The array-of-pointers case. Dig the parameter name out from the middle + # of the declaration. + # elif KernRe(r'\(.+\)\s*\[').search(arg): - # Array-of-pointers - - arg = arg.replace('#', ',') - r = KernRe(r'[^\(]+\(\s*\*\s*([\w\[\]\.]*?)\s*(\s*\[\s*[\w]+\s*\]\s*)*\)') + r = KernRe(r'[^\(]+\(\s*\*\s*' # Up to "(" and maybe "*" + r'([\w.]*?)' # The actual pointer name + r'\s*(\[\s*\w+\s*\]\s*)*\)') # The [array portion] if r.match(arg): param = r.group(1) else: self.emit_msg(ln, f"Invalid param: {arg}") param = arg - - dtype = KernRe(r'([^\(]+\(\*?)\s*' + re.escape(param)).sub(r'\1', arg) - - self.push_parameter(ln, decl_type, param, dtype, - arg, declaration_name) - + dtype = arg.replace(param, '') + self.push_parameter(ln, decl_type, param, dtype, arg, declaration_name) elif arg: + # + # Clean up extraneous spaces and split the string at commas; the first + # element of the resulting list will also include the type information. + # arg = KernRe(r'\s*:\s*').sub(":", arg) arg = KernRe(r'\s*\[').sub('[', arg) - args = KernRe(r'\s*,\s*').split(arg) - if args[0] and '*' in args[0]: - args[0] = re.sub(r'(\*+)\s*', r' \1', args[0]) - - first_arg = [] - r = KernRe(r'^(.*\s+)(.*?\[.*\].*)$') - if args[0] and r.match(args[0]): - args.pop(0) - first_arg.extend(r.group(1)) - first_arg.append(r.group(2)) + args[0] = re.sub(r'(\*+)\s*', r' \1', args[0]) + # + # args[0] has a string of "type a". If "a" includes an [array] + # declaration, we want to not be fooled by any white space inside + # the brackets, so detect and handle that case specially. + # + r = KernRe(r'^([^[\]]*\s+)(.*)$') + if r.match(args[0]): + args[0] = r.group(2) + dtype = r.group(1) else: - first_arg = KernRe(r'\s+').split(args.pop(0)) - - args.insert(0, first_arg.pop()) - dtype = ' '.join(first_arg) + # No space in args[0]; this seems wrong but preserves previous behavior + dtype = '' + bitfield_re = KernRe(r'(.*?):(\w+)') for param in args: - if KernRe(r'^(\*+)\s*(.*)').match(param): - r = KernRe(r'^(\*+)\s*(.*)') - if not r.match(param): - self.emit_msg(ln, f"Invalid param: {param}") - continue - - param = r.group(1) - + # + # For pointers, shift the star(s) from the variable name to the + # type declaration. + # + r = KernRe(r'^(\*+)\s*(.*)') + if r.match(param): self.push_parameter(ln, decl_type, r.group(2), f"{dtype} {r.group(1)}", arg, declaration_name) - - elif KernRe(r'(.*?):(\w+)').search(param): - r = KernRe(r'(.*?):(\w+)') - if not r.match(param): - self.emit_msg(ln, f"Invalid param: {param}") - continue - + # + # Perform a similar shift for bitfields. + # + elif bitfield_re.search(param): if dtype != "": # Skip unnamed bit-fields - self.push_parameter(ln, decl_type, r.group(1), - f"{dtype}:{r.group(2)}", + self.push_parameter(ln, decl_type, bitfield_re.group(1), + f"{dtype}:{bitfield_re.group(2)}", arg, declaration_name) else: self.push_parameter(ln, decl_type, param, dtype, @@ -XXX,XX +XXX,XX @@ def check_return_section(self, ln, declaration_name, return_type): self.emit_msg(ln, f"No description found for return value of '{declaration_name}'") - def dump_struct(self, ln, proto): - """ - Store an entry for an struct or union - """ - + # + # Split apart a structure prototype; returns (struct|union, name, members) or None + # + def split_struct_proto(self, proto): type_pattern = r'(struct|union)' - qualifiers = [ "__attribute__", "__packed", @@ -XXX,XX +XXX,XX @@ def dump_struct(self, ln, proto): "____cacheline_aligned_in_smp", "____cacheline_aligned", ] - definition_body = r'\{(.*)\}\s*' + "(?:" + '|'.join(qualifiers) + ")?" - struct_members = KernRe(type_pattern + r'([^\{\};]+)(\{)([^\{\}]*)(\})([^\{\}\;]*)(\;)') - - # Extract struct/union definition - members = None - declaration_name = None - decl_type = None r = KernRe(type_pattern + r'\s+(\w+)\s*' + definition_body) if r.search(proto): - decl_type = r.group(1) - declaration_name = r.group(2) - members = r.group(3) + return (r.group(1), r.group(2), r.group(3)) else: r = KernRe(r'typedef\s+' + type_pattern + r'\s*' + definition_body + r'\s*(\w+)\s*;') - if r.search(proto): - decl_type = r.group(1) - declaration_name = r.group(3) - members = r.group(2) - - if not members: - self.emit_msg(ln, f"{proto} error: Cannot parse struct or union!") - return - - if self.entry.identifier != declaration_name: - self.emit_msg(ln, - f"expecting prototype for {decl_type} {self.entry.identifier}. Prototype was for {decl_type} {declaration_name} instead\n") - return - - args_pattern = r'([^,)]+)' - - sub_prefixes = [ - (KernRe(r'\/\*\s*private:.*?\/\*\s*public:.*?\*\/', re.S | re.I), ''), - (KernRe(r'\/\*\s*private:.*', re.S | re.I), ''), - - # Strip comments - (KernRe(r'\/\*.*?\*\/', re.S), ''), - - # Strip attributes - (attribute, ' '), - (KernRe(r'\s*__aligned\s*\([^;]*\)', re.S), ' '), - (KernRe(r'\s*__counted_by\s*\([^;]*\)', re.S), ' '), - (KernRe(r'\s*__counted_by_(le|be)\s*\([^;]*\)', re.S), ' '), - (KernRe(r'\s*__packed\s*', re.S), ' '), - (KernRe(r'\s*CRYPTO_MINALIGN_ATTR', re.S), ' '), - (KernRe(r'\s*____cacheline_aligned_in_smp', re.S), ' '), - (KernRe(r'\s*____cacheline_aligned', re.S), ' '), - - # Unwrap struct_group macros based on this definition: - # __struct_group(TAG, NAME, ATTRS, MEMBERS...) - # which has variants like: struct_group(NAME, MEMBERS...) - # Only MEMBERS arguments require documentation. - # - # Parsing them happens on two steps: - # - # 1. drop struct group arguments that aren't at MEMBERS, - # storing them as STRUCT_GROUP(MEMBERS) - # - # 2. remove STRUCT_GROUP() ancillary macro. - # - # The original logic used to remove STRUCT_GROUP() using an - # advanced regex: - # - # \bSTRUCT_GROUP(\(((?:(?>[^)(]+)|(?1))*)\))[^;]*; - # - # with two patterns that are incompatible with - # Python re module, as it has: - # - # - a recursive pattern: (?1) - # - an atomic grouping: (?>...) - # - # I tried a simpler version: but it didn't work either: - # \bSTRUCT_GROUP\(([^\)]+)\)[^;]*; - # - # As it doesn't properly match the end parenthesis on some cases. - # - # So, a better solution was crafted: there's now a NestedMatch - # class that ensures that delimiters after a search are properly - # matched. So, the implementation to drop STRUCT_GROUP() will be - # handled in separate. - - (KernRe(r'\bstruct_group\s*\(([^,]*,)', re.S), r'STRUCT_GROUP('), - (KernRe(r'\bstruct_group_attr\s*\(([^,]*,){2}', re.S), r'STRUCT_GROUP('), - (KernRe(r'\bstruct_group_tagged\s*\(([^,]*),([^,]*),', re.S), r'struct \1 \2; STRUCT_GROUP('), - (KernRe(r'\b__struct_group\s*\(([^,]*,){3}', re.S), r'STRUCT_GROUP('), - - # Replace macros - # - # TODO: use NestedMatch for FOO($1, $2, ...) matches - # - # it is better to also move those to the NestedMatch logic, - # to ensure that parenthesis will be properly matched. - - (KernRe(r'__ETHTOOL_DECLARE_LINK_MODE_MASK\s*\(([^\)]+)\)', re.S), r'DECLARE_BITMAP(\1, __ETHTOOL_LINK_MODE_MASK_NBITS)'), - (KernRe(r'DECLARE_PHY_INTERFACE_MASK\s*\(([^\)]+)\)', re.S), r'DECLARE_BITMAP(\1, PHY_INTERFACE_MODE_MAX)'), - (KernRe(r'DECLARE_BITMAP\s*\(' + args_pattern + r',\s*' + args_pattern + r'\)', re.S), r'unsigned long \1[BITS_TO_LONGS(\2)]'), - (KernRe(r'DECLARE_HASHTABLE\s*\(' + args_pattern + r',\s*' + args_pattern + r'\)', re.S), r'unsigned long \1[1 << ((\2) - 1)]'), - (KernRe(r'DECLARE_KFIFO\s*\(' + args_pattern + r',\s*' + args_pattern + r',\s*' + args_pattern + r'\)', re.S), r'\2 *\1'), - (KernRe(r'DECLARE_KFIFO_PTR\s*\(' + args_pattern + r',\s*' + args_pattern + r'\)', re.S), r'\2 *\1'), - (KernRe(r'(?:__)?DECLARE_FLEX_ARRAY\s*\(' + args_pattern + r',\s*' + args_pattern + r'\)', re.S), r'\1 \2[]'), - (KernRe(r'DEFINE_DMA_UNMAP_ADDR\s*\(' + args_pattern + r'\)', re.S), r'dma_addr_t \1'), - (KernRe(r'DEFINE_DMA_UNMAP_LEN\s*\(' + args_pattern + r'\)', re.S), r'__u32 \1'), - (KernRe(r'VIRTIO_DECLARE_FEATURES\s*\(' + args_pattern + r'\)', re.S), r'u64 \1; u64 \1_array[VIRTIO_FEATURES_DWORDS]'), - ] - - # Regexes here are guaranteed to have the end limiter matching - # the start delimiter. Yet, right now, only one replace group - # is allowed. - - sub_nested_prefixes = [ - (re.compile(r'\bSTRUCT_GROUP\('), r'\1'), - ] - - for search, sub in sub_prefixes: - members = search.sub(sub, members) - - nested = NestedMatch() - - for search, sub in sub_nested_prefixes: - members = nested.sub(search, sub, members) - - # Keeps the original declaration as-is - declaration = members - - # Split nested struct/union elements - # - # This loop was simpler at the original kernel-doc perl version, as - # while ($members =~ m/$struct_members/) { ... } - # reads 'members' string on each interaction. - # - # Python behavior is different: it parses 'members' only once, - # creating a list of tuples from the first interaction. + return (r.group(1), r.group(3), r.group(2)) + return None + # + # Rewrite the members of a structure or union for easier formatting later on. + # Among other things, this function will turn a member like: + # + # struct { inner_members; } foo; + # + # into: + # + # struct foo; inner_members; + # + def rewrite_struct_members(self, members): # - # On other words, this won't get nested structs. + # Process struct/union members from the most deeply nested outward. The + # trick is in the ^{ below - it prevents a match of an outer struct/union + # until the inner one has been munged (removing the "{" in the process). # - # So, we need to have an extra loop on Python to override such - # re limitation. - - while True: - tuples = struct_members.findall(members) - if not tuples: - break - + struct_members = KernRe(r'(struct|union)' # 0: declaration type + r'([^\{\};]+)' # 1: possible name + r'(\{)' + r'([^\{\}]*)' # 3: Contents of declaration + r'(\})' + r'([^\{\};]*)(;)') # 5: Remaining stuff after declaration + tuples = struct_members.findall(members) + while tuples: for t in tuples: newmember = "" - maintype = t[0] - s_ids = t[5] - content = t[3] - - oldmember = "".join(t) - - for s_id in s_ids.split(','): + oldmember = "".join(t) # Reconstruct the original formatting + dtype, name, lbr, content, rbr, rest, semi = t + # + # Pass through each field name, normalizing the form and formatting. + # + for s_id in rest.split(','): s_id = s_id.strip() - - newmember += f"{maintype} {s_id}; " + newmember += f"{dtype} {s_id}; " + # + # Remove bitfield/array/pointer info, getting the bare name. + # s_id = KernRe(r'[:\[].*').sub('', s_id) s_id = KernRe(r'^\s*\**(\S+)\s*').sub(r'\1', s_id) - + # + # Pass through the members of this inner structure/union. + # for arg in content.split(';'): arg = arg.strip() - - if not arg: - continue - - r = KernRe(r'^([^\(]+\(\*?\s*)([\w\.]*)(\s*\).*)') + # + # Look for (type)(*name)(args) - pointer to function + # + r = KernRe(r'^([^\(]+\(\*?\s*)([\w.]*)(\s*\).*)') if r.match(arg): + dtype, name, extra = r.group(1), r.group(2), r.group(3) # Pointer-to-function - dtype = r.group(1) - name = r.group(2) - extra = r.group(3) - - if not name: - continue - if not s_id: # Anonymous struct/union newmember += f"{dtype}{name}{extra}; " else: newmember += f"{dtype}{s_id}.{name}{extra}; " - + # + # Otherwise a non-function member. + # else: - arg = arg.strip() - # Handle bitmaps + # + # Remove bitmap and array portions and spaces around commas + # arg = KernRe(r':\s*\d+\s*').sub('', arg) - - # Handle arrays arg = KernRe(r'\[.*\]').sub('', arg) - - # Handle multiple IDs arg = KernRe(r'\s*,\s*').sub(',', arg) - + # + # Look for a normal decl - "type name[,name...]" + # r = KernRe(r'(.*)\s+([\S+,]+)') - if r.search(arg): - dtype = r.group(1) - names = r.group(2) + for name in r.group(2).split(','): + name = KernRe(r'^\s*\**(\S+)\s*').sub(r'\1', name) + if not s_id: + # Anonymous struct/union + newmember += f"{r.group(1)} {name}; " + else: + newmember += f"{r.group(1)} {s_id}.{name}; " else: newmember += f"{arg}; " - continue - - for name in names.split(','): - name = KernRe(r'^\s*\**(\S+)\s*').sub(r'\1', name).strip() - - if not name: - continue - - if not s_id: - # Anonymous struct/union - newmember += f"{dtype} {name}; " - else: - newmember += f"{dtype} {s_id}.{name}; " - + # + # At the end of the s_id loop, replace the original declaration with + # the munged version. + # members = members.replace(oldmember, newmember) + # + # End of the tuple loop - search again and see if there are outer members + # that now turn up. + # + tuples = struct_members.findall(members) + return members - # Ignore other nested elements, like enums - members = re.sub(r'(\{[^\{\}]*\})', '', members) - - self.create_parameter_list(ln, decl_type, members, ';', - declaration_name) - self.check_sections(ln, declaration_name, decl_type) - - # Adjust declaration for better display + # + # Format the struct declaration into a standard form for inclusion in the + # resulting docs. + # + def format_struct_decl(self, declaration): + # + # Insert newlines, get rid of extra spaces. + # declaration = KernRe(r'([\{;])').sub(r'\1\n', declaration) declaration = KernRe(r'\}\s+;').sub('};', declaration) - - # Better handle inlined enums - while True: - r = KernRe(r'(enum\s+\{[^\}]+),([^\n])') - if not r.search(declaration): - break - + # + # Format inline enums with each member on its own line. + # + r = KernRe(r'(enum\s+\{[^\}]+),([^\n])') + while r.search(declaration): declaration = r.sub(r'\1,\n\2', declaration) - + # + # Now go through and supply the right number of tabs + # for each line. + # def_args = declaration.split('\n') level = 1 declaration = "" for clause in def_args: + clause = KernRe(r'\s+').sub(' ', clause.strip(), count=1) + if clause: + if '}' in clause and level > 1: + level -= 1 + if not clause.startswith('#'): + declaration += "\t" * level + declaration += "\t" + clause + "\n" + if "{" in clause and "}" not in clause: + level += 1 + return declaration - clause = clause.strip() - clause = KernRe(r'\s+').sub(' ', clause, count=1) - - if not clause: - continue - - if '}' in clause and level > 1: - level -= 1 - if not KernRe(r'^\s*#').match(clause): - declaration += "\t" * level + def dump_struct(self, ln, proto): + """ + Store an entry for a struct or union + """ + # + # Do the basic parse to get the pieces of the declaration. + # + struct_parts = self.split_struct_proto(proto) + if not struct_parts: + self.emit_msg(ln, f"{proto} error: Cannot parse struct or union!") + return + decl_type, declaration_name, members = struct_parts - declaration += "\t" + clause + "\n" - if "{" in clause and "}" not in clause: - level += 1 + if self.entry.identifier != declaration_name: + self.emit_msg(ln, f"expecting prototype for {decl_type} {self.entry.identifier}. " + f"Prototype was for {decl_type} {declaration_name} instead\n") + return + # + # Go through the list of members applying all of our transformations. + # + members = trim_private_members(members) + members = apply_transforms(struct_xforms, members) + nested = NestedMatch() + for search, sub in struct_nested_prefixes: + members = nested.sub(search, sub, members) + # + # Deal with embedded struct and union members, and drop enums entirely. + # + declaration = members + members = self.rewrite_struct_members(members) + members = re.sub(r'(\{[^\{\}]*\})', '', members) + # + # Output the result and we are done. + # + self.create_parameter_list(ln, decl_type, members, ';', + declaration_name) + self.check_sections(ln, declaration_name, decl_type) self.output_declaration(decl_type, declaration_name, - definition=declaration, + definition=self.format_struct_decl(declaration), purpose=self.entry.declaration_purpose) def dump_enum(self, ln, proto): """ Stores an enum inside self.entries array. """ - - # Ignore members marked private - proto = KernRe(r'\/\*\s*private:.*?\/\*\s*public:.*?\*\/', flags=re.S).sub('', proto) - proto = KernRe(r'\/\*\s*private:.*}', flags=re.S).sub('}', proto) - - # Strip comments - proto = KernRe(r'\/\*.*?\*\/', flags=re.S).sub('', proto) - - # Strip #define macros inside enums + # + # Strip preprocessor directives. Note that this depends on the + # trailing semicolon we added in process_proto_type(). + # proto = KernRe(r'#\s*((define|ifdef|if)\s+|endif)[^;]*;', flags=re.S).sub('', proto) - # # Parse out the name and members of the enum. Typedef form first. # r = KernRe(r'typedef\s+enum\s*\{(.*)\}\s*(\w*)\s*;') if r.search(proto): declaration_name = r.group(2) - members = r.group(1).rstrip() + members = trim_private_members(r.group(1)) # # Failing that, look for a straight enum # @@ -XXX,XX +XXX,XX @@ def dump_enum(self, ln, proto): r = KernRe(r'enum\s+(\w*)\s*\{(.*)\}') if r.match(proto): declaration_name = r.group(1) - members = r.group(2).rstrip() + members = trim_private_members(r.group(2)) # # OK, this isn't going to work. # @@ -XXX,XX +XXX,XX @@ def dump_enum(self, ln, proto): for k in self.entry.parameterdescs: if k not in member_set: self.emit_msg(ln, - f"Excess enum value '%{k}' description in '{declaration_name}'") + f"Excess enum value '@{k}' description in '{declaration_name}'") self.output_declaration('enum', declaration_name, purpose=self.entry.declaration_purpose) @@ -XXX,XX +XXX,XX @@ def dump_declaration(self, ln, prototype): def dump_function(self, ln, prototype): """ - Stores a function of function macro inside self.entries array. + Stores a function or function macro inside self.entries array. """ - func_macro = False + found = func_macro = False return_type = '' decl_type = 'function' - - # Prefixes that would be removed - sub_prefixes = [ - (r"^static +", "", 0), - (r"^extern +", "", 0), - (r"^asmlinkage +", "", 0), - (r"^inline +", "", 0), - (r"^__inline__ +", "", 0), - (r"^__inline +", "", 0), - (r"^__always_inline +", "", 0), - (r"^noinline +", "", 0), - (r"^__FORTIFY_INLINE +", "", 0), - (r"QEMU_[A-Z_]+ +", "", 0), - (r"__init +", "", 0), - (r"__init_or_module +", "", 0), - (r"__deprecated +", "", 0), - (r"__flatten +", "", 0), - (r"__meminit +", "", 0), - (r"__must_check +", "", 0), - (r"__weak +", "", 0), - (r"__sched +", "", 0), - (r"_noprof", "", 0), - (r"__printf\s*\(\s*\d*\s*,\s*\d*\s*\) +", "", 0), - (r"__(?:re)?alloc_size\s*\(\s*\d+\s*(?:,\s*\d+\s*)?\) +", "", 0), - (r"__diagnose_as\s*\(\s*\S+\s*(?:,\s*\d+\s*)*\) +", "", 0), - (r"DECL_BUCKET_PARAMS\s*\(\s*(\S+)\s*,\s*(\S+)\s*\)", r"\1, \2", 0), - (r"__attribute_const__ +", "", 0), - - # It seems that Python support for re.X is broken: - # At least for me (Python 3.13), this didn't work -# (r""" -# __attribute__\s*\(\( -# (?: -# [\w\s]+ # attribute name -# (?:\([^)]*\))? # attribute arguments -# \s*,? # optional comma at the end -# )+ -# \)\)\s+ -# """, "", re.X), - - # So, remove whitespaces and comments from it - (r"__attribute__\s*\(\((?:[\w\s]+(?:\([^)]*\))?\s*,?)+\)\)\s+", "", 0), - ] - - for search, sub, flags in sub_prefixes: - prototype = KernRe(search, flags).sub(sub, prototype) - - # Macros are a special case, as they change the prototype format + # + # Apply the initial transformations. + # + prototype = apply_transforms(function_xforms, prototype) + # + # If we have a macro, remove the "#define" at the front. + # new_proto = KernRe(r"^#\s*define\s+").sub("", prototype) if new_proto != prototype: - is_define_proto = True prototype = new_proto - else: - is_define_proto = False + # + # Dispense with the simple "#define A B" case here; the key + # is the space after the name of the symbol being defined. + # NOTE that the seemingly misnamed "func_macro" indicates a + # macro *without* arguments. + # + r = KernRe(r'^(\w+)\s+') + if r.search(prototype): + return_type = '' + declaration_name = r.group(1) + func_macro = True + found = True # Yes, this truly is vile. We are looking for: # 1. Return type (may be nothing if we're looking at a macro) @@ -XXX,XX +XXX,XX @@ def dump_function(self, ln, prototype): # - atomic_set (macro) # - pci_match_device, __copy_to_user (long return type) - name = r'[a-zA-Z0-9_~:]+' - prototype_end1 = r'[^\(]*' - prototype_end2 = r'[^\{]*' - prototype_end = fr'\(({prototype_end1}|{prototype_end2})\)' - - # Besides compiling, Perl qr{[\w\s]+} works as a non-capturing group. - # So, this needs to be mapped in Python with (?:...)? or (?:...)+ - + name = r'\w+' type1 = r'(?:[\w\s]+)?' type2 = r'(?:[\w\s]+\*+)+' - - found = False - - if is_define_proto: - r = KernRe(r'^()(' + name + r')\s+') - - if r.search(prototype): - return_type = '' - declaration_name = r.group(2) - func_macro = True - - found = True - + # + # Attempt to match first on (args) with no internal parentheses; this + # lets us easily filter out __acquires() and other post-args stuff. If + # that fails, just grab the rest of the line to the last closing + # parenthesis. + # + proto_args = r'\(([^\(]*|.*)\)' + # + # (Except for the simple macro case) attempt to split up the prototype + # in the various ways we understand. + # if not found: patterns = [ - rf'^()({name})\s*{prototype_end}', - rf'^({type1})\s+({name})\s*{prototype_end}', - rf'^({type2})\s*({name})\s*{prototype_end}', + rf'^()({name})\s*{proto_args}', + rf'^({type1})\s+({name})\s*{proto_args}', + rf'^({type2})\s*({name})\s*{proto_args}', ] for p in patterns: r = KernRe(p) - if r.match(prototype): - return_type = r.group(1) declaration_name = r.group(2) args = r.group(3) - self.create_parameter_list(ln, decl_type, args, ',', declaration_name) - found = True break + # + # Parsing done; make sure that things are as we expect. + # if not found: self.emit_msg(ln, f"cannot understand function prototype: '{prototype}'") return - if self.entry.identifier != declaration_name: - self.emit_msg(ln, - f"expecting prototype for {self.entry.identifier}(). Prototype was for {declaration_name}() instead") + self.emit_msg(ln, f"expecting prototype for {self.entry.identifier}(). " + f"Prototype was for {declaration_name}() instead") return - self.check_sections(ln, declaration_name, "function") - self.check_return_section(ln, declaration_name, return_type) + # + # Store the result. + # + self.output_declaration(decl_type, declaration_name, + typedef=('typedef' in return_type), + functiontype=return_type, + purpose=self.entry.declaration_purpose, + func_macro=func_macro) - if 'typedef' in return_type: - self.output_declaration(decl_type, declaration_name, - typedef=True, - functiontype=return_type, - purpose=self.entry.declaration_purpose, - func_macro=func_macro) - else: - self.output_declaration(decl_type, declaration_name, - typedef=False, - functiontype=return_type, - purpose=self.entry.declaration_purpose, - func_macro=func_macro) def dump_typedef(self, ln, proto): """ Stores a typedef inside self.entries array. """ - - typedef_type = r'((?:\s+[\w\*]+\b){0,7}\s+(?:\w+\b|\*+))\s*' + # + # We start by looking for function typedefs. + # + typedef_type = r'typedef((?:\s+[\w*]+\b){0,7}\s+(?:\w+\b|\*+))\s*' typedef_ident = r'\*?\s*(\w\S+)\s*' typedef_args = r'\s*\((.*)\);' - typedef1 = KernRe(r'typedef' + typedef_type + r'\(' + typedef_ident + r'\)' + typedef_args) - typedef2 = KernRe(r'typedef' + typedef_type + typedef_ident + typedef_args) - - # Strip comments - proto = KernRe(r'/\*.*?\*/', flags=re.S).sub('', proto) + typedef1 = KernRe(typedef_type + r'\(' + typedef_ident + r'\)' + typedef_args) + typedef2 = KernRe(typedef_type + typedef_ident + typedef_args) # Parse function typedef prototypes for r in [typedef1, typedef2]: @@ -XXX,XX +XXX,XX @@ def dump_typedef(self, ln, proto): f"expecting prototype for typedef {self.entry.identifier}. Prototype was for typedef {declaration_name} instead\n") return - decl_type = 'function' - self.create_parameter_list(ln, decl_type, args, ',', declaration_name) + self.create_parameter_list(ln, 'function', args, ',', declaration_name) - self.output_declaration(decl_type, declaration_name, + self.output_declaration('function', declaration_name, typedef=True, functiontype=return_type, purpose=self.entry.declaration_purpose) return - - # Handle nested parentheses or brackets - r = KernRe(r'(\(*.\)\s*|\[*.\]\s*);$') - while r.search(proto): - proto = r.sub('', proto) - - # Parse simple typedefs + # + # Not a function, try to parse a simple typedef. + # r = KernRe(r'typedef.*\s+(\w+)\s*;') if r.match(proto): declaration_name = r.group(1) @@ -XXX,XX +XXX,XX @@ def process_name(self, ln, line): # else: self.emit_msg(ln, - f"This comment starts with '/**', but isn't a kernel-doc comment. Refer Documentation/doc-guide/kernel-doc.rst\n{line}") + f"This comment starts with '/**', but isn't a kernel-doc comment. Refer to Documentation/doc-guide/kernel-doc.rst\n{line}") self.state = state.NORMAL return # @@ -XXX,XX +XXX,XX @@ def is_comment_end(self, ln, line): self.dump_section() # Look for doc_com + <text> + doc_end: - r = KernRe(r'\s*\*\s*[a-zA-Z_0-9:\.]+\*/') + r = KernRe(r'\s*\*\s*[a-zA-Z_0-9:.]+\*/') if r.match(line): self.emit_msg(ln, f"suspicious ending line: {line}") @@ -XXX,XX +XXX,XX @@ def process_proto_function(self, ln, line): """Ancillary routine to process a function prototype""" # strip C99-style comments to end of line - line = KernRe(r"\/\/.*$", re.S).sub('', line) + line = KernRe(r"//.*$", re.S).sub('', line) # # Soak up the line's worth of prototype text, stopping at { or ; if present. # diff --git a/scripts/lib/kdoc/kdoc_re.py b/scripts/lib/kdoc/kdoc_re.py index XXXXXXX..XXXXXXX 100644 --- a/scripts/lib/kdoc/kdoc_re.py +++ b/scripts/lib/kdoc/kdoc_re.py @@ -XXX,XX +XXX,XX @@ class KernRe: """ - Helper class to simplify regex declaration and usage, + Helper class to simplify regex declaration and usage. It calls re.compile for a given pattern. It also allows adding regular expressions and define sub at class init time. @@ -XXX,XX +XXX,XX @@ class KernRe: def _add_regex(self, string, flags): """ - Adds a new regex or re-use it from the cache. + Adds a new regex or reuses it from the cache. """ self.regex = re_cache.get(string, None) if not self.regex: @@ -XXX,XX +XXX,XX @@ class NestedMatch: '\\bSTRUCT_GROUP(\\(((?:(?>[^)(]+)|(?1))*)\\))[^;]*;' - which is used to properly match open/close parenthesis of the + which is used to properly match open/close parentheses of the string search STRUCT_GROUP(), Add a class that counts pairs of delimiters, using it to match and @@ -XXX,XX +XXX,XX @@ class NestedMatch: # \bSTRUCT_GROUP\( # # is similar to: STRUCT_GROUP\((.*)\) - # except that the content inside the match group is delimiter's aligned. + # except that the content inside the match group is delimiter-aligned. # - # The content inside parenthesis are converted into a single replace + # The content inside parentheses is converted into a single replace # group (e.g. r`\1'). # # It would be nice to change such definition to support multiple - # match groups, allowing a regex equivalent to. + # match groups, allowing a regex equivalent to: # # FOO\((.*), (.*), (.*)\) # @@ -XXX,XX +XXX,XX @@ def _search(self, regex, line): but I ended using a different implementation to align all three types of delimiters and seek for an initial regular expression. - The algorithm seeks for open/close paired delimiters and place them - into a stack, yielding a start/stop position of each match when the + The algorithm seeks for open/close paired delimiters and places them + into a stack, yielding a start/stop position of each match when the stack is zeroed. - The algorithm shoud work fine for properly paired lines, but will - silently ignore end delimiters that preceeds an start delimiter. + The algorithm should work fine for properly paired lines, but will + silently ignore end delimiters that precede a start delimiter. This should be OK for kernel-doc parser, as unaligned delimiters - would cause compilation errors. So, we don't need to rise exceptions + would cause compilation errors. So, we don't need to raise exceptions to cover such issues. """ @@ -XXX,XX +XXX,XX @@ def _search(self, regex, line): stack.append(end) continue - # Does the end delimiter match what it is expected? + # Does the end delimiter match what is expected? if stack and d == stack[-1]: stack.pop() -- 2.47.3
The company 'Arm' went through a rebranding many years back involving a recapitalization from 'ARM' to 'Arm'. As a result our documentation is a bit inconsistent between the two forms. It's not worth trying to update everywhere in QEMU, but it's easy enough to make docs/ consistent. We last did this in commit 6fe6d6c9a in 2020, but a few new uses of the wrong capitalization have crept back in since. As before, "ARMv8" and similar architecture names, and older CPU names like "ARM926" still retain all-caps. In a few places we make minor grammar fixups as we touch the sentences we're fixing. Signed-off-by: Peter Maydell <peter.maydell@linaro.org> Reviewed-by: Cédric Le Goater <clg@redhat.com> Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org> Message-id: 20260115150545.669444-1-peter.maydell@linaro.org --- docs/devel/testing/qgraph.rst | 8 ++++---- docs/devel/vfio-iommufd.rst | 2 +- docs/specs/fsi.rst | 2 +- docs/system/arm/aspeed.rst | 6 +++--- docs/system/arm/b-l475e-iot01a.rst | 2 +- docs/system/arm/nrf.rst | 4 ++-- docs/system/arm/stm32.rst | 12 ++++++------ docs/system/arm/xlnx-versal-virt.rst | 16 ++++++++-------- docs/system/guest-loader.rst | 2 +- docs/system/replay.rst | 2 +- 10 files changed, 28 insertions(+), 28 deletions(-) diff --git a/docs/devel/testing/qgraph.rst b/docs/devel/testing/qgraph.rst index XXXXXXX..XXXXXXX 100644 --- a/docs/devel/testing/qgraph.rst +++ b/docs/devel/testing/qgraph.rst @@ -XXX,XX +XXX,XX @@ take care of booting QEMU with the right machine and devices. This makes each test "hardcoded" for a specific configuration, reducing the possible coverage that it can reach. -For example, the sdhci device is supported on both x86_64 and ARM boards, +For example, the sdhci device is supported on both x86_64 and Arm boards, therefore a generic sdhci test should test all machines and drivers that support that device. Using only libqos APIs, the test has to manually take care of @@ -XXX,XX +XXX,XX @@ there. The ``arm/raspi2b`` machine node is listed as "UNAVAILABLE". Although it is reachable from the root via '' -> 'arm/raspi2b' the node is unavailable because the QEMU binary did not list it when queried by the framework. This is expected -because we used the ``qemu-system-x86_64`` binary which does not support ARM +because we used the ``qemu-system-x86_64`` binary which does not support Arm machine types. If a test is unexpectedly listed as "UNAVAILABLE", first check that the "ALL @@ -XXX,XX +XXX,XX @@ Here we continue the ``sdhci`` use case, with the following scenario: - ``sdhci-test`` aims to test the ``read[q,w], writeq`` functions offered by the ``sdhci`` drivers. -- The current ``sdhci`` device is supported by both ``x86_64/pc`` and ``ARM`` +- The current ``sdhci`` device is supported by both ``x86_64/pc`` and Arm (in this example we focus on the ``arm-raspi2b``) machines. -- QEMU offers 2 types of drivers: ``QSDHCI_MemoryMapped`` for ``ARM`` and +- QEMU offers 2 types of drivers: ``QSDHCI_MemoryMapped`` for Arm and ``QSDHCI_PCI`` for ``x86_64/pc``. Both implement the ``read[q,w], writeq`` functions. diff --git a/docs/devel/vfio-iommufd.rst b/docs/devel/vfio-iommufd.rst index XXXXXXX..XXXXXXX 100644 --- a/docs/devel/vfio-iommufd.rst +++ b/docs/devel/vfio-iommufd.rst @@ -XXX,XX +XXX,XX @@ container: Supported platform ================== -Supports x86, ARM and s390x currently. +Supports x86, Arm and s390x currently. Caveats ======= diff --git a/docs/specs/fsi.rst b/docs/specs/fsi.rst index XXXXXXX..XXXXXXX 100644 --- a/docs/specs/fsi.rst +++ b/docs/specs/fsi.rst @@ -XXX,XX +XXX,XX @@ for the implementation are: (see the `FSI specification`_ for more details) MMIO-mapping of the CFAM address straight onto a sub-region of the OPB address space. -5. An APB-to-OPB bridge enabling access to the OPB from the ARM core in the +5. An APB-to-OPB bridge enabling access to the OPB from the Arm core in the AST2600. Hardware limitations prevent the OPB from being directly mapped into APB, so all accesses are indirect through the bridge. diff --git a/docs/system/arm/aspeed.rst b/docs/system/arm/aspeed.rst index XXXXXXX..XXXXXXX 100644 --- a/docs/system/arm/aspeed.rst +++ b/docs/system/arm/aspeed.rst @@ -XXX,XX +XXX,XX @@ The QEMU Aspeed machines model BMCs of various OpenPOWER systems and Aspeed evaluation boards. They are based on different releases of the Aspeed SoC : the AST2400 integrating an ARM926EJ-S CPU (400MHz), the AST2500 with an ARM1176JZS CPU (800MHz), the AST2600 -with dual cores ARM Cortex-A7 CPUs (1.2GHz). +with dual cores Arm Cortex-A7 CPUs (1.2GHz). The SoC comes with RAM, Gigabit ethernet, USB, SD/MMC, USB, SPI, I2C, etc. @@ -XXX,XX +XXX,XX @@ Aspeed 2700 family boards (``ast2700-evb``, ``ast2700fc``) The QEMU Aspeed machines model BMCs of Aspeed evaluation boards. They are based on different releases of the Aspeed SoC : -the AST2700 with quad cores ARM Cortex-A35 64 bits CPUs (1.6GHz). +the AST2700 with quad cores Arm Cortex-A35 64 bits CPUs (1.6GHz). The SoC comes with RAM, Gigabit ethernet, USB, SD/MMC, USB, SPI, I2C, etc. @@ -XXX,XX +XXX,XX @@ Aspeed MiniBMC and Platform Root of Trust processor family boards (``ast1030-evb The QEMU Aspeed machines model mini BMCs and Platform Root of Trust processors of various Aspeed evaluation boards. They are based on different releases of the Aspeed SoC : the AST1030 (MiniBMC) -and AST1060 (Platform Root of Trust Processor), both integrating an ARM Cortex M4F CPU (200MHz). +and AST1060 (Platform Root of Trust Processor), both integrating an Arm Cortex M4F CPU (200MHz). The SoC comes with SRAM, SPI, I2C, etc. diff --git a/docs/system/arm/b-l475e-iot01a.rst b/docs/system/arm/b-l475e-iot01a.rst index XXXXXXX..XXXXXXX 100644 --- a/docs/system/arm/b-l475e-iot01a.rst +++ b/docs/system/arm/b-l475e-iot01a.rst @@ -XXX,XX +XXX,XX @@ B-L475E-IOT01A IoT Node (``b-l475e-iot01a``) ============================================ The B-L475E-IOT01A IoT Node uses the STM32L475VG SoC which is based on -ARM Cortex-M4F core. It is part of STMicroelectronics +an Arm Cortex-M4F core. It is part of STMicroelectronics :doc:`STM32 boards </system/arm/stm32>` and more specifically the STM32L4 ultra-low power series. The STM32L4x5 chip runs at up to 80 MHz and integrates 128 KiB of SRAM and up to 1MiB of Flash. The B-L475E-IOT01A board diff --git a/docs/system/arm/nrf.rst b/docs/system/arm/nrf.rst index XXXXXXX..XXXXXXX 100644 --- a/docs/system/arm/nrf.rst +++ b/docs/system/arm/nrf.rst @@ -XXX,XX +XXX,XX @@ Nordic nRF boards (``microbit``) ================================ -The `Nordic nRF`_ chips are a family of ARM-based System-on-Chip that +The `Nordic nRF`_ chips are a family of Arm-based System-on-Chip that are designed to be used for low-power and short-range wireless solutions. .. _Nordic nRF: https://www.nordicsemi.com/Products @@ -XXX,XX +XXX,XX @@ supported by QEMU. Supported devices ----------------- - * ARM Cortex-M0 (ARMv6-M) + * Arm Cortex-M0 (ARMv6-M) * Serial ports (UART) * Clock controller * Timers diff --git a/docs/system/arm/stm32.rst b/docs/system/arm/stm32.rst index XXXXXXX..XXXXXXX 100644 --- a/docs/system/arm/stm32.rst +++ b/docs/system/arm/stm32.rst @@ -XXX,XX +XXX,XX @@ STMicroelectronics STM32 boards (``netduino2``, ``netduinoplus2``, ``olimex-stm32-h405``, ``stm32vldiscovery``) =============================================================================================================== -The `STM32`_ chips are a family of 32-bit ARM-based microcontroller by +The `STM32`_ chips are a family of 32-bit Arm-based microcontrollers by STMicroelectronics. .. _STM32: https://www.st.com/en/microcontrollers-microprocessors/stm32-32-bit-arm-cortex-mcus.html -The STM32F1 series is based on ARM Cortex-M3 core. The following machines are +The STM32F1 series is based on an Arm Cortex-M3 core. The following machines are based on this chip : - ``stm32vldiscovery`` STM32VLDISCOVERY board with STM32F100RBT6 microcontroller -The STM32F2 series is based on ARM Cortex-M3 core. The following machines are +The STM32F2 series is based on an Arm Cortex-M3 core. The following machines are based on this chip : - ``netduino2`` Netduino 2 board with STM32F205RFT6 microcontroller -The STM32F4 series is based on ARM Cortex-M4F core, as well as the STM32L4 +The STM32F4 series is based on an Arm Cortex-M4F core, as well as the STM32L4 ultra-low-power series. The STM32F4 series is pin-to-pin compatible with STM32F2 series. -The following machines are based on this ARM Cortex-M4F chip : +The following machines are based on this Arm Cortex-M4F chip : - ``netduinoplus2`` Netduino Plus 2 board with STM32F405RGT6 microcontroller - ``olimex-stm32-h405`` Olimex STM32 H405 board with STM32F405RGT6 microcontroller @@ -XXX,XX +XXX,XX @@ There are many other STM32 series that are currently not supported by QEMU. Supported devices ----------------- - * ARM Cortex-M3, Cortex M4F + * Arm Cortex-M3, Cortex-M4F * Analog to Digital Converter (ADC) * EXTI interrupt * Serial ports (USART) diff --git a/docs/system/arm/xlnx-versal-virt.rst b/docs/system/arm/xlnx-versal-virt.rst index XXXXXXX..XXXXXXX 100644 --- a/docs/system/arm/xlnx-versal-virt.rst +++ b/docs/system/arm/xlnx-versal-virt.rst @@ -XXX,XX +XXX,XX @@ Versal """""" Implemented CPU cores: -- 2 ACPUs (ARM Cortex-A72) with their GICv3 and ITS -- 2 RCPUs (ARM Cortex-R5F) with their GICv2 +- 2 ACPUs (Arm Cortex-A72) with their GICv3 and ITS +- 2 RCPUs (Arm Cortex-R5F) with their GICv2 Implemented devices: -- 2 UARTs (ARM PL011) +- 2 UARTs (Arm PL011) - An RTC (Versal built-in) - 2 GEMs (Cadence MACB Ethernet MACs) - 8 ADMA (Xilinx zDMA) channels @@ -XXX,XX +XXX,XX @@ Versal Gen 2 """""""""""" Implemented CPU cores: -- 8 ACPUs (ARM Cortex-A78AE) with their GICv3 and ITS -- 10 RCPUs (ARM Cortex-R52) with their GICv3 (one per cluster) +- 8 ACPUs (Arm Cortex-A78AE) with their GICv3 and ITS +- 10 RCPUs (Arm Cortex-R52) with their GICv3 (one per cluster) Implemented devices: -- 2 UARTs (ARM PL011) +- 2 UARTs (Arm PL011) - An RTC (Versal built-in) - 3 GEMs (Cadence MACB Ethernet MACs) - 8 ADMA (Xilinx zDMA) channels @@ -XXX,XX +XXX,XX @@ Direct Linux boot of PetaLinux 2019.2: -device virtio-rng-device,bus=virtio-mmio-bus.0,rng=rng0 \ -object rng-random,filename=/dev/urandom,id=rng0 -Boot PetaLinux 2019.2 via ARM Trusted Firmware (2018.3 because the 2019.2 +Boot PetaLinux 2019.2 via Arm Trusted Firmware (2018.3 because the 2019.2 version of ATF tries to configure the CCI which we don't model) and U-boot: .. code-block:: bash @@ -XXX,XX +XXX,XX @@ Run the following at the U-Boot prompt: fdt set /chosen/dom0 reg <0x00000000 0x40000000 0x0 0x03100000> booti 30000000 - 20000000 -Boot Linux as Dom0 on Xen via ARM Trusted Firmware and U-Boot: +Boot Linux as Dom0 on Xen via Arm Trusted Firmware and U-Boot: .. code-block:: bash diff --git a/docs/system/guest-loader.rst b/docs/system/guest-loader.rst index XXXXXXX..XXXXXXX 100644 --- a/docs/system/guest-loader.rst +++ b/docs/system/guest-loader.rst @@ -XXX,XX +XXX,XX @@ size. Additional information can be passed with by using additional arguments. Currently the only supported machines which use FDT data to boot are -the ARM and RiscV ``virt`` machines. +the Arm and RiscV ``virt`` machines. Arguments ^^^^^^^^^ diff --git a/docs/system/replay.rst b/docs/system/replay.rst index XXXXXXX..XXXXXXX 100644 --- a/docs/system/replay.rst +++ b/docs/system/replay.rst @@ -XXX,XX +XXX,XX @@ Deterministic replay has the following features: the memory, state of the hardware devices, clocks, and screen of the VM. * Writes execution log into the file for later replaying for multiple times on different machines. - * Supports i386, x86_64, ARM, AArch64, Risc-V, MIPS, MIPS64, S390X, Alpha, + * Supports i386, x86_64, Arm, AArch64, Risc-V, MIPS, MIPS64, S390X, Alpha, PowerPC, PowerPC64, M68000, Microblaze, OpenRISC, SPARC, and Xtensa hardware platforms. * Performs deterministic replay of all operations with keyboard and mouse -- 2.47.3
Currently clean-includes supports two ways of specifying files to check: * --all to run on everything * specific files There's no way to say "check everything in target/arm". Add support for handling directory names, by always running the arguments through git ls-files. Signed-off-by: Peter Maydell <peter.maydell@linaro.org> Reviewed-by: Richard Henderson <richard.henderson@linaro.org> Message-id: 20260116124005.925382-2-peter.maydell@linaro.org --- scripts/clean-includes | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/scripts/clean-includes b/scripts/clean-includes index XXXXXXX..XXXXXXX 100755 --- a/scripts/clean-includes +++ b/scripts/clean-includes @@ -XXX,XX +XXX,XX @@ # the top-level directory. # Usage: -# clean-includes [--git subjectprefix] [--check-dup-head] file ... +# clean-includes [--git subjectprefix] [--check-dup-head] file-or-dir ... # or # clean-includes [--git subjectprefix] [--check-dup-head] --all # @@ -XXX,XX +XXX,XX @@ # # Using --all will cause clean-includes to run on the whole source # tree (excluding certain directories which are known not to need -# handling). +# handling). This is equivalent to passing '.' as the directory to +# scan. # This script requires Coccinelle to be installed. @@ -XXX,XX +XXX,XX @@ if [ $# -eq 0 ]; then exit 1 fi +# --all means "scan everything starting from the current directory" if [ "$1" = "--all" ]; then - # We assume there are no files in the tree with spaces in their name - set -- $(git ls-files '*.[ch]' | grep -E -v "$XDIRREGEX") + set -- '.' fi +# We assume there are no files in the tree with spaces in their name +set -- $(git ls-files "$@" | grep '\.[ch]$' | grep -E -v "$XDIRREGEX") + # Annoyingly coccinelle won't read a scriptfile unless its # name ends '.cocci', so write it out to a tempfile with the # right kind of name. -- 2.47.3
Remove an old comment suggesting a manual shell line to use to find files to run the script on. The script's exclude-list and its support for directory names make this irrelevant. Signed-off-by: Peter Maydell <peter.maydell@linaro.org> Reviewed-by: Richard Henderson <richard.henderson@linaro.org> Message-id: 20260116124005.925382-3-peter.maydell@linaro.org --- scripts/clean-includes | 9 --------- 1 file changed, 9 deletions(-) diff --git a/scripts/clean-includes b/scripts/clean-includes index XXXXXXX..XXXXXXX 100755 --- a/scripts/clean-includes +++ b/scripts/clean-includes @@ -XXX,XX +XXX,XX @@ # removed. # Other files (including C++ and ObjectiveC) can't be handled by this script. -# The following one-liner may be handy for finding files to run this on. -# However some caution is required regarding files that might be part -# of the guest agent or standalone tests. - -# for i in $(git ls-tree --name-only HEAD) ; do test -f $i && \ -# grep -E '^# *include' $i | head -1 | grep 'osdep.h' ; test $? != 0 && \ -# echo $i ; done - - GIT=no DUPHEAD=no -- 2.47.3
Currently we have a single extended regular expression defining files that clean-includes should ignore. This is now very long and awkward to read and edit. Switch to having a list of newline-separated EREs that we write to a file for grep's -f option, so we can express them more legibly in the shell script. We allow for comments in the regex list, which lets us document why we have put the exclusions in. Signed-off-by: Peter Maydell <peter.maydell@linaro.org> Reviewed-by: Richard Henderson <richard.henderson@linaro.org> Message-id: 20260116124005.925382-4-peter.maydell@linaro.org --- scripts/clean-includes | 28 ++++++++++++++++++++++------ 1 file changed, 22 insertions(+), 6 deletions(-) diff --git a/scripts/clean-includes b/scripts/clean-includes index XXXXXXX..XXXXXXX 100755 --- a/scripts/clean-includes +++ b/scripts/clean-includes @@ -XXX,XX +XXX,XX @@ GIT=no DUPHEAD=no -# Extended regular expression defining files to ignore when using --all -XDIRREGEX='^(tests/tcg|tests/multiboot|tests/fp|tests/plugin|tests/uefi-test-tools|pc-bios|subprojects|contrib/plugins|tools/ebpf|ebpf/rss.bpf.skeleton.h|linux-user/(mips64|x86_64)/(cpu_loop|signal).c)' while true do @@ -XXX,XX +XXX,XX @@ if [ "$1" = "--all" ]; then set -- '.' fi -# We assume there are no files in the tree with spaces in their name -set -- $(git ls-files "$@" | grep '\.[ch]$' | grep -E -v "$XDIRREGEX") - # Annoyingly coccinelle won't read a scriptfile unless its # name ends '.cocci', so write it out to a tempfile with the # right kind of name. COCCIFILE="$(mktemp --suffix=.cocci)" +REGEXFILE="$(mktemp --suffix=.regex)" + +trap 'rm -f -- "$COCCIFILE" "$REGEXFILE"' INT TERM HUP EXIT + +# List of extended regular expressions defining files to ignore +# Comments starting with '#' are permitted +grep -v '^#' >"$REGEXFILE" <<EOT +# These tests are generally standalone binaries +^tests/(tcg|multiboot|fp|plugin|uefi-test-tools) +# BIOS sources and third-party subprojects don't follow our rules +^pc-bios +^subprojects +# plugin binaries are standalone +^contrib/plugins +# the ebpf tool is standalone, and the skeleton header is autogenerated +^tools/ebpf +^ebpf/rss.bpf.skeleton.h +# These files just include some other .c file and have no content themselves +^linux-user/(mips64|x86_64)/(cpu_loop|signal).c +EOT -trap 'rm -f -- "$COCCIFILE"' INT TERM HUP EXIT +# We assume there are no files in the tree with spaces in their name +set -- $(git ls-files "$@" | grep '\.[ch]$' | grep -E -v -f "$REGEXFILE") cat >"$COCCIFILE" <<EOT @@ -- 2.47.3
We currently have two mechanisms for excluding files: * the REGEXFILE which excludes by regex * special cases in the "loop over each file" which make us skip the file Roll all the "skip this" cases into REGEXFILE, so we use a single mechanism for identifying which files to exclude. Signed-off-by: Peter Maydell <peter.maydell@linaro.org> Reviewed-by: Richard Henderson <richard.henderson@linaro.org> Message-id: 20260116124005.925382-5-peter.maydell@linaro.org --- scripts/clean-includes | 24 +++++++++--------------- 1 file changed, 9 insertions(+), 15 deletions(-) diff --git a/scripts/clean-includes b/scripts/clean-includes index XXXXXXX..XXXXXXX 100755 --- a/scripts/clean-includes +++ b/scripts/clean-includes @@ -XXX,XX +XXX,XX @@ grep -v '^#' >"$REGEXFILE" <<EOT ^ebpf/rss.bpf.skeleton.h # These files just include some other .c file and have no content themselves ^linux-user/(mips64|x86_64)/(cpu_loop|signal).c +# These are autogenerated headers +^include/standard-headers/ +# osdep.h itself and its friends are expected to include system headers +^include/qemu/osdep.h +^include/qemu/compiler.h +^include/glib-compat.h +^include/system/os-(posix|win32).h +# This is for use by plugins, which are standalone binaries +^include/qemu/qemu-plugin.h EOT # We assume there are no files in the tree with spaces in their name @@ -XXX,XX +XXX,XX @@ for f in "$@"; do *.c) MODE=c ;; - *include/qemu/osdep.h | \ - *include/qemu/compiler.h | \ - *include/qemu/qemu-plugin.h | \ - *include/glib-compat.h | \ - *include/system/os-posix.h | \ - *include/system/os-win32.h | \ - *include/standard-headers/ ) - # Removing include lines from osdep.h itself would be counterproductive. - echo "SKIPPING $f (special case header)" - continue - ;; - *include/standard-headers/*) - echo "SKIPPING $f (autogenerated header)" - continue - ;; *.h) MODE=h ;; -- 2.47.3
If clean-includes is creating a git commit for its changes, currently it says only "created with scripts/clean-includes". Add the command line arguments the user passed us, as useful extra information. Signed-off-by: Peter Maydell <peter.maydell@linaro.org> Reviewed-by: Markus Armbruster <armbru@redhat.com> Message-id: 20260116124005.925382-6-peter.maydell@linaro.org --- scripts/clean-includes | 23 ++++++++++++++++++++++- 1 file changed, 22 insertions(+), 1 deletion(-) diff --git a/scripts/clean-includes b/scripts/clean-includes index XXXXXXX..XXXXXXX 100755 --- a/scripts/clean-includes +++ b/scripts/clean-includes @@ -XXX,XX +XXX,XX @@ GIT=no DUPHEAD=no +# Save the original arguments in case we want to put them in +# a git commit message, quoted for the shell so that we handle +# args with spaces/metacharacters correctly. +# The quote_sh() function is the same one we use in configure. + +quote_sh() { + printf "%s" "$1" | sed "s,','\\\\'',g; s,.*,'&'," +} + +quote_args() { + while [ $# -gt 0 ]; do + printf "%s" "$(quote_sh "$1")" + shift + if [ $# -gt 0 ]; then + printf " " + fi + done +} + +QUOTEDARGS="$(quote_args "$@")" while true do @@ -XXX,XX +XXX,XX @@ if [ "$GIT" = "yes" ]; then git commit --signoff -F - <<EOF $GITSUBJ: Clean up includes -This commit was created with scripts/clean-includes. +This commit was created with scripts/clean-includes: + ./scripts/clean-includes $QUOTEDARGS All .c should include qemu/osdep.h first. The script performs three related cleanups: -- 2.47.3
Remove from the exclude list: * tests/plugin, which is a non-existent directory. This was probably intended to exclude tests/tcg/plugins/, which is caught by the tests/tcg exclude pattern anyway Add to the exclude list: * rust/ -- the headers in here are purely for input to bindgen * target/hexagon has some standalone tools used at build time * linux-user/gen-vsdo.c -- another standalone tool * linux-user/mips64/elfload.c just includes mips/elfload.c * scripts/xen-detect.c is feature-detection code used by meson.build * tests/tracetool/simple.c is autogenerated * tests/unit/ has some "C file just includes another one" files * include/system/os-wasm.h is like os-posix.h and os-win32.h and shouldn't be adjusted Signed-off-by: Peter Maydell <peter.maydell@linaro.org> Reviewed-by: Richard Henderson <richard.henderson@linaro.org> Message-id: 20260116124005.925382-7-peter.maydell@linaro.org --- scripts/clean-includes | 19 +++++++++++++++++-- 1 file changed, 17 insertions(+), 2 deletions(-) diff --git a/scripts/clean-includes b/scripts/clean-includes index XXXXXXX..XXXXXXX 100755 --- a/scripts/clean-includes +++ b/scripts/clean-includes @@ -XXX,XX +XXX,XX @@ trap 'rm -f -- "$COCCIFILE" "$REGEXFILE"' INT TERM HUP EXIT # Comments starting with '#' are permitted grep -v '^#' >"$REGEXFILE" <<EOT # These tests are generally standalone binaries -^tests/(tcg|multiboot|fp|plugin|uefi-test-tools) +^tests/(tcg|multiboot|fp|uefi-test-tools|qtest/migration/s390x) # BIOS sources and third-party subprojects don't follow our rules ^pc-bios ^subprojects +# headers under rust are only used for input to bindgen +^rust # plugin binaries are standalone ^contrib/plugins # the ebpf tool is standalone, and the skeleton header is autogenerated @@ -XXX,XX +XXX,XX @@ grep -v '^#' >"$REGEXFILE" <<EOT ^ebpf/rss.bpf.skeleton.h # These files just include some other .c file and have no content themselves ^linux-user/(mips64|x86_64)/(cpu_loop|signal).c +^linux-user/mips64/elfload.c # These are autogenerated headers ^include/standard-headers/ # osdep.h itself and its friends are expected to include system headers ^include/qemu/osdep.h ^include/qemu/compiler.h ^include/glib-compat.h -^include/system/os-(posix|win32).h +^include/system/os-(posix|win32|wasm).h # This is for use by plugins, which are standalone binaries ^include/qemu/qemu-plugin.h +# standalone tools used in building the hexagon target code +^target/hexagon/(idef-parser|gen_semantics.c|gen_dectree_import.c) +# standalone tool +^target/s390x/gen-features.c +# gen-vdso is a standalone tool +^linux-user/gen-vdso.c +# feature-detection code used by meson.bulid +^scripts/xen-detect.c +# autogenerated by tracetool +^tests/tracetool/simple.c +# these just include another C file +^tests/unit/test-rcu-(simpleq|slist|tailq).c EOT # We assume there are no files in the tree with spaces in their name -- 2.47.3
This commit was created with scripts/clean-includes: ./scripts/clean-includes '--git' 'mshv' 'accel/mshv' 'target/i386/mshv' 'include/system/mshv.h' All .c should include qemu/osdep.h first. The script performs three related cleanups: * Ensure .c files include qemu/osdep.h first. * Including it in a .h is redundant, since the .c already includes it. Drop such inclusions. * Likewise, including headers qemu/osdep.h includes is redundant. Drop these, too. Signed-off-by: Peter Maydell <peter.maydell@linaro.org> Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org> Message-id: 20260116125830.926296-2-peter.maydell@linaro.org --- accel/mshv/irq.c | 3 +-- accel/mshv/mshv-all.c | 1 - include/system/mshv.h | 1 - target/i386/mshv/mshv-cpu.c | 1 - target/i386/mshv/x86.c | 1 - 5 files changed, 1 insertion(+), 6 deletions(-) diff --git a/accel/mshv/irq.c b/accel/mshv/irq.c index XXXXXXX..XXXXXXX 100644 --- a/accel/mshv/irq.c +++ b/accel/mshv/irq.c @@ -XXX,XX +XXX,XX @@ * SPDX-License-Identifier: GPL-2.0-or-later */ -#include "linux/mshv.h" #include "qemu/osdep.h" +#include "linux/mshv.h" #include "qemu/error-report.h" #include "hw/hyperv/hvhdk_mini.h" #include "hw/hyperv/hvgdk_mini.h" @@ -XXX,XX +XXX,XX @@ #include "system/mshv.h" #include "system/mshv_int.h" #include "trace.h" -#include <stdint.h> #include <sys/ioctl.h> #define MSHV_IRQFD_RESAMPLE_FLAG (1 << MSHV_IRQFD_BIT_RESAMPLE) diff --git a/accel/mshv/mshv-all.c b/accel/mshv/mshv-all.c index XXXXXXX..XXXXXXX 100644 --- a/accel/mshv/mshv-all.c +++ b/accel/mshv/mshv-all.c @@ -XXX,XX +XXX,XX @@ #include "system/reset.h" #include "trace.h" #include <err.h> -#include <stdint.h> #include <sys/ioctl.h> #define TYPE_MSHV_ACCEL ACCEL_CLASS_NAME("mshv") diff --git a/include/system/mshv.h b/include/system/mshv.h index XXXXXXX..XXXXXXX 100644 --- a/include/system/mshv.h +++ b/include/system/mshv.h @@ -XXX,XX +XXX,XX @@ #ifndef QEMU_MSHV_H #define QEMU_MSHV_H -#include "qemu/osdep.h" #include "qemu/accel.h" #include "hw/hyperv/hyperv-proto.h" #include "hw/hyperv/hvhdk.h" diff --git a/target/i386/mshv/mshv-cpu.c b/target/i386/mshv/mshv-cpu.c index XXXXXXX..XXXXXXX 100644 --- a/target/i386/mshv/mshv-cpu.c +++ b/target/i386/mshv/mshv-cpu.c @@ -XXX,XX +XXX,XX @@ #include "qemu/osdep.h" #include "qemu/error-report.h" #include "qemu/memalign.h" -#include "qemu/typedefs.h" #include "system/mshv.h" #include "system/mshv_int.h" diff --git a/target/i386/mshv/x86.c b/target/i386/mshv/x86.c index XXXXXXX..XXXXXXX 100644 --- a/target/i386/mshv/x86.c +++ b/target/i386/mshv/x86.c @@ -XXX,XX +XXX,XX @@ #include "cpu.h" #include "emulate/x86_decode.h" #include "emulate/x86_emu.h" -#include "qemu/typedefs.h" #include "qemu/error-report.h" #include "system/mshv.h" -- 2.47.3
This commit was created with scripts/clean-includes: ./scripts/clean-includes '--git' 'bsd-user' 'bsd-user' All .c should include qemu/osdep.h first. The script performs three related cleanups: * Ensure .c files include qemu/osdep.h first. * Including it in a .h is redundant, since the .c already includes it. Drop such inclusions. * Likewise, including headers qemu/osdep.h includes is redundant. Drop these, too. Signed-off-by: Peter Maydell <peter.maydell@linaro.org> Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org> Reviewed-by: Warner Losh <imp@bsdimp.com> Message-id: 20260116125830.926296-3-peter.maydell@linaro.org --- bsd-user/bsd-mem.h | 3 --- bsd-user/bsd-proc.c | 1 - bsd-user/freebsd/os-proc.h | 2 -- bsd-user/qemu-bsd.h | 1 - 4 files changed, 7 deletions(-) diff --git a/bsd-user/bsd-mem.h b/bsd-user/bsd-mem.h index XXXXXXX..XXXXXXX 100644 --- a/bsd-user/bsd-mem.h +++ b/bsd-user/bsd-mem.h @@ -XXX,XX +XXX,XX @@ #ifndef BSD_USER_BSD_MEM_H #define BSD_USER_BSD_MEM_H -#include <sys/types.h> #include <sys/ipc.h> -#include <sys/mman.h> #include <sys/shm.h> -#include <fcntl.h> #include "qemu-bsd.h" #include "exec/mmap-lock.h" diff --git a/bsd-user/bsd-proc.c b/bsd-user/bsd-proc.c index XXXXXXX..XXXXXXX 100644 --- a/bsd-user/bsd-proc.c +++ b/bsd-user/bsd-proc.c @@ -XXX,XX +XXX,XX @@ #include "qemu/osdep.h" #include <sys/param.h> -#include <sys/types.h> #include <sys/cpuset.h> #include <sys/resource.h> #include <sys/wait.h> diff --git a/bsd-user/freebsd/os-proc.h b/bsd-user/freebsd/os-proc.h index XXXXXXX..XXXXXXX 100644 --- a/bsd-user/freebsd/os-proc.h +++ b/bsd-user/freebsd/os-proc.h @@ -XXX,XX +XXX,XX @@ #include <sys/param.h> #include <sys/procctl.h> #include <sys/signal.h> -#include <sys/types.h> #include <sys/procdesc.h> #include <sys/wait.h> -#include <unistd.h> #include "target_arch_cpu.h" diff --git a/bsd-user/qemu-bsd.h b/bsd-user/qemu-bsd.h index XXXXXXX..XXXXXXX 100644 --- a/bsd-user/qemu-bsd.h +++ b/bsd-user/qemu-bsd.h @@ -XXX,XX +XXX,XX @@ #ifndef QEMU_BSD_H #define QEMU_BSD_H -#include <sys/types.h> #include <sys/resource.h> #include <sys/ipc.h> #include <sys/msg.h> -- 2.47.3
This commit deals with various .c files that included system headers that are already pulled in by osdep.h, where the .c file includes osdep.h already itself. This commit was created with scripts/clean-includes: ./scripts/clean-includes '--git' 'misc' 'hw/core' 'semihosting' 'target/arm' 'target/i386/kvm/kvm.c' 'target/loongarch' 'target/riscv' 'tools' 'util' All .c should include qemu/osdep.h first. The script performs three related cleanups: * Ensure .c files include qemu/osdep.h first. * Including it in a .h is redundant, since the .c already includes it. Drop such inclusions. * Likewise, including headers qemu/osdep.h includes is redundant. Drop these, too. Signed-off-by: Peter Maydell <peter.maydell@linaro.org> Reviewed-by: Markus Armbruster <armbru@redhat.com> Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org> Message-id: 20260116125830.926296-4-peter.maydell@linaro.org --- hw/core/machine-qmp-cmds.c | 1 - semihosting/arm-compat-semi-stub.c | 1 - target/arm/cpu32-stubs.c | 1 - target/i386/kvm/kvm.c | 1 - target/loongarch/csr.c | 1 - target/riscv/csr.c | 1 - tools/i386/qemu-vmsr-helper.c | 1 - util/cpuinfo-aarch64.c | 1 - 8 files changed, 8 deletions(-) diff --git a/hw/core/machine-qmp-cmds.c b/hw/core/machine-qmp-cmds.c index XXXXXXX..XXXXXXX 100644 --- a/hw/core/machine-qmp-cmds.c +++ b/hw/core/machine-qmp-cmds.c @@ -XXX,XX +XXX,XX @@ #include "system/runstate.h" #include "system/system.h" #include "hw/s390x/storage-keys.h" -#include <sys/stat.h> /* * QMP query for enabled and present accelerators diff --git a/semihosting/arm-compat-semi-stub.c b/semihosting/arm-compat-semi-stub.c index XXXXXXX..XXXXXXX 100644 --- a/semihosting/arm-compat-semi-stub.c +++ b/semihosting/arm-compat-semi-stub.c @@ -XXX,XX +XXX,XX @@ #include "qemu/osdep.h" #include "semihosting/semihost.h" -#include <glib.h> bool semihosting_arm_compatible(void) { diff --git a/target/arm/cpu32-stubs.c b/target/arm/cpu32-stubs.c index XXXXXXX..XXXXXXX 100644 --- a/target/arm/cpu32-stubs.c +++ b/target/arm/cpu32-stubs.c @@ -XXX,XX +XXX,XX @@ #include "qemu/osdep.h" #include "target/arm/cpu.h" #include "target/arm/internals.h" -#include <glib.h> void arm_cpu_sme_finalize(ARMCPU *cpu, Error **errp) { diff --git a/target/i386/kvm/kvm.c b/target/i386/kvm/kvm.c index XXXXXXX..XXXXXXX 100644 --- a/target/i386/kvm/kvm.c +++ b/target/i386/kvm/kvm.c @@ -XXX,XX +XXX,XX @@ #include <sys/utsname.h> #include <sys/syscall.h> #include <sys/resource.h> -#include <sys/time.h> #include <linux/kvm.h> #include <linux/kvm_para.h> diff --git a/target/loongarch/csr.c b/target/loongarch/csr.c index XXXXXXX..XXXXXXX 100644 --- a/target/loongarch/csr.c +++ b/target/loongarch/csr.c @@ -XXX,XX +XXX,XX @@ /* * Copyright (c) 2025 Loongson Technology Corporation Limited */ -#include <stddef.h> #include "qemu/osdep.h" #include "cpu.h" #include "csr.h" diff --git a/target/riscv/csr.c b/target/riscv/csr.c index XXXXXXX..XXXXXXX 100644 --- a/target/riscv/csr.c +++ b/target/riscv/csr.c @@ -XXX,XX +XXX,XX @@ #include "qapi/error.h" #include "tcg/insn-start-words.h" #include "internals.h" -#include <stdbool.h> /* CSR function table public API */ void riscv_get_csr_ops(int csrno, riscv_csr_operations *ops) diff --git a/tools/i386/qemu-vmsr-helper.c b/tools/i386/qemu-vmsr-helper.c index XXXXXXX..XXXXXXX 100644 --- a/tools/i386/qemu-vmsr-helper.c +++ b/tools/i386/qemu-vmsr-helper.c @@ -XXX,XX +XXX,XX @@ #include "qemu/osdep.h" #include <getopt.h> -#include <stdbool.h> #include <sys/ioctl.h> #ifdef CONFIG_LIBCAP_NG #include <cap-ng.h> diff --git a/util/cpuinfo-aarch64.c b/util/cpuinfo-aarch64.c index XXXXXXX..XXXXXXX 100644 --- a/util/cpuinfo-aarch64.c +++ b/util/cpuinfo-aarch64.c @@ -XXX,XX +XXX,XX @@ #if defined(__OpenBSD__) && !defined(CONFIG_ELF_AUX_INFO) # include <machine/armreg.h> # include <machine/cpu.h> -# include <sys/types.h> # include <sys/sysctl.h> #endif -- 2.47.3
This commit was created with scripts/clean-includes: ./scripts/clean-includes '--git' 'all' '--all' and manually edited to remove one change to hw/virtio/cbor-helpers.c. All these changes are header files that include osdep.h or some system header that osdep.h pulls in; they don't need to do this. All .c should include qemu/osdep.h first. The script performs three related cleanups: * Ensure .c files include qemu/osdep.h first. * Including it in a .h is redundant, since the .c already includes it. Drop such inclusions. * Likewise, including headers qemu/osdep.h includes is redundant. Drop these, too. Signed-off-by: Peter Maydell <peter.maydell@linaro.org> Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org> Message-id: 20260116125830.926296-5-peter.maydell@linaro.org --- hw/scsi/lasi_ncr710.h | 1 - hw/scsi/ncr53c710.h | 1 - include/hw/core/loader.h | 1 - include/hw/i386/tdvf.h | 1 - include/hw/ppc/spapr_fadump.h | 1 - include/hw/riscv/iommu.h | 1 - include/system/accel-irq.h | 1 - linux-user/alpha/target_proc.h | 1 - qga/commands-windows-ssh.h | 1 - qga/vss-win32/vss-debug.h | 1 - target/i386/kvm/vmsr_energy.h | 2 -- 11 files changed, 12 deletions(-) diff --git a/hw/scsi/lasi_ncr710.h b/hw/scsi/lasi_ncr710.h index XXXXXXX..XXXXXXX 100644 --- a/hw/scsi/lasi_ncr710.h +++ b/hw/scsi/lasi_ncr710.h @@ -XXX,XX +XXX,XX @@ #define HW_LASI_NCR710_H #include "hw/core/sysbus.h" -#include "qemu/osdep.h" #include "exec/memattrs.h" #include "hw/scsi/scsi.h" #include "hw/scsi/ncr53c710.h" diff --git a/hw/scsi/ncr53c710.h b/hw/scsi/ncr53c710.h index XXXXXXX..XXXXXXX 100644 --- a/hw/scsi/ncr53c710.h +++ b/hw/scsi/ncr53c710.h @@ -XXX,XX +XXX,XX @@ #ifndef HW_NCR53C710_H #define HW_NCR53C710_H -#include "qemu/osdep.h" #include "hw/core/sysbus.h" #include "hw/scsi/scsi.h" #include "qemu/fifo8.h" diff --git a/include/hw/core/loader.h b/include/hw/core/loader.h index XXXXXXX..XXXXXXX 100644 --- a/include/hw/core/loader.h +++ b/include/hw/core/loader.h @@ -XXX,XX +XXX,XX @@ #ifndef LOADER_H #define LOADER_H #include "hw/nvram/fw_cfg.h" -#include "qemu/typedefs.h" /* loader.c */ /** diff --git a/include/hw/i386/tdvf.h b/include/hw/i386/tdvf.h index XXXXXXX..XXXXXXX 100644 --- a/include/hw/i386/tdvf.h +++ b/include/hw/i386/tdvf.h @@ -XXX,XX +XXX,XX @@ #ifndef HW_I386_TDVF_H #define HW_I386_TDVF_H -#include "qemu/osdep.h" #define TDVF_SECTION_TYPE_BFV 0 #define TDVF_SECTION_TYPE_CFV 1 diff --git a/include/hw/ppc/spapr_fadump.h b/include/hw/ppc/spapr_fadump.h index XXXXXXX..XXXXXXX 100644 --- a/include/hw/ppc/spapr_fadump.h +++ b/include/hw/ppc/spapr_fadump.h @@ -XXX,XX +XXX,XX @@ #ifndef PPC_SPAPR_FADUMP_H #define PPC_SPAPR_FADUMP_H -#include "qemu/osdep.h" #include "cpu.h" /* Fadump commands */ diff --git a/include/hw/riscv/iommu.h b/include/hw/riscv/iommu.h index XXXXXXX..XXXXXXX 100644 --- a/include/hw/riscv/iommu.h +++ b/include/hw/riscv/iommu.h @@ -XXX,XX +XXX,XX @@ #ifndef HW_RISCV_IOMMU_H #define HW_RISCV_IOMMU_H -#include "qemu/osdep.h" #include "qom/object.h" #define TYPE_RISCV_IOMMU "riscv-iommu" diff --git a/include/system/accel-irq.h b/include/system/accel-irq.h index XXXXXXX..XXXXXXX 100644 --- a/include/system/accel-irq.h +++ b/include/system/accel-irq.h @@ -XXX,XX +XXX,XX @@ #ifndef SYSTEM_ACCEL_IRQ_H #define SYSTEM_ACCEL_IRQ_H #include "hw/pci/msi.h" -#include "qemu/osdep.h" #include "system/kvm.h" #include "system/mshv.h" diff --git a/linux-user/alpha/target_proc.h b/linux-user/alpha/target_proc.h index XXXXXXX..XXXXXXX 100644 --- a/linux-user/alpha/target_proc.h +++ b/linux-user/alpha/target_proc.h @@ -XXX,XX +XXX,XX @@ #ifndef ALPHA_TARGET_PROC_H #define ALPHA_TARGET_PROC_H -#include "qemu/osdep.h" #include "target/alpha/cpu.h" static uint8_t alpha_phys_addr_space_bits(CPUAlphaState *env) diff --git a/qga/commands-windows-ssh.h b/qga/commands-windows-ssh.h index XXXXXXX..XXXXXXX 100644 --- a/qga/commands-windows-ssh.h +++ b/qga/commands-windows-ssh.h @@ -XXX,XX +XXX,XX @@ */ #include <glib/gstrfuncs.h> -#include <stdbool.h> typedef struct WindowsUserInfo { char *sshDirectory; char *authorizedKeyFile; diff --git a/qga/vss-win32/vss-debug.h b/qga/vss-win32/vss-debug.h index XXXXXXX..XXXXXXX 100644 --- a/qga/vss-win32/vss-debug.h +++ b/qga/vss-win32/vss-debug.h @@ -XXX,XX +XXX,XX @@ * See the COPYING file in the top-level directory. */ -#include "qemu/osdep.h" #include <vss-handles.h> #ifndef VSS_DEBUG_H diff --git a/target/i386/kvm/vmsr_energy.h b/target/i386/kvm/vmsr_energy.h index XXXXXXX..XXXXXXX 100644 --- a/target/i386/kvm/vmsr_energy.h +++ b/target/i386/kvm/vmsr_energy.h @@ -XXX,XX +XXX,XX @@ #ifndef VMSR_ENERGY_H #define VMSR_ENERGY_H -#include <stdint.h> -#include "qemu/osdep.h" #include "io/channel-socket.h" #include "hw/i386/topology.h" -- 2.47.3
From: Alex Bennée <alex.bennee@linaro.org> The NVIC should always be a little-endian device as big-endian behaviour is a function of the current CPU configuration not the system as a whole. Indeed the Armv8-M architecture reference manual declares: All accesses to the Private Peripheral Bus (PPB) are always little-endian, which means that the PE assumes a little-endian arrangement of the PPB registers. This should have no functional effect as the NVIC cannot be instantiated on a BE system but will help the single binary efforts. Signed-off-by: Alex Bennée <alex.bennee@linaro.org> Reviewed-by: Peter Maydell <peter.maydell@linaro.org> Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org> Message-id: 20260121105932.135676-2-alex.bennee@linaro.org Signed-off-by: Peter Maydell <peter.maydell@linaro.org> --- hw/intc/armv7m_nvic.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/hw/intc/armv7m_nvic.c b/hw/intc/armv7m_nvic.c index XXXXXXX..XXXXXXX 100644 --- a/hw/intc/armv7m_nvic.c +++ b/hw/intc/armv7m_nvic.c @@ -XXX,XX +XXX,XX @@ static MemTxResult nvic_sysreg_write(void *opaque, hwaddr addr, static const MemoryRegionOps nvic_sysreg_ops = { .read_with_attrs = nvic_sysreg_read, .write_with_attrs = nvic_sysreg_write, - .endianness = DEVICE_NATIVE_ENDIAN, + .endianness = DEVICE_LITTLE_ENDIAN, }; static int nvic_post_load(void *opaque, int version_id) -- 2.47.3
From: Alex Bennée <alex.bennee@linaro.org> The GIC should always be a little-endian device as big-endian behaviour is a function of the current CPU configuration not the system as a whole. This should have no functional effect as the GIC cannot be instantiated on a BE system but will help the single binary efforts. Signed-off-by: Alex Bennée <alex.bennee@linaro.org> Reviewed-by: Peter Maydell <peter.maydell@linaro.org> Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org> Message-id: 20260121105932.135676-3-alex.bennee@linaro.org Signed-off-by: Peter Maydell <peter.maydell@linaro.org> --- hw/intc/arm_gic.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/hw/intc/arm_gic.c b/hw/intc/arm_gic.c index XXXXXXX..XXXXXXX 100644 --- a/hw/intc/arm_gic.c +++ b/hw/intc/arm_gic.c @@ -XXX,XX +XXX,XX @@ static const MemoryRegionOps gic_ops[2] = { { .read_with_attrs = gic_dist_read, .write_with_attrs = gic_dist_write, - .endianness = DEVICE_NATIVE_ENDIAN, + .endianness = DEVICE_LITTLE_ENDIAN, }, { .read_with_attrs = gic_thiscpu_read, .write_with_attrs = gic_thiscpu_write, - .endianness = DEVICE_NATIVE_ENDIAN, + .endianness = DEVICE_LITTLE_ENDIAN, } }; static const MemoryRegionOps gic_cpu_ops = { .read_with_attrs = gic_do_cpu_read, .write_with_attrs = gic_do_cpu_write, - .endianness = DEVICE_NATIVE_ENDIAN, + .endianness = DEVICE_LITTLE_ENDIAN, }; static const MemoryRegionOps gic_virt_ops[2] = { { .read_with_attrs = gic_thiscpu_hyp_read, .write_with_attrs = gic_thiscpu_hyp_write, - .endianness = DEVICE_NATIVE_ENDIAN, + .endianness = DEVICE_LITTLE_ENDIAN, }, { .read_with_attrs = gic_thisvcpu_read, .write_with_attrs = gic_thisvcpu_write, - .endianness = DEVICE_NATIVE_ENDIAN, + .endianness = DEVICE_LITTLE_ENDIAN, } }; static const MemoryRegionOps gic_viface_ops = { .read_with_attrs = gic_do_hyp_read, .write_with_attrs = gic_do_hyp_write, - .endianness = DEVICE_NATIVE_ENDIAN, + .endianness = DEVICE_LITTLE_ENDIAN, }; static void arm_gic_realize(DeviceState *dev, Error **errp) -- 2.47.3
From: Alex Bennée <alex.bennee@linaro.org> The GIC should always be a little-endian device as big-endian behaviour is a function of the current CPU configuration not the system as a whole. This should have no functional effect as the GIC cannot be instantiated on a BE system but will help the single binary efforts. Signed-off-by: Alex Bennée <alex.bennee@linaro.org> Reviewed-by: Peter Maydell <peter.maydell@linaro.org> Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org> Message-id: 20260121105932.135676-4-alex.bennee@linaro.org Signed-off-by: Peter Maydell <peter.maydell@linaro.org> --- hw/intc/arm_gicv3.c | 4 ++-- hw/intc/arm_gicv3_its.c | 4 ++-- hw/intc/arm_gicv3_its_common.c | 2 +- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/hw/intc/arm_gicv3.c b/hw/intc/arm_gicv3.c index XXXXXXX..XXXXXXX 100644 --- a/hw/intc/arm_gicv3.c +++ b/hw/intc/arm_gicv3.c @@ -XXX,XX +XXX,XX @@ static const MemoryRegionOps gic_ops[] = { { .read_with_attrs = gicv3_dist_read, .write_with_attrs = gicv3_dist_write, - .endianness = DEVICE_NATIVE_ENDIAN, + .endianness = DEVICE_LITTLE_ENDIAN, .valid.min_access_size = 1, .valid.max_access_size = 8, .impl.min_access_size = 1, @@ -XXX,XX +XXX,XX @@ static const MemoryRegionOps gic_ops[] = { { .read_with_attrs = gicv3_redist_read, .write_with_attrs = gicv3_redist_write, - .endianness = DEVICE_NATIVE_ENDIAN, + .endianness = DEVICE_LITTLE_ENDIAN, .valid.min_access_size = 1, .valid.max_access_size = 8, .impl.min_access_size = 1, diff --git a/hw/intc/arm_gicv3_its.c b/hw/intc/arm_gicv3_its.c index XXXXXXX..XXXXXXX 100644 --- a/hw/intc/arm_gicv3_its.c +++ b/hw/intc/arm_gicv3_its.c @@ -XXX,XX +XXX,XX @@ static const MemoryRegionOps gicv3_its_control_ops = { .valid.max_access_size = 8, .impl.min_access_size = 4, .impl.max_access_size = 8, - .endianness = DEVICE_NATIVE_ENDIAN, + .endianness = DEVICE_LITTLE_ENDIAN, }; static const MemoryRegionOps gicv3_its_translation_ops = { @@ -XXX,XX +XXX,XX @@ static const MemoryRegionOps gicv3_its_translation_ops = { .valid.max_access_size = 4, .impl.min_access_size = 2, .impl.max_access_size = 4, - .endianness = DEVICE_NATIVE_ENDIAN, + .endianness = DEVICE_LITTLE_ENDIAN, }; static void gicv3_arm_its_realize(DeviceState *dev, Error **errp) diff --git a/hw/intc/arm_gicv3_its_common.c b/hw/intc/arm_gicv3_its_common.c index XXXXXXX..XXXXXXX 100644 --- a/hw/intc/arm_gicv3_its_common.c +++ b/hw/intc/arm_gicv3_its_common.c @@ -XXX,XX +XXX,XX @@ static MemTxResult gicv3_its_trans_write(void *opaque, hwaddr offset, static const MemoryRegionOps gicv3_its_trans_ops = { .read_with_attrs = gicv3_its_trans_read, .write_with_attrs = gicv3_its_trans_write, - .endianness = DEVICE_NATIVE_ENDIAN, + .endianness = DEVICE_LITTLE_ENDIAN, }; void gicv3_its_init_mmio(GICv3ITSState *s, const MemoryRegionOps *ops, -- 2.47.3
From: Alex Bennée <alex.bennee@linaro.org> This allows us to keep the MSI data in plain host order all the way from the MemoryRegionOps write method to the final KVM_SIGNAL_MSI ioctl. This fixes a theoretical bug on big-endian hosts because we were using different size byte swaps which would have truncated the data. Signed-off-by: Alex Bennée <alex.bennee@linaro.org> Reviewed-by: Peter Maydell <peter.maydell@linaro.org> Message-id: 20260121105932.135676-5-alex.bennee@linaro.org Cc: qemu-stable@nongnu.org Signed-off-by: Peter Maydell <peter.maydell@linaro.org> --- hw/intc/arm_gicv3_its_common.c | 2 +- hw/intc/arm_gicv3_its_kvm.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/hw/intc/arm_gicv3_its_common.c b/hw/intc/arm_gicv3_its_common.c index XXXXXXX..XXXXXXX 100644 --- a/hw/intc/arm_gicv3_its_common.c +++ b/hw/intc/arm_gicv3_its_common.c @@ -XXX,XX +XXX,XX @@ static MemTxResult gicv3_its_trans_write(void *opaque, hwaddr offset, if (offset == 0x0040 && ((size == 2) || (size == 4))) { GICv3ITSState *s = ARM_GICV3_ITS_COMMON(opaque); GICv3ITSCommonClass *c = ARM_GICV3_ITS_COMMON_GET_CLASS(s); - int ret = c->send_msi(s, le64_to_cpu(value), attrs.requester_id); + int ret = c->send_msi(s, value, attrs.requester_id); if (ret <= 0) { qemu_log_mask(LOG_GUEST_ERROR, diff --git a/hw/intc/arm_gicv3_its_kvm.c b/hw/intc/arm_gicv3_its_kvm.c index XXXXXXX..XXXXXXX 100644 --- a/hw/intc/arm_gicv3_its_kvm.c +++ b/hw/intc/arm_gicv3_its_kvm.c @@ -XXX,XX +XXX,XX @@ static int kvm_its_send_msi(GICv3ITSState *s, uint32_t value, uint16_t devid) msi.address_lo = extract64(s->gits_translater_gpa, 0, 32); msi.address_hi = extract64(s->gits_translater_gpa, 32, 32); - msi.data = le32_to_cpu(value); + msi.data = value; msi.flags = KVM_MSI_VALID_DEVID; msi.devid = devid; memset(msi.pad, 0, sizeof(msi.pad)); -- 2.47.3
Make some minor improvements to the rendering of the docs for the xlnx-zynq-a9 board: * use a proper hyperlink rather than a bare URL for the link to the reference manual * drop the hex address of the SMC SRAM: the bare '@' is rendered as bogus mailto: hyperlink, and the information is not very interesting to the user anyway * expand out the abbreviations in the list of Cortex-A9 per-CPU devices * correct the bullet-point list markup so it doesn't render with odd highlighted lines * capitalize 'Arm' correctly Signed-off-by: Peter Maydell <peter.maydell@linaro.org> Reviewed-by: Alex Bennée <alex.bennee@linaro.org> Reviewed-by: Zhang Chen <zhangckid@gmail.com> Message-id: 20260115142629.665319-2-peter.maydell@linaro.org --- docs/system/arm/xlnx-zynq.rst | 51 ++++++++++++++++++----------------- 1 file changed, 27 insertions(+), 24 deletions(-) diff --git a/docs/system/arm/xlnx-zynq.rst b/docs/system/arm/xlnx-zynq.rst index XXXXXXX..XXXXXXX 100644 --- a/docs/system/arm/xlnx-zynq.rst +++ b/docs/system/arm/xlnx-zynq.rst @@ -XXX,XX +XXX,XX @@ The Zynq 7000 family is based on the AMD SoC architecture. These products integrate a feature-rich dual or single-core Arm Cortex-A9 MPCore based processing system (PS) and AMD programmable logic (PL) in a single device. -More details here: -https://docs.amd.com/r/en-US/ug585-zynq-7000-SoC-TRM/Zynq-7000-SoC-Technical-Reference-Manual - -QEMU xilinx-zynq-a9 board supports following devices: - - A9 MPCORE - - cortex-a9 - - GIC v1 - - Generic timer - - wdt - - OCM 256KB - - SMC SRAM@0xe2000000 64MB - - Zynq SLCR - - SPI x2 - - QSPI - - UART - - TTC x2 - - Gigabit Ethernet Controller x2 - - SD Controller x2 - - XADC - - Arm PrimeCell DMA Controller - - DDR Memory - - USB 2.0 x2 +The SoC is documented in the +`Zynq 7000 Technical Reference manual <https://docs.amd.com/r/en-US/ug585-zynq-7000-SoC-TRM/Zynq-7000-SoC-Technical-Reference-Manual>`__. + +The QEMU xilinx-zynq-a9 board supports the following devices: + +- Arm Cortex-A9 MPCore CPU + + - Cortex-A9 CPUs + - GIC v1 interrupt controller + - Generic timer + - Watchdog timer + +- OCM 256KB +- SMC SRAM 64MB +- Zynq SLCR +- SPI x2 +- QSPI +- UART +- TTC x2 +- Gigabit Ethernet Controller x2 +- SD Controller x2 +- XADC +- Arm PrimeCell DMA Controller +- DDR Memory +- USB 2.0 x2 Running """"""" -Direct Linux boot of a generic ARM upstream Linux kernel: +Direct Linux boot of a generic Arm upstream Linux kernel: .. code-block:: bash @@ -XXX,XX +XXX,XX @@ For configuring the boot-mode provide the following on the command line: -machine boot-mode=qspi -Supported values are jtag, sd, qspi, nor. +Supported values are ``jtag``, ``sd``, ``qspi`` and ``nor``. -- 2.47.3
In rST documents, an '@' character in normal text or a parsed-literal is assumed to be an email address and will result in a 'mailto:' hyperlink in the generated HTML. In several places we have mailto: hyperlinks that are unintended nonsense; correct these by either escaping the @ character or making the text use ``...`` preformatted rendering. This commit covers only the simple cases which can be trivially fixed with escaping or ``..``; the remaining cases will be handled in separate commits. Signed-off-by: Peter Maydell <peter.maydell@linaro.org> Reviewed-by: Alex Bennée <alex.bennee@linaro.org> Reviewed-by: Zhang Chen <zhangckid@gmail.com> Reviewed-by: Markus Armbruster <armbru@redhat.com> Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org> Message-id: 20260115142629.665319-3-peter.maydell@linaro.org --- docs/devel/submitting-a-patch.rst | 2 +- docs/system/device-url-syntax.rst.inc | 4 ++-- docs/system/vnc-security.rst | 6 +++--- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/docs/devel/submitting-a-patch.rst b/docs/devel/submitting-a-patch.rst index XXXXXXX..XXXXXXX 100644 --- a/docs/devel/submitting-a-patch.rst +++ b/docs/devel/submitting-a-patch.rst @@ -XXX,XX +XXX,XX @@ one-shot fix, the bare minimum we ask is that: * - Check - Reason - * - Patches contain Signed-off-by: Your Name <author@email> + * - Patches contain ``Signed-off-by: Your Name <author@email>`` - States you are legally able to contribute the code. See :ref:`patch_emails_must_include_a_signed_off_by_line` * - Sent as patch emails to ``qemu-devel@nongnu.org`` - The project uses an email list based workflow. See :ref:`submitting_your_patches` diff --git a/docs/system/device-url-syntax.rst.inc b/docs/system/device-url-syntax.rst.inc index XXXXXXX..XXXXXXX 100644 --- a/docs/system/device-url-syntax.rst.inc +++ b/docs/system/device-url-syntax.rst.inc @@ -XXX,XX +XXX,XX @@ These are specified using a special URL syntax. .. parsed-literal:: - |qemu_system| -drive file=iscsi://user%password@192.0.2.1/iqn.2001-04.com.example/1 + |qemu_system| -drive file=iscsi://user%password\@192.0.2.1/iqn.2001-04.com.example/1 Example (CHAP username/password via environment variables): @@ -XXX,XX +XXX,XX @@ These are specified using a special URL syntax. .. parsed-literal:: - |qemu_system| -drive file=ssh://user@host/path/to/disk.img + |qemu_system| -drive file=ssh://user\@host/path/to/disk.img |qemu_system| -drive file.driver=ssh,file.user=user,file.host=host,file.port=22,file.path=/path/to/disk.img Currently authentication must be done using ssh-agent. Other diff --git a/docs/system/vnc-security.rst b/docs/system/vnc-security.rst index XXXXXXX..XXXXXXX 100644 --- a/docs/system/vnc-security.rst +++ b/docs/system/vnc-security.rst @@ -XXX,XX +XXX,XX @@ When not using TLS the recommended configuration is This says to use the 'GSSAPI' mechanism with the Kerberos v5 protocol, with the server principal stored in /etc/qemu/krb5.tab. For this to work the administrator of your KDC must generate a Kerberos principal for the -server, with a name of 'qemu/somehost.example.com@EXAMPLE.COM' replacing -'somehost.example.com' with the fully qualified host name of the machine -running QEMU, and 'EXAMPLE.COM' with the Kerberos Realm. +server, with a name of ``qemu/somehost.example.com@EXAMPLE.COM`` replacing +``somehost.example.com`` with the fully qualified host name of the machine +running QEMU, and ``EXAMPLE.COM`` with the Kerberos Realm. When using TLS, if username+password authentication is desired, then a reasonable configuration is -- 2.47.3
A few entries in qemu-options.hx use the syntax "my-option=@var{name}" (or @var{} with no name specified) when documenting an option that takes an argument. This syntax isn't consistently used, and the documentation generation has no support for it: it just appears literally in the HTML output. Switch these uses to the more common "my-option=<name>". This also doesn't have any particular support in the documentation generation and so appears literally in the output, but it is a little less odd looking to the end-user. The other common pattern we have is "my-option=name" with no marking at all that the right hand side of the '=' is not literal text; using <> seems preferable to me, as it makes it more distinct from cases where the right hand side is documenting that only certain values are permitted, as in "my-option=on|off". This patch doesn't do anything about existing uses of this pattern (except in one case which was so confused as to use "my-option=@var{}" in the --help output and "my-option=" in the RST output, where we change both for consistency), but prefers not to add more of them. We don't change the uses of @var in the colo-compare documentation, as that part deserves a slightly more wide-ranging overhaul that is better in its own commit. Signed-off-by: Peter Maydell <peter.maydell@linaro.org> Reviewed-by: Alex Bennée <alex.bennee@linaro.org> Reviewed-by: Zhang Chen <zhangckid@gmail.com> Reviewed-by: Markus Armbruster <armbru@redhat.com> Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org> Message-id: 20260115142629.665319-4-peter.maydell@linaro.org --- qemu-options.hx | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/qemu-options.hx b/qemu-options.hx index XXXXXXX..XXXXXXX 100644 --- a/qemu-options.hx +++ b/qemu-options.hx @@ -XXX,XX +XXX,XX @@ DEF("machine", HAS_ARG, QEMU_OPTION_machine, \ " dea-key-wrap=on|off controls support for DEA key wrapping (default=on)\n" " suppress-vmdesc=on|off disables self-describing migration (default=off)\n" " nvdimm=on|off controls NVDIMM support (default=off)\n" - " memory-encryption=@var{} memory encryption object to use (default=none)\n" + " memory-encryption=<id> memory encryption object to use (default=none)\n" " hmat=on|off controls ACPI HMAT support (default=off)\n" " spcr=on|off controls ACPI SPCR support (default=on)\n" #ifdef CONFIG_POSIX @@ -XXX,XX +XXX,XX @@ SRST ``nvdimm=on|off`` Enables or disables NVDIMM support. The default is off. - ``memory-encryption=`` + ``memory-encryption=<id>`` Memory encryption object to use. The default is none. ``hmat=on|off`` @@ -XXX,XX +XXX,XX @@ SRST -machine cxl-fmw.0.targets.0=cxl.0,cxl-fmw.0.targets.1=cxl.1,cxl-fmw.0.size=128G,cxl-fmw.0.interleave-granularity=512 - ``sgx-epc.0.memdev=@var{memid},sgx-epc.0.node=@var{numaid}`` + ``sgx-epc.0.memdev=<memid>,sgx-epc.0.node=<numaid>`` Define an SGX EPC section. ``smp-cache.0.cache=cachename,smp-cache.0.topology=topologylevel`` @@ -XXX,XX +XXX,XX @@ DEF("compat", HAS_ARG, QEMU_OPTION_compat, " Policy for handling unstable management interfaces\n", QEMU_ARCH_ALL) SRST -``-compat [deprecated-input=@var{input-policy}][,deprecated-output=@var{output-policy}]`` +``-compat [deprecated-input=<input-policy>][,deprecated-output=<output-policy>]`` Set policy for handling deprecated management interfaces (experimental): ``deprecated-input=accept`` (default) @@ -XXX,XX +XXX,XX @@ SRST Limitation: covers only syntactic aspects of QMP. -``-compat [unstable-input=@var{input-policy}][,unstable-output=@var{output-policy}]`` +``-compat [unstable-input=<input-policy>][,unstable-output=<output-policy>]`` Set policy for handling unstable management interfaces (experimental): ``unstable-input=accept`` (default) -- 2.47.3
The colo-compare option documentation has some formatting issues: it uses a "@var{...}" syntax which is not used elsewhere and which is rendered literally into the HTML documentation. The bare "@" sign also results in an unintended 'mailto:' hyperlink. Rewrite this into the style we seem to use most in the rest of the command line options, where an option which takes an argument is written as "my-option=<thing>". We take the opportunity to make the documentation a little clearer by splitting up the long paragraph and using preformatted-text markup for the names of the suboptions. Signed-off-by: Peter Maydell <peter.maydell@linaro.org> Reviewed-by: Alex Bennée <alex.bennee@linaro.org> Reviewed-by: Zhang Chen <zhangckid@gmail.com> Reviewed-by: Markus Armbruster <armbru@redhat.com> Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org> Message-id: 20260115142629.665319-5-peter.maydell@linaro.org --- qemu-options.hx | 41 +++++++++++++++++++++++++---------------- 1 file changed, 25 insertions(+), 16 deletions(-) diff --git a/qemu-options.hx b/qemu-options.hx index XXXXXXX..XXXXXXX 100644 --- a/qemu-options.hx +++ b/qemu-options.hx @@ -XXX,XX +XXX,XX @@ SRST stored. The file format is libpcap, so it can be analyzed with tools such as tcpdump or Wireshark. - ``-object colo-compare,id=id,primary_in=chardevid,secondary_in=chardevid,outdev=chardevid,iothread=id[,vnet_hdr_support][,notify_dev=id][,compare_timeout=@var{ms}][,expired_scan_cycle=@var{ms}][,max_queue_size=@var{size}]`` - Colo-compare gets packet from primary\_in chardevid and - secondary\_in, then compare whether the payload of primary packet - and secondary packet are the same. If same, it will output - primary packet to out\_dev, else it will notify COLO-framework to do - checkpoint and send primary packet to out\_dev. In order to - improve efficiency, we need to put the task of comparison in - another iothread. If it has the vnet\_hdr\_support flag, - colo compare will send/recv packet with vnet\_hdr\_len. - The compare\_timeout=@var{ms} determines the maximum time of the - colo-compare hold the packet. The expired\_scan\_cycle=@var{ms} - is to set the period of scanning expired primary node network packets. - The max\_queue\_size=@var{size} is to set the max compare queue - size depend on user environment. - If user want to use Xen COLO, need to add the notify\_dev to - notify Xen colo-frame to do checkpoint. + ``-object colo-compare,id=<id>,primary_in=<chardevid>,secondary_in=<chardevid>,outdev=<chardevid>,iothread=<id>[,vnet_hdr_support][,notify_dev=<id>][,compare_timeout=<time_ms>][,expired_scan_cycle=<time_ms>][,max_queue_size=<maxsize>]`` + Colo-compare gets packets from the chardev backends specified by + ``primary_in`` and ``secondary_in``, and compares whether the payloads + of the primary packet and the secondary packet are the same. + If they match, it will output the primary packet to the chardev + backend specified by ``outdev``; otherwise it will notify COLO-framework + to do a checkpoint and send the primary packet to ``outdev``. + + In order to improve efficiency, we need to put the task of comparison in + another iothread; the ``iothread`` option specifies that iothread object + (which your commandline should create). + + The ``vnet_hdr_support`` flag tells + colo compare to pass the vnet header length when it sends and receives packets. + + The ``compare_timeout`` option sets the maximum time that + colo-compare will hold the packet for, in ms. + + The ``expired_scan_cycle`` option sets the period of scanning expired + primary node network packets, in ms. + + The ``max_queue_size`` option sets the max compare queue size. + + If you want to use Xen COLO, you need to specify ``notify_dev`` to + tell colo-compare how to notify Xen colo-frame to do a checkpoint. COLO-compare must be used with the help of filter-mirror, filter-redirector and filter-rewriter. -- 2.47.3
v3->v4: Windows headers define an INT type which clashed with an enum value name in arm_gicv3_its.c... The following changes since commit eae587e8e3694b1aceab23239493fb4c7e1a80f5: Merge remote-tracking branch 'remotes/armbru/tags/pull-qapi-2021-09-13' into staging (2021-09-13 11:00:30 +0100) are available in the Git repository at: https://git.linaro.org/people/pmaydell/qemu-arm.git tags/pull-target-arm-20210913-3 for you to fetch changes up to 28e987a7e7edaa3ca7feeac65edca26145df8814: hw/arm/mps2.c: Mark internal-only I2C buses as 'full' (2021-09-13 21:01:08 +0100) ---------------------------------------------------------------- target-arm queue: * mark MPS2/MPS3 board-internal i2c buses as 'full' so that command line user-created devices are not plugged into them * Take an exception if PSTATE.IL is set * Support an emulated ITS in the virt board * Add support for kudo-bmc board * Probe for KVM_CAP_ARM_VM_IPA_SIZE when creating scratch VM * cadence_uart: Fix clock handling issues that prevented u-boot from running ---------------------------------------------------------------- Bin Meng (6): hw/misc: zynq_slcr: Correctly compute output clocks in the reset exit phase hw/char: cadence_uart: Disable transmit when input clock is disabled hw/char: cadence_uart: Move clock/reset check to uart_can_receive() hw/char: cadence_uart: Convert to memop_with_attrs() ops hw/char: cadence_uart: Ignore access when unclocked or in reset for uart_{read, write}() hw/char: cadence_uart: Log a guest error when device is unclocked or in reset Chris Rauer (1): hw/arm: Add support for kudo-bmc board. Marc Zyngier (1): hw/arm/virt: KVM: Probe for KVM_CAP_ARM_VM_IPA_SIZE when creating scratch VM Peter Maydell (5): target/arm: Take an exception if PSTATE.IL is set qdev: Support marking individual buses as 'full' hw/arm/mps2-tz.c: Add extra data parameter to MakeDevFn hw/arm/mps2-tz.c: Mark internal-only I2C buses as 'full' hw/arm/mps2.c: Mark internal-only I2C buses as 'full' Richard Henderson (1): target/arm: Merge disas_a64_insn into aarch64_tr_translate_insn Shashi Mallela (9): hw/intc: GICv3 ITS initial framework hw/intc: GICv3 ITS register definitions added hw/intc: GICv3 ITS command queue framework hw/intc: GICv3 ITS Command processing hw/intc: GICv3 ITS Feature enablement hw/intc: GICv3 redistributor ITS processing tests/data/acpi/virt: Add IORT files for ITS hw/arm/virt: add ITS support in virt GIC tests/data/acpi/virt: Update IORT files for ITS docs/system/arm/nuvoton.rst | 1 + hw/intc/gicv3_internal.h | 188 ++++- include/hw/arm/virt.h | 2 + include/hw/intc/arm_gicv3_common.h | 13 + include/hw/intc/arm_gicv3_its_common.h | 32 +- include/hw/qdev-core.h | 24 + target/arm/cpu.h | 1 + target/arm/kvm_arm.h | 4 +- target/arm/syndrome.h | 5 + target/arm/translate.h | 2 + hw/arm/mps2-tz.c | 92 ++- hw/arm/mps2.c | 12 +- hw/arm/npcm7xx_boards.c | 34 + hw/arm/virt.c | 29 +- hw/char/cadence_uart.c | 61 +- hw/intc/arm_gicv3.c | 14 + hw/intc/arm_gicv3_common.c | 13 + hw/intc/arm_gicv3_cpuif.c | 7 +- hw/intc/arm_gicv3_dist.c | 5 +- hw/intc/arm_gicv3_its.c | 1322 ++++++++++++++++++++++++++++++++ hw/intc/arm_gicv3_its_common.c | 7 +- hw/intc/arm_gicv3_its_kvm.c | 2 +- hw/intc/arm_gicv3_redist.c | 153 +++- hw/misc/zynq_slcr.c | 31 +- softmmu/qdev-monitor.c | 7 +- target/arm/helper-a64.c | 1 + target/arm/helper.c | 8 + target/arm/kvm.c | 7 +- target/arm/translate-a64.c | 255 +++--- target/arm/translate.c | 21 + hw/intc/meson.build | 1 + tests/data/acpi/virt/IORT | Bin 0 -> 124 bytes tests/data/acpi/virt/IORT.memhp | Bin 0 -> 124 bytes tests/data/acpi/virt/IORT.numamem | Bin 0 -> 124 bytes tests/data/acpi/virt/IORT.pxb | Bin 0 -> 124 bytes 35 files changed, 2144 insertions(+), 210 deletions(-) create mode 100644 hw/intc/arm_gicv3_its.c create mode 100644 tests/data/acpi/virt/IORT create mode 100644 tests/data/acpi/virt/IORT.memhp create mode 100644 tests/data/acpi/virt/IORT.numamem create mode 100644 tests/data/acpi/virt/IORT.pxb