From ae6257dce1db1be01489897c1baebc33ae4c7958 Mon Sep 17 00:00:00 2001 From: Alexander Boettcher Date: Wed, 6 Jun 2012 10:19:48 +0200 Subject: [PATCH] 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 --- base-nova/Makefile | 51 ++- base-nova/include/32bit/nova/syscalls.h | 269 +++++++++++++++ base-nova/include/64bit/nova/syscalls.h | 263 ++++++++++++++ base-nova/include/nova/stdint.h | 2 +- .../nova/{syscalls.h => syscall-generic.h} | 326 +++--------------- base-nova/lib/mk/x86_64/startup.mk | 8 + base-nova/mk/spec-nova.mk | 11 +- base-nova/mk/spec-nova_x86_32.mk | 8 + base-nova/mk/spec-nova_x86_64.mk | 8 + base-nova/patches/utcb.patch | 4 +- base-nova/run/env | 25 +- base-nova/src/base/pager/pager.cc | 2 +- base-nova/src/base/server/server.cc | 6 +- base-nova/src/base/thread/thread_nova.cc | 2 +- base-nova/src/core/echo.cc | 8 +- base-nova/src/core/platform.cc | 2 +- base-nova/src/core/rm_session_support.cc | 4 +- base-nova/src/kernel/target.mk | 21 +- base-nova/src/platform/_main_helper.h | 2 +- base/mk/spec-x86_64.mk | 2 + base/src/core/main.cc | 2 +- libports/src/lib/libc/exit.cc | 2 +- ports/src/vancouver/main.cc | 2 +- ports/src/vancouver/target.mk | 2 +- tool/boot/pulsar | Bin 0 -> 6668 bytes tool/builddir/etc/build.conf.nova_x86 | 6 - tool/builddir/etc/build.conf.nova_x86_32 | 6 + tool/builddir/etc/build.conf.nova_x86_64 | 6 + tool/create_builddir | 13 +- tool/run | 7 +- 30 files changed, 726 insertions(+), 344 deletions(-) create mode 100644 base-nova/include/32bit/nova/syscalls.h create mode 100644 base-nova/include/64bit/nova/syscalls.h rename base-nova/include/nova/{syscalls.h => syscall-generic.h} (54%) create mode 100644 base-nova/lib/mk/x86_64/startup.mk create mode 100644 base-nova/mk/spec-nova_x86_32.mk create mode 100644 base-nova/mk/spec-nova_x86_64.mk create mode 100644 tool/boot/pulsar delete mode 100644 tool/builddir/etc/build.conf.nova_x86 create mode 100644 tool/builddir/etc/build.conf.nova_x86_32 create mode 100644 tool/builddir/etc/build.conf.nova_x86_64 diff --git a/base-nova/Makefile b/base-nova/Makefile index 592b7158a..db58ac03d 100644 --- a/base-nova/Makefile +++ b/base-nova/Makefile @@ -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) diff --git a/base-nova/include/32bit/nova/syscalls.h b/base-nova/include/32bit/nova/syscalls.h new file mode 100644 index 000000000..31923a80a --- /dev/null +++ b/base-nova/include/32bit/nova/syscalls.h @@ -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 +#include + +#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_ */ diff --git a/base-nova/include/64bit/nova/syscalls.h b/base-nova/include/64bit/nova/syscalls.h new file mode 100644 index 000000000..345c9f33a --- /dev/null +++ b/base-nova/include/64bit/nova/syscalls.h @@ -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 +#include + +#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_ */ diff --git a/base-nova/include/nova/stdint.h b/base-nova/include/nova/stdint.h index fe43f9c81..01b935f22 100644 --- a/base-nova/include/nova/stdint.h +++ b/base-nova/include/nova/stdint.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; diff --git a/base-nova/include/nova/syscalls.h b/base-nova/include/nova/syscall-generic.h similarity index 54% rename from base-nova/include/nova/syscalls.h rename to base-nova/include/nova/syscall-generic.h index a73f244b0..95cbd68d6 100644 --- a/base-nova/include/nova/syscalls.h +++ b/base-nova/include/nova/syscall-generic.h @@ -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 -#include - #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 - 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 - 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); } - void _order(unsigned order) + void _order(mword_t order) { _assign(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(); } - unsigned order() const { return _query(); } + mword_t base() const { return _query(); } + mword_t order() const { return _query(); } 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(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(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); } - void _priority(unsigned priority) + void _priority(mword_t priority) { _assign(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(); } - unsigned priority() const { return _query(); } + mword_t quantum() const { return _query(); } + mword_t priority() const { return _query(); } }; @@ -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(this) + (PAGE_SIZE / sizeof(struct Item)) - ++ti; + items += 1 << 16; + Item *item = reinterpret_cast(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).value(); } + mword_t mtd_value() const { return static_cast(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_ */ diff --git a/base-nova/lib/mk/x86_64/startup.mk b/base-nova/lib/mk/x86_64/startup.mk new file mode 100644 index 000000000..57a8c96d3 --- /dev/null +++ b/base-nova/lib/mk/x86_64/startup.mk @@ -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)) diff --git a/base-nova/mk/spec-nova.mk b/base-nova/mk/spec-nova.mk index e6c5d276c..f538c314d 100644 --- a/base-nova/mk/spec-nova.mk +++ b/base-nova/mk/spec-nova.mk @@ -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 diff --git a/base-nova/mk/spec-nova_x86_32.mk b/base-nova/mk/spec-nova_x86_32.mk new file mode 100644 index 000000000..7d94836a3 --- /dev/null +++ b/base-nova/mk/spec-nova_x86_32.mk @@ -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) diff --git a/base-nova/mk/spec-nova_x86_64.mk b/base-nova/mk/spec-nova_x86_64.mk new file mode 100644 index 000000000..922c92cb1 --- /dev/null +++ b/base-nova/mk/spec-nova_x86_64.mk @@ -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) diff --git a/base-nova/patches/utcb.patch b/base-nova/patches/utcb.patch index b2efe4605..0fcd065d1 100644 --- a/base-nova/patches/utcb.patch +++ b/base-nova/patches/utcb.patch @@ -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(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(send_msg) : 0, r->cpu(), r->evt(), r->utcb(), r->esp()); + Ec *ec = new Ec (Pd::current, r->sel(), pd, r->flags() & 1 ? static_cast(send_msg) : nullptr, r->cpu(), r->evt(), r->utcb(), r->esp()); if (!Space_obj::insert_root (ec)) { diff --git a/base-nova/run/env b/base-nova/run/env index c0720c309..f9269f5f9 100644 --- a/base-nova/run/env +++ b/base-nova/run/env @@ -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 } diff --git a/base-nova/src/base/pager/pager.cc b/base-nova/src/base/pager/pager.cc index 744daaa4d..716bb4871 100644 --- a/base-nova/src/base/pager/pager.cc +++ b/base-nova/src/base/pager/pager.cc @@ -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)); } diff --git a/base-nova/src/base/server/server.cc b/base-nova/src/base/server/server.cc index fbb5bb595..d8288617f 100644 --- a/base-nova/src/base/server/server.cc +++ b/base-nova/src/base/server/server.cc @@ -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(Thread_base::myself()); Ipc_server srv(&ep->_snd_buf, &ep->_rcv_buf); diff --git a/base-nova/src/base/thread/thread_nova.cc b/base-nova/src/base/thread/thread_nova.cc index 1cca47923..b45d7cdf9 100644 --- a/base-nova/src/base/thread/thread_nova.cc +++ b/base-nova/src/base/thread/thread_nova.cc @@ -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)); } diff --git a/base-nova/src/core/echo.cc b/base-nova/src/core/echo.cc index d58375317..809b4d359 100644 --- a/base-nova/src/core/echo.cc +++ b/base-nova/src/core/echo.cc @@ -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))(); } } diff --git a/base-nova/src/core/platform.cc b/base-nova/src/core/platform.cc index 36ee5caaf..9a3fa3fb0 100644 --- a/base-nova/src/core/platform.cc +++ b/base-nova/src/core/platform.cc @@ -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(); diff --git a/base-nova/src/core/rm_session_support.cc b/base-nova/src/core/rm_session_support.cc index 98f495713..d43a50906 100644 --- a/base-nova/src/core/rm_session_support.cc +++ b/base-nova/src/core/rm_session_support.cc @@ -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); diff --git a/base-nova/src/kernel/target.mk b/base-nova/src/kernel/target.mk index 78a90fdf2..13ac1a2fc 100644 --- a/base-nova/src/kernel/target.mk +++ b/base-nova/src/kernel/target.mk @@ -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) diff --git a/base-nova/src/platform/_main_helper.h b/base-nova/src/platform/_main_helper.h index 16253908c..0b3871b3f 100644 --- a/base-nova/src/platform/_main_helper.h +++ b/base-nova/src/platform/_main_helper.h @@ -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 }; diff --git a/base/mk/spec-x86_64.mk b/base/mk/spec-x86_64.mk index 824e173cc..6cd035baf 100644 --- a/base/mk/spec-x86_64.mk +++ b/base/mk/spec-x86_64.mk @@ -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) diff --git a/base/src/core/main.cc b/base/src/core/main.cc index 38276d780..625cb3843 100644 --- a/base/src/core/main.cc +++ b/base/src/core/main.cc @@ -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_root.session("ram_quota=16K")); + = static_cap_cast(ram_root.session("ram_quota=32K")); Ram_session_client(init_ram_session_cap).ref_account(env()->ram_session_cap()); Cpu_connection init_cpu; diff --git a/libports/src/lib/libc/exit.cc b/libports/src/lib/libc/exit.cc index 0b67a6584..124a5096a 100644 --- a/libports/src/lib/libc/exit.cc +++ b/libports/src/lib/libc/exit.cc @@ -13,7 +13,7 @@ #include #include - +#include extern "C" void _exit(int status) { diff --git a/ports/src/vancouver/main.cc b/ports/src/vancouver/main.cc index 5acc61ebc..a5e7a3987 100644 --- a/ports/src/vancouver/main.cc +++ b/ports/src/vancouver/main.cc @@ -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", diff --git a/ports/src/vancouver/target.mk b/ports/src/vancouver/target.mk index 01d554c60..fca241f59 100644 --- a/ports/src/vancouver/target.mk +++ b/ports/src/vancouver/target.mk @@ -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 diff --git a/tool/boot/pulsar b/tool/boot/pulsar new file mode 100644 index 0000000000000000000000000000000000000000..0f28e9982226ff69ddd8e351a6e2488b2f5c5262 GIT binary patch literal 6668 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 $@ 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 diff --git a/tool/run b/tool/run index 90b6606f4..c37faada1 100755 --- a/tool/run +++ b/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 " }