arch: arc: add support for lock/unlock VPX
Adds support for cooperative locking/unlocking the VPX vector registers. Provided that all VPX enabled threads use these routines to control access to the VPX vector registers, it will allow multiple threads to safely use them without the need for saving/restoring them upon each context switch. Signed-off-by: Peter Mitsis <peter.mitsis@intel.com>
This commit is contained in:
parent
f629f1e287
commit
1d07e565fc
4 changed files with 151 additions and 1 deletions
|
@ -343,6 +343,15 @@ config ARC_NORMAL_FIRMWARE
|
||||||
resources of the ARC processors, and, therefore, it shall avoid
|
resources of the ARC processors, and, therefore, it shall avoid
|
||||||
accessing them.
|
accessing them.
|
||||||
|
|
||||||
|
config ARC_VPX_COOPERATIVE_SHARING
|
||||||
|
bool "Cooperative sharing of ARC VPX vector registers"
|
||||||
|
select SCHED_CPU_MASK if MP_MAX_NUM_CPUS > 1
|
||||||
|
help
|
||||||
|
This option enables the cooperative sharing of the ARC VPX vector
|
||||||
|
registers. Threads that want to use those registers must successfully
|
||||||
|
call arc_vpx_lock() before using them, and call arc_vpx_unlock()
|
||||||
|
when done using them.
|
||||||
|
|
||||||
source "arch/arc/core/dsp/Kconfig"
|
source "arch/arc/core/dsp/Kconfig"
|
||||||
|
|
||||||
menu "ARC MPU Options"
|
menu "ARC MPU Options"
|
||||||
|
|
|
@ -19,10 +19,15 @@
|
||||||
#include <zephyr/arch/arc/v2/mpu/arc_core_mpu.h>
|
#include <zephyr/arch/arc/v2/mpu/arc_core_mpu.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if defined(CONFIG_ARC_DSP) && defined(CONFIG_DSP_SHARING)
|
#if defined(CONFIG_ARC_VPX_COOPERATIVE_SHARING) || defined(CONFIG_DSP_SHARING)
|
||||||
#include <zephyr/arch/arc/v2/dsp/arc_dsp.h>
|
#include <zephyr/arch/arc/v2/dsp/arc_dsp.h>
|
||||||
static struct k_spinlock lock;
|
static struct k_spinlock lock;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#if defined(CONFIG_ARC_VPX_COOPERATIVE_SHARING)
|
||||||
|
static struct k_sem vpx_sem[CONFIG_MP_MAX_NUM_CPUS];
|
||||||
|
#endif
|
||||||
|
|
||||||
/* initial stack frame */
|
/* initial stack frame */
|
||||||
struct init_stack_frame {
|
struct init_stack_frame {
|
||||||
uintptr_t pc;
|
uintptr_t pc;
|
||||||
|
@ -320,3 +325,65 @@ void arc_dsp_enable(struct k_thread *thread, unsigned int options)
|
||||||
k_spin_unlock(&lock, key);
|
k_spin_unlock(&lock, key);
|
||||||
}
|
}
|
||||||
#endif /* CONFIG_ARC_DSP && CONFIG_DSP_SHARING */
|
#endif /* CONFIG_ARC_DSP && CONFIG_DSP_SHARING */
|
||||||
|
|
||||||
|
#if defined(CONFIG_ARC_VPX_COOPERATIVE_SHARING)
|
||||||
|
int arc_vpx_lock(k_timeout_t timeout)
|
||||||
|
{
|
||||||
|
k_spinlock_key_t key;
|
||||||
|
unsigned int id;
|
||||||
|
|
||||||
|
key = k_spin_lock(&lock);
|
||||||
|
|
||||||
|
id = _current_cpu->id;
|
||||||
|
#if (CONFIG_MP_MAX_NUM_CPUS > 1) && defined(CONFIG_SCHED_CPU_MASK)
|
||||||
|
__ASSERT(!arch_is_in_isr() && (_current->base.cpu_mask == BIT(id)), "");
|
||||||
|
#endif
|
||||||
|
k_spin_unlock(&lock, key);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* It is assumed that the thread is (still) pinned to
|
||||||
|
* the same CPU identified by <id>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
return k_sem_take(&vpx_sem[id], timeout);
|
||||||
|
}
|
||||||
|
|
||||||
|
void arc_vpx_unlock(void)
|
||||||
|
{
|
||||||
|
k_spinlock_key_t key;
|
||||||
|
unsigned int id;
|
||||||
|
|
||||||
|
key = k_spin_lock(&lock);
|
||||||
|
#if (CONFIG_MP_MAX_NUM_CPUS > 1) && defined(CONFIG_SCHED_CPU_MASK)
|
||||||
|
__ASSERT(!arch_is_in_isr() && (_current->base.cpu_mask == BIT(id)), "");
|
||||||
|
#endif
|
||||||
|
id = _current_cpu->id;
|
||||||
|
k_spin_unlock(&lock, key);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* It is assumed that this thread is (still) pinned to
|
||||||
|
* the CPU identified by <id>, and that it is the same CPU
|
||||||
|
* used by arc_vpx_lock().
|
||||||
|
*/
|
||||||
|
|
||||||
|
k_sem_give(&vpx_sem[id]);
|
||||||
|
}
|
||||||
|
|
||||||
|
void arc_vpx_unlock_force(unsigned int id)
|
||||||
|
{
|
||||||
|
__ASSERT(id < CONFIG_MP_MAX_NUM_CPUS, "");
|
||||||
|
|
||||||
|
k_sem_give(&vpx_sem[id]);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int arc_vpx_sem_init(void)
|
||||||
|
{
|
||||||
|
for (unsigned int i = 0; i < CONFIG_MP_MAX_NUM_CPUS; i++) {
|
||||||
|
k_sem_init(vpx_sem, 1, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
SYS_INIT(arc_vpx_sem_init, PRE_KERNEL_2, CONFIG_KERNEL_INIT_PRIORITY_OBJECTS);
|
||||||
|
#endif
|
||||||
|
|
|
@ -92,3 +92,23 @@ Notes
|
||||||
.. [#f6] currently only ARC VPX scalar port is supported. The support of VPX vector pipeline, VCCM,
|
.. [#f6] currently only ARC VPX scalar port is supported. The support of VPX vector pipeline, VCCM,
|
||||||
STU is not included in this port, and require additional development and / or other runtime
|
STU is not included in this port, and require additional development and / or other runtime
|
||||||
integration.
|
integration.
|
||||||
|
|
||||||
|
VPX Vector Registers
|
||||||
|
--------------------
|
||||||
|
Zephyr supports a limited form sharing of the VPX vector registers known as
|
||||||
|
cooperative sharing. Threads that use these registers must bookend the relevant
|
||||||
|
sections with calls to :c:func:`arc_vpx_lock` and :c:func:`arc_vpx_unlock` to
|
||||||
|
control access to this resource.
|
||||||
|
|
||||||
|
.. note::
|
||||||
|
If the system has multiple CPUs, then it is the responsibility of the
|
||||||
|
application developer to both pin the thread to a single CPU before it
|
||||||
|
attempts to get the cooperative lock, and not modify the CPU affinity
|
||||||
|
while it is waiting for or holding that cooperative lock.
|
||||||
|
|
||||||
|
Configuration Options
|
||||||
|
=====================
|
||||||
|
|
||||||
|
The cooperative sharing of the VPX vector registers is selected when
|
||||||
|
configuration option :kconfig:option:`CONFIG_ARC_VPX_COOPERATIVE_SHARING`
|
||||||
|
is enabled.
|
||||||
|
|
54
include/zephyr/arch/arc/v2/vpx/arc_vpx.h
Normal file
54
include/zephyr/arch/arc/v2/vpx/arc_vpx.h
Normal file
|
@ -0,0 +1,54 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2024 Synopsys.
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: Apache-2.0
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef ZEPHYR_INCLUDE_ARCH_ARC_V2_VPX_ARC_VPX_H_
|
||||||
|
#define ZEPHYR_INCLUDE_ARCH_ARC_V2_VPX_ARC_VPX_H_
|
||||||
|
|
||||||
|
#include <zephyr/sys_clock.h>
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Obtain a cooperative lock on the VPX vector registers
|
||||||
|
*
|
||||||
|
* This function is used to obtain a cooperative lock on the current CPU's
|
||||||
|
* VPX vector registers before the calling thread uses them. Callers
|
||||||
|
* attempting to obtain the cooperative lock must be already restricted to
|
||||||
|
* executing on a single CPU, and continue to execute on that same CPU while
|
||||||
|
* both waiting and holding the lock.
|
||||||
|
*
|
||||||
|
* This routine is not callable from an ISR.
|
||||||
|
*
|
||||||
|
* @param timeout Waiting period to obtain the lock, or one of the special
|
||||||
|
* values K_NO_WAIT and K_FOREVER.
|
||||||
|
*
|
||||||
|
* @return Zero on success, otherwise error code
|
||||||
|
*/
|
||||||
|
int arc_vpx_lock(k_timeout_t timeout);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Release cooperative lock on the VPX vector registers
|
||||||
|
*
|
||||||
|
* This function is used to release the cooperative lock on the current CPU's
|
||||||
|
* VPX vector registers. It is called after the current thread no longer needs
|
||||||
|
* to use the VPX vector registers, thereby allowing another thread to use them.
|
||||||
|
*
|
||||||
|
* This routine is not callable from an ISR.
|
||||||
|
*/
|
||||||
|
void arc_vpx_unlock(void);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Release cooperative lock on a CPU's VPX vector registers
|
||||||
|
*
|
||||||
|
* This function is used to release the cooperative lock on the specified CPU's
|
||||||
|
* VPX vector registers. This routine should not be used except by a system
|
||||||
|
* monitor to release the cooperative lock in case the locking thread where it
|
||||||
|
* is known that the locking thread is unable to release it (e.g. it was
|
||||||
|
* aborted while holding the lock).
|
||||||
|
*
|
||||||
|
* @param cpu_id CPU ID of the VPX vector register set to be unlocked
|
||||||
|
*/
|
||||||
|
void arc_vpx_unlock_force(unsigned int cpu_id);
|
||||||
|
|
||||||
|
#endif /* ZEPHYR_INCLUDE_ARCH_ARC_V2_VPX_ARC_VPX_H_ */
|
Loading…
Add table
Add a link
Reference in a new issue