aboutsummaryrefslogtreecommitdiffstats
path: root/arch/tile/include/asm/processor.h
diff options
context:
space:
mode:
authorChris Metcalf <cmetcalf@tilera.com>2010-05-28 23:09:12 -0400
committerChris Metcalf <cmetcalf@tilera.com>2010-06-04 17:11:18 -0400
commit867e359b97c970a60626d5d76bbe2a8fadbf38fb (patch)
treec5ccbb7f5172e8555977119608ecb1eee3cc37e3 /arch/tile/include/asm/processor.h
parent5360bd776f73d0a7da571d72a09a03f237e99900 (diff)
arch/tile: core support for Tilera 32-bit chips.
This change is the core kernel support for TILEPro and TILE64 chips. No driver support (except the console driver) is included yet. This includes the relevant Linux headers in asm/; the low-level low-level "Tile architecture" headers in arch/, which are shared with the hypervisor, etc., and are build-system agnostic; and the relevant hypervisor headers in hv/. Signed-off-by: Chris Metcalf <cmetcalf@tilera.com> Acked-by: Arnd Bergmann <arnd@arndb.de> Acked-by: FUJITA Tomonori <fujita.tomonori@lab.ntt.co.jp> Reviewed-by: Paul Mundt <lethal@linux-sh.org>
Diffstat (limited to 'arch/tile/include/asm/processor.h')
-rw-r--r--arch/tile/include/asm/processor.h339
1 files changed, 339 insertions, 0 deletions
diff --git a/arch/tile/include/asm/processor.h b/arch/tile/include/asm/processor.h
new file mode 100644
index 00000000000..96c50d2c4c2
--- /dev/null
+++ b/arch/tile/include/asm/processor.h
@@ -0,0 +1,339 @@
1/*
2 * Copyright 2010 Tilera Corporation. All Rights Reserved.
3 *
4 * This program is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU General Public License
6 * as published by the Free Software Foundation, version 2.
7 *
8 * This program is distributed in the hope that it will be useful, but
9 * WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, GOOD TITLE or
11 * NON INFRINGEMENT. See the GNU General Public License for
12 * more details.
13 */
14
15#ifndef _ASM_TILE_PROCESSOR_H
16#define _ASM_TILE_PROCESSOR_H
17
18#ifndef __ASSEMBLY__
19
20/*
21 * NOTE: we don't include <linux/ptrace.h> or <linux/percpu.h> as one
22 * normally would, due to #include dependencies.
23 */
24#include <asm/ptrace.h>
25#include <asm/percpu.h>
26
27#include <arch/chip.h>
28#include <arch/spr_def.h>
29
30struct task_struct;
31struct thread_struct;
32struct list_head;
33
34typedef struct {
35 unsigned long seg;
36} mm_segment_t;
37
38/*
39 * Default implementation of macro that returns current
40 * instruction pointer ("program counter").
41 */
42void *current_text_addr(void);
43
44#if CHIP_HAS_TILE_DMA()
45/* Capture the state of a suspended DMA. */
46struct tile_dma_state {
47 int enabled;
48 unsigned long src;
49 unsigned long dest;
50 unsigned long strides;
51 unsigned long chunk_size;
52 unsigned long src_chunk;
53 unsigned long dest_chunk;
54 unsigned long byte;
55 unsigned long status;
56};
57
58/*
59 * A mask of the DMA status register for selecting only the 'running'
60 * and 'done' bits.
61 */
62#define DMA_STATUS_MASK \
63 (SPR_DMA_STATUS__RUNNING_MASK | SPR_DMA_STATUS__DONE_MASK)
64#endif
65
66/*
67 * Track asynchronous TLB events (faults and access violations)
68 * that occur while we are in kernel mode from DMA or the SN processor.
69 */
70struct async_tlb {
71 short fault_num; /* original fault number; 0 if none */
72 char is_fault; /* was it a fault (vs an access violation) */
73 char is_write; /* for fault: was it caused by a write? */
74 unsigned long address; /* what address faulted? */
75};
76
77
78struct thread_struct {
79 /* kernel stack pointer */
80 unsigned long ksp;
81 /* kernel PC */
82 unsigned long pc;
83 /* starting user stack pointer (for page migration) */
84 unsigned long usp0;
85 /* pid of process that created this one */
86 pid_t creator_pid;
87#if CHIP_HAS_TILE_DMA()
88 /* DMA info for suspended threads (byte == 0 means no DMA state) */
89 struct tile_dma_state tile_dma_state;
90#endif
91 /* User EX_CONTEXT registers */
92 unsigned long ex_context[2];
93 /* User SYSTEM_SAVE registers */
94 unsigned long system_save[4];
95 /* User interrupt mask */
96 unsigned long long interrupt_mask;
97 /* User interrupt-control 0 state */
98 unsigned long intctrl_0;
99#if CHIP_HAS_PROC_STATUS_SPR()
100 /* Any other miscellaneous processor state bits */
101 unsigned long proc_status;
102#endif
103#if CHIP_HAS_TILE_DMA()
104 /* Async DMA TLB fault information */
105 struct async_tlb dma_async_tlb;
106#endif
107#if CHIP_HAS_SN_PROC()
108 /* Was static network processor when we were switched out? */
109 int sn_proc_running;
110 /* Async SNI TLB fault information */
111 struct async_tlb sn_async_tlb;
112#endif
113};
114
115#endif /* !__ASSEMBLY__ */
116
117/*
118 * Start with "sp" this many bytes below the top of the kernel stack.
119 * This preserves the invariant that a called function may write to *sp.
120 */
121#define STACK_TOP_DELTA 8
122
123/*
124 * When entering the kernel via a fault, start with the top of the
125 * pt_regs structure this many bytes below the top of the page.
126 * This aligns the pt_regs structure optimally for cache-line access.
127 */
128#ifdef __tilegx__
129#define KSTK_PTREGS_GAP 48
130#else
131#define KSTK_PTREGS_GAP 56
132#endif
133
134#ifndef __ASSEMBLY__
135
136#ifdef __tilegx__
137#define TASK_SIZE_MAX (MEM_LOW_END + 1)
138#else
139#define TASK_SIZE_MAX PAGE_OFFSET
140#endif
141
142/* TASK_SIZE and related variables are always checked in "current" context. */
143#ifdef CONFIG_COMPAT
144#define COMPAT_TASK_SIZE (1UL << 31)
145#define TASK_SIZE ((current_thread_info()->status & TS_COMPAT) ?\
146 COMPAT_TASK_SIZE : TASK_SIZE_MAX)
147#else
148#define TASK_SIZE TASK_SIZE_MAX
149#endif
150
151/* We provide a minimal "vdso" a la x86; just the sigreturn code for now. */
152#define VDSO_BASE (TASK_SIZE - PAGE_SIZE)
153
154#define STACK_TOP VDSO_BASE
155
156/* STACK_TOP_MAX is used temporarily in execve and should not check COMPAT. */
157#define STACK_TOP_MAX TASK_SIZE_MAX
158
159/*
160 * This decides where the kernel will search for a free chunk of vm
161 * space during mmap's, if it is using bottom-up mapping.
162 */
163#define TASK_UNMAPPED_BASE (PAGE_ALIGN(TASK_SIZE / 3))
164
165#define HAVE_ARCH_PICK_MMAP_LAYOUT
166
167#define INIT_THREAD { \
168 .ksp = (unsigned long)init_stack + THREAD_SIZE - STACK_TOP_DELTA, \
169 .interrupt_mask = -1ULL \
170}
171
172/* Kernel stack top for the task that first boots on this cpu. */
173DECLARE_PER_CPU(unsigned long, boot_sp);
174
175/* PC to boot from on this cpu. */
176DECLARE_PER_CPU(unsigned long, boot_pc);
177
178/* Do necessary setup to start up a newly executed thread. */
179static inline void start_thread(struct pt_regs *regs,
180 unsigned long pc, unsigned long usp)
181{
182 regs->pc = pc;
183 regs->sp = usp;
184}
185
186/* Free all resources held by a thread. */
187static inline void release_thread(struct task_struct *dead_task)
188{
189 /* Nothing for now */
190}
191
192/* Prepare to copy thread state - unlazy all lazy status. */
193#define prepare_to_copy(tsk) do { } while (0)
194
195extern int kernel_thread(int (*fn)(void *), void *arg, unsigned long flags);
196
197/* Helper routines for setting home cache modes at exec() time. */
198
199
200/*
201 * Return saved (kernel) PC of a blocked thread.
202 * Only used in a printk() in kernel/sched.c, so don't work too hard.
203 */
204#define thread_saved_pc(t) ((t)->thread.pc)
205
206unsigned long get_wchan(struct task_struct *p);
207
208/* Return initial ksp value for given task. */
209#define task_ksp0(task) ((unsigned long)(task)->stack + THREAD_SIZE)
210
211/* Return some info about the user process TASK. */
212#define KSTK_TOP(task) (task_ksp0(task) - STACK_TOP_DELTA)
213#define task_pt_regs(task) \
214 ((struct pt_regs *)(task_ksp0(task) - KSTK_PTREGS_GAP) - 1)
215#define task_sp(task) (task_pt_regs(task)->sp)
216#define task_pc(task) (task_pt_regs(task)->pc)
217/* Aliases for pc and sp (used in fs/proc/array.c) */
218#define KSTK_EIP(task) task_pc(task)
219#define KSTK_ESP(task) task_sp(task)
220
221/* Standard format for printing registers and other word-size data. */
222#ifdef __tilegx__
223# define REGFMT "0x%016lx"
224#else
225# define REGFMT "0x%08lx"
226#endif
227
228/*
229 * Do some slow action (e.g. read a slow SPR).
230 * Note that this must also have compiler-barrier semantics since
231 * it may be used in a busy loop reading memory.
232 */
233static inline void cpu_relax(void)
234{
235 __insn_mfspr(SPR_PASS);
236 barrier();
237}
238
239struct siginfo;
240extern void arch_coredump_signal(struct siginfo *, struct pt_regs *);
241#define arch_coredump_signal arch_coredump_signal
242
243/* Provide information about the chip model. */
244extern char chip_model[64];
245
246/* Data on which physical memory controller corresponds to which NUMA node. */
247extern int node_controller[];
248
249
250/* Do we dump information to the console when a user application crashes? */
251extern int show_crashinfo;
252
253#if CHIP_HAS_CBOX_HOME_MAP()
254/* Does the heap allocator return hash-for-home pages by default? */
255extern int hash_default;
256
257/* Should kernel stack pages be hash-for-home? */
258extern int kstack_hash;
259#else
260#define hash_default 0
261#define kstack_hash 0
262#endif
263
264/* Are we using huge pages in the TLB for kernel data? */
265extern int kdata_huge;
266
267/*
268 * Note that with OLOC the prefetch will return an unused read word to
269 * the issuing tile, which will cause some MDN traffic. Benchmarking
270 * should be done to see whether this outweighs prefetching.
271 */
272#define ARCH_HAS_PREFETCH
273#define ARCH_HAS_PREFETCHW
274#define ARCH_HAS_SPINLOCK_PREFETCH
275
276#define prefetch(ptr) __builtin_prefetch((ptr), 0, 3)
277#define prefetchw(ptr) __builtin_prefetch((ptr), 1, 3)
278
279#ifdef CONFIG_SMP
280#define spin_lock_prefetch(ptr) prefetchw(ptr)
281#else
282/* Nothing to prefetch. */
283#define spin_lock_prefetch(lock) do { } while (0)
284#endif
285
286#else /* __ASSEMBLY__ */
287
288/* Do some slow action (e.g. read a slow SPR). */
289#define CPU_RELAX mfspr zero, SPR_PASS
290
291#endif /* !__ASSEMBLY__ */
292
293/* Assembly code assumes that the PL is in the low bits. */
294#if SPR_EX_CONTEXT_1_1__PL_SHIFT != 0
295# error Fix assembly assumptions about PL
296#endif
297
298/* We sometimes use these macros for EX_CONTEXT_0_1 as well. */
299#if SPR_EX_CONTEXT_1_1__PL_SHIFT != SPR_EX_CONTEXT_0_1__PL_SHIFT || \
300 SPR_EX_CONTEXT_1_1__PL_RMASK != SPR_EX_CONTEXT_0_1__PL_RMASK || \
301 SPR_EX_CONTEXT_1_1__ICS_SHIFT != SPR_EX_CONTEXT_0_1__ICS_SHIFT || \
302 SPR_EX_CONTEXT_1_1__ICS_RMASK != SPR_EX_CONTEXT_0_1__ICS_RMASK
303# error Fix assumptions that EX1 macros work for both PL0 and PL1
304#endif
305
306/* Allow pulling apart and recombining the PL and ICS bits in EX_CONTEXT. */
307#define EX1_PL(ex1) \
308 (((ex1) >> SPR_EX_CONTEXT_1_1__PL_SHIFT) & SPR_EX_CONTEXT_1_1__PL_RMASK)
309#define EX1_ICS(ex1) \
310 (((ex1) >> SPR_EX_CONTEXT_1_1__ICS_SHIFT) & SPR_EX_CONTEXT_1_1__ICS_RMASK)
311#define PL_ICS_EX1(pl, ics) \
312 (((pl) << SPR_EX_CONTEXT_1_1__PL_SHIFT) | \
313 ((ics) << SPR_EX_CONTEXT_1_1__ICS_SHIFT))
314
315/*
316 * Provide symbolic constants for PLs.
317 * Note that assembly code assumes that USER_PL is zero.
318 */
319#define USER_PL 0
320#define KERNEL_PL 1
321
322/* SYSTEM_SAVE_1_0 holds the current cpu number ORed with ksp0. */
323#define CPU_LOG_MASK_VALUE 12
324#define CPU_MASK_VALUE ((1 << CPU_LOG_MASK_VALUE) - 1)
325#if CONFIG_NR_CPUS > CPU_MASK_VALUE
326# error Too many cpus!
327#endif
328#define raw_smp_processor_id() \
329 ((int)__insn_mfspr(SPR_SYSTEM_SAVE_1_0) & CPU_MASK_VALUE)
330#define get_current_ksp0() \
331 (__insn_mfspr(SPR_SYSTEM_SAVE_1_0) & ~CPU_MASK_VALUE)
332#define next_current_ksp0(task) ({ \
333 unsigned long __ksp0 = task_ksp0(task); \
334 int __cpu = raw_smp_processor_id(); \
335 BUG_ON(__ksp0 & CPU_MASK_VALUE); \
336 __ksp0 | __cpu; \
337})
338
339#endif /* _ASM_TILE_PROCESSOR_H */