Add the rt linux 4.1.3-rt3 as base
[kvmfornfv.git] / kernel / arch / metag / include / asm / processor.h
1 /*
2  * Copyright (C) 2005,2006,2007,2008 Imagination Technologies
3  */
4
5 #ifndef __ASM_METAG_PROCESSOR_H
6 #define __ASM_METAG_PROCESSOR_H
7
8 #include <linux/atomic.h>
9
10 #include <asm/page.h>
11 #include <asm/ptrace.h>
12 #include <asm/metag_regs.h>
13
14 /*
15  * Default implementation of macro that returns current
16  * instruction pointer ("program counter").
17  */
18 #define current_text_addr() ({ __label__ _l; _l: &&_l; })
19
20 /* The task stops where the kernel starts */
21 #define TASK_SIZE       PAGE_OFFSET
22 /* Add an extra page of padding at the top of the stack for the guard page. */
23 #define STACK_TOP       (TASK_SIZE - PAGE_SIZE)
24 #define STACK_TOP_MAX   STACK_TOP
25 /* Maximum virtual space for stack */
26 #define STACK_SIZE_MAX  (CONFIG_MAX_STACK_SIZE_MB*1024*1024)
27
28 /* This decides where the kernel will search for a free chunk of vm
29  * space during mmap's.
30  */
31 #define TASK_UNMAPPED_BASE      META_MEMORY_BASE
32
33 typedef struct {
34         unsigned long seg;
35 } mm_segment_t;
36
37 #ifdef CONFIG_METAG_FPU
38 struct meta_fpu_context {
39         TBICTXEXTFPU fpstate;
40         union {
41                 struct {
42                         TBICTXEXTBB4 fx8_15;
43                         TBICTXEXTFPACC fpacc;
44                 } fx8_15;
45                 struct {
46                         TBICTXEXTFPACC fpacc;
47                         TBICTXEXTBB4 unused;
48                 } nofx8_15;
49         } extfpstate;
50         bool needs_restore;
51 };
52 #else
53 struct meta_fpu_context {};
54 #endif
55
56 #ifdef CONFIG_METAG_DSP
57 struct meta_ext_context {
58         struct {
59                 TBIEXTCTX ctx;
60                 TBICTXEXTBB8 bb8;
61                 TBIDUAL ax[TBICTXEXTAXX_BYTES / sizeof(TBIDUAL)];
62                 TBICTXEXTHL2 hl2;
63                 TBICTXEXTTDPR ext;
64                 TBICTXEXTRP6 rp;
65         } regs;
66
67         /* DSPRAM A and B save areas. */
68         void *ram[2];
69
70         /* ECH encoded size of DSPRAM save areas. */
71         unsigned int ram_sz[2];
72 };
73 #else
74 struct meta_ext_context {};
75 #endif
76
77 struct thread_struct {
78         PTBICTX kernel_context;
79         /* A copy of the user process Sig.SaveMask. */
80         unsigned int user_flags;
81         struct meta_fpu_context *fpu_context;
82         void __user *tls_ptr;
83         unsigned short int_depth;
84         unsigned short txdefr_failure;
85         struct meta_ext_context *dsp_context;
86 };
87
88 #define INIT_THREAD  { \
89         NULL,                   /* kernel_context */    \
90         0,                      /* user_flags */        \
91         NULL,                   /* fpu_context */       \
92         NULL,                   /* tls_ptr */           \
93         1,                      /* int_depth - we start in kernel */    \
94         0,                      /* txdefr_failure */    \
95         NULL,                   /* dsp_context */       \
96 }
97
98 /* Needed to make #define as we are referencing 'current', that is not visible
99  * yet.
100  *
101  * Stack layout is as below.
102
103       argc            argument counter (integer)
104       argv[0]         program name (pointer)
105       argv[1...N]     program args (pointers)
106       argv[argc-1]    end of args (integer)
107       NULL
108       env[0...N]      environment variables (pointers)
109       NULL
110
111  */
112 #define start_thread(regs, pc, usp) do {                                   \
113         unsigned int *argc = (unsigned int *) bprm->exec;                  \
114         current->thread.int_depth = 1;                                     \
115         /* Force this process down to user land */                         \
116         regs->ctx.SaveMask = TBICTX_PRIV_BIT;                              \
117         regs->ctx.CurrPC = pc;                                             \
118         regs->ctx.AX[0].U0 = usp;                                          \
119         regs->ctx.DX[3].U1 = *((int *)argc);                    /* argc */ \
120         regs->ctx.DX[3].U0 = (int)((int *)argc + 1);            /* argv */ \
121         regs->ctx.DX[2].U1 = (int)((int *)argc +                           \
122                                    regs->ctx.DX[3].U1 + 2);     /* envp */ \
123         regs->ctx.DX[2].U0 = 0;                            /* rtld_fini */ \
124 } while (0)
125
126 /* Forward declaration, a strange C thing */
127 struct task_struct;
128
129 /* Free all resources held by a thread. */
130 static inline void release_thread(struct task_struct *dead_task)
131 {
132 }
133
134 #define copy_segments(tsk, mm)          do { } while (0)
135 #define release_segments(mm)            do { } while (0)
136
137 extern void exit_thread(void);
138
139 /*
140  * Return saved PC of a blocked thread.
141  */
142 #define thread_saved_pc(tsk)    \
143         ((unsigned long)(tsk)->thread.kernel_context->CurrPC)
144 #define thread_saved_sp(tsk)    \
145         ((unsigned long)(tsk)->thread.kernel_context->AX[0].U0)
146 #define thread_saved_fp(tsk)    \
147         ((unsigned long)(tsk)->thread.kernel_context->AX[1].U0)
148
149 unsigned long get_wchan(struct task_struct *p);
150
151 #define KSTK_EIP(tsk)   (task_pt_regs(tsk)->ctx.CurrPC)
152 #define KSTK_ESP(tsk)   (task_pt_regs(tsk)->ctx.AX[0].U0)
153
154 #define user_stack_pointer(regs)        ((regs)->ctx.AX[0].U0)
155
156 #define cpu_relax()     barrier()
157 #define cpu_relax_lowlatency()  cpu_relax()
158
159 extern void setup_priv(void);
160
161 static inline unsigned int hard_processor_id(void)
162 {
163         unsigned int id;
164
165         asm volatile ("MOV      %0, TXENABLE\n"
166                       "AND      %0, %0, %1\n"
167                       "LSR      %0, %0, %2\n"
168                       : "=&d" (id)
169                       : "I" (TXENABLE_THREAD_BITS),
170                         "K" (TXENABLE_THREAD_S)
171                       );
172
173         return id;
174 }
175
176 #define OP3_EXIT        0
177
178 #define HALT_OK         0
179 #define HALT_PANIC      -1
180
181 /*
182  * Halt (stop) the hardware thread. This instruction sequence is the
183  * standard way to cause a Meta hardware thread to exit. The exit code
184  * is pushed onto the stack which is interpreted by the debug adapter.
185  */
186 static inline void hard_processor_halt(int exit_code)
187 {
188         asm volatile ("MOV      D1Ar1, %0\n"
189                       "MOV      D0Ar6, %1\n"
190                       "MSETL    [A0StP],D0Ar6,D0Ar4,D0Ar2\n"
191                       "1:\n"
192                       "SWITCH   #0xC30006\n"
193                       "B                1b\n"
194                       : : "r" (exit_code), "K" (OP3_EXIT));
195 }
196
197 /* Set these hooks to call SoC specific code to restart/halt/power off. */
198 extern void (*soc_restart)(char *cmd);
199 extern void (*soc_halt)(void);
200
201 extern void show_trace(struct task_struct *tsk, unsigned long *sp,
202                        struct pt_regs *regs);
203
204 extern const struct seq_operations cpuinfo_op;
205
206 #endif