Skip to content
New issue

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

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

Already on GitHub? Sign in to your account

native: Linux/x86_64 support #20315

Merged
merged 1 commit into from
Feb 1, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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=1" to compile for x86_64
NATIVE_64BIT ?= 0
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can we have a native64 board that will just set this and otherwise include the native board (see e.g. openlabs-kw41z-mini-256kib).

Otherwise this won't be exercised by CI.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Probably yes, but there are a lot of additional changes needed outside the boards folder to make it work.
For example, the codebase has a lot of checks like ifeq (native, $(BOARD)) that would need to be adapted.
I have a WIP branch that is not yet finished, but it shows the extent of the changes needed WIP: native64 board.
(This one moves most of the native board into a common folder instead of the way it is handled with openlabs-kw41z-mini-256kib).


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

ifeq ($(OS_ARCH),x86_64)
CFLAGS += -m32
ifeq ($(NATIVE_64BIT), 1)
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), 1)
CFLAGS += -m64
else
CFLAGS += -m32 -DCOMPAT_32BIT -B/usr/lib32
endif
endif
endif
ifeq ($(OS),Darwin)
Expand All @@ -86,11 +97,19 @@ CXXUWFLAGS +=
CXXEXFLAGS +=

ifeq ($(OS_ARCH),x86_64)
LINKFLAGS += -m32
ifeq ($(NATIVE_64BIT), 1)
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), 1)
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=1`.
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)" != "1"
select HAS_ARCH_64BIT if "$(NATIVE_64BIT)" = "1"
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), 1)
FEATURES_PROVIDED += arch_64bit
else
FEATURES_PROVIDED += arch_32bit
endif
FEATURES_PROVIDED += arch_native
FEATURES_PROVIDED += cpp
ifneq ($(DISABLE_LIBSTDCPP),1)
Expand All @@ -20,7 +24,10 @@ FEATURES_PROVIDED += periph_pwm
FEATURES_PROVIDED += periph_timer_periodic
FEATURES_PROVIDED += periph_timer_query_freqs
ifeq ($(OS) $(OS_ARCH),Linux x86_64)
FEATURES_PROVIDED += rust_target
# TODO: Add rust support for native 64 bit.
ifneq ($(NATIVE_64BIT), 1)
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 @@
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 @@ -246,7 +246,7 @@
nleft = sizeof(int);
i = 0;

while ((nleft > 0) && ((nread = real_read(_sig_pipefd[0], ((uint8_t*)&sig) + i, nleft)) != -1)) {

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

View workflow job for this annotation

GitHub Actions / static-tests

line is longer than 100 characters
i += nread;
nleft -= nread;
}
Expand Down Expand Up @@ -278,7 +278,7 @@
warnx("native_irq_handler: ignoring SIGUSR1");
}
else {
errx(EXIT_FAILURE, "XXX: no handler for signal %i\nXXX: this should not have happened!\n", sig);

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

View workflow job for this annotation

GitHub Actions / static-tests

line is longer than 100 characters
}
}

Expand Down Expand Up @@ -353,9 +353,14 @@
_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 @@
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 @@
_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 @@

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 @@ -161,7 +166,7 @@
sched_run();
}

DEBUG("isr_cpu_switch_context_exit: calling setcontext(%" PRIkernel_pid ")\n\n", thread_getpid());

Check warning on line 169 in cpu/native/native_cpu.c

View workflow job for this annotation

GitHub Actions / static-tests

line is longer than 100 characters
/* Use intermediate cast to uintptr_t to silence -Wcast-align.
* stacks are manually word aligned in thread_static_init() */
ctx = (ucontext_t *)(uintptr_t)(thread_get_active()->sp);
Expand Down Expand Up @@ -261,9 +266,9 @@
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 @@ -143,7 +143,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 @@ -166,7 +167,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 @@
{
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 @@
}

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 @@
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 Expand Up @@ -590,7 +590,7 @@
return res;
}


Check warning on line 593 in cpu/native/socket_zep/socket_zep.c

View workflow job for this annotation

GitHub Actions / static-tests

too many consecutive empty lines
static int _confirm_op(ieee802154_dev_t *dev, ieee802154_hal_op_t op, void *ctx)
{
int res = -EAGAIN;
Expand Down
Loading
Loading