Skip to content

Commit

Permalink
native: 64 bit compatibility and Linux/x86_64 support for the native
Browse files Browse the repository at this point in the history
Initial version to test 64 bit compatibility.

Instead of a separate board, 64 bit for Linux/x86_64 is enabled by setting the environment variable `NATIVE_64BIT=y` and compiling as usual.
While I personally prefer a separate `native64` board, this ensures that all tests run with the same configuration as the 32 bit version.
A separate board would require a major refactoring of many tests, which often have special behavior for the native board,
and I didn't want to increase the size of an already large pull request.

Not currently implemented:
* Architectures other than x86_64 or operating systems other than Linux
    * No FreeBSD support
    * No Aarch support
* Rust support for x86_64
  • Loading branch information
fzi-haxel committed Jan 17, 2024
1 parent 9d982f4 commit 527fca3
Show file tree
Hide file tree
Showing 17 changed files with 181 additions and 34 deletions.
27 changes: 23 additions & 4 deletions boards/native/Makefile.include
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,9 @@ NATIVEINCLUDES += -I$(RIOTBASE)/core/lib/include/
NATIVEINCLUDES += -I$(RIOTBASE)/core/include/
NATIVEINCLUDES += -I$(RIOTBASE)/drivers/include/

# Set "NATIVE_64BIT=y" to compile for x86_64
NATIVE_64BIT ?= n

ifeq ($(OS),Darwin)
DEBUGGER ?= lldb
else
Expand Down Expand Up @@ -50,14 +53,22 @@ ifeq (,$(filter -std=%, $(CFLAGS)))
endif

ifeq ($(OS_ARCH),x86_64)
CFLAGS += -m32
ifeq ($(NATIVE_64BIT), y)
CFLAGS += -m64
else
CFLAGS += -m32
endif
endif
ifneq (,$(filter -DDEVELHELP,$(CFLAGS)))
CFLAGS += -fstack-protector-all
endif
ifeq ($(OS),FreeBSD)
ifeq ($(OS_ARCH),amd64)
CFLAGS += -m32 -DCOMPAT_32BIT -B/usr/lib32
ifeq ($(NATIVE_64BIT), y)
CFLAGS += -m64
else
CFLAGS += -m32 -DCOMPAT_32BIT -B/usr/lib32
endif
endif
endif
ifeq ($(OS),Darwin)
Expand All @@ -69,11 +80,19 @@ CXXUWFLAGS +=
CXXEXFLAGS +=

ifeq ($(OS_ARCH),x86_64)
LINKFLAGS += -m32
ifeq ($(NATIVE_64BIT), y)
LINKFLAGS += -m64
else
LINKFLAGS += -m32
endif
endif
ifeq ($(OS),FreeBSD)
ifeq ($(OS_ARCH),amd64)
LINKFLAGS += -m32 -DCOMPAT_32BIT -L/usr/lib32 -B/usr/lib32
ifeq ($(NATIVE_64BIT), y)
LINKFLAGS += -m64
else
LINKFLAGS += -m32 -DCOMPAT_32BIT -L/usr/lib32 -B/usr/lib32
endif
endif
LINKFLAGS += -L $(BINDIR)
else
Expand Down
3 changes: 2 additions & 1 deletion boards/native/doc.txt
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,8 @@

# Required packages

The `native` version of RIOT will produce a 32 bit binary.
The `native` version of RIOT will produce a 32 bit binary by default.
To compile for x86_64 set the environment variable `NATIVE_64BIT=y`.
On Debian/Ubuntu you can install the required libraries with

```
Expand Down
5 changes: 3 additions & 2 deletions cpu/native/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,8 @@

config CPU_ARCH_NATIVE
bool
select HAS_ARCH_32BIT
select HAS_ARCH_32BIT if "$(NATIVE_64BIT)" != "y"
select HAS_ARCH_64BIT if "$(NATIVE_64BIT)" = "y"
select HAS_ARCH_NATIVE
select HAS_CPP
select HAS_CPU_NATIVE
Expand Down Expand Up @@ -59,7 +60,7 @@ config NATIVE_OS_LINUX
select HAS_PERIPH_GPIO
select HAS_PERIPH_GPIO_IRQ
select HAS_PERIPH_SPI
select HAS_RUST_TARGET if "$(OS_ARCH)" = "x86_64"
select HAS_RUST_TARGET if "$(OS_ARCH)" = "x86_64" && HAS_ARCH_32BIT

config NATIVE_OS_FREEBSD
bool
Expand Down
11 changes: 9 additions & 2 deletions cpu/native/Makefile.features
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,11 @@ ifeq (FreeBSD,$(OS))
DISABLE_LIBSTDCPP ?= 1
endif

FEATURES_PROVIDED += arch_32bit
ifeq ($(NATIVE_64BIT), y)
FEATURES_PROVIDED += arch_64bit
else
FEATURES_PROVIDED += arch_32bit
endif
FEATURES_PROVIDED += arch_native
FEATURES_PROVIDED += cpp
ifneq ($(DISABLE_LIBSTDCPP),1)
Expand All @@ -19,7 +23,10 @@ FEATURES_PROVIDED += periph_pm
FEATURES_PROVIDED += periph_pwm
FEATURES_PROVIDED += periph_timer_periodic
ifeq ($(OS) $(OS_ARCH),Linux x86_64)
FEATURES_PROVIDED += rust_target
# TODO: Add rust support for native 64 bit.
ifneq ($(NATIVE_64BIT), y)
FEATURES_PROVIDED += rust_target
endif
endif
FEATURES_PROVIDED += ssp

Expand Down
6 changes: 5 additions & 1 deletion cpu/native/Makefile.include
Original file line number Diff line number Diff line change
Expand Up @@ -11,5 +11,9 @@ TOOLCHAINS_SUPPORTED = gnu llvm afl

# Platform triple as used by Rust
ifeq ($(OS) $(OS_ARCH),Linux x86_64)
RUST_TARGET = i686-unknown-linux-gnu
ifneq (,$(filter arch_32bit,$(FEATURES_USED)))
RUST_TARGET = i686-unknown-linux-gnu
else
RUST_TARGET = x86_64-unknown-linux-gnu
endif
endif
4 changes: 4 additions & 0 deletions cpu/native/include/architecture_arch.h
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,11 @@ void native_breakpoint(void);

/* Doc is provided centrally in architecture.h, hide this from Doxygen */
#ifndef DOXYGEN
#if (__SIZEOF_POINTER__ == 8)
#define ARCHITECTURE_WORD_BITS (64U)
#else
#define ARCHITECTURE_WORD_BITS (32U)
#endif
#define ARCHITECTURE_BREAKPOINT(v) native_breakpoint()
#endif /* DOXYGEN */

Expand Down
33 changes: 32 additions & 1 deletion cpu/native/include/c11_atomics_compat_cpu.hpp
Original file line number Diff line number Diff line change
@@ -1,4 +1,8 @@
/* This file was automatically generated using ./dist/tools/generate_c11_atomics_cpp_compat_header/generate_c11_atomics_cpp_compat_header.sh */
/**

Check warning on line 1 in cpu/native/include/c11_atomics_compat_cpu.hpp

View workflow job for this annotation

GitHub Actions / static-tests

no copyright notice found
* This file was generated using
* ./dist/tools/generate_c11_atomics_cpp_compat_header/generate_c11_atomics_cpp_compat_header.sh
* for 32 and 64 bit and merged manually.
*/
#pragma once

#define ATOMIC_BOOL_SIZE (1U)
Expand All @@ -17,10 +21,17 @@
#define ATOMIC_INT_SAME_SIZED_TYPE uint32_t
#define ATOMIC_UINT_SIZE (4U)
#define ATOMIC_UINT_SAME_SIZED_TYPE uint32_t
#ifdef __x86_64__
#define ATOMIC_LONG_SIZE (8U)
#define ATOMIC_LONG_SAME_SIZED_TYPE uint64_t
#define ATOMIC_ULONG_SIZE (8U)
#define ATOMIC_ULONG_SAME_SIZED_TYPE uint64_t
#else
#define ATOMIC_LONG_SIZE (4U)
#define ATOMIC_LONG_SAME_SIZED_TYPE uint32_t
#define ATOMIC_ULONG_SIZE (4U)
#define ATOMIC_ULONG_SAME_SIZED_TYPE uint32_t
#endif
#define ATOMIC_LLONG_SIZE (8U)
#define ATOMIC_LLONG_SAME_SIZED_TYPE uint64_t
#define ATOMIC_ULLONG_SIZE (8U)
Expand Down Expand Up @@ -52,6 +63,16 @@
#define ATOMIC_UINT_FAST8_T_SIZE (1U)
#define ATOMIC_UINT_FAST8_T_SAME_SIZED_TYPE uint8_t
#endif
#ifdef __x86_64__
#define ATOMIC_INT_FAST16_T_SIZE (8U)
#define ATOMIC_INT_FAST16_T_SAME_SIZED_TYPE uint64_t
#define ATOMIC_UINT_FAST16_T_SIZE (8U)
#define ATOMIC_UINT_FAST16_T_SAME_SIZED_TYPE uint64_t
#define ATOMIC_INT_FAST32_T_SIZE (8U)
#define ATOMIC_INT_FAST32_T_SAME_SIZED_TYPE uint64_t
#define ATOMIC_UINT_FAST32_T_SIZE (8U)
#define ATOMIC_UINT_FAST32_T_SAME_SIZED_TYPE uint64_t
#else
#define ATOMIC_INT_FAST16_T_SIZE (4U)
#define ATOMIC_INT_FAST16_T_SAME_SIZED_TYPE uint32_t
#define ATOMIC_UINT_FAST16_T_SIZE (4U)
Expand All @@ -60,16 +81,26 @@
#define ATOMIC_INT_FAST32_T_SAME_SIZED_TYPE uint32_t
#define ATOMIC_UINT_FAST32_T_SIZE (4U)
#define ATOMIC_UINT_FAST32_T_SAME_SIZED_TYPE uint32_t
#endif
#define ATOMIC_INT_FAST64_T_SIZE (8U)
#define ATOMIC_INT_FAST64_T_SAME_SIZED_TYPE uint64_t
#define ATOMIC_UINT_FAST64_T_SIZE (8U)
#define ATOMIC_UINT_FAST64_T_SAME_SIZED_TYPE uint64_t
#ifdef __x86_64__
#define ATOMIC_INTPTR_T_SIZE (8U)
#define ATOMIC_INTPTR_T_SAME_SIZED_TYPE uint64_t
#define ATOMIC_UINTPTR_T_SIZE (8U)
#define ATOMIC_UINTPTR_T_SAME_SIZED_TYPE uint64_t
#define ATOMIC_SIZE_T_SIZE (8U)
#define ATOMIC_SIZE_T_SAME_SIZED_TYPE uint64_t
#else
#define ATOMIC_INTPTR_T_SIZE (4U)
#define ATOMIC_INTPTR_T_SAME_SIZED_TYPE uint32_t
#define ATOMIC_UINTPTR_T_SIZE (4U)
#define ATOMIC_UINTPTR_T_SAME_SIZED_TYPE uint32_t
#define ATOMIC_SIZE_T_SIZE (4U)
#define ATOMIC_SIZE_T_SAME_SIZED_TYPE uint32_t
#endif
#define ATOMIC_PTRDIFF_T_SIZE (8U)
#define ATOMIC_PTRDIFF_T_SAME_SIZED_TYPE uint64_t
#define ATOMIC_INTMAX_T_SIZE (8U)
Expand Down
7 changes: 4 additions & 3 deletions cpu/native/include/native_internal.h
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@

#include <signal.h>
#include <stdio.h>
#include <stdint.h>
#include <poll.h>
/* enable signal handler register access on different platforms
* check here for more:
Expand Down Expand Up @@ -111,7 +112,7 @@ extern int (*real_accept)(int socket, ...);
/* The ... is a hack to save includes: */
extern int (*real_bind)(int socket, ...);
extern int (*real_connect)(int socket, ...);
extern int (*real_recv)(int sockfd, void *buf, size_t len, int flags);
extern ssize_t (*real_recv)(int sockfd, void *buf, size_t len, int flags);
extern int (*real_chdir)(const char *path);
extern int (*real_close)(int);
extern int (*real_fcntl)(int, int, ...);
Expand All @@ -127,7 +128,7 @@ extern int (*real_getaddrinfo)(const char *node, ...);
extern int (*real_getifaddrs)(struct ifaddrs **ifap);
extern int (*real_getpid)(void);
extern int (*real_gettimeofday)(struct timeval *t, ...);
extern int (*real_ioctl)(int fildes, int request, ...);
extern int (*real_ioctl)(int fildes, unsigned long request, ...);
extern int (*real_listen)(int socket, int backlog);
extern int (*real_open)(const char *path, int oflag, ...);
extern int (*real_mkdir)(const char *pathname, mode_t mode);
Expand Down Expand Up @@ -164,7 +165,7 @@ extern ssize_t (*real_send)(int sockfd, const void *buf, size_t len, int flags);
* data structures
*/
extern volatile int native_interrupts_enabled;
extern volatile unsigned int _native_saved_eip;
extern volatile uintptr_t _native_saved_eip;
extern int _sig_pipefd[2];
extern volatile int _native_sigpend;
extern volatile int _native_in_isr;
Expand Down
13 changes: 9 additions & 4 deletions cpu/native/irq_cpu.c
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@
#include <valgrind/valgrind.h>
#define VALGRIND_DEBUG DEBUG
#else
#define VALGRIND_STACK_REGISTER(...)
#define VALGRIND_STACK_REGISTER(...) (0)
#define VALGRIND_DEBUG(...)
#endif

Expand Down Expand Up @@ -53,7 +53,7 @@ char __isr_stack[SIGSTKSZ];
ucontext_t native_isr_context;
ucontext_t *_native_cur_ctx, *_native_isr_ctx;

volatile unsigned int _native_saved_eip;
volatile uintptr_t _native_saved_eip;
volatile int _native_sigpend;
int _sig_pipefd[2];

Expand Down Expand Up @@ -353,9 +353,14 @@ void native_isr_entry(int sig, siginfo_t *info, void *context)
_native_saved_eip = ((ucontext_t *)context)->uc_mcontext.arm_pc;
((ucontext_t *)context)->uc_mcontext.arm_pc = (unsigned int)&_native_sig_leave_tramp;
#else /* Linux/x86 */
#ifdef __x86_64__
_native_saved_eip = ((ucontext_t *)context)->uc_mcontext.gregs[REG_RIP];
((ucontext_t *)context)->uc_mcontext.gregs[REG_RIP] = (uintptr_t)&_native_sig_leave_tramp;
#else
//printf("\n\033[31mEIP:\t%p\ngo switching\n\n\033[0m", (void*)((ucontext_t *)context)->uc_mcontext.gregs[REG_EIP]);

Check warning on line 360 in cpu/native/irq_cpu.c

View workflow job for this annotation

GitHub Actions / static-tests

line is longer than 100 characters
_native_saved_eip = ((ucontext_t *)context)->uc_mcontext.gregs[REG_EIP];
((ucontext_t *)context)->uc_mcontext.gregs[REG_EIP] = (unsigned int)&_native_sig_leave_tramp;
#endif
#endif
#endif
}
Expand Down Expand Up @@ -466,9 +471,9 @@ void native_interrupt_init(void)
struct sigaction sa;
DEBUG("native_interrupt_init\n");

VALGRIND_STACK_REGISTER(__isr_stack, __isr_stack + sizeof(__isr_stack));
(void) VALGRIND_STACK_REGISTER(__isr_stack, __isr_stack + sizeof(__isr_stack));
VALGRIND_DEBUG("VALGRIND_STACK_REGISTER(%p, %p)\n",
(void *)__isr_stack, (void*)((int)__isr_stack + sizeof(__isr_stack)));
(void *)__isr_stack, (void*)(__isr_stack + sizeof(__isr_stack)));

_native_sigpend = 0;

Expand Down
15 changes: 10 additions & 5 deletions cpu/native/native_cpu.c
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@
#include <valgrind/valgrind.h>
#define VALGRIND_DEBUG DEBUG
#else
#define VALGRIND_STACK_REGISTER(...)
#define VALGRIND_STACK_REGISTER(...) (0)
#define VALGRIND_DEBUG(...)
#endif

Expand Down Expand Up @@ -77,8 +77,13 @@ static void _native_mod_ctx_leave_sigh(ucontext_t *ctx)
_native_saved_eip = ((ucontext_t *)ctx)->uc_mcontext.arm_pc;
((ucontext_t *)ctx)->uc_mcontext.arm_pc = (unsigned int)&_native_sig_leave_handler;
#else /* Linux/x86 */
#ifdef __x86_64__
_native_saved_eip = ctx->uc_mcontext.gregs[REG_RIP];
ctx->uc_mcontext.gregs[REG_RIP] = (unsigned long)&_native_sig_leave_handler;
#else
_native_saved_eip = ctx->uc_mcontext.gregs[REG_EIP];
ctx->uc_mcontext.gregs[REG_EIP] = (unsigned int)&_native_sig_leave_handler;
#endif
#endif
#endif
}
Expand Down Expand Up @@ -122,9 +127,9 @@ char *thread_stack_init(thread_task_func_t task_func, void *arg, void *stack_sta

stack_start = align_stack((uintptr_t)stack_start, &stacksize);

VALGRIND_STACK_REGISTER(stack_start, (char *)stack_start + stacksize);
(void) VALGRIND_STACK_REGISTER(stack_start, (char *)stack_start + stacksize);
VALGRIND_DEBUG("VALGRIND_STACK_REGISTER(%p, %p)\n",
stack_start, (void*)((int)stack_start + stacksize));
stack_start, (void*)((char *)stack_start + stacksize));

DEBUG("thread_stack_init\n");

Expand Down Expand Up @@ -261,9 +266,9 @@ void native_cpu_init(void)
end_context.uc_stack.ss_size = SIGSTKSZ;
end_context.uc_stack.ss_flags = 0;
makecontext(&end_context, sched_task_exit, 0);
VALGRIND_STACK_REGISTER(__end_stack, __end_stack + sizeof(__end_stack));
(void) VALGRIND_STACK_REGISTER(__end_stack, __end_stack + sizeof(__end_stack));
VALGRIND_DEBUG("VALGRIND_STACK_REGISTER(%p, %p)\n",
(void*)__end_stack, (void*)((int)__end_stack + sizeof(__end_stack)));
(void*)__end_stack, (void*)(__end_stack + sizeof(__end_stack)));

DEBUG("RIOT native cpu initialized.\n");
}
Expand Down
4 changes: 2 additions & 2 deletions cpu/native/periph/flashpage.c
Original file line number Diff line number Diff line change
Expand Up @@ -55,9 +55,9 @@ void flashpage_write(void *target_addr, const void *data, size_t len)
assert((uintptr_t)target_addr >= (uintptr_t)_native_flash);
assert((uintptr_t)target_addr + len <= (uintptr_t)_native_flash + sizeof(_native_flash));
assert(!(len % FLASHPAGE_WRITE_BLOCK_SIZE));
assert(!((unsigned)target_addr % FLASHPAGE_WRITE_BLOCK_ALIGNMENT));
assert(!((uintptr_t)target_addr % FLASHPAGE_WRITE_BLOCK_ALIGNMENT));

DEBUG("%p: write %u bytes\n", target_addr, len);
DEBUG("%p: write %zu bytes\n", target_addr, len);

_flash_write(target_addr, data, len);
}
Expand Down
2 changes: 1 addition & 1 deletion cpu/native/periph/spidev_linux.c
Original file line number Diff line number Diff line change
Expand Up @@ -320,7 +320,7 @@ void spi_transfer_bytes(spi_t bus, spi_cs_t cs, bool cont,
DEBUG("spi_transfer_bytes: ioctl failed\n");
}
else {
DEBUG("spi_transfer_bytes: transferred %u bytes\n", len);
DEBUG("spi_transfer_bytes: transferred %zu bytes\n", len);
}

#ifdef MODULE_PERIPH_GPIO
Expand Down
5 changes: 3 additions & 2 deletions cpu/native/periph/timer.c
Original file line number Diff line number Diff line change
Expand Up @@ -121,7 +121,8 @@ static void do_timer_set(unsigned int offset, bool periodic)
its.it_interval = its.it_value;
}

DEBUG("timer_set(): setting %lu.%09lu\n", (unsigned long)its.it_value.tv_sec, its.it_value.tv_nsec);
DEBUG("timer_set(): setting %lu.%09lu\n", (unsigned long)its.it_value.tv_sec,
(unsigned long)its.it_value.tv_nsec);
}

int timer_set(tim_t dev, int channel, unsigned int offset)
Expand All @@ -144,7 +145,7 @@ int timer_set(tim_t dev, int channel, unsigned int offset)

int timer_set_absolute(tim_t dev, int channel, unsigned int value)
{
uint32_t now = timer_read(dev);
unsigned int now = timer_read(dev);
return timer_set(dev, channel, value - now);
}

Expand Down
6 changes: 3 additions & 3 deletions cpu/native/socket_zep/socket_zep.c
Original file line number Diff line number Diff line change
Expand Up @@ -409,7 +409,7 @@ static int _request_transmit(ieee802154_dev_t *dev)
{
socket_zep_t *zepdev = dev->priv;

DEBUG("socket_zep::request_transmit(%zu bytes)\n", zepdev->snd_len);
DEBUG("socket_zep::request_transmit(%u bytes)\n", zepdev->snd_len);

dev->cb(dev, IEEE802154_RADIO_INDICATION_TX_START);

Expand Down Expand Up @@ -448,7 +448,7 @@ int _len(ieee802154_dev_t *dev)
}

if (res < (int)sizeof(zep_v2_data_hdr_t)) {
DEBUG("socket_zep::len discard short frame (%zu bytes)\n", res);
DEBUG("socket_zep::len discard short frame (%u bytes)\n", res);
return 0;
}

Expand Down Expand Up @@ -491,7 +491,7 @@ static int _read(ieee802154_dev_t *dev, void *buf, size_t max_size,
socket_zep_t *zepdev = dev->priv;
size_t frame_len = max_size + sizeof(zep_v2_data_hdr_t) + 2;

DEBUG("socket_zep::read: reading up to %u bytes into %p\n", max_size, buf);
DEBUG("socket_zep::read: reading up to %zu bytes into %p\n", max_size, buf);

if (frame_len > sizeof(zepdev->rcv_buf)) {
DEBUG("socket_zep::read: frame size (%zu) exceeds RX buffer (%zu bytes)\n",
Expand Down
Loading

0 comments on commit 527fca3

Please sign in to comment.