mirror of
https://github.com/genodelabs/genode.git
synced 2025-02-20 09:46:20 +00:00
parent
baea48fbec
commit
35489aa708
@ -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_ */
|
@ -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_ */
|
@ -1 +0,0 @@
|
||||
include $(call select_from_repositories,lib/import/import-libc.mk)
|
@ -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 =
|
@ -1 +0,0 @@
|
||||
800924f3dc293d6c21d4e15fac0605ad4d7269b9
|
@ -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
|
@ -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 $@)
|
@ -1 +0,0 @@
|
||||
2022-01-18 24cfd5b82ca7867a146b4b53bbdd4d89f194b0b2
|
@ -1,12 +0,0 @@
|
||||
base
|
||||
libc
|
||||
os
|
||||
blit
|
||||
nitpicker_gfx
|
||||
gui_session
|
||||
framebuffer_session
|
||||
input_session
|
||||
timer_session
|
||||
block_session
|
||||
nic_session
|
||||
rtc_session
|
@ -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
|
||||
}
|
@ -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
|
@ -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
|
@ -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
|
@ -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"
|
@ -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
|
@ -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
|
@ -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
|
@ -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.
|
@ -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
@ -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);
|
||||
}
|
@ -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_ */
|
@ -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")
|
@ -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_ */
|
@ -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;
|
||||
}
|
@ -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_ */
|
@ -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_ */
|
@ -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);
|
@ -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)
|
@ -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);
|
||||
}
|
@ -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_ */
|
@ -1 +0,0 @@
|
||||
../../../../demo/src/server/nitlog/mono.tff
|
@ -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;
|
||||
}
|
@ -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_ */
|
@ -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;
|
||||
}
|
@ -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_ */
|
@ -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_ */
|
@ -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 =
|
@ -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_ */
|
@ -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
|
Loading…
x
Reference in New Issue
Block a user