#!/usr/bin/expect ## # Reset the target machine or rather run the scenario with Qemu # proc check_version {qemu_version qemu_min qemu_max} { set version_min_list [split $qemu_min ".-"] set version_min_list_len [llength $version_min_list] set version_max_list [split $qemu_max ".-"] set version_max_list_len [llength $version_max_list] set version_list [split $qemu_version ".-"] set version_list_len [llength $version_list] set cmp 0 set cmp_min 0 set cmp_max 0 set i 0 foreach number $version_list { set min 0 set max 0 if { $i < $version_min_list_len } { set min [lindex $version_min_list $i] } if { $i < $version_max_list_len } { set max [lindex $version_max_list $i] } set cmp [expr {$cmp + $number * pow(1000, $version_list_len - $i) }] set cmp_min [expr {$cmp_min + $min * pow(1000, $version_list_len - $i) }] set cmp_max [expr {$cmp_max + $max * pow(1000, $version_list_len - $i) }] incr i } return [expr {($cmp_min < $cmp) && ($cmp < $cmp_max)}] } ## # Execute scenario using Qemu # proc run_power_on { } { global qemu_args global qemu global qemu_spawn_id # # Back out on platforms w/o Qemu support # if {![is_qemu_available]} { return 0 } if {[have_spec x86_32]} { set qemu "qemu-system-i386" } if {[have_spec x86_64]} { set qemu "qemu-system-x86_64" } if {[have_spec arm]} { set qemu "qemu-system-arm" } if {[have_spec arm_64]} { set qemu "qemu-system-aarch64" } if {[have_spec riscv]} { set qemu "qemu-system-riscv64" } # # Only the x86_64 variant of Qemu provides the emulation of hardware # virtualization features used by NOVA. So let's always stick to this # variant of Qemu when working with NOVA even when operating in 32bit. # if {[have_spec nova]} { set qemu "qemu-system-x86_64" } # # Redirect serial output to stdio, but only when no explicit configuration # of serial interfaces is specified in the run script. # The 'mon' prefix enables the access to the qemu console. # if {![regexp -- {-serial} $qemu_args dummy]} { # # In the raspi3 model the first UART is never used as # log output, but the second # if {[have_board rpi3]} { append qemu_args " -serial null " } append qemu_args " -serial mon:stdio " } # SVM virtualization is broken after $qemu_good_old and until before $qemu_good_new # We use "-cpu phenom" when using VMs in Qemu if {[regexp -- {-cpu phenom} $qemu_args dummy]} { catch {exec $qemu --version} qemu_version set qemu_version [regexp -inline {version[ ][0-9]+\.[0-9]+[\.0-9]*} $qemu_version] set qemu_version [regexp -inline {[0-9]+\.[0-9]+[\.0-9]*} $qemu_version] set qemu_good_old "2.4.1" set qemu_good_new "2.8.1" if {[check_version $qemu_version $qemu_good_old $qemu_good_new]} { puts "\nYour Qemu version '$qemu_version' is not working with AMD SVM virtualisation" puts "Known good Qemu versions are until $qemu_good_old and starting with $qemu_good_new\n" exit 1 } } # tweak emulated platform for specific platforms if {[have_board pbxa9]} { # # For PBXA9 qemu adjusts provided RAM chips to the -m arg. Thus we # filter user values and force value that enables all chips that Genode # expects to be available. Not doing so leads to inexplicable errors. # regsub -all {\-m ([0-9])+} $qemu_args "" qemu_args append qemu_args " -m 768" append qemu_args " -M realview-pbx-a9" } if {[have_board vpb926]} { append qemu_args " -M versatilepb -m 128 " } if {[have_board zynq_qemu]} { append qemu_args " -M xilinx-zynq-a9 -cpu cortex-a9 -m 256 " } if {[have_board rpi3]} { append qemu_args " -M raspi3 -m 512 " } if {[have_board virt_qemu]} { append qemu_args " -M virt,virtualization=true" 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_board pc]} { if {[have_spec okl4]} { # okl4 system integration specifies RAM from 32 to 800 MiB set qemu_ram 800 } else { set qemu_ram 512 } if {[regexp -- {-m} $qemu_args dummy]} { set qemu_ram [regexp -inline {\-m.[0-9]+} $qemu_args] set qemu_ram [regexp -inline {[0-9]+} $qemu_ram] } if {[have_spec okl4]} { if {$qemu_ram < 800} { puts "Configured memory ($qemu_ram) for OKL4 on Qemu must be at least 800M\n" exit 1 } } append qemu_args " -m $qemu_ram " if {[have_include "load/tftp"]} { append qemu_args " -boot n -tftp [run_dir] -bootp boot/pulsar -no-reboot -no-shutdown " } else { if {[have_include "image/iso"]} { append qemu_args " -cdrom [run_dir].iso " } else { if {[have_include "image/disk"]} { append qemu_args " -drive format=raw,file=[run_dir].img " } else { if {[have_include "image/uefi"]} { set uefi_firmware "/usr/share/ovmf/OVMF.fd" if {![file exists $uefi_firmware]} { puts "'$uefi_firmware' uefi image missing. Please install a ovmf package matching your qemu version." exit -3 } append qemu_args " --bios $uefi_firmware -net none -drive format=raw,file=[run_dir].img " # limit boot resolution in Qemu to 1920x1080 append qemu_args " -device VGA,vgamem_mb=8 " } else { puts "Aborting, cannot execute Qemu without a ISO or disk image" exit -4 } } } } append qemu_args " -machine q35 " } if {[have_board riscv_qemu]} { append qemu_args " -m 128 -machine virt -cpu rv64,priv_spec=v1.10.0 " append qemu_args " -bios default " } # on ARM/RISC-V, we supply the boot image as kernel if {[have_spec arm] || [have_spec arm_v8] || [have_spec riscv]} { append qemu_args " -kernel [run_dir]/boot/image.elf " } eval spawn $qemu $qemu_args set qemu_spawn_id $spawn_id return true }