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