Linux Kernel
3.7.1
Main Page
Related Pages
Modules
Namespaces
Data Structures
Files
File List
Globals
All
Data Structures
Namespaces
Files
Functions
Variables
Typedefs
Enumerations
Enumerator
Macros
Groups
Pages
arch
parisc
include
asm
processor.h
Go to the documentation of this file.
1
/*
2
* include/asm-parisc/processor.h
3
*
4
* Copyright (C) 1994 Linus Torvalds
5
* Copyright (C) 2001 Grant Grundler
6
*/
7
8
#ifndef __ASM_PARISC_PROCESSOR_H
9
#define __ASM_PARISC_PROCESSOR_H
10
11
#ifndef __ASSEMBLY__
12
#include <
linux/threads.h
>
13
14
#include <asm/prefetch.h>
15
#include <
asm/hardware.h
>
16
#include <asm/pdc.h>
17
#include <asm/ptrace.h>
18
#include <asm/types.h>
19
#include <asm/percpu.h>
20
21
#endif
/* __ASSEMBLY__ */
22
23
#define KERNEL_STACK_SIZE (4*PAGE_SIZE)
24
25
/*
26
* Default implementation of macro that returns current
27
* instruction pointer ("program counter").
28
*/
29
#ifdef CONFIG_PA20
30
#define current_ia(x) __asm__("mfia %0" : "=r"(x))
31
#else
/* mfia added in pa2.0 */
32
#define current_ia(x) __asm__("blr 0,%0\n\tnop" : "=r"(x))
33
#endif
34
#define current_text_addr() ({ void *pc; current_ia(pc); pc; })
35
36
#define TASK_SIZE_OF(tsk) ((tsk)->thread.task_size)
37
#define TASK_SIZE TASK_SIZE_OF(current)
38
#define TASK_UNMAPPED_BASE (current->thread.map_base)
39
40
#define DEFAULT_TASK_SIZE32 (0xFFF00000UL)
41
#define DEFAULT_MAP_BASE32 (0x40000000UL)
42
43
#ifdef CONFIG_64BIT
44
#define DEFAULT_TASK_SIZE (MAX_ADDRESS-0xf000000)
45
#define DEFAULT_MAP_BASE (0x200000000UL)
46
#else
47
#define DEFAULT_TASK_SIZE DEFAULT_TASK_SIZE32
48
#define DEFAULT_MAP_BASE DEFAULT_MAP_BASE32
49
#endif
50
51
#ifdef __KERNEL__
52
53
/* XXX: STACK_TOP actually should be STACK_BOTTOM for parisc.
54
* prumpf */
55
56
#define STACK_TOP TASK_SIZE
57
#define STACK_TOP_MAX DEFAULT_TASK_SIZE
58
59
#endif
60
61
#ifndef __ASSEMBLY__
62
63
/*
64
* Data detected about CPUs at boot time which is the same for all CPU's.
65
* HP boxes are SMP - ie identical processors.
66
*
67
* FIXME: some CPU rev info may be processor specific...
68
*/
69
struct
system_cpuinfo_parisc
{
70
unsigned
int
cpu_count
;
71
unsigned
int
cpu_hz
;
72
unsigned
int
hversion
;
73
unsigned
int
sversion
;
74
enum
cpu_type
cpu_type
;
75
76
struct
{
77
struct
pdc_model
model
;
78
unsigned
long
versions
;
79
unsigned
long
cpuid
;
80
unsigned
long
capabilities
;
81
char
sys_model_name
[81];
/* PDC-ROM returnes this model name */
82
}
pdc
;
83
84
const
char
*
cpu_name
;
/* e.g. "PA7300LC (PCX-L2)" */
85
const
char
*
family_name
;
/* e.g. "1.1e" */
86
};
87
88
89
/* Per CPU data structure - ie varies per CPU. */
90
struct
cpuinfo_parisc
{
91
unsigned
long
it_value
;
/* Interval Timer at last timer Intr */
92
unsigned
long
it_delta
;
/* Interval delta (tic_10ms / HZ * 100) */
93
unsigned
long
irq_count
;
/* number of IRQ's since boot */
94
unsigned
long
irq_max_cr16
;
/* longest time to handle a single IRQ */
95
unsigned
long
cpuid
;
/* aka slot_number or set to NO_PROC_ID */
96
unsigned
long
hpa
;
/* Host Physical address */
97
unsigned
long
txn_addr
;
/* MMIO addr of EIR or id_eid */
98
#ifdef CONFIG_SMP
99
unsigned
long
pending_ipi;
/* bitmap of type ipi_message_type */
100
unsigned
long
ipi_count;
/* number ipi Interrupts */
101
#endif
102
unsigned
long
bh_count
;
/* number of times bh was invoked */
103
unsigned
long
prof_counter
;
/* per CPU profiling support */
104
unsigned
long
prof_multiplier
;
/* per CPU profiling support */
105
unsigned
long
fp_rev
;
106
unsigned
long
fp_model
;
107
unsigned
int
state
;
108
struct
parisc_device
*
dev
;
109
unsigned
long
loops_per_jiffy
;
110
};
111
112
extern
struct
system_cpuinfo_parisc
boot_cpu_data
;
113
DECLARE_PER_CPU
(
struct
cpuinfo_parisc
,
cpu_data
);
114
115
#define CPU_HVERSION ((boot_cpu_data.hversion >> 4) & 0x0FFF)
116
117
typedef
struct
{
118
int
seg
;
119
}
mm_segment_t
;
120
121
#define ARCH_MIN_TASKALIGN 8
122
123
struct
thread_struct
{
124
struct
pt_regs
regs
;
125
unsigned
long
task_size
;
126
unsigned
long
map_base
;
127
unsigned
long
flags
;
128
};
129
130
#define task_pt_regs(tsk) ((struct pt_regs *)&((tsk)->thread.regs))
131
132
/* Thread struct flags. */
133
#define PARISC_UAC_NOPRINT (1UL << 0)
/* see prctl and unaligned.c */
134
#define PARISC_UAC_SIGBUS (1UL << 1)
135
#define PARISC_KERNEL_DEATH (1UL << 31)
/* see die_if_kernel()... */
136
137
#define PARISC_UAC_SHIFT 0
138
#define PARISC_UAC_MASK (PARISC_UAC_NOPRINT|PARISC_UAC_SIGBUS)
139
140
#define SET_UNALIGN_CTL(task,value) \
141
({ \
142
(task)->thread.flags = (((task)->thread.flags & ~PARISC_UAC_MASK) \
143
| (((value) << PARISC_UAC_SHIFT) & \
144
PARISC_UAC_MASK)); \
145
0; \
146
})
147
148
#define GET_UNALIGN_CTL(task,addr) \
149
({ \
150
put_user(((task)->thread.flags & PARISC_UAC_MASK) \
151
>> PARISC_UAC_SHIFT, (int __user *) (addr)); \
152
})
153
154
#define INIT_THREAD { \
155
.regs = { .gr = { 0, }, \
156
.fr = { 0, }, \
157
.sr = { 0, }, \
158
.iasq = { 0, }, \
159
.iaoq = { 0, }, \
160
.cr27 = 0, \
161
}, \
162
.task_size = DEFAULT_TASK_SIZE, \
163
.map_base = DEFAULT_MAP_BASE, \
164
.flags = 0 \
165
}
166
167
/*
168
* Return saved PC of a blocked thread. This is used by ps mostly.
169
*/
170
171
struct
task_struct
;
172
unsigned
long
thread_saved_pc
(
struct
task_struct
*
t
);
173
void
show_trace
(
struct
task_struct
*
task
,
unsigned
long
*
stack
);
174
175
/*
176
* Start user thread in another space.
177
*
178
* Note that we set both the iaoq and r31 to the new pc. When
179
* the kernel initially calls execve it will return through an
180
* rfi path that will use the values in the iaoq. The execve
181
* syscall path will return through the gateway page, and
182
* that uses r31 to branch to.
183
*
184
* For ELF we clear r23, because the dynamic linker uses it to pass
185
* the address of the finalizer function.
186
*
187
* We also initialize sr3 to an illegal value (illegal for our
188
* implementation, not for the architecture).
189
*/
190
typedef
unsigned
int
elf_caddr_t
;
191
192
#define start_thread_som(regs, new_pc, new_sp) do { \
193
unsigned long *sp = (unsigned long *)new_sp; \
194
__u32 spaceid = (__u32)current->mm->context; \
195
unsigned long pc = (unsigned long)new_pc; \
196
/* offset pc for priv. level */
\
197
pc |= 3; \
198
\
199
regs->iasq[0] = spaceid; \
200
regs->iasq[1] = spaceid; \
201
regs->iaoq[0] = pc; \
202
regs->iaoq[1] = pc + 4; \
203
regs->sr[2] = LINUX_GATEWAY_SPACE; \
204
regs->sr[3] = 0xffff; \
205
regs->sr[4] = spaceid; \
206
regs->sr[5] = spaceid; \
207
regs->sr[6] = spaceid; \
208
regs->sr[7] = spaceid; \
209
regs->gr[ 0] = USER_PSW; \
210
regs->gr[30] = ((new_sp)+63)&~63; \
211
regs->gr[31] = pc; \
212
\
213
get_user(regs->gr[26],&sp[0]); \
214
get_user(regs->gr[25],&sp[-1]); \
215
get_user(regs->gr[24],&sp[-2]); \
216
get_user(regs->gr[23],&sp[-3]); \
217
} while(0)
218
219
/* The ELF abi wants things done a "wee bit" differently than
220
* som does. Supporting this behavior here avoids
221
* having our own version of create_elf_tables.
222
*
223
* Oh, and yes, that is not a typo, we are really passing argc in r25
224
* and argv in r24 (rather than r26 and r25). This is because that's
225
* where __libc_start_main wants them.
226
*
227
* Duplicated from dl-machine.h for the benefit of readers:
228
*
229
* Our initial stack layout is rather different from everyone else's
230
* due to the unique PA-RISC ABI. As far as I know it looks like
231
* this:
232
233
----------------------------------- (user startup code creates this frame)
234
| 32 bytes of magic |
235
|---------------------------------|
236
| 32 bytes argument/sp save area |
237
|---------------------------------| (bprm->p)
238
| ELF auxiliary info |
239
| (up to 28 words) |
240
|---------------------------------|
241
| NULL |
242
|---------------------------------|
243
| Environment pointers |
244
|---------------------------------|
245
| NULL |
246
|---------------------------------|
247
| Argument pointers |
248
|---------------------------------| <- argv
249
| argc (1 word) |
250
|---------------------------------| <- bprm->exec (HACK!)
251
| N bytes of slack |
252
|---------------------------------|
253
| filename passed to execve |
254
|---------------------------------| (mm->env_end)
255
| env strings |
256
|---------------------------------| (mm->env_start, mm->arg_end)
257
| arg strings |
258
|---------------------------------|
259
| additional faked arg strings if |
260
| we're invoked via binfmt_script |
261
|---------------------------------| (mm->arg_start)
262
stack base is at TASK_SIZE - rlim_max.
263
264
on downward growing arches, it looks like this:
265
stack base at TASK_SIZE
266
| filename passed to execve
267
| env strings
268
| arg strings
269
| faked arg strings
270
| slack
271
| ELF
272
| envps
273
| argvs
274
| argc
275
276
* The pleasant part of this is that if we need to skip arguments we
277
* can just decrement argc and move argv, because the stack pointer
278
* is utterly unrelated to the location of the environment and
279
* argument vectors.
280
*
281
* Note that the S/390 people took the easy way out and hacked their
282
* GCC to make the stack grow downwards.
283
*
284
* Final Note: For entry from syscall, the W (wide) bit of the PSW
285
* is stuffed into the lowest bit of the user sp (%r30), so we fill
286
* it in here from the current->personality
287
*/
288
289
#ifdef CONFIG_64BIT
290
#define USER_WIDE_MODE (!test_thread_flag(TIF_32BIT))
291
#else
292
#define USER_WIDE_MODE 0
293
#endif
294
295
#define start_thread(regs, new_pc, new_sp) do { \
296
elf_addr_t *sp = (elf_addr_t *)new_sp; \
297
__u32 spaceid = (__u32)current->mm->context; \
298
elf_addr_t pc = (elf_addr_t)new_pc | 3; \
299
elf_caddr_t *argv = (elf_caddr_t *)bprm->exec + 1; \
300
\
301
regs->iasq[0] = spaceid; \
302
regs->iasq[1] = spaceid; \
303
regs->iaoq[0] = pc; \
304
regs->iaoq[1] = pc + 4; \
305
regs->sr[2] = LINUX_GATEWAY_SPACE; \
306
regs->sr[3] = 0xffff; \
307
regs->sr[4] = spaceid; \
308
regs->sr[5] = spaceid; \
309
regs->sr[6] = spaceid; \
310
regs->sr[7] = spaceid; \
311
regs->gr[ 0] = USER_PSW | (USER_WIDE_MODE ? PSW_W : 0); \
312
regs->fr[ 0] = 0LL; \
313
regs->fr[ 1] = 0LL; \
314
regs->fr[ 2] = 0LL; \
315
regs->fr[ 3] = 0LL; \
316
regs->gr[30] = (((unsigned long)sp + 63) &~ 63) | (USER_WIDE_MODE ? 1 : 0); \
317
regs->gr[31] = pc; \
318
\
319
get_user(regs->gr[25], (argv - 1)); \
320
regs->gr[24] = (long) argv; \
321
regs->gr[23] = 0; \
322
} while(0)
323
324
struct
task_struct
;
325
struct
mm_struct
;
326
327
/* Free all resources held by a thread. */
328
extern
void
release_thread
(
struct
task_struct
*);
329
extern
int
kernel_thread
(
int
(*
fn
)(
void
*),
void
*
arg
,
unsigned
long
flags
);
330
331
extern
void
map_hpux_gateway_page
(
struct
task_struct
*tsk,
struct
mm_struct
*mm);
332
333
extern
unsigned
long
get_wchan
(
struct
task_struct
*
p
);
334
335
#define KSTK_EIP(tsk) ((tsk)->thread.regs.iaoq[0])
336
#define KSTK_ESP(tsk) ((tsk)->thread.regs.gr[30])
337
338
#define cpu_relax() barrier()
339
340
/* Used as a macro to identify the combined VIPT/PIPT cached
341
* CPUs which require a guarantee of coherency (no inequivalent
342
* aliases with different data, whether clean or not) to operate */
343
static
inline
int
parisc_requires_coherency(
void
)
344
{
345
#ifdef CONFIG_PA8X00
346
return
(
boot_cpu_data
.cpu_type ==
mako
) ||
347
(
boot_cpu_data
.cpu_type ==
mako2
);
348
#else
349
return
0;
350
#endif
351
}
352
353
#endif
/* __ASSEMBLY__ */
354
355
#endif
/* __ASM_PARISC_PROCESSOR_H */
Generated on Thu Jan 10 2013 12:50:18 for Linux Kernel by
1.8.2