1 /*
2  *  Port on Texas Instruments TMS320C6x architecture
3  *
4  *  Copyright (C) 2004, 2009, 2010, 2011 Texas Instruments Incorporated
5  *  Author: Aurelien Jacquiot (aurelien.jacquiot@jaluna.com)
6  *
7  *  This program is free software; you can redistribute it and/or modify
8  *  it under the terms of the GNU General Public License version 2 as
9  *  published by the Free Software Foundation.
10  */
11 #ifndef _ASM_C6X_SYSTEM_H
12 #define _ASM_C6X_SYSTEM_H
13 
14 #include <linux/linkage.h>
15 #include <linux/irqflags.h>
16 
17 #define prepare_to_switch()    do { } while (0)
18 
19 struct task_struct;
20 struct thread_struct;
21 asmlinkage void *__switch_to(struct thread_struct *prev,
22 			     struct thread_struct *next,
23 			     struct task_struct *tsk);
24 
25 #define switch_to(prev, next, last)				\
26 	do {							\
27 		current->thread.wchan = (u_long) __builtin_return_address(0); \
28 		(last) = __switch_to(&(prev)->thread,		\
29 				     &(next)->thread, (prev));	\
30 		mb();						\
31 		current->thread.wchan = 0;			\
32 	} while (0)
33 
34 /* Reset the board */
35 #define HARD_RESET_NOW()
36 
37 #define get_creg(reg) \
38 	({ unsigned int __x; \
39 	   asm volatile ("mvc .s2 " #reg ",%0\n" : "=b"(__x)); __x; })
40 
41 #define set_creg(reg, v) \
42 	do { unsigned int __x = (unsigned int)(v); \
43 		asm volatile ("mvc .s2 %0," #reg "\n" : : "b"(__x)); \
44 	} while (0)
45 
46 #define or_creg(reg, n) \
47 	do { unsigned __x, __n = (unsigned)(n);		  \
48 		asm volatile ("mvc .s2 " #reg ",%0\n"	  \
49 			      "or  .l2 %1,%0,%0\n"	  \
50 			      "mvc .s2 %0," #reg "\n"	  \
51 			      "nop\n"			  \
52 			      : "=&b"(__x) : "b"(__n));	  \
53 	} while (0)
54 
55 #define and_creg(reg, n) \
56 	do { unsigned __x, __n = (unsigned)(n);		  \
57 		asm volatile ("mvc .s2 " #reg ",%0\n"	  \
58 			      "and .l2 %1,%0,%0\n"	  \
59 			      "mvc .s2 %0," #reg "\n"	  \
60 			      "nop\n"    \
61 			      : "=&b"(__x) : "b"(__n));	  \
62 	} while (0)
63 
64 #define get_coreid() (get_creg(DNUM) & 0xff)
65 
66 /* Set/get IST */
67 #define set_ist(x)	set_creg(ISTP, x)
68 #define get_ist()       get_creg(ISTP)
69 
70 /*
71  * Exception management
72  */
73 asmlinkage void enable_exception(void);
74 #define disable_exception()
75 #define get_except_type()        get_creg(EFR)
76 #define ack_exception(type)      set_creg(ECR, 1 << (type))
77 #define get_iexcept()            get_creg(IERR)
78 #define set_iexcept(mask)        set_creg(IERR, (mask))
79 
80 /*
81  * Misc. functions
82  */
83 #define nop()                    asm("NOP\n");
84 #define mb()                     barrier()
85 #define rmb()                    barrier()
86 #define wmb()                    barrier()
87 #define set_mb(var, value)       do { var = value;  mb(); } while (0)
88 #define set_wmb(var, value)      do { var = value; wmb(); } while (0)
89 
90 #define smp_mb()	         barrier()
91 #define smp_rmb()	         barrier()
92 #define smp_wmb()	         barrier()
93 #define smp_read_barrier_depends()	do { } while (0)
94 
95 #define xchg(ptr, x) \
96 	((__typeof__(*(ptr)))__xchg((unsigned int)(x), (void *) (ptr), \
97 				    sizeof(*(ptr))))
98 #define tas(ptr)    xchg((ptr), 1)
99 
100 unsigned int _lmbd(unsigned int, unsigned int);
101 unsigned int _bitr(unsigned int);
102 
103 struct __xchg_dummy { unsigned int a[100]; };
104 #define __xg(x) ((volatile struct __xchg_dummy *)(x))
105 
__xchg(unsigned int x,volatile void * ptr,int size)106 static inline unsigned int __xchg(unsigned int x, volatile void *ptr, int size)
107 {
108 	unsigned int tmp;
109 	unsigned long flags;
110 
111 	local_irq_save(flags);
112 
113 	switch (size) {
114 	case 1:
115 		tmp = 0;
116 		tmp = *((unsigned char *) ptr);
117 		*((unsigned char *) ptr) = (unsigned char) x;
118 		break;
119 	case 2:
120 		tmp = 0;
121 		tmp = *((unsigned short *) ptr);
122 		*((unsigned short *) ptr) = x;
123 		break;
124 	case 4:
125 		tmp = 0;
126 		tmp = *((unsigned int *) ptr);
127 		*((unsigned int *) ptr) = x;
128 		break;
129 	}
130 	local_irq_restore(flags);
131 	return tmp;
132 }
133 
134 #include <asm-generic/cmpxchg-local.h>
135 
136 /*
137  * cmpxchg_local and cmpxchg64_local are atomic wrt current CPU. Always make
138  * them available.
139  */
140 #define cmpxchg_local(ptr, o, n)					\
141 	((__typeof__(*(ptr)))__cmpxchg_local_generic((ptr),		\
142 						     (unsigned long)(o), \
143 						     (unsigned long)(n), \
144 						     sizeof(*(ptr))))
145 #define cmpxchg64_local(ptr, o, n) __cmpxchg64_local_generic((ptr), (o), (n))
146 
147 #include <asm-generic/cmpxchg.h>
148 
149 #define _extu(x, s, e)							\
150 	({      unsigned int __x;					\
151 		asm volatile ("extu .S2 %3,%1,%2,%0\n" :		\
152 			      "=b"(__x) : "n"(s), "n"(e), "b"(x));	\
153 	       __x; })
154 
155 
156 extern unsigned int c6x_core_freq;
157 
158 struct pt_regs;
159 
160 extern void die(char *str, struct pt_regs *fp, int nr);
161 extern asmlinkage int process_exception(struct pt_regs *regs);
162 extern void time_init(void);
163 extern void free_initmem(void);
164 
165 extern void (*c6x_restart)(void);
166 extern void (*c6x_halt)(void);
167 
168 #endif /* _ASM_C6X_SYSTEM_H */
169