Commit | Line | Data |
---|---|---|
1e57372e JH |
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 | |
d71f290b | 25 | /* Maximum virtual space for stack */ |
042d27ac | 26 | #define STACK_SIZE_MAX (CONFIG_MAX_STACK_SIZE_MB*1024*1024) |
1e57372e JH |
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; \ | |
1e57372e JH |
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 | ||
1e57372e JH |
137 | /* |
138 | * Return saved PC of a blocked thread. | |
139 | */ | |
140 | #define thread_saved_pc(tsk) \ | |
141 | ((unsigned long)(tsk)->thread.kernel_context->CurrPC) | |
142 | #define thread_saved_sp(tsk) \ | |
143 | ((unsigned long)(tsk)->thread.kernel_context->AX[0].U0) | |
144 | #define thread_saved_fp(tsk) \ | |
145 | ((unsigned long)(tsk)->thread.kernel_context->AX[1].U0) | |
146 | ||
147 | unsigned long get_wchan(struct task_struct *p); | |
148 | ||
c2996cb2 JH |
149 | #define KSTK_EIP(tsk) (task_pt_regs(tsk)->ctx.CurrPC) |
150 | #define KSTK_ESP(tsk) (task_pt_regs(tsk)->ctx.AX[0].U0) | |
1e57372e JH |
151 | |
152 | #define user_stack_pointer(regs) ((regs)->ctx.AX[0].U0) | |
153 | ||
154 | #define cpu_relax() barrier() | |
3a6bfbc9 | 155 | #define cpu_relax_lowlatency() cpu_relax() |
1e57372e | 156 | |
3d6b7bb0 | 157 | extern void setup_priv(void); |
1e57372e JH |
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 | ||
dca66a61 MC |
202 | extern const struct seq_operations cpuinfo_op; |
203 | ||
1e57372e | 204 | #endif |