diff --git a/lib_locks/Makefile b/lib_locks/Makefile new file mode 100644 index 0000000..f5d9ab3 --- /dev/null +++ b/lib_locks/Makefile @@ -0,0 +1,37 @@ +.SUFFIXES: + +TARGET ?= vx4a + +.PHONY: liblocks +liblocks: lib/$(TARGET)/liblocks.a + +.PHONY: clean +clean: + rm -rf build + +.PHONY: all +all: liblocks + +include $(wildcard build/*/*.d) + +OBJECTS := \ + hwlock.o \ + swlock.o \ + swlock_asm.o + +build/$(TARGET): + mkdir -p $@ + +lib/$(TARGET): + mkdir -p $@ + +lib/$(TARGET)/liblocks.a : $(addprefix build/$(TARGET)/,$(OBJECTS)) | lib/$(TARGET) + xmosar rcs $@ $^ + +.SECONDARY: build/$(TARGET)/%.o +build/$(TARGET)/%.o : src/%.c | build/$(TARGET) + xcc -c $< -o $@ -march=$(TARGET) -Os -ffunction-sections -Wall -Werror -report -I../lib_locks/api -MD -MF $|/$*.d + +.SECONDARY: build/$(TARGET)/%.o +build/$(TARGET)/%.o : src/%.S | build/$(TARGET) + xcc -c $< -o $@ -march=$(TARGET) -Os -ffunction-sections -Wall -Werror -report -I../lib_locks/api -MD -MF $|/$*.d diff --git a/lib_locks/api/hwlock.h b/lib_locks/api/hwlock.h index 7ea0e74..8086878 100644 --- a/lib_locks/api/hwlock.h +++ b/lib_locks/api/hwlock.h @@ -28,8 +28,13 @@ enum { inline hwlock_t hwlock_alloc(void) { hwlock_t lock; +#ifdef __riscv_xxcore + asm volatile ("xm.getr %0, " QUOTE(XS1_RES_TYPE_LOCK) + : "=x" (lock)); +#else asm volatile ("getr %0, " QUOTE(XS1_RES_TYPE_LOCK) : "=r" (lock)); +#endif return lock; } @@ -43,9 +48,15 @@ inline hwlock_t hwlock_alloc(void) */ inline void hwlock_free(hwlock_t lock) { +#ifdef __riscv_xxcore + asm volatile ("xm.freer %0" + : /* no output */ + : "x" (lock)); +#else asm volatile ("freer res[%0]" : /* no output */ : "r" (lock)); +#endif } /** Acquire a hardware lock. @@ -58,10 +69,17 @@ inline void hwlock_free(hwlock_t lock) */ inline void hwlock_acquire(hwlock_t lock) { +#ifdef __riscv_xxcore + asm volatile ("xm.in %0, %0" + : /* no output */ + : "x" (lock) + : "memory"); +#else asm volatile ("in %0, res[%0]" : /* no output */ : "r" (lock) : "memory"); +#endif } /** Release a hardware lock. @@ -73,10 +91,17 @@ inline void hwlock_acquire(hwlock_t lock) */ inline void hwlock_release(hwlock_t lock) { +#ifdef __riscv_xxcore + asm volatile ("xm.out %0, %0" + : /* no output */ + : "x" (lock) + : "memory"); +#else asm volatile ("out res[%0], %0" : /* no output */ : "r" (lock) : "memory"); +#endif } #endif // __hwlock_h_ diff --git a/lib_locks/api/swlock.h b/lib_locks/api/swlock.h index 63c9ec1..cf467b3 100644 --- a/lib_locks/api/swlock.h +++ b/lib_locks/api/swlock.h @@ -3,7 +3,14 @@ #ifndef __swlock_h_ #define __swlock_h_ -#include + +#ifndef REFERENCE_PARAM +#ifdef __XC__ +#define REFERENCE_PARAM(type, name) type &name +#else +#define REFERENCE_PARAM(type, name) type *name +#endif +#endif /** Type that represents a software lock */ typedef unsigned swlock_t; diff --git a/lib_locks/lib_build_info.cmake b/lib_locks/lib_build_info.cmake index 80af8d0..db9650f 100644 --- a/lib_locks/lib_build_info.cmake +++ b/lib_locks/lib_build_info.cmake @@ -1,5 +1,5 @@ set(LIB_NAME lib_locks) -set(LIB_VERSION 2.2.0) +set(LIB_VERSION 2.3.0) set(LIB_INCLUDES api) set(LIB_DEPENDENT_MODULES "") diff --git a/lib_locks/module_build_info b/lib_locks/module_build_info index e2fb703..309c85b 100644 --- a/lib_locks/module_build_info +++ b/lib_locks/module_build_info @@ -9,4 +9,4 @@ # # You can also set MODULE_XCC_C_FLAGS, MODULE_XCC_XC_FLAGS etc.. -VERSION = 2.2.0 +VERSION = 2.3.0 diff --git a/lib_locks/src/swlock_asm.S b/lib_locks/src/swlock_asm.S index 1e4a413..9a0ba0d 100644 --- a/lib_locks/src/swlock_asm.S +++ b/lib_locks/src/swlock_asm.S @@ -3,6 +3,9 @@ .file "swlock_asm.S" .text + +#ifndef __riscv_xxcore + .cc_top swlock_try_acquire.function .align 4 .globl swlock_try_acquire @@ -42,3 +45,44 @@ swlock_try_acquire: .set swlock_try_acquire.maxchanends, 0 .set swlock_try_acquire.maxtimers, 0 .set swlock_try_acquire.maxthreads, 1 + +#else + + .p2align 2 +.globl swlock_try_acquire +.globl swlock_try_acquire.maxthreads +.globl swlock_try_acquire.maxtimers +.globl swlock_try_acquire.maxchanends +.resource_const swlock_try_acquire, "stack_frame_bytes", 0 +.resource_list_empty swlock_try_acquire, "callees" +.resource_list_empty swlock_try_acquire, "tail_callees" +.resource_list_empty swlock_try_acquire, "parallel_callees" +.type swlock_try_acquire, @function +.set swlock_try_acquire.locnochandec, 1 +swlock_try_acquire: + xm.getid x28 + addi x28, x28, 1 + xm.ldwi x11, 0(x10) // Get the current mutex value. + bne x11,x0, .Lfailed // Check if it is already claimed. + xm.stwi x28, 0(x10) // Claim it. + // A high priority core needs to ensure that a low priority core + // has executed the store before we load + xm.nop + xm.nop + xm.nop + xm.nop + xm.nop + xm.nop + xm.nop + xm.ldwi x12, 0(x10) // Reload the mutex. + xm.eq x10, x28, x12 // If the value hasn't changed we've claimed the + xm.retsp 0 // mutex. +.Lfailed: + xm.ldcu x10, 0 + xm.retsp 0 +.size swlock_try_acquire, .-swlock_try_acquire +.set swlock_try_acquire.maxchanends, 0 +.set swlock_try_acquire.maxtimers, 0 +.set swlock_try_acquire.maxthreads, 1 + +#endif