diff --git a/Makefile b/Makefile index 69467c08..27e2a1bc 100644 --- a/Makefile +++ b/Makefile @@ -34,6 +34,13 @@ LIB_TARGETS := $(PREFIX_A)libphoenix.a $(PREFIX_A)crt0.o all: $(LIB_TARGETS) +ifeq ($(TARGET_SUBFAMILY),multilib) + LIBPHOENIX_MULTILIB := y + CPPFLAGS += -DLIBPHOENIX_MULTILIB +else + LIBPHOENIX_MULTILIB := n +endif + ifneq (,$(findstring arm,$(TARGET_SUFF))) include arch/arm/Makefile else ifneq (,$(findstring aarch64,$(TARGET_SUFF))) diff --git a/arch/arm/Makefile b/arch/arm/Makefile index 9b7fe83b..ba975b36 100644 --- a/arch/arm/Makefile +++ b/arch/arm/Makefile @@ -6,17 +6,34 @@ # %LICENSE% # -ifneq (,$(findstring v7a,$(TARGET_SUFF))) +# Obtain architecture based on ARM ACLE 2.0 +# https://developer.arm.com/documentation/dui0774/l/Other-Compiler-specific-Features/Predefined-macros +arm_version := $(word 3, $(shell echo | arm-phoenix-gcc $(CFLAGS) -E -dM - | grep -E "[[:space:]]__ARM_ARCH[[:space:]]")) +arm_profile_num := $(word 3, $(shell echo | arm-phoenix-gcc $(CFLAGS) -E -dM - | grep -E "[[:space:]]__ARM_ARCH_PROFILE[[:space:]]")) +# ASCII conversion +arm_profile := $(subst 65,A,$(subst 77,M,$(subst 82,R,$(arm_profile_num)))) +arm_arch := $(arm_version)$(arm_profile) + +arm_use_common := y +ifneq (,$(findstring 7A,$(arm_arch))) include arch/arm/v7a/Makefile -else ifneq (,$(findstring v7m,$(TARGET_SUFF))) +else ifneq (,$(findstring 7M,$(arm_arch))) include arch/arm/v7m/Makefile -else ifneq (,$(findstring v8m,$(TARGET_SUFF))) +else ifneq (,$(findstring 8M,$(arm_arch))) include arch/arm/v8m/Makefile -else ifneq (,$(findstring v8r,$(TARGET_SUFF))) +else ifneq (,$(findstring 8R,$(arm_arch))) include arch/arm/v8r/Makefile +else ifeq ($(LIBPHOENIX_MULTILIB),y) + include arch/arm/multilib/Makefile + arm_use_common := n else $(error Unsupported TARGET) endif +# FIXME: multilib supports more targets that functions in those files do, +# eg. arm/arch=armv5te or Thumb-1 targets (v6s-m and v8-m.base). +ifeq ($(arm_use_common),y) OBJS += $(addprefix $(PREFIX_O)arch/arm/, jmp.o memcpy.o memset.o signal.o string.o) +endif + CRT0_OBJS += $(addprefix $(PREFIX_O)arch/arm/, crt0.o) diff --git a/arch/arm/multilib/Makefile b/arch/arm/multilib/Makefile new file mode 100644 index 00000000..00fd585a --- /dev/null +++ b/arch/arm/multilib/Makefile @@ -0,0 +1,11 @@ +# +# Makefile for libphoenix/arch/arm/multilib +# +# Copyright 2025 Phoenix Systems +# +# %LICENSE% +# + +OBJS += $(addprefix $(PREFIX_O)arch/arm/multilib/, syscalls.o reboot.o) + +OBJS += $(addprefix $(PREFIX_O)arch/arm/multilib/, jmp.o signal.o string.o) diff --git a/arch/arm/multilib/jmp.c b/arch/arm/multilib/jmp.c new file mode 100644 index 00000000..bf800c81 --- /dev/null +++ b/arch/arm/multilib/jmp.c @@ -0,0 +1,42 @@ +/* + * Phoenix-RTOS + * + * libphoenix + * + * + * _setjmp, _longjmp, setjmp, sigsetjmp + * + * Copyright 2025 Phoenix Systems + * Author: Hubert Badocha + * + * This file is part of Phoenix-RTOS. + * + * %LICENSE% + */ + +#include +#include + + +int _setjmp(jmp_buf var) +{ + abort(); +} + + +__attribute__((__noreturn__)) void _longjmp(jmp_buf var, int m) +{ + abort(); +} + + +int setjmp(jmp_buf var) +{ + abort(); +} + + +int sigsetjmp(sigjmp_buf env, int savesigs) +{ + abort(); +} diff --git a/arch/arm/multilib/reboot.c b/arch/arm/multilib/reboot.c new file mode 100644 index 00000000..36353eb7 --- /dev/null +++ b/arch/arm/multilib/reboot.c @@ -0,0 +1,31 @@ +/* + * Phoenix-RTOS + * + * libphoenix + * + * reboot.c + * + * Copyright 2025 Phoenix Systems + * Author: Hubert Badocha + * + * This file is part of Phoenix-RTOS. + * + * %LICENSE% + */ + +#include +#include + + +int reboot(int magic) +{ + return -1; +} + + +int reboot_reason(uint32_t *val) +{ + *val = 0u; + + return 0; +} diff --git a/arch/arm/multilib/signal.S b/arch/arm/multilib/signal.S new file mode 100644 index 00000000..d09c7750 --- /dev/null +++ b/arch/arm/multilib/signal.S @@ -0,0 +1,24 @@ +/* + * Phoenix-RTOS + * + * libphoenix + * + * Signal trampoline (arm) + * + * Copyright 2025 Phoenix Systems + * Author: Hubert Badocha + * + * This file is part of Phoenix-RTOS. + * + * %LICENSE% + */ + +#define __ASSEMBLY__ + +.text + +.globl _signal_trampoline +.type _signal_trampoline, %function +_signal_trampoline: + bl abort +.size _signal_trampoline, .-_signal_trampoline diff --git a/arch/arm/multilib/string.c b/arch/arm/multilib/string.c new file mode 100644 index 00000000..b8a30548 --- /dev/null +++ b/arch/arm/multilib/string.c @@ -0,0 +1,127 @@ +/* + * Phoenix-RTOS + * + * libphoenix + * + * arch/arm/multilib/string + * + * Copyright 2025 Phoenix Systems + * Author: Hubert Badocha + * + * This file is part of Phoenix-RTOS. + * + * %LICENSE% + */ + + +#include + + +void *memmove(void *dest, const void *src, size_t n) +{ + for (size_t i = 0; i < n; i++) { + ((char *)dest)[i] = ((const char *)src)[i]; + } + return dest; +} + + +int memcmp(const void *ptr1, const void *ptr2, size_t n) +{ + for (size_t i = 0; i < n; i++) { + int diff = ((int)(((const unsigned char *)ptr1)[i])) - ((int)(((const unsigned char *)ptr2)[i])); + if (diff != 0) { + return diff; + } + } + return 0; +} + + +size_t strlen(const char *s) +{ + size_t len = 0; + while (s[len] != '\0') { + len++; + } + return len; +} + + +size_t strnlen(const char *s, size_t maxlen) +{ + size_t len = 0; + while ((s[len] != '\0') && (len < maxlen)) { + len++; + } + return len; +} + + +int strcmp(const char *s1, const char *s2) +{ + for (size_t i = 0; (s1[i] != '\0') || (s2[i] != '\0'); i++) { + int diff = ((int)(((const unsigned char *)s1)[i])) - ((int)(((const unsigned char *)s2)[i])); + if (diff != 0) { + return diff; + } + } + return 0; +} + + +int strncmp(const char *s1, const char *s2, size_t count) +{ + for (size_t i = 0; ((i < count) && ((s1[i] != '\0') || (s2[i] != '\0'))); i++) { + int diff = ((int)(((const unsigned char *)s1)[i])) - ((int)(((const unsigned char *)s2)[i])); + if (diff != 0) { + return diff; + } + } + return 0; +} + + +char *strcpy(char *dest, const char *src) +{ + size_t i = 0; + while ((src[i] != '\0')) { + dest[i] = src[i]; + i++; + } + dest[i] = '\0'; + return dest; +} + + +char *strncpy(char *dest, const char *src, size_t n) +{ + size_t i = 0; + while (((i < n) && (src[i] != '\0'))) { + dest[i] = src[i]; + i++; + } + while (i < n) { + dest[i] = '\0'; + i++; + } + return dest; +} + + +void *memcpy(void *dest, const void *src, size_t n) +{ + for (size_t i = 0; i < n; i++) { + ((char *)dest)[i] = ((const char *)src)[i]; + } + return dest; +} + + +void *memset(void *dest, int value, size_t n) +{ + for (size_t i = 0; i < n; i++) { + ((unsigned char *)dest)[i] = (unsigned char)value; + } + return dest; +} diff --git a/arch/arm/multilib/syscalls.S b/arch/arm/multilib/syscalls.S new file mode 100644 index 00000000..5cc33f70 --- /dev/null +++ b/arch/arm/multilib/syscalls.S @@ -0,0 +1,41 @@ +/* + * Phoenix-RTOS + * + * libphoenix + * + * syscalls (arm-multilib) + * + * Copyright 2025 Phoenix Systems + * Author: Hubert Badocha + * + * This file is part of Phoenix-RTOS. + * + * %LICENSE% + */ + +#define __ASSEMBLY__ +#include + +.text + + +#define SYSCALLDEF(sym, sn) \ +.globl sym; \ +.type sym, %function; \ +sym: \ + bl abort; \ +.size sym, .-sym + + +.globl vfork; +.type vfork, %function; +vfork: + b vforksvc +.size vfork, .-vfork + + +#define SYSCALLS_LIBC(name) \ + SYSCALLDEF(name, __COUNTER__); + + +SYSCALLS(SYSCALLS_LIBC) diff --git a/arch/arm/v7a/reboot.c b/arch/arm/v7a/reboot.c index 50be41a3..d852d97c 100644 --- a/arch/arm/v7a/reboot.c +++ b/arch/arm/v7a/reboot.c @@ -14,6 +14,25 @@ */ #include + +#if defined(LIBPHOENIX_MULTILIB) + + +int reboot(int magic) +{ + return -1; +} + + +int reboot_reason(uint32_t *val) +{ + return -1; +} + + +#else + + #include #if defined(__CPU_ZYNQ7000) #include @@ -52,3 +71,5 @@ int reboot_reason(uint32_t *val) *val = pctl.reboot.reason; return 0; } + +#endif diff --git a/arch/arm/v7m/reboot.c b/arch/arm/v7m/reboot.c index 38c32f7c..3035adee 100644 --- a/arch/arm/v7m/reboot.c +++ b/arch/arm/v7m/reboot.c @@ -14,6 +14,25 @@ */ #include + +#if defined(LIBPHOENIX_MULTILIB) + + +int reboot(int magic) +{ + return -1; +} + + +int reboot_reason(uint32_t *val) +{ + return -1; +} + + +#else + + #include #if defined(__CPU_STM32L4X6) @@ -55,3 +74,5 @@ int reboot_reason(uint32_t *val) *val = pctl.reboot.reason; return 0; } + +#endif diff --git a/arch/arm/v8m/reboot.c b/arch/arm/v8m/reboot.c index 2b7d8ff1..cc221125 100644 --- a/arch/arm/v8m/reboot.c +++ b/arch/arm/v8m/reboot.c @@ -14,6 +14,25 @@ */ #include + +#if defined(LIBPHOENIX_MULTILIB) + + +int reboot(int magic) +{ + return -1; +} + + +int reboot_reason(uint32_t *val) +{ + return -1; +} + + +#else + + #include #if defined(__CPU_NRF9160) @@ -54,3 +73,5 @@ int reboot_reason(uint32_t *val) *val = pctl.reboot.reason; return 0; } + +#endif diff --git a/arch/arm/v8r/reboot.c b/arch/arm/v8r/reboot.c index 19d33a8c..92c35760 100644 --- a/arch/arm/v8r/reboot.c +++ b/arch/arm/v8r/reboot.c @@ -14,6 +14,25 @@ */ #include + +#if defined(LIBPHOENIX_MULTILIB) + + +int reboot(int magic) +{ + return -1; +} + + +int reboot_reason(uint32_t *val) +{ + return -1; +} + + +#else + + #include #if defined(__CPU_MPS3AN536) #include @@ -40,3 +59,5 @@ int reboot_reason(uint32_t *val) return 0; } + +#endif diff --git a/include/arch/armv7a/arch.h b/include/arch/armv7a/arch.h index c35b31c0..4098e0a9 100644 --- a/include/arch/armv7a/arch.h +++ b/include/arch/armv7a/arch.h @@ -37,9 +37,11 @@ #define __ieee754_sqrt(x) ({ double a = (x); __asm__ volatile ("vsqrt.f64 %P0, %P1" : "=w"(a) : "w"(a)); a; }) #endif +#if __ARM_FP & 4 #define __IEEE754_SQRTF #define __ieee754_sqrtf(x) ({ float a = (x); __asm__ volatile ("vsqrt.f32 %0, %1" : "=t"(a) : "t"(a)); a; }) #endif +#endif #define _PAGE_SIZE 0x1000 diff --git a/include/arch/armv7m/arch.h b/include/arch/armv7m/arch.h index 1812f5a0..c9f79036 100644 --- a/include/arch/armv7m/arch.h +++ b/include/arch/armv7m/arch.h @@ -37,9 +37,11 @@ #define __ieee754_sqrt(x) ({ double a = (x); __asm__ volatile ("vsqrt.f64 %P0, %P1" : "=w"(a) : "w"(a)); a; }) #endif +#if __ARM_FP & 4 #define __IEEE754_SQRTF #define __ieee754_sqrtf(x) ({ float a = (x); __asm__ volatile ("vsqrt.f32 %0, %1" : "=t"(a) : "t"(a)); a; }) #endif +#endif #define _PAGE_SIZE 0x200 diff --git a/include/arch/armv8m/arch.h b/include/arch/armv8m/arch.h index 12df9689..17f01f6e 100644 --- a/include/arch/armv8m/arch.h +++ b/include/arch/armv8m/arch.h @@ -37,9 +37,11 @@ #define __ieee754_sqrt(x) ({ double a = (x); __asm__ volatile ("vsqrt.f64 %P0, %P1" : "=w"(a) : "w"(a)); a; }) #endif +#if __ARM_FP & 4 #define __IEEE754_SQRTF #define __ieee754_sqrtf(x) ({ float a = (x); __asm__ volatile ("vsqrt.f32 %0, %1" : "=t"(a) : "t"(a)); a; }) #endif +#endif #define _PAGE_SIZE 0x200 diff --git a/include/arch/armv8r/arch.h b/include/arch/armv8r/arch.h index 34a2d4fd..bae9a449 100644 --- a/include/arch/armv8r/arch.h +++ b/include/arch/armv8r/arch.h @@ -37,9 +37,11 @@ #define __ieee754_sqrt(x) ({ double a = (x); __asm__ volatile ("vsqrt.f64 %P0, %P1" : "=w"(a) : "w"(a)); a; }) #endif +#if __ARM_FP & 4 #define __IEEE754_SQRTF #define __ieee754_sqrtf(x) ({ float a = (x); __asm__ volatile ("vsqrt.f32 %0, %1" : "=t"(a) : "t"(a)); a; }) #endif +#endif #define _PAGE_SIZE 0x1000