1819833afSPeter Tyser /* 2819833afSPeter Tyser * include/asm-microblaze/system.h -- Low-level interrupt/thread ops 3819833afSPeter Tyser * 4819833afSPeter Tyser * Copyright (C) 2003 John Williams (jwilliams@itee.uq.edu.au) 5819833afSPeter Tyser * based upon microblaze version 6819833afSPeter Tyser * Copyright (C) 2001 NEC Corporation 7819833afSPeter Tyser * Copyright (C) 2001 Miles Bader <miles@gnu.org> 8819833afSPeter Tyser * 9819833afSPeter Tyser * This file is subject to the terms and conditions of the GNU General 10819833afSPeter Tyser * Public License. See the file COPYING in the main directory of this 11819833afSPeter Tyser * archive for more details. 12819833afSPeter Tyser * 13819833afSPeter Tyser * Written by Miles Bader <miles@gnu.org> 14819833afSPeter Tyser * Microblaze port by John Williams 15819833afSPeter Tyser * Microblaze port by John Williams 16819833afSPeter Tyser */ 17819833afSPeter Tyser 18819833afSPeter Tyser #ifndef __MICROBLAZE_SYSTEM_H__ 19819833afSPeter Tyser #define __MICROBLAZE_SYSTEM_H__ 20819833afSPeter Tyser 21819833afSPeter Tyser #if 0 22819833afSPeter Tyser #include <linux/linkage.h> 23819833afSPeter Tyser #endif 24819833afSPeter Tyser #include <asm/ptrace.h> 25819833afSPeter Tyser 26819833afSPeter Tyser #define prepare_to_switch() do { } while (0) 27819833afSPeter Tyser 28819833afSPeter Tyser /* 29819833afSPeter Tyser * switch_to(n) should switch tasks to task ptr, first checking that 30819833afSPeter Tyser * ptr isn't the current task, in which case it does nothing. 31819833afSPeter Tyser */ 32819833afSPeter Tyser struct thread_struct; 33819833afSPeter Tyser extern void *switch_thread (struct thread_struct *last, 34819833afSPeter Tyser struct thread_struct *next); 35819833afSPeter Tyser #define switch_to(prev,next,last) do { \ 36819833afSPeter Tyser if (prev != next) { \ 37819833afSPeter Tyser (last) = switch_thread (&prev->thread, &next->thread); \ 38819833afSPeter Tyser } \ 39819833afSPeter Tyser } while (0) 40819833afSPeter Tyser 41819833afSPeter Tyser 42819833afSPeter Tyser /* Enable/disable interrupts. */ 43819833afSPeter Tyser #define __sti() \ 44819833afSPeter Tyser { \ 45819833afSPeter Tyser register unsigned tmp; \ 46819833afSPeter Tyser __asm__ __volatile__ (" \ 47819833afSPeter Tyser mfs %0, rmsr; \ 48819833afSPeter Tyser ori %0, %0, 2; \ 49819833afSPeter Tyser mts rmsr, %0" \ 50819833afSPeter Tyser : "=r" (tmp) \ 51819833afSPeter Tyser : \ 52819833afSPeter Tyser : "memory"); \ 53819833afSPeter Tyser } 54819833afSPeter Tyser 55819833afSPeter Tyser #define __cli() \ 56819833afSPeter Tyser { \ 57819833afSPeter Tyser register unsigned tmp; \ 58819833afSPeter Tyser __asm__ __volatile__ (" \ 59819833afSPeter Tyser mfs %0, rmsr; \ 60819833afSPeter Tyser andi %0, %0, ~2; \ 61819833afSPeter Tyser mts rmsr, %0" \ 62819833afSPeter Tyser : "=r" (tmp) \ 63819833afSPeter Tyser : \ 64819833afSPeter Tyser : "memory"); \ 65819833afSPeter Tyser } 66819833afSPeter Tyser 67819833afSPeter Tyser #define __save_flags(flags) \ 68819833afSPeter Tyser __asm__ __volatile__ ("mfs %0, rmsr" : "=r" (flags)) 69819833afSPeter Tyser #define __restore_flags(flags) \ 70819833afSPeter Tyser __asm__ __volatile__ ("mts rmsr, %0" :: "r" (flags)) 71819833afSPeter Tyser 72819833afSPeter Tyser #define __save_flags_cli(flags) \ 73819833afSPeter Tyser { \ 74819833afSPeter Tyser register unsigned tmp; \ 75819833afSPeter Tyser __asm__ __volatile__ (" \ 76819833afSPeter Tyser mfs %0, rmsr; \ 77819833afSPeter Tyser andi %1, %0, ~2; \ 78819833afSPeter Tyser mts rmsr, %1;" \ 79819833afSPeter Tyser : "=r" (flags), "=r" (tmp) \ 80819833afSPeter Tyser : \ 81819833afSPeter Tyser : "memory"); \ 82819833afSPeter Tyser } 83819833afSPeter Tyser 84819833afSPeter Tyser #define __save_flags_sti(flags) \ 85819833afSPeter Tyser { \ 86819833afSPeter Tyser register unsigned tmp; \ 87819833afSPeter Tyser __asm__ __volatile__ (" \ 88819833afSPeter Tyser mfs %0, rmsr; \ 89819833afSPeter Tyser ori %1, %0, 2; \ 90819833afSPeter Tyser mts rmsr, %1;" \ 91819833afSPeter Tyser : "=r" (flags) ,"=r" (tmp) \ 92819833afSPeter Tyser : \ 93819833afSPeter Tyser : "memory"); \ 94819833afSPeter Tyser } 95819833afSPeter Tyser 96819833afSPeter Tyser /* For spinlocks etc */ 97819833afSPeter Tyser #define local_irq_save(flags) __save_flags_cli (flags) 98819833afSPeter Tyser #define local_irq_set(flags) __save_flags_sti (flags) 99819833afSPeter Tyser #define local_irq_restore(flags) __restore_flags (flags) 100819833afSPeter Tyser #define local_irq_disable() __cli () 101819833afSPeter Tyser #define local_irq_enable() __sti () 102819833afSPeter Tyser 103819833afSPeter Tyser #define cli() __cli () 104819833afSPeter Tyser #define sti() __sti () 105819833afSPeter Tyser #define save_flags(flags) __save_flags (flags) 106819833afSPeter Tyser #define restore_flags(flags) __restore_flags (flags) 107819833afSPeter Tyser #define save_flags_cli(flags) __save_flags_cli (flags) 108819833afSPeter Tyser 109819833afSPeter Tyser /* 110819833afSPeter Tyser * Force strict CPU ordering. 111819833afSPeter Tyser * Not really required on microblaze... 112819833afSPeter Tyser */ 113819833afSPeter Tyser #define nop() __asm__ __volatile__ ("nop") 114819833afSPeter Tyser #define mb() __asm__ __volatile__ ("nop" ::: "memory") 115819833afSPeter Tyser #define rmb() mb () 116819833afSPeter Tyser #define wmb() mb () 117819833afSPeter Tyser #define set_mb(var, value) do { var = value; mb(); } while (0) 118819833afSPeter Tyser #define set_wmb(var, value) do { var = value; wmb (); } while (0) 119819833afSPeter Tyser 120819833afSPeter Tyser #ifdef CONFIG_SMP 121819833afSPeter Tyser #define smp_mb() mb () 122819833afSPeter Tyser #define smp_rmb() rmb () 123819833afSPeter Tyser #define smp_wmb() wmb () 124819833afSPeter Tyser #else 125819833afSPeter Tyser #define smp_mb() barrier () 126819833afSPeter Tyser #define smp_rmb() barrier () 127819833afSPeter Tyser #define smp_wmb() barrier () 128819833afSPeter Tyser #endif 129819833afSPeter Tyser 130819833afSPeter Tyser #define xchg(ptr, with) \ 131819833afSPeter Tyser ((__typeof__ (*(ptr)))__xchg ((unsigned long)(with), (ptr), sizeof (*(ptr)))) 132819833afSPeter Tyser #define tas(ptr) (xchg ((ptr), 1)) 133819833afSPeter Tyser 134*e0f21e1cSNathan Rossi static inline unsigned long __xchg(unsigned long with, 135819833afSPeter Tyser __volatile__ void *ptr, int size) 136819833afSPeter Tyser { 137819833afSPeter Tyser unsigned long tmp, flags; 138819833afSPeter Tyser 139819833afSPeter Tyser save_flags_cli (flags); 140819833afSPeter Tyser 141819833afSPeter Tyser switch (size) { 142819833afSPeter Tyser case 1: 143819833afSPeter Tyser tmp = *(unsigned char *)ptr; 144819833afSPeter Tyser *(unsigned char *)ptr = with; 145819833afSPeter Tyser break; 146819833afSPeter Tyser case 2: 147819833afSPeter Tyser tmp = *(unsigned short *)ptr; 148819833afSPeter Tyser *(unsigned short *)ptr = with; 149819833afSPeter Tyser break; 150819833afSPeter Tyser case 4: 151819833afSPeter Tyser tmp = *(unsigned long *)ptr; 152819833afSPeter Tyser *(unsigned long *)ptr = with; 153819833afSPeter Tyser break; 154819833afSPeter Tyser } 155819833afSPeter Tyser 156819833afSPeter Tyser restore_flags (flags); 157819833afSPeter Tyser 158819833afSPeter Tyser return tmp; 159819833afSPeter Tyser } 160819833afSPeter Tyser 161819833afSPeter Tyser #endif /* __MICROBLAZE_SYSTEM_H__ */ 162