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