Global options

Options for the smmuman service may be specified in the command line, or in a configuration file (e.g., mysystem.smmu), or both.

The smmuman configuration uses options, which may have arguments. Options and arguments available for all supported hardware platforms are described below.

About notation

The default notations (no prefix needed) for specifying memory addresses and sizes are:

For example, allow foo 4000,4096 refers to a memory region that starts at address 0x4000 and has a size of 4096 (0x1000) bytes .

If you prefer to write a memory address or region size with a notation other than the default, you can use a prefix to specify the notation:

Thus, the following are equivalent:

allow foo 0x4000,4096
allow foo 4000,4096
allow foo 0x4000,0x1000
allow foo 0x4000,0d4096
allow foo 0d16384,4096
allow foo 0d16384,0d4096
allow foo 0d16384,0x1000

You can use size multipliers: “K”, “M”, “G” (or “k”, “m”, “g”) in the address and length arguments; for example: allow foo 4K,1k is equivalent to allow foo 0x1000,0x400. (Remember: the size multipliers are decimal multipliers, so 4K is 4 x 1024 = 4096, or 0x1000.)

Other numeric configuration values are specified in decimal; for example, in device pci:0:18.0 foo the values for bus, dev, and func are decimal values (see device below).

Note: We recommend that, to avoid confusion, when using hexadecimal values you specify the prefix; for example: allow foo 0x4000,4096.


allow allow_name start,len[,permissions]

Add to the set of addresses DMA may be used to or from. Use the arguments as follows:

Note: The recommended method for allocating memory for devices is to use the SMMUMAN API in libsmmu.a (see SMMUMAN Client API Reference. The smmuman has the allow so it can support legacy drivers (see Startup mappings in this chapter).


debug 1|2

Output debugging information. Specify 2 for more verbose output.

During intialization, all smmuman output goes to both stderr and slog2. Afterwards, smmuman output goes to slog2 only.


device device_spec [allow_name]

Set the current device being configured to device_spec.

Note that:

The device_spec argument may take the following values:


Specify increasingly detailed information about a PCI device, as follows:

  • pci:* — any PCI device
  • pci:bus:* — any PCI device on bus bus
  • pci:bus:dev.* — any function number on PCI device dev on bus bus
  • pci:bus:dev.func — function func on PCI device dev on bus bus
Specify a memory-mapped I/O device at physical address paddr for length bytes.

Devices may be attached to only one SMMU object at a time. The process that creates the SMMU object and attaches devices to it has exclusive control of the SMMU object and of the memory mappings and memory access permissions for the attached devices.

If you use the startup configuration to map a memory region for a device, the smmuman service controls both the SMMU object, and the device's memory mappings and memory access permissions. Your smmuman clients won't be able to modify these mappings and permissions, or even remove the device from the SMMU object controlled by the smmuman service.

Thus, if you may need to modify a device's memory mappings or memory access permissions after startup, you can specify the device in the startup configuration, but you can't use the device allow_name argument and assign memory regions to the device.

Memory sharing

The following shows two devices configured to share the same memory region:

smmu vtd require

allow foo   0xF8000000,0x4000,st
allow moo   0xF8000000,0x4000,st

device pci:0:18.0 foo
device pci:0:21.0 moo

Both the foo and moo allow options specify the same memory region (starting at 0xF8000000, for 0x4000 bytes), and both have their permissions set to st, so devices configured with their allow_name arguments set to foo or moo will have permission to read and write this region.

The smmuman configuration syntax provides a better way to achieve the same result, however. You can specify the the same allow_name argument for multiple devices (e.g., foo), so that all devices with this allow_name argument can read and write the same memory region:

allow foo   0xF8000000,0x4000,st

device pci:0:18.0 foo
device pci:0:21.0 foo

Since this method requires only a single allow option entry, it uses less system page memory than the previous configuration.

Finally, if several devices require access to the same memory region but with different permissions, you must use the allow option to specify different memory region names. For example, in the configuration below, devices pci:0:18.0 and pci:0:21:0 may read from the memory region at 0xF8000000,0x4000, but only device pci:0:26.2 may both read and write the region:

allow foo   0xF8000000,0x4000,s
allow moo   0xF8000000,0x4000,st

device pci:0:18.0 foo
device pci:0:21.0 foo
device pci:0:26.2 moo



After parsing the configuration, leave the smmuman service running in the foreground. The default is to leave smmuman running in the background.


reserved start_paddr,length

If this option is used, it applies to the device specified by the preceding device option.

Some devices may need to access a specific memory region in order to function (e.g., they may need access to code or to data tables found at specific locations on the hardware). For example, a graphics device may store its font definitions separately from the text it will display. This is typical for x86 boards, and for these boards the ACPI tables should provide all the information needed to reserve the required memory regions for whatever devices need them.


Remember: reserved memory isn't the same as a mapped memory region:

  • Reserved memory is only required for some devices, and is used for ancillary data, such as font definitions.
  • Typically, the smmuman retrieves the required location and size of reserved memory from the board, and programs this information into the IOMMU/SMMUs without your having to specifically ask it to do so.
  • Your smmuman client should know what memory regions it has asked the smmuman service to map for which devices, but the client needs to use the smmu_device_report_reserved() function to learn what reserved memory (if any) has been assigned to a DMA device.

You need to use the reserved option to manually set aside such regions only if the information isn't available from the board firmware. For example, if on an x86 board the ACPI DMAR tables weren't available, you would need to use the ignore option, then specify the VT-d units and the devices. Your configuration might include something like the following:

smmu vtd ignore
	unit vtd1 0xfed64000
	unit vtd2 0xfed65000

device pci:0:2.0
	use vtd1
	reserved 0x7b800000,0x4800000

device pci:*
	use vtd2

device pci:0:21.0
	reserved 0x7afe0000,0x20000

device pci:0:21.1
	reserved 0x7afe0000,0x20000

Note that no space is permitted between the start_paddr and length arguments; thus reserved 0x7afe0000,0x20000 is permitted, but reserved 0x7afe0000, 0x20000 will fail.


If a board doesn't provide information it should provide (e.g., the ACPI DMAR tables), the board likely has other problems as well, and you should consult your board manufacturer.

Additionally, any change to your board (e.g., firmware revision) will oblige you to revisit a configuration that uses the ignore option:

  • x86 – the addresses for the VT-d units may change with any firmware revision; the firmware specification doesn't provide any recommendations or guidelines.
  • ARM – the reserved regions for the GPU and for USB support may change if the board RAM layout changes.

For more information about configuring the smmuman service for x86 platforms, see Options for x86 IOMMUs (VT-ds) in this chapter.


safety none|warn|required

Specify how the smmuman service responds if any of the components on which it depends (e.g., procnto) isn't a safety-certified component:

Ignore the presence of a non-safety component and just run.
If any component isn't safety-certified, issue a warning, and run.
If a component isn't safety-certified, issue an error message and move to the DSS (see Design Safe State (DSS)).

Default behaviors are as follows:

You can use multiple instances of the safety option to specify different responses for different components. For example, in a safety-related system you might use an uncertified support file and have the smmuman service issue only a warning for that file, but move to its DSS if any other component isn't certified.

If more than one instance of the safety option is specified, the final instance is used to specify the smmuman service's global response to the presence of uncertified components (i.e., how it should respond to the presence of an uncertified procnto and other components not otherwise explicitly specified in the configuration).

Including non-safety SMMUMAN components in a system invalidates the system's safety-certification.


set var val

The set option supports the following variables types:

You can use the command line at startup to display currently permitted variables and their contexts. For example:

smmuman set ?
	grow-heap			(address, global)
	message-block-timeout		(number, global)
	slogger2-required		(boolean, global)
Note: A question mark (?) is a shell wildcard character, so you may need to escape it.
  • Context: global – applies to the entire service
  • Variable type: address
  • Default: don't grow the heap

Grow the heap by the amount specified by val. For example:

set grow-heap 0x4000

will increase the heap by 16384 bytes.

  • Context: global – applies to the entire service
  • Variable type: number
  • Default: 100 milliseconds

Set the maximum allowed time, in milliseconds, that a message from the smmuman service may be blocked before the service sends an unblock pulse to the receiving server. For example:

set message-block-timeout 200

configures the smmuman service to send an unblock pulse to any server that doesn't respond to a message within 200 milliseconds.

The set message-block-timeout variable must be a value from 5 through 10000, or 0 (zero). A 0 makes the timeout infinite (never time out).
Depending on the server's response (or non-response), the smmuman service may terminate with an error. You can use server-monitor to handle situations where a server doesn't respond to an unblock pulse (see server-monitor in the QNX Neutrino Utilities Reference).
  • Context: global – applies to the entire service
  • Variable type: boolean
  • Default: on
Log messages to a slogger2 buffer.
Note: Currently, all set variables for the smmuman service are global (i.e., specify the variable once and it applies to the entire service).


smmu smmu_type [smmu_type_parm]

Load the support library, and call its initialization routine, passing smmu_type_parm to the routine. For example:

smmu vtd

will load the support library needed for x86 boards.

smmu rcar3 0xe67b0000,228,0x4f.0x01,0x4f.0x10,0x4f.0x20

will load the library with the specified arguments.

For more information about smmu_type_parm, see the architecture-specific and board-specific sections in this chapter.


unit unit_name [smmu_unit_parm]

Define an individual IOMMU/SMMU unit with name unit_name. The type of the unit will be from the preceeding smmu option.

The unit initialization routine will be invoked and passed smmu_unit_parm. For example, for an ARM Renesas R-Car H3 board:

smmu rcar3 0xe67b0000,228,0x4f.0x01,0x4f.0x10,0x4f.0x20
	unit vi0 0xfebd0000,14	# video IO domain AXI
	unit vi1 0xfebe0000,15	# video IO domain AXI
	unit ir  0xff8b0000,3	# IMP domain AXI
	unit hc  0xe6570000,2	# high communication domain AXI

Or, for an x86 board:

smmu vtd ignore
	unit vtd1 0xfed64000
	unit vtd2 0xfed65000

For more information about smmu_unit_parm, see the architecture-specific and board-specific sections in this chapter.


use unit_name [smmu_use_parm]

The current device (specified by the preceeding device option) will use the IOMMU/SMMU unit identified by unit_name. The smmu_use_parm provides additional information on the device to the IOMMU/SMMU unit.

For more information about smmu_use_parm, see the architecture-specific and board-specific sections in this chapter.


user uid[:gid[,sup_gid]*] | user_name[,sup_gid]*

Set the user ID (uid) and group ID (gid) and, optionally, supplementary group IDs (sup_gid) the smmuman service runs with, so that it doesn't have to run as root. In the second form, the primary group is the one specified for user_name in /etc/passwd.

For more information about user and group IDs, see Process privileges in the QNX Neutrino Programmer's Guide.”