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

[arm64] add hw thread self #8942

Merged
merged 4 commits into from
May 28, 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
15 changes: 13 additions & 2 deletions include/rtdef.h
Original file line number Diff line number Diff line change
Expand Up @@ -740,8 +740,10 @@ struct rt_cpu
struct rt_thread *current_thread;

rt_uint8_t irq_switch_flag:1;
rt_uint8_t critical_switch_flag:1;
rt_uint8_t sched_lock_flag:1;
#ifndef ARCH_USING_HW_THREAD_SELF
rt_uint8_t critical_switch_flag:1;
#endif /* ARCH_USING_HW_THREAD_SELF */

rt_uint8_t current_priority;
rt_list_t priority_table[RT_THREAD_PRIORITY_MAX];
Expand All @@ -763,10 +765,19 @@ struct rt_cpu
struct rt_cpu_usage_stats cpu_stat;
#endif
};
typedef struct rt_cpu *rt_cpu_t;

#else /* !RT_USING_SMP */
struct rt_cpu
{
struct rt_thread *current_thread;
};

#endif /* RT_USING_SMP */

typedef struct rt_cpu *rt_cpu_t;
/* Noted: As API to reject writing to this variable from application codes */
#define rt_current_thread rt_thread_self()

struct rt_thread;

#ifdef RT_USING_SMART
Expand Down
5 changes: 5 additions & 0 deletions include/rtsched.h
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,10 @@ struct rt_sched_thread_ctx
rt_uint8_t sched_flag_locked:1; /**< calling thread have the scheduler locked */
rt_uint8_t sched_flag_ttmr_set:1; /**< thread timer is start */

#ifdef ARCH_USING_HW_THREAD_SELF
rt_uint8_t critical_switch_flag:1; /**< critical switch pending */
#endif /* ARCH_USING_HW_THREAD_SELF */

#ifdef RT_USING_SMP
rt_uint8_t bind_cpu; /**< thread is bind to cpu */
rt_uint8_t oncpu; /**< process on cpu */
Expand Down Expand Up @@ -170,6 +174,7 @@ rt_err_t rt_sched_thread_timer_stop(struct rt_thread *thread);
rt_err_t rt_sched_thread_timer_start(struct rt_thread *thread);
void rt_sched_insert_thread(struct rt_thread *thread);
void rt_sched_remove_thread(struct rt_thread *thread);
struct rt_thread *rt_sched_thread_self(void);

#endif /* defined(__RT_KERNEL_SOURCE__) || defined(__RT_IPC_SOURCE__) */

Expand Down
9 changes: 6 additions & 3 deletions include/rtthread.h
Original file line number Diff line number Diff line change
Expand Up @@ -669,6 +669,12 @@ rt_err_t rt_device_control(rt_device_t dev, int cmd, void *arg);
void rt_interrupt_enter(void);
void rt_interrupt_leave(void);

/**
* CPU object
*/
struct rt_cpu *rt_cpu_self(void);
struct rt_cpu *rt_cpu_index(int index);

#ifdef RT_USING_SMP

/*
Expand All @@ -679,9 +685,6 @@ rt_base_t rt_cpus_lock(void);
void rt_cpus_unlock(rt_base_t level);
void rt_cpus_lock_status_restore(struct rt_thread *thread);

struct rt_cpu *rt_cpu_self(void);
struct rt_cpu *rt_cpu_index(int index);

#ifdef RT_USING_DEBUG
rt_base_t rt_cpu_get_id(void);
#else /* !RT_USING_DEBUG */
Expand Down
6 changes: 6 additions & 0 deletions libcpu/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,8 @@ if ARCH_ARMV8 && ARCH_CPU_64BIT
default y
config ARCH_USING_GENERIC_CPUID
bool "Using generic cpuid implemenation"
select ARCH_USING_HW_THREAD_SELF
default y if RT_USING_OFW
default n
endmenu
endif
Expand Down Expand Up @@ -270,3 +272,7 @@ config ARCH_HOST_SIMULATOR
config ARCH_CPU_STACK_GROWS_UPWARD
bool
default n

config ARCH_USING_HW_THREAD_SELF
bool
default n
33 changes: 27 additions & 6 deletions libcpu/aarch64/common/context_gcc.S
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
* 2021-05-18 Jesven the first version
* 2023-06-24 WangXiaoyao Support backtrace for user thread
* 2024-01-06 Shell Fix barrier on irq_disable/enable
* 2024-01-18 Shell fix implicit dependency of cpuid management
*/

#ifndef __ASSEMBLY__
Expand All @@ -27,15 +28,35 @@ rt_thread_switch_interrupt_flag: .zero 8
#endif

.text
.weak rt_hw_cpu_id_set

/**
* #ifdef RT_USING_OFW
* void rt_hw_cpu_id_set(long cpuid)
* #else
* void rt_hw_cpu_id_set(void)
* #endif
*/
.type rt_hw_cpu_id_set, @function
rt_hw_cpu_id_set:
mrs x0, mpidr_el1 /* MPIDR_EL1: Multi-Processor Affinity Register */
#ifdef ARCH_USING_GENERIC_CPUID
.globl rt_hw_cpu_id_set
#else /* !ARCH_USING_GENERIC_CPUID */
.weak rt_hw_cpu_id_set
#endif /* ARCH_USING_GENERIC_CPUID */

#ifndef RT_USING_OFW
mrs x0, mpidr_el1 /* MPIDR_EL1: Multi-Processor Affinity Register */
#ifdef ARCH_ARM_CORTEX_A55
lsr x0, x0, #8
#endif
and x0, x0, #15
msr tpidr_el1, x0
lsr x0, x0, #8
#endif /* ARCH_ARM_CORTEX_A55 */
and x0, x0, #15
#endif /* !RT_USING_OFW */

#ifdef ARCH_USING_HW_THREAD_SELF
msr tpidrro_el0, x0
#else /* !ARCH_USING_HW_THREAD_SELF */
msr tpidr_el1, x0
#endif /* ARCH_USING_HW_THREAD_SELF */
ret

/*
Expand Down
18 changes: 18 additions & 0 deletions libcpu/aarch64/common/cpu.c
Original file line number Diff line number Diff line change
Expand Up @@ -231,6 +231,24 @@ int rt_hw_cpu_boot_secondary(int num_cpus, rt_uint64_t *cpu_hw_ids, struct cpu_o

#endif /*RT_USING_SMP*/

/**
* Generic hw-cpu-id
*/
#ifdef ARCH_USING_GENERIC_CPUID

int rt_hw_cpu_id(void)
{
#if RT_CPUS_NR > 1
long cpuid;
__asm__ volatile("mrs %0, tpidrro_el0":"=r"(cpuid));
return cpuid;
#else
return 0;
#endif /* RT_CPUS_NR > 1 */
}

#endif /* ARCH_USING_GENERIC_CPUID */

/**
* @addtogroup ARM CPU
*/
Expand Down
42 changes: 17 additions & 25 deletions libcpu/aarch64/common/cpuport.h
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
* Date Author Notes
* 2023-10-25 Shell Move ffs to cpuport, add general implementation
* by inline assembly
* 2024-01-18 Shell support rt_hw_thread_self to improve overall performance
*/

#ifndef CPUPORT_H__
Expand All @@ -27,31 +28,6 @@ typedef struct
rt_uint32_t value;
} rt_hw_spinlock_t;

/**
* Generic hw-cpu-id
*/
#ifdef ARCH_USING_GENERIC_CPUID

#if RT_CPUS_NR > 1

rt_inline int rt_hw_cpu_id(void)
{
long cpuid;
__asm__ volatile("mrs %0, tpidr_el1":"=r"(cpuid));
return cpuid;
}

#else

rt_inline int rt_hw_cpu_id(void)
{
return 0;
}

#endif /* RT_CPUS_NR > 1 */

#endif /* ARCH_USING_GENERIC_CPUID */

#endif /* RT_USING_SMP */

#define rt_hw_barrier(cmd, ...) \
Expand Down Expand Up @@ -107,4 +83,20 @@ rt_inline int __rt_ffs(int value)

#endif /* RT_USING_CPU_FFS */

#ifdef ARCH_USING_HW_THREAD_SELF
rt_inline struct rt_thread *rt_hw_thread_self(void)
{
struct rt_thread *thread;
__asm__ volatile ("mrs %0, tpidr_el1":"=r"(thread));

return thread;
}

rt_inline void rt_hw_thread_set_self(struct rt_thread *thread)
{
__asm__ volatile ("msr tpidr_el1, %0"::"r"(thread));
}

#endif /* ARCH_USING_HW_THREAD_SELF */

#endif /*CPUPORT_H__*/
12 changes: 8 additions & 4 deletions libcpu/aarch64/cortex-a/entry_point.S
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
* 2020-01-15 bigmagic the first version
* 2020-08-10 SummerGift support clang compiler
* 2023-04-29 GuEe-GUI support kernel's ARM64 boot header
* 2024-01-18 Shell fix implicit dependency of cpuid management
*/

#ifndef __ASSEMBLY__
Expand Down Expand Up @@ -95,6 +96,10 @@ _start:
/* Save cpu stack */
get_phy stack_top, .boot_cpu_stack_top
/* Save cpu id temp */
#ifdef ARCH_USING_HW_THREAD_SELF
msr tpidrro_el0, xzr
/* Save thread self */
#endif /* ARCH_USING_HW_THREAD_SELF */
msr tpidr_el1, xzr

bl init_cpu_el
Expand Down Expand Up @@ -149,11 +154,10 @@ _secondary_cpu_entry:

/* Get cpu id success */
sub x0, x2, #1
msr tpidr_el1, x0 /* Save cpu id global */
#else
bl rt_hw_cpu_id_set
mrs x0, tpidr_el1
#endif /* RT_USING_OFW */
/* Save cpu id global */
bl rt_hw_cpu_id_set
bl rt_hw_cpu_id

/* Set current cpu's stack top */
sub x0, x0, #1
Expand Down
26 changes: 26 additions & 0 deletions src/cpu_up.c
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,14 @@
* Change Logs:
* Date Author Notes
* 2024-04-19 Shell Fixup UP irq spinlock
* 2024-05-22 Shell Add UP cpu object and
* maintain the rt_current_thread inside it
*/
#include <rthw.h>
#include <rtthread.h>

static struct rt_cpu _cpu;

/**
* @brief Initialize a static spinlock object.
*
Expand Down Expand Up @@ -80,3 +84,25 @@ void rt_spin_unlock_irqrestore(struct rt_spinlock *lock, rt_base_t level)
rt_exit_critical_safe(critical_level);
rt_hw_interrupt_enable(level);
}

/**
* @brief This fucntion will return current cpu object.
*
* @return Return a pointer to the current cpu object.
*/
struct rt_cpu *rt_cpu_self(void)
{
return &_cpu;
}

/**
* @brief This fucntion will return the cpu object corresponding to index.
*
* @param index is the index of target cpu object.
*
* @return Return a pointer to the cpu object corresponding to index.
*/
struct rt_cpu *rt_cpu_index(int index)
{
return index == 0 ? &_cpu : RT_NULL;
}
Loading
Loading