]> git.proxmox.com Git - mirror_ubuntu-bionic-kernel.git/blob - arch/metag/include/asm/processor.h
Merge tag 'reset-fixes-for-4.14' of git://git.pengutronix.de/git/pza/linux into fixes
[mirror_ubuntu-bionic-kernel.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 /* 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 /*
135 * Return saved PC of a blocked thread.
136 */
137 #define thread_saved_pc(tsk) \
138 ((unsigned long)(tsk)->thread.kernel_context->CurrPC)
139 #define thread_saved_sp(tsk) \
140 ((unsigned long)(tsk)->thread.kernel_context->AX[0].U0)
141 #define thread_saved_fp(tsk) \
142 ((unsigned long)(tsk)->thread.kernel_context->AX[1].U0)
143
144 unsigned long get_wchan(struct task_struct *p);
145
146 #define KSTK_EIP(tsk) (task_pt_regs(tsk)->ctx.CurrPC)
147 #define KSTK_ESP(tsk) (task_pt_regs(tsk)->ctx.AX[0].U0)
148
149 #define user_stack_pointer(regs) ((regs)->ctx.AX[0].U0)
150
151 #define cpu_relax() barrier()
152
153 extern void setup_priv(void);
154
155 static inline unsigned int hard_processor_id(void)
156 {
157 unsigned int id;
158
159 asm volatile ("MOV %0, TXENABLE\n"
160 "AND %0, %0, %1\n"
161 "LSR %0, %0, %2\n"
162 : "=&d" (id)
163 : "I" (TXENABLE_THREAD_BITS),
164 "K" (TXENABLE_THREAD_S)
165 );
166
167 return id;
168 }
169
170 #define OP3_EXIT 0
171
172 #define HALT_OK 0
173 #define HALT_PANIC -1
174
175 /*
176 * Halt (stop) the hardware thread. This instruction sequence is the
177 * standard way to cause a Meta hardware thread to exit. The exit code
178 * is pushed onto the stack which is interpreted by the debug adapter.
179 */
180 static inline void hard_processor_halt(int exit_code)
181 {
182 asm volatile ("MOV D1Ar1, %0\n"
183 "MOV D0Ar6, %1\n"
184 "MSETL [A0StP],D0Ar6,D0Ar4,D0Ar2\n"
185 "1:\n"
186 "SWITCH #0xC30006\n"
187 "B 1b\n"
188 : : "r" (exit_code), "K" (OP3_EXIT));
189 }
190
191 /* Set these hooks to call SoC specific code to restart/halt/power off. */
192 extern void (*soc_restart)(char *cmd);
193 extern void (*soc_halt)(void);
194
195 extern void show_trace(struct task_struct *tsk, unsigned long *sp,
196 struct pt_regs *regs);
197
198 extern const struct seq_operations cpuinfo_op;
199
200 #endif