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/grlib_impl.h>
|
||||
|
||||
#if RTEMS_INTERRUPT_LOCK_NEEDS_OBJECT
|
||||
extern rtems_interrupt_lock leon3_l2c_lock;
|
||||
#endif
|
||||
|
||||
/*#define STATIC*/
|
||||
#define STATIC static
|
||||
|
||||
@@ -318,8 +322,6 @@ struct l2cache_priv {
|
||||
int ft_support;
|
||||
int split_support;
|
||||
int atomic_flush;
|
||||
/* Avoid concurrent accesses to L2C registers. */
|
||||
SPIN_DECLARE(devlock);
|
||||
|
||||
/* User defined ISR */
|
||||
l2cache_isr_t isr;
|
||||
@@ -387,22 +389,20 @@ static char * repl_names[4] = {"LRU","Random","Master-Idx-1","Master-IDx-2"};
|
||||
#endif
|
||||
|
||||
static void REG_WRITE(volatile unsigned int *addr, unsigned int val) {
|
||||
struct l2cache_priv *priv = l2cachepriv;
|
||||
SPIN_IRQFLAGS(irqflags);
|
||||
|
||||
SPIN_LOCK_IRQ(&priv->devlock, irqflags);
|
||||
SPIN_LOCK_IRQ(&leon3_l2c_lock, irqflags);
|
||||
*addr = val;
|
||||
SPIN_UNLOCK_IRQ(&priv->devlock, irqflags);
|
||||
SPIN_UNLOCK_IRQ(&leon3_l2c_lock, irqflags);
|
||||
}
|
||||
|
||||
static unsigned int REG_READ(volatile unsigned int *addr) {
|
||||
struct l2cache_priv *priv = l2cachepriv;
|
||||
SPIN_IRQFLAGS(irqflags);
|
||||
unsigned int val;
|
||||
|
||||
SPIN_LOCK_IRQ(&priv->devlock, irqflags);
|
||||
SPIN_LOCK_IRQ(&leon3_l2c_lock, irqflags);
|
||||
val = *addr;
|
||||
SPIN_UNLOCK_IRQ(&priv->devlock, irqflags);
|
||||
SPIN_UNLOCK_IRQ(&leon3_l2c_lock, irqflags);
|
||||
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) {
|
||||
struct l2cache_priv *priv = l2cachepriv;
|
||||
SPIN_IRQFLAGS(irqflags);
|
||||
|
||||
SPIN_LOCK_IRQ(&priv->devlock, irqflags);
|
||||
SPIN_LOCK_IRQ(&leon3_l2c_lock, irqflags);
|
||||
atomic_swap32((uint32_t *) addr, val);
|
||||
SPIN_UNLOCK_IRQ(&priv->devlock, irqflags);
|
||||
SPIN_UNLOCK_IRQ(&leon3_l2c_lock, irqflags);
|
||||
}
|
||||
|
||||
#else
|
||||
@@ -541,7 +540,6 @@ int l2cache_init1(struct drvmgr_dev *dev)
|
||||
priv->dev = dev;
|
||||
strncpy(&priv->devname[0], "l2cache0", DEVNAME_LEN);
|
||||
l2cachepriv = priv;
|
||||
SPIN_INIT(&priv->devlock, priv->devname);
|
||||
|
||||
/* Initialize L2CACHE Hardware */
|
||||
status = l2cache_init(priv);
|
||||
|
||||
@@ -378,6 +378,16 @@ typedef struct {
|
||||
*/
|
||||
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
|
||||
|
||||
@@ -37,6 +37,23 @@
|
||||
|
||||
#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)
|
||||
static inline l2cache *get_l2c_regs(void)
|
||||
{
|
||||
@@ -85,7 +102,7 @@ static inline size_t get_l2_size(void)
|
||||
}
|
||||
#endif
|
||||
|
||||
status = grlib_load_32(®s->l2cs);
|
||||
status = l2c_load_32(®s->l2cs);
|
||||
ways = L2CACHE_L2CS_WAY_GET(status) + 1;
|
||||
set_size = L2CACHE_L2CS_WAY_SIZE_GET(status) * 1024;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user