From 8d20a541b089ecb67a88a673548161b686ed7b85 Mon Sep 17 00:00:00 2001 From: Mikael Starvik Date: Wed, 27 Jul 2005 11:44:42 -0700 Subject: [PATCH] CRIS update: SMP Patches to support SMP. * Each CPU has its own current_pgd. * flush_tlb_range is implemented as flush_tlb_mm. * Atomic operations implemented with spinlocks. * Semaphores implemented with spinlocks. Signed-off-by: Mikael Starvik Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- include/asm-cris/arch-v10/atomic.h | 7 ++++ include/asm-cris/atomic.h | 66 ++++++++++++++------------------------ include/asm-cris/mmu_context.h | 2 +- include/asm-cris/semaphore.h | 21 ++++++------ include/asm-cris/smp.h | 7 ++++ include/asm-cris/spinlock.h | 1 + include/asm-cris/tlbflush.h | 19 +++++++++-- 7 files changed, 65 insertions(+), 58 deletions(-) create mode 100644 include/asm-cris/arch-v10/atomic.h create mode 100644 include/asm-cris/spinlock.h (limited to 'include/asm-cris') diff --git a/include/asm-cris/arch-v10/atomic.h b/include/asm-cris/arch-v10/atomic.h new file mode 100644 index 00000000000..6ef5e7d0902 --- /dev/null +++ b/include/asm-cris/arch-v10/atomic.h @@ -0,0 +1,7 @@ +#ifndef __ASM_CRIS_ARCH_ATOMIC__ +#define __ASM_CRIS_ARCH_ATOMIC__ + +#define cris_atomic_save(addr, flags) local_irq_save(flags); +#define cris_atomic_restore(addr, flags) local_irq_restore(flags); + +#endif diff --git a/include/asm-cris/atomic.h b/include/asm-cris/atomic.h index b3dfea5a71e..70605b09e8b 100644 --- a/include/asm-cris/atomic.h +++ b/include/asm-cris/atomic.h @@ -4,21 +4,14 @@ #define __ASM_CRIS_ATOMIC__ #include +#include /* * Atomic operations that C can't guarantee us. Useful for * resource counting etc.. */ -/* - * Make sure gcc doesn't try to be clever and move things around - * on us. We need to use _exactly_ the address the user gave us, - * not some alias that contains the same information. - */ - -#define __atomic_fool_gcc(x) (*(struct { int a[100]; } *)x) - -typedef struct { int counter; } atomic_t; +typedef struct { volatile int counter; } atomic_t; #define ATOMIC_INIT(i) { (i) } @@ -30,29 +23,26 @@ typedef struct { int counter; } atomic_t; extern __inline__ void atomic_add(int i, volatile atomic_t *v) { unsigned long flags; - local_save_flags(flags); - local_irq_disable(); + cris_atomic_save(v, flags); v->counter += i; - local_irq_restore(flags); + cris_atomic_restore(v, flags); } extern __inline__ void atomic_sub(int i, volatile atomic_t *v) { unsigned long flags; - local_save_flags(flags); - local_irq_disable(); + cris_atomic_save(v, flags); v->counter -= i; - local_irq_restore(flags); + cris_atomic_restore(v, flags); } extern __inline__ int atomic_add_return(int i, volatile atomic_t *v) { unsigned long flags; int retval; - local_save_flags(flags); - local_irq_disable(); + cris_atomic_save(v, flags); retval = (v->counter += i); - local_irq_restore(flags); + cris_atomic_restore(v, flags); return retval; } @@ -62,10 +52,9 @@ extern __inline__ int atomic_sub_return(int i, volatile atomic_t *v) { unsigned long flags; int retval; - local_save_flags(flags); - local_irq_disable(); + cris_atomic_save(v, flags); retval = (v->counter -= i); - local_irq_restore(flags); + cris_atomic_restore(v, flags); return retval; } @@ -73,39 +62,35 @@ extern __inline__ int atomic_sub_and_test(int i, volatile atomic_t *v) { int retval; unsigned long flags; - local_save_flags(flags); - local_irq_disable(); + cris_atomic_save(v, flags); retval = (v->counter -= i) == 0; - local_irq_restore(flags); + cris_atomic_restore(v, flags); return retval; } extern __inline__ void atomic_inc(volatile atomic_t *v) { unsigned long flags; - local_save_flags(flags); - local_irq_disable(); + cris_atomic_save(v, flags); (v->counter)++; - local_irq_restore(flags); + cris_atomic_restore(v, flags); } extern __inline__ void atomic_dec(volatile atomic_t *v) { unsigned long flags; - local_save_flags(flags); - local_irq_disable(); + cris_atomic_save(v, flags); (v->counter)--; - local_irq_restore(flags); + cris_atomic_restore(v, flags); } extern __inline__ int atomic_inc_return(volatile atomic_t *v) { unsigned long flags; int retval; - local_save_flags(flags); - local_irq_disable(); + cris_atomic_save(v, flags); retval = (v->counter)++; - local_irq_restore(flags); + cris_atomic_restore(v, flags); return retval; } @@ -113,20 +98,18 @@ extern __inline__ int atomic_dec_return(volatile atomic_t *v) { unsigned long flags; int retval; - local_save_flags(flags); - local_irq_disable(); + cris_atomic_save(v, flags); retval = (v->counter)--; - local_irq_restore(flags); + cris_atomic_restore(v, flags); return retval; } extern __inline__ int atomic_dec_and_test(volatile atomic_t *v) { int retval; unsigned long flags; - local_save_flags(flags); - local_irq_disable(); + cris_atomic_save(v, flags); retval = --(v->counter) == 0; - local_irq_restore(flags); + cris_atomic_restore(v, flags); return retval; } @@ -134,10 +117,9 @@ extern __inline__ int atomic_inc_and_test(volatile atomic_t *v) { int retval; unsigned long flags; - local_save_flags(flags); - local_irq_disable(); + cris_atomic_save(v, flags); retval = ++(v->counter) == 0; - local_irq_restore(flags); + cris_atomic_restore(v, flags); return retval; } diff --git a/include/asm-cris/mmu_context.h b/include/asm-cris/mmu_context.h index f9308c5bbd9..e6e659dc757 100644 --- a/include/asm-cris/mmu_context.h +++ b/include/asm-cris/mmu_context.h @@ -15,7 +15,7 @@ extern void switch_mm(struct mm_struct *prev, struct mm_struct *next, * registers like cr3 on the i386 */ -extern volatile pgd_t *current_pgd; /* defined in arch/cris/mm/fault.c */ +extern volatile DEFINE_PER_CPU(pgd_t *,current_pgd); /* defined in arch/cris/mm/fault.c */ static inline void enter_lazy_tlb(struct mm_struct *mm, struct task_struct *tsk) { diff --git a/include/asm-cris/semaphore.h b/include/asm-cris/semaphore.h index 605aa7eaaaf..8ed7636ab31 100644 --- a/include/asm-cris/semaphore.h +++ b/include/asm-cris/semaphore.h @@ -72,10 +72,9 @@ extern inline void down(struct semaphore * sem) might_sleep(); /* atomically decrement the semaphores count, and if its negative, we wait */ - local_save_flags(flags); - local_irq_disable(); + cris_atomic_save(sem, flags); failed = --(sem->count.counter) < 0; - local_irq_restore(flags); + cris_atomic_restore(sem, flags); if(failed) { __down(sem); } @@ -95,10 +94,9 @@ extern inline int down_interruptible(struct semaphore * sem) might_sleep(); /* atomically decrement the semaphores count, and if its negative, we wait */ - local_save_flags(flags); - local_irq_disable(); + cris_atomic_save(sem, flags); failed = --(sem->count.counter) < 0; - local_irq_restore(flags); + cris_atomic_restore(sem, flags); if(failed) failed = __down_interruptible(sem); return(failed); @@ -109,13 +107,13 @@ extern inline int down_trylock(struct semaphore * sem) unsigned long flags; int failed; - local_save_flags(flags); - local_irq_disable(); + cris_atomic_save(sem, flags); failed = --(sem->count.counter) < 0; - local_irq_restore(flags); + cris_atomic_restore(sem, flags); if(failed) failed = __down_trylock(sem); return(failed); + } /* @@ -130,10 +128,9 @@ extern inline void up(struct semaphore * sem) int wakeup; /* atomically increment the semaphores count, and if it was negative, we wake people */ - local_save_flags(flags); - local_irq_disable(); + cris_atomic_save(sem, flags); wakeup = ++(sem->count.counter) <= 0; - local_irq_restore(flags); + cris_atomic_restore(sem, flags); if(wakeup) { __up(sem); } diff --git a/include/asm-cris/smp.h b/include/asm-cris/smp.h index c2f4feaa041..dca5ef1d8c9 100644 --- a/include/asm-cris/smp.h +++ b/include/asm-cris/smp.h @@ -1,4 +1,11 @@ #ifndef __ASM_SMP_H #define __ASM_SMP_H +#include + +extern cpumask_t phys_cpu_present_map; +#define cpu_possible_map phys_cpu_present_map + +#define __smp_processor_id() (current_thread_info()->cpu) + #endif diff --git a/include/asm-cris/spinlock.h b/include/asm-cris/spinlock.h new file mode 100644 index 00000000000..2e8ba8afc7a --- /dev/null +++ b/include/asm-cris/spinlock.h @@ -0,0 +1 @@ +#include diff --git a/include/asm-cris/tlbflush.h b/include/asm-cris/tlbflush.h index 1781fe1a32f..6ed7d9ae90d 100644 --- a/include/asm-cris/tlbflush.h +++ b/include/asm-cris/tlbflush.h @@ -18,13 +18,26 @@ * */ +extern void __flush_tlb_all(void); +extern void __flush_tlb_mm(struct mm_struct *mm); +extern void __flush_tlb_page(struct vm_area_struct *vma, + unsigned long addr); + +#ifdef CONFIG_SMP extern void flush_tlb_all(void); extern void flush_tlb_mm(struct mm_struct *mm); extern void flush_tlb_page(struct vm_area_struct *vma, unsigned long addr); -extern void flush_tlb_range(struct vm_area_struct *vma, - unsigned long start, - unsigned long end); +#else +#define flush_tlb_all __flush_tlb_all +#define flush_tlb_mm __flush_tlb_mm +#define flush_tlb_page __flush_tlb_page +#endif + +static inline void flush_tlb_range(struct vm_area_struct * vma, unsigned long start, unsigned long end) +{ + flush_tlb_mm(vma->vm_mm); +} extern inline void flush_tlb_pgtables(struct mm_struct *mm, unsigned long start, unsigned long end) -- cgit v1.2.3