summaryrefslogtreecommitdiff
path: root/doc/board/emulation/qemu-riscv.rst
blob: 61137bcbf1c5c2e482aa9c7f48903592a2ac40e7 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
.. SPDX-License-Identifier: GPL-2.0+
.. Copyright (C) 2018, Bin Meng <bmeng.cn@gmail.com>

QEMU RISC-V
===========

QEMU for RISC-V supports a special 'virt' machine and 'spike' machine designed
for emulation and virtualization purposes. This document describes how to run
U-Boot under it. Both 32-bit and 64-bit targets are supported, running in
either machine or supervisor mode.

The QEMU virt machine models a generic RISC-V virtual machine with support for
the VirtIO standard networking and block storage devices. It has CLINT, PLIC,
16550A UART devices in addition to VirtIO and it also uses device-tree to pass
configuration information to guest software. It implements the latest RISC-V
privileged architecture.

See :doc:`../../develop/devicetree/dt_qemu` for information on how to see
the devicetree actually generated by QEMU.

The QEMU spike machine models a minimalistic RISC-V virtual machine with
only CLINT and HTIF devices. It also uses device-tree to pass configuration
information to guest software and implements the latest RISC-V privileged
architecture.

Building U-Boot
---------------
Set the CROSS_COMPILE environment variable as usual, and run:

- For 32-bit RISC-V::

    make qemu-riscv32_defconfig
    make

- For 64-bit RISC-V::

    make qemu-riscv64_defconfig
    make

This will compile U-Boot for machine mode. To build supervisor mode binaries,
use the configurations qemu-riscv32_smode_defconfig and
qemu-riscv64_smode_defconfig instead. Note that U-Boot running in supervisor
mode requires a supervisor binary interface (SBI), such as RISC-V OpenSBI.

Running U-Boot
--------------
The minimal QEMU command line to get U-Boot up and running is:

- For 32-bit RISC-V virt machine::

    qemu-system-riscv32 -nographic -machine virt -bios u-boot.bin

- For 64-bit RISC-V virt machine::

    qemu-system-riscv64 -nographic -machine virt -bios u-boot.bin

- For 64-bit RISC-V spike machine::

    qemu-system-riscv64 -nographic -machine spike -bios u-boot.bin

The commands above create targets with 128MiB memory by default.
A freely configurable amount of RAM can be created via the '-m'
parameter. For example, '-m 2G' creates 2GiB memory for the target,
and the memory node in the embedded DTB created by QEMU reflects
the new setting.

For instructions on how to run U-Boot in supervisor mode on QEMU
with OpenSBI, see the documentation available with OpenSBI:
https://github.com/riscv/opensbi/blob/master/docs/platform/qemu_virt.md
https://github.com/riscv/opensbi/blob/master/docs/platform/spike.md

These have been tested in QEMU 5.0.0.

Running U-Boot SPL
------------------
In the default SPL configuration, U-Boot SPL starts in machine mode. U-Boot
proper and OpenSBI (FW_DYNAMIC firmware) are bundled as FIT image and made
available to U-Boot SPL. Both are then loaded by U-Boot SPL and the location
of U-Boot proper is passed to OpenSBI. After initialization, U-Boot proper is
started in supervisor mode by OpenSBI.

OpenSBI must be compiled before compiling U-Boot. Version 0.4 and higher is
supported by U-Boot. Clone the OpenSBI repository and run the following command.

.. code-block:: console

    git clone https://github.com/riscv/opensbi.git
    cd opensbi
    make PLATFORM=generic

See the OpenSBI documentation for full details:
https://github.com/riscv/opensbi/blob/master/docs/platform/qemu_virt.md
https://github.com/riscv/opensbi/blob/master/docs/platform/spike.md

To make the FW_DYNAMIC binary (build/platform/generic/firmware/fw_dynamic.bin)
available to U-Boot, either copy it into the U-Boot root directory or specify
its location with the OPENSBI environment variable. Afterwards, compile U-Boot
with the following commands.

- For 32-bit RISC-V::

    make qemu-riscv32_spl_defconfig
    make

- For 64-bit RISC-V::

    make qemu-riscv64_spl_defconfig
    make

The minimal QEMU commands to run U-Boot SPL in both 32-bit and 64-bit
configurations are:

- For 32-bit RISC-V virt machine::

    qemu-system-riscv32 -nographic -machine virt -bios spl/u-boot-spl.bin \
    -device loader,file=u-boot.itb,addr=0x80200000

- For 64-bit RISC-V virt machine::

    qemu-system-riscv64 -nographic -machine virt -bios spl/u-boot-spl.bin \
    -device loader,file=u-boot.itb,addr=0x80200000

- For 64-bit RISC-V spike machine::

    qemu-system-riscv64 -nographic -machine spike -bios spl/u-boot-spl.bin \
    -device loader,file=u-boot.itb,addr=0x80200000

An attached disk can be emulated in RISC-V virt machine by adding::

    -device ich9-ahci,id=ahci \
    -drive if=none,file=riscv64.img,format=raw,id=mydisk \
    -device ide-hd,drive=mydisk,bus=ahci.0

You will have to run 'scsi scan' to use it.

A video console can be emulated in RISC-V virt machine by removing "-nographic"
and adding::

    -serial stdio -device VGA

In addition, a usb keyboard can be attached to an emulated xHCI controller in
RISC-V virt machine as an option of input devices by adding::

    -device qemu-xhci,id=xhci -device usb-kbd,bus=xhci.0

Running with KVM
----------------

Running with QEMU using KVM requires an S-mode U-Boot binary as created by
qemu-riscv64_smode_defconfig.

Provide the U-Boot S-mode ELF image as *-kernel* parameter and do not add a
*-bios* parameter, e.g.

.. code-block:: bash

    qemu-system-riscv64 -accel kvm -nographic -machine virt -kernel u-boot

Debug UART
----------

The following settings provide a debug UART for the virt machine::

    CONFIG_DEBUG_UART=y
    CONFIG_DEBUG_UART_NS16550=y
    CONFIG_DEBUG_UART_BASE=0x10000000
    CONFIG_DEBUG_UART_CLOCK=3686400