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; \ | |
114 | set_fs(USER_DS); \ | |
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 | #define copy_segments(tsk, mm) do { } while (0) | |
136 | #define release_segments(mm) do { } while (0) | |
137 | ||
138 | extern void exit_thread(void); | |
139 | ||
140 | /* | |
141 | * Return saved PC of a blocked thread. | |
142 | */ | |
143 | #define thread_saved_pc(tsk) \ | |
144 | ((unsigned long)(tsk)->thread.kernel_context->CurrPC) | |
145 | #define thread_saved_sp(tsk) \ | |
146 | ((unsigned long)(tsk)->thread.kernel_context->AX[0].U0) | |
147 | #define thread_saved_fp(tsk) \ | |
148 | ((unsigned long)(tsk)->thread.kernel_context->AX[1].U0) | |
149 | ||
150 | unsigned long get_wchan(struct task_struct *p); | |
151 | ||
152 | #define KSTK_EIP(tsk) ((tsk)->thread.kernel_context->CurrPC) | |
153 | #define KSTK_ESP(tsk) ((tsk)->thread.kernel_context->AX[0].U0) | |
154 | ||
155 | #define user_stack_pointer(regs) ((regs)->ctx.AX[0].U0) | |
156 | ||
157 | #define cpu_relax() barrier() | |
158 | ||
3d6b7bb0 | 159 | extern void setup_priv(void); |
1e57372e JH |
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 | ||
dca66a61 MC |
204 | extern const struct seq_operations cpuinfo_op; |
205 | ||
1e57372e | 206 | #endif |