Skip to content

Commit

Permalink
riscv: support qemu-riscv-virt platform
Browse files Browse the repository at this point in the history
Signed-off-by: Axel Heider <[email protected]>
  • Loading branch information
Axel Heider committed Apr 14, 2022
1 parent 8278066 commit fa00480
Show file tree
Hide file tree
Showing 5 changed files with 161 additions and 3 deletions.
1 change: 1 addition & 0 deletions CHANGES
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ Upcoming release: BINARY COMPATIBLE

* Added support for the ARM Cortex A55
* Added support for the ODroid C4
* Added support for qemu-riscv-virt
* Rename libsel4 config option ENABLE_SMP_SUPPORT to CONFIG_ENABLE_SMP_SUPPORT to be namespace compliant.
* Rename libsel4 config option AARCH64_VSPACE_S2_START_L1 to CONFIG_AARCH64_VSPACE_S2_START_L1 to be namespace
compliant.
Expand Down
9 changes: 6 additions & 3 deletions include/drivers/irq/riscv_plic0.h
Original file line number Diff line number Diff line change
Expand Up @@ -4,15 +4,18 @@
*
* SPDX-License-Identifier: GPL-2.0-only
*
* SiFive U54/U74 PLIC handling (HiFive Unleashed/Unmatched, Polarfire)
* SiFive U54/U74 PLIC handling (HiFive Unleashed/Unmatched, Polarfire,
* QEMU RISC-V virt)
*/

#pragma once

/* This is a check that prevents using this driver blindly. Extend the list if
* this driver is confirmed to be working on other platforms. */
#if !defined(CONFIG_PLAT_HIFIVE) && !defined(CONFIG_PLAT_POLARFIRE)
#error "This code supports the SiFive U54/U74 PLIC only."
#if !defined(CONFIG_PLAT_HIFIVE) && \
!defined(CONFIG_PLAT_POLARFIRE) && \
!defined(CONFIG_PLAT_QEMU_RISCV_VIRT)
#error "Check if this platform suppots a PLIC."
#endif

/* tell the kernel we have the set trigger feature */
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
/*
* Copyright 2022, HENSOLDT Cyber
*
* SPDX-License-Identifier: BSD-2-Clause
*/

#pragma once

#include <autoconf.h>

/* nothing here */
123 changes: 123 additions & 0 deletions src/plat/qemu-riscv-virt/config.cmake
Original file line number Diff line number Diff line change
@@ -0,0 +1,123 @@
#
# Copyright 2022, HENSOLDT Cyber
# Copyright 2020, Data61, CSIRO (ABN 41 687 119 230)
#
# SPDX-License-Identifier: GPL-2.0-only
#

cmake_minimum_required(VERSION 3.7.2)

declare_platform(qemu-riscv-virt KernelPlatformQEMURiscVVirt PLAT_QEMU_RISCV_VIRT KernelArchRiscV)

if(KernelPlatformQEMURiscVVirt)

# ToDo: use setup_seL4_arch("riscv64;riscv32")
if("${KernelSel4Arch}" STREQUAL riscv64)
declare_seL4_arch(riscv64)
elseif("${KernelSel4Arch}" STREQUAL riscv32)
declare_seL4_arch(riscv32) # This is still untested
else()
fallback_declare_seL4_arch_default(riscv64)
endif()

config_set(KernelOpenSBIPlatform OPENSBI_PLATFORM "generic")
config_set(KernelPlatformFirstHartID FIRST_HART_ID 0)

# Unless QEMU_DTS is set explicitly, the device tree is extract from QEMU.
# This keeps it nicely up to date with the newer QEMU versions and is quite
# convenient for the development usecase.
if(NOT DEFINED QEMU_DTS)

message(STATUS "Extracting device tree from QEMU")

set(QEMU_DT_BASE_NAME "${CMAKE_BINARY_DIR}/qemu-riscv-virt")
set(QEMU_DTB "${QEMU_DT_BASE_NAME}.dtb")
set(QEMU_DTS "${QEMU_DT_BASE_NAME}.dts")

set(QEMU_RISCV_VIRT_BINARY "qemu-system-${KernelSel4Arch}")
find_program(QEMU_RISCV_VIRT ${QEMU_RISCV_VIRT_BINARY})

# RISC-V virtual platform works since QEMU v5.1.0
set(QEMU_RISCV_VIRT_MIN_VERSION "5.1.0")
execute_process(
COMMAND ${QEMU_RISCV_VIRT} -version
RESULT_VARIABLE error
OUTPUT_VARIABLE QEMU_STDOUT_MESSAGE
)
if(error)
message(FATAL_ERROR "Failed to determine QEMU version (${QEMU_RISCV_VIRT})")
endif()
string(
REGEX
MATCH
"[0-9](\\.[0-9])+"
QEMU_VERSION
"${QEMU_STDOUT_MESSAGE}"
)
if("${QEMU_VERSION}" VERSION_LESS "${QEMU_RISCV_VIRT_MIN_VERSION}")
message(
FATAL_ERROR
"Error: need at least QEMU version ${QEMU_RISCV_VIRT_MIN_VERSION}, found '${QEMU_VERSION}'"
)
endif()

if(NOT DEFINED QEMU_MACHINE)
set(QEMU_MACHINE "virt")
endif()

if(NOT DEFINED QEMU_CPU)
set(QEMU_CPU "rv${KernelWordSize}")
endif()

if(NOT DEFINED QEMU_MEMORY)
# Having 2 GiB of memory as default seems a good trade-off. It's
# sufficient for test/demo systems, but still something the host can
# provide without running short on resources.
set(QEMU_MEMORY "2048M")
endif()

if(KernelMaxNumNodes)
set(QEMU_SMP_OPTION "${KernelMaxNumNodes}")
else()
set(QEMU_SMP_OPTION "1")
endif()


# run QEMU to get the device tree binary
execute_process(
COMMAND
${QEMU_RISCV_VIRT}
-machine ${QEMU_MACHINE},dumpdtb="${QEMU_DTB}"
-cpu ${QEMU_CPU}
-smp ${QEMU_SMP_OPTION}
-m ${QEMU_MEMORY}
-nographic
RESULT_VARIABLE error
)
if(error)
message(FATAL_ERROR "Failed to dump DTB using ${QEMU_RISCV_VIRT})")
endif()

# convert device tree binary to human readable device tree
execute_process(
COMMAND
dtc -q -I dtb -O dts -o "${QEMU_DTS}" "${QEMU_DTB}"
RESULT_VARIABLE error
)
if(error)
message(FATAL_ERROR "Failed to convert QEMU's DTB to a DTS (${QEMU_DTB})")
endif()

endif()

list(APPEND KernelDTSList "${QEMU_DTS}" "${CMAKE_CURRENT_LIST_DIR}/overlay-qemu-riscv-virt.dts")

# QEMU emulates a SiFive PLIC/CLINT with 127 interrupt sources by default.
# The CLINT timer pretends to run at 10 MHz, but this speed may not hold in
# practical measurements.
declare_default_headers(
TIMER_FREQUENCY 10000000 PLIC_MAX_NUM_INT 128
INTERRUPT_CONTROLLER drivers/irq/riscv_plic0.h
)

endif()
20 changes: 20 additions & 0 deletions src/plat/qemu-riscv-virt/overlay-qemu-riscv-virt.dts
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
/*
* Copyright 2022, HENSOLDT Cyber
*
* SPDX-License-Identifier: GPL-2.0-only
*/

/ {
chosen {
/*
* - elfloader and kernel use SBI console by default
* - QEMU emulates a SiFive PLIC and CLINT by default
*
* Nothing needed for elfloader
* seL4,elfloader-devices = ... ;
*
*/
seL4,kernel-devices =
&{/soc/plic@c000000};
};
};

0 comments on commit fa00480

Please sign in to comment.