hw: Add support for Qemu virt arm platforms.

This patch adds support for booting base-hw kernel on qemu-arm virt
machines. The arm_virt machine has 2GB of RAM, 2 Cortex A15 cores and
uses GICv2 interrupt controller. The arm_64_virt machine also has 2GB of
RAM, but has 4 Cortex A53 cores and uses GICv3. Both machines use PSCI
to boot additional CPU cores.

Fixes #3673
This commit is contained in:
Piotr Tworek 2019-09-15 01:10:20 +02:00 committed by Christian Helmuth
parent dad1de1865
commit 585c4b8c69
18 changed files with 359 additions and 3 deletions

View File

@ -0,0 +1,14 @@
INC_DIR += $(REP_DIR)/src/bootstrap/spec/virt_qemu
SRC_CC += bootstrap/spec/arm/arm_v7_cpu.cc
SRC_CC += bootstrap/spec/arm/cortex_a15_cpu.cc
SRC_CC += bootstrap/spec/arm/gicv2.cc
SRC_CC += bootstrap/spec/virt_qemu/platform.cc
SRC_CC += hw/spec/32bit/memory_map.cc
SRC_S += bootstrap/spec/arm/crt0.s
NR_OF_CPUS = 2
CC_MARCH = -march=armv7ve -mtune=cortex-a15 -mfpu=vfpv3 -mfloat-abi=softfp
include $(REP_DIR)/lib/mk/bootstrap-hw.inc

View File

@ -0,0 +1,13 @@
INC_DIR += $(REP_DIR)/src/core/spec/virt_qemu
# add C++ sources
SRC_CC += kernel/vm_thread_off.cc
SRC_CC += platform_services.cc
SRC_CC += spec/arm/generic_timer.cc
SRC_CC += spec/arm/gicv2.cc
NR_OF_CPUS = 2
CC_MARCH = -march=armv7ve -mtune=cortex-a15 -mfpu=vfpv3 -mfloat-abi=soft
include $(REP_DIR)/lib/mk/spec/cortex_a15/core-hw.inc

View File

@ -0,0 +1,14 @@
INC_DIR += $(REP_DIR)/src/bootstrap/spec/virt_qemu_64
SRC_CC += bootstrap/spec/arm/gicv3.cc
SRC_CC += bootstrap/spec/arm_64/cortex_a53_mmu.cc
SRC_CC += bootstrap/spec/virt_qemu_64/platform.cc
SRC_CC += lib/base/arm_64/kernel/interface.cc
SRC_CC += spec/64bit/memory_map.cc
SRC_S += bootstrap/spec/arm_64/crt0.s
vpath spec/64bit/memory_map.cc $(BASE_DIR)/../base-hw/src/lib/hw
NR_OF_CPUS = 4
include $(REP_DIR)/lib/mk/bootstrap-hw.inc

View File

@ -0,0 +1,26 @@
INC_DIR += $(REP_DIR)/src/core/spec/virt_qemu_64
INC_DIR += $(REP_DIR)/src/core/spec/arm_v8
# add C++ sources
SRC_CC += kernel/cpu_mp.cc
SRC_CC += kernel/vm_thread_off.cc
SRC_CC += platform_services.cc
SRC_CC += spec/64bit/memory_map.cc
SRC_CC += spec/arm/generic_timer.cc
SRC_CC += spec/arm/gicv3.cc
SRC_CC += spec/arm/kernel/lock.cc
SRC_CC += spec/arm/platform_support.cc
SRC_CC += spec/arm_v8/cpu.cc
SRC_CC += spec/arm_v8/kernel/cpu.cc
SRC_CC += spec/arm_v8/kernel/thread.cc
#add assembly sources
SRC_S += spec/arm_v8/exception_vector.s
SRC_S += spec/arm_v8/crt0.s
vpath spec/64bit/memory_map.cc $(BASE_DIR)/../base-hw/src/lib/hw
NR_OF_CPUS = 4
# include less specific configuration
include $(REP_DIR)/lib/mk/core-hw.inc

View File

@ -0,0 +1,7 @@
BOARD = virt_qemu
include $(GENODE_DIR)/repos/base-hw/recipes/src/base-hw_content.inc
content: enable_board_spec
enable_board_spec: etc/specs.conf
echo "SPECS += virt_qemu" >> etc/specs.conf

View File

@ -0,0 +1 @@
2020-02-10 bddcf1924aa3e440d8c728ce1a880da4489750d0

View File

@ -0,0 +1,2 @@
base-hw
base

View File

@ -0,0 +1,31 @@
/*
* \brief Board driver for bootstrap
* \author Piotr Tworek
* \date 2019-09-15
*/
/*
* Copyright (C) 2019 Genode Labs GmbH
*
* This file is part of the Genode OS framework, which is distributed
* under the terms of the GNU Affero General Public License version 3.
*/
#ifndef _SRC__BOOTSTRAP__SPEC__VIRT__QEMU_H_
#define _SRC__BOOTSTRAP__SPEC__VIRT__QEMU_H_
#include <hw/spec/arm/virt_qemu_board.h>
#include <hw/spec/arm/gicv2.h>
#include <hw/spec/arm/lpae.h>
#include <hw/spec/arm/psci_call.h>
#include <spec/arm/cpu.h>
namespace Board {
using namespace Hw::Virt_qemu_board;
using Psci = Hw::Psci<Hw::Psci_hvc_functor>;
using Pic = Hw::Gicv2;
static constexpr bool NON_SECURE = false;
};
#endif /* _SRC__BOOTSTRAP__SPEC__VIRT__QEMU_H_ */

View File

@ -0,0 +1,59 @@
/*
* \brief Platform implementations specific for base-hw and Qemu arm virt machine
* \author Piotr Tworek
* \date 2019-09-15
*/
/*
* Copyright (C) 2019 Genode Labs GmbH
*
* This file is part of the Genode OS framework, which is distributed
* under the terms of the GNU Affero General Public License version 3.
*/
#include <platform.h>
extern "C" void * _start_setup_stack;
using namespace Board;
Bootstrap::Platform::Board::Board()
: early_ram_regions(Memory_region { RAM_BASE, RAM_SIZE }),
late_ram_regions(Memory_region { }),
core_mmio(Memory_region { UART_BASE, UART_SIZE },
Memory_region { Cpu_mmio::IRQ_CONTROLLER_DISTR_BASE,
Cpu_mmio::IRQ_CONTROLLER_DISTR_SIZE },
Memory_region { Cpu_mmio::IRQ_CONTROLLER_CPU_BASE,
Cpu_mmio::IRQ_CONTROLLER_CPU_SIZE }) {}
unsigned Bootstrap::Platform::enable_mmu()
{
static volatile bool primary_cpu = true;
/* locally initialize interrupt controller */
::Board::Pic pic { };
Cpu::Sctlr::init();
Cpu::Cpsr::init();
/* primary cpu wakes up all others */
if (primary_cpu && NR_OF_CPUS > 1) {
Cpu::invalidate_data_cache();
primary_cpu = false;
Cpu::wake_up_all_cpus(&_start_setup_stack);
}
Cpu::enable_mmu_and_caches((Genode::addr_t)core_pd->table_base);
return Cpu::Mpidr::Aff_0::get(Cpu::Mpidr::read());
}
void Board::Cpu::wake_up_all_cpus(void * const ip)
{
for (unsigned cpu_id = 1; cpu_id < NR_OF_CPUS; cpu_id++) {
if (!Board::Psci::cpu_on(cpu_id, ip)) {
Genode::error("Failed to boot CPU", cpu_id);
}
}
}

View File

@ -0,0 +1,36 @@
/*
* \brief Board driver for bootstrap
* \author Piotr Tworek
* \date 2019-09-15
*/
/*
* Copyright (C) 2019 Genode Labs GmbH
*
* This file is part of the Genode OS framework, which is distributed
* under the terms of the GNU Affero General Public License version 3.
*/
#ifndef _SRC__BOOTSTRAP__SPEC__VIRT_QEMU_64_H_
#define _SRC__BOOTSTRAP__SPEC__VIRT_QEMU_64_H_
#include <hw/spec/arm/virt_qemu_board.h>
#include <hw/spec/arm/gicv3.h>
#include <hw/spec/arm/lpae.h>
#include <hw/spec/arm_64/cpu.h>
#include <hw/spec/arm_64/psci_call.h>
namespace Board {
using namespace Hw::Virt_qemu_board;
using Psci = Hw::Psci<Hw::Psci_hvc_functor>;
struct Cpu : Hw::Arm_64_cpu
{
static void wake_up_all_cpus(void*);
};
using Hw::Pic;
};
#endif /* _SRC__BOOTSTRAP__SPEC__VIRT_QEMU_64_H_ */

View File

@ -0,0 +1,36 @@
/*
* \brief Platform implementations specific for base-hw and Qemu arm64 virt machine
* \author Piotr Tworek
* \date 2019-09-15
*/
/*
* Copyright (C) 2019 Genode Labs GmbH
*
* This file is part of the Genode OS framework, which is distributed
* under the terms of the GNU Affero General Public License version 3.
*/
#include <platform.h>
Bootstrap::Platform::Board::Board()
: early_ram_regions(Memory_region { ::Board::RAM_BASE, ::Board::RAM_SIZE }),
late_ram_regions(Memory_region { }),
core_mmio(Memory_region { ::Board::UART_BASE, ::Board::UART_SIZE },
Memory_region { ::Board::Cpu_mmio::IRQ_CONTROLLER_DISTR_BASE,
::Board::Cpu_mmio::IRQ_CONTROLLER_DISTR_SIZE },
Memory_region { ::Board::Cpu_mmio::IRQ_CONTROLLER_REDIST_BASE,
::Board::Cpu_mmio::IRQ_CONTROLLER_REDIST_SIZE })
{
::Board::Pic pic {};
}
void Board::Cpu::wake_up_all_cpus(void *entry)
{
for (unsigned cpu_id = 1; cpu_id < NR_OF_CPUS; cpu_id++) {
if (!Board::Psci::cpu_on(cpu_id, entry)) {
Genode::error("Failed to boot CPU", cpu_id);
}
}
}

View File

@ -0,0 +1,28 @@
/*
* \brief Arm virt board driver for core
* \author Piotr Tworek
* \date 2019-09-15
*/
/*
* Copyright (C) 2019 Genode Labs GmbH
*
* This file is part of the Genode OS framework, which is distributed
* under the terms of the GNU Affero General Public License version 3.
*/
#ifndef _SRC__CORE__SPEC__VIRT__QEMU_H_
#define _SRC__CORE__SPEC__VIRT__QEMU_H_
#include <hw/spec/arm/virt_qemu_board.h>
#include <hw/spec/arm/gicv2.h>
#include <spec/arm/generic_timer.h>
namespace Board {
using namespace Hw::Virt_qemu_board;
using Pic = Hw::Gicv2;
enum { TIMER_IRQ = 30 /* PPI IRQ 14 */ };
};
#endif /* _SRC__CORE__SPEC__VIRT__QEMU_H_ */

View File

@ -0,0 +1,28 @@
/*
* \brief Arm64 virt board driver for core
* \author Piotr Tworek
* \date 2019-09-15
*/
/*
* Copyright (C) 2019 Genode Labs GmbH
*
* This file is part of the Genode OS framework, which is distributed
* under the terms of the GNU Affero General Public License version 3.
*/
#ifndef _SRC__CORE__SPEC__VIRT_QEMU_64_H_
#define _SRC__CORE__SPEC__VIRT_QEMU_64_H_
#include <hw/spec/arm/virt_qemu_board.h>
#include <hw/spec/arm/gicv3.h>
#include <spec/arm/generic_timer.h>
namespace Board {
using namespace Hw::Virt_qemu_board;
using Hw::Pic;
enum { TIMER_IRQ = 30 /* PPI IRQ 14 */ };
};
#endif /* _SRC__CORE__SPEC__VIRT_QEMU_64_H_ */

View File

@ -0,0 +1,46 @@
/*
* \brief Board definitions for Qemu ARM virt machine
* \author Piotr Tworek
* \date 2019-09-15
*/
/*
* Copyright (C) 2019 Genode Labs GmbH
*
* This file is part of the Genode OS framework, which is distributed
* under the terms of the GNU Affero General Public License version 3.
*/
#ifndef _SRC__INCLUDE__HW__SPEC__ARM__VIRT_QEMU_BOARD_H_
#define _SRC__INCLUDE__HW__SPEC__ARM__VIRT_QEMU_BOARD_H_
#include <drivers/uart/pl011.h>
#include <hw/spec/arm/boot_info.h>
namespace Hw::Virt_qemu_board {
using Serial = Genode::Pl011_uart;
enum {
RAM_BASE = 0x40000000,
RAM_SIZE = 0x80000000,
UART_BASE = 0x09000000,
UART_SIZE = 0x1000,
UART_CLOCK = 250000000,
CACHE_LINE_SIZE_LOG2 = 6,
};
namespace Cpu_mmio {
enum {
IRQ_CONTROLLER_DISTR_BASE = 0x08000000,
IRQ_CONTROLLER_DISTR_SIZE = 0x10000,
IRQ_CONTROLLER_CPU_BASE = 0x08010000,
IRQ_CONTROLLER_CPU_SIZE = 0x10000,
IRQ_CONTROLLER_REDIST_BASE = 0x080A0000,
IRQ_CONTROLLER_REDIST_SIZE = 0xC0000,
};
};
};
#endif /* _SRC__INCLUDE__HW__SPEC__ARM__VIRT_QEMU_BOARD_H_ */

View File

@ -6,11 +6,12 @@ QEMU_RUN_OPT := --include power_on/qemu --include log/qemu
# board to use (arndale, imx53_qsb, imx53_qsb_tz, imx6q_sabrelite, imx7d_sabre,
# nit6_solox, odroid_xu, odroid_x2, panda, pbxa9, usb_armory,
# wand_quad, or zynq_qemu)
# virt_qemu, wand_quad, or zynq_qemu)
#BOARD ?= pbxa9
# local variable for run-tool arguments that depend on the used board
BOARD_RUN_OPT(pbxa9) = $(QEMU_RUN_OPT)
BOARD_RUN_OPT(virt_qemu) = $(QEMU_RUN_OPT)
BOARD_RUN_OPT(zynq_qemu) = $(QEMU_RUN_OPT)
##

View File

@ -4,11 +4,12 @@ QEMU_RUN_OPT := --include power_on/qemu --include log/qemu
# kernel to use (hw, foc, or sel4)
#KERNEL ?= hw
# board to use (rpi3, imx8q_evk)
# board to use (rpi3, imx8q_evk, virt_qemu)
#BOARD ?= rpi3
# local variable for run-tool arguments that depend on the used board
BOARD_RUN_OPT(rpi3) := $(QEMU_RUN_OPT)
BOARD_RUN_OPT(rpi3) := $(QEMU_RUN_OPT)
BOARD_RUN_OPT(virt_qemu) := $(QEMU_RUN_OPT)
##
## Qemu arguments, effective when using the run tool's 'power_on/qemu' back end

View File

@ -22,6 +22,7 @@ proc bootstrap_link_address { } {
if {[have_spec "rpi"]} { return "0x00800000" }
if {[have_spec "rpi3"]} { return "0x00800000" }
if {[have_spec "nit6_solox"]} { return "0x88000000" }
if {[have_spec "virt_qemu"]} { return "0x40000000" }
puts "unknown platform no linker address known"
exit -1
@ -229,6 +230,7 @@ proc base_src { } {
if {[have_spec arndale]} { return base-hw-arndale }
if {[have_spec panda]} { return base-hw-panda }
if {[have_spec zynq_qemu]} { return base-hw-zynq_qemu }
if {[have_spec virt_qemu]} { return base-hw-virt_qemu }
global specs

View File

@ -109,6 +109,17 @@ proc run_power_on { } {
if {[have_spec zynq_qemu]} { append qemu_args " -M xilinx-zynq-a9 -cpu cortex-a9 -m 256 " }
if {[have_spec rpi3]} { append qemu_args " -M raspi3 -m 512 " }
if {[have_spec virt_qemu]} {
append qemu_args " -M virt"
if {[have_spec arm_v8a]} {
append qemu_args ",gic_version=3 -cpu cortex-a53 -smp 4"
}
if {[have_spec arm_v7a]} {
append qemu_args " -cpu cortex-a15 -smp 2"
}
append qemu_args " -m 2048"
}
# on x86, we support booting via pxe or iso/disk image
if {[have_spec x86]} {
if {![regexp -- {-m} $qemu_args dummy]} {