Overview
This file holds the UEFI build and evaluate instructions for RiscV Virt machine including a S-Mode EDK2 firmware and a StandaloneMm firmware which can be taken as a payload of the OpenSBI and run in a domain isolated by using the PMP/sPMP (re-used some Penglai code and put to OpenSBI).
We added MM service group in the RPMI spec https://docs.google.com/document/d/199ar3Ddd-FlzP1FR3HOkbBf1BNvLUPvJ, and evaluted the StandaloneMmPkg proejct based on the RPMI PoC mentioned here https://lists.riscv.org/g/tech-prs/message/593.
How to build (Linux Environment)
Create work space
Create a directory that would hold source code of the components.
- EDK2: https://github.com/tianocore/edk2-staging/tree/RiscV64StandaloneMm
- OpenSBI: https://github.com/Penglai-Enclave/opensbi/tree/dev-standalonemm-rpmi
- QMEU: https://github.com/yli147/qemu/tree/dev-standalonemm-rpmi
Manually build
Compile QEMU
```
git clone https://github.com/yli147/qemu.git -b dev-standalonemm-rpmi
export WORKDIR=`pwd`
cd qemu
./configure --target-list=riscv64-softmmu
make -j $(nproc)
```
Compile UEFI and StandaloneMM
```
cd $WORKDIR
git clone https://github.com/tianocore/edk2-staging.git -b RiscV64StandaloneMm
cd edk2-staging
git submodule update --init --recursive --depth=1
. edksetup.sh
make -C BaseTools
export GCC5_RISCV64_PREFIX=/usr/bin/riscv64-linux-gnu-
build -a RISCV64 -t GCC5 -p OvmfPkg/RiscVVirt/RiscVVirtQemu.dsc -b DEBUG -DSECURE_BOOT_ENABLE=TRUE
build -a RISCV64 -t GCC5 -p OvmfPkg/RiscVVirt/RiscVVirtQemuStandaloneMm.dsc -b DEBUG -D FW_BASE_ADDRESS=0x80C00000
cp Build/RiscVVirtQemu/DEBUG_GCC5/FV/RISCV_VIRT_CODE.fd $WORKDIR
cp Build/RiscVVirtQemu/DEBUG_GCC5/FV/RISCV_VIRT_VARS.fd $WORKDIR
cp Build/RiscVVirtQemuStandaloneMm/DEBUG_GCC5/FV/STANDALONE_MM.fd $WORKDIR
```
Compile OpenSBI
```
cd $WORKDIR
git clone https://github.com/Penglai-Enclave/opensbi.git -b dev-standalonemm-rpmi
cd opensbi
CROSS_COMPILE=riscv64-linux-gnu- make FW_PIC=n PLATFORM=generic
cp build/platform/generic/firmware/fw_dynamic.elf $WORKDIR
```
Run the UEFI and StandaloneMm firmware
UEFI and MM Memory layout
UEFI and MM Boot Flow on QEMU
OpenSBI Domain and Secure/Non-Secure Context Switch Flow
Edit the Device Tree
Download this qemu-virt.dts manually and copy to the $WORKDIR, then generate the new dtb file, (ignore the interrupts_extended_property warnings)
```
cd $WORKDIR
dtc -I dts -O dtb -o qemu-virt-new.dtb qemu-virt.dts
```
Run in QEMU
The EDK2 EFI firmware will be put at 0x20000000 which is the flash0 block in Qemu virt machine, The secure variable storage will be put at 0x22000000 which is the flash1 block in Qemu virt machine.
Create a "run.sh" script with below content, or you can download it here
nc -z 127.0.0.1 54320 || /usr/bin/gnome-terminal -x ./soc_term.py 54320 & nc -z 127.0.0.1 54321 || /usr/bin/gnome-terminal -x ./soc_term.py 54321 & while ! nc -z 127.0.0.1 54320 || ! nc -z 127.0.0.1 54321; do sleep 1; done ./qemu/build/qemu-system-riscv64 -d guest_errors -D guest_log.txt \ -M virt,pflash0=pflash0,pflash1=pflash1,aia=aplic-imsic,acpi=off,hmat=on,rpmi=on \ -dtb ./qemu-virt-new.dtb \ -m 4G,slots=2,maxmem=8G -object memory-backend-ram,size=2G,id=m0 -object memory-backend-ram,size=2G,id=m1 \ -numa node,nodeid=0,memdev=m0 -numa node,nodeid=1,memdev=m1 -smp 2,sockets=2,maxcpus=2 \ -bios ./fw_dynamic.elf \ -device loader,file=STANDALONE_MM.fd,addr=0x80C00000 \ -blockdev node-name=pflash0,driver=file,read-only=on,filename=./RISCV_VIRT_CODE.fd \ -blockdev node-name=pflash1,driver=file,filename=./RISCV_VIRT_VARS.fd \ -serial tcp:localhost:54320 -serial tcp:localhost:54321 \ -drive file=fat:rw:~/src/fat,id=hd0 -device virtio-blk-device,drive=hd0 \ -nographic -device virtio-net-pci,netdev=usernet -netdev user,id=usernet,hostfwd=tcp::9990-:22
Then downlaod the soc_term.py script and run the run.sh script in Linux desktop GUI envrionment shell
```
wget -c https://github.com/DevendraDevadiga/optee_qemu_armv8a_prebuilt_binaries/raw/main/optee_qemu_armv8a/soc_term.py
truncate -s 32M ./RISCV_VIRT_CODE.fd
truncate -s 32M ./RISCV_VIRT_VARS.fd
chmod a+x soc_term.py
chmod a+x run.sh
./run.sh
```
<Normal World EDK2 log> <Secure World StandaloneMm log>