Startup mappings

Updated: April 19, 2023

The smmuman configuration can be used to create DMA device to memory region mappings and permissions that the smmuman service reads in when it starts up.

Startup mappings, or client-side API?

When you use the smmuman client-side API to manage DMA device memory mappings and permissions, the smmuman clients (e.g., drivers and other processes) communicate directly with the smmuman service. When you use the smmuman configuration to specify DMA device memory mappings and permissions, you are setting up indirect communication between the DMA device drivers and the smmuman service. Neither the drivers nor the service know about each other. You need to provide the information they require to work together indirectly, through the smmuman configuration, and the startup for each process that will become a smmuman client (e.g., DMA device driver startup).

Depending on the needs of your system, you may want or need to use mappings configured at startup for all the DMA devices and their mapped memory regions on your system, and never use the client-side API.

You may also include in the startup mappings only devices needed immediately at startup, leaving the rest to be added later through the smmuman client-side API, as needed, by DMA device drivers and other processes.

If you are using a legacy DMA device driver (i.e., a driver that pre-dates smmuman and hence doesn't use the smmuman client-side API), you must use the smmuman configuration to create DMA device to memory region mappings and permissions when the smmuman service starts.

Typed memory support

To create the mappings in your smmuman configuration you use typed memory, because typed memory regions can be named. The smmuman configuration uses these names to map memory regions to devices. Thus, your DMA device driver must have an option that allows you to specify typed memory. These options differ from driver to driver (see Starting the drivers for some examples).

If the driver doesn't have such an option, you need to modify the driver. If this is the case, then unless you have a compelling reason not to do so, you should modify the driver to use the smmuman client-side API and use this API to manage your DMA device memory mappings and permissions (see Mapping DMA devices and memory regions through the API in this chapter).

For more information about typed memory, see Typed Memory in the QNX Neutrino OS System Architecture guide.

Tasks

Using the smmuman configuration to create DMA device to memory region mappings and permissions involves the following tasks:

  1. Configuring the smmuman service
  2. Setting aside the typed memory regions at system startup
  3. Starting the drivers
Note: When you specify devices, memory regions and their permissions in the smmuman configuration, you are simply instructing the smmuman service to act as its own client and use its client-side API to map these devices and memory regions.

Configuring the smmuman service

To use the smmuman configuration to create mappings between DMA devices and memory regions, add to the smmuman configuration:

For example:

debug 2

smmu vtd require

allow smbs0   $asinfo_start{smbs0},$asinfo_length{smbs0},st
allow xhci    $asinfo_start{xhci},$asinfo_length{xhci},st
allow hsu0    $asinfo_start{hsu0},$asinfo_length{hsu0},st
allow hsu1    $asinfo_start{hsu1},$asinfo_length{hsu1},st
allow hsu2    $asinfo_start{hsu2},$asinfo_length{hsu2},st
allow ieheci0 $asinfo_start{ieheci0},$asinfo_length{ieheci0},st
allow sdhci   $asinfo_start{sdhci},$asinfo_length{sdhci},st
allow ixgbe   $asinfo_start{ixgbe},$asinfo_length{ixgbe},st

device pci:0:18.0 smbs0
device pci:0:21.0 xhci
device pci:0:26.0 hsu0
device pci:0:26.1 hsu1
device pci:0:26.2 hsu2
device pci:0:27.0 ieheci0
device pci:0:28.0 sdhci
device pci:2:00.1 ixgbe
device pci:2:00.0 ixgbe

Note that the allow option's first argument is allow_name, and that the device uses this name to associate the device with a memory region. In the example above, one mapping (hsu0) is in bold.

The example uses textual substitutions and places the configuration values in the system page tables (see Textual substitutions in this chapter). For more information about how to manage permissions, see the allow and device options under Global options in this chapter.

Setting aside the typed memory regions at system startup

In your system build file, configure your startup program to use the -R option to set aside the typed memory regions you will use for your DMA devices. For example, below is the startup for an x86 board that uses the smmuman service configured as in Configuring the smmuman service above:

### Startup suitable for use with SMMUMAN (with smbus, hsu, IE heci and ethernet)
startup-foo -vv -T  \
-R64K,4K,smbs0 -R8K,4K,hsu0 -R8K,4K,hsu1 -R8K,4K,hsu2 -R128K,4K,ieheci0 -R16M,4K,ixgbe\
-f1700M,1700000000

Note that each instance of the -R option specifies the size of the memory region, its alignment, and a name. This name is the name used in the smmuman configuration to identify each memory region. In the startup configuration above, the memory region identified in bold is the region similarly identified in the smmuman configuration.

Note: Startup programs are included in the QNX BSPs. For more information about startup programs, see Startup Programs in Building Embedded Systems. For more information about the -R startup option, see startup-* options in the Utilities Reference.

Starting the drivers

Finally, after you have specified the DMA device to typed memory mappings in the smmuman configuration, and reserved the typed memory regions in the startup program, you need to start each device driver, specifying by name the typed memory region it has been assigned.

Below are some examples. Notice that the options for specifying the named memory region differ from device to device. In each example the option and the typed memory region name are shown in bold; the name corresponds to a region specified in the startup program and by the smmuman configuration allow option's allow_name argument.

System manager bus driver

io-smb -v -t smbs0 -M slave -i addr=0x46,fifo=5 -c 0x45 -a 0x44

Serial driver

devc-serhsu vid=0x8086,did=0x19d8,pci=0,dma=hsu0 -u 1 -e -b115200

Networking stack and ixgbe driver

io-pkt-v6-hc -ptcpip pkt_typed_mem=ixgbe
mount -T io-pkt -o pci=1,ign_cksum,mac=001122330001, \
typed_mem=ixgbe devnp-ixgbe.so

eMMC driver

devb-sdmmc blk cache=1m cam bounce=128K mem name=sdhci

USB and USB mass storage drivers

io-usb-otg -t memory=xhci -d xhci pindex=0,memory=xhci &
waitfor /dev/usb/io-usb-otg
devb-umass cam pnp bounce=128k mem name=xhci blk memory=xhci &