OpenCores
URL https://opencores.org/ocsvn/c0or1k/c0or1k/trunk

Subversion Repositories c0or1k

[/] [c0or1k/] [trunk/] [src/] [arch/] [arm/] [v5/] [mutex.c] - Rev 2

Compare with Previous | Blame | View Log

/*
 * ARM v5 Binary semaphore (mutex) implementation.
 *
 * Copyright (C) 2007-2010 B Labs Ltd.
 * Author: Prem Mallappa <prem.mallappa@b-labs.co.uk>
 */
 
#include <l4/lib/printk.h>
 
/* Recap on swp:
 * swp rx, ry, [rz]
 * In one instruction:
 * 1) Stores the value in ry into location pointed by rz.
 * 2) Loads the value in the location of rz into rx.
 * By doing so, in one instruction one can attempt to lock
 * a word, and discover whether it was already locked.
 */
 
#define MUTEX_UNLOCKED	0
#define MUTEX_LOCKED	1
 
void __spin_lock(unsigned long *s)
{
	int tmp = 0, tmp2;
	__asm__ __volatile__(
		"1: \n"
		"swp %0, %1, [%2] \n"
		"teq %0, %3 \n"
		"bne 1b \n"
		: "=&r" (tmp2)
		: "r" (tmp), "r"(s), "r"(0)
		: "cc", "memory"
		);
}
 
void __spin_unlock(unsigned long *s)
{
	int tmp = 1, tmp2;
	__asm__ __volatile__(
		"1: \n"
		"swp %0, %1, [%2] \n"
		"teq %0, %3 \n"
		"bne 1b \n"
		: "=&r" (tmp2)
		: "r" (tmp), "r"(s), "r"(0)
		: "cc", "memory"
		);
}
 
int __mutex_lock(unsigned long *s)
{
	int tmp = MUTEX_LOCKED, tmp2;
	__asm__ __volatile__(
		"swp %0, %1, [%2] \n"
		: "=&r"(tmp2)
		: "r"(tmp), "r"(s)
		: "cc", "memory"
		);
	if (tmp2 == MUTEX_UNLOCKED)
		return 1;
 
	return 0;
}
 
void __mutex_unlock(unsigned long *s)
{
	int tmp, tmp2=MUTEX_UNLOCKED;
	__asm__ __volatile__(
		"swp %0, %1, [%2] \n"
		: "=&r"(tmp)
		: "r"(tmp2), "r"(s)
		: "cc", "memory"
		);
	BUG_ON(tmp != MUTEX_LOCKED);
}
 

Compare with Previous | Blame | View Log

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.