[PATCH v2 00/18] AArch64: enable first stubbed support

96 views
Skip to first unread message

Claudio Fontana

unread,
Mar 25, 2014, 5:28:44 AM3/25/14
to osv...@googlegroups.com, claudio...@huawei.com
This is v2 of the patch series that enables first stubbed support
for AArch64.

They are also available at the following repo:

https://github.com/hw-claudio/osv_aarch64.git

branch "aarch64-next"

From and including commit:
959526b00e23244e "libc: add minimal support for AArch64"

Lighly tested (successful build) on x64,
tested on AArch64 Foundation v8.

Changes since v1:

* rebased on latest master: added stubs for new functions in fs, bsd,
adapted to the many recent changes.

* acpi use in core/power.cc now uses AARCH64_PORT_STUB

* added command line parsing, stop AArch64 execution in main.

Claudio Fontana (17):
libc: add minimal support for AArch64
bsd/aarch64: improve inline assembly for atomic and endian ops
bsd: add stubs for AArch64
arch.hh: introduce arch::halt_no_interrupts
arch/aarch64: first implementation
include/api/aarch64: first implementation
debug: add debug_early functionality
drivers/console: allowing building for AArch64
include/osv/trace.hh: protect x64-specific code in ifdef
elf: ifdef x64-specific code, add AArch64 dynamic rels
fs: add minimal stubs for AArch64
include: remove unused include file
core: add AArch64 stubs for mempool and mmio.
core: add AArch64 stubs for sched.cc
loader, runtime: add stubs for AArch64
build.mk: enable first AArch64 stubbed support
aarch64: get the cmdline

Jani Kokkonen (1):
drivers: move debug-console to arch-specific dir

PORTING | 96 +++++
arch/aarch64/arch-cpu.cc | 47 +++
arch/aarch64/arch-cpu.hh | 111 ++++++
arch/aarch64/arch-setup.cc | 72 ++++
arch/aarch64/arch-setup.hh | 20 +
arch/aarch64/arch-switch.hh | 74 ++++
arch/aarch64/arch-thread-state.hh | 17 +
arch/aarch64/arch.hh | 108 ++++++
arch/aarch64/arm-clock.cc | 45 +++
arch/aarch64/arm-clock.hh | 15 +
arch/aarch64/backtrace.cc | 33 ++
arch/aarch64/bitops.h | 31 ++
arch/aarch64/boot.S | 83 +++++
arch/aarch64/debug-console.cc | 61 +++
arch/aarch64/elf-dl.S | 47 +++
arch/aarch64/entry.S | 88 +++++
arch/aarch64/exceptions.hh | 60 +++
arch/aarch64/loader.ld | 135 +++++++
arch/aarch64/macros.S | 14 +
arch/aarch64/math.cc | 16 +
arch/aarch64/preboot.S | 19 +
arch/aarch64/preboot.ld | 4 +
arch/aarch64/processor.hh | 121 ++++++
arch/aarch64/safe-ptr.hh | 31 ++
arch/aarch64/signal.cc | 71 ++++
arch/aarch64/smp.cc | 29 ++
arch/aarch64/smp.hh | 15 +
arch/aarch64/string.cc | 35 ++
arch/x64/arch.hh | 5 +
{drivers => arch/x64}/debug-console.cc | 2 +-
arch/x64/exceptions.cc | 2 +-
arch/x64/processor.hh | 2 +-
bsd/aarch64/machine/atomic.h | 76 ++--
bsd/aarch64/machine/endian.h | 2 +-
bsd/porting/mmu.cc | 8 +
build.mk | 202 ++++++----
core/debug.cc | 23 ++
core/elf.cc | 31 ++
core/mempool.cc | 16 +-
core/mmio.cc | 4 +
core/power.cc | 19 +-
core/sched.cc | 8 +
drivers/console.cc | 7 +
fs/procfs/procfs_vnops.cc | 12 +
fs/vfs/vfs_fops.cc | 13 +
include/api/aarch64/bits/TODO | 3 +
include/api/aarch64/bits/alltypes.h.sh | 3 +-
include/api/aarch64/bits/fcntl.h | 38 ++
include/api/aarch64/bits/fenv.h | 42 +++
include/api/aarch64/bits/float.h | 41 +++
include/api/aarch64/bits/ioctl.h | 198 ++++++++++
include/api/aarch64/bits/ipc.h | 20 +
include/api/aarch64/bits/mman.h | 63 ++++
include/api/aarch64/bits/setjmp.h | 1 +
include/api/aarch64/bits/shm.h | 19 +
include/api/aarch64/bits/signal.h | 71 ++++
include/api/aarch64/bits/socket.h | 22 ++
include/api/aarch64/bits/stat.h | 25 ++
include/api/aarch64/bits/statfs.h | 7 +
include/api/aarch64/bits/syscall.h | 653 +++++++++++++++++++++++++++++++++
include/api/aarch64/bits/termios.h | 160 ++++++++
include/api/x64/atomic.h | 127 -------
include/osv/debug.h | 20 +
include/osv/elf.hh | 14 +
include/osv/trace.hh | 2 +
libc/arch/aarch64/atomic.h | 38 ++
libc/arch/aarch64/setjmp/longjmp.s | 14 +
libc/arch/aarch64/setjmp/setjmp.s | 17 +
libc/{ => arch/x64}/setjmp/longjmp.s | 0
libc/{ => arch/x64}/setjmp/setjmp.s | 0
libc/build.mk | 4 +-
libc/mman.cc | 28 ++
libc/pthread.cc | 13 +
libc/shm.cc | 12 +
libc/string/memcpy.c | 10 +
loader.cc | 43 ++-
runtime.cc | 8 +-
77 files changed, 3388 insertions(+), 258 deletions(-)
create mode 100644 PORTING
create mode 100644 arch/aarch64/arch-cpu.cc
create mode 100644 arch/aarch64/arch-cpu.hh
create mode 100644 arch/aarch64/arch-setup.cc
create mode 100644 arch/aarch64/arch-setup.hh
create mode 100644 arch/aarch64/arch-switch.hh
create mode 100644 arch/aarch64/arch-thread-state.hh
create mode 100644 arch/aarch64/arch.hh
create mode 100644 arch/aarch64/arm-clock.cc
create mode 100644 arch/aarch64/arm-clock.hh
create mode 100644 arch/aarch64/backtrace.cc
create mode 100644 arch/aarch64/bitops.h
create mode 100644 arch/aarch64/boot.S
create mode 100644 arch/aarch64/debug-console.cc
create mode 100644 arch/aarch64/elf-dl.S
create mode 100644 arch/aarch64/entry.S
create mode 100644 arch/aarch64/exceptions.hh
create mode 100644 arch/aarch64/loader.ld
create mode 100644 arch/aarch64/macros.S
create mode 100644 arch/aarch64/math.cc
create mode 100644 arch/aarch64/preboot.S
create mode 100644 arch/aarch64/preboot.ld
create mode 100644 arch/aarch64/processor.hh
create mode 100644 arch/aarch64/safe-ptr.hh
create mode 100644 arch/aarch64/signal.cc
create mode 100644 arch/aarch64/smp.cc
create mode 100644 arch/aarch64/smp.hh
create mode 100644 arch/aarch64/string.cc
rename {drivers => arch/x64}/debug-console.cc (97%)
create mode 100644 include/api/aarch64/bits/TODO
create mode 100644 include/api/aarch64/bits/fcntl.h
create mode 100644 include/api/aarch64/bits/fenv.h
create mode 100644 include/api/aarch64/bits/float.h
create mode 100644 include/api/aarch64/bits/ioctl.h
create mode 100644 include/api/aarch64/bits/ipc.h
create mode 100644 include/api/aarch64/bits/mman.h
create mode 100644 include/api/aarch64/bits/setjmp.h
create mode 100644 include/api/aarch64/bits/shm.h
create mode 100644 include/api/aarch64/bits/signal.h
create mode 100644 include/api/aarch64/bits/socket.h
create mode 100644 include/api/aarch64/bits/stat.h
create mode 100644 include/api/aarch64/bits/statfs.h
create mode 100644 include/api/aarch64/bits/syscall.h
create mode 100644 include/api/aarch64/bits/termios.h
delete mode 100644 include/api/x64/atomic.h
create mode 100644 libc/arch/aarch64/atomic.h
create mode 100644 libc/arch/aarch64/setjmp/longjmp.s
create mode 100644 libc/arch/aarch64/setjmp/setjmp.s
rename libc/{ => arch/x64}/setjmp/longjmp.s (100%)
rename libc/{ => arch/x64}/setjmp/setjmp.s (100%)

--
1.8.5.3

Claudio Fontana

unread,
Mar 25, 2014, 5:28:45 AM3/25/14
to osv...@googlegroups.com, claudio...@huawei.com
From: Claudio Fontana <claudio...@huawei.com>

this contains still prototyped code, which if reached either
hangs (setjmp, longjmp), aborts (all that requires mmu::),
or implements differently (allocating with malloc instead of mmap)
This is enough libc AArch64 support for reaching the end of premain.

Signed-off-by: Claudio Fontana <claudio...@huawei.com>
---
libc/arch/aarch64/atomic.h | 38 ++++++++++++++++++++++++++++++++++++
libc/arch/aarch64/setjmp/longjmp.s | 14 +++++++++++++
libc/arch/aarch64/setjmp/setjmp.s | 17 ++++++++++++++++
libc/{ => arch/x64}/setjmp/longjmp.s | 0
libc/{ => arch/x64}/setjmp/setjmp.s | 0
libc/build.mk | 4 ++--
libc/mman.cc | 28 ++++++++++++++++++++++++++
libc/pthread.cc | 13 ++++++++++++
libc/shm.cc | 12 ++++++++++++
libc/string/memcpy.c | 10 ++++++++++
10 files changed, 134 insertions(+), 2 deletions(-)
create mode 100644 libc/arch/aarch64/atomic.h
create mode 100644 libc/arch/aarch64/setjmp/longjmp.s
create mode 100644 libc/arch/aarch64/setjmp/setjmp.s
rename libc/{ => arch/x64}/setjmp/longjmp.s (100%)
rename libc/{ => arch/x64}/setjmp/setjmp.s (100%)

diff --git a/libc/arch/aarch64/atomic.h b/libc/arch/aarch64/atomic.h
new file mode 100644
index 0000000..fd997f9
--- /dev/null
+++ b/libc/arch/aarch64/atomic.h
@@ -0,0 +1,38 @@
+/*
+ * Copyright (C) 2014 Huawei Technologies Duesseldorf GmbH
+ *
+ * This work is open source software, licensed under the terms of the
+ * BSD license as described in the LICENSE file in the top-level directory.
+ */
+
+#ifndef _INTERNAL_ATOMIC_H
+#define _INTERNAL_ATOMIC_H
+
+#include <stdint.h>
+#include <bsd/sys/cddl/compat/opensolaris/sys/types.h>
+#include <machine/atomic.h>
+
+static inline int a_ctz_64(register uint64_t x)
+{
+ register uint64_t r;
+ __asm__ __volatile__ ("rbit %0, %0; clz %1, %0" : "+r"(x), "=r"(r));
+ return r;
+}
+
+static inline int a_ctz_l(unsigned long x)
+{
+ return a_ctz_64(x);
+}
+
+static inline int a_fetch_add(volatile int *x, int v)
+{
+ return atomic_fetchadd_int((unsigned int *)x, (unsigned int)v);
+}
+
+static inline void a_crash()
+{
+ __asm__ __volatile__( "1: msr daifset, #2; wfi; b 1b; " ::: "memory");
+}
+
+
+#endif /* _INTERNAL_ATOMIC_H */
diff --git a/libc/arch/aarch64/setjmp/longjmp.s b/libc/arch/aarch64/setjmp/longjmp.s
new file mode 100644
index 0000000..cf73028
--- /dev/null
+++ b/libc/arch/aarch64/setjmp/longjmp.s
@@ -0,0 +1,14 @@
+/* Copyright 2014 Huawei Technologies Duesseldorf GmbH
+ *
+ * This work is open source software, licensed under the terms of the
+ * BSD license as described in the LICENSE file in the top-level directory.
+ */
+
+.global _longjmp
+.global longjmp
+.type _longjmp,@function
+.type longjmp,@function
+_longjmp:
+longjmp:
+ wfi
+ b longjmp
diff --git a/libc/arch/aarch64/setjmp/setjmp.s b/libc/arch/aarch64/setjmp/setjmp.s
new file mode 100644
index 0000000..654ecb2
--- /dev/null
+++ b/libc/arch/aarch64/setjmp/setjmp.s
@@ -0,0 +1,17 @@
+/* Copyright 2014 Huawei Technologies Duesseldorf GmbH
+ *
+ * This work is open source software, licensed under the terms of the
+ * BSD license as described in the LICENSE file in the top-level directory.
+ */
+
+.global __setjmp
+.global _setjmp
+.global setjmp
+.type __setjmp,@function
+.type _setjmp,@function
+.type setjmp,@function
+__setjmp:
+_setjmp:
+setjmp:
+ wfi
+ b setjmp
diff --git a/libc/setjmp/longjmp.s b/libc/arch/x64/setjmp/longjmp.s
similarity index 100%
rename from libc/setjmp/longjmp.s
rename to libc/arch/x64/setjmp/longjmp.s
diff --git a/libc/setjmp/setjmp.s b/libc/arch/x64/setjmp/setjmp.s
similarity index 100%
rename from libc/setjmp/setjmp.s
rename to libc/arch/x64/setjmp/setjmp.s
diff --git a/libc/build.mk b/libc/build.mk
index 2f6f1af..e906e4e 100644
--- a/libc/build.mk
+++ b/libc/build.mk
@@ -380,8 +380,8 @@ libc += network/if_indextoname.o
libc += prng/rand.o
libc += prng/random.o

-libc += setjmp/setjmp.o
-libc += setjmp/longjmp.o
+libc += arch/$(arch)/setjmp/setjmp.o
+libc += arch/$(arch)/setjmp/longjmp.o

libc += signal/sigrtmax.o
libc += signal/sigrtmin.o
diff --git a/libc/mman.cc b/libc/mman.cc
index 8a9eed8..59ef46d 100644
--- a/libc/mman.cc
+++ b/libc/mman.cc
@@ -57,6 +57,9 @@ unsigned libc_prot_to_perm(int prot)

int mprotect(void *addr, size_t len, int prot)
{
+#ifdef AARCH64_PORT_STUB
+ abort();
+#else /* !AARCH64_PORT_STUB */
// we don't support mprotecting() the linear map (e.g.., malloc() memory)
// because that could leave the linear map a mess.
if (reinterpret_cast<long>(addr) < 0) {
@@ -70,10 +73,14 @@ int mprotect(void *addr, size_t len, int prot)
}

return mmu::mprotect(addr, len, libc_prot_to_perm(prot)).to_libc();
+#endif /* !AARCH64_PORT_STUB */
}

int mmap_validate(void *addr, size_t length, int flags, off_t offset)
{
+#ifdef AARCH64_PORT_STUB
+ abort();
+#else /* !AARCH64_PORT_STUB */
int type = flags & (MAP_SHARED|MAP_PRIVATE);
// Either MAP_SHARED or MAP_PRIVATE must be set, but not both.
if (!type || type == (MAP_SHARED|MAP_PRIVATE)) {
@@ -84,11 +91,15 @@ int mmap_validate(void *addr, size_t length, int flags, off_t offset)
return EINVAL;
}
return 0;
+#endif /* !AARCH64_PORT_STUB */
}

void *mmap(void *addr, size_t length, int prot, int flags,
int fd, off_t offset)
{
+#ifdef AARCH64_PORT_STUB
+ abort();
+#else /* !AARCH64_PORT_STUB */
trace_memory_mmap(addr, length, prot, flags, fd, offset);

int err = mmap_validate(addr, length, flags, offset);
@@ -125,6 +136,7 @@ void *mmap(void *addr, size_t length, int prot, int flags,
}
trace_memory_mmap_ret(ret);
return ret;
+#endif /* !AARCH64_PORT_STUB */
}

extern "C" void *mmap64(void *addr, size_t length, int prot, int flags,
@@ -134,14 +146,21 @@ extern "C" void *mmap64(void *addr, size_t length, int prot, int flags,

int munmap_validate(void *addr, size_t length)
{
+#ifdef AARCH64_PORT_STUB
+ abort();
+#else /* !AARCH64_PORT_STUB */
if (!mmu::is_page_aligned(addr) || length == 0) {
return EINVAL;
}
return 0;
+#endif /* !AARCH64_PORT_STUB */
}

int munmap(void *addr, size_t length)
{
+#ifdef AARCH64_PORT_STUB
+ abort();
+#else /* !AARCH64_PORT_STUB */
trace_memory_munmap(addr, length);
int error = munmap_validate(addr, length);
if (error) {
@@ -155,18 +174,27 @@ int munmap(void *addr, size_t length)
}
trace_memory_munmap_ret();
return ret;
+#endif /* !AARCH64_PORT_STUB */
}

int msync(void *addr, size_t length, int flags)
{
+#ifdef AARCH64_PORT_STUB
+ abort();
+#else /* !AARCH64_PORT_STUB */
return mmu::msync(addr, length, flags).to_libc();
+#endif /* !AARCH64_PORT_STUB */
}

int mincore(void *addr, size_t length, unsigned char *vec)
{
+#ifdef AARCH64_PORT_STUB
+ abort();
+#else /* !AARCH64_PORT_STUB */
if (!mmu::is_page_aligned(addr)) {
return libc_error(EINVAL);
}

return mmu::mincore(addr, length, vec).to_libc();
+#endif /* !AARCH64_PORT_STUB */
}
diff --git a/libc/pthread.cc b/libc/pthread.cc
index 4e594b2..abfdabb 100644
--- a/libc/pthread.cc
+++ b/libc/pthread.cc
@@ -14,7 +14,11 @@
#include <algorithm>
#include <string.h>
#include <list>
+
+#ifndef AARCH64_PORT_STUB
#include <osv/mmu.hh>
+#endif /* !AARCH64_PORT_STUB */
+
#include <osv/debug.hh>
#include <osv/prio.hh>

@@ -90,8 +94,13 @@ namespace pthread_private {
return {attr.stack_begin, attr.stack_size};
}
size_t size = attr.stack_size;
+#ifdef AARCH64_PORT_STUB
+ size = (size + (0xfff)) & (~0xfffull);
+ void *addr = malloc(size);
+#else /* !AARCH64_PORT_STUB */
void *addr = mmu::map_anon(nullptr, size, mmu::mmap_populate, mmu::perm_rw);
mmu::mprotect(addr, attr.guard_size, 0);
+#endif /* !AARCH64_PORT_STUB */
sched::thread::stack_info si{addr, size};
si.deleter = free_stack;
return si;
@@ -99,7 +108,11 @@ namespace pthread_private {

void pthread::free_stack(sched::thread::stack_info si)
{
+#ifdef AARCH64_PORT_STUB
+ free(si.begin);
+#else /* !AARCH64_PORT_STUB */
mmu::munmap(si.begin, si.size);
+#endif /* !AARCH64_PORT_STUB */
}

int pthread::join(void** retval)
diff --git a/libc/shm.cc b/libc/shm.cc
index a3c6855..c9cdc5b 100644
--- a/libc/shm.cc
+++ b/libc/shm.cc
@@ -23,6 +23,9 @@ static std::unordered_map<const void*, int> shmmap;

void *shmat(int shmid, const void *shmaddr, int shmflg)
{
+#ifdef AARCH64_PORT_STUB
+ abort();
+#else /* !AARCH64_PORT_STUB */
fileref f(fileref_from_fd(shmid));
void *addr;
try {
@@ -36,6 +39,7 @@ void *shmat(int shmid, const void *shmaddr, int shmflg)
shmmap.emplace(addr, shmid);
}
return addr;
+#endif /* !AARCH64_PORT_STUB */
}

int shmctl(int shmid, int cmd, struct shmid_ds *buf)
@@ -49,6 +53,9 @@ int shmctl(int shmid, int cmd, struct shmid_ds *buf)

int shmdt(const void *shmaddr)
{
+#ifdef AARCH64_PORT_STUB
+ abort();
+#else /* !AARCH64_PORT_STUB */
int fd;
WITH_LOCK(shm_lock) {
auto s = shmmap.find(shmaddr);
@@ -61,6 +68,7 @@ int shmdt(const void *shmaddr)
fileref f(fileref_from_fd(fd));
mmu::munmap(shmaddr, ::size(f));
return 0;
+#endif /* !AARCH64_PORT_STUB */
}

/*
@@ -69,6 +77,9 @@ int shmdt(const void *shmaddr)
*/
int shmget(key_t key, size_t size, int shmflg)
{
+#ifdef AARCH64_PORT_STUB
+ abort();
+#else
int fd;
int flags = FREAD | FWRITE;
size = align_up(size, mmu::page_size);
@@ -96,4 +107,5 @@ int shmget(key_t key, size_t size, int shmflg)
return libc_error(error);
}
return fd;
+#endif /* !AARCH64_PORT_STUB */
}
diff --git a/libc/string/memcpy.c b/libc/string/memcpy.c
index 2316215..49ea8fe 100644
--- a/libc/string/memcpy.c
+++ b/libc/string/memcpy.c
@@ -27,3 +27,13 @@ misaligned:
}
return dest;
}
+
+void *memcpy_base_backwards(void *__restrict dest, const void *__restrict src, size_t n)
+{
+ unsigned char *d = dest + n - 1;
+ const unsigned char *s = src + n - 1;
+
+ for (; n; n--) *d-- = *s--;
+
+ return dest;
+}
--
1.8.5.3

Claudio Fontana

unread,
Mar 25, 2014, 5:28:46 AM3/25/14
to osv...@googlegroups.com, claudio...@huawei.com
From: Claudio Fontana <claudio...@huawei.com>

use %wn when referring to the non-extended register n,
and %n when referring to the extended register n,
emit the right memory barrier instructions, get the
semantics of atomic_store_rel hopefully right.

Signed-off-by: Claudio Fontana <claudio...@huawei.com>
---
bsd/aarch64/machine/atomic.h | 76 ++++++++++++++++++++------------------------
bsd/aarch64/machine/endian.h | 2 +-
2 files changed, 35 insertions(+), 43 deletions(-)

diff --git a/bsd/aarch64/machine/atomic.h b/bsd/aarch64/machine/atomic.h
index 8e34736..493da4a 100644
--- a/bsd/aarch64/machine/atomic.h
+++ b/bsd/aarch64/machine/atomic.h
@@ -34,9 +34,9 @@
#endif
#endif

-#define mb() __asm __volatile("dsb SY;" : : : "memory")
-#define wmb() __asm __volatile("dsb SY;" : : : "memory")
-#define rmb() __asm __volatile("dsb SY;" : : : "memory")
+#define mb() __asm __volatile("dmb ISH;" : : : "memory")
+#define wmb() __asm __volatile("dmb ISHST;" : : : "memory")
+#define rmb() __asm __volatile("dmb ISHLD;" : : : "memory")

/*
* Various simple operations on memory, each of which is atomic in the
@@ -81,52 +81,52 @@ void atomic_##NAME##_barr_##TYPE(volatile u_##TYPE *p, u_##TYPE v)
int atomic_cmpset_int(volatile u_int *dst, u_int expect, u_int src);
int atomic_cmpset_long(volatile u_long *dst, u_long expect, u_long src);

-static __inline u_int atomic_fetchadd_int(volatile u_int *p, register u_int val)
+static __inline u_int atomic_fetchadd_int(volatile u_int *p, u_int val)
{
- register u_int result asm ("w0");
- __asm __volatile("1: ldaxr %0, %1 ; "
- " add %2, %2, %0 ; "
- " stlxr w3, %2, %1 ; "
- " cbnz w3, 1b ; "
- : "=r"(result), "+Q"(p), "+r"(val)
+ u_int result;
+ u_int status;
+ __asm __volatile("1: ldaxr %w0, %1 ; "
+ " add %w2, %w2, %w0 ; "
+ " stlxr %w3, %w2, %1 ; "
+ " cbnz %w3, 1b ; "
+ : "=r"(result), "+Q"(*p), "+r"(val), "+r"(status)
:
- : "memory", "cc", "x3");
+ : "cc");
return result;
}

-static __inline u_long atomic_fetchadd_long(volatile u_long *p, register u_long val)
+static __inline u_long atomic_fetchadd_long(volatile u_long *p, u_long val)
{
- register u_long result asm ("x0");
+ u_long result;
+ u_int status;
__asm __volatile("1: ldaxr %0, %1 ; "
" add %2, %2, %0 ; "
- " stlxr w3, %2, %1 ; "
- " cbnz w3, 1b ; "
- : "=r"(result), "+Q"(p), "+r"(val)
+ " stlxr %w3, %2, %1 ; "
+ " cbnz %w3, 1b ; "
+ : "=r"(result), "+Q"(*p), "+r"(val), "+r"(status)
:
- : "memory", "cc", "x3");
+ : "cc");
return result;
}

-static __inline void atomic_store_rel_int(volatile u_int *p, register u_int val)
+static __inline void atomic_store_rel_int(volatile u_int *p, u_int val)
{
- register u_int old;
- __asm __volatile("1: ldaxr %0, %1 ; "
- " stlxr w3, %2, %1 ; "
- " cbnz w3, 1b ; "
- : "=r"(old), "+Q"(p)
+ u_int status;
+ __asm __volatile("1: stxr %w1, %w2, %0 ; "
+ " cbnz %w1, 1b ; "
+ : "+Q"(*p), "+r"(status)
: "r"(val)
- : "memory", "cc", "x3");
+ : "cc");
}

-static __inline void atomic_store_rel_long(volatile u_long *p, register u_long val)
+static __inline void atomic_store_rel_long(volatile u_long *p, u_long val)
{
- register u_long old;
- __asm __volatile("1: ldaxr %0, %1 ; "
- " stlxr w3, %2, %1 ; "
- " cbnz w3, 1b ; "
- : "=r"(old), "+Q"(p)
+ u_int status;
+ __asm __volatile("1: stxr %w1, %2, %0 ; "
+ " cbnz %w1, 1b ; "
+ : "+Q"(*p), "+r"(status)
: "r"(val)
- : "memory", "cc", "x3");
+ : "cc");
}

static __inline void atomic_add_int(volatile u_int *p, u_int val)
@@ -149,22 +149,14 @@ static __inline void atomic_add_barr_long(volatile u_long *p, u_long val)
(void)atomic_fetchadd_long(p, val);
}

-static __inline void atomic_subtract_int(volatile u_int *p, register u_int val)
+static __inline void atomic_subtract_int(volatile u_int *p, u_int val)
{
- __asm __volatile("neg %0, %0"
- : "+r"(val)
- :
- :);
- (void)atomic_fetchadd_int(p, val);
+ (void)atomic_fetchadd_int(p, -val);
}

static __inline void atomic_subtract_long(volatile u_long *p, u_long val)
{
- __asm __volatile("neg %0, %0"
- : "+r"(val)
- :
- :);
- (void)atomic_fetchadd_long(p, val);
+ (void)atomic_fetchadd_long(p, -val);
}

#define ATOMIC_LOAD(TYPE, LOP) \
diff --git a/bsd/aarch64/machine/endian.h b/bsd/aarch64/machine/endian.h
index 1f84f71..5f84d00 100644
--- a/bsd/aarch64/machine/endian.h
+++ b/bsd/aarch64/machine/endian.h
@@ -71,7 +71,7 @@ static __inline __uint32_t
__bswap32_var(__uint32_t _x)
{

- __asm ("REV %0" : "+r" (_x));
+ __asm ("REV %w0" : "+r" (_x));
return (_x);
}

--
1.8.5.3

Claudio Fontana

unread,
Mar 25, 2014, 5:28:47 AM3/25/14
to osv...@googlegroups.com, claudio...@huawei.com
From: Claudio Fontana <claudio...@huawei.com>

virt_to_phys just returns the virtual address again
for AArch64 for now, while mmu_unmap will abort.

Signed-off-by: Claudio Fontana <claudio...@huawei.com>
---
bsd/porting/mmu.cc | 8 ++++++++
1 file changed, 8 insertions(+)

diff --git a/bsd/porting/mmu.cc b/bsd/porting/mmu.cc
index 301561f..11ad464 100644
--- a/bsd/porting/mmu.cc
+++ b/bsd/porting/mmu.cc
@@ -19,7 +19,11 @@ void *pmap_mapdev(uint64_t paddr, size_t size)

uint64_t virt_to_phys(void *virt)
{
+#ifdef AARCH64_PORT_STUB
+ return (uint64_t)virt;
+#else /* !AARCH64_PORT_STUB */
return mmu::virt_to_phys(virt);
+#endif /* !AARCH64_PORT_STUB */
}

/*
@@ -37,5 +41,9 @@ int vm_paging_needed(void)

void mmu_unmap(void *addr, size_t size)
{
+#ifdef AARCH64_PORT_STUB
+ abort();
+#else
mmu::unmap_address(addr, size);
+#endif /* !AARCH64_PORT_STUB */
}
--
1.8.5.3

Claudio Fontana

unread,
Mar 25, 2014, 5:28:48 AM3/25/14
to osv...@googlegroups.com, claudio...@huawei.com
From: Claudio Fontana <claudio...@huawei.com>

rename processor::halt_no_interrupts to cli_hlt, which
logically matches existing processor::sti_hlt.

Make use of arch::halt_no_interrupts in core/power.cc,
enclose x64-specific code in ifdefs, as well as putting
code on AArch64.

Signed-off-by: Claudio Fontana <claudio...@huawei.com>
---
arch/x64/arch.hh | 5 +++++
arch/x64/exceptions.cc | 2 +-
arch/x64/processor.hh | 2 +-
core/power.cc | 19 ++++++++++++++++---
4 files changed, 23 insertions(+), 5 deletions(-)

diff --git a/arch/x64/arch.hh b/arch/x64/arch.hh
index ccbd887..9f4a59d 100644
--- a/arch/x64/arch.hh
+++ b/arch/x64/arch.hh
@@ -41,6 +41,11 @@ inline void wait_for_interrupt()
processor::sti_hlt();
}

+inline void halt_no_interrupts()
+{
+ processor::cli_hlt();
+}
+
class irq_flag {
public:
// need to clear the red zone when playing with the stack. also, can't
diff --git a/arch/x64/exceptions.cc b/arch/x64/exceptions.cc
index bd62d23..48d3ac5 100644
--- a/arch/x64/exceptions.cc
+++ b/arch/x64/exceptions.cc
@@ -263,7 +263,7 @@ void divide_error(exception_frame *ef)
extern "C" void nmi(exception_frame* ef)
{
while (true) {
- processor::halt_no_interrupts();
+ processor::cli_hlt();
}
}

diff --git a/arch/x64/processor.hh b/arch/x64/processor.hh
index a07e6bb..02cc177 100644
--- a/arch/x64/processor.hh
+++ b/arch/x64/processor.hh
@@ -237,7 +237,7 @@ inline void wrfsbase(u64 data)
asm volatile("wrfsbase %0" : : "r"(data));
}

-inline void halt_no_interrupts() {
+inline void cli_hlt() {
asm volatile ("cli; hlt" : : : "memory");
}

diff --git a/core/power.cc b/core/power.cc
index 7874ec1..6015968 100644
--- a/core/power.cc
+++ b/core/power.cc
@@ -9,10 +9,13 @@
#include <osv/debug.hh>
#include <smp.hh>
#include <processor.hh>
+#include <arch.hh>

+#ifndef AARCH64_PORT_STUB
extern "C" {
#include "acpi.h"
}
+#endif /* !AARCH64_PORT_STUB */

namespace osv {

@@ -23,13 +26,18 @@ namespace osv {

void halt(void)
{
+#ifndef AARCH64_PORT_STUB
crash_other_processors();
- while (true)
- processor::halt_no_interrupts();
+#endif /* !AARCH64_PORT_STUB */
+
+ while (true) {
+ arch::halt_no_interrupts();
+ }
}

void poweroff(void)
{
+#ifndef AARCH64_PORT_STUB
ACPI_STATUS status = AcpiEnterSleepStatePrep(ACPI_STATE_S5);
if (ACPI_FAILURE(status)) {
debug("AcpiEnterSleepStatePrep failed: %s\n", AcpiFormatException(status));
@@ -40,7 +48,9 @@ void poweroff(void)
debug("AcpiEnterSleepState failed: %s\n", AcpiFormatException(status));
halt();
}
- // We shouldn't get here.
+#endif /* !AARCH64_PORT_STUB */
+
+ // We shouldn't get here on x86.
halt();
}

@@ -48,10 +58,13 @@ void poweroff(void)
// some reson fails.
void reboot(void)
{
+#ifdef __x86_64__
// It would be nice if AcpiReset() worked, but it doesn't seem to work
// (on qemu & kvm), so let's resort to brute force...
processor::outb(1, 0x92);
debug("osv::reboot() did not work :(\n");
+#endif /* __x86_64__ */
+ halt();
}


--
1.8.5.3

Claudio Fontana

unread,
Mar 25, 2014, 5:28:49 AM3/25/14
to osv...@googlegroups.com, claudio...@huawei.com
From: Claudio Fontana <claudio...@huawei.com>

Signed-off-by: Claudio Fontana <claudio...@huawei.com>
---
arch/aarch64/arch-cpu.cc | 47 ++++++++++++++
arch/aarch64/arch-cpu.hh | 111 +++++++++++++++++++++++++++++++
arch/aarch64/arch-setup.cc | 47 ++++++++++++++
arch/aarch64/arch-setup.hh | 20 ++++++
arch/aarch64/arch-switch.hh | 74 +++++++++++++++++++++
arch/aarch64/arch-thread-state.hh | 17 +++++
arch/aarch64/arch.hh | 108 +++++++++++++++++++++++++++++++
arch/aarch64/arm-clock.cc | 45 +++++++++++++
arch/aarch64/arm-clock.hh | 15 +++++
arch/aarch64/backtrace.cc | 33 ++++++++++
arch/aarch64/bitops.h | 31 +++++++++
arch/aarch64/boot.S | 81 +++++++++++++++++++++++
arch/aarch64/elf-dl.S | 47 ++++++++++++++
arch/aarch64/entry.S | 88 +++++++++++++++++++++++++
arch/aarch64/exceptions.hh | 60 +++++++++++++++++
arch/aarch64/loader.ld | 133 ++++++++++++++++++++++++++++++++++++++
arch/aarch64/macros.S | 14 ++++
arch/aarch64/math.cc | 16 +++++
arch/aarch64/preboot.S | 19 ++++++
arch/aarch64/preboot.ld | 4 ++
arch/aarch64/processor.hh | 121 ++++++++++++++++++++++++++++++++++
arch/aarch64/safe-ptr.hh | 31 +++++++++
arch/aarch64/signal.cc | 71 ++++++++++++++++++++
arch/aarch64/smp.cc | 29 +++++++++
arch/aarch64/smp.hh | 15 +++++
arch/aarch64/string.cc | 35 ++++++++++
26 files changed, 1312 insertions(+)
create mode 100644 arch/aarch64/arch-cpu.cc
create mode 100644 arch/aarch64/arch-cpu.hh
create mode 100644 arch/aarch64/arch-setup.cc
create mode 100644 arch/aarch64/arch-setup.hh
create mode 100644 arch/aarch64/arch-switch.hh
create mode 100644 arch/aarch64/arch-thread-state.hh
create mode 100644 arch/aarch64/arch.hh
create mode 100644 arch/aarch64/arm-clock.cc
create mode 100644 arch/aarch64/arm-clock.hh
create mode 100644 arch/aarch64/backtrace.cc
create mode 100644 arch/aarch64/bitops.h
create mode 100644 arch/aarch64/boot.S
create mode 100644 arch/aarch64/elf-dl.S
create mode 100644 arch/aarch64/entry.S
create mode 100644 arch/aarch64/exceptions.hh
create mode 100644 arch/aarch64/loader.ld
create mode 100644 arch/aarch64/macros.S
create mode 100644 arch/aarch64/math.cc
create mode 100644 arch/aarch64/preboot.S
create mode 100644 arch/aarch64/preboot.ld
create mode 100644 arch/aarch64/processor.hh
create mode 100644 arch/aarch64/safe-ptr.hh
create mode 100644 arch/aarch64/signal.cc
create mode 100644 arch/aarch64/smp.cc
create mode 100644 arch/aarch64/smp.hh
create mode 100644 arch/aarch64/string.cc

diff --git a/arch/aarch64/arch-cpu.cc b/arch/aarch64/arch-cpu.cc
new file mode 100644
index 0000000..0144071
--- /dev/null
+++ b/arch/aarch64/arch-cpu.cc
@@ -0,0 +1,47 @@
+/*
+ * Copyright (C) 2013 Cloudius Systems, Ltd.
+ *
+ * Copyright (C) 2014 Huawei Technologies Duesseldorf GmbH
+ *
+ * This work is open source software, licensed under the terms of the
+ * BSD license as described in the LICENSE file in the top-level directory.
+ */
+
+#include "arch-cpu.hh"
+#include <osv/sched.hh>
+#include <osv/debug.hh>
+
+namespace sched {
+
+__thread unsigned exception_depth = 0;
+
+inline void arch_cpu::enter_exception()
+{
+ if (exception_depth == nr_exception_stacks - 1) {
+ abort("exception nested too deeply");
+ }
+ auto& s = percpu_exception_stack[exception_depth++];
+ set_exception_stack(s, sizeof(s));
+}
+
+inline void arch_cpu::exit_exception()
+{
+ if (--exception_depth == 0) {
+ set_exception_stack(&thread::current()->_arch);
+ } else {
+ auto& s = percpu_exception_stack[exception_depth];
+ set_exception_stack(s, sizeof(s));
+ }
+}
+
+exception_guard::exception_guard()
+{
+ sched::cpu::current()->arch.enter_exception();
+}
+
+exception_guard::~exception_guard()
+{
+ sched::cpu::current()->arch.exit_exception();
+}
+
+}
diff --git a/arch/aarch64/arch-cpu.hh b/arch/aarch64/arch-cpu.hh
new file mode 100644
index 0000000..33e1838
--- /dev/null
+++ b/arch/aarch64/arch-cpu.hh
@@ -0,0 +1,111 @@
+/*
+ * Copyright (C) 2013 Cloudius Systems, Ltd.
+ *
+ * Copyright (C) 2014 Huawei Technologies Duesseldorf GmbH
+ *
+ * This work is open source software, licensed under the terms of the
+ * BSD license as described in the LICENSE file in the top-level directory.
+ */
+
+#ifndef ARCH_CPU_HH_
+#define ARCH_CPU_HH_
+
+#include "processor.hh"
+#include "osv/pagealloc.hh"
+#include <osv/debug.h>
+
+struct init_stack {
+ char stack[4096] __attribute__((aligned(4096)));
+ init_stack* next;
+} __attribute__((packed));
+
+namespace sched {
+
+struct arch_cpu;
+struct arch_thread;
+
+struct arch_cpu {
+ arch_cpu();
+
+ init_stack initstack;
+ // The per-CPU exception stack is used for nested exceptions.
+ static constexpr unsigned nr_exception_stacks = 2;
+ char percpu_exception_stack[nr_exception_stacks][4096] __attribute__((aligned(16)));
+ unsigned int gic_id;
+
+ void init_on_cpu();
+ void set_ist_entry(unsigned ist, char* base, size_t size);
+ void set_exception_stack(char* base, size_t size);
+ void set_exception_stack(arch_thread* t);
+ void set_interrupt_stack(arch_thread* t);
+ void enter_exception();
+ void exit_exception();
+};
+
+struct arch_thread {
+ char interrupt_stack[4096] __attribute__((aligned(16)));
+ char exception_stack[4096] __attribute__((aligned(16)));
+};
+
+template <class T>
+struct save_fpu {
+ T state;
+ typedef processor::fpu_state fpu_state;
+ void save() { processor::fpu_state_save(state.addr()); }
+ void restore() { processor::fpu_state_load(state.addr()); }
+};
+
+struct fpu_state_alloc_page {
+ processor::fpu_state* s =
+ static_cast<processor::fpu_state*>(memory::alloc_page());
+ processor::fpu_state *addr(){ return s; }
+ ~fpu_state_alloc_page(){ memory::free_page(s); }
+};
+
+struct fpu_state_inplace {
+ processor::fpu_state s;
+ processor::fpu_state *addr() { return &s; }
+} __attribute__((aligned(16)));
+
+typedef save_fpu<fpu_state_alloc_page> arch_fpu;
+typedef save_fpu<fpu_state_inplace> inplace_arch_fpu;
+
+inline arch_cpu::arch_cpu()
+{
+ // should set_exception_stack ?
+}
+
+inline void arch_cpu::set_ist_entry(unsigned ist, char* base, size_t size)
+{
+ processor::halt_no_interrupts();
+}
+
+inline void arch_cpu::set_exception_stack(char* base, size_t size)
+{
+ processor::halt_no_interrupts();
+}
+
+inline void arch_cpu::set_exception_stack(arch_thread* t)
+{
+ processor::halt_no_interrupts();
+}
+
+inline void arch_cpu::set_interrupt_stack(arch_thread* t)
+{
+ processor::halt_no_interrupts();
+}
+
+inline void arch_cpu::init_on_cpu()
+{
+ processor::halt_no_interrupts();
+}
+
+struct exception_guard {
+ exception_guard();
+ ~exception_guard();
+};
+
+}
+
+
+#endif /* ARCH_CPU_HH_ */
diff --git a/arch/aarch64/arch-setup.cc b/arch/aarch64/arch-setup.cc
new file mode 100644
index 0000000..d72d421
--- /dev/null
+++ b/arch/aarch64/arch-setup.cc
@@ -0,0 +1,47 @@
+/*
+ * Copyright (C) 2013 Cloudius Systems, Ltd.
+ *
+ * Copyright (C) 2014 Huawei Technologies Duesseldorf GmbH
+ *
+ * This work is open source software, licensed under the terms of the
+ * BSD license as described in the LICENSE file in the top-level directory.
+ */
+
+#include "arch.hh"
+#include "arch-setup.hh"
+#include <osv/sched.hh>
+#include <osv/mempool.hh>
+#include <osv/elf.hh>
+#include <osv/types.h>
+#include <string.h>
+#include <osv/boot.hh>
+#include <osv/debug.hh>
+
+extern elf::Elf64_Ehdr* elf_header;
+extern size_t elf_size;
+extern void* elf_start;
+extern boot_time_chart boot_time;
+
+void arch_setup_free_memory()
+{
+ register u64 edata;
+ asm ("adrp %0, .edata" : "=r"(edata));
+
+ elf_start = reinterpret_cast<void*>(elf_header);
+ elf_size = (u64)edata - (u64)elf_start;
+
+ /* just a test for now, we hardcode 512MB of memory */
+ u64 addr = (u64)elf_start + elf_size + 0x10000;
+ addr = addr & ~0xffffull;
+
+ memory::free_initial_memory_range((void*)addr, 0x20000000);
+}
+
+void arch_setup_tls(thread_control_block *tcb)
+{
+ asm volatile ("msr tpidr_el0, %0; isb; " :: "r"(tcb));
+}
+
+void arch_init_premain()
+{
+}
diff --git a/arch/aarch64/arch-setup.hh b/arch/aarch64/arch-setup.hh
new file mode 100644
index 0000000..9aa3d06
--- /dev/null
+++ b/arch/aarch64/arch-setup.hh
@@ -0,0 +1,20 @@
+/*
+ * Copyright (C) 2013 Cloudius Systems, Ltd.
+ *
+ * Copyright (C) 2014 Huawei Technologies Duesseldorf GmbH
+ *
+ * This work is open source software, licensed under the terms of the
+ * BSD license as described in the LICENSE file in the top-level directory.
+ */
+
+#ifndef ARCH_SETUP_HH_
+#define ARCH_SETUP_HH_
+
+#include <osv/tls.hh>
+
+void arch_init_premain();
+void arch_setup_tls(thread_control_block *tcb);
+
+void arch_setup_free_memory();
+
+#endif /* ARCH_SETUP_HH_ */
diff --git a/arch/aarch64/arch-switch.hh b/arch/aarch64/arch-switch.hh
new file mode 100644
index 0000000..763534f
--- /dev/null
+++ b/arch/aarch64/arch-switch.hh
@@ -0,0 +1,74 @@
+/*
+ * Copyright (C) 2013 Cloudius Systems, Ltd.
+ *
+ * Copyright (C) 2014 Huawei Technologies Duesseldorf GmbH
+ *
+ * This work is open source software, licensed under the terms of the
+ * BSD license as described in the LICENSE file in the top-level directory.
+ */
+
+#ifndef ARCH_SWITCH_HH_
+#define ARCH_SWITCH_HH_
+
+#include <osv/barrier.hh>
+#include <string.h>
+
+extern "C" {
+void thread_main(void);
+void thread_main_c(sched::thread* t);
+void stack_trampoline(sched::thread* t, void (*func)(sched::thread*),
+ void** stacktop);
+}
+
+namespace sched {
+
+void thread::switch_to()
+{
+ abort();
+}
+
+void thread::switch_to_first()
+{
+ abort();
+}
+
+void thread::init_stack()
+{
+ auto& stack = _attr._stack;
+ if (!stack.size) {
+ stack.size = 65536;
+ }
+ if (!stack.begin) {
+ stack.begin = malloc(stack.size);
+ stack.deleter = stack.default_deleter;
+ }
+ void** stacktop = reinterpret_cast<void**>(stack.begin + stack.size);
+ _state.fp = this;
+ _state.pc = reinterpret_cast<void*>(thread_main);
+ _state.sp = stacktop;
+}
+
+void thread::setup_tcb()
+{
+ assert(tls.size);
+
+ void* p = malloc(sched::tls.size + sizeof(*_tcb));
+ memcpy(p, sched::tls.start, sched::tls.size);
+ _tcb = static_cast<thread_control_block*>(p + tls.size);
+ _tcb->self = _tcb;
+ _tcb->tls_base = p;
+}
+
+void thread::free_tcb()
+{
+ free(_tcb->tls_base);
+}
+
+void thread_main_c(thread* t)
+{
+ abort();
+}
+
+}
+
+#endif /* ARCH_SWITCH_HH_ */
diff --git a/arch/aarch64/arch-thread-state.hh b/arch/aarch64/arch-thread-state.hh
new file mode 100644
index 0000000..bc592b6
--- /dev/null
+++ b/arch/aarch64/arch-thread-state.hh
@@ -0,0 +1,17 @@
+/*
+ * Copyright (C) 2014 Huawei Technologies Duesseldorf GmbH
+ *
+ * This work is open source software, licensed under the terms of the
+ * BSD license as described in the LICENSE file in the top-level directory.
+ */
+
+#ifndef ARCH_THREAD_STATE_HH_
+#define ARCH_THREAD_STATE_HH_
+
+struct thread_state {
+ void* sp;
+ void* fp;
+ void* pc;
+};
+
+#endif /* ARCH_THREAD_STATE_HH_ */
diff --git a/arch/aarch64/arch.hh b/arch/aarch64/arch.hh
new file mode 100644
index 0000000..c1d737b
--- /dev/null
+++ b/arch/aarch64/arch.hh
@@ -0,0 +1,108 @@
+/*
+ * Copyright (C) 2013 Cloudius Systems, Ltd.
+ *
+ * Copyright (C) 2014 Huawei Technologies Duesseldorf GmbH
+ *
+ * This work is open source software, licensed under the terms of the
+ * BSD license as described in the LICENSE file in the top-level directory.
+ */
+
+#ifndef ARCH_HH_
+#define ARCH_HH_
+
+#include "processor.hh"
+
+// architecture independent interface for architecture dependent operations
+
+namespace arch {
+
+#define CACHELINE_ALIGNED __attribute__((aligned(64)))
+
+inline void irq_disable()
+{
+ processor::irq_disable();
+}
+
+__attribute__((no_instrument_function))
+inline void irq_disable_notrace();
+
+inline void irq_disable_notrace()
+{
+ processor::irq_disable_notrace();
+}
+
+inline void irq_enable()
+{
+ processor::irq_enable();
+}
+
+inline void wait_for_interrupt()
+{
+ processor::wait_for_interrupt();
+}
+
+inline void halt_no_interrupts()
+{
+ processor::halt_no_interrupts();
+}
+
+class irq_flag {
+public:
+ void save() {
+ asm volatile("mrs x0, daif;"
+ "str w0, %0" : "=m"(daif) :: "memory", "x0");
+ }
+
+ void restore() {
+ asm volatile("ldr w0, %0;"
+ "msr daif, x0" :: "m"(daif) : "memory", "x0");
+ }
+ bool enabled() const {
+ return !(daif & processor::daif_i);
+ }
+
+private:
+ unsigned int daif;
+};
+
+class irq_flag_notrace {
+public:
+ __attribute__((no_instrument_function)) void save();
+ __attribute__((no_instrument_function)) void restore();
+ __attribute__((no_instrument_function)) bool enabled() const;
+private:
+ unsigned int daif;
+};
+
+inline void irq_flag_notrace::save() {
+ asm volatile("mrs x0, daif;"
+ "str w0, %0" : "=m"(daif) :: "memory", "x0");
+}
+
+inline void irq_flag_notrace::restore() {
+ asm volatile("ldr w0, %0;"
+ "msr daif, x0" :: "m"(daif) : "memory", "x0");
+}
+
+inline bool irq_flag_notrace::enabled() const {
+ return !(daif & processor::daif_i);
+}
+
+inline bool irq_enabled()
+{
+ irq_flag f;
+ f.save();
+ return f.enabled();
+}
+
+extern bool tls_available() __attribute__((no_instrument_function));
+
+inline bool tls_available()
+{
+ /* XXX */
+ return false;
+}
+
+} // namespace arch
+
+#endif /* ARCH_HH_ */
diff --git a/arch/aarch64/arm-clock.cc b/arch/aarch64/arm-clock.cc
new file mode 100644
index 0000000..f0ac5fe
--- /dev/null
+++ b/arch/aarch64/arm-clock.cc
@@ -0,0 +1,45 @@
+/*
+ * Copyright (C) 2014 Huawei Technologies Duesseldorf GmbH
+ *
+ * This work is open source software, licensed under the terms of the
+ * BSD license as described in the LICENSE file in the top-level directory.
+ */
+
+#include "drivers/clockevent.hh"
+#include "drivers/clock.hh"
+#include "arm-clock.hh"
+
+using namespace processor;
+
+class arm_clock_events : public clock_event_driver {
+public:
+ explicit arm_clock_events();
+ ~arm_clock_events();
+ virtual void setup_on_cpu();
+ virtual void set(std::chrono::nanoseconds nanos);
+private:
+ unsigned _vector;
+};
+
+
+arm_clock_events::arm_clock_events()
+{
+}
+
+arm_clock_events::~arm_clock_events()
+{
+}
+
+void arm_clock_events::setup_on_cpu()
+{
+}
+
+void arm_clock_events::set(std::chrono::nanoseconds nanos)
+{
+}
+
+void __attribute__((constructor)) init_arm_clock()
+{
+ debug_early_entry("init_arm_clock()");
+ clock_event = new arm_clock_events;
+}
diff --git a/arch/aarch64/arm-clock.hh b/arch/aarch64/arm-clock.hh
new file mode 100644
index 0000000..60cc5d0
--- /dev/null
+++ b/arch/aarch64/arm-clock.hh
@@ -0,0 +1,15 @@
+/*
+ * Copyright (C) 2014 Huawei Technologies Duesseldorf GmbH
+ *
+ * This work is open source software, licensed under the terms of the
+ * BSD license as described in the LICENSE file in the top-level directory.
+ */
+
+#ifndef ARCH_ARM_CLOCK_HH
+#define ARCH_ARM_CLOCK_HH
+
+namespace processor {
+}
+
+
+#endif /* ARCH_ARM_CLOCK_HH */
diff --git a/arch/aarch64/backtrace.cc b/arch/aarch64/backtrace.cc
new file mode 100644
index 0000000..4f369db
--- /dev/null
+++ b/arch/aarch64/backtrace.cc
@@ -0,0 +1,33 @@
+/*
+ * Copyright (C) 2014 Huawei Technologies Duesseldorf GmbH
+ *
+ * This work is open source software, licensed under the terms of the
+ * BSD license as described in the LICENSE file in the top-level directory.
+ */
+
+#include "safe-ptr.hh"
+#include <osv/debug.h>
+
+struct frame {
+ frame* next;
+ void* pc;
+};
+
+int backtrace_safe(void** pc, int nr)
+{
+ register frame* fp;
+ frame* next;
+
+ asm("mov %0, x29" : "=r"(fp));
+
+ int i = 0;
+ while (i < nr
+ && safe_load(&fp->next, next)
+ && safe_load(&fp->pc, pc[i])
+ && pc[i]) {
+ fp = next;
+ ++i;
+ }
+
+ return i;
+}
diff --git a/arch/aarch64/bitops.h b/arch/aarch64/bitops.h
new file mode 100644
index 0000000..0e04197
--- /dev/null
+++ b/arch/aarch64/bitops.h
@@ -0,0 +1,31 @@
+/*
+ * Copyright (C) 2014 Huawei Technologies Duesseldorf GmbH
+ *
+ * This work is open source software, licensed under the terms of the
+ * BSD license as described in the LICENSE file in the top-level directory.
+ */
+
+#ifndef ARCH_BITOPS_H_
+#define ARCH_BITOPS_H_
+static inline unsigned int
+bsrl(unsigned int mask)
+{
+ unsigned int result;
+ asm volatile("clz %1,%0" : "=r" (result) : "r" (mask));
+ return result;
+}
+
+static inline unsigned long
+bsrq(unsigned long mask)
+{
+ unsigned long result;
+ asm volatile("clz %1,%0" : "=r" (result) : "r" (mask));
+ return result;
+}
+
+static inline int
+fls(int mask)
+{
+ return (mask == 0 ? mask : (int)bsrl((unsigned int)mask) + 1);
+}
+#endif /* ARCH_BITOPS_H */
diff --git a/arch/aarch64/boot.S b/arch/aarch64/boot.S
new file mode 100644
index 0000000..0674a1f
--- /dev/null
+++ b/arch/aarch64/boot.S
@@ -0,0 +1,81 @@
+/*
+ * Copyright (C) 2014 Huawei Technologies Duesseldorf GmbH
+ *
+ * This work is open source software, licensed under the terms of the
+ * BSD license as described in the LICENSE file in the top-level directory.
+ */
+
+.text
+.align 16
+.globl start_elf
+start_elf:
+ /* elf program start address */
+ /* input: x0 = elf header address */
+ msr daifset, #2 // no interrupts for now
+ mov x2, x0 // elf_header ptr => x2
+ bl validate_el // check that we are at EL1 or die
+ ldr x0, sctrl_init /* initial value for SCTRL_EL1 */
+ msr sctlr_el1, x0
+
+ bl init_stack
+ bl zero_bss // initialize bss contents to 0
+ bl disable_monitor_debug
+ bl init_fpu // we need the FPU early on
+
+ adrp x1, elf_header // requires page alignment */
+ str x2, [x1] // store elf header address
+
+ mov x29, xzr
+ mov x30, xzr
+ bl premain
+ /*
+ adrp x2, __argc
+ ldr x0, [x2]
+ adrp x2, __argv
+ ldr x1, [x2]
+ b main
+ */
+sctrl_init:
+ .quad 0x34d5cb80
+
+init_stack:
+ adrp x0, init_stack_top
+ mov sp, x0
+ ret
+
+validate_el:
+ mrs x0, CurrentEL
+ ubfm x0, x0, #2, #3 // current EL[3:2] -> X0
+ cmp x0, #1
+ b.ne halt
+ ret
+
+halt: wfi
+ b halt
+
+zero_bss:
+ adrp x0, .bss
+ adrp x1, .edata
+zero_bss_loop:
+ stp xzr, xzr, [x0], #16
+ cmp x0, x1
+ b.lo zero_bss_loop
+ ret
+init_fpu:
+ mov x0, #3 << 20 // no trapping on FP/SIMD instructions
+ msr cpacr_el1, x0
+ ret
+disable_monitor_debug:
+ msr mdscr_el1, xzr // all disabled
+ ret
+.bss
+.align 16
+init_stack_bottom = .
+. = . + 4096*4
+init_stack_top = .
+
+/* hmm should we provide an interrupt stack?
+. = . + 4096*10
+.global interrupt_stack_top
+interrupt_stack_top = .
+*/
diff --git a/arch/aarch64/elf-dl.S b/arch/aarch64/elf-dl.S
new file mode 100644
index 0000000..9b51115
--- /dev/null
+++ b/arch/aarch64/elf-dl.S
@@ -0,0 +1,47 @@
+/*
+ * Copyright (C) 2014 Huawei Technologies Duesseldorf GmbH
+ *
+ * This work is open source software, licensed under the terms of the
+ * BSD license as described in the LICENSE file in the top-level directory.
+ */
+
+#include "macros.S"
+
+/* XXX this will halt, because it is not reached/tested.
+ When we reach this, test and verify against the ELF AArch64 ABI */
+.text
+
+.global __elf_resolve_pltgot
+
+// calling convention:
+// sp + 8: index
+// sp + 0: object
+__elf_resolve_pltgot:
+ .type __elf_resolve_pltgot, @function
+1: wfi
+ b 1b
+ sub sp, sp, #16 // make room for resolved address
+
+ push_pair x27, x28
+ push_pair x25, x26
+ push_pair x23, x24
+ push_pair x21, x22
+ push_pair x19, x20
+ push_pair x29, x30
+ mov x29, sp
+
+ ldr x0, [x29, #14 * 8]
+ ldr x1, [x29, #13 * 8]
+
+ bl elf_resolve_pltgot
+ str x0, [x29, #12 * 8]
+
+ pop_pair x29, x30
+ pop_pair x19, x20
+ pop_pair x21, x22
+ pop_pair x23, x24
+ pop_pair x25, x26
+ pop_pair x27, x28
+
+ add sp, sp, #16
+ ret
diff --git a/arch/aarch64/entry.S b/arch/aarch64/entry.S
new file mode 100644
index 0000000..aaba723
--- /dev/null
+++ b/arch/aarch64/entry.S
@@ -0,0 +1,88 @@
+/*
+ * Copyright (C) 2014 Huawei Technologies Duesseldorf GmbH
+ *
+ * This work is open source software, licensed under the terms of the
+ * BSD license as described in the LICENSE file in the top-level directory.
+ */
+
+/* XXX TODO nothing to see here, move along XXX */
+
+#include "macros.S"
+ /*
+ .macro exception_entry name, handler, has_error_code
+ push_pair x28, x29
+ push_pair x26, x27
+ push_pair x24, x25
+ push_pair x22, x23
+ push_pair x20, x21
+
+ push_pair x18, x19
+ push_pair x16, x17
+ push_pair x14, x15
+ push_pair x12, x13
+ push_pair x10, x11
+
+ push_pair x8, x9
+ push_pair x6, x7
+ push_pair x4, x5
+ push_pair x2, x3
+ push_pair x0, x1
+
+ push_pair x29, x30
+ ...
+ .endm
+
+.macro exception_error_entry name, handler
+ exception_entry \name, \handler, 1
+.endm
+
+.macro exception_noerror_entry name, handler
+ exception_entry \name, \handler, 0
+.endm
+
+.cfi_sections .eh_frame, .debug_frame
+
+.text
+
+*/
+
+.global thread_main
+thread_main:
+ .type thread_main, @function
+ mov x0, x29
+ bl thread_main_c
+
+.global call_signal_handler_thunk
+call_signal_handler_thunk:
+ .type call_signal_handler_thunk, @function
+ # stack contains a signal_frame
+ /*
+ .cfi_offset reg, offset
+ ...
+ mov x0, sp
+ call call_signal_handler
+ # FIXME: fpu
+
+ pop_pair...
+ add sp, sp, 16 # error_code
+ */
+ ret
+
+/*
+.global stack_trampoline
+stack_trampoline: # %rsi=arg, %rdi=func, %rdx=stack
+ .type stack_trampoline, @function
+ .cfi_startproc simple
+ .cfi_def_cfa %rsp, 0
+ # align the stack at 16 bytes for sse
+ andq $-16, %rdx
+ sub $8, %rdx
+ mov %rsp, -8(%rdx)
+ lea -8(%rdx), %rsp
+ .cfi_rel_offset %rsp, 0
+ call *%rsi
+ pop %rsp
+ .cfi_restore %rsp
+ ret
+ .cfi_endproc
+*/
diff --git a/arch/aarch64/exceptions.hh b/arch/aarch64/exceptions.hh
new file mode 100644
index 0000000..25f45bb
--- /dev/null
+++ b/arch/aarch64/exceptions.hh
@@ -0,0 +1,60 @@
+/*
+ * Copyright (C) 2013 Cloudius Systems, Ltd.
+ *
+ * Copyright (C) 2014 Huawei Technologies Duesseldorf GmbH
+ *
+ * This work is open source software, licensed under the terms of the
+ * BSD license as described in the LICENSE file in the top-level directory.
+ */
+
+#ifndef EXCEPTIONS_HH
+#define EXCEPTIONS_HH
+
+#include <stdint.h>
+#include <functional>
+#include <osv/types.h>
+#include <osv/rcu.hh>
+#include <osv/mutex.h>
+#include <vector>
+
+struct exception_frame {
+ u64 regs[31];
+ u64 sp;
+ u64 pc;
+ u64 pstate;
+ u64 error_code;
+ u64 reserved; /* align to 16 */
+};
+
+extern __thread exception_frame* current_interrupt_frame;
+
+struct shared_vector {
+ unsigned vector;
+ unsigned id;
+ shared_vector(unsigned v, unsigned i)
+ : vector(v), id(i)
+ {};
+};
+
+class interrupt_table {
+public:
+ interrupt_table();
+ void load_on_cpu();
+ unsigned register_handler(std::function<void ()> handler);
+ // The pre_eoi should 'true' when the interrupt is for the device, 'false' otherwise.
+ shared_vector register_level_triggered_handler(unsigned gsi, std::function<bool ()> pre_eoi, std::function<void ()> handler);
+ void unregister_level_triggered_handler(shared_vector v);
+ unsigned register_interrupt_handler(std::function<bool ()> pre_eoi, std::function<void ()> eoi, std::function<void ()> handler);
+ void unregister_handler(unsigned vector);
+ void invoke_interrupt(unsigned vector);
+};
+
+extern interrupt_table interrupt_table;
+
+extern "C" {
+ void page_fault(exception_frame* ef);
+}
+
+bool fixup_fault(exception_frame*);
+
+#endif /* EXCEPTIONS_HH */
diff --git a/arch/aarch64/loader.ld b/arch/aarch64/loader.ld
new file mode 100644
index 0000000..a027cbc
--- /dev/null
+++ b/arch/aarch64/loader.ld
@@ -0,0 +1,133 @@
+/*
+ * Copyright (C) 2013 Cloudius Systems, Ltd.
+ *
+ * Copyright (C) 2014 Huawei Technologies Duesseldorf GmbH
+ *
+ * This work is open source software, licensed under the terms of the
+ * BSD license as described in the LICENSE file in the top-level directory.
+ */
+
+SECTIONS
+{
+ /* Set the initial program counter to one page beyond the minimal
+ * aligned segment size. This allows the ELF header to reside with
+ * the text segment, which is useful since we need the ELF header
+ * to link against libraries later on.
+ *
+ * We can't export the ELF header base as a symbol, because ld
+ * insists on moving stuff around if we do.
+ */
+ . = 0x40091000;
+
+ .dynamic : ALIGN(16) { *(.dynamic) } : dynamic : text
+
+ .rela.dyn : ALIGN(4096) {
+ *(.rela.init)
+ *(.rela.text .rela.text.* .rela.gnu.linkonce.t.*)
+ *(.rela.fini)
+ *(.rela.rodata .rela.rodata.* .rela.gnu.linkonce.r.*)
+ *(.rela.data .rela.data.* .rela.gnu.linkonce.d.*)
+ *(.rela.tdata .rela.tdata.* .rela.gnu.linkonce.td.*)
+ *(.rela.tbss .rela.tbss.* .rela.gnu.linkonce.tb.*)
+ *(.rela.ctors)
+ *(.rela.dtors)
+ *(.rela.got)
+ *(.rela.bss .rela.bss.* .rela.gnu.linkonce.b.*)
+ *(.rela.ifunc)
+ } : dynamic : text
+
+ .rela.plt : ALIGN(4096) {
+ *(.rela.plt)
+ __rela_iplt_start = .;
+ *(.rela.iplt)
+ __rela_iplt_end = .;
+ } : dynamic : text
+
+ .plt : ALIGN (4096) { *(.plt) *(.iplt) } : dynamic : text
+ .got : ALIGN (4096) { *(.got) *(.igot) } : dynamic : text
+ .got.plt : ALIGN (4096) { *(.got.plt) *(.igot.plt) } : dynamic : text
+
+ .text : ALIGN (16) {
+ text_start = .;
+ *(.text.unlikely .text.*_unlikely .text.unlikely.*)
+ *(.text.exit .text.exit.*)
+ *(.text.startup .text.startup.*)
+ *(.text.hot .text.hot.*)
+ *(.text .stub .text.* .gnu.linkonce.t.*)
+ text_end = .;
+ } : text
+
+ .eh_frame : { *(.eh_frame) } : text
+ .eh_frame_hdr : { *(.eh_frame_hdr) } :text :eh_frame
+ .rodata : { *(.rodata*) } :text
+ .note : { *(.note*) } :text :note
+
+ .gcc_except_table : { *(.gcc_except_table) *(.gcc_except_table.*) } : text
+
+ .tracepoint_patch_sites : ALIGN(8) {
+ __tracepoint_patch_sites_start = .;
+ *(.tracepoint_patch_sites)
+ __tracepoint_patch_sites_end = .;
+ } : text
+
+ .data.rel.ro : { *(.data.rel.ro.local* .gnu.linkonce.d.rel.ro.local.*) *(.data.rel.ro .data.rel.ro.* .gnu.linkonce.d.rel.ro.*) } : text
+
+ .data : { *(.data .data.*) } : text
+
+ _init_array_start = .;
+ .init_array : ALIGN(16) {
+ *(SORT_BY_NAME(.preinit_array.*) .preinit_array)
+ *(SORT_BY_INIT_PRIORITY(.init_array.*) SORT_BY_INIT_PRIORITY(.ctors.*))
+ *(.init_array .ctors)
+ } : text
+ _init_array_end = .;
+
+ .percpu : ALIGN (4096) {
+ _percpu_start = .;
+ *(.percpu)
+ . = ALIGN(4096);
+ _percpu_end = .;
+ }
+ .percpu_workers : ALIGN (4096) {
+ _percpu_workers_start = .;
+ *(.percpu_workers)
+ _percpu_workers_end = .;
+ }
+
+ .tdata : ALIGN(64) { *(.tdata .tdata.* .gnu.linkonce.td.*) } : tls : text
+ .tbss : ALIGN(64) { *(.tbss .tbss.* .gnu.linkonce.tb.*) *(.tcommon) } : tls : text
+ .tls_template_size = SIZEOF(.tdata) + SIZEOF(.tbss);
+ .bss : { *(.dynbss .bss .bss.* .gnu.linkonce.b.*) } : text
+
+ . = ALIGN(64);
+ tcb0 = .;
+ . = . + .tls_template_size + 256;
+ . = ALIGN(4096);
+ .edata = .;
+
+ .debug_info 0 : { *(.debug_info .gnu.linkonce.wi.*) }
+ .debug_srcinfo 0 : { *(.debug_srcinfo) }
+ .debug_sfnames 0 : { *(.debug_sfnames) }
+ .debug_pubnames 0 : { *(.debug_pubnames) }
+ .debug_frame 0 : { *(.debug_frame) }
+ .debug_abbrev 0 : { *(.debug_abbrev) }
+ .debug_aranges 0 : { *(.debug_aranges) }
+ .debug_ranges 0 : { *(.debug_ranges) }
+ .debug_line 0 : { *(.debug_line) }
+ .debug_loc 0 : { *(.debug_loc) }
+ .debug_str 0 : { *(.debug_str) }
+ .debug_macinfo 0 : { *(.debug_macinfo) }
+ .debug_typenames 0 : { *(.debug_typenames) }
+ .debug_varnames 0 : { *(.debug_varnames) }
+ .debug_weaknames 0 : { *(.debug_weaknames) }
+ .gdb_index 0 : { *(.gdb_index) }
+ .comment : { *(.comment) }
+}
+PHDRS {
+ text PT_LOAD FILEHDR PHDRS;
+ tls PT_TLS;
+ dynamic PT_DYNAMIC;
+ eh_frame PT_GNU_EH_FRAME;
+ note PT_NOTE;
+}
+ENTRY(start_elf);
diff --git a/arch/aarch64/macros.S b/arch/aarch64/macros.S
new file mode 100644
index 0000000..8c790ca
--- /dev/null
+++ b/arch/aarch64/macros.S
@@ -0,0 +1,14 @@
+/*
+ * Copyright (C) 2014 Huawei Technologies Duesseldorf GmbH
+ *
+ * This work is open source software, licensed under the terms of the
+ * BSD license as described in the LICENSE file in the top-level directory.
+ */
+
+.macro push_pair reg1, reg2
+ stp \reg1, \reg2, [sp, #-16]!
+.endm
+
+.macro pop_pair reg1, reg2
+ ldp \reg1, \reg2, [sp], #16
+.endm
diff --git a/arch/aarch64/math.cc b/arch/aarch64/math.cc
new file mode 100644
index 0000000..908da34
--- /dev/null
+++ b/arch/aarch64/math.cc
@@ -0,0 +1,16 @@
+/*
+ * Copyright (C) 2014 Huawei Technologies Duesseldorf GmbH
+ *
+ * This work is open source software, licensed under the terms of the
+ * BSD license as described in the LICENSE file in the top-level directory.
+ */
+
+/* XXX todo XXX */
+#include <math.h>
+#include <osv/types.h>
+
+extern "C"
+int __isnan(double v)
+{
+ return false; /* XXX */
+}
diff --git a/arch/aarch64/preboot.S b/arch/aarch64/preboot.S
new file mode 100644
index 0000000..036b1fc
--- /dev/null
+++ b/arch/aarch64/preboot.S
@@ -0,0 +1,19 @@
+/*
+ * Copyright (C) 2014 Huawei Technologies Duesseldorf GmbH
+ *
+ * This work is open source software, licensed under the terms of the
+ * BSD license as described in the LICENSE file in the top-level directory.
+ */
+
+target = . + 0x10000
+elf_entry = 24 + target
+
+.text
+.align 16
+
+.globl prestart
+prestart: // x4 = 0x40080000 set by qemu bootloader
+ adr x0, target /* elf header start */
+ adr x1, elf_entry
+ ldr x2, [x1] // load entry point from ELF header
+ br x2
diff --git a/arch/aarch64/preboot.ld b/arch/aarch64/preboot.ld
new file mode 100644
index 0000000..4ddca8e
--- /dev/null
+++ b/arch/aarch64/preboot.ld
@@ -0,0 +1,4 @@
+SECTIONS
+{
+ .text : { *(.text) }
+}
diff --git a/arch/aarch64/processor.hh b/arch/aarch64/processor.hh
new file mode 100644
index 0000000..97fc128
--- /dev/null
+++ b/arch/aarch64/processor.hh
@@ -0,0 +1,121 @@
+/*
+ * Copyright (C) 2014 Huawei Technologies Duesseldorf GmbH
+ *
+ * This work is open source software, licensed under the terms of the
+ * BSD license as described in the LICENSE file in the top-level directory.
+ */
+
+#ifndef AARCH64_PROCESSOR_HH
+#define AARCH64_PROCESSOR_HH
+
+#include <osv/types.h>
+#include <osv/debug.h>
+
+namespace processor {
+
+constexpr unsigned daif_i = 1 << 7;
+
+inline void wfi()
+{
+ asm volatile ("wfi" ::: "memory");
+}
+
+inline void irq_enable()
+{
+ asm volatile ("msr daifclr, #2; isb; " ::: "memory");
+}
+
+inline void irq_disable()
+{
+ asm volatile ("msr daifset, #2; isb; " ::: "memory");
+}
+
+__attribute__((no_instrument_function))
+inline void irq_disable_notrace();
+
+inline void irq_disable_notrace()
+{
+ asm volatile ("msr daifset, #2; isb; " ::: "memory");
+}
+
+inline void wait_for_interrupt() {
+ irq_enable();
+ wfi();
+}
+
+inline void halt_no_interrupts() {
+ irq_disable();
+ while (1) {
+ wfi();
+ }
+}
+
+inline u64 ticks()
+{
+ static u64 i;
+ return ++i;
+}
+
+struct fpu_state {
+ __uint128_t vregs[32];
+ unsigned int fpsr;
+ unsigned int fpcr;
+};
+
+inline void fpu_state_save(fpu_state *s)
+{
+ debug_early_entry("fpu_state_save(s)");
+
+ asm volatile("stp q0, q1, %0" : "=Ump"(s->vregs[0]) :: "memory");
+ asm volatile("stp q2, q3, %0" : "=Ump"(s->vregs[2]) :: "memory");
+ asm volatile("stp q4, q5, %0" : "=Ump"(s->vregs[4]) :: "memory");
+ asm volatile("stp q6, q7, %0" : "=Ump"(s->vregs[6]) :: "memory");
+ asm volatile("stp q8, q9, %0" : "=Ump"(s->vregs[8]) :: "memory");
+ asm volatile("stp q10, q11, %0" : "=Ump"(s->vregs[10]) :: "memory");
+ asm volatile("stp q12, q13, %0" : "=Ump"(s->vregs[12]) :: "memory");
+ asm volatile("stp q14, q15, %0" : "=Ump"(s->vregs[14]) :: "memory");
+ asm volatile("stp q16, q17, %0" : "=Ump"(s->vregs[16]) :: "memory");
+ asm volatile("stp q18, q19, %0" : "=Ump"(s->vregs[18]) :: "memory");
+ asm volatile("stp q20, q21, %0" : "=Ump"(s->vregs[20]) :: "memory");
+ asm volatile("stp q22, q23, %0" : "=Ump"(s->vregs[22]) :: "memory");
+ asm volatile("stp q24, q25, %0" : "=Ump"(s->vregs[24]) :: "memory");
+ asm volatile("stp q26, q27, %0" : "=Ump"(s->vregs[26]) :: "memory");
+ asm volatile("stp q28, q29, %0" : "=Ump"(s->vregs[28]) :: "memory");
+ asm volatile("stp q30, q31, %0" : "=Ump"(s->vregs[30]) :: "memory");
+
+ asm volatile("mrs x0, fpsr" ::: "x0");
+ asm volatile("str w0, %0" : "=m"(s->fpsr) :: "memory");
+ asm volatile("mrs x0, fpcr" ::: "x0");
+ asm volatile("str w0, %0" : "=m"(s->fpcr) :: "memory");
+}
+
+inline void fpu_state_load(fpu_state *s)
+{
+ debug_early_entry("fpu_state_load(s)");
+
+ asm volatile("ldp q0, q1, %0" :: "Ump"(s->vregs[0]) : "q0", "q1");
+ asm volatile("ldp q2, q3, %0" :: "Ump"(s->vregs[2]) : "q2", "q3");
+ asm volatile("ldp q4, q5, %0" :: "Ump"(s->vregs[4]) : "q4", "q5");
+ asm volatile("ldp q6, q7, %0" :: "Ump"(s->vregs[6]) : "q6", "q7");
+ asm volatile("ldp q8, q9, %0" :: "Ump"(s->vregs[8]) : "q8", "q9");
+ asm volatile("ldp q10, q11, %0" :: "Ump"(s->vregs[10]) : "q10", "q11");
+ asm volatile("ldp q12, q13, %0" :: "Ump"(s->vregs[12]) : "q12", "q13");
+ asm volatile("ldp q14, q15, %0" :: "Ump"(s->vregs[14]) : "q14", "q15");
+ asm volatile("ldp q16, q17, %0" :: "Ump"(s->vregs[16]) : "q16", "q17");
+ asm volatile("ldp q18, q19, %0" :: "Ump"(s->vregs[18]) : "q18", "q19");
+ asm volatile("ldp q20, q21, %0" :: "Ump"(s->vregs[20]) : "q20", "q21");
+ asm volatile("ldp q22, q23, %0" :: "Ump"(s->vregs[22]) : "q22", "q23");
+ asm volatile("ldp q24, q25, %0" :: "Ump"(s->vregs[24]) : "q24", "q25");
+ asm volatile("ldp q26, q27, %0" :: "Ump"(s->vregs[26]) : "q26", "q27");
+ asm volatile("ldp q28, q29, %0" :: "Ump"(s->vregs[28]) : "q28", "q29");
+ asm volatile("ldp q30, q31, %0" :: "Ump"(s->vregs[30]) : "q30", "q31");
+
+ asm volatile("ldr w0, %0" :: "m"(s->fpsr) : "x0");
+ asm volatile("msr fpsr, x0" ::: "memory");
+ asm volatile("ldr w0, %0" :: "m"(s->fpcr) : "x0");
+ asm volatile("msr fpcr, x0" ::: "memory");
+}
+
+};
+
+#endif /* AARCH64_PROCESSOR_HH */
diff --git a/arch/aarch64/safe-ptr.hh b/arch/aarch64/safe-ptr.hh
new file mode 100644
index 0000000..f6026e2
--- /dev/null
+++ b/arch/aarch64/safe-ptr.hh
@@ -0,0 +1,31 @@
+/*
+ * Copyright (C) 2014 Huawei Technologies Duesseldorf GmbH
+ *
+ * This work is open source software, licensed under the terms of the
+ * BSD license as described in the LICENSE file in the top-level directory.
+ */
+
+#ifndef SAFE_PTR_HH_
+#define SAFE_PTR_HH_
+
+#include <osv/compiler.h>
+
+/* warning: not "safe" at all for now. */
+
+template <typename T>
+static inline bool
+safe_load(const T* potentially_bad_pointer, T& data)
+{
+ data = *potentially_bad_pointer;
+ return true;
+}
+
+template <typename T>
+static inline bool
+safe_store(const T* potentially_bad_pointer, const T& data)
+{
+ *potentially_bad_pointer = data;
+ return true;
+}
+
+#endif /* SAFE_PTR_HH_ */
diff --git a/arch/aarch64/signal.cc b/arch/aarch64/signal.cc
new file mode 100644
index 0000000..b7dd85e
--- /dev/null
+++ b/arch/aarch64/signal.cc
@@ -0,0 +1,71 @@
+/*
+ * Copyright (C) 2013 Cloudius Systems, Ltd.
+ *
+ * Copyright (C) 2014 Huawei Technologies Duesseldorf GmbH
+ *
+ * This work is open source software, licensed under the terms of the
+ * BSD license as described in the LICENSE file in the top-level directory.
+ */
+
+#include <osv/align.hh>
+#include "exceptions.hh"
+#include <signal.h>
+#include <stdlib.h>
+#include <arch-cpu.hh>
+#include <osv/debug.hh>
+
+namespace arch {
+
+struct signal_frame {
+ exception_frame state;
+ siginfo_t si;
+ struct sigaction sa;
+ sched::inplace_arch_fpu fpu;
+};
+
+}
+
+extern "C" {
+ void call_signal_handler(arch::signal_frame* frame);
+ void call_signal_handler_thunk(void);
+}
+
+namespace arch {
+
+void build_signal_frame(exception_frame* ef,
+ const siginfo_t& si,
+ const struct sigaction& sa)
+{
+ void* sp = reinterpret_cast<void*>(ef->sp);
+ sp -= sizeof(signal_frame);
+ sp = align_down(sp, 16);
+ signal_frame* frame = static_cast<signal_frame*>(sp);
+ frame->state = *ef;
+ frame->si = si;
+ frame->sa = sa;
+ ef->pc = reinterpret_cast<ulong>(call_signal_handler_thunk);
+ ef->sp = reinterpret_cast<ulong>(sp);
+}
+
+}
+
+unsigned __thread signal_nesting;
+
+void call_signal_handler(arch::signal_frame* frame)
+{
+ if (signal_nesting) {
+ // Note: nested signals are legal, but rarely used, so they usually
+ // indicate trouble
+ abort("nested signals");
+ }
+ ++signal_nesting;
+ frame->fpu.save();
+ if (frame->sa.sa_flags & SA_SIGINFO) {
+ /* XXX not implemented yet XXX */
+ }
+
+ frame->sa.sa_handler(frame->si.si_signo);
+ frame->fpu.restore();
+ --signal_nesting;
+ // FIXME: all te other gory details
+}
diff --git a/arch/aarch64/smp.cc b/arch/aarch64/smp.cc
new file mode 100644
index 0000000..3236ca0
--- /dev/null
+++ b/arch/aarch64/smp.cc
@@ -0,0 +1,29 @@
+/*
+ * Copyright (C) 2014 Huawei Technologies Duesseldorf GmbH
+ *
+ * This work is open source software, licensed under the terms of the
+ * BSD license as described in the LICENSE file in the top-level directory.
+ */
+
+#include <osv/debug.h>
+#include <osv/sched.hh>
+#include <osv/prio.hh>
+
+volatile unsigned smp_processors = 1;
+
+sched::cpu* smp_initial_find_current_cpu()
+{
+ for (auto c : sched::cpus) {
+ /* just return the single cpu we have for now */
+ return c;
+ }
+ abort();
+}
+
+void __attribute__((constructor(init_prio::sched))) smp_init()
+{
+ auto c = new sched::cpu(0);
+ c->arch.gic_id = 0;
+ sched::cpus.push_back(c);
+ sched::current_cpu = sched::cpus[0];
+}
diff --git a/arch/aarch64/smp.hh b/arch/aarch64/smp.hh
new file mode 100644
index 0000000..8b00230
--- /dev/null
+++ b/arch/aarch64/smp.hh
@@ -0,0 +1,15 @@
+/*
+ * Copyright (C) 2014 Huawei Technologies Duesseldorf GmbH
+ *
+ * This work is open source software, licensed under the terms of the
+ * BSD license as described in the LICENSE file in the top-level directory.
+ */
+
+#ifndef ARCH_SMP_HH
+#define ARCH_SMP_HH
+
+#include <osv/sched.hh>
+
+sched::cpu* smp_initial_find_current_cpu();
+
+#endif /* ARCH_SMP_HH_ */
diff --git a/arch/aarch64/string.cc b/arch/aarch64/string.cc
new file mode 100644
index 0000000..cd842d8
--- /dev/null
+++ b/arch/aarch64/string.cc
@@ -0,0 +1,35 @@
+/*
+ * Copyright (C) 2014 Huawei Technologies Duesseldorf GmbH
+ *
+ * This work is open source software, licensed under the terms of the
+ * BSD license as described in the LICENSE file in the top-level directory.
+ */
+
+#include <bits/alltypes.h>
+#include <osv/string.h>
+
+extern "C"
+void *memcpy_base(void *__restrict dest, const void *__restrict src, size_t n);
+extern "C"
+void *memset_base(void *__restrict dest, int c, size_t n);
+extern "C"
+void *memcpy_base_backwards(void *__restrict dest, const void *__restrict src, size_t n);
+
+
+extern "C"
+void *memcpy(void *__restrict dest, const void *__restrict src, size_t n)
+{
+ return memcpy_base(dest, src, n);
+}
+
+extern "C"
+void *memcpy_backwards(void *__restrict dest, const void *__restrict src, size_t n)
+{
+ return memcpy_base_backwards(dest, src, n);
+}
+
+extern "C"
+void *memset(void *__restrict dest, int c, size_t n)
+{
+ return memset_base(dest, c, n);
+}
--
1.8.5.3

Claudio Fontana

unread,
Mar 25, 2014, 5:28:50 AM3/25/14
to osv...@googlegroups.com, claudio...@huawei.com, Jani Kokkonen
From: Jani Kokkonen <jani.k...@huawei.com>

From: Jani Kokkonen <jani.k...@huawei.com>

Signed-off-by: Jani Kokkonen <jani.k...@huawei.com>
Signed-off-by: Claudio Fontana <claudio...@huawei.com>
---
arch/aarch64/debug-console.cc | 61 ++++++++++++++++++++++++++++++++++
{drivers => arch/x64}/debug-console.cc | 2 +-
2 files changed, 62 insertions(+), 1 deletion(-)
create mode 100644 arch/aarch64/debug-console.cc
rename {drivers => arch/x64}/debug-console.cc (97%)

diff --git a/arch/aarch64/debug-console.cc b/arch/aarch64/debug-console.cc
new file mode 100644
index 0000000..652e3e1
--- /dev/null
+++ b/arch/aarch64/debug-console.cc
@@ -0,0 +1,61 @@
+/*
+ * Copyright (C) 2013 Cloudius Systems, Ltd.
+ *
+ * Copyright (C) 2014 Huawei Technologies Duesseldorf GmbH
+ *
+ * This work is open source software, licensed under the terms of the
+ * BSD license as described in the LICENSE file in the top-level directory.
+ */
+
+#include <drivers/debug-console.hh>
+
+static volatile char *const uart = (char *)0x9000000; /* UART0DR */
+
+static void simple_write(const char *str, size_t len)
+{
+ while (len > 0) {
+ if ((*str == '\n'))
+ *uart = '\r';
+ *uart = *str++;
+ len--;
+ }
+}
+void debug_console::set_impl(Console* impl)
+{
+ WITH_LOCK(_lock) {
+ _impl = impl;
+ }
+}
+
+void debug_console::write(const char* str, size_t len)
+{
+ WITH_LOCK(_lock) {
+ if (_impl) {
+ _impl->write(str, len);
+ } else {
+ simple_write(str, len);
+ }
+ }
+}
+
+void debug_console::write_ll(const char *str, size_t len)
+{
+ if (_impl) {
+ _impl->write(str, len);
+ } else
+ simple_write(str, len);
+}
+
+char debug_console::readch()
+{
+ WITH_LOCK(_lock) {
+ return _impl ? _impl->readch() : 0;
+ }
+ }
+
+bool debug_console::input_ready()
+{
+ WITH_LOCK(_lock) {
+ return _impl && _impl->input_ready();
+ }
+}
diff --git a/drivers/debug-console.cc b/arch/x64/debug-console.cc
similarity index 97%
rename from drivers/debug-console.cc
rename to arch/x64/debug-console.cc
index 7d1fea2..adf10a3 100644
--- a/drivers/debug-console.cc
+++ b/arch/x64/debug-console.cc
@@ -5,7 +5,7 @@
* BSD license as described in the LICENSE file in the top-level directory.
*/

-#include "debug-console.hh"
+#include <drivers/debug-console.hh>
#include "processor.hh"

// Write to the serial port if the console is not yet initialized. Because we
--
1.8.5.3

Claudio Fontana

unread,
Mar 25, 2014, 5:28:51 AM3/25/14
to osv...@googlegroups.com, claudio...@huawei.com
From: Claudio Fontana <claudio...@huawei.com>

Signed-off-by: Claudio Fontana <claudio...@huawei.com>
---
include/api/aarch64/bits/TODO | 3 +
include/api/aarch64/bits/alltypes.h.sh | 3 +-
include/api/aarch64/bits/fcntl.h | 38 ++
include/api/aarch64/bits/fenv.h | 42 +++
include/api/aarch64/bits/float.h | 41 +++
include/api/aarch64/bits/ioctl.h | 198 ++++++++++
include/api/aarch64/bits/ipc.h | 20 +
include/api/aarch64/bits/mman.h | 63 ++++
include/api/aarch64/bits/setjmp.h | 1 +
include/api/aarch64/bits/shm.h | 19 +
include/api/aarch64/bits/signal.h | 71 ++++
include/api/aarch64/bits/socket.h | 22 ++
include/api/aarch64/bits/stat.h | 25 ++
include/api/aarch64/bits/statfs.h | 7 +
include/api/aarch64/bits/syscall.h | 653 +++++++++++++++++++++++++++++++++
include/api/aarch64/bits/termios.h | 160 ++++++++
16 files changed, 1365 insertions(+), 1 deletion(-)
create mode 100644 include/api/aarch64/bits/TODO
create mode 100644 include/api/aarch64/bits/fcntl.h
create mode 100644 include/api/aarch64/bits/fenv.h
create mode 100644 include/api/aarch64/bits/float.h
create mode 100644 include/api/aarch64/bits/ioctl.h
create mode 100644 include/api/aarch64/bits/ipc.h
create mode 100644 include/api/aarch64/bits/mman.h
create mode 100644 include/api/aarch64/bits/setjmp.h
create mode 100644 include/api/aarch64/bits/shm.h
create mode 100644 include/api/aarch64/bits/signal.h
create mode 100644 include/api/aarch64/bits/socket.h
create mode 100644 include/api/aarch64/bits/stat.h
create mode 100644 include/api/aarch64/bits/statfs.h
create mode 100644 include/api/aarch64/bits/syscall.h
create mode 100644 include/api/aarch64/bits/termios.h

diff --git a/include/api/aarch64/bits/TODO b/include/api/aarch64/bits/TODO
new file mode 100644
index 0000000..bbe4530
--- /dev/null
+++ b/include/api/aarch64/bits/TODO
@@ -0,0 +1,3 @@
+This is just tentative, testing needed.
+
+Note the big XXX hack XXX in float.h!
diff --git a/include/api/aarch64/bits/alltypes.h.sh b/include/api/aarch64/bits/alltypes.h.sh
index 05b3548..35d01f6 100755
--- a/include/api/aarch64/bits/alltypes.h.sh
+++ b/include/api/aarch64/bits/alltypes.h.sh
@@ -17,6 +17,7 @@ union \1 \2;\
/'

#define __NEED_socklen_t
+#define __NEED_size_t

TYPEDEF unsigned long size_t;
#define _SIZE_T_DECLARED
@@ -25,7 +26,7 @@ TYPEDEF long ptrdiff_t;
TYPEDEF __builtin_va_list va_list;

#ifndef __cplusplus
-TYPEDEF int wchar_t;
+TYPEDEF unsigned int wchar_t;
#endif
TYPEDEF int wint_t;
TYPEDEF const int * wctrans_t;
diff --git a/include/api/aarch64/bits/fcntl.h b/include/api/aarch64/bits/fcntl.h
new file mode 100644
index 0000000..0949f31
--- /dev/null
+++ b/include/api/aarch64/bits/fcntl.h
@@ -0,0 +1,38 @@
+#define O_CREAT 0100
+#define O_EXCL 0200
+#define O_NOCTTY 0400
+#define O_TRUNC 01000
+#define O_APPEND 02000
+#define O_NONBLOCK 04000
+#define O_DSYNC 010000
+#define O_SYNC 04010000
+#define O_RSYNC 04010000
+#define O_DIRECTORY 0200000
+#define O_NOFOLLOW 0400000
+#define O_CLOEXEC 02000000
+
+#define O_ASYNC 020000
+#define O_DIRECT 040000
+#define O_LARGEFILE 0
+#define O_NOATIME 01000000
+#define O_NDELAY O_NONBLOCK
+
+#define F_DUPFD 0
+#define F_GETFD 1
+#define F_SETFD 2
+#define F_GETFL 3
+#define F_SETFL 4
+
+#define F_SETOWN 8
+#define F_GETOWN 9
+#define F_SETSIG 10
+#define F_GETSIG 11
+
+#define F_GETLK 5
+#define F_SETLK 6
+#define F_SETLKW 7
+
+#define F_SETOWN_EX 15
+#define F_GETOWN_EX 16
+
+#define F_GETOWNER_UIDS 17
diff --git a/include/api/aarch64/bits/fenv.h b/include/api/aarch64/bits/fenv.h
new file mode 100644
index 0000000..9e29b4a
--- /dev/null
+++ b/include/api/aarch64/bits/fenv.h
@@ -0,0 +1,42 @@
+/*
+ * Copyright (C) 2014 Huawei Technologies Duesseldorf GmbH
+ *
+ * This work is open source software, licensed under the terms of the
+ * BSD license as described in the LICENSE file in the top-level directory.
+ */
+
+#ifndef OSV_BITS_FENV_H
+#define OSV_BITS_FENV_H
+
+/* reference here is the fpsr status */
+#define FE_INVALID 0x01 /* IOC */
+#define FE_DIVBYZERO 0x02 /* DZC */
+#define FE_OVERFLOW 0x04 /* OFC */
+#define FE_UNDERFLOW 0x08 /* UFC */
+#define FE_INEXACT 0x10 /* IXC */
+/* bits 6:5 are RES0 */
+#define __FE_DENORM 0x80 /* IDC */
+
+#define FE_ALL_EXCEPT 0x9f
+
+/* routing modes in fpcr rmode */
+#define FE_TONEAREST 0x000000
+#define FE_UPWARD 0x400000
+#define FE_DOWNWARD 0x800000
+#define FE_TOWARDZERO 0xc00000
+
+/* floating-point environment */
+typedef struct
+{
+ unsigned int __fpcr;
+ unsigned int __fpsr;
+} fenv_t;
+
+
+#define FE_DFL_ENV ((const fenv_t *) -1L)
+/* no idea if we need this NOMASK thing */
+#define FE_NOMASK_ENV ((const fenv_t *) -2L)
+
+typedef unsigned int fexcept_t;
+
+#endif /* OSV_BITS_FENV_H */
diff --git a/include/api/aarch64/bits/float.h b/include/api/aarch64/bits/float.h
new file mode 100644
index 0000000..7378df6
--- /dev/null
+++ b/include/api/aarch64/bits/float.h
@@ -0,0 +1,41 @@
+/*
+ * Copyright (C) 2014 Huawei Technologies Duesseldorf GmbH
+ *
+ * This work is open source software, licensed under the terms of the
+ * BSD license as described in the LICENSE file in the top-level directory.
+ */
+
+#ifndef OSV_BITS_FLOAT_H
+#define OSV_BITS_FLOAT_H
+
+#define FLT_ROUNDS 1
+#define FLT_EVAL_METHOD 0
+
+#define LDBL_MIN 3.36210314311209350626267781732175260e-4932L
+#define LDBL_MAX 1.18973149535723176508575932662800702e+4932L
+#define LDBL_EPSILON 1.92592994438723585305597794258492732e-34L
+
+#define LDBL_MANT_DIG 113
+#define LDBL_MIN_EXP (-16381)
+#define LDBL_MAX_EXP 16384
+
+/* XXX HACK XXX */
+/* libc/ math stuff does not handle LDBL_MANT_DIG 113 well:
+ the modules recognize the case and handle it with the same code
+ as LDBL_MANT_DIG=64, but the referenced implementation in
+ __invtrigl.c et al do not provide an implementation for
+ 113, so we are left with unresolved symbols.
+
+ So we redefine to 64, which is probably wrong.
+ */
+
+#undef LDBL_MANT_DIG
+#define LDBL_MANT_DIG 64
+
+#define LDBL_DIG 33
+#define LDBL_MIN_10_EXP (-4931)
+#define LDBL_MAX_10_EXP 4932
+
+#define DECIMAL_DIG 36
+
+#endif /* OSV_BITS_FLOAT_H */
diff --git a/include/api/aarch64/bits/ioctl.h b/include/api/aarch64/bits/ioctl.h
new file mode 100644
index 0000000..9a13a0e
--- /dev/null
+++ b/include/api/aarch64/bits/ioctl.h
@@ -0,0 +1,198 @@
+#define _IOC(a,b,c,d) ( ((a)<<30) | ((b)<<8) | (c) | ((d)<<16) )
+#define _IOC_NONE 0U
+#define _IOC_WRITE 1U
+#define _IOC_READ 2U
+
+#define _IO(a,b) _IOC(_IOC_NONE,(a),(b),0)
+#define _IOW(a,b,c) _IOC(1,(a),(b),sizeof(c))
+#define _IOR(a,b,c) _IOC(2,(a),(b),sizeof(c))
+#define _IOWR(a,b,c) _IOC(3,(a),(b),sizeof(c))
+
+#define TCGETS 0x5401
+#define TCSETS 0x5402
+#define TCSETSW 0x5403
+#define TCSETSF 0x5404
+#define TCGETA 0x5405
+#define TCSETA 0x5406
+#define TCSETAW 0x5407
+#define TCSETAF 0x5408
+#define TCSBRK 0x5409
+#define TCXONC 0x540A
+#define TCFLSH 0x540B
+#define TIOCEXCL 0x540C
+#define TIOCNXCL 0x540D
+#define TIOCSCTTY 0x540E
+#define TIOCGPGRP 0x540F
+#define TIOCSPGRP 0x5410
+#define TIOCOUTQ 0x5411
+#define TIOCSTI 0x5412
+#define TIOCGWINSZ 0x5413
+#define TIOCSWINSZ 0x5414
+#define TIOCMGET 0x5415
+#define TIOCMBIS 0x5416
+#define TIOCMBIC 0x5417
+#define TIOCMSET 0x5418
+#define TIOCGSOFTCAR 0x5419
+#define TIOCSSOFTCAR 0x541A
+#define FIONREAD 0x541B
+#define TIOCINQ FIONREAD
+#define TIOCLINUX 0x541C
+#define TIOCCONS 0x541D
+#define TIOCGSERIAL 0x541E
+#define TIOCSSERIAL 0x541F
+#define TIOCPKT 0x5420
+#define FIONBIO 0x5421
+#define TIOCNOTTY 0x5422
+#define TIOCSETD 0x5423
+#define TIOCGETD 0x5424
+#define TCSBRKP 0x5425
+#define TIOCTTYGSTRUCT 0x5426
+#define TIOCSBRK 0x5427
+#define TIOCCBRK 0x5428
+#define TIOCGSID 0x5429
+#define TIOCGPTN 0x80045430
+#define TIOCSPTLCK 0x40045431
+#define TCGETX 0x5432
+#define TCSETX 0x5433
+#define TCSETXF 0x5434
+#define TCSETXW 0x5435
+
+#define FIONCLEX 0x5450
+#define FIOCLEX 0x5451
+#define FIOASYNC 0x5452
+#define TIOCSERCONFIG 0x5453
+#define TIOCSERGWILD 0x5454
+#define TIOCSERSWILD 0x5455
+#define TIOCGLCKTRMIOS 0x5456
+#define TIOCSLCKTRMIOS 0x5457
+#define TIOCSERGSTRUCT 0x5458
+#define TIOCSERGETLSR 0x5459
+#define TIOCSERGETMULTI 0x545A
+#define TIOCSERSETMULTI 0x545B
+
+#define TIOCMIWAIT 0x545C
+#define TIOCGICOUNT 0x545D
+#define TIOCGHAYESESP 0x545E
+#define TIOCSHAYESESP 0x545F
+#define FIOQSIZE 0x5460
+
+#define TIOCPKT_DATA 0
+#define TIOCPKT_FLUSHREAD 1
+#define TIOCPKT_FLUSHWRITE 2
+#define TIOCPKT_STOP 4
+#define TIOCPKT_START 8
+#define TIOCPKT_NOSTOP 16
+#define TIOCPKT_DOSTOP 32
+#define TIOCPKT_IOCTL 64
+
+#define TIOCSER_TEMT 0x01
+
+struct winsize {
+ unsigned short ws_row;
+ unsigned short ws_col;
+ unsigned short ws_xpixel;
+ unsigned short ws_ypixel;
+};
+
+#define TIOCM_LE 0x001
+#define TIOCM_DTR 0x002
+#define TIOCM_RTS 0x004
+#define TIOCM_ST 0x008
+#define TIOCM_SR 0x010
+#define TIOCM_CTS 0x020
+#define TIOCM_CAR 0x040
+#define TIOCM_RNG 0x080
+#define TIOCM_DSR 0x100
+#define TIOCM_CD TIOCM_CAR
+#define TIOCM_RI TIOCM_RNG
+#define TIOCM_OUT1 0x2000
+#define TIOCM_OUT2 0x4000
+#define TIOCM_LOOP 0x8000
+#define TIOCM_MODEM_BITS TIOCM_OUT2
+
+#define N_TTY 0
+#define N_SLIP 1
+#define N_MOUSE 2
+#define N_PPP 3
+#define N_STRIP 4
+#define N_AX25 5
+#define N_X25 6
+#define N_6PACK 7
+#define N_MASC 8
+#define N_R3964 9
+#define N_PROFIBUS_FDL 10
+#define N_IRDA 11
+#define N_SMSBLOCK 12
+#define N_HDLC 13
+#define N_SYNC_PPP 14
+#define N_HCI 15
+
+#define FIOSETOWN 0x8901
+#define SIOCSPGRP 0x8902
+#define FIOGETOWN 0x8903
+#define SIOCGPGRP 0x8904
+#define SIOCATMARK 0x8905
+#define SIOCGSTAMP 0x8906
+
+#define SIOCADDRT 0x890B
+#define SIOCDELRT 0x890C
+#define SIOCRTMSG 0x890D
+
+#define SIOCGIFNAME 0x8910
+#define SIOCSIFLINK 0x8911
+#define SIOCGIFCONF 0x8912
+#define SIOCGIFFLAGS 0x8913
+#define SIOCSIFFLAGS 0x8914
+#define SIOCGIFADDR 0x8915
+#define SIOCSIFADDR 0x8916
+#define SIOCGIFDSTADDR 0x8917
+#define SIOCSIFDSTADDR 0x8918
+#define SIOCGIFBRDADDR 0x8919
+#define SIOCSIFBRDADDR 0x891a
+#define SIOCGIFNETMASK 0x891b
+#define SIOCSIFNETMASK 0x891c
+#define SIOCGIFMETRIC 0x891d
+#define SIOCSIFMETRIC 0x891e
+#define SIOCGIFMEM 0x891f
+#define SIOCSIFMEM 0x8920
+#define SIOCGIFMTU 0x8921
+#define SIOCSIFMTU 0x8922
+#define SIOCSIFNAME 0x8923
+#define SIOCSIFHWADDR 0x8924
+#define SIOCGIFENCAP 0x8925
+#define SIOCSIFENCAP 0x8926
+#define SIOCGIFHWADDR 0x8927
+#define SIOCGIFSLAVE 0x8929
+#define SIOCSIFSLAVE 0x8930
+#define SIOCADDMULTI 0x8931
+#define SIOCDELMULTI 0x8932
+#define SIOCGIFINDEX 0x8933
+#define SIOGIFINDEX SIOCGIFINDEX
+#define SIOCSIFPFLAGS 0x8934
+#define SIOCGIFPFLAGS 0x8935
+#define SIOCDIFADDR 0x8936
+#define SIOCSIFHWBROADCAST 0x8937
+#define SIOCGIFCOUNT 0x8938
+
+#define SIOCGIFBR 0x8940
+#define SIOCSIFBR 0x8941
+
+#define SIOCGIFTXQLEN 0x8942
+#define SIOCSIFTXQLEN 0x8943
+
+#define SIOCDARP 0x8953
+#define SIOCGARP 0x8954
+#define SIOCSARP 0x8955
+
+#define SIOCDRARP 0x8960
+#define SIOCGRARP 0x8961
+#define SIOCSRARP 0x8962
+
+#define SIOCGIFMAP 0x8970
+#define SIOCSIFMAP 0x8971
+
+#define SIOCADDDLCI 0x8980
+#define SIOCDELDLCI 0x8981
+
+#define SIOCDEVPRIVATE 0x89F0
+#define SIOCPROTOPRIVATE 0x89E0
diff --git a/include/api/aarch64/bits/ipc.h b/include/api/aarch64/bits/ipc.h
new file mode 100644
index 0000000..36fb5bf
--- /dev/null
+++ b/include/api/aarch64/bits/ipc.h
@@ -0,0 +1,20 @@
+#ifndef BITS_IPC_H
+#define BITS_IPC_H
+
+struct ipc_perm {
+ key_t __ipc_perm_key;
+ uid_t uid;
+ gid_t gid;
+ uid_t cuid;
+ gid_t cgid;
+ unsigned short int mode;
+ unsigned short int __pad1;
+ unsigned short int __ipc_perm_seq;
+ unsigned short int __pad2;
+ unsigned long long __unused1;
+ unsigned long long __unused2;
+};
+
+#define IPC_64 0
+
+#endif /* BITS_IPC_H */
diff --git a/include/api/aarch64/bits/mman.h b/include/api/aarch64/bits/mman.h
new file mode 100644
index 0000000..dc07c61
--- /dev/null
+++ b/include/api/aarch64/bits/mman.h
@@ -0,0 +1,63 @@
+#define MAP_FAILED ((void *) -1)
+
+#define PROT_NONE 0
+#define PROT_READ 1
+#define PROT_WRITE 2
+#define PROT_EXEC 4
+#define PROT_GROWSDOWN 0x01000000
+#define PROT_GROWSUP 0x02000000
+
+#define MAP_SHARED 0x01
+#define MAP_PRIVATE 0x02
+#define MAP_FIXED 0x10
+
+#define MAP_TYPE 0x0f
+#define MAP_FILE 0x00
+#define MAP_ANON 0x20
+#define MAP_ANONYMOUS MAP_ANON
+#define MAP_32BIT 0x40
+#define MAP_NORESERVE 0x4000
+#define MAP_GROWSDOWN 0x0100
+#define MAP_DENYWRITE 0x0800
+#define MAP_EXECUTABLE 0x1000
+#define MAP_LOCKED 0x2000
+#define MAP_POPULATE 0x8000
+#define MAP_NONBLOCK 0x10000
+#define MAP_STACK 0x20000
+#define MAP_HUGETLB 0x40000
+#define MAP_UNINITIALIZED 0x4000000
+
+#define POSIX_MADV_NORMAL 0
+#define POSIX_MADV_RANDOM 1
+#define POSIX_MADV_SEQUENTIAL 2
+#define POSIX_MADV_WILLNEED 3
+#define POSIX_MADV_DONTNEED 0
+
+#define MS_ASYNC 1
+#define MS_INVALIDATE 2
+#define MS_SYNC 4
+
+#define MCL_CURRENT 1
+#define MCL_FUTURE 2
+
+#if defined(_GNU_SOURCE) || defined(_BSD_SOURCE)
+#define MADV_NORMAL 0
+#define MADV_RANDOM 1
+#define MADV_SEQUENTIAL 2
+#define MADV_WILLNEED 3
+#define MADV_DONTNEED 4
+#define MADV_REMOVE 9
+#define MADV_DONTFORK 10
+#define MADV_DOFORK 11
+#define MADV_MERGEABLE 12
+#define MADV_UNMERGEABLE 13
+#define MADV_HUGEPAGE 14
+#define MADV_NOHUGEPAGE 15
+#define MADV_DONTDUMP 16
+#define MADV_DODUMP 17
+#define MADV_HWPOISON 100
+#define MADV_SOFT_OFFLINE 101
+
+#define MREMAP_MAYMOVE 1
+#define MREMAP_FIXED 2
+#endif
diff --git a/include/api/aarch64/bits/setjmp.h b/include/api/aarch64/bits/setjmp.h
new file mode 100644
index 0000000..81d4968
--- /dev/null
+++ b/include/api/aarch64/bits/setjmp.h
@@ -0,0 +1 @@
+typedef unsigned long jmp_buf[8];
diff --git a/include/api/aarch64/bits/shm.h b/include/api/aarch64/bits/shm.h
new file mode 100644
index 0000000..6ae8451
--- /dev/null
+++ b/include/api/aarch64/bits/shm.h
@@ -0,0 +1,19 @@
+#ifndef BITS_SHM_H
+#define BITS_SHM_H
+
+#define SHMLBA 4096
+
+struct shmid_ds {
+ struct ipc_perm shm_perm;
+ size_t shm_segsz;
+ time_t shm_atime;
+ time_t shm_dtime;
+ time_t shm_ctime;
+ pid_t shm_cpid;
+ pid_t shm_lpid;
+ unsigned long shm_nattch;
+ unsigned long __pad1;
+ unsigned long __pad2;
+};
+
+#endif /* BITS_SHM_H */
diff --git a/include/api/aarch64/bits/signal.h b/include/api/aarch64/bits/signal.h
new file mode 100644
index 0000000..2ed4eeb
--- /dev/null
+++ b/include/api/aarch64/bits/signal.h
@@ -0,0 +1,71 @@
+#ifndef OSV_BITS_SIGNAL_H
+#define OSV_BITS_SIGNAL_H
+
+struct sigcontext
+{
+ unsigned long long regs[31]; /* X0 to X30 */
+ unsigned long long sp;
+ unsigned long long pc;
+ unsigned long long pstate;
+ /* XXX floating point XXX */
+};
+
+typedef struct sigcontext mcontext_t;
+
+typedef struct ucontext
+{
+ unsigned long uc_flags;
+ struct ucontext *uc_link;
+ stack_t uc_stack;
+ mcontext_t uc_mcontext;
+ sigset_t uc_sigmask;
+ /* XXX add floating point XXX */
+} ucontext_t;
+
+#define SA_NOCLDSTOP 1
+#define SA_NOCLDWAIT 2
+#define SA_SIGINFO 4
+#define SA_ONSTACK 0x08000000
+#define SA_RESTART 0x10000000
+#define SA_NODEFER 0x40000000
+#define SA_RESETHAND 0x80000000
+#define SA_RESTORER 0x04000000
+
+#define SIGHUP 1
+#define SIGINT 2
+#define SIGQUIT 3
+#define SIGILL 4
+#define SIGTRAP 5
+#define SIGABRT 6
+#define SIGIOT SIGABRT
+#define SIGBUS 7
+#define SIGFPE 8
+#define SIGKILL 9
+#define SIGUSR1 10
+#define SIGSEGV 11
+#define SIGUSR2 12
+#define SIGPIPE 13
+#define SIGALRM 14
+#define SIGTERM 15
+#define SIGSTKFLT 16
+#define SIGCHLD 17
+#define SIGCONT 18
+#define SIGSTOP 19
+#define SIGTSTP 20
+#define SIGTTIN 21
+#define SIGTTOU 22
+#define SIGURG 23
+#define SIGXCPU 24
+#define SIGXFSZ 25
+#define SIGVTALRM 26
+#define SIGPROF 27
+#define SIGWINCH 28
+#define SIGIO 29
+#define SIGPOLL 29
+#define SIGPWR 30
+#define SIGSYS 31
+#define SIGUNUSED SIGSYS
+
+#define _NSIG 65
+
+#endif /* OSV_BITS_SIGNAL_H */
diff --git a/include/api/aarch64/bits/socket.h b/include/api/aarch64/bits/socket.h
new file mode 100644
index 0000000..bd81599
--- /dev/null
+++ b/include/api/aarch64/bits/socket.h
@@ -0,0 +1,22 @@
+#ifndef OSV_BITS_SOCKET_H
+#define OSV_BITS_SOCKET_H
+
+struct msghdr
+{
+ void *msg_name;
+ socklen_t msg_namelen;
+ struct iovec *msg_iov;
+ int msg_iovlen, __pad1;
+ void *msg_control;
+ socklen_t msg_controllen, __pad2;
+ int msg_flags;
+};
+
+struct cmsghdr
+{
+ socklen_t cmsg_len;
+ int __pad1;
+ int cmsg_level;
+ int cmsg_type;
+};
+#endif
diff --git a/include/api/aarch64/bits/stat.h b/include/api/aarch64/bits/stat.h
new file mode 100644
index 0000000..87308a5
--- /dev/null
+++ b/include/api/aarch64/bits/stat.h
@@ -0,0 +1,25 @@
+#ifndef OSV_BITS_STAT_H
+#define OSV_BITS_STAT_H
+
+/* for aarch64 moved padding to keep stuff 8-aligned */
+struct stat {
+ dev_t st_dev;
+ ino_t st_ino;
+ nlink_t st_nlink;
+ mode_t st_mode;
+ uid_t st_uid;
+ gid_t st_gid;
+ dev_t st_rdev;
+ off_t st_size;
+
+ blksize_t st_blksize; /* blksize_t is int */
+ unsigned int __pad0; /* therefore pad here */
+
+ blkcnt_t st_blocks;
+ struct timespec st_atim;
+ struct timespec st_mtim;
+ struct timespec st_ctim;
+ long __unused[2];
+};
+
+#endif /* OSV_BITS_STAT_H */
diff --git a/include/api/aarch64/bits/statfs.h b/include/api/aarch64/bits/statfs.h
new file mode 100644
index 0000000..f103f4e
--- /dev/null
+++ b/include/api/aarch64/bits/statfs.h
@@ -0,0 +1,7 @@
+struct statfs {
+ unsigned long f_type, f_bsize;
+ fsblkcnt_t f_blocks, f_bfree, f_bavail;
+ fsfilcnt_t f_files, f_ffree;
+ fsid_t f_fsid;
+ unsigned long f_namelen, f_frsize, f_flags, f_spare[4];
+};
diff --git a/include/api/aarch64/bits/syscall.h b/include/api/aarch64/bits/syscall.h
new file mode 100644
index 0000000..cbd4a54
--- /dev/null
+++ b/include/api/aarch64/bits/syscall.h
@@ -0,0 +1,653 @@
+#define __NR_read 0
+#define __NR_write 1
+#define __NR_open 2
+#define __NR_close 3
+#define __NR_stat 4
+#define __NR_fstat 5
+#define __NR_lstat 6
+#define __NR_poll 7
+#define __NR_lseek 8
+#define __NR_mmap 9
+#define __NR_mprotect 10
+#define __NR_munmap 11
+#define __NR_brk 12
+#define __NR_rt_sigaction 13
+#define __NR_rt_sigprocmask 14
+#define __NR_rt_sigreturn 15
+#define __NR_ioctl 16
+#define __NR_pread64 17
+#define __NR_pwrite64 18
+#define __NR_readv 19
+#define __NR_writev 20
+#define __NR_access 21
+#define __NR_pipe 22
+#define __NR_select 23
+#define __NR_sched_yield 24
+#define __NR_mremap 25
+#define __NR_msync 26
+#define __NR_mincore 27
+#define __NR_madvise 28
+#define __NR_shmget 29
+#define __NR_shmat 30
+#define __NR_shmctl 31
+#define __NR_dup 32
+#define __NR_dup2 33
+#define __NR_pause 34
+#define __NR_nanosleep 35
+#define __NR_getitimer 36
+#define __NR_alarm 37
+#define __NR_setitimer 38
+#define __NR_getpid 39
+#define __NR_sendfile 40
+#define __NR_socket 41
+#define __NR_connect 42
+#define __NR_accept 43
+#define __NR_sendto 44
+#define __NR_recvfrom 45
+#define __NR_sendmsg 46
+#define __NR_recvmsg 47
+#define __NR_shutdown 48
+#define __NR_bind 49
+#define __NR_listen 50
+#define __NR_getsockname 51
+#define __NR_getpeername 52
+#define __NR_socketpair 53
+#define __NR_setsockopt 54
+#define __NR_getsockopt 55
+#define __NR_clone 56
+#define __NR_fork 57
+#define __NR_vfork 58
+#define __NR_execve 59
+#define __NR_exit 60
+#define __NR_wait4 61
+#define __NR_kill 62
+#define __NR_uname 63
+#define __NR_semget 64
+#define __NR_semop 65
+#define __NR_semctl 66
+#define __NR_shmdt 67
+#define __NR_msgget 68
+#define __NR_msgsnd 69
+#define __NR_msgrcv 70
+#define __NR_msgctl 71
+#define __NR_fcntl 72
+#define __NR_flock 73
+#define __NR_fsync 74
+#define __NR_fdatasync 75
+#define __NR_truncate 76
+#define __NR_ftruncate 77
+#define __NR_getdents 78
+#define __NR_getcwd 79
+#define __NR_chdir 80
+#define __NR_fchdir 81
+#define __NR_rename 82
+#define __NR_mkdir 83
+#define __NR_rmdir 84
+#define __NR_creat 85
+#define __NR_link 86
+#define __NR_unlink 87
+#define __NR_symlink 88
+#define __NR_readlink 89
+#define __NR_chmod 90
+#define __NR_fchmod 91
+#define __NR_chown 92
+#define __NR_fchown 93
+#define __NR_lchown 94
+#define __NR_umask 95
+#define __NR_gettimeofday 96
+#define __NR_getrlimit 97
+#define __NR_getrusage 98
+#define __NR_sysinfo 99
+#define __NR_times 100
+#define __NR_ptrace 101
+#define __NR_getuid 102
+#define __NR_syslog 103
+#define __NR_getgid 104
+#define __NR_setuid 105
+#define __NR_setgid 106
+#define __NR_geteuid 107
+#define __NR_getegid 108
+#define __NR_setpgid 109
+#define __NR_getppid 110
+#define __NR_getpgrp 111
+#define __NR_setsid 112
+#define __NR_setreuid 113
+#define __NR_setregid 114
+#define __NR_getgroups 115
+#define __NR_setgroups 116
+#define __NR_setresuid 117
+#define __NR_getresuid 118
+#define __NR_setresgid 119
+#define __NR_getresgid 120
+#define __NR_getpgid 121
+#define __NR_setfsuid 122
+#define __NR_setfsgid 123
+#define __NR_getsid 124
+#define __NR_capget 125
+#define __NR_capset 126
+#define __NR_rt_sigpending 127
+#define __NR_rt_sigtimedwait 128
+#define __NR_rt_sigqueueinfo 129
+#define __NR_rt_sigsuspend 130
+#define __NR_sigaltstack 131
+#define __NR_utime 132
+#define __NR_mknod 133
+#define __NR_uselib 134
+#define __NR_personality 135
+#define __NR_ustat 136
+#define __NR_statfs 137
+#define __NR_fstatfs 138
+#define __NR_sysfs 139
+#define __NR_getpriority 140
+#define __NR_setpriority 141
+#define __NR_sched_setparam 142
+#define __NR_sched_getparam 143
+#define __NR_sched_setscheduler 144
+#define __NR_sched_getscheduler 145
+#define __NR_sched_get_priority_max 146
+#define __NR_sched_get_priority_min 147
+#define __NR_sched_rr_get_interval 148
+#define __NR_mlock 149
+#define __NR_munlock 150
+#define __NR_mlockall 151
+#define __NR_munlockall 152
+#define __NR_vhangup 153
+#define __NR_modify_ldt 154
+#define __NR_pivot_root 155
+#define __NR__sysctl 156
+#define __NR_prctl 157
+#define __NR_arch_prctl 158
+#define __NR_adjtimex 159
+#define __NR_setrlimit 160
+#define __NR_chroot 161
+#define __NR_sync 162
+#define __NR_acct 163
+#define __NR_settimeofday 164
+#define __NR_mount 165
+#define __NR_umount2 166
+#define __NR_swapon 167
+#define __NR_swapoff 168
+#define __NR_reboot 169
+#define __NR_sethostname 170
+#define __NR_setdomainname 171
+#define __NR_iopl 172
+#define __NR_ioperm 173
+#define __NR_create_module 174
+#define __NR_init_module 175
+#define __NR_delete_module 176
+#define __NR_get_kernel_syms 177
+#define __NR_query_module 178
+#define __NR_quotactl 179
+#define __NR_nfsservctl 180
+#define __NR_getpmsg 181
+#define __NR_putpmsg 182
+#define __NR_afs_syscall 183
+#define __NR_tuxcall 184
+#define __NR_security 185
+#define __NR_gettid 186
+#define __NR_readahead 187
+#define __NR_setxattr 188
+#define __NR_lsetxattr 189
+#define __NR_fsetxattr 190
+#define __NR_getxattr 191
+#define __NR_lgetxattr 192
+#define __NR_fgetxattr 193
+#define __NR_listxattr 194
+#define __NR_llistxattr 195
+#define __NR_flistxattr 196
+#define __NR_removexattr 197
+#define __NR_lremovexattr 198
+#define __NR_fremovexattr 199
+#define __NR_tkill 200
+#define __NR_time 201
+#define __NR_futex 202
+#define __NR_sched_setaffinity 203
+#define __NR_sched_getaffinity 204
+#define __NR_set_thread_area 205
+#define __NR_io_setup 206
+#define __NR_io_destroy 207
+#define __NR_io_getevents 208
+#define __NR_io_submit 209
+#define __NR_io_cancel 210
+#define __NR_get_thread_area 211
+#define __NR_lookup_dcookie 212
+#define __NR_epoll_create 213
+#define __NR_epoll_ctl_old 214
+#define __NR_epoll_wait_old 215
+#define __NR_remap_file_pages 216
+#define __NR_getdents64 217
+#define __NR_set_tid_address 218
+#define __NR_restart_syscall 219
+#define __NR_semtimedop 220
+#define __NR_fadvise64 221
+#define __NR_timer_create 222
+#define __NR_timer_settime 223
+#define __NR_timer_gettime 224
+#define __NR_timer_getoverrun 225
+#define __NR_timer_delete 226
+#define __NR_clock_settime 227
+#define __NR_clock_gettime 228
+#define __NR_clock_getres 229
+#define __NR_clock_nanosleep 230
+#define __NR_exit_group 231
+#define __NR_epoll_wait 232
+#define __NR_epoll_ctl 233
+#define __NR_tgkill 234
+#define __NR_utimes 235
+#define __NR_vserver 236
+#define __NR_mbind 237
+#define __NR_set_mempolicy 238
+#define __NR_get_mempolicy 239
+#define __NR_mq_open 240
+#define __NR_mq_unlink 241
+#define __NR_mq_timedsend 242
+#define __NR_mq_timedreceive 243
+#define __NR_mq_notify 244
+#define __NR_mq_getsetattr 245
+#define __NR_kexec_load 246
+#define __NR_waitid 247
+#define __NR_add_key 248
+#define __NR_request_key 249
+#define __NR_keyctl 250
+#define __NR_ioprio_set 251
+#define __NR_ioprio_get 252
+#define __NR_inotify_init 253
+#define __NR_inotify_add_watch 254
+#define __NR_inotify_rm_watch 255
+#define __NR_migrate_pages 256
+#define __NR_openat 257
+#define __NR_mkdirat 258
+#define __NR_mknodat 259
+#define __NR_fchownat 260
+#define __NR_futimesat 261
+#define __NR_newfstatat 262
+#define __NR_unlinkat 263
+#define __NR_renameat 264
+#define __NR_linkat 265
+#define __NR_symlinkat 266
+#define __NR_readlinkat 267
+#define __NR_fchmodat 268
+#define __NR_faccessat 269
+#define __NR_pselect6 270
+#define __NR_ppoll 271
+#define __NR_unshare 272
+#define __NR_set_robust_list 273
+#define __NR_get_robust_list 274
+#define __NR_splice 275
+#define __NR_tee 276
+#define __NR_sync_file_range 277
+#define __NR_vmsplice 278
+#define __NR_move_pages 279
+#define __NR_utimensat 280
+#define __NR_epoll_pwait 281
+#define __NR_signalfd 282
+#define __NR_timerfd_create 283
+#define __NR_eventfd 284
+#define __NR_fallocate 285
+#define __NR_timerfd_settime 286
+#define __NR_timerfd_gettime 287
+#define __NR_accept4 288
+#define __NR_signalfd4 289
+#define __NR_eventfd2 290
+#define __NR_epoll_create1 291
+#define __NR_dup3 292
+#define __NR_pipe2 293
+#define __NR_inotify_init1 294
+#define __NR_preadv 295
+#define __NR_pwritev 296
+#define __NR_rt_tgsigqueueinfo 297
+#define __NR_perf_event_open 298
+#define __NR_recvmmsg 299
+#define __NR_fanotify_init 300
+#define __NR_fanotify_mark 301
+#define __NR_prlimit64 302
+#define __NR_name_to_handle_at 303
+#define __NR_open_by_handle_at 304
+#define __NR_clock_adjtime 305
+#define __NR_syncfs 306
+#define __NR_sendmmsg 307
+#define __NR_setns 308
+#define __NR_getcpu 309
+#define __NR_process_vm_readv 310
+#define __NR_process_vm_writev 311
+#define __NR_kcmp 312
+#define __NR_finit_module 313
+
+#undef __NR_fstatat
+#undef __NR_pread
+#undef __NR_pwrite
+#undef __NR_getdents
+#define __NR_fstatat __NR_newfstatat
+#define __NR_pread __NR_pread64
+#define __NR_pwrite __NR_pwrite64
+#define __NR_getdents __NR_getdents64
+#define __NR_fadvise __NR_fadvise64
+
+
+
+/* Repeat with SYS_ prefix */
+
+#define SYS_read 0
+#define SYS_write 1
+#define SYS_open 2
+#define SYS_close 3
+#define SYS_stat 4
+#define SYS_fstat 5
+#define SYS_lstat 6
+#define SYS_poll 7
+#define SYS_lseek 8
+#define SYS_mmap 9
+#define SYS_mprotect 10
+#define SYS_munmap 11
+#define SYS_brk 12
+#define SYS_rt_sigaction 13
+#define SYS_rt_sigprocmask 14
+#define SYS_rt_sigreturn 15
+#define SYS_ioctl 16
+#define SYS_pread64 17
+#define SYS_pwrite64 18
+#define SYS_readv 19
+#define SYS_writev 20
+#define SYS_access 21
+#define SYS_pipe 22
+#define SYS_select 23
+#define SYS_sched_yield 24
+#define SYS_mremap 25
+#define SYS_msync 26
+#define SYS_mincore 27
+#define SYS_madvise 28
+#define SYS_shmget 29
+#define SYS_shmat 30
+#define SYS_shmctl 31
+#define SYS_dup 32
+#define SYS_dup2 33
+#define SYS_pause 34
+#define SYS_nanosleep 35
+#define SYS_getitimer 36
+#define SYS_alarm 37
+#define SYS_setitimer 38
+#define SYS_getpid 39
+#define SYS_sendfile 40
+#define SYS_socket 41
+#define SYS_connect 42
+#define SYS_accept 43
+#define SYS_sendto 44
+#define SYS_recvfrom 45
+#define SYS_sendmsg 46
+#define SYS_recvmsg 47
+#define SYS_shutdown 48
+#define SYS_bind 49
+#define SYS_listen 50
+#define SYS_getsockname 51
+#define SYS_getpeername 52
+#define SYS_socketpair 53
+#define SYS_setsockopt 54
+#define SYS_getsockopt 55
+#define SYS_clone 56
+#define SYS_fork 57
+#define SYS_vfork 58
+#define SYS_execve 59
+#define SYS_exit 60
+#define SYS_wait4 61
+#define SYS_kill 62
+#define SYS_uname 63
+#define SYS_semget 64
+#define SYS_semop 65
+#define SYS_semctl 66
+#define SYS_shmdt 67
+#define SYS_msgget 68
+#define SYS_msgsnd 69
+#define SYS_msgrcv 70
+#define SYS_msgctl 71
+#define SYS_fcntl 72
+#define SYS_flock 73
+#define SYS_fsync 74
+#define SYS_fdatasync 75
+#define SYS_truncate 76
+#define SYS_ftruncate 77
+#define SYS_getdents 78
+#define SYS_getcwd 79
+#define SYS_chdir 80
+#define SYS_fchdir 81
+#define SYS_rename 82
+#define SYS_mkdir 83
+#define SYS_rmdir 84
+#define SYS_creat 85
+#define SYS_link 86
+#define SYS_unlink 87
+#define SYS_symlink 88
+#define SYS_readlink 89
+#define SYS_chmod 90
+#define SYS_fchmod 91
+#define SYS_chown 92
+#define SYS_fchown 93
+#define SYS_lchown 94
+#define SYS_umask 95
+#define SYS_gettimeofday 96
+#define SYS_getrlimit 97
+#define SYS_getrusage 98
+#define SYS_sysinfo 99
+#define SYS_times 100
+#define SYS_ptrace 101
+#define SYS_getuid 102
+#define SYS_syslog 103
+#define SYS_getgid 104
+#define SYS_setuid 105
+#define SYS_setgid 106
+#define SYS_geteuid 107
+#define SYS_getegid 108
+#define SYS_setpgid 109
+#define SYS_getppid 110
+#define SYS_getpgrp 111
+#define SYS_setsid 112
+#define SYS_setreuid 113
+#define SYS_setregid 114
+#define SYS_getgroups 115
+#define SYS_setgroups 116
+#define SYS_setresuid 117
+#define SYS_getresuid 118
+#define SYS_setresgid 119
+#define SYS_getresgid 120
+#define SYS_getpgid 121
+#define SYS_setfsuid 122
+#define SYS_setfsgid 123
+#define SYS_getsid 124
+#define SYS_capget 125
+#define SYS_capset 126
+#define SYS_rt_sigpending 127
+#define SYS_rt_sigtimedwait 128
+#define SYS_rt_sigqueueinfo 129
+#define SYS_rt_sigsuspend 130
+#define SYS_sigaltstack 131
+#define SYS_utime 132
+#define SYS_mknod 133
+#define SYS_uselib 134
+#define SYS_personality 135
+#define SYS_ustat 136
+#define SYS_statfs 137
+#define SYS_fstatfs 138
+#define SYS_sysfs 139
+#define SYS_getpriority 140
+#define SYS_setpriority 141
+#define SYS_sched_setparam 142
+#define SYS_sched_getparam 143
+#define SYS_sched_setscheduler 144
+#define SYS_sched_getscheduler 145
+#define SYS_sched_get_priority_max 146
+#define SYS_sched_get_priority_min 147
+#define SYS_sched_rr_get_interval 148
+#define SYS_mlock 149
+#define SYS_munlock 150
+#define SYS_mlockall 151
+#define SYS_munlockall 152
+#define SYS_vhangup 153
+#define SYS_modify_ldt 154
+#define SYS_pivot_root 155
+#define SYS__sysctl 156
+#define SYS_prctl 157
+#define SYS_arch_prctl 158
+#define SYS_adjtimex 159
+#define SYS_setrlimit 160
+#define SYS_chroot 161
+#define SYS_sync 162
+#define SYS_acct 163
+#define SYS_settimeofday 164
+#define SYS_mount 165
+#define SYS_umount2 166
+#define SYS_swapon 167
+#define SYS_swapoff 168
+#define SYS_reboot 169
+#define SYS_sethostname 170
+#define SYS_setdomainname 171
+#define SYS_iopl 172
+#define SYS_ioperm 173
+#define SYS_create_module 174
+#define SYS_init_module 175
+#define SYS_delete_module 176
+#define SYS_get_kernel_syms 177
+#define SYS_query_module 178
+#define SYS_quotactl 179
+#define SYS_nfsservctl 180
+#define SYS_getpmsg 181
+#define SYS_putpmsg 182
+#define SYS_afs_syscall 183
+#define SYS_tuxcall 184
+#define SYS_security 185
+#define SYS_gettid 186
+#define SYS_readahead 187
+#define SYS_setxattr 188
+#define SYS_lsetxattr 189
+#define SYS_fsetxattr 190
+#define SYS_getxattr 191
+#define SYS_lgetxattr 192
+#define SYS_fgetxattr 193
+#define SYS_listxattr 194
+#define SYS_llistxattr 195
+#define SYS_flistxattr 196
+#define SYS_removexattr 197
+#define SYS_lremovexattr 198
+#define SYS_fremovexattr 199
+#define SYS_tkill 200
+#define SYS_time 201
+#define SYS_futex 202
+#define SYS_sched_setaffinity 203
+#define SYS_sched_getaffinity 204
+#define SYS_set_thread_area 205
+#define SYS_io_setup 206
+#define SYS_io_destroy 207
+#define SYS_io_getevents 208
+#define SYS_io_submit 209
+#define SYS_io_cancel 210
+#define SYS_get_thread_area 211
+#define SYS_lookup_dcookie 212
+#define SYS_epoll_create 213
+#define SYS_epoll_ctl_old 214
+#define SYS_epoll_wait_old 215
+#define SYS_remap_file_pages 216
+#define SYS_getdents64 217
+#define SYS_set_tid_address 218
+#define SYS_restart_syscall 219
+#define SYS_semtimedop 220
+#define SYS_fadvise64 221
+#define SYS_timer_create 222
+#define SYS_timer_settime 223
+#define SYS_timer_gettime 224
+#define SYS_timer_getoverrun 225
+#define SYS_timer_delete 226
+#define SYS_clock_settime 227
+#define SYS_clock_gettime 228
+#define SYS_clock_getres 229
+#define SYS_clock_nanosleep 230
+#define SYS_exit_group 231
+#define SYS_epoll_wait 232
+#define SYS_epoll_ctl 233
+#define SYS_tgkill 234
+#define SYS_utimes 235
+#define SYS_vserver 236
+#define SYS_mbind 237
+#define SYS_set_mempolicy 238
+#define SYS_get_mempolicy 239
+#define SYS_mq_open 240
+#define SYS_mq_unlink 241
+#define SYS_mq_timedsend 242
+#define SYS_mq_timedreceive 243
+#define SYS_mq_notify 244
+#define SYS_mq_getsetattr 245
+#define SYS_kexec_load 246
+#define SYS_waitid 247
+#define SYS_add_key 248
+#define SYS_request_key 249
+#define SYS_keyctl 250
+#define SYS_ioprio_set 251
+#define SYS_ioprio_get 252
+#define SYS_inotify_init 253
+#define SYS_inotify_add_watch 254
+#define SYS_inotify_rm_watch 255
+#define SYS_migrate_pages 256
+#define SYS_openat 257
+#define SYS_mkdirat 258
+#define SYS_mknodat 259
+#define SYS_fchownat 260
+#define SYS_futimesat 261
+#define SYS_newfstatat 262
+#define SYS_unlinkat 263
+#define SYS_renameat 264
+#define SYS_linkat 265
+#define SYS_symlinkat 266
+#define SYS_readlinkat 267
+#define SYS_fchmodat 268
+#define SYS_faccessat 269
+#define SYS_pselect6 270
+#define SYS_ppoll 271
+#define SYS_unshare 272
+#define SYS_set_robust_list 273
+#define SYS_get_robust_list 274
+#define SYS_splice 275
+#define SYS_tee 276
+#define SYS_sync_file_range 277
+#define SYS_vmsplice 278
+#define SYS_move_pages 279
+#define SYS_utimensat 280
+#define SYS_epoll_pwait 281
+#define SYS_signalfd 282
+#define SYS_timerfd_create 283
+#define SYS_eventfd 284
+#define SYS_fallocate 285
+#define SYS_timerfd_settime 286
+#define SYS_timerfd_gettime 287
+#define SYS_accept4 288
+#define SYS_signalfd4 289
+#define SYS_eventfd2 290
+#define SYS_epoll_create1 291
+#define SYS_dup3 292
+#define SYS_pipe2 293
+#define SYS_inotify_init1 294
+#define SYS_preadv 295
+#define SYS_pwritev 296
+#define SYS_rt_tgsigqueueinfo 297
+#define SYS_perf_event_open 298
+#define SYS_recvmmsg 299
+#define SYS_fanotify_init 300
+#define SYS_fanotify_mark 301
+#define SYS_prlimit64 302
+#define SYS_name_to_handle_at 303
+#define SYS_open_by_handle_at 304
+#define SYS_clock_adjtime 305
+#define SYS_syncfs 306
+#define SYS_sendmmsg 307
+#define SYS_setns 308
+#define SYS_getcpu 309
+#define SYS_process_vm_readv 310
+#define SYS_process_vm_writev 311
+#define SYS_kcmp 312
+#define SYS_finit_module 313
+
+#undef SYS_fstatat
+#undef SYS_pread
+#undef SYS_pwrite
+#undef SYS_getdents
+#define SYS_fstatat SYS_newfstatat
+#define SYS_pread SYS_pread64
+#define SYS_pwrite SYS_pwrite64
+#define SYS_getdents SYS_getdents64
+#define SYS_fadvise SYS_fadvise64
diff --git a/include/api/aarch64/bits/termios.h b/include/api/aarch64/bits/termios.h
new file mode 100644
index 0000000..61c888f
--- /dev/null
+++ b/include/api/aarch64/bits/termios.h
@@ -0,0 +1,160 @@
+struct termios
+{
+ tcflag_t c_iflag;
+ tcflag_t c_oflag;
+ tcflag_t c_cflag;
+ tcflag_t c_lflag;
+ cc_t c_line;
+ cc_t c_cc[NCCS];
+ speed_t __c_ispeed;
+ speed_t __c_ospeed;
+};
+
+#define VINTR 0
+#define VQUIT 1
+#define VERASE 2
+#define VKILL 3
+#define VEOF 4
+#define VTIME 5
+#define VMIN 6
+#define VSWTC 7
+#define VSTART 8
+#define VSTOP 9
+#define VSUSP 10
+#define VEOL 11
+#define VREPRINT 12
+#define VDISCARD 13
+#define VWERASE 14
+#define VLNEXT 15
+#define VEOL2 16
+
+#define IGNBRK 0000001
+#define BRKINT 0000002
+#define IGNPAR 0000004
+#define PARMRK 0000010
+#define INPCK 0000020
+#define ISTRIP 0000040
+#define INLCR 0000100
+#define IGNCR 0000200
+#define ICRNL 0000400
+#define IUCLC 0001000
+#define IXON 0002000
+#define IXANY 0004000
+#define IXOFF 0010000
+#define IMAXBEL 0020000
+
+#define OPOST 0000001
+#define OLCUC 0000002
+#define ONLCR 0000004
+#define OCRNL 0000010
+#define ONOCR 0000020
+#define ONLRET 0000040
+#define OFILL 0000100
+#define OFDEL 0000200
+#define NLDLY 0000400
+#define NL0 0000000
+#define NL1 0000400
+#define CRDLY 0003000
+#define CR0 0000000
+#define CR1 0001000
+#define CR2 0002000
+#define CR3 0003000
+#define TABDLY 0014000
+#define TAB0 0000000
+#define TAB1 0004000
+#define TAB2 0010000
+#define TAB3 0014000
+#define BSDLY 0020000
+#define BS0 0000000
+#define BS1 0020000
+#define FFDLY 0100000
+#define FF0 0000000
+#define FF1 0100000
+
+#define VTDLY 0040000
+#define VT0 0000000
+#define VT1 0040000
+
+/* ?? */
+#define XTABS 0014000
+
+#define B0 0000000
+#define B50 0000001
+#define B75 0000002
+#define B110 0000003
+#define B134 0000004
+#define B150 0000005
+#define B200 0000006
+#define B300 0000007
+#define B600 0000010
+#define B1200 0000011
+#define B1800 0000012
+#define B2400 0000013
+#define B4800 0000014
+#define B9600 0000015
+#define B19200 0000016
+#define B38400 0000017
+
+#define B57600 0010001
+#define B115200 0010002
+#define B230400 0010003
+#define B460800 0010004
+#define B500000 0010005
+#define B576000 0010006
+#define B921600 0010007
+#define B1000000 0010010
+#define B1152000 0010011
+#define B1500000 0010012
+#define B2000000 0010013
+#define B2500000 0010014
+#define B3000000 0010015
+#define B3500000 0010016
+#define B4000000 0010017
+
+#define CBAUD 0010017
+
+#define CSIZE 0000060
+#define CS5 0000000
+#define CS6 0000020
+#define CS7 0000040
+#define CS8 0000060
+#define CSTOPB 0000100
+#define CREAD 0000200
+#define PARENB 0000400
+#define PARODD 0001000
+#define HUPCL 0002000
+#define CLOCAL 0004000
+
+#define CRTSCTS 020000000000
+
+#define ISIG 0000001
+#define ICANON 0000002
+#define ECHO 0000010
+#define ECHOE 0000020
+#define ECHOK 0000040
+#define ECHONL 0000100
+#define NOFLSH 0000200
+#define TOSTOP 0000400
+#define IEXTEN 0100000
+
+/* Extensions? */
+#define CBAUDEX 0010000
+#define ECHOCTL 0001000
+#define ECHOPRT 0002000
+#define ECHOKE 0004000
+#define FLUSHO 0010000
+#define PENDIN 0040000
+#define EXTPROC 0200000
+
+#define TCOOFF 0
+#define TCOON 1
+#define TCIOFF 2
+#define TCION 3
+
+#define TCIFLUSH 0
+#define TCOFLUSH 1
+#define TCIOFLUSH 2
+
+#define TCSANOW 0
+#define TCSADRAIN 1
+#define TCSAFLUSH 2
--
1.8.5.3

Claudio Fontana

unread,
Mar 25, 2014, 5:28:52 AM3/25/14
to osv...@googlegroups.com, claudio...@huawei.com
From: Claudio Fontana <claudio...@huawei.com>

the functions debug_early, debug_early_u64 and
debug_early_entry can be used very early, before premain.

Signed-off-by: Claudio Fontana <claudio...@huawei.com>
---
core/debug.cc | 23 +++++++++++++++++++++++
include/osv/debug.h | 20 ++++++++++++++++++++
2 files changed, 43 insertions(+)

diff --git a/core/debug.cc b/core/debug.cc
index d3818bf..f9a3543 100644
--- a/core/debug.cc
+++ b/core/debug.cc
@@ -248,4 +248,27 @@ extern "C" {
console::write_ll(msg, strlen(msg));
}

+ void debug_early(const char *msg)
+ {
+ console::write_ll(msg, strlen(msg));
+ }
+
+ void debug_early_u64(const char *msg, unsigned long long val)
+ {
+ char nr[16] = { 0 };
+
+ for (int i = 15; i >= 0; i--) {
+ unsigned char nibble = val & 0x0f;
+ if (nibble <= 9) {
+ nr[i] = nibble + '0';
+ } else {
+ nr[i] = nibble - 0x0a + 'a';
+ }
+ val >>= 4;
+ }
+
+ console::write_ll(msg, strlen(msg));
+ console::write_ll(nr, 16);
+ console::write_ll("\n", 1);
+ }
}
diff --git a/include/osv/debug.h b/include/osv/debug.h
index df30fe4..27838d9 100644
--- a/include/osv/debug.h
+++ b/include/osv/debug.h
@@ -40,6 +40,26 @@ void debug_write(const char *msg, size_t len);
should be used only to debug faults */
void debug_ll(const char *fmt, ...);

+/* an early debug that does not need any c/c++ init before being usable */
+void debug_early(const char *msg);
+void debug_early_u64(const char *msg, unsigned long long val);
+
+#ifdef __aarch64__
+#define debug_early_entry(msg) \
+ { \
+ register unsigned long long lr; \
+ asm("mov %0, x30" : "=r"(lr)); \
+ debug_early_u64(msg " ENTERED, lr=", lr); \
+ } \
+
+#else
+#define debug_early_entry(msg) \
+ { \
+ debug_early(msg " ENTERED\n"); \
+ } \
+
+#endif /* !__aarch64__ */
+
int vkprintf(const char *__restrict fmt, va_list ap)
__attribute__((format(printf, 1, 0)));
int kprintf(const char *__restrict fmt, ...)
--
1.8.5.3

Claudio Fontana

unread,
Mar 25, 2014, 5:28:53 AM3/25/14
to osv...@googlegroups.com, claudio...@huawei.com
From: Claudio Fontana <claudio...@huawei.com>

stub console_init for AArch64.

Signed-off-by: Claudio Fontana <claudio...@huawei.com>
---
drivers/console.cc | 7 +++++++
1 file changed, 7 insertions(+)

diff --git a/drivers/console.cc b/drivers/console.cc
index e09fd78..fad791a 100644
--- a/drivers/console.cc
+++ b/drivers/console.cc
@@ -14,8 +14,11 @@
#include <vector>
#include <sys/ioctl.h>

+#ifdef __x86_64__
#include "isa-serial.hh"
#include "vga.hh"
+#endif /* __x86_64__ */
+
#include "debug-console.hh"
#include <termios.h>
#include <signal.h>
@@ -282,6 +285,9 @@ struct driver console_driver = {

void console_init(bool use_vga)
{
+#ifdef AARCH64_PORT_STUB
+ abort();
+#else /* !AARCH64_PORT_STUB */
auto console_poll_thread = new sched::thread(console_poll,
sched::thread::attr().name("console"));
Console* console;
@@ -293,6 +299,7 @@ void console_init(bool use_vga)
console_poll_thread->start();
console::console.set_impl(console);
device_create(&console_driver, "console", D_CHR);
+#endif /* !AARCH64_PORT_STUB */
}

class console_file : public special_file {
--
1.8.5.3

Claudio Fontana

unread,
Mar 25, 2014, 5:28:54 AM3/25/14
to osv...@googlegroups.com, claudio...@huawei.com
From: Claudio Fontana <claudio...@huawei.com>

protect x64 machine code in #ifdef __x86_64__

Signed-off-by: Claudio Fontana <claudio...@huawei.com>
---
include/osv/trace.hh | 2 ++
1 file changed, 2 insertions(+)

diff --git a/include/osv/trace.hh b/include/osv/trace.hh
index 97bfccb..d4861e1 100644
--- a/include/osv/trace.hh
+++ b/include/osv/trace.hh
@@ -299,6 +299,7 @@ public:
sig = signature();
}
void operator()(r_args... as) {
+#ifdef __x86_64__
asm goto("1: .byte 0x0f, 0x1f, 0x44, 0x00, 0x00 \n\t" // 5-byte nop
".pushsection .tracepoint_patch_sites, \"a\", @progbits \n\t"
".quad %c[id] \n\t"
@@ -309,6 +310,7 @@ public:
: : [type]"i"(&typeid(*this)), [id]"i"(_id) : : slow_path);
return;
slow_path:
+#endif /* __x86_64__ */
trace_slow_path(assign(as...));
}
void trace_slow_path(std::tuple<s_args...> as) __attribute__((cold)) {
--
1.8.5.3

Claudio Fontana

unread,
Mar 25, 2014, 5:28:55 AM3/25/14
to osv...@googlegroups.com, claudio...@huawei.com
From: Claudio Fontana <claudio...@huawei.com>

implementation includes only for the few rels that are actually
encountered during elf::get_init().

Signed-off-by: Claudio Fontana <claudio...@huawei.com>
---
core/elf.cc | 31 +++++++++++++++++++++++++++++++
include/osv/elf.hh | 14 ++++++++++++++
2 files changed, 45 insertions(+)

diff --git a/core/elf.cc b/core/elf.cc
index 293ce20..da815e0 100644
--- a/core/elf.cc
+++ b/core/elf.cc
@@ -228,14 +228,17 @@ void file::load_program_headers()
}
}

+#ifndef AARCH64_PORT_STUB
namespace {

ulong page_size = 4096;

}
+#endif /* !AARCH64_PORT_STUB */

void file::load_segment(const Elf64_Phdr& phdr)
{
+#ifndef AARCH64_PORT_STUB
ulong vstart = align_down(phdr.p_vaddr, page_size);
ulong filesz_unaligned = phdr.p_vaddr + phdr.p_filesz - vstart;
ulong filesz = align_up(filesz_unaligned, page_size);
@@ -244,6 +247,9 @@ void file::load_segment(const Elf64_Phdr& phdr)
_f, align_down(phdr.p_offset, page_size));
memset(_base + vstart + filesz_unaligned, 0, filesz - filesz_unaligned);
mmu::map_anon(_base + vstart + filesz, memsz - filesz, mmu::mmap_fixed, mmu::perm_rwx);
+#else /* AARCH64_PORT_STUB */
+ abort();
+#endif /* AARCH64_PORT_STUB */
}

void object::load_segments()
@@ -281,12 +287,16 @@ void object::load_segments()

void file::unload_segment(const Elf64_Phdr& phdr)
{
+#ifndef AARCH64_PORT_STUB
ulong vstart = align_down(phdr.p_vaddr, page_size);
ulong filesz_unaligned = phdr.p_vaddr + phdr.p_filesz - vstart;
ulong filesz = align_up(filesz_unaligned, page_size);
ulong memsz = align_up(phdr.p_vaddr + phdr.p_memsz, page_size) - vstart;
mmu::munmap(_base + vstart, filesz);
mmu::munmap(_base + vstart + filesz, memsz - filesz);
+#else /* AARCH64_PORT_STUB */
+ abort();
+#endif
}

void object::unload_segments()
@@ -390,6 +400,9 @@ symbol_module object::symbol(unsigned idx)

void object::relocate_rela()
{
+#ifdef AARCH64_PORT_STUB
+ abort();
+#endif
auto rela = dynamic_ptr<Elf64_Rela>(DT_RELA);
assert(dynamic_val(DT_RELAENT) == sizeof(Elf64_Rela));
unsigned nb = dynamic_val(DT_RELASZ) / sizeof(Elf64_Rela);
@@ -1057,6 +1070,7 @@ init_table get_init(Elf64_Ehdr* header)
abort();
};
switch (type) {
+#ifdef __x86_64__
case R_X86_64_NONE:
break;
case R_X86_64_64:
@@ -1083,7 +1097,20 @@ init_table get_init(Elf64_Ehdr* header)
case R_X86_64_IRELATIVE:
*static_cast<void**>(addr) = reinterpret_cast<void *(*)()>(base + addend)();
break;
+#endif /* __x86_64__ */
+#ifdef __aarch64__
+ case R_AARCH64_NONE:
+ case R_AARCH64_NONE2:
+ break;
+ case R_AARCH64_GLOB_DAT:
+ *static_cast<u64*>(addr) = lookup()->st_value + addend;
+ break;
+ case R_AARCH64_TLS_TPREL64:
+ *static_cast<u64*>(addr) = lookup()->st_value + addend;
+ break;
+#endif /* __aarch64__ */
default:
+ debug_early_u64("Unsupported relocation type=", (u64)type);
abort();
}

@@ -1202,5 +1229,9 @@ struct module_and_offset {
extern "C"
void* __tls_get_addr(module_and_offset* mao)
{
+#ifdef AARCH64_PORT_STUB
+ abort();
+#endif /* AARCH64_PORT_STUB */
+
return s_program->tls_addr(mao->module) + mao->offset;
}
diff --git a/include/osv/elf.hh b/include/osv/elf.hh
index df699a9..68586dd 100644
--- a/include/osv/elf.hh
+++ b/include/osv/elf.hh
@@ -208,6 +208,20 @@ enum {
};

enum {
+ R_AARCH64_NONE = 0,
+ R_AARCH64_NONE2 = 256,
+ R_AARCH64_COPY = 1024,
+ R_AARCH64_GLOB_DAT = 1025,
+ R_AARCH64_JUMP_SLOT = 1026,
+ R_AARCH64_RELATIVE = 1027,
+ R_AARCH64_TLS_DTPREL64 = 1028,
+ R_AARCH64_TLS_DTPMOD64 = 1029,
+ R_AARCH64_TLS_TPREL64 = 1030,
+ R_AARCH64_TLSDESC = 1031,
+ R_AARCH64_IRELATIVE = 1032
+ };
+
+enum {
STB_LOCAL = 0, // Not visible outside the object file
STB_GLOBAL = 1, // Global symbol, visible to all object files
STB_WEAK = 2, // Global scope, but with lower precedence than global symbols
--
1.8.5.3

Claudio Fontana

unread,
Mar 25, 2014, 5:28:56 AM3/25/14
to osv...@googlegroups.com, claudio...@huawei.com
From: Claudio Fontana <claudio...@huawei.com>

Signed-off-by: Claudio Fontana <claudio...@huawei.com>
---
fs/procfs/procfs_vnops.cc | 12 ++++++++++++
fs/vfs/vfs_fops.cc | 13 +++++++++++++
2 files changed, 25 insertions(+)

diff --git a/fs/procfs/procfs_vnops.cc b/fs/procfs/procfs_vnops.cc
index 8f7739f..798947d 100644
--- a/fs/procfs/procfs_vnops.cc
+++ b/fs/procfs/procfs_vnops.cc
@@ -203,13 +203,25 @@ procfs_readdir(vnode *vp, file *fp, dirent *dir)
return ENOENT;
}

+#ifdef AARCH64_PORT_STUB
+static std::string procfs_maps_tmp()
+{
+ std::string s("0-0 rwxp 00000000 00:00 0\n");
+ return s;
+}
+#endif /* AARCH64_PORT_STUB */
+
static int
procfs_mount(mount* mp, char *dev, int flags, void* data)
{
auto* vp = mp->m_root->d_vnode;

auto self = make_shared<proc_dir_node>(inode_count++);
+#ifdef AARCH64_PORT_STUB
+ self->add("maps", inode_count++, procfs_maps_tmp);
+#else /* !AARCH64_PORT_STUB */
self->add("maps", inode_count++, mmu::procfs_maps);
+#endif /* !AARCH64_PORT_STUB */

auto* root = new proc_dir_node(vp->v_ino);
root->add("self", self);
diff --git a/fs/vfs/vfs_fops.cc b/fs/vfs/vfs_fops.cc
index 1e64b9b..68ab8c5 100644
--- a/fs/vfs/vfs_fops.cc
+++ b/fs/vfs/vfs_fops.cc
@@ -165,7 +165,12 @@ void* vfs_file::get_page(uintptr_t start, uintptr_t off, size_t size)
assert(VOP_MAP(vp, fp, data) == 0);
vn_unlock(vp);

+#ifdef AARCH64_PORT_STUB
+ abort();
+#else
mmu::add_mapping(map_data.buffer, start);
+#endif /* !AARCH64_PORT_STUB */
+
return io.iov_base + map_data.buf_off;
}

@@ -187,11 +192,18 @@ void vfs_file::put_page(void *addr, uintptr_t start, uintptr_t off, size_t size)
assert(VOP_UNMAP(vp, fp, &data) == 0);
vn_unlock(vp);

+#ifdef AARCH64_PORT_STUB
+ abort();
+#else
mmu::remove_mapping(addr, start);
+#endif /* !AARCH64_PORT_STUB */
}

std::unique_ptr<mmu::file_vma> vfs_file::mmap(addr_range range, unsigned flags, unsigned perm, off_t offset)
{
+#ifdef AARCH64_PORT_STUB
+ abort();
+#else /* !AARCH64_PORT_STUB */
auto fp = this;
struct vnode *vp = fp->f_dentry->d_vnode;
if ((perm & mmu::perm_write) || (!vp->v_op->vop_map)) {
@@ -200,4 +212,5 @@ std::unique_ptr<mmu::file_vma> vfs_file::mmap(addr_range range, unsigned flags,
// Don't know what to do if we have one but not the other
assert(vp->v_op->vop_unmap);
return mmu::map_file_mmap(this, range, flags, perm, offset);

Claudio Fontana

unread,
Mar 25, 2014, 5:28:57 AM3/25/14
to osv...@googlegroups.com, claudio...@huawei.com
From: Claudio Fontana <claudio...@huawei.com>

include/api/x64/atomic.h is not used anywhere.

Signed-off-by: Claudio Fontana <claudio...@huawei.com>
---
include/api/x64/atomic.h | 127 -----------------------------------------------
1 file changed, 127 deletions(-)
delete mode 100644 include/api/x64/atomic.h

diff --git a/include/api/x64/atomic.h b/include/api/x64/atomic.h
deleted file mode 100644
index 0d3da6f..0000000
--- a/include/api/x64/atomic.h
+++ /dev/null
@@ -1,127 +0,0 @@
-#ifndef _INTERNAL_ATOMIC_H
-#define _INTERNAL_ATOMIC_H
-
-#include <stdint.h>
-
-static inline int a_ctz_64(uint64_t x)
-{
- long r;
- __asm__( "bsf %1,%0" : "=r"(r) : "r"(x) );
- return r;
-}
-
-static inline int a_ctz_l(unsigned long x)
-{
- long r;
- __asm__( "bsf %1,%0" : "=r"(r) : "r"(x) );
- return r;
-}
-
-static inline void a_and_64(volatile uint64_t *p, uint64_t v)
-{
- __asm__( "lock ; andq %1, %0"
- : "=m"(*(long *)p) : "r"(v) : "memory" );
-}
-
-static inline void a_or_64(volatile uint64_t *p, uint64_t v)
-{
- __asm__( "lock ; orq %1, %0"
- : "=m"(*(long *)p) : "r"(v) : "memory" );
-}
-
-static inline void a_store_l(volatile void *p, long x)
-{
- __asm__( "movq %1, %0" : "=m"(*(long *)p) : "r"(x) : "memory" );
-}
-
-static inline void a_or_l(volatile void *p, long v)
-{
- __asm__( "lock ; orq %1, %0"
- : "=m"(*(long *)p) : "r"(v) : "memory" );
-}
-
-static inline void *a_cas_p(volatile void *p, void *t, void *s)
-{
- __asm__( "lock ; cmpxchg %3, %1"
- : "=a"(t), "=m"(*(long *)p) : "a"(t), "r"(s) : "memory" );
- return t;
-}
-
-static inline long a_cas_l(volatile void *p, long t, long s)
-{
- __asm__( "lock ; cmpxchg %3, %1"
- : "=a"(t), "=m"(*(long *)p) : "a"(t), "r"(s) : "memory" );
- return t;
-}
-
-static inline int a_cas(volatile int *p, int t, int s)
-{
- __asm__( "lock ; cmpxchgl %3, %1"
- : "=a"(t), "=m"(*p) : "a"(t), "r"(s) : "memory" );
- return t;
-}
-
-static inline void *a_swap_p(void *volatile *x, void *v)
-{
- __asm__( "xchg %0, %1" : "=r"(v), "=m"(*(void **)x) : "0"(v) : "memory" );
- return v;
-}
-static inline long a_swap_l(volatile void *x, long v)
-{
- __asm__( "xchg %0, %1" : "=r"(v), "=m"(*(long *)x) : "0"(v) : "memory" );
- return v;
-}
-
-static inline void a_or(volatile void *p, int v)
-{
- __asm__( "lock ; orl %1, %0"
- : "=m"(*(int *)p) : "r"(v) : "memory" );
-}
-
-static inline void a_and(volatile void *p, int v)
-{
- __asm__( "lock ; andl %1, %0"
- : "=m"(*(int *)p) : "r"(v) : "memory" );
-}
-
-static inline int a_swap(volatile int *x, int v)
-{
- __asm__( "xchg %0, %1" : "=r"(v), "=m"(*x) : "0"(v) : "memory" );
- return v;
-}
-
-#define a_xchg a_swap
-
-static inline int a_fetch_add(volatile int *x, int v)
-{
- __asm__( "lock ; xadd %0, %1" : "=r"(v), "=m"(*x) : "0"(v) : "memory" );
- return v;
-}
-
-static inline void a_inc(volatile int *x)
-{
- __asm__( "lock ; incl %0" : "=m"(*x) : "m"(*x) : "memory" );
-}
-
-static inline void a_dec(volatile int *x)
-{
- __asm__( "lock ; decl %0" : "=m"(*x) : "m"(*x) : "memory" );
-}
-
-static inline void a_store(volatile int *p, int x)
-{
- __asm__( "movl %1, %0" : "=m"(*p) : "r"(x) : "memory" );
-}
-
-static inline void a_spin()
-{
- __asm__ __volatile__( "pause" : : : "memory" );
-}
-
-static inline void a_crash()
-{
- __asm__ __volatile__( "hlt" : : : "memory" );
-}
-
-
-#endif
--
1.8.5.3

Claudio Fontana

unread,
Mar 25, 2014, 5:28:58 AM3/25/14
to osv...@googlegroups.com, claudio...@huawei.com
From: Claudio Fontana <claudio...@huawei.com>

Signed-off-by: Claudio Fontana <claudio...@huawei.com>
---
core/mempool.cc | 16 +++++++++++++++-
core/mmio.cc | 4 ++++
2 files changed, 19 insertions(+), 1 deletion(-)

diff --git a/core/mempool.cc b/core/mempool.cc
index 8102c4e..0b44c92 100644
--- a/core/mempool.cc
+++ b/core/mempool.cc
@@ -244,6 +244,11 @@ void pool::add_page()
header->local_free = obj;
}
_free->push_back(*header);
+ if (_free->empty()) {
+ /* encountered when starting to enable TLS for AArch64 in mixed
+ LE / IE tls models */
+ abort();
+ }
}
}

@@ -864,7 +869,8 @@ static void* early_alloc_page()
{
WITH_LOCK(free_page_ranges_lock) {
if (free_page_ranges.empty()) {
- abort("alloc_page(): out of memory\n");
+ debug_early("early_alloc_page(): out of memory\n");
+ abort();
}

auto p = &*free_page_ranges.begin();
@@ -1151,6 +1157,9 @@ static const size_t pad_after = mmu::page_size;

void* malloc(size_t size)
{
+#ifdef AARCH64_PORT_STUB
+ abort();
+#else /* !AARCH64_PORT_STUB */
if (!enabled) {
return std_malloc(size);
}
@@ -1167,10 +1176,14 @@ void* malloc(size_t size)
uint8_t garbage = 3;
std::generate_n(static_cast<uint8_t*>(v), size, [&] { return garbage++; });
return v;
+#endif /* !AARCH64_PORT_STUB */
}

void free(void* v)
{
+#ifdef AARCH64_PORT_STUB
+ abort();
+#else /* !AARCH64_PORT_STUB */
if (v < debug_base) {
return std_free(v);
}
@@ -1183,6 +1196,7 @@ void free(void* v)
mmu::vdepopulate(h, mmu::page_size);
mmu::vdepopulate(v, asize);
mmu::vcleanup(h, pad_before + asize);
+#endif /* !AARCH64_PORT_STUB */
}

void* realloc(void* v, size_t size)
diff --git a/core/mmio.cc b/core/mmio.cc
index cebd2cc..3b19947 100644
--- a/core/mmio.cc
+++ b/core/mmio.cc
@@ -53,9 +53,13 @@ u64 mmio_getq(mmioaddr_t addr)

mmioaddr_t mmio_map(u64 paddr, size_t size_bytes)
{
+#ifdef AARCH64_PORT_STUB
+ abort();
+#else /* !AARCH64_PORT_STUB */
char* map_to = mmu::phys_mem + paddr;
linear_map(map_to, paddr, size_bytes);
return map_to;
+#endif /* !AARCH64_PORT_STUB */
}

void mmio_unmap(mmioaddr_t addr, size_t size_bytes)
--
1.8.5.3

Claudio Fontana

unread,
Mar 25, 2014, 5:28:59 AM3/25/14
to osv...@googlegroups.com, claudio...@huawei.com
From: Claudio Fontana <claudio...@huawei.com>

Signed-off-by: Claudio Fontana <claudio...@huawei.com>
---
core/sched.cc | 8 ++++++++
1 file changed, 8 insertions(+)

diff --git a/core/sched.cc b/core/sched.cc
index 1c23512..6885aa4 100644
--- a/core/sched.cc
+++ b/core/sched.cc
@@ -12,7 +12,11 @@
#include <osv/debug.hh>
#include <osv/irqlock.hh>
#include <osv/align.hh>
+
+#ifndef AARCH64_PORT_STUB
#include <osv/interrupt.hh>
+#endif /* !AARCH64_PORT_STUB */
+
#include "smp.hh"
#include "osv/trace.hh"
#include <osv/percpu.hh>
@@ -54,7 +58,9 @@ bool __thread need_reschedule = false;

elf::tls_data tls;

+#ifndef AARCH64_PORT_STUB
inter_processor_interrupt wakeup_ipi{[] {}};
+#endif /* !AARCH64_PORT_STUB */

// "tau" controls the length of the history we consider for scheduling,
// or more accurately the rate of decay of an exponential moving average.
@@ -315,10 +321,12 @@ void cpu::idle_poll_end()

void cpu::send_wakeup_ipi()
{
+#ifndef AARCH64_PORT_STUB
std::atomic_thread_fence(std::memory_order_seq_cst);
if (!idle_poll.load(std::memory_order_relaxed)) {
wakeup_ipi.send(this);
}
+#endif /* !AARCH64_PORT_STUB */
}

void cpu::do_idle()
--
1.8.5.3

Claudio Fontana

unread,
Mar 25, 2014, 5:29:00 AM3/25/14
to osv...@googlegroups.com, claudio...@huawei.com
From: Claudio Fontana <claudio...@huawei.com>

Signed-off-by: Claudio Fontana <claudio...@huawei.com>
---
loader.cc | 37 +++++++++++++++++++++++++++++++------
runtime.cc | 8 +++++++-
2 files changed, 38 insertions(+), 7 deletions(-)

diff --git a/loader.cc b/loader.cc
index 6124764..47b36e9 100644
--- a/loader.cc
+++ b/loader.cc
@@ -5,7 +5,10 @@
* BSD license as described in the LICENSE file in the top-level directory.
*/

+#ifdef __x86_64__
#include "drivers/isa-serial.hh"
+#endif /* __x86_64__ */
+
#include "fs/fs.hh"
#include <bsd/net.hh>
#include <boost/format.hpp>
@@ -14,12 +17,14 @@
#include <cctype>
#include <osv/elf.hh>
#include <osv/tls.hh>
-#include "exceptions.hh"
#include <osv/debug.hh>
-#include "drivers/pci.hh"
+
#include "smp.hh"
-#include "ioapic.hh"

+#ifndef AARCH64_PORT_STUB
+#include "exceptions.hh"
+#include "drivers/pci.hh"
+#include "ioapic.hh"
#include "drivers/acpi.hh"
#include "drivers/driver.hh"
#include "drivers/virtio-net.hh"
@@ -31,10 +36,10 @@
#include "drivers/ide.hh"
#include "drivers/vmw-pvscsi.hh"
#include "drivers/vmxnet3.hh"
+#include "drivers/pvpanic.hh"
+#endif /* !AARCH64_PORT_STUB */

#include <osv/sched.hh>
-#include "drivers/console.hh"
-#include "drivers/pvpanic.hh"
#include <osv/barrier.hh>
#include "arch.hh"
#include "arch-setup.hh"
@@ -58,7 +63,13 @@ asm(".pushsection \".debug_gdb_scripts\", \"MS\",@progbits,1 \n"
".asciz \"scripts/loader.py\" \n"
".popsection \n");

-elf::Elf64_Ehdr* elf_header;
+#ifdef AARCH64_PORT_STUB
+#define ALIGN_ELF_HEADER_ADDR 4096
+#else
+#define ALIGN_ELF_HEADER_ADDR 8
+#endif
+elf::Elf64_Ehdr* elf_header __attribute__ ((aligned(ALIGN_ELF_HEADER_ADDR)));
+
size_t elf_size;
void* elf_start;
elf::tls_data tls_data;
@@ -96,15 +107,27 @@ void premain()
(*init)();
}
boot_time.event(".init functions");
+
+#ifdef AARCH64_PORT_STUB
+ printf("OSv AArch64: end of premain reached, halting.\n");
+ while (1) {
+ asm ("wfi;");
+ }
+#endif /* AARCH64_PORT_STUB */
}

int main(int ac, char **av)
{
+ printf("OSv " OSV_VERSION "\n");
+
+#ifndef AARCH64_PORT_STUB
smp_initial_find_current_cpu()->init_on_cpu();
void main_cont(int ac, char** av);
sched::init([=] { main_cont(ac, av); });
+#endif /* !AARCH64_PORT_STUB */
}

+#ifndef AARCH64_PORT_STUB
static bool opt_leak = false;
static bool opt_noshutdown = false;
static bool opt_log_backtrace = false;
@@ -427,5 +450,7 @@ void main_cont(int ac, char** av)
}
}

+#endif /* !AARCH64_PORT_STUB */
+
int __argc;
char** __argv;
diff --git a/runtime.cc b/runtime.cc
index c5e0865..466beaa 100644
--- a/runtime.cc
+++ b/runtime.cc
@@ -84,6 +84,10 @@ static void print_backtrace(void)
int len;

debug_ll("\n[backtrace]\n");
+#ifdef AARCH64_PORT_STUB
+ debug_ll("NIY\n");
+ return;
+#endif

len = backtrace_safe(addrs, 128);

@@ -114,7 +118,7 @@ void abort()
void abort(const char *fmt, ...)
{
if (!already_aborted) {
- processor::cli();
+ arch::irq_disable();
already_aborted = true;

static char msg[1024];
@@ -126,7 +130,9 @@ void abort(const char *fmt, ...)

debug_ll(msg);
print_backtrace();
+#ifndef AARCH64_PORT_STUB
panic::pvpanic::panicked();
+#endif /* !AARCH64_PORT_STUB */
}
osv::halt();
}
--
1.8.5.3

Claudio Fontana

unread,
Mar 25, 2014, 5:29:01 AM3/25/14
to osv...@googlegroups.com, claudio...@huawei.com
From: Claudio Fontana <claudio...@huawei.com>

This should build and reach end of premain.

See PORTING for some initial build instructions.

Signed-off-by: Claudio Fontana <claudio...@huawei.com>
---
PORTING | 96 ++++++++++++++++++++++++++++++
build.mk | 202 +++++++++++++++++++++++++++++++++++++++++----------------------
2 files changed, 227 insertions(+), 71 deletions(-)
create mode 100644 PORTING

diff --git a/PORTING b/PORTING
new file mode 100644
index 0000000..78382bb
--- /dev/null
+++ b/PORTING
@@ -0,0 +1,96 @@
+AArch64 Port
+============
+
+The AArch64 Port is being started, initially targeting the QEMU Mach-virt
+platform, and running on the Foundation Model v8.
+
+These are some brief instructions about how to cross-compile OSv's
+loader.img (very incomplete still) on an X86-64 build host machine.
+
+------------------------------
+Environment Variables for make
+------------------------------
+
+In addition to the general requirements (see README.md),
+note that the simple build system recognizes the CROSS_PREFIX
+environment variable, and looks for build tools prefixed with its contents.
+
+Alternatively, the following variables can be used to control the tools to use:
+
+CXX The target C++ compiler
+HOST_CXX The build host C++ compiler
+CC The target C compiler
+LD The target linker
+STRIP The target strip
+OBJCOPY The target objcopy
+
+If for some reason the ARCH-detection code does not work, it is possible to use
+
+ARCH=aarch64
+
+to force the target architecture to AArch64.
+
+---------------------------------------
+Crosscompiler Tools & Image from Linaro
+---------------------------------------
+
+You can find a [ 32bit :-( needs multilib] crosscompiler from Linaro,
+in particular the package
+
+gcc-linaro-aarch64-linux-gnu-4.8-2013.12_linux,
+
+which is not distro-specific [ :-) ], and includes all tools needed.
+
+For debugging purposes, a standalone gdb package for target AAarch64
+can be also downloaded from the Linaro web site.
+
+For the root filesystem for AArch64, a good option is the Linaro LEG Image
+
+linaro-image-leg-java-genericarmv8-20131215-598.rootfs.tar.gz
+
+http://www.linaro.org/downloads/
+
+------------------------------
+Crosscompiler Tools for Ubuntu
+------------------------------
+
+For Ubuntu there are AArch64 crosscompilers available in the official
+repositories as well e..g packages
+
+g++-4.8-aarch64-linux-gnu
+gcc-4.8-aarch64-linux-gnu
+
+
+--------------------------------------
+ARMv8 Foundation Model guest debugging
+--------------------------------------
+
+In ARMv8 Foundation model it would be possible to debug the guest kernel
+via the following setup:
+
+1. Start Foundation model with options
+
+--network=nat --network-nat-ports=1234=1234
+
+The latter option will expose the gdb port used by QEMU on the host side
+(default port 1234) to the same port number in the guest running inside
+the model.
+
+2. If you are skipping the user space initialization via something like
+init=/bin/sh for speedup, in Foundation model you will need to run at least:
+
+/sbin/udhcpc eth0
+
+3. In Foundation model start qemu-system-aarch64 with the -s -S options
+
+4. On the host side, open gdb in a new terminal window and attach to the
+guest kernel with the command:
+
+target remote :1234
+
+This is not currently functional due to unimplemented support in
+KVM/QEMU.
+
+---
+Jani Kokkonen <jani.k...@huawei.com>
+Claudio Fontana <claudio...@huawei.com>
diff --git a/build.mk b/build.mk
index ab1e07d..9bfa8e1 100644
--- a/build.mk
+++ b/build.mk
@@ -1,10 +1,14 @@
ifndef CROSS_PREFIX
HOST_CXX=$(CXX)
+ STRIP=strip
+ OBJCOPY=objcopy
else
HOST_CXX=g++
CXX=$(CROSS_PREFIX)g++
CC=$(CROSS_PREFIX)gcc
LD=$(CROSS_PREFIX)ld
+ STRIP=$(CROSS_PREFIX)strip
+ OBJCOPY=$(CROSS_PREFIX)objcopy
endif

detect_arch=$(shell echo $(1) | $(CC) -E -xc - | tail -n 1)
@@ -42,8 +46,12 @@ gcc-inc-base3 := $(dir $(shell dirname `find $(gccbase)/ -name c++config.h | gre

INCLUDES += -isystem $(gcc-inc-base)
INCLUDES += -isystem $(gcc-inc-base3)
+
+ifeq ($(arch),x64)
INCLUDES += -isystem $(src)/external/$(arch)/acpica/source/include
-INCLUDES += -isystem $(src)/external/$(arch)/misc.bin/usr/include
+endif
+
+INCLUDES += -isystem $(miscbase)/usr/include
INCLUDES += -isystem $(src)/include/api
INCLUDES += -isystem $(src)/include/api/$(arch)
# must be after include/api, since it includes some libc-style headers:
@@ -127,6 +135,15 @@ ifeq ($(arch),x64)
arch-cflags = -msse4.1
endif

+ifeq ($(arch),aarch64)
+# BUGS: you will die horribly without -mstrict-align, probably due to
+# unaligned access to a mutex variable with ldst exclusive.
+# Also, mixed TLS models resulted in different var addresses seen by
+# different objects depending on the TLS model used.
+# Force all __thread variables encountered to local exec.
+arch-cflags = -mstrict-align -mtls-dialect=desc -ftls-model=local-exec -DAARCH64_PORT_STUB
+endif
+
quiet = $(if $V, $1, @echo " $2"; $1)
very-quiet = $(if $V, $1, @$1)

@@ -262,6 +279,8 @@ tools += tools/route/lsroute.so
tools += tools/mkfs/mkfs.so
tools += tools/cpiod/cpiod.so

+ifeq ($(arch),x64)
+
all: loader.img loader.bin usr.img

boot.bin: arch/x64/boot16.ld arch/x64/boot16.o
@@ -271,25 +290,77 @@ image-size = $(shell stat --printf %s lzloader.elf)

loader-stripped.elf: loader.elf
$(call very-quiet, cp loader.elf loader-stripped.elf)
- $(call quiet, strip loader-stripped.elf, STRIP loader.elf)
+ $(call quiet, $(STRIP) loader-stripped.elf, STRIP loader.elf)

loader.img: boot.bin lzloader.elf
$(call quiet, dd if=boot.bin of=$@ > /dev/null 2>&1, DD $@ boot.bin)
$(call quiet, dd if=lzloader.elf of=$@ conv=notrunc seek=128 > /dev/null 2>&1, \
- DD $@ loader.elf)
+ DD $@ lzloader.elf)
$(call quiet, $(src)/scripts/imgedit.py setsize $@ $(image-size), IMGEDIT $@)
$(call quiet, $(src)/scripts/imgedit.py setargs $@ $(cmdline), IMGEDIT $@)

-loader-size = $(shell stat --printf %s loader.img)
-zfs-start = $(shell echo $$(($(loader-size)+2097151 & ~2097151)))
-zfs-size = $(shell echo $$(($(fs_size_mb) * 1024 * 1024 - $(zfs-start))))
-
loader.bin: arch/x64/boot32.o arch/x64/loader32.ld
$(call quiet, $(LD) -nostartfiles -static -nodefaultlibs -o $@ \
$(filter-out %.bin, $(^:%.ld=-T %.ld)), LD $@)

arch/x64/boot32.o: loader.elf

+fastlz/fastlz.o:
+ $(makedir)
+ $(call quiet, $(CXX) $(CXXFLAGS) -O2 -m32 -o $@ -c $(src)/fastlz/fastlz.cc, CXX $@)
+
+fastlz/lz: fastlz/fastlz.cc fastlz/lz.cc
+ $(makedir)
+ $(call quiet, $(CXX) $(CXXFLASG) -O2 -o $@ $(filter %.cc, $^), CXX $@)
+
+loader-stripped.elf.lz.o: loader-stripped.elf fastlz/lz
+ $(call quiet, $(out)/fastlz/lz $(out)/loader-stripped.elf, LZ $@)
+ $(call quiet, objcopy -B i386 -I binary -O elf32-i386 loader-stripped.elf.lz $@, OBJCOPY $@)
+
+fastlz/lzloader.o: fastlz/lzloader.cc
+ $(call quiet, $(CXX) $(CXXFLAGS) -O2 -m32 -o $@ -c $(src)/fastlz/lzloader.cc, CXX $@)
+
+lzloader.elf: loader-stripped.elf.lz.o fastlz/lzloader.o arch/x64/lzloader.ld \
+ fastlz/fastlz.o
+ $(call quiet, $(src)/scripts/check-image-size.sh loader-stripped.elf 23068672)
+ $(call quiet, $(LD) -o $@ \
+ -Bdynamic --export-dynamic --eh-frame-hdr --enable-new-dtags \
+ -T $(src)/arch/x64/lzloader.ld \
+ $(patsubst %.o,$(out)/%.o, $(filter %.o, $^)), LD $@)
+
+acpi-defines = -DACPI_MACHINE_WIDTH=64 -DACPI_USE_LOCAL_CACHE
+
+acpi-source := $(shell find $(src)/external/$(arch)/acpica/source/components -type f -name '*.c')
+acpi = $(patsubst $(src)/%.c, %.o, $(acpi-source))
+
+$(acpi): CFLAGS += -fno-strict-aliasing -Wno-strict-aliasing
+
+endif # x64
+
+ifeq ($(arch),aarch64)
+
+all: loader.img
+
+preboot.elf: arch/$(arch)/preboot.ld arch/$(arch)/preboot.o
+ $(call quiet, $(LD) -o $@ -T $^, LD $@)
+
+preboot.bin: preboot.elf
+ $(call quiet, $(OBJCOPY) -O binary $^ $@, OBJCOPY $@)
+
+image-size = $(shell stat --printf %s loader-stripped.elf)
+
+loader-stripped.elf: loader.elf
+ $(call very-quiet, cp loader.elf loader-stripped.elf)
+ $(call quiet, $(STRIP) loader-stripped.elf, STRIP loader.elf)
+
+loader.img: preboot.bin loader-stripped.elf
+ $(call quiet, dd if=preboot.bin of=$@ > /dev/null 2>&1, DD $@ preboot.bin)
+ $(call quiet, dd if=loader-stripped.elf of=$@ conv=notrunc obs=4096 seek=16 > /dev/null 2>&1, DD $@ loader-stripped.elf)
+ $(call quiet, $(src)/scripts/imgedit.py setsize $@ $(image-size), IMGEDIT $@)
+ $(call quiet, $(src)/scripts/imgedit.py setargs $@ $(cmdline), IMGEDIT $@)
+
+endif # aarch64
+
bsd/sys/crypto/sha2/sha2.o: CFLAGS+=-Wno-strict-aliasing

include $(src)/bsd/cddl/contrib/opensolaris/lib/libuutil/common/build.mk
@@ -384,6 +455,7 @@ bsd += bsd/sys/xdr/xdr.o
bsd += bsd/sys/xdr/xdr_array.o
bsd += bsd/sys/xdr/xdr_mem.o

+ifeq ($(arch),x64)
bsd/%.o: COMMON += -DXEN -DXENHVM
bsd += bsd/sys/xen/gnttab.o
bsd += bsd/sys/xen/evtchn.o
@@ -393,6 +465,7 @@ bsd += bsd/sys/xen/xenbus/xenbusb.o
bsd += bsd/sys/xen/xenbus/xenbusb_front.o
bsd += bsd/sys/dev/xen/netfront/netfront.o
bsd += bsd/sys/dev/xen/blkfront/blkfront.o
+endif

bsd/sys/%.o: COMMON += -Wno-sign-compare -Wno-narrowing -Wno-write-strings -Wno-parentheses -Wno-unused-but-set-variable

@@ -559,17 +632,22 @@ libtsm += drivers/libtsm/tsm_screen.o
libtsm += drivers/libtsm/tsm_vte.o
libtsm += drivers/libtsm/tsm_vte_charsets.o

-drivers :=
-drivers += drivers/console.o drivers/vga.o drivers/kbd.o drivers/isa-serial.o
-drivers += drivers/debug-console.o
+drivers := $(bsd) $(solaris)
+drivers += drivers/console.o
+drivers += arch/$(arch)/debug-console.o
+drivers += drivers/clock.o
+drivers += drivers/clockevent.o
drivers += drivers/ramdisk.o
-drivers += $(bsd) $(solaris) $(libtsm)
-drivers += core/mmu.o
drivers += core/elf.o
+
+ifeq ($(arch),x64)
+drivers += $(libtsm)
+drivers += drivers/vga.o drivers/kbd.o drivers/isa-serial.o
+drivers += core/mmu.o
drivers += core/interrupt.o
drivers += core/pvclock-abi.o
drivers += drivers/device.o
-drivers += drivers/pci-device.o drivers/pci-function.o drivers/pci-bridge.o
+drivers += drivers/pci-device.o drivers/pci-function.o drivers/pci-bridge.o
drivers += drivers/driver.o
drivers += drivers/virtio.o
drivers += drivers/virtio-vring.o
@@ -579,8 +657,7 @@ drivers += drivers/vmxnet3-queues.o
drivers += drivers/virtio-blk.o
drivers += drivers/virtio-scsi.o
drivers += drivers/virtio-rng.o
-drivers += drivers/clock.o drivers/kvmclock.o drivers/xenclock.o
-drivers += drivers/clockevent.o
+drivers += drivers/kvmclock.o drivers/xenclock.o
drivers += drivers/acpi.o
drivers += drivers/hpet.o
drivers += drivers/xenfront.o drivers/xenfront-xenbus.o drivers/xenfront-blk.o
@@ -588,30 +665,38 @@ drivers += drivers/pvpanic.o
drivers += drivers/random.o
drivers += drivers/ahci.o
drivers += drivers/ide.o
+drivers += drivers/pci.o
drivers += drivers/scsi-common.o
drivers += drivers/vmw-pvscsi.o
drivers += java/jvm_balloon.o
drivers += java/java_api.o
+endif # x64
+
+objects := bootfs.o
+objects += arch/$(arch)/arch-setup.o
+objects += arch/$(arch)/signal.o
+objects += arch/$(arch)/string.o
+objects += arch/$(arch)/arch-cpu.o
+objects += arch/$(arch)/backtrace.o
+objects += arch/$(arch)/smp.o
+objects += arch/$(arch)/elf-dl.o
+objects += arch/$(arch)/entry.o

-objects = bootfs.o
+ifeq ($(arch),x64)
objects += arch/x64/dump.o
objects += arch/x64/exceptions.o
-objects += arch/x64/entry.o
objects += arch/x64/ioapic.o
objects += arch/x64/mmu.o
objects += arch/x64/math.o
objects += arch/x64/apic.o
objects += arch/x64/apic-clock.o
-objects += arch/x64/arch-setup.o
-objects += arch/x64/smp.o
-objects += arch/x64/signal.o
objects += arch/x64/cpuid.o
-objects += arch/x64/string.o
-objects += arch/x64/arch-cpu.o
objects += arch/x64/entry-xen.o
objects += arch/x64/xen.o
-objects += arch/x64/backtrace.o
objects += arch/x64/xen_intr.o
+objects += $(acpi)
+endif # x64
+
objects += core/spinlock.o
objects += core/lfmutex.o
objects += core/rwlock.o
@@ -619,11 +704,10 @@ objects += core/semaphore.o
objects += core/condvar.o
objects += core/debug.o
objects += core/rcu.o
-objects += drivers/pci.o
objects += core/mempool.o
objects += core/alloctracker.o
objects += core/printf.o
-objects += arch/x64/elf-dl.o
+
objects += linux.o
objects += core/commands.o
objects += core/sched.o
@@ -652,23 +736,25 @@ include $(src)/libc/build.mk

objects += $(addprefix fs/, $(fs))
objects += $(addprefix libc/, $(libc))
-objects += $(acpi)
-
-acpi-defines = -DACPI_MACHINE_WIDTH=64 -DACPI_USE_LOCAL_CACHE
-
-acpi-source := $(shell find $(src)/external/$(arch)/acpica/source/components -type f -name '*.c')
-acpi = $(patsubst $(src)/%.c, %.o, $(acpi-source))
-
-$(acpi): CFLAGS += -fno-strict-aliasing -Wno-strict-aliasing

libstdc++.a = $(shell find $(gccbase)/ -name libstdc++.a)
libsupc++.a = $(shell find $(gccbase)/ -name libsupc++.a)
libgcc_s.a = $(shell find $(gccbase)/ -name libgcc.a | grep -v /32/)
libgcc_eh.a = $(shell find $(gccbase)/ -name libgcc_eh.a | grep -v /32/)

-loader.elf: arch/x64/boot.o arch/x64/loader.ld loader.o runtime.o $(drivers) \
- $(objects) dummy-shlib.so \
- bootfs.bin
+boost-lib-dir := $(shell dirname `find $(miscbase)/ -name libboost_system-mt.a`)
+
+boost-libs := $(boost-lib-dir)/libboost_program_options-mt.a \
+ $(boost-lib-dir)/libboost_system-mt.a
+
+$(boost-tests): $(boost-lib-dir)/libboost_unit_test_framework-mt.so \
+ $(boost-lib-dir)/libboost_filesystem-mt.so
+
+dummy-shlib.so: dummy-shlib.o
+ $(call quiet, $(CXX) -nodefaultlibs -shared -o $@ $^, LD $@)
+
+loader.elf: arch/$(arch)/boot.o arch/$(arch)/loader.ld loader.o runtime.o $(drivers) \
+ $(objects) dummy-shlib.so bootfs.bin
$(call quiet, $(LD) -o $@ \
-Bdynamic --export-dynamic --eh-frame-hdr --enable-new-dtags \
$(filter-out %.bin, $(^:%.ld=-T %.ld)) \
@@ -678,46 +764,15 @@ loader.elf: arch/x64/boot.o arch/x64/loader.ld loader.o runtime.o $(drivers) \
--no-whole-archive, \
LD $@)

-fastlz/fastlz.o:
- $(makedir)
- $(call quiet, $(CXX) $(CXXFLAGS) -O2 -m32 -o $@ -c $(src)/fastlz/fastlz.cc, CXX $@)
-
-fastlz/lz: fastlz/fastlz.cc fastlz/lz.cc
- $(makedir)
- $(call quiet, $(CXX) $(CXXFLASG) -O2 -o $@ $(filter %.cc, $^), CXX $@)
-
-loader-stripped.elf.lz.o: loader-stripped.elf fastlz/lz
- $(call quiet, $(out)/fastlz/lz $(out)/loader-stripped.elf, LZ $@)
- $(call quiet, objcopy -B i386 -I binary -O elf32-i386 loader-stripped.elf.lz $@, OBJCOPY $@)
-
-fastlz/lzloader.o: fastlz/lzloader.cc
- $(call quiet, $(CXX) $(CXXFLAGS) -O2 -m32 -o $@ -c $(src)/fastlz/lzloader.cc, CXX $@)
-
-lzloader.elf: loader-stripped.elf.lz.o fastlz/lzloader.o arch/x64/lzloader.ld \
- fastlz/fastlz.o
- $(call quiet, $(src)/scripts/check-image-size.sh loader-stripped.elf 23068672)
- $(call quiet, $(LD) -o $@ \
- -Bdynamic --export-dynamic --eh-frame-hdr --enable-new-dtags \
- -T $(src)/arch/x64/lzloader.ld \
- $(patsubst %.o,$(out)/%.o, $(filter %.o, $^)), LD $@)
-
-
-dummy-shlib.so: dummy-shlib.o
- $(call quiet, $(CXX) -nodefaultlibs -shared -o $@ $^, LD $@)
-
-boost-lib-dir := $(shell dirname `find $(miscbase)/ -name libboost_system-mt.a`)
-
-boost-libs := $(boost-lib-dir)/libboost_program_options-mt.a \
- $(boost-lib-dir)/libboost_system-mt.a
-
-$(boost-tests): $(boost-lib-dir)/libboost_unit_test_framework-mt.so \
- $(boost-lib-dir)/libboost_filesystem-mt.so
-
bsd/%.o: COMMON += -DSMP -D'__FBSDID(__str__)=extern int __bogus__'

jni = java/jni/balloon.so java/jni/elf-loader.so java/jni/networking.so \
java/jni/stty.so java/jni/tracepoint.so java/jni/power.so java/jni/monitor.so

+loader-size = $(shell stat --printf %s loader.img)
+zfs-start = $(shell echo $$(($(loader-size)+2097151 & ~2097151)))
+zfs-size = $(shell echo $$(($(fs_size_mb) * 1024 * 1024 - $(zfs-start))))
+
bare.raw: loader.img
$(call quiet, qemu-img create $@ 100M, QEMU-IMG CREATE $@)
$(call quiet, dd if=loader.img of=$@ conv=notrunc > /dev/null 2>&1)
@@ -744,12 +799,17 @@ osv.vmdk osv.vdi:

$(jni): INCLUDES += -I /usr/lib/jvm/java/include -I /usr/lib/jvm/java/include/linux/

+ifeq ($(arch),aarch64)
+bootfs.bin:
+ touch bootfs.bin
+else
bootfs.bin: scripts/mkbootfs.py $(java-targets) $(out)/bootfs.manifest $(tests) $(java_tests) $(tools) \
tests/testrunner.so \
zpool.so zfs.so
$(call quiet, $(src)/scripts/mkbootfs.py -o $@ -d $@.d -m $(out)/bootfs.manifest \
-D jdkbase=$(jdkbase) -D gccbase=$(gccbase) -D \
glibcbase=$(glibcbase) -D miscbase=$(miscbase), MKBOOTFS $@)
+endif

bootfs.o: bootfs.bin

--
1.8.5.3

Claudio Fontana

unread,
Mar 25, 2014, 5:29:02 AM3/25/14
to osv...@googlegroups.com, claudio...@huawei.com
From: Claudio Fontana <claudio...@huawei.com>

trying to stay clear of apparent random limitations
during boot early stage with the model.
Terminate AArch64 execution in main after printing the args.

Signed-off-by: Claudio Fontana <claudio...@huawei.com>
---
arch/aarch64/arch-setup.cc | 25 +++++++++++++++++++++++++
arch/aarch64/boot.S | 12 +++++++-----
arch/aarch64/loader.ld | 2 ++
loader.cc | 18 ++++++++++++------
4 files changed, 46 insertions(+), 11 deletions(-)

diff --git a/arch/aarch64/arch-setup.cc b/arch/aarch64/arch-setup.cc
index d72d421..cc11d9c 100644
--- a/arch/aarch64/arch-setup.cc
+++ b/arch/aarch64/arch-setup.cc
@@ -22,6 +22,27 @@ extern size_t elf_size;
extern void* elf_start;
extern boot_time_chart boot_time;

+char *cmdline;
+
+extern char** __argv;
+extern int __argc;
+
+void parse_cmdline(char* cmdline)
+{
+ char* p = cmdline;
+ char* cmd = strdup(cmdline);
+
+ static std::vector<char*> args;
+ char* save;
+ while ((p = strtok_r(cmd, " \t\n", &save)) != nullptr) {
+ args.push_back(p);
+ cmd = nullptr;
+ }
+ args.push_back(nullptr);
+ __argv = args.data();
+ __argc = args.size() - 1;
+}
+
void arch_setup_free_memory()
{
register u64 edata;
@@ -35,6 +56,10 @@ void arch_setup_free_memory()
addr = addr & ~0xffffull;

memory::free_initial_memory_range((void*)addr, 0x20000000);
+
+ extern char cmdline_addr[];
+ cmdline = cmdline_addr;
+ parse_cmdline(cmdline);
}

void arch_setup_tls(thread_control_block *tcb)
diff --git a/arch/aarch64/boot.S b/arch/aarch64/boot.S
index 0674a1f..9be1404 100644
--- a/arch/aarch64/boot.S
+++ b/arch/aarch64/boot.S
@@ -28,13 +28,15 @@ start_elf:
mov x29, xzr
mov x30, xzr
bl premain
- /*
+
adrp x2, __argc
- ldr x0, [x2]
+ ldr x0, [x2, #:lo12:__argc]
adrp x2, __argv
- ldr x1, [x2]
- b main
- */
+ ldr x1, [x2, #:lo12:__argv]
+ bl main
+
+ bl halt
+
sctrl_init:
.quad 0x34d5cb80

diff --git a/arch/aarch64/loader.ld b/arch/aarch64/loader.ld
index a027cbc..c8eff22 100644
--- a/arch/aarch64/loader.ld
+++ b/arch/aarch64/loader.ld
@@ -17,6 +17,8 @@ SECTIONS
* We can't export the ELF header base as a symbol, because ld
* insists on moving stuff around if we do.
*/
+ cmdline_addr = 0x40080200;
+
. = 0x40091000;

.dynamic : ALIGN(16) { *(.dynamic) } : dynamic : text
diff --git a/loader.cc b/loader.cc
index 47b36e9..2eed6fe 100644
--- a/loader.cc
+++ b/loader.cc
@@ -107,18 +107,24 @@ void premain()
(*init)();
}
boot_time.event(".init functions");
+}
+
+int main(int ac, char **av)
+{
+ printf("OSv " OSV_VERSION "\n");

#ifdef AARCH64_PORT_STUB
- printf("OSv AArch64: end of premain reached, halting.\n");
+ printf("argc=%d\n", ac);
+
+ for (int i = 0; i < ac; i++) {
+ printf("argv[%d] = %s\n", i, av[i]);
+ }
+
+ printf("OSv AArch64: main reached, halting.\n");
while (1) {
asm ("wfi;");
}
#endif /* AARCH64_PORT_STUB */
-}
-
-int main(int ac, char **av)
-{
- printf("OSv " OSV_VERSION "\n");

#ifndef AARCH64_PORT_STUB
smp_initial_find_current_cpu()->init_on_cpu();
--
1.8.5.3

Pekka Enberg

unread,
Mar 25, 2014, 5:36:14 AM3/25/14
to Claudio Fontana, Osv Dev, Claudio Fontana, Avi Kivity
On Tue, Mar 25, 2014 at 11:28 AM, Claudio Fontana <hw.cl...@gmail.com> wrote:
> This is v2 of the patch series that enables first stubbed support
> for AArch64.
>
> They are also available at the following repo:
>
> https://github.com/hw-claudio/osv_aarch64.git
>
> branch "aarch64-next"
>
> From and including commit:
> 959526b00e23244e "libc: add minimal support for AArch64"
>
> Lighly tested (successful build) on x64,
> tested on AArch64 Foundation v8.

This does not break anything on x86-64 which is good. :-) I'm not
completely happy with stubs in the generic code but I guess we can
live with them.

Avi?

Gleb Natapov

unread,
Mar 31, 2014, 12:24:12 PM3/31/14
to Claudio Fontana, osv...@googlegroups.com, claudio...@huawei.com
You could stub that function too to reduce amount of ifdefs.
poweroff and reboot could also call arch::poweroff() arch::reboot() to
get rid of ifdefs.


--
Gleb.

Nadav Har'El

unread,
Mar 31, 2014, 1:36:14 PM3/31/14
to Claudio Fontana, Osv Dev, Claudio Fontana
On Tue, Mar 25, 2014 at 11:28 AM, Claudio Fontana <hw.cl...@gmail.com> wrote:
From: Claudio Fontana <claudio...@huawei.com>

rename processor::halt_no_interrupts to cli_hlt, which
logically matches existing processor::sti_hlt.

Can you please explain the rationale of this patch:

1. Why need to rename "halt_no_interrupts" to "cli_hlt" (I'm not saying it's a bad name, I don't like the original name too much either, but just curious)
2. processor::halt_no_interrupts was always arch-dependent, so why do we also need arch::halt_no_interrupts?
3. Why in your patch do you continue to call processor::cli_hlt() in one place and arch::halt_no_interrupts() in another place?

Finally, similarly to what Gleb already suggested, would it be reasonable to say that the whole of core/power.cc is arch-dependent, so should move to arch/x64, and add a stub implementation for arch/arm? I think this would make this patch unnecessary?

Note that its header file, include/osv/power.hh, should remain shared by all architecture.



--
1.8.5.3

--
You received this message because you are subscribed to the Google Groups "OSv Development" group.
To unsubscribe from this group and stop receiving emails from it, send an email to osv-dev+u...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.



--

Avi Kivity

unread,
Mar 31, 2014, 7:00:01 PM3/31/14
to Claudio Fontana, osv...@googlegroups.com, claudio...@huawei.com
Shouldn't status be "=r" since it's output only?

I'm surprised gcc doesn't complain that it is not initialized.


> }
>
> -static __inline u_long atomic_fetchadd_long(volatile u_long *p, register u_long val)
> +static __inline u_long atomic_fetchadd_long(volatile u_long *p, u_long val)
> {
> - register u_long result asm ("x0");
> + u_long result;
> + u_int status;
> __asm __volatile("1: ldaxr %0, %1 ; "
> " add %2, %2, %0 ; "
> - " stlxr w3, %2, %1 ; "
> - " cbnz w3, 1b ; "
> - : "=r"(result), "+Q"(p), "+r"(val)
> + " stlxr %w3, %2, %1 ; "
> + " cbnz %w3, 1b ; "
> + : "=r"(result), "+Q"(*p), "+r"(val), "+r"(status)
> :
> - : "memory", "cc", "x3");
> + : "cc");
> return result;

Here too. btw, wherever you use an output register in an instruction
that is not the last one in the sequence, you need to specify early
clobber ("=&r"(result)). Otherwise gcc is free to pick the same
register for %0 and %1, and thus corrupt %1 before the next use.


Avi Kivity

unread,
Mar 31, 2014, 7:18:34 PM3/31/14
to Claudio Fontana, osv...@googlegroups.com, claudio...@huawei.com

On 03/25/2014 11:28 AM, Claudio Fontana wrote:
This copying is unhappy, need to reuse the code.

The problem of nested exceptions is not unique to x64. However do we
really need the same solution?

Maybe it's better to stub out nested exception support until we know more.
aarch64 doesn't have an IST, does it?

> + void set_exception_stack(char* base, size_t size);
> + void set_exception_stack(arch_thread* t);
> + void set_interrupt_stack(arch_thread* t);

Do we need to change interrupt stacks dynamically? On x64 we do,
because of the red zone. But on aarch64 the problem doesn't exist. How
is the stack pointer determined on an exception or interrupt? From EL1
to EL1.
Again, duplication. Do you need the alignment?
Overall, it is better to stub the callers of these APIs instead, since
duplicating x64 APis may not make sense here.
Do you have to use x0 here? And a memory write?

won't "mrs %0, daif" : "=r"(daif) work better?


> +}
> +
> +inline void irq_flag_notrace::restore() {
> + asm volatile("ldr w0, %0;"
> + "msr daif, x0" :: "m"(daif) : "memory", "x0");
> +}

Similar.
Are there caller-saved fp registers that need to be saved here?

This function is like an interrupt, in that the compiler does not expect
it to be called, so we need to save caller-saved registers too. x64 is
also missing a save/restore here.

> diff --git a/arch/aarch64/entry.S b/arch/aarch64/entry.S
> new file mode 100644
> index 0000000..aaba723
> --- /dev/null
> +++ b/arch/aarch64/entry.S
> @@ -0,0 +1,88 @@
> +/*
> + * Copyright (C) 2014 Huawei Technologies Duesseldorf GmbH
> + *
> + * This work is open source software, licensed under the terms of the
> + * BSD license as described in the LICENSE file in the top-level directory.
> + */
> +
> +/* XXX TODO nothing to see here, move along XXX */

> +/*
> +.global stack_trampoline
> +stack_trampoline: # %rsi=arg, %rdi=func, %rdx=stack
> + .type stack_trampoline, @function
> + .cfi_startproc simple
> + .cfi_def_cfa %rsp, 0
> + # align the stack at 16 bytes for sse
> + andq $-16, %rdx
> + sub $8, %rdx
> + mov %rsp, -8(%rdx)
> + lea -8(%rdx), %rsp
> + .cfi_rel_offset %rsp, 0
> + call *%rsi
> + pop %rsp
> + .cfi_restore %rsp
> + ret
> + .cfi_endproc
> +*/

This is not the instruction set you're looking for....
Do you in fact have an error_code in aarch64 exceptions, or was it
copied from x64?
Again better to let the compiler select the register rather than forcing x0.

hw.cl...@gmail.com

unread,
Apr 1, 2014, 3:55:21 AM4/1/14
to osv...@googlegroups.com, Claudio Fontana, Claudio Fontana
On Monday, 31 March 2014 19:36:14 UTC+2, Nadav Har'El wrote:
> On Tue, Mar 25, 2014 at 11:28 AM, Claudio Fontana <hw.cl...@gmail.com> wrote:
>
> From: Claudio Fontana <claudio...@huawei.com>
>
>
>
> rename processor::halt_no_interrupts to cli_hlt, which
>
> logically matches existing processor::sti_hlt.
>
>
>
> Can you please explain the rationale of this patch:
>
>
> 1. Why need to rename "halt_no_interrupts" to "cli_hlt" (I'm not saying it's a bad name, I don't like the original name too much either, but just curious)

currently in x64 you have in processor.hh:

inline void halt_no_interrupts() {
asm volatile ("cli; hlt" : : : "memory");
}

inline void sti_hlt() {
asm volatile ("sti; hlt" : : : "memory");
}


can you explain why that is?

I renamed halt_no_interrupts to cli_hlt, to just try to resolve this discrepancy.
So processor.hh contains arch-specific function names, besides the implementation, while arch.hh does not. I don't know if that is ok for you, but the current discrepancy is confusing, at least to me.

> 2. processor::halt_no_interrupts was always arch-dependent, so why do we also need arch::halt_no_interrupts?

in arch.hh you already have:

inline void wait_for_interrupt()
{
processor::sti_hlt();
}


From here I got the impression that arch.hh is an arch-independent interface, which uses the internal processor.hh arch-dependent interface.

So adding to the above

inline void halt_no_interrupts()
{
processor::cli_hlt();
}

just makes sense to me.


>
> 3. Why in your patch do you continue to call processor::cli_hlt() in one place and arch::halt_no_interrupts() in another place?

halt_no_interrupts is used in the patch in every place where an arch-independent name makes sense; processor::cli_hlt is only used for x64's implementation of arch::halt_no_interrupts and in x64's nmi handling which is very specific to x64.

>
>
>
> Finally, similarly to what Gleb already suggested, would it be reasonable to say that the whole of core/power.cc is arch-dependent, so should move to arch/x64, and add a stub implementation for arch/arm? I think this would make this patch unnecessary?

We could, although there is a chance to reuse core/power.cc when the dust settles on ACPI on ARM64, that is why in v2 I replaced the __aarch64__ with AARCH64_PORT_STUB.

Thanks,

Claudio

hw.cl...@gmail.com

unread,
Apr 1, 2014, 3:59:46 AM4/1/14
to osv...@googlegroups.com, Claudio Fontana, claudio...@huawei.com

yes you are right, will fix.

Nadav Har'El

unread,
Apr 1, 2014, 4:12:51 AM4/1/14
to Claudio Fontana, Osv Dev, Claudio Fontana
On Tue, Apr 1, 2014 at 10:55 AM, <hw.cl...@gmail.com> wrote:

> 1. Why need to rename "halt_no_interrupts" to "cli_hlt" (I'm not saying it's a bad name, I don't like the original name too much either, but just curious)

currently in x64 you have in processor.hh:

inline void halt_no_interrupts() {
    asm volatile ("cli; hlt" : : : "memory");
}

inline void sti_hlt() {
    asm volatile ("sti; hlt" : : : "memory");
}


can you explain why that is?

I renamed halt_no_interrupts to cli_hlt, to just try to resolve this discrepancy.
So processor.hh contains arch-specific function names, besides the implementation, while arch.hh does not. I don't know if that is ok for you, but the current discrepancy is confusing, at least to me.

Hmm,... I think I understand now. You want processor.hh (which is x86-64-specific, with x86-64-specific function names) to be only included from arch/x64/*.cc, and a new header file arch.hh which will have generic names (like "halt_no_interrupts") will be included elsewhere.

I guess it makes sense.

Although in the specific case of cli_hlt, if you had a have arch/x64/power.cc, I guess you wouldn't need the generic "halt_no_interrupts" feature, as users will call halt(), not halt_not_interrupts() directly.

But I'm also fine with what you did (Avi - please take a look if you agree).

hw.cl...@gmail.com

unread,
Apr 1, 2014, 4:12:59 AM4/1/14
to osv...@googlegroups.com, Claudio Fontana, claudio...@huawei.com

Not really, this is probably unnecessary in our case, this can probably mostly be removed for AArch64 for now.


>
>
>
> Maybe it's better to stub out nested exception support until we know more.

Yes.

Currently we are of the idea of staying at EL1, and use the SP_ELx for simplicity, so as you say we do not need to switch stacks.


As you noticed these are basically just stubs.
It is not yet clear if in some case it would make sense to follow the x64 approach, but I'll look at this again to clean it up for the next version.

The use of w0 (and again later) instead of letting gcc choose one is an oversight, will fix.

> > +static inli...

Avi Kivity

unread,
Apr 1, 2014, 4:55:37 AM4/1/14
to hw.cl...@gmail.com, osv...@googlegroups.com, claudio...@huawei.com
On 04/01/2014 11:12 AM, hw.cl...@gmail.com wrote:
> On Tuesday, 1 April 2014 01:18:34 UTC+2, Avi Kivity wrote:
>> On 03/25/2014 11:28 AM, Claudio Fontana wrote:
>>
>>> From: Claudio Fontana <claudio...@huawei.com>
>>
>> Do we need to change interrupt stacks dynamically? On x64 we do,
>>
>> because of the red zone. But on aarch64 the problem doesn't exist. How
>>
>> is the stack pointer determined on an exception or interrupt? From EL1
>>
>> to EL1.
> Currently we are of the idea of staying at EL1, and use the SP_ELx for simplicity, so as you say we do not need to switch stacks.


There is one case where we do, and that is if we get a page fault while
accessing the stack itself. A user application can/will use demand
paged memory for the stack, and we must be able to process a fault
caused by accessing an unmapped stack, on a different stack.

Is there some facility that allows us to do this?

Nadav Har'El

unread,
Apr 1, 2014, 5:03:11 AM4/1/14
to Avi Kivity, Claudio Fontana, Osv Dev, Claudio Fontana
BTW,  note that demand-paged stacks do not yet work correctly on x86-64 as well - see https://github.com/cloudius-systems/osv/issues/143
This should of course be fixed.

Reply all
Reply to author
Forward
0 new messages