Shouldn't a spinlock act as a system-wide memory barrier? I took the example given with CodeWarrior (<Install folder>/PA/CodeWarrior_Examples/Bareboard_Examples/P4080_SMP) and enabled caching. I modified the code and it's now like this:
extern char *ret_from_spin_loop;
#define MASTER_CORE_ID 0
#define MAX_NUM_OF_CORES 8
unsigned long long volatile spin_table[MAX_NUM_OF_CORES] = {0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1};
uint32_t spin_table_lock = 1; /* yes, locked */
void __spin_table_loop(void)
{
/* I translated the original assembly code to C */
unsigned long proc_id;
asm ("mfpir %0" : "=r" (proc_id));
proc_id >>= 5;
unsigned long long TEA = 0x1;
lwe_spin_lock(&spin_table_lock);
do {
TEA = spin_table[proc_id];
} while (TEA == 0x1);
lwe_spin_unlock(&spin_table_lock);
void (*fptr)(void) = (void*)(size_t) TEA;
fptr();
}
void __init_smp(void)
{
unsigned long proc_id;
asm ("mfpir %0" : "=r" (proc_id));
proc_id >>= 5;
if (proc_id == MASTER_CORE_ID) {
const unsigned long startAddr = (unsigned long) &ret_from_spin_loop;
for (int coreId = 0; coreId < MAX_NUM_OF_CORES; coreId++) {
spin_table[coreId] = startAddr;
}
lwe_spin_unlock(&spin_table_lock);
}
}
It happens that cores > 0 never see what core 0 writes in the spin_table array, and, consequently, never step-out of the__spin_table_loop function. What's wrong with my code?
> and enabled caching
Each core has its own I and D and L2 cache.
Are your spinlocks in shared-and-uncached memory? If not, how are you making sure all cores are seeing all accesses? What's the memory access architecture on this chip - do they snoop?
Tom