mirror of
https://github.com/genodelabs/genode.git
synced 2024-12-18 21:27:56 +00:00
Use NOVA microkernel from github, add 64bit
Use git to get recent kernels from github. Adjust NOVA patch to compile with recent github version. Patch and use makefile of NOVA microkernel to avoid duplicated (and outdated) makefile in Genode Furthermore, this patch adds support for using NOVA on x86_64. The generic part of the syscall bindings has been moved to 'base-nova/include/nova/syscall-generic.h'. The 32/64-bit specific parts are located at 'base-nova/include/32bit/nova/syscalls.h' and 'base-nova/include/64bit/nova/syscalls.h' respectively. On x86_64, the run environment boots qemu using the Pulsar boot loader because GRUB legacy does not support booting 64bit ELF executables. In addition to the NOVA-specific changes in base-nova, this patch rectifies compile-time warnings or build errors in the 'ports' and 'libports' repositories that are related to NOVA x86_64 (i.e., Vancouver builds for 32bit only and needed an adaptation to NOVAs changed bindings) Fixes #233, fixes #234
This commit is contained in:
parent
200deec403
commit
ae6257dce1
@ -1,55 +1,50 @@
|
||||
#
|
||||
# \brief Download, and unpack the NOVA hypervisor.
|
||||
# \author Stefan Kalkowski
|
||||
# \date 2011-07-20
|
||||
# \author Alexander Boettcher
|
||||
# \date 2012-06-04
|
||||
#
|
||||
|
||||
VERBOSE ?= @
|
||||
ECHO = @echo
|
||||
DOWNLOAD_DIR = download
|
||||
CONTRIB_DIR = contrib
|
||||
NOVA_ARCHIVE = nova-hypervisor-0.4.tar.bz2
|
||||
NOVA_URI = http://os.inf.tu-dresden.de/~us15/nova/$(NOVA_ARCHIVE)
|
||||
ECHO = @echo
|
||||
GIT_URL = git://github.com/IntelLabs/NOVA.git
|
||||
GIT_REV = f6bad89f2df036c9ee75699c2138586e28c711a0
|
||||
CONTRIB_DIR = contrib
|
||||
PATCHES = $(shell find patches -name *.patch)
|
||||
|
||||
#
|
||||
# Utility to check if a tool is installed
|
||||
#
|
||||
check_tool = $(if $(shell which $(1)),,$(error Need to have '$(1)' installed.))
|
||||
|
||||
$(call check_tool,wget)
|
||||
$(call check_tool,git)
|
||||
$(call check_tool,patch)
|
||||
|
||||
#
|
||||
# Print help information by default
|
||||
#
|
||||
help:
|
||||
help::
|
||||
|
||||
prepare: $(CONTRIB_DIR)
|
||||
|
||||
help::
|
||||
$(ECHO)
|
||||
$(ECHO) "Prepare the NOVA base repository"
|
||||
$(ECHO)
|
||||
$(ECHO) "--- available commands ---"
|
||||
$(ECHO) "prepare - download and extract the NOVA source code"
|
||||
$(ECHO) "clean - clean everything except downloaded archives"
|
||||
$(ECHO) "cleanall - clean everything including downloaded archives"
|
||||
$(ECHO) "prepare - checkout upstream source codes"
|
||||
$(ECHO) "clean - remove upstream source codes"
|
||||
$(ECHO)
|
||||
|
||||
$(DOWNLOAD_DIR)/$(NOVA_ARCHIVE):
|
||||
$(ECHO) "downloading source code to '$(DOWNLOAD_DIR)/'"
|
||||
$(VERBOSE)mkdir -p $(DOWNLOAD_DIR)
|
||||
$(VERBOSE)wget -c $(NOVA_URI) -O $@
|
||||
$(CONTRIB_DIR)/.git:
|
||||
$(VERBOSE)git clone $(GIT_URL) $(CONTRIB_DIR)
|
||||
|
||||
$(CONTRIB_DIR): clean
|
||||
$(CONTRIB_DIR): $(CONTRIB_DIR)/.git
|
||||
$(VERBOSE)cd $(CONTRIB_DIR); git reset --hard $(GIT_REV)
|
||||
$(ECHO) "applying patches to '$(CONTRIB_DIR)/'"
|
||||
$(VERBOSE)for i in $(PATCHES); do patch -d $@ -p1 < $$i; done
|
||||
|
||||
$(CONTRIB_DIR): $(DOWNLOAD_DIR)/$(NOVA_ARCHIVE)
|
||||
$(ECHO) "unpacking source code to '$(CONTRIB_DIR)/'"
|
||||
$(VERBOSE)tar xjf $<
|
||||
$(VERBOSE)mv hypervisor $@
|
||||
$(VERBOSE)patch -d $@ -p1 < patches/utcb.patch
|
||||
$(VERBOSE)touch $@
|
||||
.PHONY: $(CONTRIB_DIR)
|
||||
|
||||
prepare: $(CONTRIB_DIR)
|
||||
|
||||
clean:
|
||||
clean::
|
||||
$(VERBOSE)rm -rf $(CONTRIB_DIR)
|
||||
|
||||
cleanall: clean
|
||||
$(VERBOSE)rm -rf $(DOWNLOAD_DIR)
|
||||
|
269
base-nova/include/32bit/nova/syscalls.h
Normal file
269
base-nova/include/32bit/nova/syscalls.h
Normal file
@ -0,0 +1,269 @@
|
||||
/*
|
||||
* \brief Syscall bindings for the NOVA microhypervisor
|
||||
* \author Norman Feske
|
||||
* \author Sebastian Sumpf
|
||||
* \date 2009-12-27
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (c) 2009 Genode Labs
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person
|
||||
* obtaining a copy of this software and associated documentation
|
||||
* files (the "Software"), to deal in the Software without
|
||||
* restriction, including without limitation the rights to use,
|
||||
* copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the
|
||||
* Software is furnished to do so, subject to the following
|
||||
* conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be
|
||||
* included in all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
|
||||
* OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
|
||||
* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
||||
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
|
||||
* OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#ifndef _PLATFORM__NOVA_SYSCALLS_H_
|
||||
#define _PLATFORM__NOVA_SYSCALLS_H_
|
||||
|
||||
#include <nova/stdint.h>
|
||||
#include <nova/syscall-generic.h>
|
||||
|
||||
#define ALWAYS_INLINE __attribute__((always_inline))
|
||||
|
||||
namespace Nova {
|
||||
|
||||
ALWAYS_INLINE
|
||||
inline unsigned eax(Syscall s, uint8_t flags, unsigned sel)
|
||||
{
|
||||
return sel << 8 | (flags & 0xf) << 4 | s;
|
||||
}
|
||||
|
||||
|
||||
ALWAYS_INLINE
|
||||
inline uint8_t syscall_0(Syscall s, uint8_t flags, unsigned sel = 0)
|
||||
{
|
||||
mword_t status = eax(s, flags, sel);
|
||||
|
||||
asm volatile (" mov %%esp, %%ecx;"
|
||||
" call 0f;"
|
||||
"0:"
|
||||
" addl $(1f-0b), (%%esp);"
|
||||
" mov (%%esp), %%edx;"
|
||||
" sysenter;"
|
||||
"1:"
|
||||
: "+a" (status)
|
||||
:
|
||||
: "ecx", "edx", "memory");
|
||||
return status;
|
||||
}
|
||||
|
||||
|
||||
ALWAYS_INLINE
|
||||
inline uint8_t syscall_1(Syscall s, uint8_t flags, mword_t p1)
|
||||
{
|
||||
mword_t status = eax(s, flags, 0);
|
||||
|
||||
asm volatile (" mov %%esp, %%ecx;"
|
||||
" call 0f;"
|
||||
"0:"
|
||||
" addl $(1f-0b), (%%esp);"
|
||||
" mov (%%esp), %%edx;"
|
||||
" sysenter;"
|
||||
"1:"
|
||||
: "+a" (status)
|
||||
: "D" (p1)
|
||||
: "ecx", "edx");
|
||||
return status;
|
||||
}
|
||||
|
||||
|
||||
ALWAYS_INLINE
|
||||
inline uint8_t syscall_2(Syscall s, uint8_t flags, unsigned sel, mword_t p1, mword_t p2)
|
||||
{
|
||||
mword_t status = eax(s, flags, sel);
|
||||
|
||||
asm volatile (" mov %%esp, %%ecx;"
|
||||
" call 0f;"
|
||||
"0:"
|
||||
" addl $(1f-0b), (%%esp);"
|
||||
" mov (%%esp), %%edx;"
|
||||
" sysenter;"
|
||||
"1:"
|
||||
: "+a" (status)
|
||||
: "D" (p1), "S" (p2)
|
||||
: "ecx", "edx");
|
||||
return status;
|
||||
}
|
||||
|
||||
|
||||
ALWAYS_INLINE
|
||||
inline uint8_t syscall_3(Syscall s, uint8_t flags, unsigned sel,
|
||||
mword_t p1, mword_t p2, mword_t p3)
|
||||
{
|
||||
mword_t status = eax(s, flags, sel);
|
||||
|
||||
asm volatile (" push %%ebx;"
|
||||
" mov %%edx, %%ebx;"
|
||||
" mov %%esp, %%ecx;"
|
||||
" call 0f;"
|
||||
"0:"
|
||||
" addl $(1f-0b), (%%esp);"
|
||||
" mov (%%esp), %%edx;"
|
||||
" sysenter;"
|
||||
"1:"
|
||||
" pop %%ebx;"
|
||||
: "+a" (status)
|
||||
: "D" (p1), "S" (p2), "d" (p3)
|
||||
: "ecx");
|
||||
return status;
|
||||
}
|
||||
|
||||
|
||||
ALWAYS_INLINE
|
||||
inline uint8_t syscall_4(Syscall s, uint8_t flags, unsigned sel,
|
||||
mword_t p1, mword_t p2, mword_t p3, mword_t p4)
|
||||
{
|
||||
mword_t status = eax(s, flags, sel);
|
||||
|
||||
asm volatile (" push %%ebp;"
|
||||
" push %%ebx;"
|
||||
|
||||
" mov %%ecx, %%ebx;"
|
||||
" mov %%esp, %%ecx;"
|
||||
" mov %%edx, %%ebp;"
|
||||
|
||||
" call 0f;"
|
||||
"0:"
|
||||
" addl $(1f-0b), (%%esp);"
|
||||
" mov (%%esp), %%edx;"
|
||||
"sysenter;"
|
||||
"1:"
|
||||
|
||||
" pop %%ebx;"
|
||||
" pop %%ebp;"
|
||||
: "+a" (status)
|
||||
: "D" (p1), "S" (p2), "c" (p3), "d" (p4)
|
||||
: "memory");
|
||||
return status;
|
||||
}
|
||||
|
||||
|
||||
ALWAYS_INLINE
|
||||
inline uint8_t call(unsigned pt)
|
||||
{
|
||||
return syscall_0(NOVA_CALL, 0, pt);
|
||||
}
|
||||
|
||||
|
||||
ALWAYS_INLINE
|
||||
inline void reply(void *next_sp)
|
||||
{
|
||||
asm volatile ("sysenter;"
|
||||
:
|
||||
: "a" (NOVA_REPLY), "c" (next_sp)
|
||||
: "memory");
|
||||
}
|
||||
|
||||
|
||||
ALWAYS_INLINE
|
||||
inline uint8_t create_pd(unsigned pd0, unsigned pd, Crd crd)
|
||||
{
|
||||
return syscall_2(NOVA_CREATE_PD, 0, pd0, pd, crd.value());
|
||||
}
|
||||
|
||||
|
||||
ALWAYS_INLINE
|
||||
inline uint8_t create_ec(unsigned ec, unsigned pd,
|
||||
mword_t cpu, mword_t utcb,
|
||||
mword_t esp, mword_t evt,
|
||||
bool global = 0)
|
||||
{
|
||||
return syscall_4(NOVA_CREATE_EC, global, ec, pd,
|
||||
(cpu & 0xfff) | (utcb & ~0xfff),
|
||||
esp, evt);
|
||||
}
|
||||
|
||||
|
||||
ALWAYS_INLINE
|
||||
inline uint8_t ec_ctrl(unsigned ec)
|
||||
{
|
||||
return syscall_1(NOVA_EC_CTRL, 0, ec);
|
||||
}
|
||||
|
||||
ALWAYS_INLINE
|
||||
inline uint8_t create_sc(unsigned sc, unsigned pd, unsigned ec, Qpd qpd)
|
||||
{
|
||||
return syscall_3(NOVA_CREATE_SC, 0, sc, pd, ec, qpd.value());
|
||||
}
|
||||
|
||||
|
||||
ALWAYS_INLINE
|
||||
inline uint8_t create_pt(unsigned pt, unsigned pd, unsigned ec, Mtd mtd, mword_t eip)
|
||||
{
|
||||
return syscall_4(NOVA_CREATE_PT, 0, pt, pd, ec, mtd.value(), eip);
|
||||
}
|
||||
|
||||
|
||||
ALWAYS_INLINE
|
||||
inline uint8_t create_sm(unsigned sm, unsigned pd, mword_t cnt)
|
||||
{
|
||||
return syscall_2(NOVA_CREATE_SM, 0, sm, pd, cnt);
|
||||
}
|
||||
|
||||
|
||||
ALWAYS_INLINE
|
||||
inline uint8_t revoke(Crd crd, bool self = true)
|
||||
{
|
||||
return syscall_1(NOVA_REVOKE, self, crd.value());
|
||||
}
|
||||
|
||||
|
||||
ALWAYS_INLINE
|
||||
inline uint8_t lookup(Crd &crd)
|
||||
{
|
||||
mword_t status = eax(NOVA_LOOKUP, 0, 0);
|
||||
mword_t raw = crd.value();
|
||||
|
||||
asm volatile (" mov %%esp, %%ecx;"
|
||||
" call 0f;"
|
||||
"0:"
|
||||
" addl $(1f-0b), (%%esp);"
|
||||
" mov (%%esp), %%edx;"
|
||||
" sysenter;"
|
||||
"1:"
|
||||
: "+a" (status), "+D" (raw)
|
||||
:
|
||||
: "ecx", "edx", "memory");
|
||||
|
||||
crd = Crd(raw);
|
||||
return status;
|
||||
}
|
||||
|
||||
/**
|
||||
* Semaphore operations
|
||||
*/
|
||||
enum Sem_op { SEMAPHORE_UP = 0, SEMAPHORE_DOWN = 1 };
|
||||
|
||||
|
||||
ALWAYS_INLINE
|
||||
inline uint8_t sm_ctrl(unsigned sm, Sem_op op)
|
||||
{
|
||||
return syscall_0(NOVA_SM_CTRL, op, sm);
|
||||
}
|
||||
|
||||
|
||||
ALWAYS_INLINE
|
||||
inline uint8_t assign_gsi(unsigned sm, mword_t dev, mword_t cpu)
|
||||
{
|
||||
return syscall_2(NOVA_ASSIGN_GSI, 0, sm, dev, cpu);
|
||||
}
|
||||
}
|
||||
#endif /* _PLATFORM__NOVA_SYSCALLS_H_ */
|
263
base-nova/include/64bit/nova/syscalls.h
Normal file
263
base-nova/include/64bit/nova/syscalls.h
Normal file
@ -0,0 +1,263 @@
|
||||
/*
|
||||
* \brief Syscall bindings for the NOVA microhypervisor x86_64
|
||||
* \author Norman Feske
|
||||
* \author Sebastian Sumpf
|
||||
* \author Alexander Boettcher
|
||||
* \date 2012-06-06
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (c) 2012 Genode Labs
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person
|
||||
* obtaining a copy of this software and associated documentation
|
||||
* files (the "Software"), to deal in the Software without
|
||||
* restriction, including without limitation the rights to use,
|
||||
* copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the
|
||||
* Software is furnished to do so, subject to the following
|
||||
* conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be
|
||||
* included in all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
|
||||
* OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
|
||||
* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
||||
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
|
||||
* OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#ifndef _PLATFORM__NOVA_SYSCALLS_H_
|
||||
#define _PLATFORM__NOVA_SYSCALLS_H_
|
||||
|
||||
#include <nova/stdint.h>
|
||||
#include <nova/syscall-generic.h>
|
||||
|
||||
#define ALWAYS_INLINE __attribute__((always_inline))
|
||||
|
||||
namespace Nova {
|
||||
|
||||
ALWAYS_INLINE
|
||||
inline mword_t rdi(Syscall s, uint8_t flags, mword_t sel)
|
||||
{
|
||||
return sel << 8 | (flags & 0xf) << 4 | s;
|
||||
}
|
||||
|
||||
|
||||
ALWAYS_INLINE
|
||||
inline uint8_t syscall_0(Syscall s, uint8_t flags, mword_t sel = 0)
|
||||
{
|
||||
mword_t status = rdi(s, flags, sel);
|
||||
|
||||
asm volatile ("syscall"
|
||||
: "+D" (status)
|
||||
:
|
||||
: "rcx", "r11", "memory");
|
||||
return status;
|
||||
}
|
||||
|
||||
|
||||
ALWAYS_INLINE
|
||||
inline uint8_t syscall_1(Syscall s, uint8_t flags, mword_t p1, mword_t * p2 = 0)
|
||||
{
|
||||
mword_t status = rdi(s, flags, 0);
|
||||
|
||||
asm volatile ("syscall"
|
||||
: "+D" (status), "+S" (p1)
|
||||
:
|
||||
: "rcx", "r11", "memory");
|
||||
if (p2) *p2 = p1;
|
||||
return status;
|
||||
}
|
||||
|
||||
|
||||
ALWAYS_INLINE
|
||||
inline uint8_t syscall_2(Syscall s, uint8_t flags, mword_t sel, mword_t p1, mword_t p2)
|
||||
{
|
||||
mword_t status = rdi(s, flags, sel);
|
||||
|
||||
asm volatile ("syscall"
|
||||
: "+D" (status)
|
||||
: "S" (p1), "d" (p2)
|
||||
: "rcx", "r11", "memory");
|
||||
return status;
|
||||
}
|
||||
|
||||
|
||||
ALWAYS_INLINE
|
||||
inline uint8_t syscall_3(Syscall s, uint8_t flags, unsigned sel,
|
||||
mword_t p1, mword_t p2, mword_t p3)
|
||||
{
|
||||
mword_t status = rdi(s, flags, sel);
|
||||
|
||||
asm volatile ("syscall"
|
||||
: "+D" (status)
|
||||
: "S" (p1), "d" (p2), "a" (p3)
|
||||
: "rcx", "r11", "memory");
|
||||
return status;
|
||||
}
|
||||
|
||||
|
||||
ALWAYS_INLINE
|
||||
inline uint8_t syscall_4(Syscall s, uint8_t flags, mword_t sel,
|
||||
mword_t p1, mword_t p2, mword_t p3, mword_t p4)
|
||||
{
|
||||
mword_t status = rdi(s, flags, sel);
|
||||
register mword_t r8 asm ("r8") = p4;
|
||||
|
||||
asm volatile ("syscall;"
|
||||
: "+D" (status)
|
||||
: "S" (p1), "d" (p2), "a" (p3), "r" (r8)
|
||||
: "rcx", "r11", "memory");
|
||||
return status;
|
||||
}
|
||||
|
||||
|
||||
ALWAYS_INLINE
|
||||
inline uint8_t syscall_5(Syscall s, uint8_t flags, mword_t sel,
|
||||
mword_t p1, mword_t p2, mword_t &p3, mword_t &p4)
|
||||
{
|
||||
mword_t status = rdi(s, flags, sel);
|
||||
|
||||
asm volatile ("syscall"
|
||||
: "+D" (status), "+S"(p3), "+d"(p4)
|
||||
:
|
||||
: "rcx", "r11", "memory");
|
||||
return status;
|
||||
}
|
||||
|
||||
|
||||
ALWAYS_INLINE
|
||||
inline uint8_t call(mword_t pt)
|
||||
{
|
||||
return syscall_0(NOVA_CALL, 0, pt);
|
||||
}
|
||||
|
||||
|
||||
ALWAYS_INLINE
|
||||
inline void reply(void *next_sp)
|
||||
{
|
||||
asm volatile ("mov %1, %%rsp;"
|
||||
"syscall;"
|
||||
:
|
||||
: "D" (NOVA_REPLY), "ir" (next_sp)
|
||||
: "memory");
|
||||
}
|
||||
|
||||
|
||||
ALWAYS_INLINE
|
||||
inline uint8_t create_pd(mword_t pd0, mword_t pd, Crd crd)
|
||||
{
|
||||
return syscall_2(NOVA_CREATE_PD, 0, pd0, pd, crd.value());
|
||||
}
|
||||
|
||||
|
||||
ALWAYS_INLINE
|
||||
inline uint8_t create_ec(mword_t ec, mword_t pd,
|
||||
mword_t cpu, mword_t utcb,
|
||||
mword_t esp, mword_t evt,
|
||||
bool global = 0)
|
||||
{
|
||||
return syscall_4(NOVA_CREATE_EC, global, ec, pd,
|
||||
(cpu & 0xfff) | (utcb & ~0xfff),
|
||||
esp, evt);
|
||||
}
|
||||
|
||||
|
||||
ALWAYS_INLINE
|
||||
inline uint8_t ec_ctrl(mword_t ec)
|
||||
{
|
||||
return syscall_0(NOVA_EC_CTRL, 0, ec);
|
||||
}
|
||||
|
||||
ALWAYS_INLINE
|
||||
inline uint8_t create_sc(mword_t sc, mword_t pd, mword_t ec, Qpd qpd)
|
||||
{
|
||||
return syscall_3(NOVA_CREATE_SC, 0, sc, pd, ec, qpd.value());
|
||||
}
|
||||
|
||||
|
||||
ALWAYS_INLINE
|
||||
inline uint8_t create_pt(mword_t pt, mword_t pd, mword_t ec, Mtd mtd, mword_t rip)
|
||||
{
|
||||
return syscall_4(NOVA_CREATE_PT, 0, pt, pd, ec, mtd.value(), rip);
|
||||
}
|
||||
|
||||
|
||||
ALWAYS_INLINE
|
||||
inline uint8_t create_sm(mword_t sm, mword_t pd, mword_t cnt)
|
||||
{
|
||||
return syscall_2(NOVA_CREATE_SM, 0, sm, pd, cnt);
|
||||
}
|
||||
|
||||
|
||||
ALWAYS_INLINE
|
||||
inline uint8_t revoke(Crd crd, bool self = true)
|
||||
{
|
||||
return syscall_1(NOVA_REVOKE, self, crd.value());
|
||||
}
|
||||
|
||||
|
||||
ALWAYS_INLINE
|
||||
inline uint8_t lookup(Crd &crd)
|
||||
{
|
||||
mword_t crd_r;
|
||||
uint8_t res=syscall_1(NOVA_LOOKUP, 0, crd.value(), &crd_r);
|
||||
crd = Crd(crd_r);
|
||||
return res;
|
||||
}
|
||||
|
||||
/**
|
||||
* Semaphore operations
|
||||
*/
|
||||
enum Sem_op { SEMAPHORE_UP = 0, SEMAPHORE_DOWN = 1 };
|
||||
|
||||
|
||||
ALWAYS_INLINE
|
||||
inline uint8_t sm_ctrl(mword_t sm, Sem_op op)
|
||||
{
|
||||
return syscall_0(NOVA_SM_CTRL, op, sm);
|
||||
}
|
||||
|
||||
|
||||
ALWAYS_INLINE
|
||||
inline uint8_t sc_ctrl(mword_t sm, Sem_op op, mword_t &time)
|
||||
{
|
||||
mword_t status = rdi(NOVA_SC_CTRL, op, sm);
|
||||
mword_t time_h;
|
||||
|
||||
uint8_t res = syscall_5(NOVA_SC_CTRL, op, sm, 0, 0, time_h, time);
|
||||
asm volatile ("syscall"
|
||||
: "+D" (status), "=S"(time_h), "=d"(time)
|
||||
:
|
||||
: "rcx", "r11", "memory");
|
||||
|
||||
time = (time_h & ~0xFFFFFFFFULL) | (time & 0xFFFFFFFFULL);
|
||||
return res;
|
||||
}
|
||||
|
||||
|
||||
ALWAYS_INLINE
|
||||
inline uint8_t assign_pci(mword_t pd, mword_t mem, mword_t rid)
|
||||
{
|
||||
return syscall_2(NOVA_ASSIGN_GSI, 0, pd, mem, rid);
|
||||
}
|
||||
|
||||
ALWAYS_INLINE
|
||||
inline uint8_t assign_gsi(mword_t sm, mword_t dev, mword_t rid)
|
||||
{
|
||||
mword_t dummy1, dummy2;
|
||||
return syscall_5(NOVA_ASSIGN_GSI, 0, sm, dev, rid, dummy1, dummy2);
|
||||
}
|
||||
|
||||
ALWAYS_INLINE
|
||||
inline uint8_t assign_gsi(mword_t sm, mword_t dev, mword_t rid, mword_t &msi_addr, mword_t &msi_data)
|
||||
{
|
||||
return syscall_5(NOVA_ASSIGN_GSI, 0, sm, dev, rid, msi_addr, msi_data);
|
||||
}
|
||||
}
|
||||
#endif /* _PLATFORM__NOVA_SYSCALLS_H_ */
|
@ -18,7 +18,7 @@
|
||||
|
||||
namespace Nova {
|
||||
|
||||
typedef long mword_t;
|
||||
typedef unsigned long mword_t;
|
||||
typedef unsigned char uint8_t;
|
||||
typedef Genode::uint16_t uint16_t;
|
||||
typedef Genode::uint32_t uint32_t;
|
||||
|
@ -30,21 +30,19 @@
|
||||
* OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#ifndef _PLATFORM__NOVA_SYSCALLS_H_
|
||||
#define _PLATFORM__NOVA_SYSCALLS_H_
|
||||
#ifndef _PLATFORM__NOVA_SYSCALLS_GENERIC_H_
|
||||
#define _PLATFORM__NOVA_SYSCALLS_GENERIC_H_
|
||||
|
||||
#include <nova/stdint.h>
|
||||
|
||||
#include <base/printf.h>
|
||||
|
||||
#define ALWAYS_INLINE __attribute__((always_inline))
|
||||
|
||||
namespace Nova {
|
||||
|
||||
enum {
|
||||
PAGE_SIZE_LOG2 = 12,
|
||||
PAGE_SIZE = 1 << PAGE_SIZE_LOG2,
|
||||
PAGE_MASK = ~(PAGE_SIZE - 1)
|
||||
PAGE_SIZE_BYTE = 1 << PAGE_SIZE_LOG2,
|
||||
PAGE_MASK_ = ~(PAGE_SIZE_BYTE - 1)
|
||||
};
|
||||
|
||||
/**
|
||||
@ -117,13 +115,13 @@ namespace Nova {
|
||||
{
|
||||
protected:
|
||||
|
||||
unsigned _value;
|
||||
mword_t _value;
|
||||
|
||||
/**
|
||||
* Assign bitfield to descriptor
|
||||
*/
|
||||
template<int MASK, int SHIFT>
|
||||
void _assign(unsigned new_bits)
|
||||
void _assign(mword_t new_bits)
|
||||
{
|
||||
_value &= ~(MASK << SHIFT);
|
||||
_value |= (new_bits & MASK) << SHIFT;
|
||||
@ -133,11 +131,11 @@ namespace Nova {
|
||||
* Query bitfield from descriptor
|
||||
*/
|
||||
template<int MASK, int SHIFT>
|
||||
unsigned _query() const { return (_value >> SHIFT) & MASK; }
|
||||
mword_t _query() const { return (_value >> SHIFT) & MASK; }
|
||||
|
||||
public:
|
||||
|
||||
unsigned value() const { return _value; }
|
||||
mword_t value() const { return _value; }
|
||||
};
|
||||
|
||||
|
||||
@ -148,7 +146,7 @@ namespace Nova {
|
||||
{
|
||||
private:
|
||||
|
||||
unsigned const _value;
|
||||
mword_t const _value;
|
||||
|
||||
public:
|
||||
|
||||
@ -167,9 +165,9 @@ namespace Nova {
|
||||
ALL = 0x000fffff & ~CTRL,
|
||||
};
|
||||
|
||||
Mtd(unsigned value) : _value(value) { }
|
||||
Mtd(mword_t value) : _value(value) { }
|
||||
|
||||
unsigned value() const { return _value; }
|
||||
mword_t value() const { return _value; }
|
||||
};
|
||||
|
||||
|
||||
@ -200,29 +198,29 @@ namespace Nova {
|
||||
OBJ_CRD_ALL = OBJ_CRD_TYPE | RIGHTS_ALL,
|
||||
};
|
||||
|
||||
void _base(unsigned base)
|
||||
void _base(mword_t base)
|
||||
{ _assign<BASE_MASK, BASE_SHIFT>(base); }
|
||||
|
||||
void _order(unsigned order)
|
||||
void _order(mword_t order)
|
||||
{ _assign<ORDER_MASK, ORDER_SHIFT>(order); }
|
||||
|
||||
public:
|
||||
|
||||
Crd(unsigned base, unsigned order) {
|
||||
Crd(mword_t base, mword_t order) {
|
||||
_value = 0; _base(base), _order(order); }
|
||||
|
||||
Crd(unsigned value) { _value = value; }
|
||||
Crd(mword_t value) { _value = value; }
|
||||
|
||||
unsigned hotspot(unsigned sel_hotspot) const
|
||||
mword_t hotspot(mword_t sel_hotspot) const
|
||||
{
|
||||
if ((value() & TYPE_MASK) == MEM_CRD_TYPE)
|
||||
return sel_hotspot & PAGE_MASK;
|
||||
return sel_hotspot & PAGE_MASK_;
|
||||
|
||||
return sel_hotspot << 12;
|
||||
}
|
||||
|
||||
unsigned base() const { return _query<BASE_MASK, BASE_SHIFT>(); }
|
||||
unsigned order() const { return _query<ORDER_MASK, ORDER_SHIFT>(); }
|
||||
mword_t base() const { return _query<BASE_MASK, BASE_SHIFT>(); }
|
||||
mword_t order() const { return _query<ORDER_MASK, ORDER_SHIFT>(); }
|
||||
bool is_null() const { return (_value & TYPE_MASK) == NULL_CRD_TYPE; }
|
||||
};
|
||||
|
||||
@ -269,7 +267,7 @@ namespace Nova {
|
||||
|
||||
public:
|
||||
|
||||
Mem_crd(unsigned base, unsigned order, Rights rights = Rights())
|
||||
Mem_crd(mword_t base, mword_t order, Rights rights = Rights())
|
||||
: Crd(base, order)
|
||||
{
|
||||
_rights(rights);
|
||||
@ -292,7 +290,7 @@ namespace Nova {
|
||||
{
|
||||
public:
|
||||
|
||||
Io_crd(unsigned base, unsigned order)
|
||||
Io_crd(mword_t base, mword_t order)
|
||||
: Crd(base, order)
|
||||
{
|
||||
_assign<TYPE_MASK | RIGHTS_MASK, TYPE_SHIFT>(IO_CRD_ALL);
|
||||
@ -304,7 +302,7 @@ namespace Nova {
|
||||
{
|
||||
public:
|
||||
|
||||
Obj_crd(unsigned base, unsigned order)
|
||||
Obj_crd(mword_t base, mword_t order)
|
||||
: Crd(base, order)
|
||||
{
|
||||
_assign<TYPE_MASK | RIGHTS_MASK, TYPE_SHIFT>(OBJ_CRD_ALL);
|
||||
@ -324,25 +322,25 @@ namespace Nova {
|
||||
PRIORITY_MASK = 0xff, PRIORITY_SHIFT = 0
|
||||
};
|
||||
|
||||
void _quantum(unsigned quantum)
|
||||
void _quantum(mword_t quantum)
|
||||
{ _assign<QUANTUM_MASK, QUANTUM_SHIFT>(quantum); }
|
||||
|
||||
void _priority(unsigned priority)
|
||||
void _priority(mword_t priority)
|
||||
{ _assign<PRIORITY_MASK, PRIORITY_SHIFT>(priority); }
|
||||
|
||||
public:
|
||||
|
||||
enum { DEFAULT_QUANTUM = 10000, DEFAULT_PRIORITY = 1 };
|
||||
|
||||
Qpd(unsigned quantum = DEFAULT_QUANTUM,
|
||||
unsigned priority = DEFAULT_PRIORITY)
|
||||
Qpd(mword_t quantum = DEFAULT_QUANTUM,
|
||||
mword_t priority = DEFAULT_PRIORITY)
|
||||
{
|
||||
_value = 0;
|
||||
_quantum(quantum), _priority(priority);
|
||||
}
|
||||
|
||||
unsigned quantum() const { return _query<QUANTUM_MASK, QUANTUM_SHIFT>(); }
|
||||
unsigned priority() const { return _query<PRIORITY_MASK, PRIORITY_SHIFT>(); }
|
||||
mword_t quantum() const { return _query<QUANTUM_MASK, QUANTUM_SHIFT>(); }
|
||||
mword_t priority() const { return _query<PRIORITY_MASK, PRIORITY_SHIFT>(); }
|
||||
};
|
||||
|
||||
|
||||
@ -351,11 +349,10 @@ namespace Nova {
|
||||
*/
|
||||
struct Utcb
|
||||
{
|
||||
unsigned short ui; /* number of untyped items */
|
||||
unsigned short ti; /* number of typed itmes */
|
||||
mword_t items; /* number of untyped items uses lowest 16 bit, number of typed items uses bit 16-31, bit 32+ are ignored on 64bit */
|
||||
Crd crd_xlt; /* receive capability-range descriptor for translation */
|
||||
Crd crd_rcv; /* receive capability-range descriptor for delegation */
|
||||
unsigned tls;
|
||||
mword_t tls;
|
||||
|
||||
/**
|
||||
* Data area
|
||||
@ -366,24 +363,28 @@ namespace Nova {
|
||||
union {
|
||||
|
||||
/* message payload */
|
||||
unsigned msg[];
|
||||
mword_t msg[];
|
||||
|
||||
/* exception state */
|
||||
struct {
|
||||
unsigned mtd, instr_len, eip, eflags;
|
||||
mword_t mtd, instr_len, eip, eflags;
|
||||
unsigned misc[4];
|
||||
unsigned eax, ecx, edx, ebx;
|
||||
unsigned esp, ebp, esi, edi;
|
||||
long long qual[2]; /* exit qualification */
|
||||
unsigned misc2[4];
|
||||
unsigned cr0, cr2, cr3, cr4;
|
||||
unsigned misc3[44];
|
||||
mword_t eax, ecx, edx, ebx;
|
||||
mword_t esp, ebp, esi, edi;
|
||||
#ifdef __x86_64__
|
||||
mword_t rxx[8];
|
||||
#endif
|
||||
unsigned long long qual[2]; /* exit qualification */
|
||||
unsigned ctrl[2];
|
||||
unsigned long long tsc;
|
||||
mword_t cr0, cr2, cr3, cr4;
|
||||
// unsigned misc3[44];
|
||||
};
|
||||
};
|
||||
|
||||
struct Item {
|
||||
unsigned crd;
|
||||
unsigned hotspot;
|
||||
mword_t crd;
|
||||
mword_t hotspot;
|
||||
};
|
||||
|
||||
/**
|
||||
@ -392,24 +393,25 @@ namespace Nova {
|
||||
* Calling this function has the side effect of removing all typed
|
||||
* message items from the message buffer.
|
||||
*/
|
||||
void set_msg_word(unsigned num) { ui = num; ti = 0; }
|
||||
void set_msg_word(unsigned num) { items = num; }
|
||||
|
||||
/**
|
||||
* Return current number of message word in UTCB
|
||||
*/
|
||||
unsigned msg_words() { return ui; }
|
||||
unsigned msg_words() { return items & 0xff; }
|
||||
|
||||
/**
|
||||
* Append message-transfer item to message buffer
|
||||
*
|
||||
* \param exception true to append the item to an exception reply
|
||||
*/
|
||||
void append_item(Crd crd, unsigned sel_hotspot,
|
||||
void append_item(Crd crd, mword_t sel_hotspot,
|
||||
bool kern_pd = false,
|
||||
bool update_guest_pt = false)
|
||||
{
|
||||
/* transfer items start at the end of the UTCB */
|
||||
Item *item = reinterpret_cast<Item *>(this) + (PAGE_SIZE / sizeof(struct Item)) - ++ti;
|
||||
items += 1 << 16;
|
||||
Item *item = reinterpret_cast<Item *>(this) + (PAGE_SIZE_BYTE / sizeof(struct Item)) - (items >> 16);
|
||||
|
||||
/* map from hypervisor or current pd */
|
||||
unsigned h = kern_pd ? (1 << 11) : 0;
|
||||
@ -422,7 +424,7 @@ namespace Nova {
|
||||
|
||||
}
|
||||
|
||||
unsigned mtd_value() const { return static_cast<Mtd>(mtd).value(); }
|
||||
mword_t mtd_value() const { return static_cast<Mtd>(mtd).value(); }
|
||||
};
|
||||
|
||||
/**
|
||||
@ -443,231 +445,5 @@ namespace Nova {
|
||||
PD_SEL = 0x1b,
|
||||
};
|
||||
|
||||
|
||||
ALWAYS_INLINE
|
||||
inline unsigned eax(Syscall s, uint8_t flags, unsigned sel)
|
||||
{
|
||||
return sel << 8 | (flags & 0xf) << 4 | s;
|
||||
}
|
||||
|
||||
|
||||
ALWAYS_INLINE
|
||||
inline uint8_t syscall_0(Syscall s, uint8_t flags, unsigned sel = 0)
|
||||
{
|
||||
mword_t status = eax(s, flags, sel);
|
||||
|
||||
asm volatile (" mov %%esp, %%ecx;"
|
||||
" call 0f;"
|
||||
"0:"
|
||||
" addl $(1f-0b), (%%esp);"
|
||||
" mov (%%esp), %%edx;"
|
||||
" sysenter;"
|
||||
"1:"
|
||||
: "+a" (status)
|
||||
:
|
||||
: "ecx", "edx", "memory");
|
||||
return status;
|
||||
}
|
||||
|
||||
|
||||
ALWAYS_INLINE
|
||||
inline uint8_t syscall_1(Syscall s, uint8_t flags, mword_t p1)
|
||||
{
|
||||
mword_t status = eax(s, flags, 0);
|
||||
|
||||
asm volatile (" mov %%esp, %%ecx;"
|
||||
" call 0f;"
|
||||
"0:"
|
||||
" addl $(1f-0b), (%%esp);"
|
||||
" mov (%%esp), %%edx;"
|
||||
" sysenter;"
|
||||
"1:"
|
||||
: "+a" (status)
|
||||
: "D" (p1)
|
||||
: "ecx", "edx");
|
||||
return status;
|
||||
}
|
||||
|
||||
|
||||
ALWAYS_INLINE
|
||||
inline uint8_t syscall_2(Syscall s, uint8_t flags, unsigned sel, mword_t p1, mword_t p2)
|
||||
{
|
||||
mword_t status = eax(s, flags, sel);
|
||||
|
||||
asm volatile (" mov %%esp, %%ecx;"
|
||||
" call 0f;"
|
||||
"0:"
|
||||
" addl $(1f-0b), (%%esp);"
|
||||
" mov (%%esp), %%edx;"
|
||||
" sysenter;"
|
||||
"1:"
|
||||
: "+a" (status)
|
||||
: "D" (p1), "S" (p2)
|
||||
: "ecx", "edx");
|
||||
return status;
|
||||
}
|
||||
|
||||
|
||||
ALWAYS_INLINE
|
||||
inline uint8_t syscall_3(Syscall s, uint8_t flags, unsigned sel,
|
||||
mword_t p1, mword_t p2, mword_t p3)
|
||||
{
|
||||
mword_t status = eax(s, flags, sel);
|
||||
|
||||
asm volatile (" push %%ebx;"
|
||||
" mov %%edx, %%ebx;"
|
||||
" mov %%esp, %%ecx;"
|
||||
" call 0f;"
|
||||
"0:"
|
||||
" addl $(1f-0b), (%%esp);"
|
||||
" mov (%%esp), %%edx;"
|
||||
" sysenter;"
|
||||
"1:"
|
||||
" pop %%ebx;"
|
||||
: "+a" (status)
|
||||
: "D" (p1), "S" (p2), "d" (p3)
|
||||
: "ecx");
|
||||
return status;
|
||||
}
|
||||
|
||||
|
||||
ALWAYS_INLINE
|
||||
inline uint8_t syscall_4(Syscall s, uint8_t flags, unsigned sel,
|
||||
mword_t p1, mword_t p2, mword_t p3, mword_t p4)
|
||||
{
|
||||
mword_t status = eax(s, flags, sel);
|
||||
|
||||
asm volatile (" push %%ebp;"
|
||||
" push %%ebx;"
|
||||
|
||||
" mov %%ecx, %%ebx;"
|
||||
" mov %%esp, %%ecx;"
|
||||
" mov %%edx, %%ebp;"
|
||||
|
||||
" call 0f;"
|
||||
"0:"
|
||||
" addl $(1f-0b), (%%esp);"
|
||||
" mov (%%esp), %%edx;"
|
||||
"sysenter;"
|
||||
"1:"
|
||||
|
||||
" pop %%ebx;"
|
||||
" pop %%ebp;"
|
||||
: "+a" (status)
|
||||
: "D" (p1), "S" (p2), "c" (p3), "d" (p4)
|
||||
: "memory");
|
||||
return status;
|
||||
}
|
||||
|
||||
|
||||
ALWAYS_INLINE
|
||||
inline uint8_t call(unsigned pt)
|
||||
{
|
||||
return syscall_0(NOVA_CALL, 0, pt);
|
||||
}
|
||||
|
||||
|
||||
ALWAYS_INLINE
|
||||
inline void reply(void *next_sp)
|
||||
{
|
||||
asm volatile ("sysenter;"
|
||||
:
|
||||
: "a" (NOVA_REPLY), "c" (next_sp)
|
||||
: "memory");
|
||||
}
|
||||
|
||||
|
||||
ALWAYS_INLINE
|
||||
inline uint8_t create_pd(unsigned pd0, unsigned pd, Crd crd)
|
||||
{
|
||||
return syscall_2(NOVA_CREATE_PD, 0, pd0, pd, crd.value());
|
||||
}
|
||||
|
||||
|
||||
ALWAYS_INLINE
|
||||
inline uint8_t create_ec(unsigned ec, unsigned pd,
|
||||
mword_t cpu, mword_t utcb,
|
||||
mword_t esp, mword_t evt,
|
||||
bool global = 0)
|
||||
{
|
||||
return syscall_4(NOVA_CREATE_EC, global, ec, pd,
|
||||
(cpu & 0xfff) | (utcb & ~0xfff),
|
||||
esp, evt);
|
||||
}
|
||||
|
||||
|
||||
ALWAYS_INLINE
|
||||
inline uint8_t ec_ctrl(unsigned ec)
|
||||
{
|
||||
return syscall_1(NOVA_EC_CTRL, 0, ec);
|
||||
}
|
||||
|
||||
ALWAYS_INLINE
|
||||
inline uint8_t create_sc(unsigned sc, unsigned pd, unsigned ec, Qpd qpd)
|
||||
{
|
||||
return syscall_3(NOVA_CREATE_SC, 0, sc, pd, ec, qpd.value());
|
||||
}
|
||||
|
||||
|
||||
ALWAYS_INLINE
|
||||
inline uint8_t create_pt(unsigned pt, unsigned pd, unsigned ec, Mtd mtd, mword_t eip)
|
||||
{
|
||||
return syscall_4(NOVA_CREATE_PT, 0, pt, pd, ec, mtd.value(), eip);
|
||||
}
|
||||
|
||||
|
||||
ALWAYS_INLINE
|
||||
inline uint8_t create_sm(unsigned sm, unsigned pd, mword_t cnt)
|
||||
{
|
||||
return syscall_2(NOVA_CREATE_SM, 0, sm, pd, cnt);
|
||||
}
|
||||
|
||||
|
||||
ALWAYS_INLINE
|
||||
inline uint8_t revoke(Crd crd, bool self = true)
|
||||
{
|
||||
return syscall_1(NOVA_REVOKE, self, crd.value());
|
||||
}
|
||||
|
||||
|
||||
ALWAYS_INLINE
|
||||
inline uint8_t lookup(Crd *crd)
|
||||
{
|
||||
mword_t status = eax(NOVA_LOOKUP, 0, 0);
|
||||
mword_t raw = crd->value();
|
||||
|
||||
asm volatile (" mov %%esp, %%ecx;"
|
||||
" call 0f;"
|
||||
"0:"
|
||||
" addl $(1f-0b), (%%esp);"
|
||||
" mov (%%esp), %%edx;"
|
||||
" sysenter;"
|
||||
"1:"
|
||||
: "+a" (status), "+D" (raw)
|
||||
:
|
||||
: "ecx", "edx", "memory");
|
||||
|
||||
*crd = Crd(raw);
|
||||
return status;
|
||||
}
|
||||
|
||||
/**
|
||||
* Semaphore operations
|
||||
*/
|
||||
enum Sem_op { SEMAPHORE_UP = 0, SEMAPHORE_DOWN = 1 };
|
||||
|
||||
|
||||
ALWAYS_INLINE
|
||||
inline uint8_t sm_ctrl(unsigned sm, Sem_op op)
|
||||
{
|
||||
return syscall_0(NOVA_SM_CTRL, op, sm);
|
||||
}
|
||||
|
||||
|
||||
ALWAYS_INLINE
|
||||
inline uint8_t assign_gsi(unsigned sm, mword_t dev, mword_t cpu)
|
||||
{
|
||||
return syscall_2(NOVA_ASSIGN_GSI, 0, sm, dev, cpu);
|
||||
}
|
||||
}
|
||||
#endif /* _PLATFORM__NOVA_SYSCALLS_H_ */
|
||||
#endif /* _PLATFORM__NOVA_SYSCALLS_GENERIC_H_ */
|
8
base-nova/lib/mk/x86_64/startup.mk
Normal file
8
base-nova/lib/mk/x86_64/startup.mk
Normal file
@ -0,0 +1,8 @@
|
||||
REQUIRES = nova x86_64
|
||||
LIBS = cxx lock
|
||||
SRC_S = crt0.s
|
||||
SRC_CC = _main.cc
|
||||
INC_DIR += $(REP_DIR)/src/platform
|
||||
|
||||
vpath crt0.s $(BASE_DIR)/src/platform/x86_64
|
||||
vpath _main.cc $(dir $(call select_from_repositories,src/platform/_main.cc))
|
@ -2,6 +2,12 @@
|
||||
# Specifics for the NOVA kernel API
|
||||
#
|
||||
|
||||
SPECS += nova
|
||||
SPECS += pci ps2 vesa
|
||||
|
||||
#
|
||||
# Linker options that are specific for x86
|
||||
#
|
||||
LD_TEXT_ADDR ?= 0x01000000
|
||||
|
||||
#
|
||||
@ -9,8 +15,3 @@ LD_TEXT_ADDR ?= 0x01000000
|
||||
#
|
||||
STARTUP_LIB ?= startup
|
||||
PRG_LIBS += $(STARTUP_LIB)
|
||||
|
||||
#
|
||||
# NOVA only runs on x86, enable x86 devices
|
||||
#
|
||||
SPECS += pci ps2 vesa
|
||||
|
8
base-nova/mk/spec-nova_x86_32.mk
Normal file
8
base-nova/mk/spec-nova_x86_32.mk
Normal file
@ -0,0 +1,8 @@
|
||||
#
|
||||
# Specifics for the NOVA kernel API x86 32 bit
|
||||
#
|
||||
|
||||
SPECS += nova x86_32
|
||||
|
||||
include $(call select_from_repositories,mk/spec-x86_32.mk)
|
||||
include $(call select_from_repositories,mk/spec-nova.mk)
|
8
base-nova/mk/spec-nova_x86_64.mk
Normal file
8
base-nova/mk/spec-nova_x86_64.mk
Normal file
@ -0,0 +1,8 @@
|
||||
#
|
||||
# Specifics for the NOVA kernel API x86 64 bit
|
||||
#
|
||||
|
||||
SPECS += nova x86_64
|
||||
|
||||
include $(call select_from_repositories,mk/spec-x86_64.mk)
|
||||
include $(call select_from_repositories,mk/spec-nova.mk)
|
@ -1,7 +1,7 @@
|
||||
diff -r 11c290b5edf9 src/syscall.cpp
|
||||
--- a/src/syscall.cpp Wed Nov 09 14:50:18 2011 +0100
|
||||
+++ b/src/syscall.cpp Wed Nov 09 15:07:03 2011 +0100
|
||||
@@ -240,11 +240,13 @@
|
||||
@@ -244,11 +244,13 @@
|
||||
}
|
||||
Pd *pd = static_cast<Pd *>(cap.obj());
|
||||
|
||||
@ -13,6 +13,6 @@ diff -r 11c290b5edf9 src/syscall.cpp
|
||||
|
||||
+ pd->insert_utcb (r->utcb());
|
||||
+
|
||||
Ec *ec = new Ec (Pd::current, r->sel(), pd, r->flags() & 1 ? static_cast<void (*)()>(send_msg<ret_user_iret>) : 0, r->cpu(), r->evt(), r->utcb(), r->esp());
|
||||
Ec *ec = new Ec (Pd::current, r->sel(), pd, r->flags() & 1 ? static_cast<void (*)()>(send_msg<ret_user_iret>) : nullptr, r->cpu(), r->evt(), r->utcb(), r->esp());
|
||||
|
||||
if (!Space_obj::insert_root (ec)) {
|
||||
|
@ -6,6 +6,12 @@
|
||||
# This file is meant to be used as '--include' argument for 'tool/run'.
|
||||
#
|
||||
|
||||
##
|
||||
# Install files needed to boot via PXE
|
||||
#
|
||||
proc install_pxe_bootloader_to_run_dir { } {
|
||||
exec cp [genode_dir]/tool/boot/pulsar [run_dir]/boot/pulsar
|
||||
}
|
||||
|
||||
##
|
||||
# Read the location of the Pistachio user directory from 'etc/pistachio.conf'
|
||||
@ -17,7 +23,7 @@ proc nova_kernel { } {
|
||||
if {[file exists etc/nova.conf]} {
|
||||
set _nova_kernel [exec sed -n "/^NOVA_KERNEL/s/^.*=\\s*//p" etc/nova.conf]
|
||||
} else {
|
||||
set _nova_kernel "[pwd]/kernel/hypervisor"
|
||||
set _nova_kernel "[pwd]/kernel/hypervisor"
|
||||
}
|
||||
}
|
||||
return $_nova_kernel
|
||||
@ -55,12 +61,12 @@ proc build_boot_image {binaries} {
|
||||
|
||||
install_iso_bootloader_to_run_dir
|
||||
|
||||
#
|
||||
# Generate grub config file
|
||||
#
|
||||
# The core binary is part of the 'binaries' list but it must
|
||||
# appear right after 'sigma0' as boot module. Hence the special case.
|
||||
#
|
||||
# Generate grub config file
|
||||
#
|
||||
set fh [open "[run_dir]/boot/grub/menu.lst" "WRONLY CREAT TRUNC"]
|
||||
puts $fh "timeout 0"
|
||||
puts $fh "default 0"
|
||||
@ -74,6 +80,19 @@ proc build_boot_image {binaries} {
|
||||
close $fh
|
||||
|
||||
create_iso_image_from_run_dir
|
||||
|
||||
#
|
||||
# Generate pulsar config file
|
||||
#
|
||||
set fh [open "[run_dir]/config-52-54-00-12-34-56" "WRONLY CREAT TRUNC"]
|
||||
puts $fh " exec /hypervisor serial spinner"
|
||||
puts $fh " load /genode/core"
|
||||
puts $fh " load /genode/config"
|
||||
foreach binary $binaries {
|
||||
if {$binary != "core"} {
|
||||
puts $fh " load /genode/$binary" } }
|
||||
close $fh
|
||||
install_pxe_bootloader_to_run_dir
|
||||
}
|
||||
|
||||
|
||||
|
@ -151,7 +151,7 @@ Pager_object::~Pager_object()
|
||||
revoke(Obj_crd(_tid.ec_sel, 0));
|
||||
/* revoke utcb */
|
||||
Rights rwx(true, true, true);
|
||||
revoke(Nova::Mem_crd((unsigned)Thread_base::myself()->utcb() >> 12, 0, rwx));
|
||||
revoke(Nova::Mem_crd((addr_t)Thread_base::myself()->utcb() >> 12, 0, rwx));
|
||||
}
|
||||
|
||||
|
||||
|
@ -87,7 +87,11 @@ void Rpc_entrypoint::_dissolve(Rpc_object_base *obj)
|
||||
void Rpc_entrypoint::_activation_entry()
|
||||
{
|
||||
/* retrieve portal id from eax */
|
||||
int id_pt; asm volatile ("" : "=a" (id_pt));
|
||||
#ifdef __x86_64__
|
||||
addr_t id_pt; asm volatile ("" : "=D" (id_pt));
|
||||
#else
|
||||
addr_t id_pt; asm volatile ("" : "=a" (id_pt));
|
||||
#endif
|
||||
Rpc_entrypoint *ep = static_cast<Rpc_entrypoint *>(Thread_base::myself());
|
||||
|
||||
Ipc_server srv(&ep->_snd_buf, &ep->_rcv_buf);
|
||||
|
@ -107,7 +107,7 @@ void Thread_base::_deinit_platform_thread()
|
||||
|
||||
/* revoke utcb */
|
||||
Nova::Rights rwx(true, true, true);
|
||||
Nova::revoke(Nova::Mem_crd((unsigned)Thread_base::myself()->utcb() >> 12, 0, rwx));
|
||||
Nova::revoke(Nova::Mem_crd((addr_t)Thread_base::myself()->utcb() >> 12, 0, rwx));
|
||||
}
|
||||
|
||||
|
||||
|
@ -47,15 +47,15 @@ Echo::Echo(Genode::addr_t utcb_addr)
|
||||
|
||||
/* create echo EC */
|
||||
int pd_sel = Genode::Cap_selector_allocator::pd_sel();
|
||||
int res = create_ec(_ec_sel, pd_sel, ECHO_CPU_NO, utcb_addr,
|
||||
(mword_t)echo_stack_top(), ECHO_EXC_BASE, ECHO_GLOBAL);
|
||||
uint8_t res = create_ec(_ec_sel, pd_sel, ECHO_CPU_NO, utcb_addr,
|
||||
(mword_t)echo_stack_top(), ECHO_EXC_BASE, ECHO_GLOBAL);
|
||||
|
||||
/* make error condition visible by raising an unhandled page fault */
|
||||
if (res) { ((void (*)())(res*0x10000))(); }
|
||||
if (res) { ((void (*)())(res*0x10000UL))(); }
|
||||
|
||||
/* set up echo portal to ourself */
|
||||
res = create_pt(_pt_sel, pd_sel, _ec_sel, Mtd(0), (mword_t)echo_reply);
|
||||
if (res) { ((void (*)())(res*0x10001))(); }
|
||||
if (res) { ((void (*)())(res*0x10001UL))(); }
|
||||
}
|
||||
|
||||
|
||||
|
@ -319,7 +319,7 @@ Platform::Platform() :
|
||||
|
||||
/* IRQ allocator */
|
||||
_irq_alloc.add_range(0, hip->sel_gsi - 1);
|
||||
_gsi_base_sel = hip->sel_exc;
|
||||
_gsi_base_sel = (hip->mem_desc_offset - hip->cpu_desc_offset) / hip->cpu_desc_size;
|
||||
|
||||
if (verbose_boot_info) {
|
||||
printf(":virt_alloc: "); _core_mem_alloc.virt_alloc()->raw()->dump_addr_tree();
|
||||
|
@ -33,7 +33,7 @@ void Rm_client::unmap(addr_t core_local_base, addr_t virt_base, size_t size)
|
||||
|
||||
while (true) {
|
||||
Nova::Mem_crd crd(core_local_base >> 12, 32, rwx);
|
||||
Nova::lookup(&crd);
|
||||
Nova::lookup(crd);
|
||||
|
||||
if (crd.is_null()) {
|
||||
PERR("Invalid unmap at local: %08lx virt: %08lx",
|
||||
@ -42,7 +42,7 @@ void Rm_client::unmap(addr_t core_local_base, addr_t virt_base, size_t size)
|
||||
}
|
||||
|
||||
if (verbose)
|
||||
PINF("Lookup core_addr: %08lx base: %x order: %x is null %d", core_local_base, crd.base(), crd.order(), crd.is_null());
|
||||
PINF("Lookup core_addr: %08lx base: %lx order: %lx is null %d", core_local_base, crd.base(), crd.order(), crd.is_null());
|
||||
|
||||
unmap_local(crd, false);
|
||||
|
||||
|
@ -1,5 +1,5 @@
|
||||
TARGET = hypervisor
|
||||
REQUIRES = x86 32bit nova
|
||||
REQUIRES = x86 nova
|
||||
NOVA_SRC_DIR = $(REP_DIR)/contrib
|
||||
NOVA_BUILD_DIR = $(BUILD_BASE_DIR)/kernel
|
||||
STARTUP_LIB =
|
||||
@ -15,18 +15,29 @@ CC_WARN = -Wall -Wextra -Waggregate-return -Wcast-align -Wcast-qual \
|
||||
-Wold-style-cast -Woverloaded-virtual -Wsign-promo \
|
||||
-Wframe-larger-than=64 -Wlogical-op -Wstrict-null-sentinel \
|
||||
-Wstrict-overflow=5 -Wvolatile-register-var
|
||||
CC_OPT += -pipe -mpreferred-stack-boundary=2 -mregparm=3 -m32 \
|
||||
CC_OPT += -pipe \
|
||||
-fdata-sections -fomit-frame-pointer -freg-struct-return \
|
||||
-freorder-blocks -funit-at-a-time -fno-exceptions -fno-rtti \
|
||||
-fno-stack-protector -fvisibility-inlines-hidden
|
||||
-fno-stack-protector -fvisibility-inlines-hidden \
|
||||
-fno-asynchronous-unwind-tables -std=gnu++0x
|
||||
ifeq ($(filter-out $(SPECS),32bit),)
|
||||
CC_OPT += -mpreferred-stack-boundary=2 -mregparm=3
|
||||
else
|
||||
ifeq ($(filter-out $(SPECS),64bit),)
|
||||
CC_OPT += -mpreferred-stack-boundary=4 -mcmodel=kernel -mno-red-zone
|
||||
else
|
||||
$(error Unsupported environment)
|
||||
endif
|
||||
endif
|
||||
|
||||
CXX_LINK_OPT = -Wl,--gc-sections -Wl,--warn-common -Wl,-static -Wl,-n
|
||||
LD_TEXT_ADDR = 0xc0000000
|
||||
LD_TEXT_ADDR = # 0xc000000000 - when setting this 64bit compile fails because of relocation issues!!
|
||||
LD_SCRIPT_STATIC = hypervisor.o
|
||||
|
||||
$(TARGET): hypervisor.o
|
||||
|
||||
hypervisor.o: $(NOVA_SRC_DIR)/src/hypervisor.ld
|
||||
$(VERBOSE)$(CC) $(INCLUDES) -MP -MMD -pipe -m32 -xc -E -P $< -o $@
|
||||
$(VERBOSE)$(CC) $(INCLUDES) -MP -MMD -pipe $(CC_MARCH) -xc -E -P $< -o $@
|
||||
|
||||
clean cleanall:
|
||||
$(VERBOSE)rm -rf $(NOVA_BUILD_DIR)
|
||||
|
@ -42,7 +42,7 @@ extern int __local_pd_sel;
|
||||
static void main_thread_bootstrap()
|
||||
{
|
||||
/* register UTCB of main thread */
|
||||
__main_thread_utcb = __initial_sp - Nova::PAGE_SIZE;
|
||||
__main_thread_utcb = __initial_sp - Nova::PAGE_SIZE_BYTE;
|
||||
|
||||
/* register start of usable capability range */
|
||||
enum { FIRST_FREE_PORTAL = 0x1000 };
|
||||
|
@ -9,4 +9,6 @@ SPECS += x86 64bit
|
||||
REP_INC_DIR += include/x86
|
||||
REP_INC_DIR += include/x86_64
|
||||
|
||||
CC_MARCH ?= -m64
|
||||
|
||||
include $(call select_from_repositories,mk/spec-64bit.mk)
|
||||
|
@ -212,7 +212,7 @@ int main()
|
||||
|
||||
/* create ram session for init and transfer some of our own quota */
|
||||
Ram_session_capability init_ram_session_cap
|
||||
= static_cap_cast<Ram_session>(ram_root.session("ram_quota=16K"));
|
||||
= static_cap_cast<Ram_session>(ram_root.session("ram_quota=32K"));
|
||||
Ram_session_client(init_ram_session_cap).ref_account(env()->ram_session_cap());
|
||||
|
||||
Cpu_connection init_cpu;
|
||||
|
@ -13,7 +13,7 @@
|
||||
|
||||
#include <base/env.h>
|
||||
#include <base/sleep.h>
|
||||
|
||||
#include <base/printf.h>
|
||||
|
||||
extern "C" void _exit(int status)
|
||||
{
|
||||
|
@ -318,7 +318,7 @@ class Vcpu_dispatcher : Genode::Thread_base,
|
||||
Nova::Mem_crd crd(src >> PAGE_SIZE_LOG2, 32 - PAGE_SIZE_LOG2,
|
||||
Nova::Rights(true, true, true));
|
||||
|
||||
Nova::uint8_t ret = Nova::lookup(&crd);
|
||||
Nova::uint8_t ret = Nova::lookup(crd);
|
||||
|
||||
if (verbose_npt)
|
||||
Logging::printf("looked up crd (base=0x%lx, order=%ld)\n",
|
||||
|
@ -4,7 +4,7 @@ CONTRIB_DIR = $(REP_DIR)/contrib/vancouver-0.4
|
||||
VANCOUVER_DIR = $(CONTRIB_DIR)/vancouver
|
||||
NOVA_INCLUDE_DIR = $(REP_DIR)/contrib/vancouver-0.4/base/include
|
||||
|
||||
REQUIRES = nova
|
||||
REQUIRES = nova x86_32
|
||||
|
||||
ifeq ($(wildcard $(VANCOUVER_DIR)),)
|
||||
REQUIRES += prepare_ports_vancouver
|
||||
|
BIN
tool/boot/pulsar
Normal file
BIN
tool/boot/pulsar
Normal file
Binary file not shown.
@ -1,6 +0,0 @@
|
||||
REPOSITORIES = $(GENODE_DIR)/base-nova
|
||||
|
||||
#
|
||||
# The current NOVA kernel build is optimized for Intel Core Duo.
|
||||
#
|
||||
QEMU_OPT += -cpu coreduo
|
6
tool/builddir/etc/build.conf.nova_x86_32
Normal file
6
tool/builddir/etc/build.conf.nova_x86_32
Normal file
@ -0,0 +1,6 @@
|
||||
REPOSITORIES = $(GENODE_DIR)/base-nova
|
||||
|
||||
#
|
||||
# The current NOVA kernel build is optimized for Intel Core2 Duo.
|
||||
#
|
||||
QEMU_OPT += -cpu core2duo
|
6
tool/builddir/etc/build.conf.nova_x86_64
Normal file
6
tool/builddir/etc/build.conf.nova_x86_64
Normal file
@ -0,0 +1,6 @@
|
||||
REPOSITORIES = $(GENODE_DIR)/base-nova
|
||||
|
||||
#
|
||||
# The current NOVA kernel build is optimized for Intel Core2 Duo.
|
||||
#
|
||||
QEMU_OPT += -cpu core2duo
|
@ -23,7 +23,8 @@ usage:
|
||||
@echo " 'fiasco_x86'"
|
||||
@echo " 'pistachio_x86'"
|
||||
@echo " 'okl4_x86'"
|
||||
@echo " 'nova_x86'"
|
||||
@echo " 'nova_x86_32'"
|
||||
@echo " 'nova_x86_64'"
|
||||
@echo " 'codezero_vpb926'"
|
||||
@echo " 'mb_s3a_starter_kit'"
|
||||
@echo " 'foc_x86_32'"
|
||||
@ -70,7 +71,7 @@ $(BUILD_DIR)/etc/build.conf::
|
||||
#
|
||||
# Supply -no-kvm argument to Qemu for kernels that are incompatible with KVM
|
||||
#
|
||||
ifeq ($(filter-out foc_x86_32 foc_x86_64 okl4_x86 nova_x86 pistachio_x86,$(PLATFORM)),)
|
||||
ifeq ($(filter-out foc_x86_32 foc_x86_64 okl4_x86 nova_x86_32 nova_x86_64 pistachio_x86,$(PLATFORM)),)
|
||||
$(BUILD_DIR)/etc/build.conf::
|
||||
@cat $(BUILD_CONF).qemu_no_kvm >> $@
|
||||
endif
|
||||
@ -120,7 +121,7 @@ endif
|
||||
#
|
||||
# Add x86 drivers repositories to x86 build directories
|
||||
#
|
||||
ifeq ($(filter-out foc_x86_32 okl4_x86 nova_x86 pistachio_x86 fiasco_x86,$(PLATFORM)),)
|
||||
ifeq ($(filter-out foc_x86_32 okl4_x86 nova_x86_32 nova_x86_64 pistachio_x86 fiasco_x86,$(PLATFORM)),)
|
||||
$(BUILD_DIR)/etc/build.conf::
|
||||
@cat $(BUILD_CONF).drivers_x86 >> $@
|
||||
endif
|
||||
@ -144,6 +145,12 @@ foc_x86_32::
|
||||
foc_x86_64::
|
||||
@echo "SPECS = genode foc_x86_64" > $(BUILD_DIR)/etc/specs.conf
|
||||
|
||||
nova_x86_32::
|
||||
@echo "SPECS = genode nova_x86_32 x86_32" > $(BUILD_DIR)/etc/specs.conf
|
||||
|
||||
nova_x86_64::
|
||||
@echo "SPECS = genode nova_x86_64 x86_64" > $(BUILD_DIR)/etc/specs.conf
|
||||
|
||||
foc_pbxa9::
|
||||
@echo "SPECS = genode foc_pbxa9" > $(BUILD_DIR)/etc/specs.conf
|
||||
|
||||
|
7
tool/run
7
tool/run
@ -441,7 +441,12 @@ proc spawn_qemu { wait_for_re timeout_value } {
|
||||
if {[have_spec platform_vea9x4]} { append qemu_args " -M vexpress-a9 -cpu cortex-a9 -m 256 " }
|
||||
|
||||
# on x86, we supply the boot image as ISO image
|
||||
if {[have_spec x86]} { append qemu_args " -cdrom [run_dir].iso " }
|
||||
if {[have_spec x86_64] && [have_spec nova]} {
|
||||
append qemu_args " -boot n -tftp [run_dir] -bootp boot/pulsar -no-reboot -no-shutdown "
|
||||
} else {
|
||||
# on x86, we supply the boot image as ISO image
|
||||
if {[have_spec x86]} { append qemu_args " -cdrom [run_dir].iso " }
|
||||
}
|
||||
|
||||
# on ARM, we supply the boot image as kernel
|
||||
if {[have_spec arm]} { append qemu_args " -kernel [run_dir]/image.elf " }
|
||||
|
Loading…
Reference in New Issue
Block a user