home *** CD-ROM | disk | FTP | other *** search
/ PC Welt 2006 November (DVD) / PCWELT_11_2006.ISO / casper / filesystem.squashfs / usr / src / linux-headers-2.6.17-6 / include / asm-m68knommu / system.h < prev    next >
Encoding:
C/C++ Source or Header  |  2006-08-11  |  8.9 KB  |  341 lines

  1. #ifndef _M68KNOMMU_SYSTEM_H
  2. #define _M68KNOMMU_SYSTEM_H
  3.  
  4. #include <linux/linkage.h>
  5. #include <asm/segment.h>
  6. #include <asm/entry.h>
  7.  
  8. /*
  9.  * switch_to(n) should switch tasks to task ptr, first checking that
  10.  * ptr isn't the current task, in which case it does nothing.  This
  11.  * also clears the TS-flag if the task we switched to has used the
  12.  * math co-processor latest.
  13.  */
  14. /*
  15.  * switch_to() saves the extra registers, that are not saved
  16.  * automatically by SAVE_SWITCH_STACK in resume(), ie. d0-d5 and
  17.  * a0-a1. Some of these are used by schedule() and its predecessors
  18.  * and so we might get see unexpected behaviors when a task returns
  19.  * with unexpected register values.
  20.  *
  21.  * syscall stores these registers itself and none of them are used
  22.  * by syscall after the function in the syscall has been called.
  23.  *
  24.  * Beware that resume now expects *next to be in d1 and the offset of
  25.  * tss to be in a1. This saves a few instructions as we no longer have
  26.  * to push them onto the stack and read them back right after.
  27.  *
  28.  * 02/17/96 - Jes Sorensen (jds@kom.auc.dk)
  29.  *
  30.  * Changed 96/09/19 by Andreas Schwab
  31.  * pass prev in a0, next in a1, offset of tss in d1, and whether
  32.  * the mm structures are shared in d2 (to avoid atc flushing).
  33.  */
  34. asmlinkage void resume(void);
  35. #define switch_to(prev,next,last)                \
  36. {                                \
  37.   void *_last;                            \
  38.   __asm__ __volatile__(                        \
  39.       "movel    %1, %%a0\n\t"                    \
  40.     "movel    %2, %%a1\n\t"                    \
  41.     "jbsr resume\n\t"                    \
  42.     "movel    %%d1, %0\n\t"                    \
  43.        : "=d" (_last)                        \
  44.        : "d" (prev), "d" (next)                    \
  45.        : "cc", "d0", "d1", "d2", "d3", "d4", "d5", "a0", "a1");    \
  46.   (last) = _last;                        \
  47. }
  48.  
  49. #ifdef CONFIG_COLDFIRE
  50. #define local_irq_enable() __asm__ __volatile__ (        \
  51.     "move %/sr,%%d0\n\t"                    \
  52.     "andi.l #0xf8ff,%%d0\n\t"                \
  53.     "move %%d0,%/sr\n"                    \
  54.     : /* no outputs */                    \
  55.     :                            \
  56.         : "cc", "%d0", "memory")
  57. #define local_irq_disable() __asm__ __volatile__ (        \
  58.     "move %/sr,%%d0\n\t"                    \
  59.     "ori.l #0x0700,%%d0\n\t"                \
  60.     "move %%d0,%/sr\n"                    \
  61.     : /* no outputs */                    \
  62.     :                            \
  63.     : "cc", "%d0", "memory")
  64. /* For spinlocks etc */
  65. #define local_irq_save(x) __asm__ __volatile__ (        \
  66.     "movew %%sr,%0\n\t"                    \
  67.     "movew #0x0700,%%d0\n\t"                \
  68.     "or.l  %0,%%d0\n\t"                    \
  69.     "movew %%d0,%/sr"                    \
  70.     : "=d" (x)                        \
  71.     :                            \
  72.     : "cc", "%d0", "memory")
  73. #else
  74.  
  75. /* portable version */ /* FIXME - see entry.h*/
  76. #define ALLOWINT 0xf8ff
  77.  
  78. #define local_irq_enable() asm volatile ("andiw %0,%%sr": : "i" (ALLOWINT) : "memory")
  79. #define local_irq_disable() asm volatile ("oriw  #0x0700,%%sr": : : "memory")
  80. #endif
  81.  
  82. #define local_save_flags(x) asm volatile ("movew %%sr,%0":"=d" (x) : : "memory")
  83. #define local_irq_restore(x) asm volatile ("movew %0,%%sr": :"d" (x) : "memory")
  84.  
  85. /* For spinlocks etc */
  86. #ifndef local_irq_save
  87. #define local_irq_save(x) do { local_save_flags(x); local_irq_disable(); } while (0)
  88. #endif
  89.  
  90. #define    irqs_disabled()            \
  91. ({                    \
  92.     unsigned long flags;        \
  93.     local_save_flags(flags);    \
  94.     ((flags & 0x0700) == 0x0700);    \
  95. })
  96.  
  97. #define iret() __asm__ __volatile__ ("rte": : :"memory", "sp", "cc")
  98.  
  99. /*
  100.  * Force strict CPU ordering.
  101.  * Not really required on m68k...
  102.  */
  103. #define nop()  asm volatile ("nop"::)
  104. #define mb()   asm volatile (""   : : :"memory")
  105. #define rmb()  asm volatile (""   : : :"memory")
  106. #define wmb()  asm volatile (""   : : :"memory")
  107. #define set_rmb(var, value)    do { xchg(&var, value); } while (0)
  108. #define set_mb(var, value)     set_rmb(var, value)
  109. #define set_wmb(var, value)    do { var = value; wmb(); } while (0)
  110.  
  111. #ifdef CONFIG_SMP
  112. #define smp_mb()    mb()
  113. #define smp_rmb()    rmb()
  114. #define smp_wmb()    wmb()
  115. #define smp_read_barrier_depends()    read_barrier_depends()
  116. #else
  117. #define smp_mb()    barrier()
  118. #define smp_rmb()    barrier()
  119. #define smp_wmb()    barrier()
  120. #define smp_read_barrier_depends()    do { } while(0)
  121. #endif
  122.  
  123. #define xchg(ptr,x) ((__typeof__(*(ptr)))__xchg((unsigned long)(x),(ptr),sizeof(*(ptr))))
  124. #define tas(ptr) (xchg((ptr),1))
  125.  
  126. struct __xchg_dummy { unsigned long a[100]; };
  127. #define __xg(x) ((volatile struct __xchg_dummy *)(x))
  128.  
  129. #ifndef CONFIG_RMW_INSNS
  130. static inline unsigned long __xchg(unsigned long x, volatile void * ptr, int size)
  131. {
  132.   unsigned long tmp, flags;
  133.  
  134.   local_irq_save(flags);
  135.  
  136.   switch (size) {
  137.   case 1:
  138.     __asm__ __volatile__
  139.     ("moveb %2,%0\n\t"
  140.      "moveb %1,%2"
  141.     : "=&d" (tmp) : "d" (x), "m" (*__xg(ptr)) : "memory");
  142.     break;
  143.   case 2:
  144.     __asm__ __volatile__
  145.     ("movew %2,%0\n\t"
  146.      "movew %1,%2"
  147.     : "=&d" (tmp) : "d" (x), "m" (*__xg(ptr)) : "memory");
  148.     break;
  149.   case 4:
  150.     __asm__ __volatile__
  151.     ("movel %2,%0\n\t"
  152.      "movel %1,%2"
  153.     : "=&d" (tmp) : "d" (x), "m" (*__xg(ptr)) : "memory");
  154.     break;
  155.   }
  156.   local_irq_restore(flags);
  157.   return tmp;
  158. }
  159. #else
  160. static inline unsigned long __xchg(unsigned long x, volatile void * ptr, int size)
  161. {
  162.     switch (size) {
  163.         case 1:
  164.         __asm__ __volatile__
  165.             ("moveb %2,%0\n\t"
  166.              "1:\n\t"
  167.              "casb %0,%1,%2\n\t"
  168.              "jne 1b"
  169.              : "=&d" (x) : "d" (x), "m" (*__xg(ptr)) : "memory");
  170.         break;
  171.         case 2:
  172.         __asm__ __volatile__
  173.             ("movew %2,%0\n\t"
  174.              "1:\n\t"
  175.              "casw %0,%1,%2\n\t"
  176.              "jne 1b"
  177.              : "=&d" (x) : "d" (x), "m" (*__xg(ptr)) : "memory");
  178.         break;
  179.         case 4:
  180.         __asm__ __volatile__
  181.             ("movel %2,%0\n\t"
  182.              "1:\n\t"
  183.              "casl %0,%1,%2\n\t"
  184.              "jne 1b"
  185.              : "=&d" (x) : "d" (x), "m" (*__xg(ptr)) : "memory");
  186.         break;
  187.     }
  188.     return x;
  189. }
  190. #endif
  191.  
  192. /*
  193.  * Atomic compare and exchange.  Compare OLD with MEM, if identical,
  194.  * store NEW in MEM.  Return the initial value in MEM.  Success is
  195.  * indicated by comparing RETURN with OLD.
  196.  */
  197. #define __HAVE_ARCH_CMPXCHG    1
  198.  
  199. static __inline__ unsigned long
  200. cmpxchg(volatile int *p, int old, int new)
  201. {
  202.     unsigned long flags;
  203.     int prev;
  204.  
  205.     local_irq_save(flags);
  206.     if ((prev = *p) == old)
  207.         *p = new;
  208.     local_irq_restore(flags);
  209.     return(prev);
  210. }
  211.  
  212.  
  213. #ifdef CONFIG_M68332
  214. #define HARD_RESET_NOW() ({        \
  215.         local_irq_disable();        \
  216.         asm("                \
  217.     movew   #0x0000, 0xfffa6a;    \
  218.         reset;                \
  219.         /*movew #0x1557, 0xfffa44;*/    \
  220.         /*movew #0x0155, 0xfffa46;*/    \
  221.         moveal #0, %a0;            \
  222.         movec %a0, %vbr;        \
  223.         moveal 0, %sp;            \
  224.         moveal 4, %a0;            \
  225.         jmp (%a0);            \
  226.         ");                \
  227. })
  228. #endif
  229.  
  230. #if defined( CONFIG_M68328 ) || defined( CONFIG_M68EZ328 ) || \
  231.     defined (CONFIG_M68360) || defined( CONFIG_M68VZ328 )
  232. #define HARD_RESET_NOW() ({        \
  233.         local_irq_disable();        \
  234.         asm("                \
  235.         moveal #0x10c00000, %a0;    \
  236.         moveb #0, 0xFFFFF300;        \
  237.         moveal 0(%a0), %sp;        \
  238.         moveal 4(%a0), %a0;        \
  239.         jmp (%a0);            \
  240.         ");                \
  241. })
  242. #endif
  243.  
  244. #ifdef CONFIG_COLDFIRE
  245. #if defined(CONFIG_M5272) && defined(CONFIG_NETtel)
  246. /*
  247.  * Need to account for broken early mask of 5272 silicon. So don't
  248.  * jump through the original start address. Jump strait into the
  249.  * known start of the FLASH code.
  250.  */
  251. #define HARD_RESET_NOW() ({        \
  252.         asm("                \
  253.     movew #0x2700, %sr;        \
  254.         jmp 0xf0000400;            \
  255.         ");                \
  256. })
  257. #elif defined(CONFIG_NETtel) || defined(CONFIG_eLIA) || \
  258.       defined(CONFIG_DISKtel) || defined(CONFIG_SECUREEDGEMP3) || \
  259.       defined(CONFIG_CLEOPATRA)
  260. #define HARD_RESET_NOW() ({        \
  261.         asm("                \
  262.     movew #0x2700, %sr;        \
  263.     moveal #0x10000044, %a0;    \
  264.     movel #0xffffffff, (%a0);    \
  265.     moveal #0x10000001, %a0;    \
  266.     moveb #0x00, (%a0);        \
  267.         moveal #0xf0000004, %a0;    \
  268.         moveal (%a0), %a0;        \
  269.         jmp (%a0);            \
  270.         ");                \
  271. })
  272. #elif defined(CONFIG_M5272)
  273. /*
  274.  * Retrieve the boot address in flash using CSBR0 and CSOR0
  275.  * find the reset vector at flash_address + 4 (e.g. 0x400)
  276.  * remap it in the flash's current location (e.g. 0xf0000400)
  277.  * and jump there.
  278.  */ 
  279. #define HARD_RESET_NOW() ({        \
  280.     asm("                \
  281.     movew #0x2700, %%sr;        \
  282.     move.l    %0+0x40,%%d0;        \
  283.     and.l    %0+0x44,%%d0;        \
  284.     andi.l    #0xfffff000,%%d0;    \
  285.     mov.l    %%d0,%%a0;        \
  286.     or.l    4(%%a0),%%d0;        \
  287.     mov.l    %%d0,%%a0;        \
  288.     jmp (%%a0);"            \
  289.     : /* No output */        \
  290.     : "o" (*(char *)MCF_MBAR) );    \
  291. })
  292. #elif defined(CONFIG_M528x)
  293. /*
  294.  * The MCF528x has a bit (SOFTRST) in memory (Reset Control Register RCR),
  295.  * that when set, resets the MCF528x.
  296.  */
  297. #define HARD_RESET_NOW() \
  298. ({                        \
  299.     unsigned char volatile *reset;        \
  300.     asm("move.w    #0x2700, %sr");        \
  301.     reset = ((volatile unsigned short *)(MCF_IPSBAR + 0x110000));    \
  302.     while(1)                \
  303.     *reset |= (0x01 << 7);\
  304. })
  305. #elif defined(CONFIG_M523x)
  306. #define HARD_RESET_NOW() ({        \
  307.     asm("                \
  308.     movew #0x2700, %sr;        \
  309.     movel #0x01000000, %sp;        \
  310.     moveal #0x40110000, %a0;    \
  311.     moveb #0x80, (%a0);        \
  312.     ");                \
  313. })
  314. #elif defined(CONFIG_M520x)
  315.     /*
  316.      * The MCF5208 has a bit (SOFTRST) in memory (Reset Control Register 
  317.      * RCR), that when set, resets the MCF5208.
  318.      */
  319. #define HARD_RESET_NOW()         \
  320. ({                    \
  321.     unsigned char volatile *reset;    \
  322.     asm("move.w     #0x2700, %sr");    \
  323.     reset = ((volatile unsigned short *)(MCF_IPSBAR + 0xA0000));    \
  324.     while(1)            \
  325.         *reset |= 0x80;        \
  326. })
  327. #else
  328. #define HARD_RESET_NOW() ({        \
  329.         asm("                \
  330.     movew #0x2700, %sr;        \
  331.         moveal #0x4, %a0;        \
  332.         moveal (%a0), %a0;        \
  333.         jmp (%a0);            \
  334.         ");                \
  335. })
  336. #endif
  337. #endif
  338. #define arch_align_stack(x) (x)
  339.  
  340. #endif /* _M68KNOMMU_SYSTEM_H */
  341.