Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Solo5/spt: aarch32 support #470

Open
wants to merge 8 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 12 additions & 1 deletion GNUmakefile
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,12 @@ $(TOPDIR)/Makeconf:
$(error Makeconf not found, please run ./configure.sh)
include Makefile.common

SUBDIRS := bindings tenders elftool tests
ifeq ($(CONFIG_BITS), __BITS_32__)
SUBDIRS := lib32
else
SUBDIRS :=
endif
SUBDIRS += bindings tenders elftool tests

tests: bindings elftool

Expand Down Expand Up @@ -130,6 +135,9 @@ ifdef CONFIG_HVT
endif
ifdef CONFIG_SPT
cp tenders/spt/solo5-spt $(PREFIX)/bin
ifeq ($(CONFIG_ARCH), arm)
cp lib32/aeabi/libaeabi.a $(PREFIX)/lib/solo5-bindings-spt
endif
endif
ifdef CONFIG_VIRTIO
cp scripts/virtio-mkimage/solo5-virtio-mkimage.sh \
Expand Down Expand Up @@ -157,6 +165,9 @@ uninstall-opam-%: force-uninstall
$(PREFIX)/bin/solo5-hvt-configure
# CONFIG_SPT
$(RM) $(PREFIX)/bin/solo5-spt
ifeq ($(CONFIG_ARCH), arm)
$(RM) $(PREFIX)/lib/solo5-bindings-spt/libaeabi.a
endif
# CONFIG_VIRTIO
$(RM) $(PREFIX)/bin/solo5-virtio-mkimage
$(RM) $(PREFIX)/bin/solo5-virtio-run
Expand Down
5 changes: 3 additions & 2 deletions Makefile.common
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,7 @@ HOSTAR := ar

define HOSTCOMPILE.c
@echo "HOSTCC $<"
$(HOSTCC) $(DEPFLAGS) $(HOSTCFLAGS) $(HOSTCPPFLAGS) -c $< -o $@
$(HOSTCC) $(DEPFLAGS) $(HOSTCFLAGS) $(HOSTCPPFLAGS) -D$(CONFIG_BITS) -c $< -o $@
mv -f $*.Td $*.d && touch $@
endef

Expand All @@ -82,8 +82,9 @@ define HOSTCOMPILE.S
mv -f $*.Td $*.d && touch $@
endef

# @echo "HOSTLINK $@"
define HOSTLINK
@echo "HOSTLINK $@"
@echo "$(HOSTCC) $(HOSTLDFLAGS) $^ $(HOSTLDLIBS) -o $@"
$(HOSTCC) $(HOSTLDFLAGS) $^ $(HOSTLDLIBS) -o $@
endef

Expand Down
16 changes: 11 additions & 5 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -52,12 +52,18 @@ unikernel in particular:
- [Debugging Solo5-based unikernels](docs/debugging.md)
- [Technical overview, goals and limitations, and architecture of Solo5](docs/architecture.md)

# Contributing and community
# License, contributing and community

Solo5 is developed on GitHub and licensed under a liberal ISC license. We
accept contributions via GitHub pull requests. When submitting a contribution,
please add your details to the `AUTHORS` file, and if your contribution adds
new source files copy the copyright header from an existing source file.
Solo5 is developed on GitHub and its original contributions are licensed under
a liberal ISC license.

This package incorporates components derived or copied from LLVM compiler-rt.
For full details of the licenses of the components, refer to each source file.

We accept contributions via GitHub pull requests. When submitting a
contribution, please add your details to the `AUTHORS` file, and if your
contribution adds new source files copy the copyright header from an existing
source file.

The coding style for the project is "as for the Linux kernel, but with 4
spaces instead of tabs". When in doubt, please follow style in existing source
Expand Down
11 changes: 8 additions & 3 deletions bindings/GNUmakefile
Original file line number Diff line number Diff line change
Expand Up @@ -41,9 +41,14 @@ hvt_SRCS := hvt/start.c $(common_SRCS) $(common_hvt_SRCS) \
hvt/platform_lifecycle.c hvt/yield.c hvt/tscclock.c hvt/console.c \
hvt/net.c hvt/block.c

spt_SRCS := spt/start.c \
abort.c crt.c printf.c lib.c mem.c exit.c log.c cmdline.c tls.c mft.c \
spt/bindings.c spt/block.c spt/net.c spt/platform.c \
ifeq ($(CONFIG_BITS), __BITS_32__)
spt_SRCS := mem32.c
else ifeq ($(CONFIG_BITS), __BITS_64__)
spt_SRCS := mem64.c
endif
spt_SRCS += spt/start.c \
abort.c crt.c printf.c lib.c exit.c log.c cmdline.c tls.c \
mft.c spt/bindings.c spt/block.c spt/net.c spt/platform.c \
spt/sys_linux_$(CONFIG_ARCH).c

virtio_SRCS := virtio/boot.S virtio/start.c $(common_SRCS) \
Expand Down
13 changes: 13 additions & 0 deletions bindings/bindings.h
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,8 @@
#include "cpu_x86_64.h"
#elif defined(__aarch64__)
#include "cpu_aarch64.h"
#elif defined(__arm__)
#include "cpu_arm.h"
#elif defined(__powerpc64__)
#include "cpu_ppc64.h"
#else
Expand Down Expand Up @@ -91,7 +93,13 @@ extern int cpu_intr_depth;

/* intr.c: interrupt handling */
void intr_register_irq(unsigned irq, int (*handler)(void *), void *arg);
#if defined(__BITS_32__)
void intr_irq_handler(uint32_t irq);
#elif defined(__BITS_64__)
void intr_irq_handler(uint64_t irq);
#else
#error Unsupported architecture bits
#endif

/* mem.c: low-level page alloc routines */
void mem_init(void);
Expand All @@ -118,7 +126,12 @@ const char *platform_cmdline(void);
uint64_t platform_mem_size(void);
void platform_exit(int status, void *cookie) __attribute__((noreturn));
int platform_puts(const char *buf, int n);

#if defined(__BITS_32__)
int platform_set_tls_base(uint32_t base);
#else
int platform_set_tls_base(uint64_t base);
#endif

/* platform_intr.c: platform-specific interrupt handling */
void platform_intr_init(void);
Expand Down
77 changes: 77 additions & 0 deletions bindings/cpu_arm.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
/*
* Copyright (c) 2015-2019 Contributors as noted in the AUTHORS file
*
* This file is part of Solo5, a sandboxed execution environment.
*
* Permission to use, copy, modify, and/or distribute this software
* for any purpose with or without fee is hereby granted, provided
* that the above copyright notice and this permission notice appear
* in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
* WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
* AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR
* CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS
* OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT,
* NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
* CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
#ifndef __CPU_ARM_H__
#define __CPU_ARM_H__

/* memory defines */
#define PAGE_SIZE 4096
#define PAGE_SHIFT 12
#define PAGE_MASK ~(0xfff)

#ifndef _BITUL

#ifdef ASM_FILE
#define _AC(X,Y) X
#define _AT(T,X) X
#else
#define __AC(X,Y) (X##Y)
#define _AC(X,Y) __AC(X,Y)
#define _AT(T,X) ((T)(X))
#endif

#define _BITUL(x) (_AC(1,UL) << (x))
#define _BITULL(x) (_AC(1,ULL) << (x))

#endif

#define ESR_EC_IABT_LOW _AC(0x20, UL)
#define ESR_EC_IABT_CUR _AC(0x21, UL)
#define ESR_EC_DABT_LOW _AC(0x24, UL)
#define ESR_EC_DABT_CUR _AC(0x25, UL)

#define ESR_EC_SHIFT _AC(26, UL)
#define ESR_EC_MASK (_AC(0x3F, UL) << ESR_EC_SHIFT)
#define ESR_EC(esr) (((esr) & ESR_EC_MASK) >> ESR_EC_SHIFT)

#ifndef ASM_FILE

/*
* The remainder of this file is used only from C.
*/
static inline uint64_t cpu_cntvct(void)
{
uint32_t hi, lo;

__asm__ __volatile__("mrrc p15, 1, %0, %1, c14" : "=r" (lo), "=r" (hi));
return ((uint64_t) hi << 32) | lo;
}

static inline uint64_t mul64_32(uint64_t a, uint32_t b, uint8_t s)
{
return (a * b) >> s;
}
#endif /* !ASM_FILE */

static inline void cpu_set_tls_base(uint32_t base)
{
__asm__ __volatile__("mcr p15, 0, %0, c13, c0, 2" :: "r"(base));
}

#endif /* __CPU_ARM_H__ */
6 changes: 6 additions & 0 deletions bindings/crt.c
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,13 @@
* crt_init_early(), keep an easily recognisable "terminator" value here to
* flag if that did not happen as expected.
*/
#if (__BITS_32__)
uintptr_t SSP_GUARD = 0xdeadbeef;
#elif (__BITS_64__)
uintptr_t SSP_GUARD = 0x00deadbeef0d0a00;
#else
#error Unsupported architecture bits
#endif

/*
* Called by compiler-generated code when corruption of the canary value is
Expand Down
2 changes: 2 additions & 0 deletions bindings/crt_init.h
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,8 @@ extern uintptr_t SSP_GUARD;
#define READ_CPU_TICKS cpu_rdtsc
#elif defined(__aarch64__)
#define READ_CPU_TICKS cpu_cntvct
#elif defined(__arm__)
#define READ_CPU_TICKS cpu_cntvct
#elif defined(__powerpc64__)
#define READ_CPU_TICKS cpu_cntvct
#else
Expand Down
83 changes: 83 additions & 0 deletions bindings/mem32.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
/*
* Copyright (c) 2015-2019 Contributors as noted in the AUTHORS file
*
* This file is part of Solo5, a sandboxed execution environment.
*
* Permission to use, copy, modify, and/or distribute this software
* for any purpose with or without fee is hereby granted, provided
* that the above copyright notice and this permission notice appear
* in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
* WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
* AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR
* CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS
* OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT,
* NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
* CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/

#include "bindings.h"

static uint32_t heap_start;

/*
* Locks the memory layout (by disabling mem_ialloc_pages()). Must be called
* before passing control to the application via solo5_app_main().
*
* Returns the first usable memory address for application heap in (*start)
* and the size of the heap in (*size).
*/
static int mem_locked = 0;
void mem_lock_heap(uintptr_t *start, size_t *size)
{
assert(!mem_locked);

mem_locked = 1;
*start = heap_start;
*size = platform_mem_size() - heap_start;
}

void mem_init(void)
{
extern char _stext[], _etext[], _erodata[], _end[];
uint32_t mem_size;

mem_size = platform_mem_size();
heap_start = ((uint32_t)&_end + PAGE_SIZE - 1) & PAGE_MASK;

/*
* Cowardly refuse to run with less than 512KB of free memory.
*/
if (heap_start + 0x80000 > mem_size)
PANIC("Not enough memory", NULL);

log(INFO, "Solo5: Memory map: %lu MB addressable:\n",
(unsigned long)mem_size >> 20);
log(INFO, "Solo5: reserved @ (0x0 - 0x%lx)\n",
(unsigned long)_stext-1);
log(INFO, "Solo5: text @ (0x%lx - 0x%lx)\n",
(unsigned long)_stext, (unsigned long)_etext-1);
log(INFO, "Solo5: rodata @ (0x%lx - 0x%lx)\n",
(unsigned long)_etext, (unsigned long)_erodata-1);
log(INFO, "Solo5: data @ (0x%lx - 0x%lx)\n",
(unsigned long)_erodata, (unsigned long)_end-1);
log(INFO, "Solo5: heap >= 0x%lx < stack < 0x%lx\n",
(unsigned long)heap_start, (unsigned long)mem_size);
}

/*
* Allocate pages on the heap. Should only be called on
* initialization (before solo5_app_main).
*/
void *mem_ialloc_pages(size_t num)
{
assert(!mem_locked);

uint32_t prev = heap_start;
heap_start += num << PAGE_SHIFT;
assert(heap_start < (uint32_t)&prev);

return (void *)prev;
}
File renamed without changes.
10 changes: 8 additions & 2 deletions bindings/spt/bindings.h
Original file line number Diff line number Diff line change
Expand Up @@ -35,13 +35,19 @@

long sys_read(long fd, void *buf, long size);
long sys_write(long fd, const void *buf, long size);
long sys_pread64(long fd, void *buf, long size, long pos);
long sys_pwrite64(long fd, const void *buf, long size, long pos);
long sys_pread64(long fd, void *buf, long size, solo5_off_t pos);
long sys_pwrite64(long fd, const void *buf, long size, solo5_off_t pos);

void sys_exit_group(long status) __attribute__((noreturn));

struct sys_timespec {
#if defined(__BITS_32__)
uint32_t tv_sec;
#elif defined(__BITS_64__)
uint64_t tv_sec;
#else
#error Unsupported architecture bits
#endif
long tv_nsec;
};

Expand Down
7 changes: 7 additions & 0 deletions bindings/spt/net.c
Original file line number Diff line number Diff line change
Expand Up @@ -102,8 +102,15 @@ void solo5_yield(solo5_time_t deadline, solo5_handle_set_t *ready_set)
struct sys_itimerspec it = {
.it_interval = { 0 },
.it_value = {
#if defined(__BITS_32__)
.tv_sec = (uint32_t)(deadline / 1000000000ULL),
.tv_nsec = (long)(deadline % 1000000000ULL)
#elif defined(__BITS_64__)
.tv_sec = deadline / 1000000000ULL,
.tv_nsec = deadline % 1000000000ULL
#else
#error Unsupported architecture bits
#endif
}
};
/*
Expand Down
14 changes: 13 additions & 1 deletion bindings/spt/platform.c
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,13 @@
#include "bindings.h"

static const char *cmdline;
#if defined(__BITS_32__)
static uint32_t mem_size;
#elif defined(__BITS_64__)
static uint64_t mem_size;
#else
#error Unsupported architecture bits
#endif

void platform_init(const void *arg)
{
Expand Down Expand Up @@ -52,12 +58,18 @@ int platform_puts(const char *buf, int n)
return n;
}

#if defined(__BITS_32__)
int platform_set_tls_base(uint32_t base)
#elif defined(__BITS_64__)
int platform_set_tls_base(uint64_t base)
#else
#error Unsupported architecture bits
#endif
{
#if defined(__x86_64__)
/* In x86 we need to ask the host kernel to change %fs for us. */
return sys_arch_prctl(SYS_ARCH_SET_FS, base);
#elif defined(__aarch64__)
#elif defined(__aarch64__) || defined(__arm__)
cpu_set_tls_base(base);
return 0;
#elif defined(__powerpc64__)
Expand Down
Loading