-
Notifications
You must be signed in to change notification settings - Fork 40
rv64g initial import #364
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
base: main
Are you sure you want to change the base?
rv64g initial import #364
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,40 @@ | ||
/* Portions of this file are Copyright (c) 2025 Tactical Computing Labs, LLC; see COPYING */ | ||
#include "qthread/common.h" | ||
|
||
#include <stddef.h> | ||
#include <stdint.h> | ||
|
||
#include "qt_visibility.h" | ||
|
||
#define setcontext(u) qt_setmctxt(&(u)->mc) | ||
#define getcontext(u) qt_getmctxt(&(u)->mc) | ||
typedef struct mctxt mctxt_t; | ||
typedef struct uctxt uctxt_t; | ||
|
||
struct mctxt { | ||
/* Saved main processor registers. */ | ||
#ifdef NEEDARMA64CONTEXT | ||
uint64_t regs[32]; /* callee saves x0-x30, SP */ | ||
uint64_t fpu_regs[32]; /* 32 64 bit FPU Registers */ | ||
#else | ||
uint32_t regs[16]; /* callee saves r0-r15 */ | ||
#endif | ||
char first; | ||
}; | ||
|
||
struct uctxt { | ||
struct { | ||
void *ss_sp; | ||
size_t ss_size; | ||
} uc_stack; | ||
|
||
// sigset_t uc_sigmask; | ||
mctxt_t mc; | ||
struct uctxt *uc_link; /* unused */ | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Don't worry about this for this PR, but I need to remember to come back and remove these |
||
}; | ||
|
||
int INTERNAL qt_swapctxt(uctxt_t *, uctxt_t *); | ||
void INTERNAL qt_makectxt(uctxt_t *, void (*)(void), int, ...); | ||
int INTERNAL qt_getmctxt(mctxt_t *); | ||
void INTERNAL qt_setmctxt(mctxt_t *); | ||
/* vim:set expandtab: */ |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,3 +1,5 @@ | ||
/* Portions of this file are Copyright (c) 2025 Tactical Computing Labs, LLC; see COPYING */ | ||
|
||
#ifndef TASKIMPL_H | ||
#define TASKIMPL_H | ||
|
||
|
@@ -22,6 +24,11 @@ | |
#define NEEDARMMAKECONTEXT | ||
#define NEEDSWAPCONTEXT | ||
#include "arm-ucontext.h" | ||
#elif (QTHREAD_ASSEMBLY_ARCH == QTHREAD_ARM) | ||
#include <stdarg.h> | ||
#define NEEDRISCVMAKECONTEXT | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Unused macro? |
||
#define NEEDSWAPCONTEXT | ||
#include "riscv-ucontext.h" | ||
#elif (QTHREAD_ASSEMBLY_ARCH == QTHREAD_ARMV8_A64) | ||
#include <stdarg.h> | ||
#define NEEDARMA64MAKECONTEXT | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,3 +1,5 @@ | ||
/* Portions of this file are Copyright (c) 2025 Tactical Computing Labs, LLC; see COPYING */ | ||
|
||
#ifndef QT_ATOMICS_H | ||
#define QT_ATOMICS_H | ||
|
||
|
@@ -29,6 +31,9 @@ | |
QTHREAD_ASSEMBLY_ARCH == QTHREAD_ARMV8_A64 | ||
#define SPINLOCK_BODY() \ | ||
do { __asm__ __volatile__("yield" ::: "memory"); } while (0) | ||
#elif QTHREAD_ASSEMBLY_ARCH == QTHREAD_RISCV | ||
#define SPINLOCK_BODY() \ | ||
do { atomic_thread_fence(memory_order_acq_rel); } while (0) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This is not right. It should be some kind of pause instruction, not a memory fence. The fences are handled elsewhere. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I chased this down a bit more. The correct assembly seems to be the same as the AMD64 branch. The only catch is that clang needs explicit permission to use the zihintpause extension so |
||
#elif QTHREAD_ASSEMBLY_ARCH == QTHREAD_POWERPC64 || \ | ||
QTHREAD_ASSEMBLY_ARCH == QTHREAD_POWERPC32 | ||
// For whatever reason the 29 (mdoio) version of this instruction performed | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,3 +1,5 @@ | ||
/* Portions of this file are Copyright (c) 2025 Tactical Computing Labs, LLC; see COPYING */ | ||
|
||
#ifdef DEBUG_CPUID | ||
#include <stdio.h> | ||
#endif | ||
|
@@ -14,6 +16,23 @@ enum vendor { AMD, Intel, Unknown }; | |
static int cacheline_bytes = 0; | ||
|
||
#define MAX(a, b) (((a) > (b)) ? (a) : (b)) | ||
#if defined(__riscv) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Please include this as a part of the big if/elif/elif... below instead of nesting the ifdefs further |
||
|
||
#include <unistd.h> | ||
|
||
// https://matrix89.github.io/writes/writes/experiments-in-riscv/ | ||
// | ||
static unsigned int cpuid() { | ||
register unsigned int hart_id = 0; | ||
__asm__ __volatile__("csrr %0, mhartid" : "=r" (hart_id) : : ); | ||
return hart_id; | ||
} | ||
|
||
static void figure_out_cacheline_size(void) { | ||
cacheline_bytes = sysconf (_SC_LEVEL1_DCACHE_LINESIZE); | ||
} | ||
|
||
#else | ||
|
||
#if ((QTHREAD_ASSEMBLY_ARCH == QTHREAD_IA32) || \ | ||
(QTHREAD_ASSEMBLY_ARCH == QTHREAD_AMD64)) && \ | ||
|
@@ -23,6 +42,8 @@ static void cpuid(unsigned int const op, | |
unsigned int *ebx_ptr, | ||
unsigned int *ecx_ptr, | ||
unsigned int *edx_ptr) { | ||
|
||
|
||
#if (QTHREAD_ASSEMBLY_ARCH == QTHREAD_IA32) && defined(__PIC__) | ||
unsigned int eax, ebx, ecx, edx; | ||
unsigned int pic_ebx = 0; | ||
|
@@ -43,13 +64,15 @@ static void cpuid(unsigned int const op, | |
: "=a"(*eax_ptr), "=b"(*ebx_ptr), "=c"(*ecx_ptr), "=d"(*edx_ptr) | ||
: "a"(op)); | ||
#endif /* if (QTHREAD_ASSEMBLY_ARCH == QTHREAD_IA32) && defined(__PIC__) */ | ||
|
||
} | ||
|
||
static void cpuid4(int const cache, | ||
unsigned int *eax_ptr, | ||
unsigned int *ebx_ptr, | ||
unsigned int *ecx_ptr, | ||
unsigned int *edx_ptr) { | ||
|
||
#if (QTHREAD_ASSEMBLY_ARCH == QTHREAD_IA32) && defined(__PIC__) | ||
unsigned int eax, ebx, ecx, edx; | ||
unsigned int pic_ebx = 0; | ||
|
@@ -339,6 +362,8 @@ static void figure_out_cacheline_size(void) { | |
(QTHREAD_ASSEMBLY_ARCH == QTHREAD_POWERPC64) */ | ||
} | ||
|
||
#endif | ||
|
||
/* returns the cache line size */ | ||
int API_FUNC qthread_cacheline(void) { | ||
if (cacheline_bytes == 0) { | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,4 +1,5 @@ | ||
/* System Headers */ | ||
/* Portions of this file are Copyright (c) 2025 Tactical Computing Labs, LLC; see COPYING */ | ||
#include <limits.h> /* for INT_MAX */ | ||
#include <stdint.h> | ||
|
||
|
@@ -80,6 +81,19 @@ extern unsigned int QTHREAD_LOCKING_STRIPES; | |
#if (QTHREAD_ASSEMBLY_ARCH == QTHREAD_AMD64 || \ | ||
QTHREAD_ASSEMBLY_ARCH == QTHREAD_ARM || \ | ||
QTHREAD_ASSEMBLY_ARCH == QTHREAD_ARMV8_A64) | ||
#define UNLOCK_THIS_UNMODIFIED_SYNCVAR(addr, unlocked) \ | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The risc-v branch is identical to the AMD64 and ARM branches so please just include |
||
do { \ | ||
atomic_store_explicit( \ | ||
(_Atomic uint64_t *)&(addr)->u.w, (unlocked), memory_order_relaxed); \ | ||
} while (0) | ||
#define UNLOCK_THIS_MODIFIED_SYNCVAR(addr, val, state) \ | ||
do { \ | ||
MACHINE_FENCE; \ | ||
atomic_store_explicit((_Atomic uint64_t *)&(addr)->u.w, \ | ||
BUILD_UNLOCKED_SYNCVAR(val, state), \ | ||
memory_order_relaxed); \ | ||
} while (0) | ||
#elif (QTHREAD_RISCV) | ||
#define UNLOCK_THIS_UNMODIFIED_SYNCVAR(addr, unlocked) \ | ||
do { \ | ||
atomic_store_explicit( \ | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is just re-using the same mctxt that's used for ARM, and I'm not sure that's right. The NEEDARMA64CONTEXT macro should never be set here and it appears the corresponding assembly is saving more than 16 registers (like it would in the 32-bit case) so this seems wrong.