| 1 | AMD Versal Virt (``amd-versal-virt``, ``amd-versal2-virt``) |
| 2 | =========================================================== |
| 3 | |
| 4 | AMD Versal is a family of heterogeneous multi-core SoCs |
| 5 | (System on Chip) that combine traditional hardened CPUs and I/O |
| 6 | peripherals in a Processing System (PS) with runtime programmable |
| 7 | FPGA logic (PL) and an Artificial Intelligence Engine (AIE). |
| 8 | |
| 9 | QEMU implements the following Versal SoCs variants: |
| 10 | |
| 11 | - Versal (the ``amd-versal-virt`` machine, the alias ``xlnx-versal-virt`` is |
| 12 | kept for backward compatibility) |
| 13 | - Versal Gen 2 (the ``amd-versal2-virt`` machine) |
| 14 | |
| 15 | More details here: |
| 16 | https://www.amd.com/en/products/adaptive-socs-and-fpgas/versal.html |
| 17 | |
| 18 | The family of Versal SoCs share a single architecture but come in |
| 19 | different parts with different speed grades, amounts of PL and |
| 20 | other differences. |
| 21 | |
| 22 | The AMD Versal Virt board in QEMU is a model of a virtual board |
| 23 | (does not exist in reality) with a virtual Versal SoC without I/O |
| 24 | limitations. Currently, we support the following cores and devices: |
| 25 | |
| 26 | Versal |
| 27 | """""" |
| 28 | Implemented CPU cores: |
| 29 | |
| 30 | - 2 ACPUs (Arm Cortex-A72) with their GICv3 and ITS |
| 31 | - 2 RCPUs (Arm Cortex-R5F) with their GICv2 |
| 32 | |
| 33 | Implemented devices: |
| 34 | |
| 35 | - 2 UARTs (Arm PL011) |
| 36 | - An RTC (Versal built-in) |
| 37 | - 2 GEMs (Cadence MACB Ethernet MACs) |
| 38 | - 8 ADMA (Xilinx zDMA) channels |
| 39 | - 2 SD Controllers |
| 40 | - OCM (256KB of On Chip Memory) |
| 41 | - XRAM (4MB of on chip Accelerator RAM) |
| 42 | - DDR memory |
| 43 | - BBRAM (36 bytes of Battery-backed RAM) |
| 44 | - eFUSE (3072 bytes of one-time field-programmable bit array) |
| 45 | - 2 CANFDs |
| 46 | - USB controller |
| 47 | - OSPI controller |
| 48 | - TRNG controller |
| 49 | |
| 50 | Versal Gen 2 |
| 51 | """""""""""" |
| 52 | Implemented CPU cores: |
| 53 | |
| 54 | - 8 ACPUs (Arm Cortex-A78AE) with their GICv3 and ITS |
| 55 | - 10 RCPUs (Arm Cortex-R52) with their GICv3 (one per cluster) |
| 56 | |
| 57 | Implemented devices: |
| 58 | |
| 59 | - 2 UARTs (Arm PL011) |
| 60 | - An RTC (Versal built-in) |
| 61 | - 3 GEMs (Cadence MACB Ethernet MACs) |
| 62 | - 8 ADMA (Xilinx zDMA) channels |
| 63 | - 2 SD Controllers |
| 64 | - OCM (256KB of On Chip Memory) |
| 65 | - DDR memory |
| 66 | - BBRAM (36 bytes of Battery-backed RAM) |
| 67 | - 2 CANFDs |
| 68 | - 2 USB controllers |
| 69 | - OSPI controller |
| 70 | - TRNG controller |
| 71 | |
| 72 | QEMU does not yet model any other devices, including the PL and the AI Engine. |
| 73 | |
| 74 | Other differences between the hardware and the QEMU model: |
| 75 | |
| 76 | - QEMU allows the amount of DDR memory provided to be specified with the |
| 77 | ``-m`` argument. If a DTB is provided on the command line then QEMU will |
| 78 | edit it to include suitable entries describing the Versal DDR memory ranges. |
| 79 | |
| 80 | - QEMU provides 8 virtio-mmio virtio transports. They use reserved memory |
| 81 | regions and IRQ pins to avoid conflicts with real SoC peripherals. |
| 82 | |
| 83 | Running |
| 84 | """"""" |
| 85 | If the user provides an Operating System to be loaded, we expect users |
| 86 | to use the ``-kernel`` command line option. |
| 87 | |
| 88 | Users can load firmware or boot-loaders with the ``-device loader`` options. |
| 89 | |
| 90 | When loading an OS, QEMU generates a DTB and selects an appropriate address |
| 91 | where it gets loaded. This DTB will be passed to the kernel in register x0. |
| 92 | |
| 93 | If there's no ``-kernel`` option, we generate a DTB and place it at 0x1000 |
| 94 | for boot-loaders or firmware to pick it up. To dump and observe the generated |
| 95 | DTB, one can use the ``dumpdtb`` machine option: |
| 96 | |
| 97 | .. code-block:: bash |
| 98 | |
| 99 | $ qemu-system-aarch64 -M amd-versal-virt,dumpdtb=example.dtb -m 2G |
| 100 | |
| 101 | |
| 102 | If users want to provide their own DTB, they can use the ``-dtb`` option. |
| 103 | These DTBs will have their memory nodes modified to match QEMU's |
| 104 | selected ram_size option before they get passed to the kernel or FW. |
| 105 | |
| 106 | When loading an OS, we turn on QEMU's PSCI implementation with SMC |
| 107 | as the PSCI conduit. When there's no ``-kernel`` option, we assume the user |
| 108 | provides EL3 firmware to handle PSCI. |
| 109 | |
| 110 | A few examples: |
| 111 | |
| 112 | Direct Linux boot of a generic ARM64 upstream Linux kernel: |
| 113 | |
| 114 | .. code-block:: bash |
| 115 | |
| 116 | $ qemu-system-aarch64 -M amd-versal-virt -m 2G \ |
| 117 | -serial mon:stdio -display none \ |
| 118 | -kernel arch/arm64/boot/Image \ |
| 119 | -nic user -nic user \ |
| 120 | -device virtio-rng-device,bus=virtio-mmio-bus.0 \ |
| 121 | -drive if=none,index=0,file=hd0.qcow2,id=hd0,snapshot \ |
| 122 | -drive file=qemu_sd.qcow2,if=sd,index=0,snapshot \ |
| 123 | -device virtio-blk-device,drive=hd0 -append root=/dev/vda |
| 124 | |
| 125 | Direct Linux boot of PetaLinux 2019.2: |
| 126 | |
| 127 | .. code-block:: bash |
| 128 | |
| 129 | $ qemu-system-aarch64 -M amd-versal-virt -m 2G \ |
| 130 | -serial mon:stdio -display none \ |
| 131 | -kernel petalinux-v2019.2/Image \ |
| 132 | -append "rdinit=/sbin/init console=ttyAMA0,115200n8 earlycon=pl011,mmio,0xFF000000,115200n8" \ |
| 133 | -net nic,model=cadence_gem,netdev=net0 -netdev user,id=net0 \ |
| 134 | -device virtio-rng-device,bus=virtio-mmio-bus.0,rng=rng0 \ |
| 135 | -object rng-random,filename=/dev/urandom,id=rng0 |
| 136 | |
| 137 | Boot PetaLinux 2019.2 via Arm Trusted Firmware (2018.3 because the 2019.2 |
| 138 | version of ATF tries to configure the CCI which we don't model) and U-boot: |
| 139 | |
| 140 | .. code-block:: bash |
| 141 | |
| 142 | $ qemu-system-aarch64 -M amd-versal-virt -m 2G \ |
| 143 | -serial stdio -display none \ |
| 144 | -device loader,file=petalinux-v2018.3/bl31.elf,cpu-num=0 \ |
| 145 | -device loader,file=petalinux-v2019.2/u-boot.elf \ |
| 146 | -device loader,addr=0x20000000,file=petalinux-v2019.2/Image \ |
| 147 | -nic user -nic user \ |
| 148 | -device virtio-rng-device,bus=virtio-mmio-bus.0,rng=rng0 \ |
| 149 | -object rng-random,filename=/dev/urandom,id=rng0 |
| 150 | |
| 151 | Run the following at the U-Boot prompt: |
| 152 | |
| 153 | .. code-block:: bash |
| 154 | |
| 155 | Versal> |
| 156 | fdt addr $fdtcontroladdr |
| 157 | fdt move $fdtcontroladdr 0x40000000 |
| 158 | fdt set /timer clock-frequency <0x3dfd240> |
| 159 | setenv bootargs "rdinit=/sbin/init maxcpus=1 console=ttyAMA0,115200n8 earlycon=pl011,mmio,0xFF000000,115200n8" |
| 160 | booti 20000000 - 40000000 |
| 161 | fdt addr $fdtcontroladdr |
| 162 | |
| 163 | Boot Linux as DOM0 on Xen via U-Boot: |
| 164 | |
| 165 | .. code-block:: bash |
| 166 | |
| 167 | $ qemu-system-aarch64 -M amd-versal-virt -m 4G \ |
| 168 | -serial stdio -display none \ |
| 169 | -device loader,file=petalinux-v2019.2/u-boot.elf,cpu-num=0 \ |
| 170 | -device loader,addr=0x30000000,file=linux/2018-04-24/xen \ |
| 171 | -device loader,addr=0x40000000,file=petalinux-v2019.2/Image \ |
| 172 | -nic user -nic user \ |
| 173 | -device virtio-rng-device,bus=virtio-mmio-bus.0,rng=rng0 \ |
| 174 | -object rng-random,filename=/dev/urandom,id=rng0 |
| 175 | |
| 176 | Run the following at the U-Boot prompt: |
| 177 | |
| 178 | .. code-block:: bash |
| 179 | |
| 180 | Versal> |
| 181 | fdt addr $fdtcontroladdr |
| 182 | fdt move $fdtcontroladdr 0x20000000 |
| 183 | fdt set /timer clock-frequency <0x3dfd240> |
| 184 | fdt set /chosen xen,xen-bootargs "console=dtuart dtuart=/uart@ff000000 dom0_mem=640M bootscrub=0 maxcpus=1 timer_slop=0" |
| 185 | fdt set /chosen xen,dom0-bootargs "rdinit=/sbin/init clk_ignore_unused console=hvc0 maxcpus=1" |
| 186 | fdt mknode /chosen dom0 |
| 187 | fdt set /chosen/dom0 compatible "xen,multiboot-module" |
| 188 | fdt set /chosen/dom0 reg <0x00000000 0x40000000 0x0 0x03100000> |
| 189 | booti 30000000 - 20000000 |
| 190 | |
| 191 | Boot Linux as Dom0 on Xen via Arm Trusted Firmware and U-Boot: |
| 192 | |
| 193 | .. code-block:: bash |
| 194 | |
| 195 | $ qemu-system-aarch64 -M amd-versal-virt -m 4G \ |
| 196 | -serial stdio -display none \ |
| 197 | -device loader,file=petalinux-v2018.3/bl31.elf,cpu-num=0 \ |
| 198 | -device loader,file=petalinux-v2019.2/u-boot.elf \ |
| 199 | -device loader,addr=0x30000000,file=linux/2018-04-24/xen \ |
| 200 | -device loader,addr=0x40000000,file=petalinux-v2019.2/Image \ |
| 201 | -nic user -nic user \ |
| 202 | -device virtio-rng-device,bus=virtio-mmio-bus.0,rng=rng0 \ |
| 203 | -object rng-random,filename=/dev/urandom,id=rng0 |
| 204 | |
| 205 | Run the following at the U-Boot prompt: |
| 206 | |
| 207 | .. code-block:: bash |
| 208 | |
| 209 | Versal> |
| 210 | fdt addr $fdtcontroladdr |
| 211 | fdt move $fdtcontroladdr 0x20000000 |
| 212 | fdt set /timer clock-frequency <0x3dfd240> |
| 213 | fdt set /chosen xen,xen-bootargs "console=dtuart dtuart=/uart@ff000000 dom0_mem=640M bootscrub=0 maxcpus=1 timer_slop=0" |
| 214 | fdt set /chosen xen,dom0-bootargs "rdinit=/sbin/init clk_ignore_unused console=hvc0 maxcpus=1" |
| 215 | fdt mknode /chosen dom0 |
| 216 | fdt set /chosen/dom0 compatible "xen,multiboot-module" |
| 217 | fdt set /chosen/dom0 reg <0x00000000 0x40000000 0x0 0x03100000> |
| 218 | booti 30000000 - 20000000 |
| 219 | |
| 220 | It's possible to change the OSPI flash model emulated by using the machine model |
| 221 | option ``ospi-flash``. |
| 222 | |
| 223 | BBRAM File Backend |
| 224 | """""""""""""""""" |
| 225 | BBRAM can have an optional file backend, which must be a seekable |
| 226 | binary file with a size of 36 bytes or larger. A file with all |
| 227 | binary 0s is a 'blank'. |
| 228 | |
| 229 | To add a file-backend for the BBRAM: |
| 230 | |
| 231 | .. code-block:: bash |
| 232 | |
| 233 | -drive if=pflash,index=0,file=versal-bbram.bin,format=raw |
| 234 | |
| 235 | To use a different index value, N, from default of 0, add: |
| 236 | |
| 237 | .. code-block:: bash |
| 238 | |
| 239 | -global driver=xlnx.bbram-ctrl,property=drive-index,value=N |
| 240 | |
| 241 | eFUSE File Backend |
| 242 | """""""""""""""""" |
| 243 | |
| 244 | .. note:: |
| 245 | The eFUSE device is not implemented in the Versal Gen 2 QEMU model |
| 246 | yet. |
| 247 | |
| 248 | eFUSE can have an optional file backend, which must be a seekable |
| 249 | binary file with a size of 3072 bytes or larger. A file with all |
| 250 | binary 0s is a 'blank'. |
| 251 | |
| 252 | To add a file-backend for the eFUSE: |
| 253 | |
| 254 | .. code-block:: bash |
| 255 | |
| 256 | -drive if=pflash,index=1,file=versal-efuse.bin,format=raw |
| 257 | |
| 258 | To use a different index value, N, from default of 1, add: |
| 259 | |
| 260 | .. code-block:: bash |
| 261 | |
| 262 | -global xlnx-efuse.drive-index=N |
| 263 | |
| 264 | .. warning:: |
| 265 | In actual physical Versal, BBRAM and eFUSE contain sensitive data. |
| 266 | The QEMU device models do **not** encrypt nor obfuscate any data |
| 267 | when holding them in models' memory or when writing them to their |
| 268 | file backends. |
| 269 | |
| 270 | Thus, a file backend should be used with caution, and 'format=luks' |
| 271 | is highly recommended (albeit with usage complexity). |
| 272 | |
| 273 | Better yet, do not use actual product data when running guest image |
| 274 | on this AMD Versal Virt board. |
| 275 | |
| 276 | Using CANFDs for Versal Virt |
| 277 | """""""""""""""""""""""""""" |
| 278 | Versal CANFD controller is developed based on SocketCAN and QEMU CAN bus |
| 279 | implementation. Bus connection and socketCAN connection for each CAN module |
| 280 | can be set through command lines. |
| 281 | |
| 282 | To connect both CANFD0 and CANFD1 on the same bus: |
| 283 | |
| 284 | .. code-block:: bash |
| 285 | |
| 286 | -object can-bus,id=canbus -machine canbus0=canbus -machine canbus1=canbus |
| 287 | |
| 288 | To connect CANFD0 and CANFD1 to separate buses: |
| 289 | |
| 290 | .. code-block:: bash |
| 291 | |
| 292 | -object can-bus,id=canbus0 -object can-bus,id=canbus1 \ |
| 293 | -machine canbus0=canbus0 -machine canbus1=canbus1 |
| 294 | |
| 295 | The SocketCAN interface can connect to a Physical or a Virtual CAN interfaces on |
| 296 | the host machine. Please check this document to learn about CAN interface on |
| 297 | Linux: docs/system/devices/can.rst |
| 298 | |
| 299 | To connect CANFD0 and CANFD1 to host machine's CAN interface can0: |
| 300 | |
| 301 | .. code-block:: bash |
| 302 | |
| 303 | -object can-bus,id=canbus -machine canbus0=canbus -machine canbus1=canbus |
| 304 | -object can-host-socketcan,id=canhost0,if=can0,canbus=canbus |
| 305 | |
| 306 | .. note:: |
| 307 | Versal Gen 2 has 4 CAN controllers. ``canbus0`` to ``canbus3`` can |
| 308 | be specified on the command line. |