diff --git a/drivers/ddk/core.S b/drivers/ddk/core.S index aaf789b6ad..5dafcb514d 100644 --- a/drivers/ddk/core.S +++ b/drivers/ddk/core.S @@ -47,6 +47,11 @@ .global _MutexInit .global _MutexLock .global _MutexUnlock + .global _InitRwsem + .global _DownRead + .global _DownWrite + .global _UpRead + .global _UpWrite .global _PciApi .global _PciRead16 @@ -120,6 +125,12 @@ .def _MutexLock; .scl 2; .type 32; .endef .def _MutexUnlock; .scl 2; .type 32; .endef + .def _InitRwsem; .scl 2; .type 32; .endef + .def _DownRead; .scl 2; .type 32; .endef + .def _DownWrite; .scl 2; .type 32; .endef + .def _UpRead; .scl 2; .type 32; .endef + .def _UpWrite; .scl 2; .type 32; .endef + .def _PciApi; .scl 2; .type 32; .endef .def _PciRead16; .scl 2; .type 32; .endef .def _PciRead32; .scl 2; .type 32; .endef @@ -191,6 +202,12 @@ _MutexInit: _MutexLock: _MutexUnlock: +_InitRwsem: +_DownRead: +_DownWrite: +_UpRead: +_UpWrite: + _PciApi: _PciRead16: _PciRead32: @@ -263,6 +280,12 @@ _WaitEventTimeout: .ascii " -export:MutexLock" # fastcall .ascii " -export:MutexUnlock" # fastcall + .ascii " -export:InitRwsem" # fastcall + .ascii " -export:DownRead" # fastcall + .ascii " -export:DownWrite" # fastcall + .ascii " -export:UpRead" # fastcall + .ascii " -export:UpWrite" # fastcall + .ascii " -export:PciApi" # .ascii " -export:PciRead16" # stdcall .ascii " -export:PciRead32" # stdcall diff --git a/drivers/include/asm/rwsem.h b/drivers/include/asm/rwsem.h index cad82c9c2f..ce9c349daa 100644 --- a/drivers/include/asm/rwsem.h +++ b/drivers/include/asm/rwsem.h @@ -39,112 +39,24 @@ #ifdef __KERNEL__ #include -/* - * The bias values and the counter type limits the number of - * potential readers/writers to 32767 for 32 bits and 2147483647 - * for 64 bits. - */ +#define FASTCALL __attribute__ ((fastcall)) __attribute__ ((dllimport)) -#ifdef CONFIG_X86_64 -# define RWSEM_ACTIVE_MASK 0xffffffffL -#else -# define RWSEM_ACTIVE_MASK 0x0000ffffL -#endif - -#define RWSEM_UNLOCKED_VALUE 0x00000000L -#define RWSEM_ACTIVE_BIAS 0x00000001L -#define RWSEM_WAITING_BIAS (-RWSEM_ACTIVE_MASK-1) -#define RWSEM_ACTIVE_READ_BIAS RWSEM_ACTIVE_BIAS -#define RWSEM_ACTIVE_WRITE_BIAS (RWSEM_WAITING_BIAS + RWSEM_ACTIVE_BIAS) +void FASTCALL DownRead(struct rw_semaphore *sem)__asm__("DownRead"); +void FASTCALL DownWrite(struct rw_semaphore *sem)__asm__("DownWrite"); +void FASTCALL UpRead(struct rw_semaphore *sem)__asm__("UpRead"); +void FASTCALL UpWrite(struct rw_semaphore *sem)__asm__("UpWrite"); /* * lock for reading */ static inline void __down_read(struct rw_semaphore *sem) { - asm volatile("# beginning down_read\n\t" - LOCK_PREFIX _ASM_INC "(%1)\n\t" - /* adds 0x00000001 */ - " jns 1f\n" - " call call_rwsem_down_read_failed\n" - "1:\n\t" - "# ending down_read\n\t" - : "+m" (sem->count) - : "a" (sem) - : "memory", "cc"); -} - -/* - * trylock for reading -- returns 1 if successful, 0 if contention - */ -static inline int __down_read_trylock(struct rw_semaphore *sem) -{ - long result, tmp; - asm volatile("# beginning __down_read_trylock\n\t" - " mov %0,%1\n\t" - "1:\n\t" - " mov %1,%2\n\t" - " add %3,%2\n\t" - " jle 2f\n\t" - LOCK_PREFIX " cmpxchg %2,%0\n\t" - " jnz 1b\n\t" - "2:\n\t" - "# ending __down_read_trylock\n\t" - : "+m" (sem->count), "=&a" (result), "=&r" (tmp) - : "i" (RWSEM_ACTIVE_READ_BIAS) - : "memory", "cc"); - return result >= 0 ? 1 : 0; -} - -/* - * lock for writing - */ -static inline void __down_write_nested(struct rw_semaphore *sem, int subclass) -{ - long tmp; - asm volatile("# beginning down_write\n\t" - LOCK_PREFIX " xadd %1,(%2)\n\t" - /* adds 0xffff0001, returns the old value */ - " test " __ASM_SEL(%w1,%k1) "," __ASM_SEL(%w1,%k1) "\n\t" - /* was the active mask 0 before? */ - " jz 1f\n" - " call call_rwsem_down_write_failed\n" - "1:\n" - "# ending down_write" - : "+m" (sem->count), "=d" (tmp) - : "a" (sem), "1" (RWSEM_ACTIVE_WRITE_BIAS) - : "memory", "cc"); + DownRead(sem); } static inline void __down_write(struct rw_semaphore *sem) { - __down_write_nested(sem, 0); -} - -/* - * trylock for writing -- returns 1 if successful, 0 if contention - */ -static inline int __down_write_trylock(struct rw_semaphore *sem) -{ - long result, tmp; - asm volatile("# beginning __down_write_trylock\n\t" - " mov %0,%1\n\t" - "1:\n\t" - " test " __ASM_SEL(%w1,%k1) "," __ASM_SEL(%w1,%k1) "\n\t" - /* was the active mask 0 before? */ - " jnz 2f\n\t" - " mov %1,%2\n\t" - " add %3,%2\n\t" - LOCK_PREFIX " cmpxchg %2,%0\n\t" - " jnz 1b\n\t" - "2:\n\t" - " sete %b1\n\t" - " movzbl %b1, %k1\n\t" - "# ending __down_write_trylock\n\t" - : "+m" (sem->count), "=&a" (result), "=&r" (tmp) - : "er" (RWSEM_ACTIVE_WRITE_BIAS) - : "memory", "cc"); - return result; + DownWrite(sem); } /* @@ -152,17 +64,7 @@ static inline int __down_write_trylock(struct rw_semaphore *sem) */ static inline void __up_read(struct rw_semaphore *sem) { - long tmp; - asm volatile("# beginning __up_read\n\t" - LOCK_PREFIX " xadd %1,(%2)\n\t" - /* subtracts 1, returns the old value */ - " jns 1f\n\t" - " call call_rwsem_wake\n" /* expects old value in %edx */ - "1:\n" - "# ending __up_read\n" - : "+m" (sem->count), "=d" (tmp) - : "a" (sem), "1" (-RWSEM_ACTIVE_READ_BIAS) - : "memory", "cc"); + UpRead(sem); } /* @@ -170,55 +72,7 @@ static inline void __up_read(struct rw_semaphore *sem) */ static inline void __up_write(struct rw_semaphore *sem) { - long tmp; - asm volatile("# beginning __up_write\n\t" - LOCK_PREFIX " xadd %1,(%2)\n\t" - /* subtracts 0xffff0001, returns the old value */ - " jns 1f\n\t" - " call call_rwsem_wake\n" /* expects old value in %edx */ - "1:\n\t" - "# ending __up_write\n" - : "+m" (sem->count), "=d" (tmp) - : "a" (sem), "1" (-RWSEM_ACTIVE_WRITE_BIAS) - : "memory", "cc"); -} - -/* - * downgrade write lock to read lock - */ -static inline void __downgrade_write(struct rw_semaphore *sem) -{ - asm volatile("# beginning __downgrade_write\n\t" - LOCK_PREFIX _ASM_ADD "%2,(%1)\n\t" - /* - * transitions 0xZZZZ0001 -> 0xYYYY0001 (i386) - * 0xZZZZZZZZ00000001 -> 0xYYYYYYYY00000001 (x86_64) - */ - " jns 1f\n\t" - " call call_rwsem_downgrade_wake\n" - "1:\n\t" - "# ending __downgrade_write\n" - : "+m" (sem->count) - : "a" (sem), "er" (-RWSEM_WAITING_BIAS) - : "memory", "cc"); -} - -/* - * implement atomic add functionality - */ -static inline void rwsem_atomic_add(long delta, struct rw_semaphore *sem) -{ - asm volatile(LOCK_PREFIX _ASM_ADD "%1,%0" - : "+m" (sem->count) - : "er" (delta)); -} - -/* - * implement exchange and add functionality - */ -static inline long rwsem_atomic_update(long delta, struct rw_semaphore *sem) -{ - return delta + xadd(&sem->count, delta); + UpWrite(sem); } #endif /* __KERNEL__ */ diff --git a/drivers/include/ddk.h b/drivers/include/ddk.h index 0ff3495348..c220f948af 100644 --- a/drivers/include/ddk.h +++ b/drivers/include/ddk.h @@ -7,6 +7,7 @@ #include #include #include +#include #include diff --git a/drivers/include/linux/rwsem.h b/drivers/include/linux/rwsem.h index 8f498cdde2..3da265b4ab 100644 --- a/drivers/include/linux/rwsem.h +++ b/drivers/include/linux/rwsem.h @@ -25,8 +25,8 @@ struct rw_semaphore; #else /* All arch specific implementations share the same struct */ struct rw_semaphore { - long count; struct list_head wait_list; + long count; raw_spinlock_t wait_lock; #ifdef CONFIG_RWSEM_SPIN_ON_OWNER struct optimistic_spin_queue osq; /* spinner MCS lock */ diff --git a/drivers/include/syscall.h b/drivers/include/syscall.h index 43a925639b..9e79245024 100644 --- a/drivers/include/syscall.h +++ b/drivers/include/syscall.h @@ -1,9 +1,8 @@ - -#include - #ifndef __SYSCALL_H__ #define __SYSCALL_H__ +#include + typedef u32 addr_t; typedef u32 count_t; @@ -55,6 +54,12 @@ void FASTCALL MutexInit(struct mutex*)__asm__("MutexInit"); void FASTCALL MutexLock(struct mutex*)__asm__("MutexLock"); void FASTCALL MutexUnlock(struct mutex*)__asm__("MutexUnlock"); +void FASTCALL InitRwsem(struct rw_semaphore *sem)__asm__("InitRwsem"); +void FASTCALL DownRead(struct rw_semaphore *sem)__asm__("DownRead"); +void FASTCALL DownWrite(struct rw_semaphore *sem)__asm__("DownWrite"); +void FASTCALL UpRead(struct rw_semaphore *sem)__asm__("UpRead"); +void FASTCALL UpWrite(struct rw_semaphore *sem)__asm__("UpWrite"); + addr_t IMPORT GetStackBase(void)__asm__("GetStackBase"); u32 IMPORT GetPid(void)__asm__("GetPid");