1
0
mirror of https://github.com/RIOT-OS/RIOT.git synced 2024-12-29 04:50:03 +01:00

Merge pull request #20315 from fzi-haxel/native-x86-64-support

native: Linux/x86_64 support
This commit is contained in:
benpicco 2024-02-01 17:11:56 +00:00 committed by GitHub
commit 5bd879b406
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
17 changed files with 181 additions and 34 deletions

View File

@ -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
ifeq ($(OS),Darwin)
DEBUGGER ?= lldb
else
@ -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)
@ -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

View File

@ -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
```

View File

@ -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
@ -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

View File

@ -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)
@ -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

View File

@ -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

View File

@ -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 */

View File

@ -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 */
/**
* 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)
@ -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)
@ -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)
@ -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)

View File

@ -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:
@ -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, ...);
@ -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);
@ -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;

View File

@ -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
@ -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];
@ -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]);
_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
}
@ -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;

View File

@ -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
@ -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
}
@ -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");
@ -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");
}

View File

@ -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);
}

View File

@ -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

View File

@ -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)
@ -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);
}

View File

@ -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);
@ -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;
}
@ -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",

View File

@ -82,7 +82,7 @@ int (*real_fork)(void);
int (*real_feof)(FILE *stream);
int (*real_ferror)(FILE *stream);
int (*real_listen)(int socket, int backlog);
int (*real_ioctl)(int fildes, int request, ...);
int (*real_ioctl)(int fildes, unsigned long request, ...);
int (*real_open)(const char *path, int oflag, ...);
int (*real_pause)(void);
int (*real_pipe)(int[2]);
@ -334,29 +334,39 @@ int getc(FILE *fp)
__attribute__((__format__ (__printf__, 1, 0)))
char *make_message(const char *format, va_list argp)
{
int size = 100;
int size = 128;
char *message, *temp;
if ((message = malloc(size)) == NULL) {
return NULL;
}
/* argp is undefined after calling vsnprintf, so we copy the list first */
va_list argp_copy;
va_copy(argp_copy, argp);
while (1) {
int n = vsnprintf(message, size, format, argp);
if (n < 0) {
free(message);
va_end(argp_copy);
return NULL;
}
if (n < size) {
va_end(argp_copy);
return message;
}
size = n + 1;
if ((temp = realloc(message, size)) == NULL) {
free(message);
va_end(argp_copy);
return NULL;
}
else {
message = temp;
/* copy the list back and try again */
va_end(argp);
va_copy(argp, argp_copy);
}
}
}

View File

@ -69,6 +69,54 @@ _native_sig_leave_handler:
#else
.globl _native_sig_leave_tramp
#ifdef __x86_64__
_native_sig_leave_tramp:
pushq _native_saved_eip(%rip)
pushfq
pushq %rax
pushq %rcx
pushq %rdx
pushq %rbx
pushq %rbp
pushq %rsi
pushq %rdi
pushq %r8
pushq %r9
pushq %r10
pushq %r11
pushq %r12
pushq %r13
pushq %r14
pushq %r15
mov _native_isr_ctx(%rip), %rsi
mov _native_cur_ctx(%rip), %rdi
call swapcontext
call irq_enable
movl $0x0, _native_in_isr(%rip)
popq %r15
popq %r14
popq %r13
popq %r12
popq %r11
popq %r10
popq %r9
popq %r8
popq %rdi
popq %rsi
popq %rbp
popq %rbx
popq %rdx
popq %rcx
popq %rax
popfq
ret
#else
_native_sig_leave_tramp:
pushl _native_saved_eip
pushfl
@ -86,11 +134,17 @@ _native_sig_leave_tramp:
popfl
ret
#endif
.globl _native_sig_leave_handler
_native_sig_leave_handler:
#ifdef __x86_64__
pushq _native_saved_eip(%rip)
movl $0x0, _native_in_isr(%rip)
#else
pushl _native_saved_eip
movl $0x0, _native_in_isr
#endif
ret
#endif

View File

@ -24,13 +24,17 @@ CFLAGS += -Wno-cast-function-type
RIOT_INCLUDES = $(filter-out -%,$(subst -I,,$(INCLUDES)))
#translate (CPU_ARCH) to Build Target
#WAMR_BUILD_TARGET is "X86_32" "AARCH64[sub]", "ARM[sub]",
#WAMR_BUILD_TARGET is "X86_32", "X86_64", "AARCH64[sub]", "ARM[sub]",
# "THUMB[sub]", "XTENSA"
#no msp430, no AVR support for now
ifeq ($(CPU),native)
ifeq ($(findstring x86,$(OS_ARCH)),x86)
ifneq (,$(filter arch_32bit,$(FEATURES_USED)))
WAMR_BUILD_TARGET = X86_32
else
WAMR_BUILD_TARGET = X86_64
endif
endif
ifeq ($(findstring arm,$(OS_ARCH)),arm)
WAMR_BUILD_TARGET = ARM