forked from Imagelibrary/rtems
sparc/leon3: Add leon3_l2c_lock
Use a single lock for all L2C support functions. Close #4925.
This commit is contained in:
committed by
Kinsey Moore
parent
7d5c08db80
commit
e53dfabe36
@@ -40,6 +40,10 @@
|
|||||||
#include <grlib/l2c.h>
|
#include <grlib/l2c.h>
|
||||||
#include <grlib/grlib_impl.h>
|
#include <grlib/grlib_impl.h>
|
||||||
|
|
||||||
|
#if RTEMS_INTERRUPT_LOCK_NEEDS_OBJECT
|
||||||
|
extern rtems_interrupt_lock leon3_l2c_lock;
|
||||||
|
#endif
|
||||||
|
|
||||||
/*#define STATIC*/
|
/*#define STATIC*/
|
||||||
#define STATIC static
|
#define STATIC static
|
||||||
|
|
||||||
@@ -318,8 +322,6 @@ struct l2cache_priv {
|
|||||||
int ft_support;
|
int ft_support;
|
||||||
int split_support;
|
int split_support;
|
||||||
int atomic_flush;
|
int atomic_flush;
|
||||||
/* Avoid concurrent accesses to L2C registers. */
|
|
||||||
SPIN_DECLARE(devlock);
|
|
||||||
|
|
||||||
/* User defined ISR */
|
/* User defined ISR */
|
||||||
l2cache_isr_t isr;
|
l2cache_isr_t isr;
|
||||||
@@ -387,22 +389,20 @@ static char * repl_names[4] = {"LRU","Random","Master-Idx-1","Master-IDx-2"};
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
static void REG_WRITE(volatile unsigned int *addr, unsigned int val) {
|
static void REG_WRITE(volatile unsigned int *addr, unsigned int val) {
|
||||||
struct l2cache_priv *priv = l2cachepriv;
|
|
||||||
SPIN_IRQFLAGS(irqflags);
|
SPIN_IRQFLAGS(irqflags);
|
||||||
|
|
||||||
SPIN_LOCK_IRQ(&priv->devlock, irqflags);
|
SPIN_LOCK_IRQ(&leon3_l2c_lock, irqflags);
|
||||||
*addr = val;
|
*addr = val;
|
||||||
SPIN_UNLOCK_IRQ(&priv->devlock, irqflags);
|
SPIN_UNLOCK_IRQ(&leon3_l2c_lock, irqflags);
|
||||||
}
|
}
|
||||||
|
|
||||||
static unsigned int REG_READ(volatile unsigned int *addr) {
|
static unsigned int REG_READ(volatile unsigned int *addr) {
|
||||||
struct l2cache_priv *priv = l2cachepriv;
|
|
||||||
SPIN_IRQFLAGS(irqflags);
|
SPIN_IRQFLAGS(irqflags);
|
||||||
unsigned int val;
|
unsigned int val;
|
||||||
|
|
||||||
SPIN_LOCK_IRQ(&priv->devlock, irqflags);
|
SPIN_LOCK_IRQ(&leon3_l2c_lock, irqflags);
|
||||||
val = *addr;
|
val = *addr;
|
||||||
SPIN_UNLOCK_IRQ(&priv->devlock, irqflags);
|
SPIN_UNLOCK_IRQ(&leon3_l2c_lock, irqflags);
|
||||||
return val;
|
return val;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -418,12 +418,11 @@ static inline uint32_t atomic_swap32(uint32_t *addr, uint32_t val) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
static void REG_WRITE_ATOMIC(volatile unsigned int *addr, unsigned int val) {
|
static void REG_WRITE_ATOMIC(volatile unsigned int *addr, unsigned int val) {
|
||||||
struct l2cache_priv *priv = l2cachepriv;
|
|
||||||
SPIN_IRQFLAGS(irqflags);
|
SPIN_IRQFLAGS(irqflags);
|
||||||
|
|
||||||
SPIN_LOCK_IRQ(&priv->devlock, irqflags);
|
SPIN_LOCK_IRQ(&leon3_l2c_lock, irqflags);
|
||||||
atomic_swap32((uint32_t *) addr, val);
|
atomic_swap32((uint32_t *) addr, val);
|
||||||
SPIN_UNLOCK_IRQ(&priv->devlock, irqflags);
|
SPIN_UNLOCK_IRQ(&leon3_l2c_lock, irqflags);
|
||||||
}
|
}
|
||||||
|
|
||||||
#else
|
#else
|
||||||
@@ -541,7 +540,6 @@ int l2cache_init1(struct drvmgr_dev *dev)
|
|||||||
priv->dev = dev;
|
priv->dev = dev;
|
||||||
strncpy(&priv->devname[0], "l2cache0", DEVNAME_LEN);
|
strncpy(&priv->devname[0], "l2cache0", DEVNAME_LEN);
|
||||||
l2cachepriv = priv;
|
l2cachepriv = priv;
|
||||||
SPIN_INIT(&priv->devlock, priv->devname);
|
|
||||||
|
|
||||||
/* Initialize L2CACHE Hardware */
|
/* Initialize L2CACHE Hardware */
|
||||||
status = l2cache_init(priv);
|
status = l2cache_init(priv);
|
||||||
|
|||||||
@@ -378,6 +378,16 @@ typedef struct {
|
|||||||
*/
|
*/
|
||||||
extern leon3_timecounter leon3_timecounter_instance;
|
extern leon3_timecounter leon3_timecounter_instance;
|
||||||
|
|
||||||
|
#if RTEMS_INTERRUPT_LOCK_NEEDS_OBJECT
|
||||||
|
/**
|
||||||
|
* @brief This interrupt lock prevents concurrent access to L2C registers.
|
||||||
|
*
|
||||||
|
* This is required as a workaround for the in GR740 errata: Level-2 Cache
|
||||||
|
* Issues H1 2023 (GRLIB-TN-0021).
|
||||||
|
*/
|
||||||
|
extern rtems_interrupt_lock leon3_l2c_lock;
|
||||||
|
#endif
|
||||||
|
|
||||||
/** @} */
|
/** @} */
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
|
|||||||
@@ -37,6 +37,23 @@
|
|||||||
|
|
||||||
#define CPU_DATA_CACHE_ALIGNMENT 64
|
#define CPU_DATA_CACHE_ALIGNMENT 64
|
||||||
|
|
||||||
|
#if RTEMS_INTERRUPT_LOCK_NEEDS_OBJECT
|
||||||
|
rtems_interrupt_lock leon3_l2c_lock =
|
||||||
|
RTEMS_INTERRUPT_LOCK_INITIALIZER( "LEON3 L2C" );
|
||||||
|
#endif
|
||||||
|
|
||||||
|
static inline uint32_t l2c_load_32(const volatile uint32_t *address)
|
||||||
|
{
|
||||||
|
rtems_interrupt_lock_context lock_context;
|
||||||
|
uint32_t value;
|
||||||
|
|
||||||
|
rtems_interrupt_lock_acquire(&leon3_l2c_lock, &lock_context);
|
||||||
|
value = grlib_load_32(address);
|
||||||
|
rtems_interrupt_lock_release(&leon3_l2c_lock, &lock_context);
|
||||||
|
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
|
||||||
#if !defined(LEON3_L2CACHE_BASE)
|
#if !defined(LEON3_L2CACHE_BASE)
|
||||||
static inline l2cache *get_l2c_regs(void)
|
static inline l2cache *get_l2c_regs(void)
|
||||||
{
|
{
|
||||||
@@ -85,7 +102,7 @@ static inline size_t get_l2_size(void)
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
status = grlib_load_32(®s->l2cs);
|
status = l2c_load_32(®s->l2cs);
|
||||||
ways = L2CACHE_L2CS_WAY_GET(status) + 1;
|
ways = L2CACHE_L2CS_WAY_GET(status) + 1;
|
||||||
set_size = L2CACHE_L2CS_WAY_SIZE_GET(status) * 1024;
|
set_size = L2CACHE_L2CS_WAY_SIZE_GET(status) * 1024;
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user