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:
Alexander Boettcher 2012-06-06 10:19:48 +02:00 committed by Norman Feske
parent 200deec403
commit ae6257dce1
30 changed files with 726 additions and 344 deletions

View File

@ -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)

View 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_ */

View 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_ */

View File

@ -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;

View File

@ -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_ */

View 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))

View File

@ -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

View 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)

View 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)

View File

@ -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)) {

View File

@ -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
}

View File

@ -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));
}

View File

@ -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);

View File

@ -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));
}

View File

@ -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))(); }
}

View File

@ -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();

View File

@ -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);

View File

@ -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)

View File

@ -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 };

View File

@ -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)

View File

@ -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;

View File

@ -13,7 +13,7 @@
#include <base/env.h>
#include <base/sleep.h>
#include <base/printf.h>
extern "C" void _exit(int status)
{

View File

@ -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",

View File

@ -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

Binary file not shown.

View File

@ -1,6 +0,0 @@
REPOSITORIES = $(GENODE_DIR)/base-nova
#
# The current NOVA kernel build is optimized for Intel Core Duo.
#
QEMU_OPT += -cpu coreduo

View 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

View 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

View File

@ -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

View File

@ -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 " }