seoul: move to genode-world

Fixes #4412
This commit is contained in:
Alexander Boettcher 2022-02-09 09:35:46 +01:00 committed by Norman Feske
parent baea48fbec
commit 35489aa708
40 changed files with 0 additions and 5844 deletions

View File

@ -1,81 +0,0 @@
/*
* \brief Utilities for implementing VMMs on Genode/NOVA
* \author Norman Feske
* \date 2013-08-20
*
* The VMM and the guest share the same PD. However, the guest's view on the PD
* is restricted to the guest-physical-to-VMM-local mappings installed by the
* VMM for the VCPU's EC.
*
* The guest memory is shadowed at the lower portion of the VMM's address
* space. If the guest (the VCPU EC) tries to access a page that has no mapping
* in the VMM's PD, NOVA does not generate a page-fault (which would be
* delivered to the pager of the VMM, i.e., core) but it produces a NPT
* virtualization event handled locally by the VMM. The NPT event handler is
* the '_svm_npt' function.
*/
/*
* Copyright (C) 2013-2017 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 _INCLUDE__VMM__GUEST_MEMORY_H_
#define _INCLUDE__VMM__GUEST_MEMORY_H_
/* Genode includes */
#include <base/attached_ram_dataspace.h>
#include <base/env.h>
#include <rm_session/connection.h>
#include <region_map/client.h>
/* VMM utilities includes */
#include <vmm/types.h>
namespace Vmm {
using namespace Genode;
class Virtual_reservation;
class Guest_memory;
}
/**
* The 'Virtual_reservation' is a managed dataspace that occupies the lower
* part of the address space, which contains the shadow of the VCPU's physical
* memory.
*/
struct Vmm::Virtual_reservation : private Rm_connection, Region_map_client
{
Genode::Env &_env;
Virtual_reservation(Genode::Env &env, addr_t vm_size)
:
Rm_connection(env),
Region_map_client(Rm_connection::create(vm_size)),
_env(env)
{
try {
/*
* Attach reservation to the beginning of the local address
* space. We leave out the very first page because core denies
* the attachment of anything at the zero page.
*/
env.rm().attach_at(Region_map_client::dataspace(), PAGE_SIZE, 0,
PAGE_SIZE);
} catch (Region_map::Region_conflict) {
error("region conflict while attaching guest-physical memory");
}
}
~Virtual_reservation()
{
_env.rm().detach((void *)PAGE_SIZE);
}
};
#endif /* _INCLUDE__VMM__GUEST_MEMORY_H_ */

View File

@ -1,25 +0,0 @@
/*
* \brief Utilities for implementing VMMs on Genode/NOVA
* \author Norman Feske
* \date 2013-08-20
*/
/*
* Copyright (C) 2013-2017 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 _INCLUDE__VMM__TYPES_H_
#define _INCLUDE__VMM__TYPES_H_
namespace Vmm {
enum {
PAGE_SIZE_LOG2 = 12UL,
PAGE_SIZE = PAGE_SIZE_LOG2 << 12
};
}
#endif /* _INCLUDE__VMM__TYPES_H_ */

View File

@ -1 +0,0 @@
include $(call select_from_repositories,lib/import/import-libc.mk)

View File

@ -1,9 +0,0 @@
include $(call select_from_repositories,lib/mk/libc-common.inc)
SRC_C = stdlib/strtoul.c
SRC_C += $(addprefix string/,strchr.c strncpy.c strspn.c strcspn.c strstr.c strlen.c strnlen.c strcpy.c memcmp.c strcmp.c)
SRC_C += sys/__error.c gen/errno.c locale/none.c locale/table.c
vpath %.c $(LIBC_DIR)/lib/libc
CC_CXX_WARN_STRICT =

View File

@ -1 +0,0 @@
800924f3dc293d6c21d4e15fac0605ad4d7269b9

View File

@ -1,38 +0,0 @@
LICENSE := GPLv2
VERSION := git
DOWNLOADS := seoul.git
URL(seoul) := https://github.com/alex-ab/seoul.git
# branch genode_21_05
REV(seoul) := 5676b9efa5be9f1c9f7a8297ab462d76933896af
DIR(seoul) := src/app/seoul
#
# We need to execute some python scripts for preparing the i82576vf
# device model.
#
PYTHON2 := $(notdir $(lastword $(shell which python2 python2.{4,5,6,7,8})))
ifeq ($(PYTHON2),)
default : missing_tool
missing_tool:
$(ECHO) "Error: Seoul needs Python 2 to be installed"
@false;
endif
I82576VF_DIR = src/app/seoul/model/intel82576vf
EXECUTOR_DIR = src/app/seoul/executor
default : additional_steps
additional_steps : $(DOWNLOADS)
@echo "fix python version in code generator scripts ..." && \
sed -i "s/env python2/env $(PYTHON2)/" $(I82576VF_DIR)/genreg.py $(EXECUTOR_DIR)/build_instructions.py && \
sed -i "/Generated on/d" $(I82576VF_DIR)/genreg.py && \
echo "call code generators ... takes a while ..." && \
cd $(EXECUTOR_DIR) && \
./build_instructions.py > instructions.inc && \
cd $(CURDIR)/$(I82576VF_DIR) && \
./genreg.py reg_pci.py ../../include/model/intel82576vfpci.inc && \
cd $(CURDIR)/$(I82576VF_DIR) && \
./genreg.py reg_mmio.py ../../include/model/intel82576vfmmio.inc
.PHONY: additional_steps

View File

@ -1,65 +0,0 @@
PORT_DIR_SEOUL := $(call port_dir,$(REP_DIR)/ports/seoul)
SRC_DIR = src/app/seoul
content: $(SRC_DIR) src/include
$(SRC_DIR):
mkdir -p $@
cp -rH $(REP_DIR)/$@/* $@/
cp -r $(PORT_DIR_SEOUL)/$@/* $@/
cp $(PORT_DIR_SEOUL)/$@/LICENSE .
BASE_SRC_INCLUDE := src/include/base/internal/crt0.h \
src/include/base/internal/globals.h \
src/include/base/internal/unmanaged_singleton.h
src/include:
mkdir -p $@/base/internal
for file in $(BASE_SRC_INCLUDE); do \
cp $(GENODE_DIR)/repos/base/$$file $$file; \
done
MIRROR_FROM_PORT_DIR := lib/mk/seoul_libc_support.mk \
include/vmm/types.h
content: $(MIRROR_FROM_PORT_DIR)
$(MIRROR_FROM_PORT_DIR):
mkdir -p $(dir $@)
cp -r $(GENODE_DIR)/repos/ports/$@ $(dir $@)
MIRROR_FROM_LIBPORTS := lib/mk/libc-common.inc
content: $(MIRROR_FROM_LIBPORTS)
$(MIRROR_FROM_LIBPORTS):
mkdir -p $(dir $@)
cp -r $(GENODE_DIR)/repos/libports/$@ $(dir $@)
content:
MIRROR_FROM_BASE := lib/mk/cxx.mk
content: $(MIRROR_FROM_BASE)
$(MIRROR_FROM_BASE):
mkdir -p $(dir $@)
cp -r $(GENODE_DIR)/repos/base/$@ $(dir $@)
PORT_DIR := $(call port_dir,$(GENODE_DIR)/repos/libports/ports/libc)
include $(REP_DIR)/lib/mk/seoul_libc_support.mk
MIRROR_FROM_LIBC := $(addprefix src/lib/libc/lib/libc/,$(SRC_C)) \
src/lib/libc/lib/libc/locale/mblocal.h \
src/lib/libc/lib/libc/locale/xlocale_private.h \
src/lib/libc/lib/libc/locale/setlocale.h \
src/lib/libc/lib/libc/include/libc_private.h \
content: $(MIRROR_FROM_LIBC)
$(MIRROR_FROM_LIBC):
mkdir -p $(dir $@)
cp -r $(PORT_DIR)/$@ $(dir $@)

View File

@ -1 +0,0 @@
2022-01-18 24cfd5b82ca7867a146b4b53bbdd4d89f194b0b2

View File

@ -1,12 +0,0 @@
base
libc
os
blit
nitpicker_gfx
gui_session
framebuffer_session
input_session
timer_session
block_session
nic_session
rtc_session

View File

@ -1,86 +0,0 @@
#
# \brief Seoul on Genode - for automated testing
# \author Alexander Boettcher
# \date 2013-06-11
#
# This run script starts the Seoul VMM booting from a multiboot image.
# It assumes that the module files are present at '<build-dir>/bin/'
#
assert_spec x86
if { [get_cmd_switch --autopilot] && [have_spec x86_32] } {
puts "Run script does not support autopilot mode on 32 bit"
exit 0
}
if {[have_spec foc] || [have_spec sel4] || [have_spec nova]} {
} else {
puts "\n Run script is not supported on this platform. \n";
exit 0
}
set use_multiboot 1
set use_genode_iso 0
set use_model_ahci 0
set use_model_ide 0
set use_block_vdi 0
set use_block_ram 0
set use_block_sata 0
set use_part_block 0
set use_nic_session 1
set use_framebuffer 1
set use_fancy_stuff 0
set use_top 0
set memory_vmm_vm "128M"
set vcpus_to_be_used 2
if {[have_spec sel4]} {
# The seL4 kernel dies with an exception XXX
set vcpus_to_be_used 1
}
set multiboot_files {
<rom name="munich"/>
<rom name="bzImage-3.1" cmdline="root=/dev/ram0 earlyprintk=ttyS0 console=ttyS0 text"/>
<rom name="seoul-auto.gz"/>
}
set guest_os_binaries { munich bzImage-3.1 seoul-auto.gz}
set sha1_os_binaries { 7ecb4ba634a0ecfa6429418ea73490d6f65afead 6b2ef2c5bf16db3ebcbe33ce134e4e0a96944f82 bb6384fe58ab0c945b231f6cc107bcdff1bdacbe}
#
# Download demo kernel, image and
# munich (part of Oslo framework http://os.inf.tu-dresden.de/~kauer/oslo)
#
set uri "http://genode.org/files/seoul"
foreach binary $guest_os_binaries {
if {![file exists bin/$binary]} {
exec mkdir -p bin
puts "Download file bin/$binary"
exec >& /dev/null wget -c -O bin/$binary $uri/$binary
}
}
source ${genode_dir}/repos/ports/run/seoul.inc
append qemu_args " -cpu phenom "
append qemu_args " -nographic "
append_qemu_nic_args
if { [get_cmd_switch --autopilot] } {
run_genode_until {\[init -\> seoul\] VMM: # Hello Genode world!} 300
} else {
run_genode_until forever
}
foreach binary $guest_os_binaries {
exec rm -f bin/$binary
}

View File

@ -1,45 +0,0 @@
#
# \brief Seoul on Genode - test to boot from a raw disk
# \author Alexander Boettcher
# \date 2013-06-11
#
# This run script starts the Seoul VMM booting from a disc image.
# It assumes that the module files are present at '<build-dir>/bin/'
#
set use_multiboot 0
set use_genode_iso 0
set use_model_ahci 1
set use_model_ide 0
set use_block_vdi 0
set use_block_ram 1
set use_block_sata 0
set use_part_block 0
set use_nic_session 1
set use_framebuffer 1
set use_fancy_stuff 0
set use_top 0
set memory_vmm_vm "512M"
set vcpus_to_be_used 1
if {[have_include power_on/qemu]} {
if {![file exists bin/seoul-disc.raw]} {
puts "Please provide a disk image file to bin/seoul-disc.raw"
exit 1
}
append qemu_args " -m 1536 "
append qemu_args " -cpu phenom"
append_if $use_block_sata qemu_args " -drive id=disk,file=bin/seoul-disc.raw,format=raw,if=none -device ahci,id=ahci -device ide-drive,drive=disk,bus=ahci.0 -boot d"
}
source ${genode_dir}/repos/ports/run/seoul.inc
run_genode_until forever

View File

@ -1,64 +0,0 @@
#
# \brief Example for using Seoul on Genode
# \author Norman Feske
# \author Markus Partheymueller
# \author Alexander Boettcher
# \date 2011-11-21
#
# This run script starts the Seoul VMM booting the multiboot modules
# listed in the 'multiboot' config node. It assumes that the module files
# are present at '<build-dir>/bin/' (see the 'boot_modules' variable).
#
set use_multiboot 1
set use_genode_iso 0
set use_model_ahci 0
set use_model_ide 0
set use_block_vdi 0
set use_block_ram 0
set use_block_sata 0
set use_part_block 0
set use_nic_session 1
set use_framebuffer 1
set use_fancy_stuff 1
set use_top 0
set memory_init "288M"
set memory_vmm_vm "128M"
set vcpus_to_be_used 1
set multiboot_files {
<rom name="munich"/>
<rom name="bzImage-3.1" cmdline="root=/dev/ram0 earlyprintk=ttyS0 vga=0x338"/>
<rom name="tc-browser.gz"/>
}
set guest_os_binaries { munich bzImage-3.1 tc-browser.gz }
set sha1_os_binaries { 7ecb4ba634a0ecfa6429418ea73490d6f65afead 6b2ef2c5bf16db3ebcbe33ce134e4e0a96944f82 51aa53eb494b71d65f7fe3eb05e52af4616878bd}
#
# Download demo kernel, image and
# munich (part of Oslo framework http://os.inf.tu-dresden.de/~kauer/oslo)
#
set uri "http://genode.org/files/seoul"
foreach binary $guest_os_binaries {
if {![file exists bin/$binary]} {
puts "Download file bin/$binary"
exec mkdir -p bin
exec >& /dev/null wget -c -O bin/$binary $uri/$binary
}
}
source ${genode_dir}/repos/ports/run/seoul.inc
append qemu_args " -m 1024 "
append qemu_args " -cpu phenom "
append_qemu_nic_args
run_genode_until forever

View File

@ -1,96 +0,0 @@
#
# \brief Turn a Genode setup(run script) into a VM to be bootable in Seoul
# \author Alexander Boettcher
# \date 2014-09-21
#
# This run script starts the Seoul VMM booting from a multiboot Genode setup
# created by another Genode run script. The referenced run script can be
# adapted by tuning the variables run_script and build_dir below accordingly.
#
set use_multiboot 1
set use_genode_iso 1
set use_model_ahci 1
set use_model_ide 0
set use_block_vdi 0
set use_block_ram 0
set use_block_sata 0
set use_part_block 0
set use_nic_session 1
set use_framebuffer 1
set use_fancy_stuff 0
set use_top 1
set memory_vmm_vm "128M"
set vcpus_to_be_used 1
# Put the multiboot data structure out of the way of Nova's bss.
set use_multiboot_modaddr 0x2800000
# Use a Genode run script of a 32bit platform and turn it into a bootable
# setup for Seoul - adjust build_dir and run_script variable accordingly
set run_script "log"
set build_dir "."
set run_script_path "$build_dir/var/run/$run_script"
set genode_iso "$build_dir/var/run/$run_script.iso"
if {[catch {exec cp $genode_iso bin/genode.iso}]} {
puts "Run scenario '$run_script' is not present. Please run it before\
invoking this run script."
exit 1
}
set files_vm [exec isoinfo -i $genode_iso -x "/boot/grub/grub.cfg;1"]
set vm [split $files_vm "\n"]
set guest_os_binaries {}
foreach line $vm {
if {[regexp "module\.*" $line] || [regexp "kernel\.*" $line]} {
set label_file [lindex $line 1]
set binary_cmdline [lrange $line 2 end]
regsub -all "/fiasco/" $label_file "" binary_file
regsub -all "/boot/" $binary_file "" binary_file
regsub -all "/genode/" $binary_file "" binary_file
# skip bender to speed up booting
if {$binary_file == "bender"} {
continue
}
set file_type [exec file $run_script_path$label_file]
if {[regexp "gzip" $file_type]} {
exec gunzip --keep $run_script_path$label_file -c >file.tmp
set file_type [exec file file.tmp]
exec rm file.tmp
}
if {[regexp "ELF 64-bit" $file_type]} {
puts "Seoul supports only 32bit guests - choose a 32bit Genode platform"
puts "Exit reason: $file_type"
exit 2
}
if {[regexp "No such" $file_type]} {
puts "$file_type"
exit 3
}
if {$binary_cmdline eq ""} {
append multiboot_files "<rom name=\"$binary_file\" label=\"$label_file\"/>\n"
} else {
append multiboot_files "<rom name=\"$binary_file\" label=\"$label_file\" cmdline=\"$binary_cmdline\"/>\n"
}
}
}
# Seoul VM setup done
source ${genode_dir}/repos/ports/run/seoul.inc
append qemu_args " -m 1024 "
append qemu_args " -cpu phenom "
run_genode_until forever

View File

@ -1,80 +0,0 @@
#
# \brief Seoul on Genode - build Linux kernel inside VM
# \author Alexander Boettcher
# \date 2013-06-11
#
# This run script starts the Seoul VMM booting from a multiboot image.
# It assumes that the module files are present at '<build-dir>/bin/'
#
assert_spec x86
if {[have_include power_on/qemu]} {
puts "\nAuto test running on Qemu is not recommended.\n"
exit
}
set use_multiboot 1
set use_genode_iso 0
set use_model_ahci 0
set use_model_ide 0
set use_block_vdi 0
set use_block_ram 0
set use_block_sata 0
set use_part_block 0
set use_nic_session 0
set use_framebuffer 1
set use_fancy_stuff 0
set use_top 0
set memory_vmm_vm "950M"
# adjust also '-j option' accordingly - see benchmark_cmd
set vcpus_to_be_used 1
set multiboot_files {
<rom name="munich"/>
<rom name="bzImage-3.1" cmdline="root=/dev/ram0 earlyprintk=ttyS0 console=ttyS0 text benchmark_cmd='make -C /usr/src/linux-* defconfig && make -j 1 -C /usr/src/linux-* bzImage'"/>
<rom name="kernelbuild-e2fs.bz2"/>
}
set guest_os_binaries { munich bzImage-3.1 kernelbuild-e2fs.bz2 }
set sha1_os_binaries { 7ecb4ba634a0ecfa6429418ea73490d6f65afead 6b2ef2c5bf16db3ebcbe33ce134e4e0a96944f82 978b2a297c7ff8e53191321d300e70baa1036519 }
#
# Download demo kernel, image and
# munich (part of Oslo framework http://os.inf.tu-dresden.de/~kauer/oslo)
#
set guest_uri { "http://genode.org/files/seoul" "http://genode.org/files/seoul" "http://os.inf.tu-dresden.de/~nils/imgs" }
set binary_counter 0
foreach binary $guest_os_binaries {
if {![file exists bin/$binary]} {
set uri [lindex $guest_uri $binary_counter]
exec mkdir -p bin
puts "Download file bin/$binary from $uri"
exec >& /dev/null wget -c -O bin/$binary $uri/$binary
}
incr binary_counter 1
}
source ${genode_dir}/repos/ports/run/seoul.inc
append qemu_args " -m 1536 "
append qemu_args " -cpu phenom "
append qemu_args " -nographic "
run_genode_until {\[init -\> seoul\] VM is starting with } 400
set serial_id [output_spawn_id]
set time_start [ clock seconds ]
run_genode_until {\[init -\> seoul\] VMM: # ! PERF: kbuild [ 0-9]+ s ok} 2000 $serial_id
set time_end [ clock seconds ]
puts "\n! PERF: runtime [expr $time_end - $time_start ] seconds ok"
puts "Test succeeded"

View File

@ -1,59 +0,0 @@
#
# \brief Seoul on Genode - for testing network
# \author Alexander Boettcher
# \date 2013-06-11
#
# This run script starts the Seoul VMM booting from a multiboot image.
# It assumes that the module files are present at '<build-dir>/bin/'
#
set use_multiboot 1
set use_genode_iso 0
set use_model_ahci 0
set use_model_ide 0
set use_block_vdi 0
set use_block_ram 0
set use_block_sata 0
set use_part_block 0
set use_nic_session 1
set use_framebuffer 1
set use_fancy_stuff 0
set use_top 0
set memory_vmm_vm "128M"
set vcpus_to_be_used 1
set multiboot_files {
<rom name="munich"/>
<rom name="bzImage-3.1" cmdline="root=/dev/ram0 earlyprintk=ttyS0 text"/>
<rom name="tc-net.gz"/>
}
set guest_os_binaries { munich bzImage-3.1 tc-net.gz}
set sha1_os_binaries { 7ecb4ba634a0ecfa6429418ea73490d6f65afead 6b2ef2c5bf16db3ebcbe33ce134e4e0a96944f82 201deb4bd18fb07f3d0b5495b948ba622ff98e4b}
#
# Download demo kernel, image and
# munich (part of Oslo framework http://os.inf.tu-dresden.de/~kauer/oslo)
#
set uri "http://genode.org/files/seoul"
foreach binary $guest_os_binaries {
if {![file exists bin/$binary]} {
exec mkdir -p bin
puts "Download file bin/$binary"
exec >& /dev/null wget -c -O bin/$binary $uri/$binary
}
}
source ${genode_dir}/repos/ports/run/seoul.inc
append qemu_args " -cpu phenom "
append_qemu_nic_args
run_genode_until forever

View File

@ -1,654 +0,0 @@
#
# \brief Using Seoul on Genode
# \author Norman Feske
# \author Markus Partheymueller
# \author Alexander Boettcher
# \date 2011-11-21
set use_fs_rump $use_block_vdi
set use_drv_ahci [expr $use_block_vdi || $use_block_sata]
set use_vfs_block [expr $use_block_ram || $use_genode_iso]
create_boot_directory
import_from_depot [depot_user]/src/[base_src] \
[depot_user]/src/event_filter \
[depot_user]/src/init \
[depot_user]/src/nitpicker \
[depot_user]/src/usb_host_drv \
[depot_user]/src/usb_hid_drv \
[depot_user]/src/vfs_import \
[depot_user]/src/ps2_drv \
[depot_user]/raw/drivers_interactive-pc
if {$use_fs_rump} {
import_from_depot [depot_user]/src/vfs \
[depot_user]/src/rump
}
if {$use_part_block} {
import_from_depot [depot_user]/src/part_block
}
#
# Build
#
assert_spec x86
set map_small "no"
set vmm_vcpu_same_cpu "no"
if {[have_spec sel4]} {
set map_small "yes"
set vmm_vcpu_same_cpu "yes"
# seL4 has no AMD SVM support
if {[have_include "power_on/qemu"]} {
puts "\n Run script is not supported on this platform. \n";
exit 0
}
}
if {[have_spec foc]} {
# The performance is considerable bad when
# vmm and vcpu is not on same physical CPU
set vmm_vcpu_same_cpu "yes"
# Qemu SVM has no EPT support
if {[have_include "power_on/qemu"]} {
puts "\n Run script is not supported on this platform. \n";
exit 0
}
}
source ${genode_dir}/repos/base/run/platform_drv.inc
# override defaults of platform_drv.inc
proc platform_drv_priority {} { return { priority="-1"} }
set build_components {
drivers/rtc
app/seoul
}
if {$use_fancy_stuff} { set use_framebuffer 1 }
lappend_if $use_block_vdi build_components server/vdi_block
lappend_if $use_vfs_block build_components server/vfs_block
lappend_if $use_drv_ahci build_components drivers/ahci
lappend_if $use_nic_session build_components drivers/nic
lappend_if $use_nic_session build_components server/nic_router
lappend_if $use_framebuffer build_components drivers/framebuffer
lappend_if $use_fancy_stuff build_components app/status_bar
lappend_if $use_fancy_stuff build_components app/launchpad
lappend_if $use_fancy_stuff build_components server/report_rom
lappend_if $use_genode_iso build_components server/iso9660
lappend_if $use_top build_components app/top
append_platform_drv_build_components
build $build_components
# write Seoul config file
set vm_cfg_fd [open "bin/vm_seoul.cfg" w]
puts $vm_cfg_fd "<config map_small=\"$map_small\" vmm_vcpu_same_cpu=\"$vmm_vcpu_same_cpu\" vmm_memory=\"16M\">"
puts $vm_cfg_fd { <machine verbose="no">
<mem start="0x0" end="0x9a000"/>
<mem start="0x100000" end="0xfffff000"/>
<!--<ioio/>-->
<nullio io_base="0x80" />
<pic io_base="0x20" elcr_base="0x4d0"/>
<pic io_base="0xa0" irq="2" elcr_base="0x4d1"/>
<pit io_base="0x40" irq="0"/>
<scp io_port_a="0x92" io_port_b="0x61"/>
<kbc io_base="0x60" irq_kbd="1" irq_aux="12"/>
<keyb ps2_port="0" host_keyboard="0x10000"/>
<mouse ps2_port="1" host_mouse="0x10001"/>
<rtc io_base="0x70" irq="8"/>
<serial io_base="0x3f8" irq="0x4" host_serial="0x4711"/>
<hostsink host_dev="0x4712" buffer="80"/>
<vga io_base="0x03c0"/>}
if {!$use_multiboot} {
puts $vm_cfg_fd {
<vbios_disk/>
}
}
puts $vm_cfg_fd {
<vbios_keyboard host_keyboard="0x10000"/>
<vbios_mem/>
<vbios_time/>
<vbios_reset/>}
if {$use_multiboot} {
if {[info exists use_multiboot_modaddr]} {
puts $vm_cfg_fd " <vbios_multiboot modaddr=\"$use_multiboot_modaddr\"/>"
} else {
puts $vm_cfg_fd { <vbios_multiboot/>}
}
}
puts $vm_cfg_fd {
<msi/>
<ioapic/>
<pcihostbridge bus_num="0" bus_count="0x10" io_base="0xcf8"
mem_base="0xe0000000"/>
<pmtimer io_port="0x8000"/>}
for {set i 0} {$i < $vcpus_to_be_used} {incr i 1} {
puts $vm_cfg_fd {
<vcpu/> <halifax/> <vbios/> <lapic/>}
}
if {!$use_multiboot} {
if {$use_model_ahci} {
puts $vm_cfg_fd {
<ahci mem="0xe0800000" irq="14" bdf="0x30"/>
<drive sigma0drive="0" controller="0" port="0"/>
}
}
if {$use_model_ide} {
puts $vm_cfg_fd {
<ide port0="0x1f0" port1="0x3f6" irq="14" bdf="0x38" disk="0"/>
}
}
}
if {$use_nic_session} {
puts $vm_cfg_fd {
<!-- <rtl8029 irq="9" port="0x300"/> -->
<intel82576vf/>
}
}
puts $vm_cfg_fd {
</machine>
<multiboot>}
if {$use_multiboot} {
puts $vm_cfg_fd $multiboot_files
}
puts $vm_cfg_fd {
</multiboot>
</config>}
close $vm_cfg_fd
#
# Generate Genode config
#
set config {
<config verbose="yes" prio_levels="4">
<parent-provides>
<service name="ROM"/>
<service name="IRQ"/>
<service name="IO_MEM"/>
<service name="IO_PORT"/>
<service name="PD"/>
<service name="RM"/>
<service name="CPU"/>
<service name="VM"/>
<service name="LOG"/>}
append_if $use_top config {
<service name="TRACE"/>}
append config {
</parent-provides>
<default-route>
<any-service> <parent/> <any-child/> </any-service>
</default-route>
<default caps="100"/>
<start name="timer">
<resource name="RAM" quantum="1M"/>
<provides><service name="Timer"/></provides>
</start>
<start name="rtc_drv" priority="-1">
<resource name="RAM" quantum="1M"/>
<provides><service name="Rtc"/></provides>
</start>
<start name="ps2_drv" priority="-1">
<resource name="RAM" quantum="3M"/>
<config/>
<route>
<service name="Event"> <child name="event_filter" label="ps2"/> </service>
<any-service><parent/> <any-child/> </any-service> </route>
</start>
<start name="event_filter" caps="90" priority="-1">
<resource name="RAM" quantum="1280K"/>
<provides> <service name="Event"/> </provides>
<route>
<service name="ROM" label="config"> <parent label="event_filter.config"/> </service>
<service name="Event"> <child name="nitpicker"/> </service>
<any-service><parent/><any-child/></any-service>
</route>
</start>
<start name="usb_drv" priority="-1" caps="120">
<binary name="x86_pc_usb_host_drv"/>
<resource name="RAM" quantum="12M"/>
<provides> <service name="Usb"/> </provides>
<config uhci="yes" ohci="yes" ehci="yes" xhci="yes">
<report devices="yes"/>
<policy label_prefix="usb_hid_drv" class="0x3"/>
</config>
<route>
<service name="Report"> <child name="report_rom"/> </service>
<any-service><parent/><any-child/></any-service>
</route>
</start>
<start name="usb_hid_drv" priority="-1" caps="140">
<resource name="RAM" quantum="11M"/>
<config use_report="yes"/>
<route>
<service name="Report"> <child name="report_rom"/> </service>
<service name="Event"> <child name="event_filter" label="usb"/> </service>
<service name="ROM" label="report"> <child name="report_rom"/> </service>
<service name="Usb"> <child name="usb_drv"/> </service>
<any-service><parent/><any-child/></any-service>
</route>
</start>}
append_if $use_drv_ahci config {
<start name="ahci_drv" priority="-1">
<resource name="RAM" quantum="1M" />
<provides><service name="Block"/></provides>
<config>}
append_if [expr $use_block_sata && !$use_part_block] config {
<policy label="seoul -> VirtualDisk 0" device="0" writeable="yes"/>}
append_if [expr $use_block_vdi && !$use_part_block] config {
<policy label="rump_fs -> " device="0" writeable="yes"/>}
append_if [expr $use_block_vdi && $use_part_block] config {
<policy label="part_block -> " device="0" writeable="yes"/>}
append_if [expr $use_block_sata && $use_part_block] config {
<policy label="part_block -> " device="0" writeable="yes"/>}
append_if $use_drv_ahci config {
</config>
</start>}
append_if $use_part_block config {
<start name="part_block" priority="-1">
<resource name="RAM" quantum="10M"/>
<provides><service name="Block"/></provides>
<route>
<any-service><child name="ahci_drv"/> <parent/></any-service>
</route>
<config>
<policy label="seoul -> VirtualDisk 0" partition="5" writeable="yes"/>
<policy label="rump_fs -> " partition="4" writeable="yes"/>
</config>
</start>}
append_if $use_block_ram config {
<start name="vfs_block" priority="-1">
<resource name="RAM" quantum="266M" />
<provides><service name="Block"/></provides>
<config>
<vfs>
<ram/>
<import>
<rom name="seoul-disc.raw"/>
</import>
</vfs>
<default-policy file="/seoul-disc.raw" block_size="512"
writeable="yes"/>
</config>
</start>}
append_if $use_fs_rump config {
<start name="rump_fs" priority="-1" caps="200">
<binary name="vfs"/>
<resource name="RAM" quantum="32M"/>
<provides><service name="File_system"/></provides>
<config ld_verbose="yes">
<vfs>
<rump fs="ext2fs" ram="28M"/>
</vfs>
<default-policy root="/" writeable="yes"/>
</config>
<route>
<service name="Timer"><child name="timer"/></service>}
append_if [expr $use_fs_rump && $use_part_block] config {
<service name="Block"><child name="part_block"/></service>}
append_if [expr $use_fs_rump && !$use_part_block] config {
<service name="Block"><child name="ahci_drv"/></service>}
append_if $use_fs_rump config {
<any-service> <parent/> </any-service>
</route>
</start>}
append_if $use_block_vdi config {
<start name="vdi_block">
<resource name="RAM" quantum="8M"/>
<provides> <service name="Block"/> </provides>
<config file="/seoul_stress32.vdi" writeable="yes">
<vfs> <fs buffer_size="1M"/> </vfs>
<policy label="seoul -> VirtualDisk 0" writeable="yes"/>
</config>
<route>
<service name="File_system"><child name="rump_fs"/></service>
<any-service> <parent/> <any-child /> </any-service>
</route>
</start>}
append_if $use_genode_iso config {
<start name="vfs_block" priority="-1">
<resource name="RAM" quantum="16M" />
<provides><service name="Block"/></provides>
<config>
<vfs>
<rom name="genode.iso"/>
</vfs>
<default-policy file="/genode.iso" block_size="2048"/>
</config>
</start>
<start name="iso9660" priority="-1">
<resource name="RAM" quantum="16M"/>
<provides><service name="ROM"/></provides>
<route>
<service name="Block"><child name="vfs_block"/></service>
<any-service><parent/></any-service>
</route>
</start>}
append_platform_drv_config
append_if $use_nic_session config {
<start name="nic_drv" priority="-2">
<binary name="ipxe_nic_drv"/>
<resource name="RAM" quantum="8M"/>
<route>
<service name="Uplink"><child name="nic_router"/></service>
<any-service><parent/><any-child/></any-service>
</route>
</start>
<start name="nic_router" caps="200" priority="-1">
<resource name="RAM" quantum="10M"/>
<provides>
<service name="Nic"/>
<service name="Uplink"/>
</provides>
<config verbose_domain_state="yes">
<policy label_prefix="seoul" domain="downlink"/>
<policy label_prefix="launchpad" domain="downlink"/>
<policy label_prefix="nic_drv" domain="uplink"/>
<domain name="uplink">
<nat domain="downlink"
tcp-ports="16384"
udp-ports="16384"
icmp-ids="16384"/>
</domain>
<domain name="downlink" interface="10.0.3.1/24">
<dhcp-server ip_first="10.0.3.55" ip_last="10.0.3.155" dns_config_from="uplink"/>
<tcp dst="0.0.0.0/0"><permit-any domain="uplink" /></tcp>
<udp dst="0.0.0.0/0"><permit-any domain="uplink" /></udp>
<icmp dst="0.0.0.0/0" domain="uplink"/>
</domain>
</config>
</start>
}
append_if $use_framebuffer config {
<start name="fb_drv" priority="-1" caps="130">
<binary name="vesa_fb_drv"/>
<resource name="RAM" quantum="16M"/>
<route>
<service name="Timer"> <child name="timer"/></service>
<service name="Capture"> <child name="nitpicker"/></service>
<service name="Platform"> <any-child/></service>
<any-service> <parent/> </any-service>
</route>}
append_if [expr $use_framebuffer && [have_include "power_on/qemu"]] config {
<config width="1280" height="960"/>}
append_if [expr $use_framebuffer && ![have_include "power_on/qemu"]] config {
<config/>}
append_if $use_framebuffer config {
</start> }
if {!$use_fancy_stuff} {
append config {
<start name="seoul" priority="-2" caps="1200">
<binary name="seoul"/>}
append config "
<resource name=\"RAM\" quantum=\"$memory_vmm_vm\"/>"
append config {
<route>
<service name="Timer"><child name="timer"/></service>
<service name="ROM" label="config">
<parent label="vm_seoul.cfg"/> </service>}
append_if [expr $use_nic_session] config {
<service name="Nic"> <child name="nic_router"/> </service>}
append_if $use_genode_iso config {
<service name="ROM" unscoped_label="seoul"> <parent/> </service>
<service name="ROM" unscoped_label="ld.lib.so"> <parent/> </service>
<service name="ROM" label="platform_info"> <parent/> </service>
<service name="ROM"><child name="iso9660"/></service>}
append_if $use_block_vdi config {
<service name="Block"><child name="vdi_block"/></service>}
append_if [expr $use_block_sata && $use_part_block] config {
<service name="Block"><child name="part_block"/></service>}
append config {
<service name="Rtc"><child name="rtc_drv"/></service>
<any-service><parent/><any-child/></any-service>
</route>
</start> }
}
append config {
<start name="nitpicker" priority="-1" caps="120">
<resource name="RAM" quantum="8M"/>
<provides>
<service name="Gui"/> <service name="Capture"/> <service name="Event"/>
</provides>
<config>
<capture/> <event/>
<report focus="yes" />
<domain name="pointer" layer="1" content="client" label="no" origin="pointer" />
<domain name="panel" layer="2" content="client" label="no" focus="none" />
<domain name="init.1" layer="3" content="client" focus="click"
hover="always" xpos="20" ypos="30" height="-20"/>
<domain name="init.2" layer="3" content="client" focus="click"
hover="always" xpos="30" ypos="40" height="-20"/>
<domain name="init.3" layer="3" content="client" focus="click"
hover="always" xpos="40" ypos="50" height="-20"/>
<domain name="" layer="3" content="client" focus="click"
hover="always" xpos="10" ypos="20" height="-20"/>
<policy label_prefix="pointer" domain="pointer"/>
<policy label_prefix="status_bar" domain="panel"/>
<policy label_prefix="launchpad -> init.1" domain="init.1"/>
<policy label_prefix="launchpad -> init.2" domain="init.2"/>
<policy label_prefix="launchpad -> init.3" domain="init.3"/>
<default-policy domain=""/>
</config>
<route>
<service name="Timer"> <child name="timer"/></service>
<service name="Report"> <child name="report_rom"/></service>
<any-service><parent/><any-child/></any-service>
</route>
</start>
<start name="pointer">
<resource name="RAM" quantum="2M"/>
<config/>
</start>
<start name="report_rom">
<resource name="RAM" quantum="1M"/>
<provides> <service name="Report"/> <service name="ROM"/> </provides>
<config>
<policy label="status_bar -> focus" report="nitpicker -> focus"/>
<policy label="usb_hid_drv -> report" report="usb_drv -> devices"/>
</config>
</start>}
append_if $use_top config {
<start name="top">
<resource name="RAM" quantum="2M"/>
<config period_ms="10000"/>
</start>}
append_if $use_fancy_stuff config {
<start name="status_bar">
<resource name="RAM" quantum="1M"/>
<route>
<service name="ROM" label="focus"> <child name="report_rom"/> </service>
<any-service> <parent/> <any-child/> </any-service>
</route>
</start>
<start name="launchpad" priority="-2" caps="2000">
<resource name="RAM" quantum="64000M"/>
<route>
<service name="Nic"> <child name="nic_router"/> </service>
<service name="ROM" label="config">
<parent label="launchpad-config"/> </service>
<any-service><parent/><any-child/></any-service>
</route>
</start>}
append config {
</config>}
#
# Generate Launchpad config file
#
if {$use_fancy_stuff} {
set launchpad_cfg_fd [open "bin/launchpad-config" w]
puts $launchpad_cfg_fd "<config>
<launcher ram_quota=\"$memory_init\" name=\"init\" caps=\"500\" >"
puts $launchpad_cfg_fd {
<config>
<parent-provides>
<service name="ROM"/>
<service name="IRQ"/>
<service name="IO_MEM"/>
<service name="IO_PORT"/>
<service name="PD"/>
<service name="RM"/>
<service name="CPU"/>
<service name="LOG"/>
<service name="Gui"/>
<service name="Timer"/>
<service name="Nic"/>
<service name="Block"/>
<service name="Rtc"/>
<service name="VM"/>
</parent-provides>
<start name="seoul" caps="400">
<binary name="seoul"/>
<resource name="RAM" quantum="256M"/>
<route>
<service name="Timer"><parent/></service>
<service name="Nic"><parent/></service>
<service name="ROM" label="config">
<parent label="vm_seoul.cfg"/> </service>
<any-service><parent/></any-service>
</route>
</start>
</config>
</launcher>}
puts $launchpad_cfg_fd {</config>}
close $launchpad_cfg_fd
}
install_config $config
#
# Boot modules
#
# generic modules
set boot_modules {
rtc_drv
seoul
vm_seoul.cfg
}
lappend_if $use_block_vdi boot_modules vdi_block
lappend_if $use_vfs_block boot_modules vfs_block
lappend_if $use_vfs_block boot_modules vfs.lib.so
lappend_if $use_drv_ahci boot_modules ahci_drv
lappend_if $use_nic_session boot_modules ipxe_nic_drv
lappend_if $use_nic_session boot_modules nic_router
lappend_if $use_framebuffer boot_modules vesa_fb_drv
lappend_if $use_fancy_stuff boot_modules status_bar
lappend_if $use_fancy_stuff boot_modules launchpad
lappend_if $use_fancy_stuff boot_modules launchpad-config
lappend_if $use_fancy_stuff boot_modules report_rom
lappend_if $use_genode_iso boot_modules iso9660
lappend_if $use_genode_iso boot_modules genode.iso
lappend_if $use_block_ram boot_modules seoul-disc.raw
lappend_if $use_top boot_modules top
#
# Add OS binaries of guest
#
if {$use_multiboot} {
set guest_os_binary_missing 0
set binary_counter 0
foreach binary $guest_os_binaries {
if {![file exists bin/$binary]} {
puts stderr "Error: guest OS binary \"bin/$binary\" does not exist"
set guest_os_binary_missing 1
}
if {[info exists sha1_os_binaries]} {
set sha1 [exec sha1sum bin/$binary]
set sha1 [regexp -inline {[0-9a-h]+} $sha1]
if {[string compare $sha1 [lindex $sha1_os_binaries $binary_counter]]} {
puts "SHA1 sum of binary does not match with expected one - abort"
puts "$binary $sha1 != [lindex $sha1_os_binaries $binary_counter]"
set guest_os_binary_missing 1
}
}
incr binary_counter 1
}
if {$guest_os_binary_missing} { exit 1 }
append boot_modules $guest_os_binaries
}
append_platform_drv_boot_modules
build_boot_image $boot_modules
# A copy of the config is placed in the run folder.
exec rm -f bin/vm_seoul.cfg

View File

@ -1,137 +0,0 @@
#
# \brief Seoul on Genode - boot from a vdi or raw
# \author Alexander Boettcher
# \date 2020-03-12
#
assert_spec x86
if { [get_cmd_switch --autopilot] && [have_spec x86_32] } {
puts "Run script does not support autopilot mode on 32 bit"
exit 0
}
if { [get_cmd_switch --autopilot] && [have_include power_on/qemu] } {
puts "\n Run script is not supported on this platform. \n";
exit 0
}
#if {[have_spec foc] || [have_spec sel4] || [have_spec nova]} {
if {[have_spec nova]} {
} else {
puts "\n Run script is not supported on this platform. \n";
exit 0
}
set use_multiboot 0
set use_genode_iso 0
set use_model_ahci 1
set use_model_ide 0
set use_block_vdi 0
set use_block_ram 0
set use_block_sata 1
set use_part_block [expr ![have_include power_on/qemu]]
set use_nic_session 1
set use_usb 0
set use_framebuffer 1
set use_fancy_stuff 0
set use_top 0
set memory_vmm_vm "1280M"
set vcpus_to_be_used 2
if {[have_include power_on/qemu]} {
if {![file exists bin/seoul-disc.raw]} {
if {![file exists bin/seoul_stress32.vdi]} {
puts "Please provide a disk image file to bin/seoul_stress32.vdi"
exit 1
}
# if {![file exists bin/seoul_stress32.raw]} {
# puts "Please provide a disk image file to bin/seoul_stress32.raw"
# exit 1
# }
set mke2fs [installed_command mke2fs]
set dd [installed_command dd]
# catch { exec $dd if=/dev/zero of=bin/seoul-disc.raw bs=1M count=12000 }
catch { exec $dd if=/dev/zero of=bin/seoul-disc.raw bs=1M count=6000 }
catch { exec $mke2fs -F bin/seoul-disc.raw }
exec [installed_command e2cp] bin/seoul_stress32.vdi bin/seoul-disc.raw:seoul_stress32.vdi
# exec [installed_command e2cp] bin/seoul_stress32.raw bin/seoul-disc.raw:seoul_stress32.raw
}
append qemu_args " -m 2536 "
append qemu_args " -cpu phenom"
append qemu_args " -drive id=disk,file=bin/seoul-disc.raw,format=raw,if=none"
append qemu_args " -device ahci,id=ahci -device ide-drive,drive=disk,bus=ahci.0"
run_genode_until forever
exit
}
set match_guest_log "\[init -\> seoul\].*VMM: #"
set match_guest_down "\[init -\> seoul\].*VMM: STANDBY IMMEDIATE"
set match_boot_string "--- Seoul VMM starting ---"
set vmm_name "seoul"
set vcpus_to_be_used 1
set use_vcpus $vcpus_to_be_used
lappend results_expected 1 2 20 75
lappend boottime_expected 51
source ${genode_dir}/repos/ports/run/seoul.inc
source ${genode_dir}/repos/ports/run/vmm_vm_stress.inc
run_genode_until $match_guest_down 20 [output_spawn_id]
kill_spawned [output_spawn_id]
set vcpus_to_be_used 2
set use_vcpus $vcpus_to_be_used
lappend results_expected 2 2 21 46
lappend boottime_expected 51
source ${genode_dir}/repos/ports/run/seoul.inc
source ${genode_dir}/repos/ports/run/vmm_vm_stress.inc
run_genode_until $match_guest_down 20 [output_spawn_id]
kill_spawned [output_spawn_id]
set vcpus_to_be_used 3
set use_vcpus $vcpus_to_be_used
lappend results_expected 3 2 21 37
lappend boottime_expected 52
source ${genode_dir}/repos/ports/run/seoul.inc
source ${genode_dir}/repos/ports/run/vmm_vm_stress.inc
run_genode_until $match_guest_down 20 [output_spawn_id]
kill_spawned [output_spawn_id]
set vcpus_to_be_used 4
set use_vcpus $vcpus_to_be_used
lappend results_expected 4 2 23 33
lappend boottime_expected 53
source ${genode_dir}/repos/ports/run/seoul.inc
source ${genode_dir}/repos/ports/run/vmm_vm_stress.inc
run_genode_until $match_guest_down 20 [output_spawn_id]
kill_spawned [output_spawn_id]
#
# Dump aggregated output of the several runs above
#
grep_output "$match_guest_log.*cpus="
puts $output
set merge_host_output [split $output_host "\n"]
set merge_host_extra [split $output_host_extra "\n"]
for { set i 0 } { $i < [llength $merge_host_output] } { incr i} {
puts "[lindex $merge_host_output $i] [lindex $merge_host_extra $i]"
}
evaluate_stress

View File

@ -1,32 +0,0 @@
Seoul (formerly Vancouver) is a virtual machine monitor originally developed
for the use with the NOVA hypervisor. Nowadays it is also available for seL4,
for Fiasco.OC and for NOVA on Genode. Seoul virtualizes 32bit x86 PC hardware
including various peripherals. The combination of NOVA and Vancouver (later
Seoul) is described in the following paper by Udo Steinberg and Bernhard Kauer:
[http://os.inf.tu-dresden.de/papers_ps/steinberg_eurosys2010.pdf - NOVA: A Microhypervisor-Based Secure Virtualization Architecture]
The NOVA project website is [http://hypervisor.org]
The latest <outdated> Seoul home is [https://github.com/TUD-OS/seoul]
The Seoul version as used by Genode is [https://github.com/alex-ab/seoul], branch
genode_<release>.
Usage
-----
<config width="1024" height="768" vmm_memory="10M" map_small="no"
rdtsc_exit="no" vmm_vcpu_same_cpu="no">
...
</config>
* The width/height specify the maximum area announced to the guest for the
framebuffer. The values are read once during boot of the VMM. The
values shown above are the default values.
* The vmm_memory value specify the amount of memory reserved for the Seoul VMM
(so it is not available to the VM). The rest of the memory as specified in
the Genode config is assigned to the VM.
* map_small specifies whether just 4k pages should be used. Default is shown.
* rdtsc_exit specifies whether the VM should exit on each rdtsc instruction.
Default is shown.
* vmm_vcpu_same_cpu specifies whether the main entrypoint should run on the
same CPU as the first virtual CPU. Default is shown.

View File

@ -1,235 +0,0 @@
/*
* \brief Back end used for obtaining multi-boot modules
* \author Norman Feske
* \author Markus Partheymueller
* \date 2011-11-20
*/
/*
* Copyright (C) 2011-2017 Genode Labs GmbH
* Copyright (C) 2012 Intel Corporation
*
* This file is distributed under the terms of the GNU General Public License
* version 2.
*
* The code is partially based on the Vancouver VMM, which is distributed
* under the terms of the GNU General Public License version 2.
*
* Modifications by Intel Corporation are contributed under the terms and
* conditions of the GNU General Public License version 2.
*/
#ifndef _BOOT_MODULE_PROVIDER_H_
#define _BOOT_MODULE_PROVIDER_H_
/* Genode includes */
#include <util/string.h>
#include <util/misc_math.h>
#include <util/xml_node.h>
#include <base/log.h>
#include <rom_session/connection.h>
class Boot_module_provider
{
private:
Genode::Xml_node _multiboot_node;
enum { MODULE_NAME_MAX_LEN = 48 };
typedef Genode::String<MODULE_NAME_MAX_LEN> Name;
public:
/**
* Exception class
*/
class Destination_buffer_too_small { };
class Module_loading_failed { };
/**
* Constructor
*
* \param multiboot_node XML node containing the list of boot modules
* as sub nodes
*/
Boot_module_provider(Genode::Xml_node multiboot_node)
:
_multiboot_node(multiboot_node)
{ }
/************************************
** Boot_module_provider interface **
************************************/
/**
* Copy module data to specified buffer
*
* \return module size in bytes, or 0 if module does not exist
* \throw Destination_buffer_too_small
*/
Genode::size_t data(Genode::Env &env, int module_index,
void *dst, Genode::size_t dst_len) const
{
using namespace Genode;
try {
Xml_node mod_node = _multiboot_node.sub_node(module_index);
if (mod_node.has_type("rom")) {
/*
* Determine ROM file name, which is specified as 'label'
* attribute of the 'rom' node. If no 'label' argument is
* provided, use the 'name' attribute as file name.
*/
Name const label = mod_node.has_attribute("label")
? mod_node.attribute_value("label", Name())
: mod_node.attribute_value("name", Name());
/*
* Open ROM session
*/
Rom_connection rom(env, label.string());
Dataspace_capability ds = rom.dataspace();
Genode::size_t const src_len = Dataspace_client(ds).size();
if (src_len > dst_len) {
warning(__func__, ": src_len=", src_len, " dst_len=", dst_len);
throw Destination_buffer_too_small();
}
void * const src = env.rm().attach(ds);
/*
* Copy content to destination buffer
*/
Genode::memcpy(dst, src, src_len);
/*
* Detach ROM dataspace from local address space. The ROM
* session will be closed automatically when we leave the
* current scope and the 'rom' object gets destructed.
*/
env.rm().detach(src);
return src_len;
} else if (mod_node.has_type("inline")) {
/*
* Copy inline content directly to destination buffer
*/
mod_node.with_raw_content([&] (char const *ptr, size_t size) {
Genode::memcpy(dst, ptr, size); });
return mod_node.content_size();
}
warning("XML node ", module_index, " in multiboot node has unexpected type");
throw Module_loading_failed();
}
catch (Xml_node::Nonexistent_sub_node) { }
catch (Xml_node::Nonexistent_attribute) { }
catch (Destination_buffer_too_small) {
error("Boot_module_provider: destination buffer too small"); }
catch (Region_map::Region_conflict) {
error("Boot_module_provider: Region_map::Region_conflict");
throw Module_loading_failed(); }
catch (Region_map::Invalid_dataspace) {
error("Boot_module_provider: Region_map::Invalid_dataspace");
throw Module_loading_failed(); }
catch (Rom_connection::Rom_connection_failed) {
error("Boot_module_provider: Rom_connection_failed"); }
catch (...) {
error("Boot_module_provider: Spurious exception");
throw Module_loading_failed();
}
/*
* We should get here only if there are XML parsing errors
*/
return 0;
}
/**
* Copy command line to specified buffer
*
* \return length of command line in bytes, or 0 if module does not exist
*/
Genode::size_t cmdline(int module_index,
char *dst, Genode::size_t dst_len) const
{
using namespace Genode;
try {
Xml_node mod_node = _multiboot_node.sub_node(module_index);
if (mod_node.has_type("rom") || mod_node.has_type("inline")) {
Genode::size_t cmd_len = 0;
Name const name = mod_node.attribute_value("name", Name());
Genode::size_t const name_len = Genode::strlen(name.string());
/*
* Check if destination buffer can hold the name including
* the zero termination.
*/
if (name_len + 1 >= dst_len)
return 0;
/* copy name to command line */
copy_cstring(&dst[cmd_len], name.string(), name_len + 1);
cmd_len += name_len;
/* check if name fills entire destination buffer */
if (cmd_len + 1 == dst_len) {
dst[cmd_len++] = 0;
return cmd_len;
}
if (mod_node.has_attribute("cmdline")) {
typedef String<256> Cmdline;
Cmdline const cmdline = mod_node.attribute_value("cmdline", Cmdline());
/* add single space between name and arguments */
dst[cmd_len++] = ' ';
if (cmd_len + 1 == dst_len) {
dst[cmd_len++] = 0;
return cmd_len;
}
/* copy 'cmdline' attribute to destination buffer */
copy_cstring(&dst[cmd_len], cmdline.string(), dst_len - cmd_len);
/*
* The string returned by the 'value' function is
* zero-terminated. Count and return the total number
* of command-line characters.
*/
return Genode::strlen(dst);
}
return cmd_len;
}
warning("XML node ", module_index, " in multiboot node has unexpected type");
return 0;
}
catch (Xml_node::Nonexistent_sub_node) { }
/*
* We should get here only if there are XML parsing errors
*/
return 0;
}
};
#endif /* _BOOT_MODULE_PROVIDER_H_ */

File diff suppressed because it is too large Load Diff

View File

@ -1,434 +0,0 @@
/*
* \brief Manager of all VM requested console functionality
* \author Markus Partheymueller
* \author Norman Feske
* \author Alexander Boettcher
* \date 2012-07-31
*/
/*
* Copyright (C) 2011-2017 Genode Labs GmbH
* Copyright (C) 2012 Intel Corporation
*
* This file is distributed under the terms of the GNU General Public License
* version 2.
*
* The code is partially based on the Vancouver VMM, which is distributed
* under the terms of the GNU General Public License version 2.
*
* Modifications by Intel Corporation are contributed under the terms and
* conditions of the GNU General Public License version 2.
*/
/* base includes */
#include <util/register.h>
/* nitpicker graphics backend */
#include <nitpicker_gfx/tff_font.h>
#include <nul/motherboard.h>
#include <host/screen.h>
/* local includes */
#include "console.h"
extern char _binary_mono_tff_start[];
static Tff_font::Static_glyph_buffer<4096> glyph_buffer { };
static Tff_font default_font(_binary_mono_tff_start, glyph_buffer);
static struct {
Genode::uint64_t checksum1 = 0;
Genode::uint64_t checksum2 = 0;
unsigned unchanged = 0;
bool cmp_even = 1;
bool active = false;
bool vga_revoked = false;
bool vga_update = false; /* update indirectly by vbios */
} fb_state;
/**
* Layout of PS/2 mouse packet
*/
struct Ps2_mouse_packet : Genode::Register<32>
{
struct Packet_size : Bitfield<0, 3> { };
struct Left_button : Bitfield<8, 1> { };
struct Middle_button : Bitfield<9, 1> { };
struct Right_button : Bitfield<10, 1> { };
struct Rx_high : Bitfield<12, 1> { };
struct Ry_high : Bitfield<13, 1> { };
struct Rx_low : Bitfield<16, 8> { };
struct Ry_low : Bitfield<24, 8> { };
};
static bool mouse_event(Input::Event const &ev)
{
using namespace Input;
bool result = false;
auto mouse_button = [] (Keycode key) {
return key == BTN_LEFT || key == BTN_MIDDLE || key == BTN_RIGHT; };
ev.handle_press([&] (Keycode key, Genode::Codepoint) {
result |= mouse_button(key); });
ev.handle_release([&] (Keycode key) {
result |= mouse_button(key); });
result |= ev.absolute_motion() || ev.relative_motion();
result |= ev.wheel();
return result;
}
/**
* Convert Genode::Input event to PS/2 packet
*
* This function updates _left, _middle, and _right as a side effect.
*/
unsigned Seoul::Console::_input_to_ps2mouse(Input::Event const &ev)
{
/* track state of mouse buttons */
auto apply_button = [] (Input::Event const &ev, Input::Keycode key, bool &state) {
if (ev.key_press (key)) state = true;
if (ev.key_release(key)) state = false;
};
apply_button(ev, Input::BTN_LEFT, _left);
apply_button(ev, Input::BTN_MIDDLE, _middle);
apply_button(ev, Input::BTN_RIGHT, _right);
int rx = 0;
int ry = 0;
ev.handle_absolute_motion([&] (int x, int y) {
static int ox = 0, oy = 0;
rx = x - ox; ry = y - oy;
ox = x; oy = y;
});
ev.handle_relative_motion([&] (int x, int y) { rx = x; ry = y; });
/* clamp relative motion vector to bounds */
int const boundary = 200;
rx = Genode::min(boundary, Genode::max(-boundary, rx));
ry = -Genode::min(boundary, Genode::max(-boundary, ry));
/* assemble PS/2 packet */
Ps2_mouse_packet::access_t packet = 0;
Ps2_mouse_packet::Packet_size::set (packet, 3);
Ps2_mouse_packet::Left_button::set (packet, _left);
Ps2_mouse_packet::Middle_button::set(packet, _middle);
Ps2_mouse_packet::Right_button::set (packet, _right);
Ps2_mouse_packet::Rx_high::set (packet, (rx >> 8) & 1);
Ps2_mouse_packet::Ry_high::set (packet, (ry >> 8) & 1);
Ps2_mouse_packet::Rx_low::set (packet, rx & 0xff);
Ps2_mouse_packet::Ry_low::set (packet, ry & 0xff);
return packet;
}
enum {
PHYS_FRAME_VGA = 0xa0,
PHYS_FRAME_VGA_COLOR = 0xb8,
FRAME_COUNT_COLOR = 0x8
};
unsigned Seoul::Console::_input_to_ps2wheel(Input::Event const &ev)
{
int rz = 0;
ev.handle_wheel([&](int x, int y) { rz = y; });
return (unsigned)rz;
}
/* bus callbacks */
bool Seoul::Console::receive(MessageConsole &msg)
{
switch (msg.type) {
case MessageConsole::TYPE_ALLOC_VIEW :
_guest_fb = msg.ptr;
_regs = msg.regs;
msg.view = 0;
return true;
case MessageConsole::TYPE_SWITCH_VIEW:
/* XXX: For now, we only have one view. */
return true;
case MessageConsole::TYPE_GET_MODEINFO:
enum {
MEMORY_MODEL_TEXT = 0,
MEMORY_MODEL_DIRECT_COLOR = 6,
};
/*
* We supply two modes to the guest, text mode and one
* configured graphics mode 16-bit.
*/
if (msg.index == 0) {
msg.info->_vesa_mode = 3;
msg.info->attr = 0x1;
msg.info->resolution[0] = 80;
msg.info->resolution[1] = 25;
msg.info->bytes_per_scanline = 80*2;
msg.info->bytes_scanline = 80*2;
msg.info->bpp = 4;
msg.info->memory_model = MEMORY_MODEL_TEXT;
msg.info->phys_base = PHYS_FRAME_VGA_COLOR << 12;
msg.info->_phys_size = FRAME_COUNT_COLOR << 12;
return true;
} else if (msg.index == 1) {
/*
* It's important to set the _vesa_mode field, otherwise the
* device model is going to ignore this mode.
*/
unsigned const bpp = _fb_mode.bytes_per_pixel();
msg.info->_vesa_mode = 0x138;
msg.info->attr = 0x39f;
msg.info->resolution[0] = _fb_mode.area.w();
msg.info->resolution[1] = _fb_mode.area.h();
msg.info->bytes_per_scanline = _fb_mode.area.w()*bpp;
msg.info->bytes_scanline = _fb_mode.area.w()*bpp;
msg.info->bpp = 32;
msg.info->memory_model = MEMORY_MODEL_DIRECT_COLOR;
msg.info->vbe1[0] = 0x8; /* red mask size */
msg.info->vbe1[1] = 0x10; /* red field position */
msg.info->vbe1[2] = 0x8; /* green mask size */
msg.info->vbe1[3] = 0x8; /* green field position */
msg.info->vbe1[4] = 0x8; /* blue mask size */
msg.info->vbe1[5] = 0x0; /* blue field position */
msg.info->vbe1[6] = 0x0; /* reserved mask size */
msg.info->vbe1[7] = 0x0; /* reserved field position */
msg.info->colormode = 0x0; /* direct color mode info */
msg.info->phys_base = 0xe0000000;
msg.info->_phys_size = _fb_mode.area.count()*bpp;
return true;
}
return false;
case MessageConsole::TYPE_KILL: /* all CPUs go idle */
_handle_fb(); /* refresh before going to sleep */
fb_state.active = false;
return true;
case MessageConsole::TYPE_RESET: /* first of all sleeping CPUs woke up */
_reactivate();
return true;
default:
return true;
}
}
void Screen::vga_updated()
{
fb_state.vga_update = true;
}
void Seoul::Console::_reactivate()
{
fb_state.active = true;
MessageTimer msg(_timer, _unsynchronized_motherboard.clock()->abstime(1, 1000));
_unsynchronized_motherboard.bus_timer.send(msg);
}
bool Seoul::Console::receive(MessageMemRegion &msg)
{
/* we had a fault in the text framebuffer */
bool reactivate = (msg.page >= PHYS_FRAME_VGA &&
msg.page < PHYS_FRAME_VGA_COLOR + FRAME_COUNT_COLOR);
/* vga memory got changed indirectly by vbios */
if (fb_state.vga_update) {
fb_state.vga_update = false;
if (!fb_state.active)
reactivate = true;
}
if (reactivate) {
fb_state.vga_revoked = false;
//Logging::printf("Reactivating text buffer loop.\n");
_reactivate();
}
return false;
}
unsigned Seoul::Console::_handle_fb()
{
if (!_guest_fb || !_regs)
return 0;
enum { TEXT_MODE = 0 };
/* transfer text buffer content into chunky canvas */
if (_regs->mode == TEXT_MODE) {
if (fb_state.vga_revoked || !fb_state.active) return 0;
memset(_pixels, 0, _fb_size);
if (fb_state.cmp_even) fb_state.checksum1 = 0;
else fb_state.checksum2 = 0;
for (int j=0; j<25; j++) {
for (int i=0; i<80; i++) {
Text_painter::Position const where(i*8, j*15);
char character = *((char *) (_guest_fb +(_regs->offset << 1) +j*80*2+i*2));
char colorvalue = *((char *) (_guest_fb+(_regs->offset << 1)+j*80*2+i*2+1));
char buffer[2]; buffer[0] = character; buffer[1] = 0;
char fg = colorvalue & 0xf;
if (fg == 0x8) fg = 0x7;
unsigned lum = ((fg & 0x8) >> 3)*127;
Genode::Color color(((fg & 0x4) >> 2)*127+lum, /* R+luminosity */
((fg & 0x2) >> 1)*127+lum, /* G+luminosity */
(fg & 0x1)*127+lum /* B+luminosity */);
Text_painter::paint(_surface, where, default_font, color, buffer);
/* Checksum for comparing */
if (fb_state.cmp_even) fb_state.checksum1 += character;
else fb_state.checksum2 += character;
}
}
fb_state.cmp_even = !fb_state.cmp_even;
/* compare checksums to detect changed buffer */
if (fb_state.checksum1 != fb_state.checksum2) {
fb_state.unchanged = 0;
_framebuffer.refresh(0, 0, _fb_mode.area.w(), _fb_mode.area.h());
return 100;
}
if (++fb_state.unchanged < 10)
return fb_state.unchanged * 30;
/* if we copy the same data 10 times, unmap the text buffer from guest */
_memory.detach(PHYS_FRAME_VGA_COLOR << 12,
FRAME_COUNT_COLOR << 12);
fb_state.vga_revoked = true;
fb_state.unchanged = 0;
_framebuffer.refresh(0, 0, _fb_mode.area.w(), _fb_mode.area.h());
//Logging::printf("Deactivated text buffer loop.\n");
return 0;
}
if (!fb_state.vga_revoked) {
_memory.detach(PHYS_FRAME_VGA_COLOR << 12,
FRAME_COUNT_COLOR << 12);
fb_state.vga_revoked = true;
}
if (!fb_state.active) {
fb_state.unchanged = 0;
return 0;
}
_framebuffer.refresh(0, 0, _fb_mode.area.w(), _fb_mode.area.h());
fb_state.unchanged++;
return (fb_state.unchanged > 4) ? 4 * 10 : fb_state.unchanged * 10;
}
void Seoul::Console::_handle_input()
{
_input.for_each_event([&] (Input::Event const &ev) {
if (!fb_state.active) {
fb_state.active = true;
MessageTimer msg(_timer, _motherboard()->clock()->abstime(1, 1000));
_motherboard()->bus_timer.send(msg);
}
/* update mouse model (PS2) */
if (mouse_event(ev)) {
MessageInput msg(0x10001, _input_to_ps2mouse(ev), _input_to_ps2wheel(ev));
_motherboard()->bus_input.send(msg);
}
ev.handle_press([&] (Input::Keycode key, Genode::Codepoint) {
if (key <= 0xee)
_vkeyb.handle_keycode_press(key); });
ev.handle_release([&] (Input::Keycode key) {
if (key <= 0xee)
_vkeyb.handle_keycode_release(key); });
});
}
void Seoul::Console::register_host_operations(Motherboard &motherboard)
{
motherboard.bus_console .add(this, receive_static<MessageConsole>);
motherboard.bus_memregion.add(this, receive_static<MessageMemRegion>);
motherboard.bus_timeout .add(this, receive_static<MessageTimeout>);
MessageTimer msg;
if (!motherboard.bus_timer.send(msg))
Logging::panic("%s can't get a timer", __PRETTY_FUNCTION__);
_timer = msg.nr;
}
bool Seoul::Console::receive(MessageTimeout &msg) {
if (msg.nr != _timer)
return false;
unsigned next_timeout_ms = _handle_fb();
if (next_timeout_ms) {
MessageTimer msg_t(_timer, _unsynchronized_motherboard.clock()->abstime(next_timeout_ms, 1000));
_unsynchronized_motherboard.bus_timer.send(msg_t);
}
return true;
}
Seoul::Console::Console(Genode::Env &env, Genode::Allocator &alloc,
Synced_motherboard &mb,
Motherboard &unsynchronized_motherboard,
Gui::Connection &gui,
Seoul::Guest_memory &guest_memory)
:
_env(env),
_unsynchronized_motherboard(unsynchronized_motherboard),
_motherboard(mb),
_framebuffer(*gui.framebuffer()),
_input(*gui.input()),
_memory(guest_memory),
_fb_ds(_framebuffer.dataspace()),
_fb_mode(_framebuffer.mode()),
_fb_size(Genode::Dataspace_client(_fb_ds).size()),
_fb_vm_ds(env.ram().alloc(_fb_size)),
_fb_vm_mapping(_env.rm().attach(_fb_vm_ds)),
_vm_phys_fb(guest_memory.alloc_io_memory(_fb_size)),
_pixels(_env.rm().attach(_fb_ds)),
_surface(reinterpret_cast<Genode::Pixel_rgb888 *>(_pixels), _fb_mode.area)
{
guest_memory.add_region(alloc, PHYS_FRAME_VGA << 12,
_fb_vm_mapping, _fb_vm_ds, _fb_size);
guest_memory.add_region(alloc, _vm_phys_fb,
Genode::addr_t(_pixels), _fb_ds, _fb_size);
_input.sigh(_signal_input);
}

View File

@ -1,113 +0,0 @@
/*
* \brief Manager of all VM requested console functionality
* \author Markus Partheymueller
* \date 2012-07-31
*/
/*
* Copyright (C) 2012 Intel Corporation
* Copyright (C) 2013-2017 Genode Labs GmbH
*
* This file is distributed under the terms of the GNU General Public License
* version 2.
*
* The code is partially based on the Vancouver VMM, which is distributed
* under the terms of the GNU General Public License version 2.
*
* Modifications by Intel Corporation are contributed under the terms and
* conditions of the GNU General Public License version 2.
*/
#ifndef _CONSOLE_H_
#define _CONSOLE_H_
/* base includes */
#include <base/env.h>
#include <dataspace/client.h>
#include <util/string.h>
#include <util/bit_array.h>
/* os includes */
#include <framebuffer_session/connection.h>
#include <input/event.h>
#include <gui_session/connection.h>
#include <timer_session/connection.h>
#include <os/pixel_rgb888.h>
/* local includes */
#include "keyboard.h"
#include "synced_motherboard.h"
#include "guest_memory.h"
namespace Seoul {
class Console;
using Genode::Pixel_rgb888;
using Genode::Dataspace_capability;
}
class Seoul::Console : public StaticReceiver<Seoul::Console>
{
private:
Genode::Env &_env;
Motherboard &_unsynchronized_motherboard;
Synced_motherboard &_motherboard;
Framebuffer::Session &_framebuffer;
Input::Session_client &_input;
Seoul::Guest_memory &_memory;
Dataspace_capability const _fb_ds;
Framebuffer::Mode const _fb_mode;
size_t const _fb_size;
Dataspace_capability const _fb_vm_ds;
Genode::addr_t const _fb_vm_mapping;
Genode::addr_t const _vm_phys_fb;
short *_pixels;
Genode::Surface<Pixel_rgb888> _surface;
unsigned _timer { 0 };
Keyboard _vkeyb { _motherboard };
char *_guest_fb { nullptr };
VgaRegs *_regs { nullptr };
bool _left { false };
bool _middle { false };
bool _right { false };
unsigned _input_to_ps2mouse(Input::Event const &);
unsigned _input_to_ps2wheel(Input::Event const &);
Genode::Signal_handler<Console> _signal_input
= { _env.ep(), *this, &Console::_handle_input };
void _handle_input();
unsigned _handle_fb();
void _reactivate();
/*
* Noncopyable
*/
Console(Console const &);
Console &operator = (Console const &);
public:
Genode::addr_t attached_framebuffer() const { return _fb_vm_mapping; }
Genode::addr_t framebuffer_size() const { return _fb_size; }
Genode::addr_t vm_phys_framebuffer() const { return _vm_phys_fb; }
/* bus callbacks */
bool receive(MessageConsole &);
bool receive(MessageMemRegion &);
bool receive(MessageTimeout &);
void register_host_operations(Motherboard &);
/**
* Constructor
*/
Console(Genode::Env &env, Genode::Allocator &alloc,
Synced_motherboard &, Motherboard &,
Gui::Connection &, Seoul::Guest_memory &);
};
#endif /* _CONSOLE_H_ */

View File

@ -1,105 +0,0 @@
/*
* \brief Meta-data registry about the device models of Vancouver
* \author Norman Feske
* \author Markus Partheymueller
* \date 2011-11-18
*/
/*
* Copyright (C) 2011-2017 Genode Labs GmbH
* Copyright (C) 2012 Intel Corporation
*
* This file is distributed under the terms of the GNU General Public License
* version 2.
*
* The code is partially based on the Vancouver VMM, which is distributed
* under the terms of the GNU General Public License version 2.
*
* Modifications by Intel Corporation are contributed under the terms and
* conditions of the GNU General Public License version 2.
*/
/* local includes */
#include "device_model_registry.h"
Device_model_registry *device_model_registry()
{
static Device_model_registry inst;
return &inst;
}
Device_model_info::Device_model_info(char const *name, Create create,
char const *arg_names[])
:
name(name), create(create), arg_names(arg_names)
{
device_model_registry()->insert(this);
}
/**
* Helper macro to create global 'Device_model_info' objects
*/
#define MODEL_INFO(name, ...) \
extern "C" void __parameter_##name##_fn(Motherboard &, unsigned long *, \
const char *, unsigned); \
static char const * name##_arg_names[] = { __VA_ARGS__ , 0 }; \
static Device_model_info \
name##_model_info(#name, __parameter_##name##_fn, name##_arg_names);
#define MODEL_INFO_NO_ARG(name) MODEL_INFO(name, 0)
/*******************************
** Registry of device models **
*******************************/
/*
* For each device model, a dedicated global 'Device_model_info' object is
* created. At construction time, each 'Device_model_info' adds itself to
* the 'Device_model_registry'.
*
* We supplement the device models with the information about their argument
* names. This enables us to describe a virtual machine via a simple XML format
* instead of using a special syntax.
*/
MODEL_INFO(mem, "start", "end")
MODEL_INFO(nullio, "io_base", "size")
MODEL_INFO(pic, "io_base", "irq", "elcr_base")
MODEL_INFO(pit, "io_base", "irq")
MODEL_INFO(scp, "io_port_a", "io_port_b")
MODEL_INFO(kbc, "io_base", "irq_kbd", "irq_aux")
MODEL_INFO(keyb, "ps2_port", "host_keyboard")
MODEL_INFO(mouse, "ps2_port", "host_mouse")
MODEL_INFO(rtc, "io_base", "irq")
MODEL_INFO(serial, "io_base", "irq", "host_serial")
MODEL_INFO(pmtimer, "io_port")
MODEL_INFO(vga, "io_base", "fb_size")
MODEL_INFO(vga_fbsize, "fb_size")
MODEL_INFO(pcihostbridge, "bus_num", "bus_count", "io_base", "mem_base")
MODEL_INFO(intel82576vf, "promisc", "mem_mmio", "mem_msix", "txpoll_us", "rx_map")
MODEL_INFO(rtl8029, "bdf", "irq", "port")
MODEL_INFO(ide, "port0", "port1", "irq", "bdf", "disk")
MODEL_INFO(ahci, "mem", "irq", "bdf")
MODEL_INFO(drive, "sigma0drive", "controller", "port")
MODEL_INFO(vbios_multiboot, "modaddr", "lowmem")
MODEL_INFO_NO_ARG(vbios_disk)
MODEL_INFO(vbios_keyboard, "host_keyboard")
MODEL_INFO_NO_ARG(vbios_mem)
MODEL_INFO_NO_ARG(vbios_time)
MODEL_INFO_NO_ARG(vbios_reset)
MODEL_INFO_NO_ARG(msi)
MODEL_INFO_NO_ARG(ioapic)
MODEL_INFO_NO_ARG(vcpu)
MODEL_INFO_NO_ARG(halifax)
MODEL_INFO_NO_ARG(vbios)
MODEL_INFO_NO_ARG(lapic)
MODEL_INFO(hostsink, "host_dev", "buffer")

View File

@ -1,66 +0,0 @@
/*
* \brief Meta-data registry about the device models of Vancouver
* \author Norman Feske
* \date 2011-11-18
*/
/*
* Copyright (C) 2011-2017 Genode Labs GmbH
*
* This file is part of the Genode OS framework, which is distributed
* under the terms of the GNU General Public License version 2.
*/
#ifndef _DEVICE_MODEL_REGISTRY_H_
#define _DEVICE_MODEL_REGISTRY_H_
/* Genode includes */
#include <util/list.h>
#include <util/string.h>
/* NOVA userland includes */
#include <nul/motherboard.h>
struct Device_model_info : Genode::List<Device_model_info>::Element
{
typedef void (*Create)(Motherboard &, unsigned long *argv,
const char *args, unsigned args_len);
/**
* Name of device model
*/
char const *name;
/**
* Function for creating a new device-model instance
*/
Create create;
/**
* Argument names
*/
char const **arg_names;
Device_model_info(char const *name, Create create, char const *arg_names[]);
};
struct Device_model_registry : Genode::List<Device_model_info>
{
Device_model_info *lookup(char const *name)
{
for (Device_model_info *curr = first(); curr; curr = curr->next())
if (Genode::strcmp(curr->name, name) == 0)
return curr;
return 0;
}
};
/**
* Return singleton instance of device model registry
*/
Device_model_registry *device_model_registry();
#endif /* _DEVICE_MODEL_REGISTRY_H_ */

View File

@ -1,422 +0,0 @@
/*
* \brief Block interface
* \author Markus Partheymueller
* \author Alexander Boettcher
* \date 2012-09-15
*/
/*
* Copyright (C) 2012 Intel Corporation
* Copyright (C) 2013-2018 Genode Labs GmbH
*
* This file is distributed under the terms of the GNU General Public License
* version 2.
*
* The code is partially based on the Vancouver VMM, which is distributed
* under the terms of the GNU General Public License version 2.
*
* Modifications by Intel Corporation are contributed under the terms and
* conditions of the GNU General Public License version 2.
*/
/* Genode includes */
#include <base/log.h>
#include <block_session/connection.h>
#include <base/heap.h>
/* local includes */
#include "disk.h"
static Genode::Heap * disk_heap(Genode::Ram_allocator *ram = nullptr,
Genode::Region_map *rm = nullptr)
{
static Genode::Heap heap(ram, rm);
return &heap;
}
static Genode::Heap * disk_heap_msg(Genode::Env &env)
{
static Genode::Heap heap(&env.ram(), &env.rm(), 4096);
return &heap;
}
static Genode::Heap * disk_heap_avl(Genode::Env &env)
{
static Genode::Heap heap(&env.ram(), &env.rm(), 4096);
return &heap;
}
Seoul::Disk::Disk(Genode::Env &env, Synced_motherboard &mb,
char * backing_store_base, Genode::size_t backing_store_size)
:
_env(env),
_motherboard(mb),
_backing_store_base(backing_store_base),
_backing_store_size(backing_store_size),
_tslab_msg(disk_heap_msg(env)),
_tslab_avl(disk_heap_avl(env))
{
/* initialize disk heap */
disk_heap(&env.ram(), &env.rm());
/* initialize struct with 0 size */
for (int i=0; i < MAX_DISKS; i++) {
_diskcon[i].info.block_size = 0;
}
}
void Seoul::Disk::register_host_operations(Motherboard &motherboard)
{
motherboard.bus_disk.add(this, receive_static<MessageDisk>);
}
void Seoul::Disk_signal::_signal() { _obj.handle_disk(_id); }
void Seoul::Disk::handle_disk(unsigned disknr)
{
Block::Session::Tx::Source *source = _diskcon[disknr].blk_con->tx();
while (source->ack_avail())
{
Block::Packet_descriptor packet = source->get_acked_packet();
char * const source_addr = source->packet_content(packet);
/* find the corresponding MessageDisk object */
Avl_entry * obj = lookup_and_remove(_lookup_msg, source_addr);
if (!obj) {
Genode::warning("unknown MessageDisk object - drop ack of block session ", (void *)source_addr);
continue;
}
/* got the MessageDisk object */
MessageDisk * msg = obj->msg();
/* delete helper object */
destroy(&_tslab_avl, obj);
/* go ahead and tell VMM about new block event */
if (!packet.succeeded() ||
!(packet.operation() == Block::Packet_descriptor::Opcode::READ ||
packet.operation() == Block::Packet_descriptor::Opcode::WRITE)) {
Genode::warning("getting block failed");
MessageDiskCommit mdc(disknr, msg->usertag,
MessageDisk::DISK_STATUS_DEVICE);
_motherboard()->bus_diskcommit.send(mdc);
} else {
if (packet.operation() == Block::Packet_descriptor::Opcode::READ) {
unsigned long long sector = msg->sector;
sector = (sector-packet.block_number())
* _diskcon[disknr].info.block_size;
bool const ok = check_dma_descriptors(msg,
[&](char * const dma_addr, unsigned i)
{
size_t const bytecount = msg->dma[i].bytecount;
if (bytecount > packet.size() ||
sector > packet.size() ||
sector + bytecount > packet.size() ||
source_addr > source->packet_content(packet) + packet.size() - sector - bytecount ||
_backing_store_base + _backing_store_size - bytecount < dma_addr)
return false;
memcpy(dma_addr, source_addr + sector, bytecount);
sector += bytecount;
return true;
});
if (!ok)
Genode::warning("DMA bounds violation during read");
destroy(disk_heap(), msg->dma);
msg->dma = nullptr;
}
MessageDiskCommit mdc (disknr, msg->usertag, MessageDisk::DISK_OK);
_motherboard()->bus_diskcommit.send(mdc);
}
{
Genode::Mutex::Guard guard(_alloc_mutex);
source->release_packet(packet);
}
destroy(&_tslab_msg, msg);
}
/* restart disk operations suspended due to out of memory by alloc_packet */
check_restart();
}
bool Seoul::Disk::receive(MessageDisk &msg)
{
if (msg.disknr >= MAX_DISKS)
Logging::panic("You configured more disks than supported.\n");
struct disk_session &disk = _diskcon[msg.disknr];
if (!disk.info.block_size) {
Genode::String<16> label("VirtualDisk ", msg.disknr);
/*
* If we receive a message for this disk the first time, create the
* structure for it.
*/
try {
Genode::Allocator_avl * block_alloc =
new (disk_heap()) Genode::Allocator_avl(disk_heap());
disk.blk_con =
new (disk_heap()) Block::Connection<>(_env, block_alloc,
4*512*1024,
label.string());
disk.signal =
new (disk_heap()) Seoul::Disk_signal(_env.ep(), *this,
*disk.blk_con, msg.disknr);
} catch (...) {
/* there is none. */
return false;
}
disk.info = disk.blk_con->info();
}
msg.error = MessageDisk::DISK_OK;
switch (msg.type) {
case MessageDisk::DISK_GET_PARAMS:
{
Genode::String<16> label("VirtualDisk ", msg.disknr);
msg.params->flags = DiskParameter::FLAG_HARDDISK;
msg.params->sectors = disk.info.block_count;
msg.params->sectorsize = disk.info.block_size;
msg.params->maxrequestcount = disk.info.block_count;
memcpy(msg.params->name, label.string(), label.length());
return true;
}
case MessageDisk::DISK_WRITE:
/* don't write on read only medium */
if (!disk.info.writeable) {
MessageDiskCommit ro(msg.disknr, msg.usertag,
MessageDisk::DISK_STATUS_DEVICE);
_motherboard()->bus_diskcommit.send(ro);
return true;
}
[[fallthrough]];
case MessageDisk::DISK_READ:
/* read and write handling */
return execute(msg.type == MessageDisk::DISK_WRITE, disk, msg);
default:
Logging::printf("Got MessageDisk type %x\n", msg.type);
return false;
}
}
void Seoul::Disk::check_restart()
{
bool restarted = true;
while (restarted) {
Avl_entry * obj = lookup_and_remove(_restart_msg);
if (!obj)
return;
MessageDisk * const msg = obj->msg();
struct disk_session const &disk = _diskcon[msg->disknr];
restarted = restart(disk, msg);
if (restarted) {
destroy(&_tslab_avl, obj);
} else {
Genode::Mutex::Guard guard(_alloc_mutex);
_restart_msg.insert(obj);
}
}
}
bool Seoul::Disk::restart(struct disk_session const &disk,
MessageDisk * const msg)
{
Block::Session::Tx::Source * const source = disk.blk_con->tx();
unsigned long const total = DmaDescriptor::sum_length(msg->dmacount, msg->dma);
unsigned long const blk_size = disk.info.block_size;
unsigned long const blocks = total/blk_size + ((total%blk_size) ? 1 : 0);
bool const write = msg->type == MessageDisk::DISK_WRITE;
Block::Packet_descriptor packet;
try {
Genode::Mutex::Guard guard(_alloc_mutex);
packet = Block::Packet_descriptor(
disk.blk_con->alloc_packet(blocks * blk_size),
(write) ? Block::Packet_descriptor::WRITE
: Block::Packet_descriptor::READ,
msg->sector, blocks);
char * source_addr = source->packet_content(packet);
_lookup_msg.insert(new (&_tslab_avl) Avl_entry(source_addr, msg));
} catch (...) { return false; }
/* read */
if (!write) {
source->submit_packet(packet);
return true;
}
/* write */
char * source_addr = source->packet_content(packet);
source_addr += (msg->sector - packet.block_number()) * blk_size;
for (unsigned i = 0; i < msg->dmacount; i++) {
char * const dma_addr = _backing_store_base +
msg->dma[i].byteoffset +
msg->physoffset;
memcpy(source_addr, dma_addr, msg->dma[i].bytecount);
source_addr += msg->dma[i].bytecount;
}
/* free up DMA descriptors of write */
destroy(disk_heap(), msg->dma);
msg->dma = nullptr;
source->submit_packet(packet);
return true;
}
bool Seoul::Disk::execute(bool const write, struct disk_session const &disk,
MessageDisk const &msg)
{
unsigned long long const sector = msg.sector;
unsigned long const total = DmaDescriptor::sum_length(msg.dmacount, msg.dma);
unsigned long const blk_size = disk.info.block_size;
unsigned long const blocks = total/blk_size + ((total%blk_size) ? 1 : 0);
Block::Session::Tx::Source * const source = disk.blk_con->tx();
Block::Packet_descriptor packet;
/* msg copy required for acknowledgements */
MessageDisk * const msg_cpy = new (&_tslab_msg) MessageDisk(msg);
char * source_addr = nullptr;
try {
Genode::Mutex::Guard guard(_alloc_mutex);
packet = Block::Packet_descriptor(
disk.blk_con->alloc_packet(blocks * blk_size),
(write) ? Block::Packet_descriptor::WRITE
: Block::Packet_descriptor::READ,
sector, blocks);
source_addr = source->packet_content(packet);
_lookup_msg.insert(new (&_tslab_avl) Avl_entry(source_addr, msg_cpy));
} catch (Block::Session::Tx::Source::Packet_alloc_failed) {
/* msg_cpy object will be used/freed below by copy_dma_descriptors */
} catch (...) {
if (msg_cpy)
destroy(&_tslab_msg, msg_cpy);
Logging::printf("could not allocate disk block elements - "
"write=%u blocks=%lu\n", write, blocks);
return false;
}
/*
* Copy DMA descriptors ever for read requests and for deferred write
* requests. The descriptors can be changed by the guest at any time.
*/
bool const copy_dma_descriptors = !source_addr || !write;
/* invalid packet allocation or read request */
if (copy_dma_descriptors) {
msg_cpy->dma = new (disk_heap()) DmaDescriptor[msg_cpy->dmacount];
for (unsigned i = 0; i < msg_cpy->dmacount; i++)
memcpy(msg_cpy->dma + i, msg.dma + i, sizeof(DmaDescriptor));
/* validate DMA descriptors */
bool const ok = check_dma_descriptors(msg_cpy,
[&](char * const dma_addr, unsigned i)
{
if (!write)
/* evaluated during receive */
return true;
size_t const bytecount = msg_cpy->dma[i].bytecount;
if (bytecount > packet.size() ||
source_addr > source->packet_content(packet) + packet.size() - bytecount ||
_backing_store_base + _backing_store_size - bytecount < dma_addr)
return false;
return true;
});
if (ok) {
/* DMA descriptors look good - go ahead with disk request */
if (source_addr)
/* valid packet for read request */
source->submit_packet(packet);
else {
/* failed packet allocation, restart at later point in time */
Genode::Mutex::Guard guard(_alloc_mutex);
_restart_msg.insert(new (&_tslab_avl) Avl_entry(source_addr,
msg_cpy));
}
return true;
}
/* DMA descriptors look bad - free resources */
destroy(disk_heap(), msg_cpy->dma);
destroy(&_tslab_msg, msg_cpy);
if (source_addr) {
Genode::Mutex::Guard guard(_alloc_mutex);
source->release_packet(packet);
}
return false;
}
/* valid packet allocation for write request */
source_addr += (sector - packet.block_number()) * blk_size;
bool const ok = check_dma_descriptors(msg_cpy,
[&](char * const dma_addr, unsigned i)
{
/* read bytecount from guest memory once and don't evaluate again */
size_t const bytecount = msg.dma[i].bytecount;
if (bytecount > packet.size() ||
source_addr > source->packet_content(packet) + packet.size() - bytecount ||
_backing_store_base + _backing_store_size - bytecount < dma_addr)
return false;
memcpy(source_addr, dma_addr, bytecount);
source_addr += bytecount;
return true;
});
if (ok) {
/* don't needed anymore + protect us to use it again */
msg_cpy->dma = nullptr;
source->submit_packet(packet);
} else {
destroy(&_tslab_msg, msg_cpy);
Genode::Mutex::Guard guard(_alloc_mutex);
source->release_packet(packet);
}
return ok;
}

View File

@ -1,197 +0,0 @@
/*
* \brief Block interface
* \author Markus Partheymueller
* \author Alexander Boettcher
* \date 2012-09-15
*/
/*
* Copyright (C) 2012 Intel Corporation
* Copyright (C) 2013-2017 Genode Labs GmbH
*
* This file is distributed under the terms of the GNU General Public License
* version 2.
*
* The code is partially based on the Vancouver VMM, which is distributed
* under the terms of the GNU General Public License version 2.
*
* Modifications by Intel Corporation are contributed under the terms and
* conditions of the GNU General Public License version 2.
*/
#ifndef _DISK_H_
#define _DISK_H_
/* Genode includes */
#include <base/allocator_avl.h>
#include <block_session/connection.h>
#include <util/string.h>
#include <base/synced_allocator.h>
/* local includes */
#include "synced_motherboard.h"
/* Seoul includes */
#include <host/dma.h>
namespace Seoul {
class Disk;
class Disk_signal;
}
class Seoul::Disk_signal
{
private:
Disk &_obj;
unsigned _id;
void _signal();
public:
Genode::Signal_handler<Disk_signal> const sigh;
Disk_signal(Genode::Entrypoint &ep, Disk &obj,
Block::Connection<> &block, unsigned disk_nr)
:
_obj(obj), _id(disk_nr),
sigh(ep, *this, &Disk_signal::_signal)
{
block.tx_channel()->sigh_ack_avail(sigh);
block.tx_channel()->sigh_ready_to_submit(sigh);
}
};
class Seoul::Disk : public StaticReceiver<Seoul::Disk>
{
private:
Genode::Env &_env;
/* helper class to lookup a MessageDisk object */
class Avl_entry : public Genode::Avl_node<Avl_entry>
{
private:
Genode::addr_t const _key;
MessageDisk * const _msg;
/*
* Noncopyable
*/
Avl_entry(Avl_entry const &);
Avl_entry &operator = (Avl_entry const &);
public:
Avl_entry(void * key, MessageDisk * const msg)
: _key(reinterpret_cast<Genode::addr_t>(key)), _msg(msg) { }
bool higher(Avl_entry *e) const { return e->_key > _key; }
Avl_entry *find(Genode::addr_t ptr)
{
if (ptr == _key) return this;
Avl_entry *obj = this->child(ptr > _key);
return obj ? obj->find(ptr) : 0;
}
MessageDisk * msg() { return _msg; }
};
/* block session used by disk models of VMM */
enum { MAX_DISKS = 4 };
struct disk_session {
Block::Connection<> *blk_con;
Block::Session::Info info;
Disk_signal *signal;
} _diskcon[MAX_DISKS] { };
Synced_motherboard &_motherboard;
char * const _backing_store_base;
size_t const _backing_store_size;
/* slabs for temporary holding MessageDisk objects */
typedef Genode::Tslab<MessageDisk, 128> MessageDisk_Slab;
typedef Genode::Synced_allocator<MessageDisk_Slab> MessageDisk_Slab_Sync;
MessageDisk_Slab_Sync _tslab_msg;
/* Structure to find back the MessageDisk object out of a Block Ack */
typedef Genode::Tslab<Avl_entry, 128> Avl_entry_slab;
typedef Genode::Synced_allocator<Avl_entry_slab> Avl_entry_slab_sync;
Avl_entry_slab_sync _tslab_avl;
Genode::Avl_tree<Avl_entry> _lookup_msg { };
Genode::Avl_tree<Avl_entry> _restart_msg { };
/* _alloc_mutex protects both lists + alloc_packet/release_packet !!! */
Genode::Mutex _alloc_mutex { };
/*
* Noncopyable
*/
Disk(Disk const &);
Disk &operator = (Disk const &);
void check_restart();
bool restart(struct disk_session const &, MessageDisk * const);
bool execute(bool const write, struct disk_session const &,
MessageDisk const &);
template <typename FN>
bool check_dma_descriptors(MessageDisk const * const msg,
FN const &fn)
{
/* check bounds for read and write operations */
for (unsigned i = 0; i < msg->dmacount; i++) {
char * const dma_addr = _backing_store_base +
msg->dma[i].byteoffset +
msg->physoffset;
/* check for bounds */
if (dma_addr >= _backing_store_base + _backing_store_size ||
dma_addr < _backing_store_base)
return false;
if (!fn(dma_addr, i))
return false;
}
return true;
}
/* find the corresponding MessageDisk object */
Avl_entry * lookup_and_remove(Genode::Avl_tree<Avl_entry> &tree,
void * specific_obj = nullptr)
{
Genode::Mutex::Guard guard(_alloc_mutex);
Avl_entry * obj = tree.first();
if (obj && specific_obj)
obj = obj->find(reinterpret_cast<Genode::addr_t>(specific_obj));
if (obj)
tree.remove(obj);
return obj;
}
public:
/**
* Constructor
*/
Disk(Genode::Env &, Synced_motherboard &, char * backing_store_base,
Genode::size_t backing_store_size);
void handle_disk(unsigned);
bool receive(MessageDisk &msg);
void register_host_operations(Motherboard &);
};
#endif /* _DISK_H_ */

View File

@ -1,174 +0,0 @@
/*
* \brief Seoul Guest memory management
* \author Alexander Boettcher
* \author Norman Feske
* \author Markus Partheymueller
* \date 2011-11-18
*/
/*
* Copyright (C) 2011-2019 Genode Labs GmbH
* Copyright (C) 2012 Intel Corporation
*
* This file is distributed under the terms of the GNU General Public License
* version 2.
*
* The code is partially based on the Vancouver VMM, which is distributed
* under the terms of the GNU General Public License version 2.
*/
#ifndef _GUEST_MEMORY_H_
#define _GUEST_MEMORY_H_
#include <rm_session/connection.h>
#include <vm_session/connection.h>
#include <region_map/client.h>
namespace Seoul { class Guest_memory; }
class Seoul::Guest_memory
{
private:
Genode::Env &_env;
Genode::Vm_connection &_vm_con;
Genode::Ram_dataspace_capability _ds;
Genode::size_t const _backing_store_size;
Genode::addr_t _io_mem_alloc;
Genode::addr_t const _local_addr;
/*
* Noncopyable
*/
Guest_memory(Guest_memory const &);
Guest_memory &operator = (Guest_memory const &);
struct Region : Genode::List<Region>::Element {
Genode::addr_t _guest_addr;
Genode::addr_t _local_addr;
Genode::Dataspace_capability _ds;
Genode::addr_t _ds_size;
Region (Genode::addr_t const guest_addr,
Genode::addr_t const local_addr,
Genode::Dataspace_capability ds,
Genode::addr_t const ds_size)
: _guest_addr(guest_addr), _local_addr(local_addr),
_ds(ds), _ds_size(ds_size)
{ }
};
Genode::List<Region> _regions { };
public:
/**
* Number of bytes that are available to the guest
*
* At startup time, some device models (i.e., the VGA controller) claim
* a bit of guest-physical memory for their respective devices (i.e.,
* the virtual frame buffer) by calling 'OP_ALLOC_FROM_GUEST'. This
* function allocates such blocks from the end of the backing store.
* The 'remaining_size' contains the number of bytes left at the lower
* part of the backing store for the use as normal guest-physical RAM.
* It is initialized with the actual backing store size and then
* managed by the 'OP_ALLOC_FROM_GUEST' handler.
*/
Genode::size_t remaining_size;
/**
* Constructor
*
* \param backing_store_size number of bytes of physical RAM to be
* used as guest-physical and device memory,
* allocated from core's RAM service
*/
Guest_memory(Genode::Env &env, Genode::Allocator &alloc,
Genode::Vm_connection &vm_con,
Genode::size_t backing_store_size)
:
_env(env), _vm_con(vm_con),
_ds(env.ram().alloc(backing_store_size)),
_backing_store_size(backing_store_size),
_io_mem_alloc(backing_store_size),
_local_addr(env.rm().attach(_ds)),
remaining_size(backing_store_size)
{
/* free region for attaching it executable */
env.rm().detach(_local_addr);
/*
* RAM used as backing store for guest-physical memory
*/
env.rm().attach_executable(_ds, _local_addr);
/* register ds for VM region */
add_region(alloc, 0UL, _local_addr, _ds, remaining_size);
}
~Guest_memory()
{
/* detach and free backing store */
_env.rm().detach((void *)_local_addr);
_env.ram().free(_ds);
}
/**
* Return pointer to locally mapped backing store
*/
char *backing_store_local_base()
{
return reinterpret_cast<char *>(_local_addr);
}
Genode::size_t backing_store_size()
{
return _backing_store_size;
}
void add_region(Genode::Allocator &alloc,
Genode::addr_t const guest_addr,
Genode::addr_t const local_addr,
Genode::Dataspace_capability ds,
Genode::addr_t const ds_size)
{
_regions.insert(new (alloc) Region(guest_addr, local_addr, ds, ds_size));
}
void attach_to_vm(Genode::Vm_connection &vm_con,
Genode::addr_t guest_start,
Genode::addr_t size)
{
for (Region *r = _regions.first(); r; r = r->next())
{
if (!r->_ds_size || !size || size & 0xfff) continue;
if (size > r->_ds_size) continue;
if (guest_start < r->_guest_addr) continue;
if (guest_start > r->_guest_addr + r->_ds_size - 1) continue;
Genode::addr_t ds_offset = guest_start - r->_guest_addr;
vm_con.attach(r->_ds, guest_start, { .offset = ds_offset,
.size = size,
.executable = true,
.writeable = true });
return;
}
}
void detach(Genode::addr_t const guest_addr, Genode::addr_t const size)
{
_vm_con.detach(guest_addr, size);
}
Genode::addr_t alloc_io_memory(Genode::addr_t const size)
{
Genode::addr_t io_mem = _io_mem_alloc;
_io_mem_alloc += size;
return io_mem;
}
};
#endif /* _GUEST_MEMORY_H_ */

View File

@ -1,25 +0,0 @@
/*
* \brief Memory header expected by Seoul
* \author Markus Partheymueller
* \date 2013-03-02
*/
/*
* Copyright (C) 2011-2017 Genode Labs GmbH
*
* This file is part of the Genode OS framework, which is distributed
* under the terms of the GNU General Public License version 2.
*/
struct Aligned {
size_t alignment;
Aligned(size_t alignment) : alignment(alignment) {}
};
void *operator new[](size_t size);
void *operator new[](size_t size, Aligned const alignment);
void *operator new (size_t size);
void operator delete[](void *ptr);

View File

@ -1,22 +0,0 @@
/*
* \brief Disable original profiling macros of the NOVA userland
* \author Norman Feske
* \date 2011-11-19
*
* This header has the sole purpose to shadow the orignal 'service/profile.h'
* header of the NOVA userland. The original macros rely on special support in
* the linker script. However, we prefer to stick with Genode's generic linker
* script.
*/
/*
* Copyright (C) 2011-2017 Genode Labs GmbH
*
* This file is part of the Genode OS framework, which is distributed
* under the terms of the GNU General Public License version 2.
*/
#pragma once
#define COUNTER_INC(NAME)
#define COUNTER_SET(NAME, VALUE)

View File

@ -1,134 +0,0 @@
/*
* \brief Keyboard manager
* \author Markus Partheymueller
* \date 2012-07-31
*/
/*
* Copyright (C) 2012 Intel Corporation
* Copyright (C) 2013-2017 Genode Labs GmbH
*
* This file is distributed under the terms of the GNU General Public License
* version 2.
*
* The code is partially based on the Vancouver VMM, which is distributed
* under the terms of the GNU General Public License version 2.
*
* Modifications by Intel Corporation are contributed under the terms and
* conditions of the GNU General Public License version 2.
*/
/* local includes */
#include "keyboard.h"
/* vancouver generic keyboard helper */
#include <host/keyboard.h>
#include <nul/vcpu.h>
Seoul::Keyboard::Keyboard(Synced_motherboard &mb)
: _motherboard(mb), _flags(0) { }
bool Seoul::Keyboard::_map_keycode(unsigned &keycode, bool press)
{
switch (keycode) {
/* modifiers */
case Input::KEY_LEFTSHIFT: _flags |= KBFLAG_LSHIFT; keycode = 0x12; break;
case Input::KEY_RIGHTSHIFT: _flags |= KBFLAG_RSHIFT; keycode = 0x59; break;
case Input::KEY_LEFTALT: _flags |= KBFLAG_LALT; keycode = 0x11; break;
case Input::KEY_RIGHTALT: _flags |= KBFLAG_RALT; keycode = 0x11; break;
case Input::KEY_LEFTCTRL: _flags |= KBFLAG_LCTRL; keycode = 0x14; break;
case Input::KEY_RIGHTCTRL: _flags |= KBFLAG_RCTRL; keycode = 0x14; break;
case Input::KEY_LEFTMETA: _flags |= KBFLAG_LWIN; keycode = 0x1f;
if (press) return false;
break;
case Input::KEY_RIGHTMETA: _flags |= KBFLAG_RWIN; keycode = 0x27;
if (press) return false;
break;
case Input::KEY_KPSLASH: _flags |= KBFLAG_EXTEND0;
keycode = GenericKeyboard::translate_sc1_to_sc2(0x35); break;
case Input::KEY_KPENTER: _flags |= KBFLAG_EXTEND0;
keycode = GenericKeyboard::translate_sc1_to_sc2(0x1c); break;
case Input::KEY_F11: _flags |= KBFLAG_EXTEND0;
keycode = GenericKeyboard::translate_sc1_to_sc2(0x57); break;
case Input::KEY_F12: _flags |= KBFLAG_EXTEND0;
keycode = GenericKeyboard::translate_sc1_to_sc2(0x58); break;
case Input::KEY_INSERT: _flags |= KBFLAG_EXTEND0;
keycode = GenericKeyboard::translate_sc1_to_sc2(0x52); break;
case Input::KEY_DELETE: _flags |= KBFLAG_EXTEND0;
keycode = GenericKeyboard::translate_sc1_to_sc2(0x53); break;
case Input::KEY_HOME: _flags |= KBFLAG_EXTEND0;
keycode = GenericKeyboard::translate_sc1_to_sc2(0x47); break;
case Input::KEY_END: _flags |= KBFLAG_EXTEND0;
keycode = GenericKeyboard::translate_sc1_to_sc2(0x4f); break;
case Input::KEY_PAGEUP: _flags |= KBFLAG_EXTEND0;
keycode = GenericKeyboard::translate_sc1_to_sc2(0x49); break;
case Input::KEY_PAGEDOWN: _flags |= KBFLAG_EXTEND0;
keycode = GenericKeyboard::translate_sc1_to_sc2(0x51); break;
case Input::KEY_LEFT: _flags |= KBFLAG_EXTEND0;
keycode = GenericKeyboard::translate_sc1_to_sc2(0x4b); break;
case Input::KEY_RIGHT: _flags |= KBFLAG_EXTEND0;
keycode = GenericKeyboard::translate_sc1_to_sc2(0x4d); break;
case Input::KEY_UP: _flags |= KBFLAG_EXTEND0;
keycode = GenericKeyboard::translate_sc1_to_sc2(0x48); break;
case Input::KEY_DOWN: _flags |= KBFLAG_EXTEND0;
keycode = GenericKeyboard::translate_sc1_to_sc2(0x50); break;
/* up to 0x53, the Genode key codes correspond to scan code set 1 */
default:
if (keycode <= 0x53) {
keycode = GenericKeyboard::translate_sc1_to_sc2(keycode);
break;
} else return false;
}
return true;
}
void Seoul::Keyboard::handle_keycode_press(unsigned keycode)
{
unsigned orig_keycode = keycode;
if (!_map_keycode(keycode, true))
return;
MessageInput msg(0x10000, _flags | keycode);
/* debug */
if ((_flags & KBFLAG_LWIN) && orig_keycode == Input::KEY_INSERT) {
Logging::printf("DEBUG key\n");
/* we send an empty event */
CpuEvent msg(VCpu::EVENT_DEBUG);
for (VCpu *vcpu = _motherboard()->last_vcpu; vcpu; vcpu=vcpu->get_last())
vcpu->bus_event.send(msg);
}
/* reset */
else if ((_flags & KBFLAG_LWIN) && orig_keycode == Input::KEY_END) {
Logging::printf("Reset VM\n");
MessageLegacy msg2(MessageLegacy::RESET, 0);
_motherboard()->bus_legacy.send_fifo(msg2);
}
else _motherboard()->bus_input.send(msg);
_flags &= ~(KBFLAG_EXTEND0 | KBFLAG_RELEASE | KBFLAG_EXTEND1);
}
void Seoul::Keyboard::handle_keycode_release(unsigned keycode)
{
_flags |= KBFLAG_RELEASE;
if (!_map_keycode(keycode, false))
return;
MessageInput msg(0x10000, _flags | keycode);
_motherboard()->bus_input.send(msg);
_flags &= ~(KBFLAG_EXTEND0 | KBFLAG_RELEASE | KBFLAG_EXTEND1);
}

View File

@ -1,57 +0,0 @@
/*
* \brief Keyboard manager
* \author Markus Partheymueller
* \date 2012-07-31
*/
/*
* Copyright (C) 2012 Intel Corporation
* Copyright (C) 2013-2017 Genode Labs GmbH
*
* This file is distributed under the terms of the GNU General Public License
* version 2.
*
* The code is partially based on the Vancouver VMM, which is distributed
* under the terms of the GNU General Public License version 2.
*
* Modifications by Intel Corporation are contributed under the terms and
* conditions of the GNU General Public License version 2.
*/
#ifndef _KEYBOARD_H_
#define _KEYBOARD_H_
/* includes for I/O */
#include <base/env.h>
#include <input/event.h>
#include <input/keycodes.h>
/* local includes */
#include "synced_motherboard.h"
namespace Seoul {
class Keyboard;
}
class Seoul::Keyboard
{
private:
Synced_motherboard &_motherboard;
unsigned _flags;
bool _map_keycode(unsigned &, bool);
public:
/**
* Constructor
*/
Keyboard(Synced_motherboard &);
void handle_keycode_press(unsigned keycode);
void handle_keycode_release(unsigned keycode);
};
#endif /* _KEYBOARD_H_ */

View File

@ -1 +0,0 @@
../../../../demo/src/server/nitlog/mono.tff

View File

@ -1,87 +0,0 @@
/*
* \brief Network receive handler per MAC address
* \author Markus Partheymueller
* \author Alexander Boettcher
* \date 2012-07-31
*/
/*
* Copyright (C) 2012 Intel Corporation
* Copyright (C) 2013-2017 Genode Labs GmbH
*
* This file is distributed under the terms of the GNU General Public License
* version 2.
*
* The code is partially based on the Vancouver VMM, which is distributed
* under the terms of the GNU General Public License version 2.
*
* Modifications by Intel Corporation are contributed under the terms and
* conditions of the GNU General Public License version 2.
*/
/* local includes */
#include "network.h"
Seoul::Network::Network(Genode::Env &env, Genode::Heap &heap,
Synced_motherboard &mb)
:
_motherboard(mb), _tx_block_alloc(&heap),
_nic(env, &_tx_block_alloc, BUF_SIZE, BUF_SIZE),
_packet_avail(env.ep(), *this, &Network::_handle_packets)
{
_nic.rx_channel()->sigh_packet_avail(_packet_avail);
}
void Seoul::Network::_handle_packets()
{
while (_nic.rx()->packet_avail()) {
Nic::Packet_descriptor rx_packet = _nic.rx()->get_packet();
/* send it to the network bus */
char * rx_content = _nic.rx()->packet_content(rx_packet);
_forward_pkt = rx_content;
MessageNetwork msg((unsigned char *)rx_content, rx_packet.size(), 0);
_motherboard()->bus_network.send(msg);
_forward_pkt = 0;
/* acknowledge received packet */
if (!_nic.rx()->ready_to_ack())
Logging::printf("not ready for acks");
_nic.rx()->acknowledge_packet(rx_packet);
}
}
bool Seoul::Network::transmit(void const * const packet, Genode::size_t len)
{
if (packet == _forward_pkt)
/* don't end in an endless forwarding loop */
return false;
/* check for acknowledgements */
while (_nic.tx()->ack_avail()) {
Nic::Packet_descriptor const ack = _nic.tx()->get_acked_packet();
_nic.tx()->release_packet(ack);
}
/* allocate transmit packet */
Nic::Packet_descriptor tx_packet;
try {
tx_packet = _nic.tx()->alloc_packet(len);
} catch (Nic::Session::Tx::Source::Packet_alloc_failed) {
Logging::printf("error: tx packet alloc failed\n");
return false;
}
/* fill packet with content */
char * const tx_content = _nic.tx()->packet_content(tx_packet);
memcpy(tx_content, packet, len);
_nic.tx()->submit_packet(tx_packet);
return true;
}

View File

@ -1,72 +0,0 @@
/*
* \brief Network receive handler per MAC address
* \author Markus Partheymueller
* \author Alexander Boettcher
* \date 2012-07-31
*/
/*
* Copyright (C) 2012 Intel Corporation
* Copyright (C) 2013-2017 Genode Labs GmbH
*
* This file is distributed under the terms of the GNU General Public License
* version 2.
*
* The code is partially based on the Vancouver VMM, which is distributed
* under the terms of the GNU General Public License version 2.
*
* Modifications by Intel Corporation are contributed under the terms and
* conditions of the GNU General Public License version 2.
*/
#ifndef _NETWORK_H_
#define _NETWORK_H_
/* base includes */
#include <base/heap.h>
/* os includes */
#include <nic_session/connection.h>
#include <nic/packet_allocator.h>
/* local includes */
#include "synced_motherboard.h"
namespace Seoul {
class Network;
}
class Seoul::Network
{
private:
enum {
PACKET_SIZE = Nic::Packet_allocator::DEFAULT_PACKET_SIZE,
BUF_SIZE = Nic::Session::QUEUE_SIZE * PACKET_SIZE,
};
Synced_motherboard &_motherboard;
Nic::Packet_allocator _tx_block_alloc;
Nic::Connection _nic;
Genode::Signal_handler<Network> const _packet_avail;
void const * _forward_pkt = nullptr;
void _handle_packets();
/*
* Noncopyable
*/
Network(Network const &);
Network &operator = (Network const &);
public:
Network(Genode::Env &, Genode::Heap &, Synced_motherboard &);
Nic::Mac_address mac_address() { return _nic.mac_address(); }
bool transmit(void const * const packet, Genode::size_t len);
};
#endif /* _NETWORK_H_ */

View File

@ -1,413 +0,0 @@
/*
* \brief Transform state between Genode VM session interface and Seoul
* \author Alexander Boettcher
* \date 2018-08-27
*/
/*
* Copyright (C) 2018 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 <base/log.h>
#include "state.h"
void Seoul::write_vm_state(CpuState &seoul, unsigned mtr, Genode::Vcpu_state &state)
{
state.discharge(); /* reset */
if (mtr & MTD_GPR_ACDB) {
state.ax.charge(seoul.rax);
state.cx.charge(seoul.rcx);
state.dx.charge(seoul.rdx);
state.bx.charge(seoul.rbx);
mtr &= ~MTD_GPR_ACDB;
}
if (mtr & MTD_GPR_BSD) {
state.di.charge(seoul.rdix);
state.si.charge(seoul.rsix);
state.bp.charge(seoul.rbpx);
mtr &= ~MTD_GPR_BSD;
}
if (mtr & MTD_RIP_LEN) {
state.ip.charge(seoul.ripx);
state.ip_len.charge(seoul.inst_len);
mtr &= ~MTD_RIP_LEN;
}
if (mtr & MTD_RSP) {
state.sp.charge(seoul.rspx);
mtr &= ~MTD_RSP;
}
if (mtr & MTD_RFLAGS) {
state.flags.charge(seoul.rflx);
mtr &= ~MTD_RFLAGS;
}
if (mtr & MTD_DR) {
state.dr7.charge(seoul.dr7);
mtr &= ~MTD_DR;
}
if (mtr & MTD_CR) {
state.cr0.charge(seoul.cr0);
state.cr2.charge(seoul.cr2);
state.cr3.charge(seoul.cr3);
state.cr4.charge(seoul.cr4);
mtr &= ~MTD_CR;
}
typedef Genode::Vcpu_state::Segment Segment;
typedef Genode::Vcpu_state::Range Range;
if (mtr & MTD_CS_SS) {
state.cs.charge(Segment { .sel = seoul.cs.sel,
.ar = seoul.cs.ar,
.limit = seoul.cs.limit,
.base = seoul.cs.base });
state.ss.charge(Segment { .sel = seoul.ss.sel,
.ar = seoul.ss.ar,
.limit = seoul.ss.limit,
.base = seoul.ss.base });
mtr &= ~MTD_CS_SS;
}
if (mtr & MTD_DS_ES) {
state.es.charge(Segment { .sel = seoul.es.sel,
.ar = seoul.es.ar,
.limit = seoul.es.limit,
.base = seoul.es.base });
state.ds.charge(Segment { .sel = seoul.ds.sel,
.ar = seoul.ds.ar,
.limit = seoul.ds.limit,
.base = seoul.ds.base });
mtr &= ~MTD_DS_ES;
}
if (mtr & MTD_FS_GS) {
state.fs.charge(Segment { .sel = seoul.fs.sel,
.ar = seoul.fs.ar,
.limit = seoul.fs.limit,
.base = seoul.fs.base });
state.gs.charge(Segment { .sel = seoul.gs.sel,
.ar = seoul.gs.ar,
.limit = seoul.gs.limit,
.base = seoul.gs.base });
mtr &= ~MTD_FS_GS;
}
if (mtr & MTD_TR) {
state.tr.charge(Segment { .sel = seoul.tr.sel,
.ar = seoul.tr.ar,
.limit = seoul.tr.limit,
.base = seoul.tr.base });
mtr &= ~MTD_TR;
}
if (mtr & MTD_LDTR) {
state.ldtr.charge(Segment { .sel = seoul.ld.sel,
.ar = seoul.ld.ar,
.limit = seoul.ld.limit,
.base = seoul.ld.base });
mtr &= ~MTD_LDTR;
}
if (mtr & MTD_GDTR) {
state.gdtr.charge(Range { .limit = seoul.gd.limit,
.base = seoul.gd.base });
mtr &= ~MTD_GDTR;
}
if (mtr & MTD_IDTR) {
state.idtr.charge(Range{ .limit = seoul.id.limit,
.base = seoul.id.base });
mtr &= ~MTD_IDTR;
}
if (mtr & MTD_SYSENTER) {
state.sysenter_cs.charge(seoul.sysenter_cs);
state.sysenter_sp.charge(seoul.sysenter_esp);
state.sysenter_ip.charge(seoul.sysenter_eip);
mtr &= ~MTD_SYSENTER;
}
if (mtr & MTD_QUAL) {
state.qual_primary.charge(seoul.qual[0]);
state.qual_secondary.charge(seoul.qual[1]);
/* not read by any kernel */
mtr &= ~MTD_QUAL;
}
if (mtr & MTD_CTRL) {
state.ctrl_primary.charge(seoul.ctrl[0]);
state.ctrl_secondary.charge(seoul.ctrl[1]);
mtr &= ~MTD_CTRL;
}
if (mtr & MTD_INJ) {
state.inj_info.charge(seoul.inj_info);
state.inj_error.charge(seoul.inj_error);
mtr &= ~MTD_INJ;
}
if (mtr & MTD_STATE) {
state.intr_state.charge(seoul.intr_state);
state.actv_state.charge(seoul.actv_state);
mtr &= ~MTD_STATE;
}
if (mtr & MTD_TSC) {
state.tsc.charge(seoul.tsc_value);
state.tsc_offset.charge(seoul.tsc_off);
mtr &= ~MTD_TSC;
}
if (mtr)
Genode::error("state transfer incomplete ", Genode::Hex(mtr));
}
unsigned Seoul::read_vm_state(Genode::Vcpu_state &state, CpuState &seoul)
{
unsigned mtr = 0;
if (state.ax.charged() || state.cx.charged() ||
state.dx.charged() || state.bx.charged()) {
if (!state.ax.charged() || !state.cx.charged() ||
!state.dx.charged() || !state.bx.charged())
Genode::warning("missing state ", __LINE__);
mtr |= MTD_GPR_ACDB;
seoul.rax = state.ax.value();
seoul.rcx = state.cx.value();
seoul.rdx = state.dx.value();
seoul.rbx = state.bx.value();
}
if (state.bp.charged() || state.di.charged() || state.si.charged()) {
if (!state.bp.charged() || !state.di.charged() || !state.si.charged())
Genode::warning("missing state ", __LINE__);
mtr |= MTD_GPR_BSD;
seoul.rdix = state.di.value();
seoul.rsix = state.si.value();
seoul.rbpx = state.bp.value();
}
if (state.flags.charged()) {
mtr |= MTD_RFLAGS;
seoul.rflx = state.flags.value();
}
if (state.sp.charged()) {
mtr |= MTD_RSP;
seoul.rspx = state.sp.value();
}
if (state.ip.charged() || state.ip_len.charged()) {
if (!state.ip.charged() || !state.ip_len.charged())
Genode::warning("missing state ", __LINE__);
mtr |= MTD_RIP_LEN;
seoul.ripx = state.ip.value();
seoul.inst_len = state.ip_len.value();
}
if (state.dr7.charged()) {
mtr |= MTD_DR;
seoul.dr7 = state.dr7.value();
}
#if 0
if (state.r8.charged() || state.r9.charged() ||
state.r10.charged() || state.r11.charged() ||
state.r12.charged() || state.r13.charged() ||
state.r14.charged() || state.r15.charged()) {
Genode::warning("r8-r15 not supported");
}
#endif
if (state.cr0.charged() || state.cr2.charged() ||
state.cr3.charged() || state.cr4.charged()) {
mtr |= MTD_CR;
seoul.cr0 = state.cr0.value();
seoul.cr2 = state.cr2.value();
seoul.cr3 = state.cr3.value();
seoul.cr4 = state.cr4.value();
}
if (state.cs.charged() || state.ss.charged()) {
if (!state.cs.charged() || !state.ss.charged())
Genode::warning("missing state ", __LINE__);
mtr |= MTD_CS_SS;
seoul.cs.sel = state.cs.value().sel;
seoul.cs.ar = state.cs.value().ar;
seoul.cs.limit = state.cs.value().limit;
seoul.cs.base = state.cs.value().base;
seoul.ss.sel = state.ss.value().sel;
seoul.ss.ar = state.ss.value().ar;
seoul.ss.limit = state.ss.value().limit;
seoul.ss.base = state.ss.value().base;
}
if (state.es.charged() || state.ds.charged()) {
if (!state.es.charged() || !state.ds.charged())
Genode::warning("missing state ", __LINE__);
mtr |= MTD_DS_ES;
seoul.es.sel = state.es.value().sel;
seoul.es.ar = state.es.value().ar;
seoul.es.limit = state.es.value().limit;
seoul.es.base = state.es.value().base;
seoul.ds.sel = state.ds.value().sel;
seoul.ds.ar = state.ds.value().ar;
seoul.ds.limit = state.ds.value().limit;
seoul.ds.base = state.ds.value().base;
}
if (state.fs.charged() || state.gs.charged()) {
if (!state.fs.charged() || !state.gs.charged())
Genode::warning("missing state ", __LINE__);
mtr |= MTD_FS_GS;
seoul.fs.sel = state.fs.value().sel;
seoul.fs.ar = state.fs.value().ar;
seoul.fs.limit = state.fs.value().limit;
seoul.fs.base = state.fs.value().base;
seoul.gs.sel = state.gs.value().sel;
seoul.gs.ar = state.gs.value().ar;
seoul.gs.limit = state.gs.value().limit;
seoul.gs.base = state.gs.value().base;
}
if (state.tr.charged()) {
mtr |= MTD_TR;
seoul.tr.sel = state.tr.value().sel;
seoul.tr.ar = state.tr.value().ar;
seoul.tr.limit = state.tr.value().limit;
seoul.tr.base = state.tr.value().base;
}
if (state.ldtr.charged()) {
mtr |= MTD_LDTR;
seoul.ld.sel = state.ldtr.value().sel;
seoul.ld.ar = state.ldtr.value().ar;
seoul.ld.limit = state.ldtr.value().limit;
seoul.ld.base = state.ldtr.value().base;
}
if (state.gdtr.charged()) {
mtr |= MTD_GDTR;
seoul.gd.limit = state.gdtr.value().limit;
seoul.gd.base = state.gdtr.value().base;
}
if (state.idtr.charged()) {
mtr |= MTD_IDTR;
seoul.id.limit = state.idtr.value().limit;
seoul.id.base = state.idtr.value().base;
}
if (state.sysenter_cs.charged() || state.sysenter_sp.charged() ||
state.sysenter_ip.charged()) {
if (!state.sysenter_cs.charged() || !state.sysenter_sp.charged() ||
!state.sysenter_ip.charged())
Genode::warning("missing state ", __LINE__);
mtr |= MTD_SYSENTER;
seoul.sysenter_cs = state.sysenter_cs.value();
seoul.sysenter_esp = state.sysenter_sp.value();
seoul.sysenter_eip = state.sysenter_ip.value();
}
if (state.ctrl_primary.charged() || state.ctrl_secondary.charged()) {
if (!state.ctrl_primary.charged() || !state.ctrl_secondary.charged())
Genode::warning("missing state ", __LINE__);
mtr |= MTD_CTRL;
seoul.ctrl[0] = state.ctrl_primary.value();
seoul.ctrl[1] = state.ctrl_secondary.value();
}
if (state.inj_info.charged() || state.inj_error.charged()) {
if (!state.inj_info.charged() || !state.inj_error.charged())
Genode::warning("missing state ", __LINE__);
mtr |= MTD_INJ;
seoul.inj_info = state.inj_info.value();
seoul.inj_error = state.inj_error.value();
}
if (state.intr_state.charged() || state.actv_state.charged()) {
if (!state.intr_state.charged() || !state.actv_state.charged())
Genode::warning("missing state ", __LINE__);
mtr |= MTD_STATE;
seoul.intr_state = state.intr_state.value();
seoul.actv_state = state.actv_state.value();
}
if (state.tsc.charged() || state.tsc_offset.charged()) {
if (!state.tsc.charged() || !state.tsc_offset.charged())
Genode::warning("missing state ", __LINE__);
mtr |= MTD_TSC;
seoul.tsc_value = state.tsc.value();
seoul.tsc_off = state.tsc_offset.value();
}
if (state.qual_primary.charged() || state.qual_secondary.charged()) {
if (!state.qual_primary.charged() || !state.qual_secondary.charged())
Genode::warning("missing state ", __LINE__);
mtr |= MTD_QUAL;
seoul.qual[0] = state.qual_primary.value();
seoul.qual[1] = state.qual_secondary.value();
}
#if 0
if (state.efer.charged()) {
Genode::warning("efer not supported by Seoul");
}
if (state.pdpte_0.charged() || state.pdpte_1.charged() ||
state.pdpte_2.charged() || state.pdpte_3.charged()) {
Genode::warning("pdpte not supported by Seoul");
}
if (state.star.charged() || state.lstar.charged() || state.cstar.charged() ||
state.fmask.charged() || state.kernel_gs_base.charged()) {
Genode::warning("star, lstar, cstar, fmask, kernel_gs not supported by Seoul");
}
if (state.tpr.charged() || state.tpr_threshold.charged()) {
Genode::warning("tpr not supported by Seoul");
}
#endif
return mtr;
}

View File

@ -1,26 +0,0 @@
/*
* \brief Transform state between Genode VM session interface and Seoul
* \author Alexander Boettcher
* \date 2018-08-27
*/
/*
* Copyright (C) 2018 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 _STATE_H_
#define _STATE_H_
#include <cpu/vcpu_state.h>
#include <nul/vcpu.h>
namespace Seoul {
void write_vm_state(CpuState &, unsigned mtr, Genode::Vcpu_state &);
unsigned read_vm_state(Genode::Vcpu_state &, CpuState &);
}
#endif /* _STATE_H_ */

View File

@ -1,22 +0,0 @@
/*
* \brief Synchronized access to Vancouver motherboard
* \author Norman Feske
* \date 2013-05-16
*/
/*
* Copyright (C) 2013-2017 Genode Labs GmbH
*
* This file is part of the Genode OS framework, which is distributed
* under the terms of the GNU General Public License version 2.
*/
#ifndef _SYNCED_MOTHERBOARD_H_
#define _SYNCED_MOTHERBOARD_H_
#include <nul/motherboard.h>
#include <base/synced_interface.h>
typedef Genode::Synced_interface<Motherboard> Synced_motherboard;
#endif /* _SYNCED_MOTHERBOARD_H_ */

View File

@ -1,37 +0,0 @@
TARGET = seoul
REQUIRES = x86
SEOUL_CONTRIB_DIR = $(call select_from_ports,seoul)/src/app/seoul
SEOUL_GENODE_DIR = $(SEOUL_CONTRIB_DIR)/genode
LIBS += base blit seoul_libc_support
SRC_CC = component.cc user_env.cc device_model_registry.cc state.cc
SRC_CC += console.cc keyboard.cc network.cc disk.cc
SRC_BIN = mono.tff
MODEL_SRC_CC += $(notdir $(wildcard $(SEOUL_CONTRIB_DIR)/model/*.cc))
EXECUTOR_SRC_CC += $(notdir $(wildcard $(SEOUL_CONTRIB_DIR)/executor/*.cc))
ifneq ($(filter x86_64, $(SPECS)),)
CC_CXX_OPT += -mcmodel=large
endif
SRC_CC += $(filter-out $(FILTER_OUT),$(addprefix model/,$(MODEL_SRC_CC)))
SRC_CC += $(filter-out $(FILTER_OUT),$(addprefix executor/,$(EXECUTOR_SRC_CC)))
INC_DIR += $(SEOUL_CONTRIB_DIR)/include
INC_DIR += $(SEOUL_GENODE_DIR)/include
INC_DIR += $(REP_DIR)/src/app/seoul/include
include $(call select_from_repositories,lib/mk/libc-common.inc)
CC_WARN += -Wno-unused
CC_CXX_OPT += -march=core2
CC_OPT_model/intel82576vf := -mssse3
CC_OPT_PIC :=
vpath %.cc $(SEOUL_CONTRIB_DIR)
vpath %.cc $(REP_DIR)/src/app/seoul
vpath %.tff $(REP_DIR)/src/app/seoul
CC_CXX_WARN_STRICT_CONVERSION =

View File

@ -1,81 +0,0 @@
/*
* \brief Handle timeouts which are late due to poor signal performance or
* due to scheduling overload
* \author Alexander Boettcher
* \date 2019-05-07
*/
/*
* Copyright (C) 2019 Genode Labs GmbH
*
* This file is distributed under the terms of the GNU General Public License
* version 2.
*
* The code is partially based on the Seoul/Vancouver VMM, which is distributed
* under the terms of the GNU General Public License version 2.
*
* Modifications by Intel Corporation are contributed under the terms and
* conditions of the GNU General Public License version 2.
*/
#ifndef _TIMEOUT_LATE_H_
#define _TIMEOUT_LATE_H_
class Late_timeout
{
public:
struct Remote
{
timevalue _now { 0 };
timevalue _timeout { 0 };
unsigned _timer_nr { ~0U };
bool valid() const { return _timer_nr != ~0U; };
};
private:
Genode::Mutex _mutex { };
Remote _remote { };
public:
Late_timeout() { }
void timeout(Clock &clock, MessageTimer const &msg)
{
Genode::Mutex::Guard guard(_mutex);
Genode::uint64_t const now = clock.time();
if (!_remote._now || now < _remote._now) {
_remote._now = now;
_remote._timeout = msg.abstime;
_remote._timer_nr = msg.nr;
}
}
Remote reset()
{
Genode::Mutex::Guard guard(_mutex);
Remote last = _remote;
_remote._now = 0;
_remote._timeout = 0;
_remote._timer_nr = ~0U;
return last;
}
bool apply(Remote const &remote,
unsigned const timer_nr,
Genode::uint64_t now)
{
return (timer_nr == remote._timer_nr) &&
((remote._timeout - remote._now) < (now - _remote._now));
}
};
#endif /* _TIMEOUT_LATE_H_ */

View File

@ -1,177 +0,0 @@
/*
* \brief Environment expected by the Seoul code
* \author Norman Feske
* \date 2011-11-18
*/
/*
* Copyright (C) 2011-2019 Genode Labs GmbH
*
* This file is part of the Genode OS framework, which is distributed
* under the terms of the GNU General Public License version 2.
*/
/* Genode includes */
#include <log_session/log_session.h>
#include <base/snprintf.h>
#include <base/env.h>
#include <base/heap.h>
#include <base/sleep.h>
#include <base/thread.h>
/* Seoul userland includes */
#include <service/logging.h>
#include <service/memory.h>
enum { verbose_memory_leak = false };
static
void vprintf(const char *format, va_list &args)
{
using namespace Genode;
static char buf[Log_session::MAX_STRING_LEN-4];
String_console sc(buf, sizeof(buf));
sc.vprintf(format, args);
int n = sc.len();
if (0 < n && buf[n-1] == '\n') n--;
log("VMM: ", Cstring(buf, n));
}
void Logging::printf(const char *format, ...)
{
va_list list;
va_start(list, format);
::vprintf(format, list);
va_end(list);
}
void Logging::vprintf(const char *format, va_list &ap)
{
::vprintf(format, ap);
}
void Logging::panic(const char *format, ...)
{
va_list list;
va_start(list, format);
Genode::error("VMM PANIC!");
::vprintf(format, list);
va_end(list);
for (;;)
Genode::sleep_forever();
}
static Genode::Allocator * heap = nullptr;
void heap_init_env(Genode::Heap *h)
{
heap = h;
}
static void *heap_alloc(size_t size)
{
void *res = heap->alloc(size);
if (res)
return res;
Genode::error("out of memory");
Genode::sleep_forever();
}
static void heap_free(void * ptr)
{
if (heap->need_size_for_free()) {
Genode::warning("leaking memory");
return;
}
heap->free(ptr, 0);
}
void *operator new[](size_t size)
{
void * addr = heap_alloc(size);
if (addr)
Genode::memset(addr, 0, size);
return addr;
}
void *operator new[](size_t size, Aligned const alignment)
{
size_t align = alignment.alignment;
void *res = heap_alloc(size + align);
if (res)
Genode::memset(res, 0, size + align);
void *aligned_res = (void *)(((Genode::addr_t)res & ~(align - 1)) + align);
return aligned_res;
}
void *operator new (size_t size)
{
void * addr = heap_alloc(size);
if (addr)
Genode::memset(addr, 0, size);
return addr;
}
void operator delete[](void *ptr)
{
if (verbose_memory_leak)
Genode::warning("delete[] not implemented ", ptr);
}
void operator delete[](void *ptr, long unsigned int)
{
if (verbose_memory_leak)
Genode::warning("delete[] not implemented ", ptr);
}
void operator delete (void * ptr)
{
heap_free(ptr);
}
void operator delete(void *ptr, long unsigned int)
{
heap_free(ptr);
}
void do_exit(char const *msg)
{
Genode::log("*** ", msg);
Genode::sleep_forever();
}
char __param_table_start;
char __param_table_end;
/* parameter support */
#include <service/params.h>
Genode::Fifo<Parameter> &Parameter::all_parameters()
{
static Genode::Fifo<Parameter> _all_parameters;
return _all_parameters;
}
// EOF