aboutsummaryrefslogtreecommitdiffstats
path: root/arch/tile
diff options
context:
space:
mode:
Diffstat (limited to 'arch/tile')
-rw-r--r--arch/tile/Kbuild3
-rw-r--r--arch/tile/Kconfig356
-rw-r--r--arch/tile/Kconfig.debug43
-rw-r--r--arch/tile/Makefile54
-rw-r--r--arch/tile/configs/tile_defconfig71
-rw-r--r--arch/tile/include/arch/abi.h96
-rw-r--r--arch/tile/include/arch/chip.h23
-rw-r--r--arch/tile/include/arch/chip_tile64.h255
-rw-r--r--arch/tile/include/arch/chip_tilepro.h255
-rw-r--r--arch/tile/include/arch/icache.h94
-rw-r--r--arch/tile/include/arch/interrupts.h19
-rw-r--r--arch/tile/include/arch/interrupts_32.h304
-rw-r--r--arch/tile/include/arch/sim_def.h512
-rw-r--r--arch/tile/include/arch/spr_def.h19
-rw-r--r--arch/tile/include/arch/spr_def_32.h162
-rw-r--r--arch/tile/include/asm/Kbuild3
-rw-r--r--arch/tile/include/asm/asm-offsets.h1
-rw-r--r--arch/tile/include/asm/atomic.h159
-rw-r--r--arch/tile/include/asm/atomic_32.h333
-rw-r--r--arch/tile/include/asm/auxvec.h20
-rw-r--r--arch/tile/include/asm/backtrace.h195
-rw-r--r--arch/tile/include/asm/bitops.h127
-rw-r--r--arch/tile/include/asm/bitops_32.h132
-rw-r--r--arch/tile/include/asm/bitsperlong.h26
-rw-r--r--arch/tile/include/asm/bug.h1
-rw-r--r--arch/tile/include/asm/bugs.h1
-rw-r--r--arch/tile/include/asm/byteorder.h1
-rw-r--r--arch/tile/include/asm/cache.h51
-rw-r--r--arch/tile/include/asm/cacheflush.h140
-rw-r--r--arch/tile/include/asm/checksum.h24
-rw-r--r--arch/tile/include/asm/compat.h257
-rw-r--r--arch/tile/include/asm/cputime.h1
-rw-r--r--arch/tile/include/asm/current.h31
-rw-r--r--arch/tile/include/asm/delay.h34
-rw-r--r--arch/tile/include/asm/device.h1
-rw-r--r--arch/tile/include/asm/div64.h1
-rw-r--r--arch/tile/include/asm/dma-mapping.h93
-rw-r--r--arch/tile/include/asm/dma.h25
-rw-r--r--arch/tile/include/asm/elf.h167
-rw-r--r--arch/tile/include/asm/emergency-restart.h1
-rw-r--r--arch/tile/include/asm/errno.h1
-rw-r--r--arch/tile/include/asm/fcntl.h1
-rw-r--r--arch/tile/include/asm/fixmap.h124
-rw-r--r--arch/tile/include/asm/ftrace.h20
-rw-r--r--arch/tile/include/asm/futex.h141
-rw-r--r--arch/tile/include/asm/hardirq.h47
-rw-r--r--arch/tile/include/asm/hardwall.h56
-rw-r--r--arch/tile/include/asm/highmem.h73
-rw-r--r--arch/tile/include/asm/homecache.h125
-rw-r--r--arch/tile/include/asm/hugetlb.h109
-rw-r--r--arch/tile/include/asm/hv_driver.h60
-rw-r--r--arch/tile/include/asm/hw_irq.h18
-rw-r--r--arch/tile/include/asm/ide.h25
-rw-r--r--arch/tile/include/asm/io.h279
-rw-r--r--arch/tile/include/asm/ioctl.h1
-rw-r--r--arch/tile/include/asm/ioctls.h1
-rw-r--r--arch/tile/include/asm/ipc.h1
-rw-r--r--arch/tile/include/asm/ipcbuf.h1
-rw-r--r--arch/tile/include/asm/irq.h87
-rw-r--r--arch/tile/include/asm/irq_regs.h1
-rw-r--r--arch/tile/include/asm/irqflags.h266
-rw-r--r--arch/tile/include/asm/kdebug.h1
-rw-r--r--arch/tile/include/asm/kexec.h53
-rw-r--r--arch/tile/include/asm/kmap_types.h43
-rw-r--r--arch/tile/include/asm/linkage.h51
-rw-r--r--arch/tile/include/asm/local.h1
-rw-r--r--arch/tile/include/asm/memprof.h33
-rw-r--r--arch/tile/include/asm/mman.h40
-rw-r--r--arch/tile/include/asm/mmu.h31
-rw-r--r--arch/tile/include/asm/mmu_context.h131
-rw-r--r--arch/tile/include/asm/mmzone.h81
-rw-r--r--arch/tile/include/asm/module.h1
-rw-r--r--arch/tile/include/asm/msgbuf.h1
-rw-r--r--arch/tile/include/asm/mutex.h1
-rw-r--r--arch/tile/include/asm/opcode-tile.h30
-rw-r--r--arch/tile/include/asm/opcode-tile_32.h1506
-rw-r--r--arch/tile/include/asm/opcode-tile_64.h1506
-rw-r--r--arch/tile/include/asm/opcode_constants.h26
-rw-r--r--arch/tile/include/asm/opcode_constants_32.h480
-rw-r--r--arch/tile/include/asm/opcode_constants_64.h480
-rw-r--r--arch/tile/include/asm/page.h343
-rw-r--r--arch/tile/include/asm/param.h1
-rw-r--r--arch/tile/include/asm/pci-bridge.h117
-rw-r--r--arch/tile/include/asm/pci.h128
-rw-r--r--arch/tile/include/asm/percpu.h24
-rw-r--r--arch/tile/include/asm/pgalloc.h119
-rw-r--r--arch/tile/include/asm/pgtable.h480
-rw-r--r--arch/tile/include/asm/pgtable_32.h129
-rw-r--r--arch/tile/include/asm/poll.h1
-rw-r--r--arch/tile/include/asm/posix_types.h1
-rw-r--r--arch/tile/include/asm/processor.h338
-rw-r--r--arch/tile/include/asm/ptrace.h166
-rw-r--r--arch/tile/include/asm/resource.h1
-rw-r--r--arch/tile/include/asm/scatterlist.h1
-rw-r--r--arch/tile/include/asm/sections.h44
-rw-r--r--arch/tile/include/asm/sembuf.h1
-rw-r--r--arch/tile/include/asm/setup.h36
-rw-r--r--arch/tile/include/asm/shmbuf.h1
-rw-r--r--arch/tile/include/asm/shmparam.h1
-rw-r--r--arch/tile/include/asm/sigcontext.h27
-rw-r--r--arch/tile/include/asm/sigframe.h33
-rw-r--r--arch/tile/include/asm/siginfo.h34
-rw-r--r--arch/tile/include/asm/signal.h32
-rw-r--r--arch/tile/include/asm/smp.h147
-rw-r--r--arch/tile/include/asm/socket.h1
-rw-r--r--arch/tile/include/asm/sockios.h1
-rw-r--r--arch/tile/include/asm/spinlock.h24
-rw-r--r--arch/tile/include/asm/spinlock_32.h199
-rw-r--r--arch/tile/include/asm/spinlock_types.h60
-rw-r--r--arch/tile/include/asm/stack.h74
-rw-r--r--arch/tile/include/asm/stat.h1
-rw-r--r--arch/tile/include/asm/statfs.h1
-rw-r--r--arch/tile/include/asm/string.h32
-rw-r--r--arch/tile/include/asm/swab.h29
-rw-r--r--arch/tile/include/asm/syscall.h79
-rw-r--r--arch/tile/include/asm/syscalls.h108
-rw-r--r--arch/tile/include/asm/system.h248
-rw-r--r--arch/tile/include/asm/termbits.h1
-rw-r--r--arch/tile/include/asm/termios.h1
-rw-r--r--arch/tile/include/asm/thread_info.h166
-rw-r--r--arch/tile/include/asm/timex.h47
-rw-r--r--arch/tile/include/asm/tlb.h25
-rw-r--r--arch/tile/include/asm/tlbflush.h128
-rw-r--r--arch/tile/include/asm/topology.h85
-rw-r--r--arch/tile/include/asm/traps.h62
-rw-r--r--arch/tile/include/asm/types.h1
-rw-r--r--arch/tile/include/asm/uaccess.h580
-rw-r--r--arch/tile/include/asm/ucontext.h1
-rw-r--r--arch/tile/include/asm/unaligned.h24
-rw-r--r--arch/tile/include/asm/unistd.h46
-rw-r--r--arch/tile/include/asm/user.h21
-rw-r--r--arch/tile/include/asm/xor.h1
-rw-r--r--arch/tile/include/hv/drv_pcie_rc_intf.h38
-rw-r--r--arch/tile/include/hv/hypervisor.h2375
-rw-r--r--arch/tile/include/hv/pagesize.h32
-rw-r--r--arch/tile/include/hv/syscall_public.h42
-rw-r--r--arch/tile/kernel/Makefile17
-rw-r--r--arch/tile/kernel/asm-offsets.c76
-rw-r--r--arch/tile/kernel/backtrace.c682
-rw-r--r--arch/tile/kernel/compat.c167
-rw-r--r--arch/tile/kernel/compat_signal.c437
-rw-r--r--arch/tile/kernel/early_printk.c109
-rw-r--r--arch/tile/kernel/entry.S141
-rw-r--r--arch/tile/kernel/hardwall.c796
-rw-r--r--arch/tile/kernel/head_32.S180
-rw-r--r--arch/tile/kernel/hvglue.lds58
-rw-r--r--arch/tile/kernel/init_task.c59
-rw-r--r--arch/tile/kernel/intvec_32.S2018
-rw-r--r--arch/tile/kernel/irq.c334
-rw-r--r--arch/tile/kernel/machine_kexec.c279
-rw-r--r--arch/tile/kernel/messaging.c116
-rw-r--r--arch/tile/kernel/module.c257
-rw-r--r--arch/tile/kernel/pci-dma.c251
-rw-r--r--arch/tile/kernel/proc.c90
-rw-r--r--arch/tile/kernel/process.c672
-rw-r--r--arch/tile/kernel/ptrace.c205
-rw-r--r--arch/tile/kernel/reboot.c51
-rw-r--r--arch/tile/kernel/regs_32.S145
-rw-r--r--arch/tile/kernel/relocate_kernel.S280
-rw-r--r--arch/tile/kernel/setup.c1511
-rw-r--r--arch/tile/kernel/signal.c358
-rw-r--r--arch/tile/kernel/single_step.c663
-rw-r--r--arch/tile/kernel/smp.c256
-rw-r--r--arch/tile/kernel/smpboot.c278
-rw-r--r--arch/tile/kernel/stack.c478
-rw-r--r--arch/tile/kernel/sys.c120
-rw-r--r--arch/tile/kernel/tile-desc_32.c2498
-rw-r--r--arch/tile/kernel/time.c226
-rw-r--r--arch/tile/kernel/tlb.c97
-rw-r--r--arch/tile/kernel/traps.c319
-rw-r--r--arch/tile/kernel/vmlinux.lds.S98
-rw-r--r--arch/tile/lib/Makefile18
-rw-r--r--arch/tile/lib/atomic_32.c330
-rw-r--r--arch/tile/lib/atomic_asm_32.S196
-rw-r--r--arch/tile/lib/cacheflush.c23
-rw-r--r--arch/tile/lib/checksum.c102
-rw-r--r--arch/tile/lib/cpumask.c52
-rw-r--r--arch/tile/lib/delay.c34
-rw-r--r--arch/tile/lib/exports.c85
-rw-r--r--arch/tile/lib/mb_incoherent.S34
-rw-r--r--arch/tile/lib/memchr_32.c68
-rw-r--r--arch/tile/lib/memcpy_32.S616
-rw-r--r--arch/tile/lib/memcpy_tile64.c271
-rw-r--r--arch/tile/lib/memmove_32.c63
-rw-r--r--arch/tile/lib/memset_32.c250
-rw-r--r--arch/tile/lib/spinlock_32.c221
-rw-r--r--arch/tile/lib/spinlock_common.h64
-rw-r--r--arch/tile/lib/strchr_32.c66
-rw-r--r--arch/tile/lib/strlen_32.c36
-rw-r--r--arch/tile/lib/uaccess.c32
-rw-r--r--arch/tile/lib/usercopy_32.S223
-rw-r--r--arch/tile/mm/Makefile9
-rw-r--r--arch/tile/mm/elf.c164
-rw-r--r--arch/tile/mm/extable.c30
-rw-r--r--arch/tile/mm/fault.c875
-rw-r--r--arch/tile/mm/highmem.c328
-rw-r--r--arch/tile/mm/homecache.c436
-rw-r--r--arch/tile/mm/hugetlbpage.c343
-rw-r--r--arch/tile/mm/init.c1085
-rw-r--r--arch/tile/mm/migrate.h50
-rw-r--r--arch/tile/mm/migrate_32.S211
-rw-r--r--arch/tile/mm/mmap.c75
-rw-r--r--arch/tile/mm/pgtable.c529
203 files changed, 38003 insertions, 0 deletions
diff --git a/arch/tile/Kbuild b/arch/tile/Kbuild
new file mode 100644
index 000000000000..a9b922716092
--- /dev/null
+++ b/arch/tile/Kbuild
@@ -0,0 +1,3 @@
1
2obj-y += kernel/
3obj-y += mm/
diff --git a/arch/tile/Kconfig b/arch/tile/Kconfig
new file mode 100644
index 000000000000..1eb308cb711a
--- /dev/null
+++ b/arch/tile/Kconfig
@@ -0,0 +1,356 @@
1# For a description of the syntax of this configuration file,
2# see Documentation/kbuild/config-language.txt.
3
4config MMU
5 def_bool y
6
7config GENERIC_CSUM
8 def_bool y
9
10config GENERIC_HARDIRQS
11 def_bool y
12
13config GENERIC_HARDIRQS_NO__DO_IRQ
14 def_bool y
15
16config GENERIC_IRQ_PROBE
17 def_bool y
18
19config GENERIC_PENDING_IRQ
20 def_bool y
21 depends on GENERIC_HARDIRQS && SMP
22
23config SEMAPHORE_SLEEPERS
24 def_bool y
25
26config HAVE_ARCH_ALLOC_REMAP
27 def_bool y
28
29config HAVE_SETUP_PER_CPU_AREA
30 def_bool y
31
32config NEED_PER_CPU_PAGE_FIRST_CHUNK
33 def_bool y
34
35config SYS_SUPPORTS_HUGETLBFS
36 def_bool y
37
38config GENERIC_TIME
39 def_bool y
40
41config GENERIC_CLOCKEVENTS
42 def_bool y
43
44# FIXME: tilegx can implement a more efficent rwsem.
45config RWSEM_GENERIC_SPINLOCK
46 def_bool y
47
48# We have a very flat architecture from a migration point of view,
49# so save boot time by presetting this (particularly useful on tile-sim).
50config DEFAULT_MIGRATION_COST
51 int
52 default "10000000"
53
54# We only support gcc 4.4 and above, so this should work.
55config ARCH_SUPPORTS_OPTIMIZED_INLINING
56 def_bool y
57
58config ARCH_PHYS_ADDR_T_64BIT
59 def_bool y
60
61config LOCKDEP_SUPPORT
62 def_bool y
63
64config STACKTRACE_SUPPORT
65 def_bool y
66 select STACKTRACE
67
68# We use discontigmem for now; at some point we may want to switch
69# to sparsemem (Tilera bug 7996).
70config ARCH_DISCONTIGMEM_ENABLE
71 def_bool y
72
73config ARCH_DISCONTIGMEM_DEFAULT
74 def_bool y
75
76config TRACE_IRQFLAGS_SUPPORT
77 def_bool y
78
79config STRICT_DEVMEM
80 def_bool y
81
82# SMP is required for Tilera Linux.
83config SMP
84 def_bool y
85
86# Allow checking for compile-time determined overflow errors in
87# copy_from_user(). There are still unprovable places in the
88# generic code as of 2.6.34, so this option is not really compatible
89# with -Werror, which is more useful in general.
90config DEBUG_COPY_FROM_USER
91 def_bool n
92
93config HVC_TILE
94 select HVC_DRIVER
95 def_bool y
96
97config TILE
98 def_bool y
99 select GENERIC_FIND_FIRST_BIT
100 select GENERIC_FIND_NEXT_BIT
101 select USE_GENERIC_SMP_HELPERS
102 select CC_OPTIMIZE_FOR_SIZE
103
104# FIXME: investigate whether we need/want these options.
105# select HAVE_IOREMAP_PROT
106# select HAVE_OPTPROBES
107# select HAVE_REGS_AND_STACK_ACCESS_API
108# select HAVE_HW_BREAKPOINT
109# select PERF_EVENTS
110# select HAVE_USER_RETURN_NOTIFIER
111# config NO_BOOTMEM
112# config ARCH_SUPPORTS_DEBUG_PAGEALLOC
113# config HUGETLB_PAGE_SIZE_VARIABLE
114
115
116mainmenu "Linux/TILE Kernel Configuration"
117
118# Please note: TILE-Gx support is not yet finalized; this is
119# the preliminary support. TILE-Gx drivers are only provided
120# with the alpha or beta test versions for Tilera customers.
121config TILEGX
122 depends on EXPERIMENTAL
123 bool "Building with TILE-Gx (64-bit) compiler and toolchain"
124
125config 64BIT
126 depends on TILEGX
127 def_bool y
128
129config ARCH_DEFCONFIG
130 string
131 default "arch/tile/configs/tile_defconfig" if !TILEGX
132 default "arch/tile/configs/tilegx_defconfig" if TILEGX
133
134source "init/Kconfig"
135
136menu "Tilera-specific configuration"
137
138config NR_CPUS
139 int "Maximum number of tiles (2-255)"
140 range 2 255
141 depends on SMP
142 default "64"
143 ---help---
144 Building with 64 is the recommended value, but a slightly
145 smaller kernel memory footprint results from using a smaller
146 value on chips with fewer tiles.
147
148source "kernel/time/Kconfig"
149
150source "kernel/Kconfig.hz"
151
152config KEXEC
153 bool "kexec system call"
154 ---help---
155 kexec is a system call that implements the ability to shutdown your
156 current kernel, and to start another kernel. It is like a reboot
157 but it is independent of the system firmware. It is used
158 to implement the "mboot" Tilera booter.
159
160 The name comes from the similarity to the exec system call.
161
162config COMPAT
163 bool "Support 32-bit TILE-Gx binaries in addition to 64-bit"
164 depends on TILEGX
165 select COMPAT_BINFMT_ELF
166 default y
167 ---help---
168 If enabled, the kernel will support running TILE-Gx binaries
169 that were built with the -m32 option.
170
171config SYSVIPC_COMPAT
172 def_bool y
173 depends on COMPAT && SYSVIPC
174
175# We do not currently support disabling HIGHMEM on tile64 and tilepro.
176config HIGHMEM
177 bool # "Support for more than 512 MB of RAM"
178 default !TILEGX
179 ---help---
180 Linux can use the full amount of RAM in the system by
181 default. However, the address space of TILE processors is
182 only 4 Gigabytes large. That means that, if you have a large
183 amount of physical memory, not all of it can be "permanently
184 mapped" by the kernel. The physical memory that's not
185 permanently mapped is called "high memory".
186
187 If you are compiling a kernel which will never run on a
188 machine with more than 512 MB total physical RAM, answer
189 "false" here. This will result in the kernel mapping all of
190 physical memory into the top 1 GB of virtual memory space.
191
192 If unsure, say "true".
193
194# We do not currently support disabling NUMA.
195config NUMA
196 bool # "NUMA Memory Allocation and Scheduler Support"
197 depends on SMP && DISCONTIGMEM
198 default y
199 ---help---
200 NUMA memory allocation is required for TILE processors
201 unless booting with memory striping enabled in the
202 hypervisor, or with only a single memory controller.
203 It is recommended that this option always be enabled.
204
205config NODES_SHIFT
206 int "Log base 2 of the max number of memory controllers"
207 default 2
208 depends on NEED_MULTIPLE_NODES
209 ---help---
210 By default, 2, i.e. 2^2 == 4 DDR2 controllers.
211 In a system with more controllers, this value should be raised.
212
213# Need 16MB areas to enable hugetlb
214# See build-time check in arch/tile/mm/init.c.
215config FORCE_MAX_ZONEORDER
216 int
217 default 9
218
219choice
220 depends on !TILEGX
221 prompt "Memory split" if EMBEDDED
222 default VMSPLIT_3G
223 ---help---
224 Select the desired split between kernel and user memory.
225
226 If the address range available to the kernel is less than the
227 physical memory installed, the remaining memory will be available
228 as "high memory". Accessing high memory is a little more costly
229 than low memory, as it needs to be mapped into the kernel first.
230 Note that increasing the kernel address space limits the range
231 available to user programs, making the address space there
232 tighter. Selecting anything other than the default 3G/1G split
233 will also likely make your kernel incompatible with binary-only
234 kernel modules.
235
236 If you are not absolutely sure what you are doing, leave this
237 option alone!
238
239 config VMSPLIT_375G
240 bool "3.75G/0.25G user/kernel split (no kernel networking)"
241 config VMSPLIT_35G
242 bool "3.5G/0.5G user/kernel split"
243 config VMSPLIT_3G
244 bool "3G/1G user/kernel split"
245 config VMSPLIT_3G_OPT
246 bool "3G/1G user/kernel split (for full 1G low memory)"
247 config VMSPLIT_2G
248 bool "2G/2G user/kernel split"
249 config VMSPLIT_1G
250 bool "1G/3G user/kernel split"
251endchoice
252
253config PAGE_OFFSET
254 hex
255 default 0xF0000000 if VMSPLIT_375G
256 default 0xE0000000 if VMSPLIT_35G
257 default 0xB0000000 if VMSPLIT_3G_OPT
258 default 0x80000000 if VMSPLIT_2G
259 default 0x40000000 if VMSPLIT_1G
260 default 0xC0000000
261
262source "mm/Kconfig"
263
264config CMDLINE_BOOL
265 bool "Built-in kernel command line"
266 default n
267 ---help---
268 Allow for specifying boot arguments to the kernel at
269 build time. On some systems (e.g. embedded ones), it is
270 necessary or convenient to provide some or all of the
271 kernel boot arguments with the kernel itself (that is,
272 to not rely on the boot loader to provide them.)
273
274 To compile command line arguments into the kernel,
275 set this option to 'Y', then fill in the
276 the boot arguments in CONFIG_CMDLINE.
277
278 Systems with fully functional boot loaders (e.g. mboot, or
279 if booting over PCI) should leave this option set to 'N'.
280
281config CMDLINE
282 string "Built-in kernel command string"
283 depends on CMDLINE_BOOL
284 default ""
285 ---help---
286 Enter arguments here that should be compiled into the kernel
287 image and used at boot time. If the boot loader provides a
288 command line at boot time, it is appended to this string to
289 form the full kernel command line, when the system boots.
290
291 However, you can use the CONFIG_CMDLINE_OVERRIDE option to
292 change this behavior.
293
294 In most cases, the command line (whether built-in or provided
295 by the boot loader) should specify the device for the root
296 file system.
297
298config CMDLINE_OVERRIDE
299 bool "Built-in command line overrides boot loader arguments"
300 default n
301 depends on CMDLINE_BOOL
302 ---help---
303 Set this option to 'Y' to have the kernel ignore the boot loader
304 command line, and use ONLY the built-in command line.
305
306 This is used to work around broken boot loaders. This should
307 be set to 'N' under normal conditions.
308
309config VMALLOC_RESERVE
310 hex
311 default 0x1000000
312
313config HARDWALL
314 bool "Hardwall support to allow access to user dynamic network"
315 default y
316
317endmenu # Tilera-specific configuration
318
319menu "Bus options"
320
321config NO_IOMEM
322 def_bool !PCI
323
324config NO_IOPORT
325 def_bool !PCI
326
327source "drivers/pci/Kconfig"
328
329source "drivers/pci/hotplug/Kconfig"
330
331endmenu
332
333menu "Executable file formats"
334
335# only elf supported
336config KCORE_ELF
337 def_bool y
338 depends on PROC_FS
339
340source "fs/Kconfig.binfmt"
341
342endmenu
343
344source "net/Kconfig"
345
346source "drivers/Kconfig"
347
348source "fs/Kconfig"
349
350source "arch/tile/Kconfig.debug"
351
352source "security/Kconfig"
353
354source "crypto/Kconfig"
355
356source "lib/Kconfig"
diff --git a/arch/tile/Kconfig.debug b/arch/tile/Kconfig.debug
new file mode 100644
index 000000000000..a81f0fbf7e60
--- /dev/null
+++ b/arch/tile/Kconfig.debug
@@ -0,0 +1,43 @@
1menu "Kernel hacking"
2
3source "lib/Kconfig.debug"
4
5config EARLY_PRINTK
6 bool "Early printk" if EMBEDDED && DEBUG_KERNEL
7 default y
8 help
9 Write kernel log output directly via the hypervisor console.
10
11 This is useful for kernel debugging when your machine crashes very
12 early before the console code is initialized. For normal operation
13 it is not recommended because it looks ugly and doesn't cooperate
14 with klogd/syslogd. You should normally N here,
15 unless you want to debug such a crash.
16
17config DEBUG_STACKOVERFLOW
18 bool "Check for stack overflows"
19 depends on DEBUG_KERNEL
20 help
21 This option will cause messages to be printed if free stack space
22 drops below a certain limit.
23
24config DEBUG_STACK_USAGE
25 bool "Stack utilization instrumentation"
26 depends on DEBUG_KERNEL
27 help
28 Enables the display of the minimum amount of free stack which each
29 task has ever had available in the sysrq-T and sysrq-P debug output.
30
31 This option will slow down process creation somewhat.
32
33config DEBUG_EXTRA_FLAGS
34 string "Additional compiler arguments when building with '-g'"
35 depends on DEBUG_INFO
36 default ""
37 help
38 Debug info can be large, and flags like
39 `-femit-struct-debug-baseonly' can reduce the kernel file
40 size and build time noticeably. Such flags are often
41 helpful if the main use of debug info is line number info.
42
43endmenu
diff --git a/arch/tile/Makefile b/arch/tile/Makefile
new file mode 100644
index 000000000000..fd8f6bb5face
--- /dev/null
+++ b/arch/tile/Makefile
@@ -0,0 +1,54 @@
1#
2# This file is subject to the terms and conditions of the GNU General Public
3# License. See the file "COPYING" in the main directory of this archive
4# for more details.
5#
6# This file is included by the global makefile so that you can add your own
7# architecture-specific flags and dependencies. Remember to do have actions
8# for "archclean" and "archdep" for cleaning up and making dependencies for
9# this architecture
10
11# If building with TILERA_ROOT set (i.e. using the Tilera Multicore
12# Development Environment) we can set CROSS_COMPILE based on that.
13# If we're not cross-compiling, make sure we're on the right architecture.
14# Only bother to test for a few common targets, to avoid useless errors.
15ifeq ($(CROSS_COMPILE),)
16 ifdef TILERA_ROOT
17 CROSS_COMPILE := $(TILERA_ROOT)/bin/tile-
18 else
19 goals := $(if $(MAKECMDGOALS), $(MAKECMDGOALS), all)
20 ifneq ($(strip $(filter vmlinux modules all,$(goals))),)
21 HOST_ARCH := $(shell uname -m)
22 ifneq ($(HOST_ARCH),$(ARCH))
23$(error Set TILERA_ROOT or CROSS_COMPILE when building $(ARCH) on $(HOST_ARCH))
24 endif
25 endif
26 endif
27endif
28
29
30KBUILD_CFLAGS += $(CONFIG_DEBUG_EXTRA_FLAGS)
31
32LIBGCC_PATH := $(shell $(CC) $(KBUILD_CFLAGS) -print-libgcc-file-name)
33
34# Provide the path to use for "make defconfig".
35KBUILD_DEFCONFIG := $(ARCH)_defconfig
36
37# Used as a file extension when useful, e.g. head_$(BITS).o
38# Not needed for (e.g.) "$(CC) -m32" since the compiler automatically
39# uses the right default anyway.
40export BITS
41ifeq ($(CONFIG_TILEGX),y)
42BITS := 64
43else
44BITS := 32
45endif
46
47head-y := arch/tile/kernel/head_$(BITS).o
48
49libs-y += arch/tile/lib/
50libs-y += $(LIBGCC_PATH)
51
52
53# See arch/tile/Kbuild for content of core part of the kernel
54core-y += arch/tile/
diff --git a/arch/tile/configs/tile_defconfig b/arch/tile/configs/tile_defconfig
new file mode 100644
index 000000000000..919c54afd981
--- /dev/null
+++ b/arch/tile/configs/tile_defconfig
@@ -0,0 +1,71 @@
1CONFIG_EXPERIMENTAL=y
2# CONFIG_SWAP is not set
3CONFIG_SYSVIPC=y
4CONFIG_BLK_DEV_INITRD=y
5CONFIG_INITRAMFS_SOURCE="usr/contents.txt"
6CONFIG_EMBEDDED=y
7# CONFIG_COMPAT_BRK is not set
8CONFIG_PROFILING=y
9CONFIG_MODULES=y
10CONFIG_MODULE_UNLOAD=y
11# CONFIG_BLK_DEV_BSG is not set
12# CONFIG_IOSCHED_DEADLINE is not set
13# CONFIG_IOSCHED_CFQ is not set
14CONFIG_NO_HZ=y
15CONFIG_HIGH_RES_TIMERS=y
16CONFIG_HZ_100=y
17CONFIG_NET=y
18CONFIG_PACKET=y
19CONFIG_UNIX=y
20CONFIG_INET=y
21CONFIG_IP_MULTICAST=y
22# CONFIG_INET_XFRM_MODE_TRANSPORT is not set
23# CONFIG_INET_XFRM_MODE_TUNNEL is not set
24# CONFIG_INET_LRO is not set
25# CONFIG_INET_DIAG is not set
26CONFIG_IPV6=y
27# CONFIG_WIRELESS is not set
28CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
29CONFIG_SCSI=y
30CONFIG_BLK_DEV_SD=y
31CONFIG_SCSI_CONSTANTS=y
32CONFIG_SCSI_LOGGING=y
33CONFIG_NETDEVICES=y
34CONFIG_TUN=y
35# CONFIG_NETDEV_10000 is not set
36# CONFIG_WLAN is not set
37# CONFIG_INPUT_MOUSEDEV is not set
38# CONFIG_INPUT_KEYBOARD is not set
39# CONFIG_INPUT_MOUSE is not set
40# CONFIG_SERIO is not set
41# CONFIG_VT is not set
42# CONFIG_LEGACY_PTYS is not set
43# CONFIG_HW_RANDOM is not set
44CONFIG_WATCHDOG=y
45CONFIG_WATCHDOG_NOWAYOUT=y
46# CONFIG_HID_SUPPORT is not set
47CONFIG_RTC_CLASS=y
48# CONFIG_RTC_INTF_SYSFS is not set
49# CONFIG_RTC_INTF_PROC is not set
50CONFIG_EXT2_FS=y
51CONFIG_EXT3_FS=y
52# CONFIG_EXT3_DEFAULTS_TO_ORDERED is not set
53CONFIG_FUSE_FS=y
54CONFIG_MSDOS_FS=y
55CONFIG_VFAT_FS=m
56CONFIG_TMPFS=y
57CONFIG_HUGETLBFS=y
58CONFIG_NFS_FS=m
59CONFIG_NFS_V3=y
60CONFIG_NLS_CODEPAGE_437=y
61CONFIG_NLS_ISO8859_1=y
62CONFIG_FRAME_WARN=2048
63CONFIG_MAGIC_SYSRQ=y
64CONFIG_DEBUG_KERNEL=y
65CONFIG_DETECT_HUNG_TASK=y
66CONFIG_DEBUG_SPINLOCK_SLEEP=y
67CONFIG_DEBUG_INFO=y
68CONFIG_DEBUG_VM=y
69# CONFIG_RCU_CPU_STALL_DETECTOR is not set
70CONFIG_DEBUG_STACKOVERFLOW=y
71CONFIG_DEBUG_EXTRA_FLAGS="-femit-struct-debug-baseonly"
diff --git a/arch/tile/include/arch/abi.h b/arch/tile/include/arch/abi.h
new file mode 100644
index 000000000000..8affc76f771a
--- /dev/null
+++ b/arch/tile/include/arch/abi.h
@@ -0,0 +1,96 @@
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/**
16 * @file
17 *
18 * ABI-related register definitions helpful when writing assembly code.
19 */
20
21#ifndef __ARCH_ABI_H__
22#define __ARCH_ABI_H__
23
24#include <arch/chip.h>
25
26/* Registers 0 - 55 are "normal", but some perform special roles. */
27
28#define TREG_FP 52 /**< Frame pointer. */
29#define TREG_TP 53 /**< Thread pointer. */
30#define TREG_SP 54 /**< Stack pointer. */
31#define TREG_LR 55 /**< Link to calling function PC. */
32
33/** Index of last normal general-purpose register. */
34#define TREG_LAST_GPR 55
35
36/* Registers 56 - 62 are "special" network registers. */
37
38#define TREG_SN 56 /**< Static network access. */
39#define TREG_IDN0 57 /**< IDN demux 0 access. */
40#define TREG_IDN1 58 /**< IDN demux 1 access. */
41#define TREG_UDN0 59 /**< UDN demux 0 access. */
42#define TREG_UDN1 60 /**< UDN demux 1 access. */
43#define TREG_UDN2 61 /**< UDN demux 2 access. */
44#define TREG_UDN3 62 /**< UDN demux 3 access. */
45
46/* Register 63 is the "special" zero register. */
47
48#define TREG_ZERO 63 /**< "Zero" register; always reads as "0". */
49
50
51/** By convention, this register is used to hold the syscall number. */
52#define TREG_SYSCALL_NR 10
53
54/** Name of register that holds the syscall number, for use in assembly. */
55#define TREG_SYSCALL_NR_NAME r10
56
57
58/**
59 * The ABI requires callers to allocate a caller state save area of
60 * this many bytes at the bottom of each stack frame.
61 */
62#define C_ABI_SAVE_AREA_SIZE (2 * (CHIP_WORD_SIZE() / 8))
63
64/**
65 * The operand to an 'info' opcode directing the backtracer to not
66 * try to find the calling frame.
67 */
68#define INFO_OP_CANNOT_BACKTRACE 2
69
70#ifndef __ASSEMBLER__
71#if CHIP_WORD_SIZE() > 32
72
73/** Unsigned type that can hold a register. */
74typedef unsigned long long uint_reg_t;
75
76/** Signed type that can hold a register. */
77typedef long long int_reg_t;
78
79/** String prefix to use for printf(). */
80#define INT_REG_FMT "ll"
81
82#elif !defined(__LP64__) /* avoid confusion with LP64 cross-build tools */
83
84/** Unsigned type that can hold a register. */
85typedef unsigned long uint_reg_t;
86
87/** Signed type that can hold a register. */
88typedef long int_reg_t;
89
90/** String prefix to use for printf(). */
91#define INT_REG_FMT "l"
92
93#endif
94#endif /* __ASSEMBLER__ */
95
96#endif /* !__ARCH_ABI_H__ */
diff --git a/arch/tile/include/arch/chip.h b/arch/tile/include/arch/chip.h
new file mode 100644
index 000000000000..926d3db0e91e
--- /dev/null
+++ b/arch/tile/include/arch/chip.h
@@ -0,0 +1,23 @@
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#if __tile_chip__ == 0
16#include <arch/chip_tile64.h>
17#elif __tile_chip__ == 1
18#include <arch/chip_tilepro.h>
19#elif defined(__tilegx__)
20#include <arch/chip_tilegx.h>
21#else
22#error Unexpected Tilera chip type
23#endif
diff --git a/arch/tile/include/arch/chip_tile64.h b/arch/tile/include/arch/chip_tile64.h
new file mode 100644
index 000000000000..1246573be59e
--- /dev/null
+++ b/arch/tile/include/arch/chip_tile64.h
@@ -0,0 +1,255 @@
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/*
16 * @file
17 * Global header file.
18 * This header file specifies defines for TILE64.
19 */
20
21#ifndef __ARCH_CHIP_H__
22#define __ARCH_CHIP_H__
23
24/** Specify chip version.
25 * When possible, prefer the CHIP_xxx symbols below for future-proofing.
26 * This is intended for cross-compiling; native compilation should
27 * use the predefined __tile_chip__ symbol.
28 */
29#define TILE_CHIP 0
30
31/** Specify chip revision.
32 * This provides for the case of a respin of a particular chip type;
33 * the normal value for this symbol is "0".
34 * This is intended for cross-compiling; native compilation should
35 * use the predefined __tile_chip_rev__ symbol.
36 */
37#define TILE_CHIP_REV 0
38
39/** The name of this architecture. */
40#define CHIP_ARCH_NAME "tile64"
41
42/** The ELF e_machine type for binaries for this chip. */
43#define CHIP_ELF_TYPE() EM_TILE64
44
45/** The alternate ELF e_machine type for binaries for this chip. */
46#define CHIP_COMPAT_ELF_TYPE() 0x2506
47
48/** What is the native word size of the machine? */
49#define CHIP_WORD_SIZE() 32
50
51/** How many bits of a virtual address are used. Extra bits must be
52 * the sign extension of the low bits.
53 */
54#define CHIP_VA_WIDTH() 32
55
56/** How many bits are in a physical address? */
57#define CHIP_PA_WIDTH() 36
58
59/** Size of the L2 cache, in bytes. */
60#define CHIP_L2_CACHE_SIZE() 65536
61
62/** Log size of an L2 cache line in bytes. */
63#define CHIP_L2_LOG_LINE_SIZE() 6
64
65/** Size of an L2 cache line, in bytes. */
66#define CHIP_L2_LINE_SIZE() (1 << CHIP_L2_LOG_LINE_SIZE())
67
68/** Associativity of the L2 cache. */
69#define CHIP_L2_ASSOC() 2
70
71/** Size of the L1 data cache, in bytes. */
72#define CHIP_L1D_CACHE_SIZE() 8192
73
74/** Log size of an L1 data cache line in bytes. */
75#define CHIP_L1D_LOG_LINE_SIZE() 4
76
77/** Size of an L1 data cache line, in bytes. */
78#define CHIP_L1D_LINE_SIZE() (1 << CHIP_L1D_LOG_LINE_SIZE())
79
80/** Associativity of the L1 data cache. */
81#define CHIP_L1D_ASSOC() 2
82
83/** Size of the L1 instruction cache, in bytes. */
84#define CHIP_L1I_CACHE_SIZE() 8192
85
86/** Log size of an L1 instruction cache line in bytes. */
87#define CHIP_L1I_LOG_LINE_SIZE() 6
88
89/** Size of an L1 instruction cache line, in bytes. */
90#define CHIP_L1I_LINE_SIZE() (1 << CHIP_L1I_LOG_LINE_SIZE())
91
92/** Associativity of the L1 instruction cache. */
93#define CHIP_L1I_ASSOC() 1
94
95/** Stride with which flush instructions must be issued. */
96#define CHIP_FLUSH_STRIDE() CHIP_L2_LINE_SIZE()
97
98/** Stride with which inv instructions must be issued. */
99#define CHIP_INV_STRIDE() CHIP_L1D_LINE_SIZE()
100
101/** Stride with which finv instructions must be issued. */
102#define CHIP_FINV_STRIDE() CHIP_L1D_LINE_SIZE()
103
104/** Can the local cache coherently cache data that is homed elsewhere? */
105#define CHIP_HAS_COHERENT_LOCAL_CACHE() 0
106
107/** How many simultaneous outstanding victims can the L2 cache have? */
108#define CHIP_MAX_OUTSTANDING_VICTIMS() 2
109
110/** Does the TLB support the NC and NOALLOC bits? */
111#define CHIP_HAS_NC_AND_NOALLOC_BITS() 0
112
113/** Does the chip support hash-for-home caching? */
114#define CHIP_HAS_CBOX_HOME_MAP() 0
115
116/** Number of entries in the chip's home map tables. */
117/* #define CHIP_CBOX_HOME_MAP_SIZE() -- does not apply to chip 0 */
118
119/** Do uncacheable requests miss in the cache regardless of whether
120 * there is matching data? */
121#define CHIP_HAS_ENFORCED_UNCACHEABLE_REQUESTS() 0
122
123/** Does the mf instruction wait for victims? */
124#define CHIP_HAS_MF_WAITS_FOR_VICTIMS() 1
125
126/** Does the chip have an "inv" instruction that doesn't also flush? */
127#define CHIP_HAS_INV() 0
128
129/** Does the chip have a "wh64" instruction? */
130#define CHIP_HAS_WH64() 0
131
132/** Does this chip have a 'dword_align' instruction? */
133#define CHIP_HAS_DWORD_ALIGN() 0
134
135/** Number of performance counters. */
136#define CHIP_PERFORMANCE_COUNTERS() 2
137
138/** Does this chip have auxiliary performance counters? */
139#define CHIP_HAS_AUX_PERF_COUNTERS() 0
140
141/** Is the CBOX_MSR1 SPR supported? */
142#define CHIP_HAS_CBOX_MSR1() 0
143
144/** Is the TILE_RTF_HWM SPR supported? */
145#define CHIP_HAS_TILE_RTF_HWM() 0
146
147/** Is the TILE_WRITE_PENDING SPR supported? */
148#define CHIP_HAS_TILE_WRITE_PENDING() 0
149
150/** Is the PROC_STATUS SPR supported? */
151#define CHIP_HAS_PROC_STATUS_SPR() 0
152
153/** Log of the number of mshims we have. */
154#define CHIP_LOG_NUM_MSHIMS() 2
155
156/** Are the bases of the interrupt vector areas fixed? */
157#define CHIP_HAS_FIXED_INTVEC_BASE() 1
158
159/** Are the interrupt masks split up into 2 SPRs? */
160#define CHIP_HAS_SPLIT_INTR_MASK() 1
161
162/** Is the cycle count split up into 2 SPRs? */
163#define CHIP_HAS_SPLIT_CYCLE() 1
164
165/** Does the chip have a static network? */
166#define CHIP_HAS_SN() 1
167
168/** Does the chip have a static network processor? */
169#define CHIP_HAS_SN_PROC() 1
170
171/** Size of the L1 static network processor instruction cache, in bytes. */
172#define CHIP_L1SNI_CACHE_SIZE() 2048
173
174/** Does the chip have DMA support in each tile? */
175#define CHIP_HAS_TILE_DMA() 1
176
177/** Does the chip have the second revision of the directly accessible
178 * dynamic networks? This encapsulates a number of characteristics,
179 * including the absence of the catch-all, the absence of inline message
180 * tags, the absence of support for network context-switching, and so on.
181 */
182#define CHIP_HAS_REV1_XDN() 0
183
184/** Does the chip have cmpexch and similar (fetchadd, exch, etc.)? */
185#define CHIP_HAS_CMPEXCH() 0
186
187/** Does the chip have memory-mapped I/O support? */
188#define CHIP_HAS_MMIO() 0
189
190/** Does the chip have post-completion interrupts? */
191#define CHIP_HAS_POST_COMPLETION_INTERRUPTS() 0
192
193/** Does the chip have native single step support? */
194#define CHIP_HAS_SINGLE_STEP() 0
195
196#ifndef __OPEN_SOURCE__ /* features only relevant to hypervisor-level code */
197
198/** How many entries are present in the instruction TLB? */
199#define CHIP_ITLB_ENTRIES() 8
200
201/** How many entries are present in the data TLB? */
202#define CHIP_DTLB_ENTRIES() 16
203
204/** How many MAF entries does the XAUI shim have? */
205#define CHIP_XAUI_MAF_ENTRIES() 16
206
207/** Does the memory shim have a source-id table? */
208#define CHIP_HAS_MSHIM_SRCID_TABLE() 1
209
210/** Does the L1 instruction cache clear on reset? */
211#define CHIP_HAS_L1I_CLEAR_ON_RESET() 0
212
213/** Does the chip come out of reset with valid coordinates on all tiles?
214 * Note that if defined, this also implies that the upper left is 1,1.
215 */
216#define CHIP_HAS_VALID_TILE_COORD_RESET() 0
217
218/** Does the chip have unified packet formats? */
219#define CHIP_HAS_UNIFIED_PACKET_FORMATS() 0
220
221/** Does the chip support write reordering? */
222#define CHIP_HAS_WRITE_REORDERING() 0
223
224/** Does the chip support Y-X routing as well as X-Y? */
225#define CHIP_HAS_Y_X_ROUTING() 0
226
227/** Is INTCTRL_3 managed with the correct MPL? */
228#define CHIP_HAS_INTCTRL_3_STATUS_FIX() 0
229
230/** Is it possible to configure the chip to be big-endian? */
231#define CHIP_HAS_BIG_ENDIAN_CONFIG() 0
232
233/** Is the CACHE_RED_WAY_OVERRIDDEN SPR supported? */
234#define CHIP_HAS_CACHE_RED_WAY_OVERRIDDEN() 0
235
236/** Is the DIAG_TRACE_WAY SPR supported? */
237#define CHIP_HAS_DIAG_TRACE_WAY() 0
238
239/** Is the MEM_STRIPE_CONFIG SPR supported? */
240#define CHIP_HAS_MEM_STRIPE_CONFIG() 0
241
242/** Are the TLB_PERF SPRs supported? */
243#define CHIP_HAS_TLB_PERF() 0
244
245/** Is the VDN_SNOOP_SHIM_CTL SPR supported? */
246#define CHIP_HAS_VDN_SNOOP_SHIM_CTL() 0
247
248/** Does the chip support rev1 DMA packets? */
249#define CHIP_HAS_REV1_DMA_PACKETS() 0
250
251/** Does the chip have an IPI shim? */
252#define CHIP_HAS_IPI() 0
253
254#endif /* !__OPEN_SOURCE__ */
255#endif /* __ARCH_CHIP_H__ */
diff --git a/arch/tile/include/arch/chip_tilepro.h b/arch/tile/include/arch/chip_tilepro.h
new file mode 100644
index 000000000000..e864c47fc89c
--- /dev/null
+++ b/arch/tile/include/arch/chip_tilepro.h
@@ -0,0 +1,255 @@
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/*
16 * @file
17 * Global header file.
18 * This header file specifies defines for TILEPro.
19 */
20
21#ifndef __ARCH_CHIP_H__
22#define __ARCH_CHIP_H__
23
24/** Specify chip version.
25 * When possible, prefer the CHIP_xxx symbols below for future-proofing.
26 * This is intended for cross-compiling; native compilation should
27 * use the predefined __tile_chip__ symbol.
28 */
29#define TILE_CHIP 1
30
31/** Specify chip revision.
32 * This provides for the case of a respin of a particular chip type;
33 * the normal value for this symbol is "0".
34 * This is intended for cross-compiling; native compilation should
35 * use the predefined __tile_chip_rev__ symbol.
36 */
37#define TILE_CHIP_REV 0
38
39/** The name of this architecture. */
40#define CHIP_ARCH_NAME "tilepro"
41
42/** The ELF e_machine type for binaries for this chip. */
43#define CHIP_ELF_TYPE() EM_TILEPRO
44
45/** The alternate ELF e_machine type for binaries for this chip. */
46#define CHIP_COMPAT_ELF_TYPE() 0x2507
47
48/** What is the native word size of the machine? */
49#define CHIP_WORD_SIZE() 32
50
51/** How many bits of a virtual address are used. Extra bits must be
52 * the sign extension of the low bits.
53 */
54#define CHIP_VA_WIDTH() 32
55
56/** How many bits are in a physical address? */
57#define CHIP_PA_WIDTH() 36
58
59/** Size of the L2 cache, in bytes. */
60#define CHIP_L2_CACHE_SIZE() 65536
61
62/** Log size of an L2 cache line in bytes. */
63#define CHIP_L2_LOG_LINE_SIZE() 6
64
65/** Size of an L2 cache line, in bytes. */
66#define CHIP_L2_LINE_SIZE() (1 << CHIP_L2_LOG_LINE_SIZE())
67
68/** Associativity of the L2 cache. */
69#define CHIP_L2_ASSOC() 4
70
71/** Size of the L1 data cache, in bytes. */
72#define CHIP_L1D_CACHE_SIZE() 8192
73
74/** Log size of an L1 data cache line in bytes. */
75#define CHIP_L1D_LOG_LINE_SIZE() 4
76
77/** Size of an L1 data cache line, in bytes. */
78#define CHIP_L1D_LINE_SIZE() (1 << CHIP_L1D_LOG_LINE_SIZE())
79
80/** Associativity of the L1 data cache. */
81#define CHIP_L1D_ASSOC() 2
82
83/** Size of the L1 instruction cache, in bytes. */
84#define CHIP_L1I_CACHE_SIZE() 16384
85
86/** Log size of an L1 instruction cache line in bytes. */
87#define CHIP_L1I_LOG_LINE_SIZE() 6
88
89/** Size of an L1 instruction cache line, in bytes. */
90#define CHIP_L1I_LINE_SIZE() (1 << CHIP_L1I_LOG_LINE_SIZE())
91
92/** Associativity of the L1 instruction cache. */
93#define CHIP_L1I_ASSOC() 1
94
95/** Stride with which flush instructions must be issued. */
96#define CHIP_FLUSH_STRIDE() CHIP_L2_LINE_SIZE()
97
98/** Stride with which inv instructions must be issued. */
99#define CHIP_INV_STRIDE() CHIP_L2_LINE_SIZE()
100
101/** Stride with which finv instructions must be issued. */
102#define CHIP_FINV_STRIDE() CHIP_L2_LINE_SIZE()
103
104/** Can the local cache coherently cache data that is homed elsewhere? */
105#define CHIP_HAS_COHERENT_LOCAL_CACHE() 1
106
107/** How many simultaneous outstanding victims can the L2 cache have? */
108#define CHIP_MAX_OUTSTANDING_VICTIMS() 4
109
110/** Does the TLB support the NC and NOALLOC bits? */
111#define CHIP_HAS_NC_AND_NOALLOC_BITS() 1
112
113/** Does the chip support hash-for-home caching? */
114#define CHIP_HAS_CBOX_HOME_MAP() 1
115
116/** Number of entries in the chip's home map tables. */
117#define CHIP_CBOX_HOME_MAP_SIZE() 64
118
119/** Do uncacheable requests miss in the cache regardless of whether
120 * there is matching data? */
121#define CHIP_HAS_ENFORCED_UNCACHEABLE_REQUESTS() 1
122
123/** Does the mf instruction wait for victims? */
124#define CHIP_HAS_MF_WAITS_FOR_VICTIMS() 0
125
126/** Does the chip have an "inv" instruction that doesn't also flush? */
127#define CHIP_HAS_INV() 1
128
129/** Does the chip have a "wh64" instruction? */
130#define CHIP_HAS_WH64() 1
131
132/** Does this chip have a 'dword_align' instruction? */
133#define CHIP_HAS_DWORD_ALIGN() 1
134
135/** Number of performance counters. */
136#define CHIP_PERFORMANCE_COUNTERS() 4
137
138/** Does this chip have auxiliary performance counters? */
139#define CHIP_HAS_AUX_PERF_COUNTERS() 1
140
141/** Is the CBOX_MSR1 SPR supported? */
142#define CHIP_HAS_CBOX_MSR1() 1
143
144/** Is the TILE_RTF_HWM SPR supported? */
145#define CHIP_HAS_TILE_RTF_HWM() 1
146
147/** Is the TILE_WRITE_PENDING SPR supported? */
148#define CHIP_HAS_TILE_WRITE_PENDING() 1
149
150/** Is the PROC_STATUS SPR supported? */
151#define CHIP_HAS_PROC_STATUS_SPR() 1
152
153/** Log of the number of mshims we have. */
154#define CHIP_LOG_NUM_MSHIMS() 2
155
156/** Are the bases of the interrupt vector areas fixed? */
157#define CHIP_HAS_FIXED_INTVEC_BASE() 1
158
159/** Are the interrupt masks split up into 2 SPRs? */
160#define CHIP_HAS_SPLIT_INTR_MASK() 1
161
162/** Is the cycle count split up into 2 SPRs? */
163#define CHIP_HAS_SPLIT_CYCLE() 1
164
165/** Does the chip have a static network? */
166#define CHIP_HAS_SN() 1
167
168/** Does the chip have a static network processor? */
169#define CHIP_HAS_SN_PROC() 0
170
171/** Size of the L1 static network processor instruction cache, in bytes. */
172/* #define CHIP_L1SNI_CACHE_SIZE() -- does not apply to chip 1 */
173
174/** Does the chip have DMA support in each tile? */
175#define CHIP_HAS_TILE_DMA() 1
176
177/** Does the chip have the second revision of the directly accessible
178 * dynamic networks? This encapsulates a number of characteristics,
179 * including the absence of the catch-all, the absence of inline message
180 * tags, the absence of support for network context-switching, and so on.
181 */
182#define CHIP_HAS_REV1_XDN() 0
183
184/** Does the chip have cmpexch and similar (fetchadd, exch, etc.)? */
185#define CHIP_HAS_CMPEXCH() 0
186
187/** Does the chip have memory-mapped I/O support? */
188#define CHIP_HAS_MMIO() 0
189
190/** Does the chip have post-completion interrupts? */
191#define CHIP_HAS_POST_COMPLETION_INTERRUPTS() 0
192
193/** Does the chip have native single step support? */
194#define CHIP_HAS_SINGLE_STEP() 0
195
196#ifndef __OPEN_SOURCE__ /* features only relevant to hypervisor-level code */
197
198/** How many entries are present in the instruction TLB? */
199#define CHIP_ITLB_ENTRIES() 16
200
201/** How many entries are present in the data TLB? */
202#define CHIP_DTLB_ENTRIES() 16
203
204/** How many MAF entries does the XAUI shim have? */
205#define CHIP_XAUI_MAF_ENTRIES() 32
206
207/** Does the memory shim have a source-id table? */
208#define CHIP_HAS_MSHIM_SRCID_TABLE() 0
209
210/** Does the L1 instruction cache clear on reset? */
211#define CHIP_HAS_L1I_CLEAR_ON_RESET() 1
212
213/** Does the chip come out of reset with valid coordinates on all tiles?
214 * Note that if defined, this also implies that the upper left is 1,1.
215 */
216#define CHIP_HAS_VALID_TILE_COORD_RESET() 1
217
218/** Does the chip have unified packet formats? */
219#define CHIP_HAS_UNIFIED_PACKET_FORMATS() 1
220
221/** Does the chip support write reordering? */
222#define CHIP_HAS_WRITE_REORDERING() 1
223
224/** Does the chip support Y-X routing as well as X-Y? */
225#define CHIP_HAS_Y_X_ROUTING() 1
226
227/** Is INTCTRL_3 managed with the correct MPL? */
228#define CHIP_HAS_INTCTRL_3_STATUS_FIX() 1
229
230/** Is it possible to configure the chip to be big-endian? */
231#define CHIP_HAS_BIG_ENDIAN_CONFIG() 1
232
233/** Is the CACHE_RED_WAY_OVERRIDDEN SPR supported? */
234#define CHIP_HAS_CACHE_RED_WAY_OVERRIDDEN() 1
235
236/** Is the DIAG_TRACE_WAY SPR supported? */
237#define CHIP_HAS_DIAG_TRACE_WAY() 1
238
239/** Is the MEM_STRIPE_CONFIG SPR supported? */
240#define CHIP_HAS_MEM_STRIPE_CONFIG() 1
241
242/** Are the TLB_PERF SPRs supported? */
243#define CHIP_HAS_TLB_PERF() 1
244
245/** Is the VDN_SNOOP_SHIM_CTL SPR supported? */
246#define CHIP_HAS_VDN_SNOOP_SHIM_CTL() 1
247
248/** Does the chip support rev1 DMA packets? */
249#define CHIP_HAS_REV1_DMA_PACKETS() 1
250
251/** Does the chip have an IPI shim? */
252#define CHIP_HAS_IPI() 0
253
254#endif /* !__OPEN_SOURCE__ */
255#endif /* __ARCH_CHIP_H__ */
diff --git a/arch/tile/include/arch/icache.h b/arch/tile/include/arch/icache.h
new file mode 100644
index 000000000000..5c87c9016338
--- /dev/null
+++ b/arch/tile/include/arch/icache.h
@@ -0,0 +1,94 @@
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
16/**
17 * @file
18 *
19 * Support for invalidating bytes in the instruction
20 */
21
22#ifndef __ARCH_ICACHE_H__
23#define __ARCH_ICACHE_H__
24
25#include <arch/chip.h>
26
27
28/**
29 * Invalidate the instruction cache for the given range of memory.
30 *
31 * @param addr The start of memory to be invalidated.
32 * @param size The number of bytes to be invalidated.
33 * @param page_size The system's page size, typically the PAGE_SIZE constant
34 * in sys/page.h. This value must be a power of two no larger
35 * than the page containing the code to be invalidated. If the value
36 * is smaller than the actual page size, this function will still
37 * work, but may run slower than necessary.
38 */
39static __inline void
40invalidate_icache(const void* addr, unsigned long size,
41 unsigned long page_size)
42{
43 const unsigned long cache_way_size =
44 CHIP_L1I_CACHE_SIZE() / CHIP_L1I_ASSOC();
45 unsigned long max_useful_size;
46 const char* start, *end;
47 long num_passes;
48
49 if (__builtin_expect(size == 0, 0))
50 return;
51
52#ifdef __tilegx__
53 /* Limit the number of bytes visited to avoid redundant iterations. */
54 max_useful_size = (page_size < cache_way_size) ? page_size : cache_way_size;
55
56 /* No PA aliasing is possible, so one pass always suffices. */
57 num_passes = 1;
58#else
59 /* Limit the number of bytes visited to avoid redundant iterations. */
60 max_useful_size = cache_way_size;
61
62 /*
63 * Compute how many passes we need (we'll treat 0 as if it were 1).
64 * This works because we know the page size is a power of two.
65 */
66 num_passes = cache_way_size >> __builtin_ctzl(page_size);
67#endif
68
69 if (__builtin_expect(size > max_useful_size, 0))
70 size = max_useful_size;
71
72 /* Locate the first and last bytes to be invalidated. */
73 start = (const char *)((unsigned long)addr & -CHIP_L1I_LINE_SIZE());
74 end = (const char*)addr + size - 1;
75
76 __insn_mf();
77
78 do
79 {
80 const char* p;
81
82 for (p = start; p <= end; p += CHIP_L1I_LINE_SIZE())
83 __insn_icoh(p);
84
85 start += page_size;
86 end += page_size;
87 }
88 while (--num_passes > 0);
89
90 __insn_drain();
91}
92
93
94#endif /* __ARCH_ICACHE_H__ */
diff --git a/arch/tile/include/arch/interrupts.h b/arch/tile/include/arch/interrupts.h
new file mode 100644
index 000000000000..20f8f07d2de9
--- /dev/null
+++ b/arch/tile/include/arch/interrupts.h
@@ -0,0 +1,19 @@
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#ifdef __tilegx__
16#include <arch/interrupts_64.h>
17#else
18#include <arch/interrupts_32.h>
19#endif
diff --git a/arch/tile/include/arch/interrupts_32.h b/arch/tile/include/arch/interrupts_32.h
new file mode 100644
index 000000000000..9d0bfa7e59be
--- /dev/null
+++ b/arch/tile/include/arch/interrupts_32.h
@@ -0,0 +1,304 @@
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 __ARCH_INTERRUPTS_H__
16#define __ARCH_INTERRUPTS_H__
17
18/** Mask for an interrupt. */
19#ifdef __ASSEMBLER__
20/* Note: must handle breaking interrupts into high and low words manually. */
21#define INT_MASK(intno) (1 << (intno))
22#else
23#define INT_MASK(intno) (1ULL << (intno))
24#endif
25
26
27/** Where a given interrupt executes */
28#define INTERRUPT_VECTOR(i, pl) (0xFC000000 + ((pl) << 24) + ((i) << 8))
29
30/** Where to store a vector for a given interrupt. */
31#define USER_INTERRUPT_VECTOR(i) INTERRUPT_VECTOR(i, 0)
32
33/** The base address of user-level interrupts. */
34#define USER_INTERRUPT_VECTOR_BASE INTERRUPT_VECTOR(0, 0)
35
36
37/** Additional synthetic interrupt. */
38#define INT_BREAKPOINT (63)
39
40#define INT_ITLB_MISS 0
41#define INT_MEM_ERROR 1
42#define INT_ILL 2
43#define INT_GPV 3
44#define INT_SN_ACCESS 4
45#define INT_IDN_ACCESS 5
46#define INT_UDN_ACCESS 6
47#define INT_IDN_REFILL 7
48#define INT_UDN_REFILL 8
49#define INT_IDN_COMPLETE 9
50#define INT_UDN_COMPLETE 10
51#define INT_SWINT_3 11
52#define INT_SWINT_2 12
53#define INT_SWINT_1 13
54#define INT_SWINT_0 14
55#define INT_UNALIGN_DATA 15
56#define INT_DTLB_MISS 16
57#define INT_DTLB_ACCESS 17
58#define INT_DMATLB_MISS 18
59#define INT_DMATLB_ACCESS 19
60#define INT_SNITLB_MISS 20
61#define INT_SN_NOTIFY 21
62#define INT_SN_FIREWALL 22
63#define INT_IDN_FIREWALL 23
64#define INT_UDN_FIREWALL 24
65#define INT_TILE_TIMER 25
66#define INT_IDN_TIMER 26
67#define INT_UDN_TIMER 27
68#define INT_DMA_NOTIFY 28
69#define INT_IDN_CA 29
70#define INT_UDN_CA 30
71#define INT_IDN_AVAIL 31
72#define INT_UDN_AVAIL 32
73#define INT_PERF_COUNT 33
74#define INT_INTCTRL_3 34
75#define INT_INTCTRL_2 35
76#define INT_INTCTRL_1 36
77#define INT_INTCTRL_0 37
78#define INT_BOOT_ACCESS 38
79#define INT_WORLD_ACCESS 39
80#define INT_I_ASID 40
81#define INT_D_ASID 41
82#define INT_DMA_ASID 42
83#define INT_SNI_ASID 43
84#define INT_DMA_CPL 44
85#define INT_SN_CPL 45
86#define INT_DOUBLE_FAULT 46
87#define INT_SN_STATIC_ACCESS 47
88#define INT_AUX_PERF_COUNT 48
89
90#define NUM_INTERRUPTS 49
91
92#define QUEUED_INTERRUPTS ( \
93 INT_MASK(INT_MEM_ERROR) | \
94 INT_MASK(INT_DMATLB_MISS) | \
95 INT_MASK(INT_DMATLB_ACCESS) | \
96 INT_MASK(INT_SNITLB_MISS) | \
97 INT_MASK(INT_SN_NOTIFY) | \
98 INT_MASK(INT_SN_FIREWALL) | \
99 INT_MASK(INT_IDN_FIREWALL) | \
100 INT_MASK(INT_UDN_FIREWALL) | \
101 INT_MASK(INT_TILE_TIMER) | \
102 INT_MASK(INT_IDN_TIMER) | \
103 INT_MASK(INT_UDN_TIMER) | \
104 INT_MASK(INT_DMA_NOTIFY) | \
105 INT_MASK(INT_IDN_CA) | \
106 INT_MASK(INT_UDN_CA) | \
107 INT_MASK(INT_IDN_AVAIL) | \
108 INT_MASK(INT_UDN_AVAIL) | \
109 INT_MASK(INT_PERF_COUNT) | \
110 INT_MASK(INT_INTCTRL_3) | \
111 INT_MASK(INT_INTCTRL_2) | \
112 INT_MASK(INT_INTCTRL_1) | \
113 INT_MASK(INT_INTCTRL_0) | \
114 INT_MASK(INT_BOOT_ACCESS) | \
115 INT_MASK(INT_WORLD_ACCESS) | \
116 INT_MASK(INT_I_ASID) | \
117 INT_MASK(INT_D_ASID) | \
118 INT_MASK(INT_DMA_ASID) | \
119 INT_MASK(INT_SNI_ASID) | \
120 INT_MASK(INT_DMA_CPL) | \
121 INT_MASK(INT_SN_CPL) | \
122 INT_MASK(INT_DOUBLE_FAULT) | \
123 INT_MASK(INT_AUX_PERF_COUNT) | \
124 0)
125#define NONQUEUED_INTERRUPTS ( \
126 INT_MASK(INT_ITLB_MISS) | \
127 INT_MASK(INT_ILL) | \
128 INT_MASK(INT_GPV) | \
129 INT_MASK(INT_SN_ACCESS) | \
130 INT_MASK(INT_IDN_ACCESS) | \
131 INT_MASK(INT_UDN_ACCESS) | \
132 INT_MASK(INT_IDN_REFILL) | \
133 INT_MASK(INT_UDN_REFILL) | \
134 INT_MASK(INT_IDN_COMPLETE) | \
135 INT_MASK(INT_UDN_COMPLETE) | \
136 INT_MASK(INT_SWINT_3) | \
137 INT_MASK(INT_SWINT_2) | \
138 INT_MASK(INT_SWINT_1) | \
139 INT_MASK(INT_SWINT_0) | \
140 INT_MASK(INT_UNALIGN_DATA) | \
141 INT_MASK(INT_DTLB_MISS) | \
142 INT_MASK(INT_DTLB_ACCESS) | \
143 INT_MASK(INT_SN_STATIC_ACCESS) | \
144 0)
145#define CRITICAL_MASKED_INTERRUPTS ( \
146 INT_MASK(INT_MEM_ERROR) | \
147 INT_MASK(INT_DMATLB_MISS) | \
148 INT_MASK(INT_DMATLB_ACCESS) | \
149 INT_MASK(INT_SNITLB_MISS) | \
150 INT_MASK(INT_SN_NOTIFY) | \
151 INT_MASK(INT_SN_FIREWALL) | \
152 INT_MASK(INT_IDN_FIREWALL) | \
153 INT_MASK(INT_UDN_FIREWALL) | \
154 INT_MASK(INT_TILE_TIMER) | \
155 INT_MASK(INT_IDN_TIMER) | \
156 INT_MASK(INT_UDN_TIMER) | \
157 INT_MASK(INT_DMA_NOTIFY) | \
158 INT_MASK(INT_IDN_CA) | \
159 INT_MASK(INT_UDN_CA) | \
160 INT_MASK(INT_IDN_AVAIL) | \
161 INT_MASK(INT_UDN_AVAIL) | \
162 INT_MASK(INT_PERF_COUNT) | \
163 INT_MASK(INT_INTCTRL_3) | \
164 INT_MASK(INT_INTCTRL_2) | \
165 INT_MASK(INT_INTCTRL_1) | \
166 INT_MASK(INT_INTCTRL_0) | \
167 INT_MASK(INT_AUX_PERF_COUNT) | \
168 0)
169#define CRITICAL_UNMASKED_INTERRUPTS ( \
170 INT_MASK(INT_ITLB_MISS) | \
171 INT_MASK(INT_ILL) | \
172 INT_MASK(INT_GPV) | \
173 INT_MASK(INT_SN_ACCESS) | \
174 INT_MASK(INT_IDN_ACCESS) | \
175 INT_MASK(INT_UDN_ACCESS) | \
176 INT_MASK(INT_IDN_REFILL) | \
177 INT_MASK(INT_UDN_REFILL) | \
178 INT_MASK(INT_IDN_COMPLETE) | \
179 INT_MASK(INT_UDN_COMPLETE) | \
180 INT_MASK(INT_SWINT_3) | \
181 INT_MASK(INT_SWINT_2) | \
182 INT_MASK(INT_SWINT_1) | \
183 INT_MASK(INT_SWINT_0) | \
184 INT_MASK(INT_UNALIGN_DATA) | \
185 INT_MASK(INT_DTLB_MISS) | \
186 INT_MASK(INT_DTLB_ACCESS) | \
187 INT_MASK(INT_BOOT_ACCESS) | \
188 INT_MASK(INT_WORLD_ACCESS) | \
189 INT_MASK(INT_I_ASID) | \
190 INT_MASK(INT_D_ASID) | \
191 INT_MASK(INT_DMA_ASID) | \
192 INT_MASK(INT_SNI_ASID) | \
193 INT_MASK(INT_DMA_CPL) | \
194 INT_MASK(INT_SN_CPL) | \
195 INT_MASK(INT_DOUBLE_FAULT) | \
196 INT_MASK(INT_SN_STATIC_ACCESS) | \
197 0)
198#define MASKABLE_INTERRUPTS ( \
199 INT_MASK(INT_MEM_ERROR) | \
200 INT_MASK(INT_IDN_REFILL) | \
201 INT_MASK(INT_UDN_REFILL) | \
202 INT_MASK(INT_IDN_COMPLETE) | \
203 INT_MASK(INT_UDN_COMPLETE) | \
204 INT_MASK(INT_DMATLB_MISS) | \
205 INT_MASK(INT_DMATLB_ACCESS) | \
206 INT_MASK(INT_SNITLB_MISS) | \
207 INT_MASK(INT_SN_NOTIFY) | \
208 INT_MASK(INT_SN_FIREWALL) | \
209 INT_MASK(INT_IDN_FIREWALL) | \
210 INT_MASK(INT_UDN_FIREWALL) | \
211 INT_MASK(INT_TILE_TIMER) | \
212 INT_MASK(INT_IDN_TIMER) | \
213 INT_MASK(INT_UDN_TIMER) | \
214 INT_MASK(INT_DMA_NOTIFY) | \
215 INT_MASK(INT_IDN_CA) | \
216 INT_MASK(INT_UDN_CA) | \
217 INT_MASK(INT_IDN_AVAIL) | \
218 INT_MASK(INT_UDN_AVAIL) | \
219 INT_MASK(INT_PERF_COUNT) | \
220 INT_MASK(INT_INTCTRL_3) | \
221 INT_MASK(INT_INTCTRL_2) | \
222 INT_MASK(INT_INTCTRL_1) | \
223 INT_MASK(INT_INTCTRL_0) | \
224 INT_MASK(INT_AUX_PERF_COUNT) | \
225 0)
226#define UNMASKABLE_INTERRUPTS ( \
227 INT_MASK(INT_ITLB_MISS) | \
228 INT_MASK(INT_ILL) | \
229 INT_MASK(INT_GPV) | \
230 INT_MASK(INT_SN_ACCESS) | \
231 INT_MASK(INT_IDN_ACCESS) | \
232 INT_MASK(INT_UDN_ACCESS) | \
233 INT_MASK(INT_SWINT_3) | \
234 INT_MASK(INT_SWINT_2) | \
235 INT_MASK(INT_SWINT_1) | \
236 INT_MASK(INT_SWINT_0) | \
237 INT_MASK(INT_UNALIGN_DATA) | \
238 INT_MASK(INT_DTLB_MISS) | \
239 INT_MASK(INT_DTLB_ACCESS) | \
240 INT_MASK(INT_BOOT_ACCESS) | \
241 INT_MASK(INT_WORLD_ACCESS) | \
242 INT_MASK(INT_I_ASID) | \
243 INT_MASK(INT_D_ASID) | \
244 INT_MASK(INT_DMA_ASID) | \
245 INT_MASK(INT_SNI_ASID) | \
246 INT_MASK(INT_DMA_CPL) | \
247 INT_MASK(INT_SN_CPL) | \
248 INT_MASK(INT_DOUBLE_FAULT) | \
249 INT_MASK(INT_SN_STATIC_ACCESS) | \
250 0)
251#define SYNC_INTERRUPTS ( \
252 INT_MASK(INT_ITLB_MISS) | \
253 INT_MASK(INT_ILL) | \
254 INT_MASK(INT_GPV) | \
255 INT_MASK(INT_SN_ACCESS) | \
256 INT_MASK(INT_IDN_ACCESS) | \
257 INT_MASK(INT_UDN_ACCESS) | \
258 INT_MASK(INT_IDN_REFILL) | \
259 INT_MASK(INT_UDN_REFILL) | \
260 INT_MASK(INT_IDN_COMPLETE) | \
261 INT_MASK(INT_UDN_COMPLETE) | \
262 INT_MASK(INT_SWINT_3) | \
263 INT_MASK(INT_SWINT_2) | \
264 INT_MASK(INT_SWINT_1) | \
265 INT_MASK(INT_SWINT_0) | \
266 INT_MASK(INT_UNALIGN_DATA) | \
267 INT_MASK(INT_DTLB_MISS) | \
268 INT_MASK(INT_DTLB_ACCESS) | \
269 INT_MASK(INT_SN_STATIC_ACCESS) | \
270 0)
271#define NON_SYNC_INTERRUPTS ( \
272 INT_MASK(INT_MEM_ERROR) | \
273 INT_MASK(INT_DMATLB_MISS) | \
274 INT_MASK(INT_DMATLB_ACCESS) | \
275 INT_MASK(INT_SNITLB_MISS) | \
276 INT_MASK(INT_SN_NOTIFY) | \
277 INT_MASK(INT_SN_FIREWALL) | \
278 INT_MASK(INT_IDN_FIREWALL) | \
279 INT_MASK(INT_UDN_FIREWALL) | \
280 INT_MASK(INT_TILE_TIMER) | \
281 INT_MASK(INT_IDN_TIMER) | \
282 INT_MASK(INT_UDN_TIMER) | \
283 INT_MASK(INT_DMA_NOTIFY) | \
284 INT_MASK(INT_IDN_CA) | \
285 INT_MASK(INT_UDN_CA) | \
286 INT_MASK(INT_IDN_AVAIL) | \
287 INT_MASK(INT_UDN_AVAIL) | \
288 INT_MASK(INT_PERF_COUNT) | \
289 INT_MASK(INT_INTCTRL_3) | \
290 INT_MASK(INT_INTCTRL_2) | \
291 INT_MASK(INT_INTCTRL_1) | \
292 INT_MASK(INT_INTCTRL_0) | \
293 INT_MASK(INT_BOOT_ACCESS) | \
294 INT_MASK(INT_WORLD_ACCESS) | \
295 INT_MASK(INT_I_ASID) | \
296 INT_MASK(INT_D_ASID) | \
297 INT_MASK(INT_DMA_ASID) | \
298 INT_MASK(INT_SNI_ASID) | \
299 INT_MASK(INT_DMA_CPL) | \
300 INT_MASK(INT_SN_CPL) | \
301 INT_MASK(INT_DOUBLE_FAULT) | \
302 INT_MASK(INT_AUX_PERF_COUNT) | \
303 0)
304#endif /* !__ARCH_INTERRUPTS_H__ */
diff --git a/arch/tile/include/arch/sim_def.h b/arch/tile/include/arch/sim_def.h
new file mode 100644
index 000000000000..6418fbde063e
--- /dev/null
+++ b/arch/tile/include/arch/sim_def.h
@@ -0,0 +1,512 @@
1// Copyright 2010 Tilera Corporation. All Rights Reserved.
2//
3// This program is free software; you can redistribute it and/or
4// modify it under the terms of the GNU General Public License
5// as published by the Free Software Foundation, version 2.
6//
7// This program is distributed in the hope that it will be useful, but
8// WITHOUT ANY WARRANTY; without even the implied warranty of
9// MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, GOOD TITLE or
10// NON INFRINGEMENT. See the GNU General Public License for
11// more details.
12
13//! @file
14//!
15//! Some low-level simulator definitions.
16//!
17
18#ifndef __ARCH_SIM_DEF_H__
19#define __ARCH_SIM_DEF_H__
20
21
22//! Internal: the low bits of the SIM_CONTROL_* SPR values specify
23//! the operation to perform, and the remaining bits are
24//! an operation-specific parameter (often unused).
25//!
26#define _SIM_CONTROL_OPERATOR_BITS 8
27
28
29//== Values which can be written to SPR_SIM_CONTROL.
30
31//! If written to SPR_SIM_CONTROL, stops profiling.
32//!
33#define SIM_CONTROL_PROFILER_DISABLE 0
34
35//! If written to SPR_SIM_CONTROL, starts profiling.
36//!
37#define SIM_CONTROL_PROFILER_ENABLE 1
38
39//! If written to SPR_SIM_CONTROL, clears profiling counters.
40//!
41#define SIM_CONTROL_PROFILER_CLEAR 2
42
43//! If written to SPR_SIM_CONTROL, checkpoints the simulator.
44//!
45#define SIM_CONTROL_CHECKPOINT 3
46
47//! If written to SPR_SIM_CONTROL, combined with a mask (shifted by 8),
48//! sets the tracing mask to the given mask. See "sim_set_tracing()".
49//!
50#define SIM_CONTROL_SET_TRACING 4
51
52//! If written to SPR_SIM_CONTROL, combined with a mask (shifted by 8),
53//! dumps the requested items of machine state to the log.
54//!
55#define SIM_CONTROL_DUMP 5
56
57//! If written to SPR_SIM_CONTROL, clears chip-level profiling counters.
58//!
59#define SIM_CONTROL_PROFILER_CHIP_CLEAR 6
60
61//! If written to SPR_SIM_CONTROL, disables chip-level profiling.
62//!
63#define SIM_CONTROL_PROFILER_CHIP_DISABLE 7
64
65//! If written to SPR_SIM_CONTROL, enables chip-level profiling.
66//!
67#define SIM_CONTROL_PROFILER_CHIP_ENABLE 8
68
69//! If written to SPR_SIM_CONTROL, enables chip-level functional mode
70//!
71#define SIM_CONTROL_ENABLE_FUNCTIONAL 9
72
73//! If written to SPR_SIM_CONTROL, disables chip-level functional mode.
74//!
75#define SIM_CONTROL_DISABLE_FUNCTIONAL 10
76
77//! If written to SPR_SIM_CONTROL, enables chip-level functional mode.
78//! All tiles must perform this write for functional mode to be enabled.
79//! Ignored in naked boot mode unless --functional is specified.
80//! WARNING: Only the hypervisor startup code should use this!
81//!
82#define SIM_CONTROL_ENABLE_FUNCTIONAL_BARRIER 11
83
84//! If written to SPR_SIM_CONTROL, combined with a character (shifted by 8),
85//! writes a string directly to the simulator output. Written to once for
86//! each character in the string, plus a final NUL. Instead of NUL,
87//! you can also use "SIM_PUTC_FLUSH_STRING" or "SIM_PUTC_FLUSH_BINARY".
88//!
89// ISSUE: Document the meaning of "newline", and the handling of NUL.
90//
91#define SIM_CONTROL_PUTC 12
92
93//! If written to SPR_SIM_CONTROL, clears the --grind-coherence state for
94//! this core. This is intended to be used before a loop that will
95//! invalidate the cache by loading new data and evicting all current data.
96//! Generally speaking, this API should only be used by system code.
97//!
98#define SIM_CONTROL_GRINDER_CLEAR 13
99
100//! If written to SPR_SIM_CONTROL, shuts down the simulator.
101//!
102#define SIM_CONTROL_SHUTDOWN 14
103
104//! If written to SPR_SIM_CONTROL, combined with a pid (shifted by 8),
105//! indicates that a fork syscall just created the given process.
106//!
107#define SIM_CONTROL_OS_FORK 15
108
109//! If written to SPR_SIM_CONTROL, combined with a pid (shifted by 8),
110//! indicates that an exit syscall was just executed by the given process.
111//!
112#define SIM_CONTROL_OS_EXIT 16
113
114//! If written to SPR_SIM_CONTROL, combined with a pid (shifted by 8),
115//! indicates that the OS just switched to the given process.
116//!
117#define SIM_CONTROL_OS_SWITCH 17
118
119//! If written to SPR_SIM_CONTROL, combined with a character (shifted by 8),
120//! indicates that an exec syscall was just executed. Written to once for
121//! each character in the executable name, plus a final NUL.
122//!
123#define SIM_CONTROL_OS_EXEC 18
124
125//! If written to SPR_SIM_CONTROL, combined with a character (shifted by 8),
126//! indicates that an interpreter (PT_INTERP) was loaded. Written to once
127//! for each character in "ADDR:PATH", plus a final NUL, where "ADDR" is a
128//! hex load address starting with "0x", and "PATH" is the executable name.
129//!
130#define SIM_CONTROL_OS_INTERP 19
131
132//! If written to SPR_SIM_CONTROL, combined with a character (shifted by 8),
133//! indicates that a dll was loaded. Written to once for each character
134//! in "ADDR:PATH", plus a final NUL, where "ADDR" is a hexadecimal load
135//! address starting with "0x", and "PATH" is the executable name.
136//!
137#define SIM_CONTROL_DLOPEN 20
138
139//! If written to SPR_SIM_CONTROL, combined with a character (shifted by 8),
140//! indicates that a dll was unloaded. Written to once for each character
141//! in "ADDR", plus a final NUL, where "ADDR" is a hexadecimal load
142//! address starting with "0x".
143//!
144#define SIM_CONTROL_DLCLOSE 21
145
146//! If written to SPR_SIM_CONTROL, combined with a flag (shifted by 8),
147//! indicates whether to allow data reads to remotely-cached
148//! dirty cache lines to be cached locally without grinder warnings or
149//! assertions (used by Linux kernel fast memcpy).
150//!
151#define SIM_CONTROL_ALLOW_MULTIPLE_CACHING 22
152
153//! If written to SPR_SIM_CONTROL, enables memory tracing.
154//!
155#define SIM_CONTROL_ENABLE_MEM_LOGGING 23
156
157//! If written to SPR_SIM_CONTROL, disables memory tracing.
158//!
159#define SIM_CONTROL_DISABLE_MEM_LOGGING 24
160
161//! If written to SPR_SIM_CONTROL, changes the shaping parameters of one of
162//! the gbe or xgbe shims. Must specify the shim id, the type, the units, and
163//! the rate, as defined in SIM_SHAPING_SPR_ARG.
164//!
165#define SIM_CONTROL_SHAPING 25
166
167//! If written to SPR_SIM_CONTROL, combined with character (shifted by 8),
168//! requests that a simulator command be executed. Written to once for each
169//! character in the command, plus a final NUL.
170//!
171#define SIM_CONTROL_COMMAND 26
172
173//! If written to SPR_SIM_CONTROL, indicates that the simulated system
174//! is panicking, to allow debugging via --debug-on-panic.
175//!
176#define SIM_CONTROL_PANIC 27
177
178//! If written to SPR_SIM_CONTROL, triggers a simulator syscall.
179//! See "sim_syscall()" for more info.
180//!
181#define SIM_CONTROL_SYSCALL 32
182
183//! If written to SPR_SIM_CONTROL, combined with a pid (shifted by 8),
184//! provides the pid that subsequent SIM_CONTROL_OS_FORK writes should
185//! use as the pid, rather than the default previous SIM_CONTROL_OS_SWITCH.
186//!
187#define SIM_CONTROL_OS_FORK_PARENT 33
188
189//! If written to SPR_SIM_CONTROL, combined with a mPIPE shim number
190//! (shifted by 8), clears the pending magic data section. The cleared
191//! pending magic data section and any subsequently appended magic bytes
192//! will only take effect when the classifier blast programmer is run.
193#define SIM_CONTROL_CLEAR_MPIPE_MAGIC_BYTES 34
194
195//! If written to SPR_SIM_CONTROL, combined with a mPIPE shim number
196//! (shifted by 8) and a byte of data (shifted by 16), appends that byte
197//! to the shim's pending magic data section. The pending magic data
198//! section takes effect when the classifier blast programmer is run.
199#define SIM_CONTROL_APPEND_MPIPE_MAGIC_BYTE 35
200
201//! If written to SPR_SIM_CONTROL, combined with a mPIPE shim number
202//! (shifted by 8), an enable=1/disable=0 bit (shifted by 16), and a
203//! mask of links (shifted by 32), enable or disable the corresponding
204//! mPIPE links.
205#define SIM_CONTROL_ENABLE_MPIPE_LINK_MAGIC_BYTE 36
206
207//== Syscall numbers for use with "sim_syscall()".
208
209//! Syscall number for sim_add_watchpoint().
210//!
211#define SIM_SYSCALL_ADD_WATCHPOINT 2
212
213//! Syscall number for sim_remove_watchpoint().
214//!
215#define SIM_SYSCALL_REMOVE_WATCHPOINT 3
216
217//! Syscall number for sim_query_watchpoint().
218//!
219#define SIM_SYSCALL_QUERY_WATCHPOINT 4
220
221//! Syscall number that asserts that the cache lines whose 64-bit PA
222//! is passed as the second argument to sim_syscall(), and over a
223//! range passed as the third argument, are no longer in cache.
224//! The simulator raises an error if this is not the case.
225//!
226#define SIM_SYSCALL_VALIDATE_LINES_EVICTED 5
227
228
229//== Bit masks which can be shifted by 8, combined with
230//== SIM_CONTROL_SET_TRACING, and written to SPR_SIM_CONTROL.
231
232//! @addtogroup arch_sim
233//! @{
234
235//! Enable --trace-cycle when passed to simulator_set_tracing().
236//!
237#define SIM_TRACE_CYCLES 0x01
238
239//! Enable --trace-router when passed to simulator_set_tracing().
240//!
241#define SIM_TRACE_ROUTER 0x02
242
243//! Enable --trace-register-writes when passed to simulator_set_tracing().
244//!
245#define SIM_TRACE_REGISTER_WRITES 0x04
246
247//! Enable --trace-disasm when passed to simulator_set_tracing().
248//!
249#define SIM_TRACE_DISASM 0x08
250
251//! Enable --trace-stall-info when passed to simulator_set_tracing().
252//!
253#define SIM_TRACE_STALL_INFO 0x10
254
255//! Enable --trace-memory-controller when passed to simulator_set_tracing().
256//!
257#define SIM_TRACE_MEMORY_CONTROLLER 0x20
258
259//! Enable --trace-l2 when passed to simulator_set_tracing().
260//!
261#define SIM_TRACE_L2_CACHE 0x40
262
263//! Enable --trace-lines when passed to simulator_set_tracing().
264//!
265#define SIM_TRACE_LINES 0x80
266
267//! Turn off all tracing when passed to simulator_set_tracing().
268//!
269#define SIM_TRACE_NONE 0
270
271//! Turn on all tracing when passed to simulator_set_tracing().
272//!
273#define SIM_TRACE_ALL (-1)
274
275//! @}
276
277//! Computes the value to write to SPR_SIM_CONTROL to set tracing flags.
278//!
279#define SIM_TRACE_SPR_ARG(mask) \
280 (SIM_CONTROL_SET_TRACING | ((mask) << _SIM_CONTROL_OPERATOR_BITS))
281
282
283//== Bit masks which can be shifted by 8, combined with
284//== SIM_CONTROL_DUMP, and written to SPR_SIM_CONTROL.
285
286//! @addtogroup arch_sim
287//! @{
288
289//! Dump the general-purpose registers.
290//!
291#define SIM_DUMP_REGS 0x001
292
293//! Dump the SPRs.
294//!
295#define SIM_DUMP_SPRS 0x002
296
297//! Dump the ITLB.
298//!
299#define SIM_DUMP_ITLB 0x004
300
301//! Dump the DTLB.
302//!
303#define SIM_DUMP_DTLB 0x008
304
305//! Dump the L1 I-cache.
306//!
307#define SIM_DUMP_L1I 0x010
308
309//! Dump the L1 D-cache.
310//!
311#define SIM_DUMP_L1D 0x020
312
313//! Dump the L2 cache.
314//!
315#define SIM_DUMP_L2 0x040
316
317//! Dump the switch registers.
318//!
319#define SIM_DUMP_SNREGS 0x080
320
321//! Dump the switch ITLB.
322//!
323#define SIM_DUMP_SNITLB 0x100
324
325//! Dump the switch L1 I-cache.
326//!
327#define SIM_DUMP_SNL1I 0x200
328
329//! Dump the current backtrace.
330//!
331#define SIM_DUMP_BACKTRACE 0x400
332
333//! Only dump valid lines in caches.
334//!
335#define SIM_DUMP_VALID_LINES 0x800
336
337//! Dump everything that is dumpable.
338//!
339#define SIM_DUMP_ALL (-1 & ~SIM_DUMP_VALID_LINES)
340
341// @}
342
343//! Computes the value to write to SPR_SIM_CONTROL to dump machine state.
344//!
345#define SIM_DUMP_SPR_ARG(mask) \
346 (SIM_CONTROL_DUMP | ((mask) << _SIM_CONTROL_OPERATOR_BITS))
347
348
349//== Bit masks which can be shifted by 8, combined with
350//== SIM_CONTROL_PROFILER_CHIP_xxx, and written to SPR_SIM_CONTROL.
351
352//! @addtogroup arch_sim
353//! @{
354
355//! Use with with SIM_PROFILER_CHIP_xxx to control the memory controllers.
356//!
357#define SIM_CHIP_MEMCTL 0x001
358
359//! Use with with SIM_PROFILER_CHIP_xxx to control the XAUI interface.
360//!
361#define SIM_CHIP_XAUI 0x002
362
363//! Use with with SIM_PROFILER_CHIP_xxx to control the PCIe interface.
364//!
365#define SIM_CHIP_PCIE 0x004
366
367//! Use with with SIM_PROFILER_CHIP_xxx to control the MPIPE interface.
368//!
369#define SIM_CHIP_MPIPE 0x008
370
371//! Reference all chip devices.
372//!
373#define SIM_CHIP_ALL (-1)
374
375//! @}
376
377//! Computes the value to write to SPR_SIM_CONTROL to clear chip statistics.
378//!
379#define SIM_PROFILER_CHIP_CLEAR_SPR_ARG(mask) \
380 (SIM_CONTROL_PROFILER_CHIP_CLEAR | ((mask) << _SIM_CONTROL_OPERATOR_BITS))
381
382//! Computes the value to write to SPR_SIM_CONTROL to disable chip statistics.
383//!
384#define SIM_PROFILER_CHIP_DISABLE_SPR_ARG(mask) \
385 (SIM_CONTROL_PROFILER_CHIP_DISABLE | ((mask) << _SIM_CONTROL_OPERATOR_BITS))
386
387//! Computes the value to write to SPR_SIM_CONTROL to enable chip statistics.
388//!
389#define SIM_PROFILER_CHIP_ENABLE_SPR_ARG(mask) \
390 (SIM_CONTROL_PROFILER_CHIP_ENABLE | ((mask) << _SIM_CONTROL_OPERATOR_BITS))
391
392
393
394// Shim bitrate controls.
395
396//! The number of bits used to store the shim id.
397//!
398#define SIM_CONTROL_SHAPING_SHIM_ID_BITS 3
399
400//! @addtogroup arch_sim
401//! @{
402
403//! Change the gbe 0 bitrate.
404//!
405#define SIM_CONTROL_SHAPING_GBE_0 0x0
406
407//! Change the gbe 1 bitrate.
408//!
409#define SIM_CONTROL_SHAPING_GBE_1 0x1
410
411//! Change the gbe 2 bitrate.
412//!
413#define SIM_CONTROL_SHAPING_GBE_2 0x2
414
415//! Change the gbe 3 bitrate.
416//!
417#define SIM_CONTROL_SHAPING_GBE_3 0x3
418
419//! Change the xgbe 0 bitrate.
420//!
421#define SIM_CONTROL_SHAPING_XGBE_0 0x4
422
423//! Change the xgbe 1 bitrate.
424//!
425#define SIM_CONTROL_SHAPING_XGBE_1 0x5
426
427//! The type of shaping to do.
428//!
429#define SIM_CONTROL_SHAPING_TYPE_BITS 2
430
431//! Control the multiplier.
432//!
433#define SIM_CONTROL_SHAPING_MULTIPLIER 0
434
435//! Control the PPS.
436//!
437#define SIM_CONTROL_SHAPING_PPS 1
438
439//! Control the BPS.
440//!
441#define SIM_CONTROL_SHAPING_BPS 2
442
443//! The number of bits for the units for the shaping parameter.
444//!
445#define SIM_CONTROL_SHAPING_UNITS_BITS 2
446
447//! Provide a number in single units.
448//!
449#define SIM_CONTROL_SHAPING_UNITS_SINGLE 0
450
451//! Provide a number in kilo units.
452//!
453#define SIM_CONTROL_SHAPING_UNITS_KILO 1
454
455//! Provide a number in mega units.
456//!
457#define SIM_CONTROL_SHAPING_UNITS_MEGA 2
458
459//! Provide a number in giga units.
460//!
461#define SIM_CONTROL_SHAPING_UNITS_GIGA 3
462
463// @}
464
465//! How many bits are available for the rate.
466//!
467#define SIM_CONTROL_SHAPING_RATE_BITS \
468 (32 - (_SIM_CONTROL_OPERATOR_BITS + \
469 SIM_CONTROL_SHAPING_SHIM_ID_BITS + \
470 SIM_CONTROL_SHAPING_TYPE_BITS + \
471 SIM_CONTROL_SHAPING_UNITS_BITS))
472
473//! Computes the value to write to SPR_SIM_CONTROL to change a bitrate.
474//!
475#define SIM_SHAPING_SPR_ARG(shim, type, units, rate) \
476 (SIM_CONTROL_SHAPING | \
477 ((shim) | \
478 ((type) << (SIM_CONTROL_SHAPING_SHIM_ID_BITS)) | \
479 ((units) << (SIM_CONTROL_SHAPING_SHIM_ID_BITS + \
480 SIM_CONTROL_SHAPING_TYPE_BITS)) | \
481 ((rate) << (SIM_CONTROL_SHAPING_SHIM_ID_BITS + \
482 SIM_CONTROL_SHAPING_TYPE_BITS + \
483 SIM_CONTROL_SHAPING_UNITS_BITS))) << _SIM_CONTROL_OPERATOR_BITS)
484
485
486//== Values returned when reading SPR_SIM_CONTROL.
487// ISSUE: These names should share a longer common prefix.
488
489//! When reading SPR_SIM_CONTROL, the mask of simulator tracing bits
490//! (SIM_TRACE_xxx values).
491//!
492#define SIM_TRACE_FLAG_MASK 0xFFFF
493
494//! When reading SPR_SIM_CONTROL, the mask for whether profiling is enabled.
495//!
496#define SIM_PROFILER_ENABLED_MASK 0x10000
497
498
499//== Special arguments for "SIM_CONTROL_PUTC".
500
501//! Flag value for forcing a PUTC string-flush, including
502//! coordinate/cycle prefix and newline.
503//!
504#define SIM_PUTC_FLUSH_STRING 0x100
505
506//! Flag value for forcing a PUTC binary-data-flush, which skips the
507//! prefix and does not append a newline.
508//!
509#define SIM_PUTC_FLUSH_BINARY 0x101
510
511
512#endif //__ARCH_SIM_DEF_H__
diff --git a/arch/tile/include/arch/spr_def.h b/arch/tile/include/arch/spr_def.h
new file mode 100644
index 000000000000..c8fdbd9a45e6
--- /dev/null
+++ b/arch/tile/include/arch/spr_def.h
@@ -0,0 +1,19 @@
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#ifdef __tilegx__
16#include <arch/spr_def_64.h>
17#else
18#include <arch/spr_def_32.h>
19#endif
diff --git a/arch/tile/include/arch/spr_def_32.h b/arch/tile/include/arch/spr_def_32.h
new file mode 100644
index 000000000000..b4fc06864df6
--- /dev/null
+++ b/arch/tile/include/arch/spr_def_32.h
@@ -0,0 +1,162 @@
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 __DOXYGEN__
16
17#ifndef __ARCH_SPR_DEF_H__
18#define __ARCH_SPR_DEF_H__
19
20#define SPR_AUX_PERF_COUNT_0 0x6005
21#define SPR_AUX_PERF_COUNT_1 0x6006
22#define SPR_AUX_PERF_COUNT_CTL 0x6007
23#define SPR_AUX_PERF_COUNT_STS 0x6008
24#define SPR_CYCLE_HIGH 0x4e06
25#define SPR_CYCLE_LOW 0x4e07
26#define SPR_DMA_BYTE 0x3900
27#define SPR_DMA_CHUNK_SIZE 0x3901
28#define SPR_DMA_CTR 0x3902
29#define SPR_DMA_CTR__REQUEST_MASK 0x1
30#define SPR_DMA_CTR__SUSPEND_MASK 0x2
31#define SPR_DMA_DST_ADDR 0x3903
32#define SPR_DMA_DST_CHUNK_ADDR 0x3904
33#define SPR_DMA_SRC_ADDR 0x3905
34#define SPR_DMA_SRC_CHUNK_ADDR 0x3906
35#define SPR_DMA_STATUS__DONE_MASK 0x1
36#define SPR_DMA_STATUS__BUSY_MASK 0x2
37#define SPR_DMA_STATUS__RUNNING_MASK 0x10
38#define SPR_DMA_STRIDE 0x3907
39#define SPR_DMA_USER_STATUS 0x3908
40#define SPR_DONE 0x4e08
41#define SPR_EVENT_BEGIN 0x4e0d
42#define SPR_EVENT_END 0x4e0e
43#define SPR_EX_CONTEXT_0_0 0x4a05
44#define SPR_EX_CONTEXT_0_1 0x4a06
45#define SPR_EX_CONTEXT_0_1__PL_SHIFT 0
46#define SPR_EX_CONTEXT_0_1__PL_RMASK 0x3
47#define SPR_EX_CONTEXT_0_1__PL_MASK 0x3
48#define SPR_EX_CONTEXT_0_1__ICS_SHIFT 2
49#define SPR_EX_CONTEXT_0_1__ICS_RMASK 0x1
50#define SPR_EX_CONTEXT_0_1__ICS_MASK 0x4
51#define SPR_EX_CONTEXT_1_0 0x4805
52#define SPR_EX_CONTEXT_1_1 0x4806
53#define SPR_EX_CONTEXT_1_1__PL_SHIFT 0
54#define SPR_EX_CONTEXT_1_1__PL_RMASK 0x3
55#define SPR_EX_CONTEXT_1_1__PL_MASK 0x3
56#define SPR_EX_CONTEXT_1_1__ICS_SHIFT 2
57#define SPR_EX_CONTEXT_1_1__ICS_RMASK 0x1
58#define SPR_EX_CONTEXT_1_1__ICS_MASK 0x4
59#define SPR_FAIL 0x4e09
60#define SPR_INTCTRL_0_STATUS 0x4a07
61#define SPR_INTCTRL_1_STATUS 0x4807
62#define SPR_INTERRUPT_CRITICAL_SECTION 0x4e0a
63#define SPR_INTERRUPT_MASK_0_0 0x4a08
64#define SPR_INTERRUPT_MASK_0_1 0x4a09
65#define SPR_INTERRUPT_MASK_1_0 0x4809
66#define SPR_INTERRUPT_MASK_1_1 0x480a
67#define SPR_INTERRUPT_MASK_RESET_0_0 0x4a0a
68#define SPR_INTERRUPT_MASK_RESET_0_1 0x4a0b
69#define SPR_INTERRUPT_MASK_RESET_1_0 0x480b
70#define SPR_INTERRUPT_MASK_RESET_1_1 0x480c
71#define SPR_INTERRUPT_MASK_SET_0_0 0x4a0c
72#define SPR_INTERRUPT_MASK_SET_0_1 0x4a0d
73#define SPR_INTERRUPT_MASK_SET_1_0 0x480d
74#define SPR_INTERRUPT_MASK_SET_1_1 0x480e
75#define SPR_MPL_DMA_CPL_SET_0 0x5800
76#define SPR_MPL_DMA_CPL_SET_1 0x5801
77#define SPR_MPL_DMA_NOTIFY_SET_0 0x3800
78#define SPR_MPL_DMA_NOTIFY_SET_1 0x3801
79#define SPR_MPL_INTCTRL_0_SET_0 0x4a00
80#define SPR_MPL_INTCTRL_0_SET_1 0x4a01
81#define SPR_MPL_INTCTRL_1_SET_0 0x4800
82#define SPR_MPL_INTCTRL_1_SET_1 0x4801
83#define SPR_MPL_SN_ACCESS_SET_0 0x0800
84#define SPR_MPL_SN_ACCESS_SET_1 0x0801
85#define SPR_MPL_SN_CPL_SET_0 0x5a00
86#define SPR_MPL_SN_CPL_SET_1 0x5a01
87#define SPR_MPL_SN_FIREWALL_SET_0 0x2c00
88#define SPR_MPL_SN_FIREWALL_SET_1 0x2c01
89#define SPR_MPL_SN_NOTIFY_SET_0 0x2a00
90#define SPR_MPL_SN_NOTIFY_SET_1 0x2a01
91#define SPR_MPL_UDN_ACCESS_SET_0 0x0c00
92#define SPR_MPL_UDN_ACCESS_SET_1 0x0c01
93#define SPR_MPL_UDN_AVAIL_SET_0 0x4000
94#define SPR_MPL_UDN_AVAIL_SET_1 0x4001
95#define SPR_MPL_UDN_CA_SET_0 0x3c00
96#define SPR_MPL_UDN_CA_SET_1 0x3c01
97#define SPR_MPL_UDN_COMPLETE_SET_0 0x1400
98#define SPR_MPL_UDN_COMPLETE_SET_1 0x1401
99#define SPR_MPL_UDN_FIREWALL_SET_0 0x3000
100#define SPR_MPL_UDN_FIREWALL_SET_1 0x3001
101#define SPR_MPL_UDN_REFILL_SET_0 0x1000
102#define SPR_MPL_UDN_REFILL_SET_1 0x1001
103#define SPR_MPL_UDN_TIMER_SET_0 0x3600
104#define SPR_MPL_UDN_TIMER_SET_1 0x3601
105#define SPR_MPL_WORLD_ACCESS_SET_0 0x4e00
106#define SPR_MPL_WORLD_ACCESS_SET_1 0x4e01
107#define SPR_PASS 0x4e0b
108#define SPR_PERF_COUNT_0 0x4205
109#define SPR_PERF_COUNT_1 0x4206
110#define SPR_PERF_COUNT_CTL 0x4207
111#define SPR_PERF_COUNT_STS 0x4208
112#define SPR_PROC_STATUS 0x4f00
113#define SPR_SIM_CONTROL 0x4e0c
114#define SPR_SNCTL 0x0805
115#define SPR_SNCTL__FRZFABRIC_MASK 0x1
116#define SPR_SNCTL__FRZPROC_MASK 0x2
117#define SPR_SNPC 0x080b
118#define SPR_SNSTATIC 0x080c
119#define SPR_SYSTEM_SAVE_0_0 0x4b00
120#define SPR_SYSTEM_SAVE_0_1 0x4b01
121#define SPR_SYSTEM_SAVE_0_2 0x4b02
122#define SPR_SYSTEM_SAVE_0_3 0x4b03
123#define SPR_SYSTEM_SAVE_1_0 0x4900
124#define SPR_SYSTEM_SAVE_1_1 0x4901
125#define SPR_SYSTEM_SAVE_1_2 0x4902
126#define SPR_SYSTEM_SAVE_1_3 0x4903
127#define SPR_TILE_COORD 0x4c17
128#define SPR_TILE_RTF_HWM 0x4e10
129#define SPR_TILE_TIMER_CONTROL 0x3205
130#define SPR_TILE_WRITE_PENDING 0x4e0f
131#define SPR_UDN_AVAIL_EN 0x4005
132#define SPR_UDN_CA_DATA 0x0d00
133#define SPR_UDN_DATA_AVAIL 0x0d03
134#define SPR_UDN_DEADLOCK_TIMEOUT 0x3606
135#define SPR_UDN_DEMUX_CA_COUNT 0x0c05
136#define SPR_UDN_DEMUX_COUNT_0 0x0c06
137#define SPR_UDN_DEMUX_COUNT_1 0x0c07
138#define SPR_UDN_DEMUX_COUNT_2 0x0c08
139#define SPR_UDN_DEMUX_COUNT_3 0x0c09
140#define SPR_UDN_DEMUX_CTL 0x0c0a
141#define SPR_UDN_DEMUX_QUEUE_SEL 0x0c0c
142#define SPR_UDN_DEMUX_STATUS 0x0c0d
143#define SPR_UDN_DEMUX_WRITE_FIFO 0x0c0e
144#define SPR_UDN_DIRECTION_PROTECT 0x3005
145#define SPR_UDN_REFILL_EN 0x1005
146#define SPR_UDN_SP_FIFO_DATA 0x0c11
147#define SPR_UDN_SP_FIFO_SEL 0x0c12
148#define SPR_UDN_SP_FREEZE 0x0c13
149#define SPR_UDN_SP_FREEZE__SP_FRZ_MASK 0x1
150#define SPR_UDN_SP_FREEZE__DEMUX_FRZ_MASK 0x2
151#define SPR_UDN_SP_FREEZE__NON_DEST_EXT_MASK 0x4
152#define SPR_UDN_SP_STATE 0x0c14
153#define SPR_UDN_TAG_0 0x0c15
154#define SPR_UDN_TAG_1 0x0c16
155#define SPR_UDN_TAG_2 0x0c17
156#define SPR_UDN_TAG_3 0x0c18
157#define SPR_UDN_TAG_VALID 0x0c19
158#define SPR_UDN_TILE_COORD 0x0c1a
159
160#endif /* !defined(__ARCH_SPR_DEF_H__) */
161
162#endif /* !defined(__DOXYGEN__) */
diff --git a/arch/tile/include/asm/Kbuild b/arch/tile/include/asm/Kbuild
new file mode 100644
index 000000000000..3b8f55b82dee
--- /dev/null
+++ b/arch/tile/include/asm/Kbuild
@@ -0,0 +1,3 @@
1include include/asm-generic/Kbuild.asm
2
3header-y += ucontext.h
diff --git a/arch/tile/include/asm/asm-offsets.h b/arch/tile/include/asm/asm-offsets.h
new file mode 100644
index 000000000000..d370ee36a182
--- /dev/null
+++ b/arch/tile/include/asm/asm-offsets.h
@@ -0,0 +1 @@
#include <generated/asm-offsets.h>
diff --git a/arch/tile/include/asm/atomic.h b/arch/tile/include/asm/atomic.h
new file mode 100644
index 000000000000..b8c49f98a44c
--- /dev/null
+++ b/arch/tile/include/asm/atomic.h
@@ -0,0 +1,159 @@
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 * Atomic primitives.
15 */
16
17#ifndef _ASM_TILE_ATOMIC_H
18#define _ASM_TILE_ATOMIC_H
19
20#ifndef __ASSEMBLY__
21
22#include <linux/compiler.h>
23#include <asm/system.h>
24
25#define ATOMIC_INIT(i) { (i) }
26
27/**
28 * atomic_read - read atomic variable
29 * @v: pointer of type atomic_t
30 *
31 * Atomically reads the value of @v.
32 */
33static inline int atomic_read(const atomic_t *v)
34{
35 return v->counter;
36}
37
38/**
39 * atomic_sub_return - subtract integer and return
40 * @v: pointer of type atomic_t
41 * @i: integer value to subtract
42 *
43 * Atomically subtracts @i from @v and returns @v - @i
44 */
45#define atomic_sub_return(i, v) atomic_add_return((int)(-(i)), (v))
46
47/**
48 * atomic_sub - subtract integer from atomic variable
49 * @i: integer value to subtract
50 * @v: pointer of type atomic_t
51 *
52 * Atomically subtracts @i from @v.
53 */
54#define atomic_sub(i, v) atomic_add((int)(-(i)), (v))
55
56/**
57 * atomic_sub_and_test - subtract value from variable and test result
58 * @i: integer value to subtract
59 * @v: pointer of type atomic_t
60 *
61 * Atomically subtracts @i from @v and returns true if the result is
62 * zero, or false for all other cases.
63 */
64#define atomic_sub_and_test(i, v) (atomic_sub_return((i), (v)) == 0)
65
66/**
67 * atomic_inc_return - increment memory and return
68 * @v: pointer of type atomic_t
69 *
70 * Atomically increments @v by 1 and returns the new value.
71 */
72#define atomic_inc_return(v) atomic_add_return(1, (v))
73
74/**
75 * atomic_dec_return - decrement memory and return
76 * @v: pointer of type atomic_t
77 *
78 * Atomically decrements @v by 1 and returns the new value.
79 */
80#define atomic_dec_return(v) atomic_sub_return(1, (v))
81
82/**
83 * atomic_inc - increment atomic variable
84 * @v: pointer of type atomic_t
85 *
86 * Atomically increments @v by 1.
87 */
88#define atomic_inc(v) atomic_add(1, (v))
89
90/**
91 * atomic_dec - decrement atomic variable
92 * @v: pointer of type atomic_t
93 *
94 * Atomically decrements @v by 1.
95 */
96#define atomic_dec(v) atomic_sub(1, (v))
97
98/**
99 * atomic_dec_and_test - decrement and test
100 * @v: pointer of type atomic_t
101 *
102 * Atomically decrements @v by 1 and returns true if the result is 0.
103 */
104#define atomic_dec_and_test(v) (atomic_dec_return(v) == 0)
105
106/**
107 * atomic_inc_and_test - increment and test
108 * @v: pointer of type atomic_t
109 *
110 * Atomically increments @v by 1 and returns true if the result is 0.
111 */
112#define atomic_inc_and_test(v) (atomic_inc_return(v) == 0)
113
114/**
115 * atomic_add_negative - add and test if negative
116 * @v: pointer of type atomic_t
117 * @i: integer value to add
118 *
119 * Atomically adds @i to @v and returns true if the result is
120 * negative, or false when result is greater than or equal to zero.
121 */
122#define atomic_add_negative(i, v) (atomic_add_return((i), (v)) < 0)
123
124/**
125 * atomic_inc_not_zero - increment unless the number is zero
126 * @v: pointer of type atomic_t
127 *
128 * Atomically increments @v by 1, so long as @v is non-zero.
129 * Returns non-zero if @v was non-zero, and zero otherwise.
130 */
131#define atomic_inc_not_zero(v) atomic_add_unless((v), 1, 0)
132
133
134/*
135 * We define xchg() and cmpxchg() in the included headers.
136 * Note that we do not define __HAVE_ARCH_CMPXCHG, since that would imply
137 * that cmpxchg() is an efficient operation, which is not particularly true.
138 */
139
140/* Nonexistent functions intended to cause link errors. */
141extern unsigned long __xchg_called_with_bad_pointer(void);
142extern unsigned long __cmpxchg_called_with_bad_pointer(void);
143
144#define tas(ptr) (xchg((ptr), 1))
145
146#endif /* __ASSEMBLY__ */
147
148#ifndef __tilegx__
149#include <asm/atomic_32.h>
150#else
151#include <asm/atomic_64.h>
152#endif
153
154/* Provide the appropriate atomic_long_t definitions. */
155#ifndef __ASSEMBLY__
156#include <asm-generic/atomic-long.h>
157#endif
158
159#endif /* _ASM_TILE_ATOMIC_H */
diff --git a/arch/tile/include/asm/atomic_32.h b/arch/tile/include/asm/atomic_32.h
new file mode 100644
index 000000000000..ed359aee8837
--- /dev/null
+++ b/arch/tile/include/asm/atomic_32.h
@@ -0,0 +1,333 @@
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 * Do not include directly; use <asm/atomic.h>.
15 */
16
17#ifndef _ASM_TILE_ATOMIC_32_H
18#define _ASM_TILE_ATOMIC_32_H
19
20#include <arch/chip.h>
21
22#ifndef __ASSEMBLY__
23
24/* Tile-specific routines to support <asm/atomic.h>. */
25int _atomic_xchg(atomic_t *v, int n);
26int _atomic_xchg_add(atomic_t *v, int i);
27int _atomic_xchg_add_unless(atomic_t *v, int a, int u);
28int _atomic_cmpxchg(atomic_t *v, int o, int n);
29
30/**
31 * atomic_xchg - atomically exchange contents of memory with a new value
32 * @v: pointer of type atomic_t
33 * @i: integer value to store in memory
34 *
35 * Atomically sets @v to @i and returns old @v
36 */
37static inline int atomic_xchg(atomic_t *v, int n)
38{
39 smp_mb(); /* barrier for proper semantics */
40 return _atomic_xchg(v, n);
41}
42
43/**
44 * atomic_cmpxchg - atomically exchange contents of memory if it matches
45 * @v: pointer of type atomic_t
46 * @o: old value that memory should have
47 * @n: new value to write to memory if it matches
48 *
49 * Atomically checks if @v holds @o and replaces it with @n if so.
50 * Returns the old value at @v.
51 */
52static inline int atomic_cmpxchg(atomic_t *v, int o, int n)
53{
54 smp_mb(); /* barrier for proper semantics */
55 return _atomic_cmpxchg(v, o, n);
56}
57
58/**
59 * atomic_add - add integer to atomic variable
60 * @i: integer value to add
61 * @v: pointer of type atomic_t
62 *
63 * Atomically adds @i to @v.
64 */
65static inline void atomic_add(int i, atomic_t *v)
66{
67 _atomic_xchg_add(v, i);
68}
69
70/**
71 * atomic_add_return - add integer and return
72 * @v: pointer of type atomic_t
73 * @i: integer value to add
74 *
75 * Atomically adds @i to @v and returns @i + @v
76 */
77static inline int atomic_add_return(int i, atomic_t *v)
78{
79 smp_mb(); /* barrier for proper semantics */
80 return _atomic_xchg_add(v, i) + i;
81}
82
83/**
84 * atomic_add_unless - add unless the number is already a given value
85 * @v: pointer of type atomic_t
86 * @a: the amount to add to v...
87 * @u: ...unless v is equal to u.
88 *
89 * Atomically adds @a to @v, so long as @v was not already @u.
90 * Returns non-zero if @v was not @u, and zero otherwise.
91 */
92static inline int atomic_add_unless(atomic_t *v, int a, int u)
93{
94 smp_mb(); /* barrier for proper semantics */
95 return _atomic_xchg_add_unless(v, a, u) != u;
96}
97
98/**
99 * atomic_set - set atomic variable
100 * @v: pointer of type atomic_t
101 * @i: required value
102 *
103 * Atomically sets the value of @v to @i.
104 *
105 * atomic_set() can't be just a raw store, since it would be lost if it
106 * fell between the load and store of one of the other atomic ops.
107 */
108static inline void atomic_set(atomic_t *v, int n)
109{
110 _atomic_xchg(v, n);
111}
112
113#define xchg(ptr, x) ((typeof(*(ptr))) \
114 ((sizeof(*(ptr)) == sizeof(atomic_t)) ? \
115 atomic_xchg((atomic_t *)(ptr), (long)(x)) : \
116 __xchg_called_with_bad_pointer()))
117
118#define cmpxchg(ptr, o, n) ((typeof(*(ptr))) \
119 ((sizeof(*(ptr)) == sizeof(atomic_t)) ? \
120 atomic_cmpxchg((atomic_t *)(ptr), (long)(o), (long)(n)) : \
121 __cmpxchg_called_with_bad_pointer()))
122
123/* A 64bit atomic type */
124
125typedef struct {
126 u64 __aligned(8) counter;
127} atomic64_t;
128
129#define ATOMIC64_INIT(val) { (val) }
130
131u64 _atomic64_xchg(atomic64_t *v, u64 n);
132u64 _atomic64_xchg_add(atomic64_t *v, u64 i);
133u64 _atomic64_xchg_add_unless(atomic64_t *v, u64 a, u64 u);
134u64 _atomic64_cmpxchg(atomic64_t *v, u64 o, u64 n);
135
136/**
137 * atomic64_read - read atomic variable
138 * @v: pointer of type atomic64_t
139 *
140 * Atomically reads the value of @v.
141 */
142static inline u64 atomic64_read(const atomic64_t *v)
143{
144 /*
145 * Requires an atomic op to read both 32-bit parts consistently.
146 * Casting away const is safe since the atomic support routines
147 * do not write to memory if the value has not been modified.
148 */
149 return _atomic64_xchg_add((atomic64_t *)v, 0);
150}
151
152/**
153 * atomic64_xchg - atomically exchange contents of memory with a new value
154 * @v: pointer of type atomic64_t
155 * @i: integer value to store in memory
156 *
157 * Atomically sets @v to @i and returns old @v
158 */
159static inline u64 atomic64_xchg(atomic64_t *v, u64 n)
160{
161 smp_mb(); /* barrier for proper semantics */
162 return _atomic64_xchg(v, n);
163}
164
165/**
166 * atomic64_cmpxchg - atomically exchange contents of memory if it matches
167 * @v: pointer of type atomic64_t
168 * @o: old value that memory should have
169 * @n: new value to write to memory if it matches
170 *
171 * Atomically checks if @v holds @o and replaces it with @n if so.
172 * Returns the old value at @v.
173 */
174static inline u64 atomic64_cmpxchg(atomic64_t *v, u64 o, u64 n)
175{
176 smp_mb(); /* barrier for proper semantics */
177 return _atomic64_cmpxchg(v, o, n);
178}
179
180/**
181 * atomic64_add - add integer to atomic variable
182 * @i: integer value to add
183 * @v: pointer of type atomic64_t
184 *
185 * Atomically adds @i to @v.
186 */
187static inline void atomic64_add(u64 i, atomic64_t *v)
188{
189 _atomic64_xchg_add(v, i);
190}
191
192/**
193 * atomic64_add_return - add integer and return
194 * @v: pointer of type atomic64_t
195 * @i: integer value to add
196 *
197 * Atomically adds @i to @v and returns @i + @v
198 */
199static inline u64 atomic64_add_return(u64 i, atomic64_t *v)
200{
201 smp_mb(); /* barrier for proper semantics */
202 return _atomic64_xchg_add(v, i) + i;
203}
204
205/**
206 * atomic64_add_unless - add unless the number is already a given value
207 * @v: pointer of type atomic64_t
208 * @a: the amount to add to v...
209 * @u: ...unless v is equal to u.
210 *
211 * Atomically adds @a to @v, so long as @v was not already @u.
212 * Returns non-zero if @v was not @u, and zero otherwise.
213 */
214static inline u64 atomic64_add_unless(atomic64_t *v, u64 a, u64 u)
215{
216 smp_mb(); /* barrier for proper semantics */
217 return _atomic64_xchg_add_unless(v, a, u) != u;
218}
219
220/**
221 * atomic64_set - set atomic variable
222 * @v: pointer of type atomic64_t
223 * @i: required value
224 *
225 * Atomically sets the value of @v to @i.
226 *
227 * atomic64_set() can't be just a raw store, since it would be lost if it
228 * fell between the load and store of one of the other atomic ops.
229 */
230static inline void atomic64_set(atomic64_t *v, u64 n)
231{
232 _atomic64_xchg(v, n);
233}
234
235#define atomic64_add_negative(a, v) (atomic64_add_return((a), (v)) < 0)
236#define atomic64_inc(v) atomic64_add(1LL, (v))
237#define atomic64_inc_return(v) atomic64_add_return(1LL, (v))
238#define atomic64_inc_and_test(v) (atomic64_inc_return(v) == 0)
239#define atomic64_sub_return(i, v) atomic64_add_return(-(i), (v))
240#define atomic64_sub_and_test(a, v) (atomic64_sub_return((a), (v)) == 0)
241#define atomic64_sub(i, v) atomic64_add(-(i), (v))
242#define atomic64_dec(v) atomic64_sub(1LL, (v))
243#define atomic64_dec_return(v) atomic64_sub_return(1LL, (v))
244#define atomic64_dec_and_test(v) (atomic64_dec_return((v)) == 0)
245#define atomic64_inc_not_zero(v) atomic64_add_unless((v), 1LL, 0LL)
246
247/*
248 * We need to barrier before modifying the word, since the _atomic_xxx()
249 * routines just tns the lock and then read/modify/write of the word.
250 * But after the word is updated, the routine issues an "mf" before returning,
251 * and since it's a function call, we don't even need a compiler barrier.
252 */
253#define smp_mb__before_atomic_dec() smp_mb()
254#define smp_mb__before_atomic_inc() smp_mb()
255#define smp_mb__after_atomic_dec() do { } while (0)
256#define smp_mb__after_atomic_inc() do { } while (0)
257
258#endif /* !__ASSEMBLY__ */
259
260/*
261 * Internal definitions only beyond this point.
262 */
263
264#define ATOMIC_LOCKS_FOUND_VIA_TABLE() \
265 (!CHIP_HAS_CBOX_HOME_MAP() && defined(CONFIG_SMP))
266
267#if ATOMIC_LOCKS_FOUND_VIA_TABLE()
268
269/* Number of entries in atomic_lock_ptr[]. */
270#define ATOMIC_HASH_L1_SHIFT 6
271#define ATOMIC_HASH_L1_SIZE (1 << ATOMIC_HASH_L1_SHIFT)
272
273/* Number of locks in each struct pointed to by atomic_lock_ptr[]. */
274#define ATOMIC_HASH_L2_SHIFT (CHIP_L2_LOG_LINE_SIZE() - 2)
275#define ATOMIC_HASH_L2_SIZE (1 << ATOMIC_HASH_L2_SHIFT)
276
277#else /* ATOMIC_LOCKS_FOUND_VIA_TABLE() */
278
279/*
280 * Number of atomic locks in atomic_locks[]. Must be a power of two.
281 * There is no reason for more than PAGE_SIZE / 8 entries, since that
282 * is the maximum number of pointer bits we can use to index this.
283 * And we cannot have more than PAGE_SIZE / 4, since this has to
284 * fit on a single page and each entry takes 4 bytes.
285 */
286#define ATOMIC_HASH_SHIFT (PAGE_SHIFT - 3)
287#define ATOMIC_HASH_SIZE (1 << ATOMIC_HASH_SHIFT)
288
289#ifndef __ASSEMBLY__
290extern int atomic_locks[];
291#endif
292
293#endif /* ATOMIC_LOCKS_FOUND_VIA_TABLE() */
294
295/*
296 * All the code that may fault while holding an atomic lock must
297 * place the pointer to the lock in ATOMIC_LOCK_REG so the fault code
298 * can correctly release and reacquire the lock. Note that we
299 * mention the register number in a comment in "lib/atomic_asm.S" to help
300 * assembly coders from using this register by mistake, so if it
301 * is changed here, change that comment as well.
302 */
303#define ATOMIC_LOCK_REG 20
304#define ATOMIC_LOCK_REG_NAME r20
305
306#ifndef __ASSEMBLY__
307/* Called from setup to initialize a hash table to point to per_cpu locks. */
308void __init_atomic_per_cpu(void);
309
310#ifdef CONFIG_SMP
311/* Support releasing the atomic lock in do_page_fault_ics(). */
312void __atomic_fault_unlock(int *lock_ptr);
313#endif
314
315/* Private helper routines in lib/atomic_asm_32.S */
316extern struct __get_user __atomic_cmpxchg(volatile int *p,
317 int *lock, int o, int n);
318extern struct __get_user __atomic_xchg(volatile int *p, int *lock, int n);
319extern struct __get_user __atomic_xchg_add(volatile int *p, int *lock, int n);
320extern struct __get_user __atomic_xchg_add_unless(volatile int *p,
321 int *lock, int o, int n);
322extern struct __get_user __atomic_or(volatile int *p, int *lock, int n);
323extern struct __get_user __atomic_andn(volatile int *p, int *lock, int n);
324extern struct __get_user __atomic_xor(volatile int *p, int *lock, int n);
325extern u64 __atomic64_cmpxchg(volatile u64 *p, int *lock, u64 o, u64 n);
326extern u64 __atomic64_xchg(volatile u64 *p, int *lock, u64 n);
327extern u64 __atomic64_xchg_add(volatile u64 *p, int *lock, u64 n);
328extern u64 __atomic64_xchg_add_unless(volatile u64 *p,
329 int *lock, u64 o, u64 n);
330
331#endif /* !__ASSEMBLY__ */
332
333#endif /* _ASM_TILE_ATOMIC_32_H */
diff --git a/arch/tile/include/asm/auxvec.h b/arch/tile/include/asm/auxvec.h
new file mode 100644
index 000000000000..1d393edb0641
--- /dev/null
+++ b/arch/tile/include/asm/auxvec.h
@@ -0,0 +1,20 @@
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_AUXVEC_H
16#define _ASM_TILE_AUXVEC_H
17
18/* No extensions to auxvec */
19
20#endif /* _ASM_TILE_AUXVEC_H */
diff --git a/arch/tile/include/asm/backtrace.h b/arch/tile/include/asm/backtrace.h
new file mode 100644
index 000000000000..758ca4619d50
--- /dev/null
+++ b/arch/tile/include/asm/backtrace.h
@@ -0,0 +1,195 @@
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 _TILE_BACKTRACE_H
16#define _TILE_BACKTRACE_H
17
18
19
20#include <linux/types.h>
21
22#include <arch/chip.h>
23
24#if defined(__tile__)
25typedef unsigned long VirtualAddress;
26#elif CHIP_VA_WIDTH() > 32
27typedef unsigned long long VirtualAddress;
28#else
29typedef unsigned int VirtualAddress;
30#endif
31
32
33/** Reads 'size' bytes from 'address' and writes the data to 'result'.
34 * Returns true if successful, else false (e.g. memory not readable).
35 */
36typedef bool (*BacktraceMemoryReader)(void *result,
37 VirtualAddress address,
38 unsigned int size,
39 void *extra);
40
41typedef struct {
42 /** Current PC. */
43 VirtualAddress pc;
44
45 /** Current stack pointer value. */
46 VirtualAddress sp;
47
48 /** Current frame pointer value (i.e. caller's stack pointer) */
49 VirtualAddress fp;
50
51 /** Internal use only: caller's PC for first frame. */
52 VirtualAddress initial_frame_caller_pc;
53
54 /** Internal use only: callback to read memory. */
55 BacktraceMemoryReader read_memory_func;
56
57 /** Internal use only: arbitrary argument to read_memory_func. */
58 void *read_memory_func_extra;
59
60} BacktraceIterator;
61
62
63/** Initializes a backtracer to start from the given location.
64 *
65 * If the frame pointer cannot be determined it is set to -1.
66 *
67 * @param state The state to be filled in.
68 * @param read_memory_func A callback that reads memory. If NULL, a default
69 * value is provided.
70 * @param read_memory_func_extra An arbitrary argument to read_memory_func.
71 * @param pc The current PC.
72 * @param lr The current value of the 'lr' register.
73 * @param sp The current value of the 'sp' register.
74 * @param r52 The current value of the 'r52' register.
75 */
76extern void backtrace_init(BacktraceIterator *state,
77 BacktraceMemoryReader read_memory_func,
78 void *read_memory_func_extra,
79 VirtualAddress pc, VirtualAddress lr,
80 VirtualAddress sp, VirtualAddress r52);
81
82
83/** Advances the backtracing state to the calling frame, returning
84 * true iff successful.
85 */
86extern bool backtrace_next(BacktraceIterator *state);
87
88
89typedef enum {
90
91 /* We have no idea what the caller's pc is. */
92 PC_LOC_UNKNOWN,
93
94 /* The caller's pc is currently in lr. */
95 PC_LOC_IN_LR,
96
97 /* The caller's pc can be found by dereferencing the caller's sp. */
98 PC_LOC_ON_STACK
99
100} CallerPCLocation;
101
102
103typedef enum {
104
105 /* We have no idea what the caller's sp is. */
106 SP_LOC_UNKNOWN,
107
108 /* The caller's sp is currently in r52. */
109 SP_LOC_IN_R52,
110
111 /* The caller's sp can be found by adding a certain constant
112 * to the current value of sp.
113 */
114 SP_LOC_OFFSET
115
116} CallerSPLocation;
117
118
119/* Bit values ORed into CALLER_* values for info ops. */
120enum {
121 /* Setting the low bit on any of these values means the info op
122 * applies only to one bundle ago.
123 */
124 ONE_BUNDLE_AGO_FLAG = 1,
125
126 /* Setting this bit on a CALLER_SP_* value means the PC is in LR.
127 * If not set, PC is on the stack.
128 */
129 PC_IN_LR_FLAG = 2,
130
131 /* This many of the low bits of a CALLER_SP_* value are for the
132 * flag bits above.
133 */
134 NUM_INFO_OP_FLAGS = 2,
135
136 /* We cannot have one in the memory pipe so this is the maximum. */
137 MAX_INFO_OPS_PER_BUNDLE = 2
138};
139
140
141/** Internal constants used to define 'info' operands. */
142enum {
143 /* 0 and 1 are reserved, as are all negative numbers. */
144
145 CALLER_UNKNOWN_BASE = 2,
146
147 CALLER_SP_IN_R52_BASE = 4,
148
149 CALLER_SP_OFFSET_BASE = 8
150};
151
152
153/** Current backtracer state describing where it thinks the caller is. */
154typedef struct {
155 /*
156 * Public fields
157 */
158
159 /* How do we find the caller's PC? */
160 CallerPCLocation pc_location : 8;
161
162 /* How do we find the caller's SP? */
163 CallerSPLocation sp_location : 8;
164
165 /* If sp_location == SP_LOC_OFFSET, then caller_sp == sp +
166 * loc->sp_offset. Else this field is undefined.
167 */
168 uint16_t sp_offset;
169
170 /* In the most recently visited bundle a terminating bundle? */
171 bool at_terminating_bundle;
172
173 /*
174 * Private fields
175 */
176
177 /* Will the forward scanner see someone clobbering sp
178 * (i.e. changing it with something other than addi sp, sp, N?)
179 */
180 bool sp_clobber_follows;
181
182 /* Operand to next "visible" info op (no more than one bundle past
183 * the next terminating bundle), or -32768 if none.
184 */
185 int16_t next_info_operand;
186
187 /* Is the info of in next_info_op in the very next bundle? */
188 bool is_next_info_operand_adjacent;
189
190} CallerLocation;
191
192
193
194
195#endif /* _TILE_BACKTRACE_H */
diff --git a/arch/tile/include/asm/bitops.h b/arch/tile/include/asm/bitops.h
new file mode 100644
index 000000000000..6832b4be8990
--- /dev/null
+++ b/arch/tile/include/asm/bitops.h
@@ -0,0 +1,127 @@
1/*
2 * Copyright 1992, Linus Torvalds.
3 * Copyright 2010 Tilera Corporation. All Rights Reserved.
4 *
5 * This program is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU General Public License
7 * as published by the Free Software Foundation, version 2.
8 *
9 * This program is distributed in the hope that it will be useful, but
10 * WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, GOOD TITLE or
12 * NON INFRINGEMENT. See the GNU General Public License for
13 * more details.
14 */
15
16#ifndef _ASM_TILE_BITOPS_H
17#define _ASM_TILE_BITOPS_H
18
19#include <linux/types.h>
20
21#ifndef _LINUX_BITOPS_H
22#error only <linux/bitops.h> can be included directly
23#endif
24
25#ifdef __tilegx__
26#include <asm/bitops_64.h>
27#else
28#include <asm/bitops_32.h>
29#endif
30
31/**
32 * __ffs - find first set bit in word
33 * @word: The word to search
34 *
35 * Undefined if no set bit exists, so code should check against 0 first.
36 */
37static inline unsigned long __ffs(unsigned long word)
38{
39 return __builtin_ctzl(word);
40}
41
42/**
43 * ffz - find first zero bit in word
44 * @word: The word to search
45 *
46 * Undefined if no zero exists, so code should check against ~0UL first.
47 */
48static inline unsigned long ffz(unsigned long word)
49{
50 return __builtin_ctzl(~word);
51}
52
53/**
54 * __fls - find last set bit in word
55 * @word: The word to search
56 *
57 * Undefined if no set bit exists, so code should check against 0 first.
58 */
59static inline unsigned long __fls(unsigned long word)
60{
61 return (sizeof(word) * 8) - 1 - __builtin_clzl(word);
62}
63
64/**
65 * ffs - find first set bit in word
66 * @x: the word to search
67 *
68 * This is defined the same way as the libc and compiler builtin ffs
69 * routines, therefore differs in spirit from the other bitops.
70 *
71 * ffs(value) returns 0 if value is 0 or the position of the first
72 * set bit if value is nonzero. The first (least significant) bit
73 * is at position 1.
74 */
75static inline int ffs(int x)
76{
77 return __builtin_ffs(x);
78}
79
80/**
81 * fls - find last set bit in word
82 * @x: the word to search
83 *
84 * This is defined in a similar way as the libc and compiler builtin
85 * ffs, but returns the position of the most significant set bit.
86 *
87 * fls(value) returns 0 if value is 0 or the position of the last
88 * set bit if value is nonzero. The last (most significant) bit is
89 * at position 32.
90 */
91static inline int fls(int x)
92{
93 return (sizeof(int) * 8) - __builtin_clz(x);
94}
95
96static inline int fls64(__u64 w)
97{
98 return (sizeof(__u64) * 8) - __builtin_clzll(w);
99}
100
101static inline unsigned int __arch_hweight32(unsigned int w)
102{
103 return __builtin_popcount(w);
104}
105
106static inline unsigned int __arch_hweight16(unsigned int w)
107{
108 return __builtin_popcount(w & 0xffff);
109}
110
111static inline unsigned int __arch_hweight8(unsigned int w)
112{
113 return __builtin_popcount(w & 0xff);
114}
115
116static inline unsigned long __arch_hweight64(__u64 w)
117{
118 return __builtin_popcountll(w);
119}
120
121#include <asm-generic/bitops/const_hweight.h>
122#include <asm-generic/bitops/lock.h>
123#include <asm-generic/bitops/sched.h>
124#include <asm-generic/bitops/ext2-non-atomic.h>
125#include <asm-generic/bitops/minix.h>
126
127#endif /* _ASM_TILE_BITOPS_H */
diff --git a/arch/tile/include/asm/bitops_32.h b/arch/tile/include/asm/bitops_32.h
new file mode 100644
index 000000000000..7a93c001ac19
--- /dev/null
+++ b/arch/tile/include/asm/bitops_32.h
@@ -0,0 +1,132 @@
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_BITOPS_32_H
16#define _ASM_TILE_BITOPS_32_H
17
18#include <linux/compiler.h>
19#include <asm/atomic.h>
20#include <asm/system.h>
21
22/* Tile-specific routines to support <asm/bitops.h>. */
23unsigned long _atomic_or(volatile unsigned long *p, unsigned long mask);
24unsigned long _atomic_andn(volatile unsigned long *p, unsigned long mask);
25unsigned long _atomic_xor(volatile unsigned long *p, unsigned long mask);
26
27/**
28 * set_bit - Atomically set a bit in memory
29 * @nr: the bit to set
30 * @addr: the address to start counting from
31 *
32 * This function is atomic and may not be reordered.
33 * See __set_bit() if you do not require the atomic guarantees.
34 * Note that @nr may be almost arbitrarily large; this function is not
35 * restricted to acting on a single-word quantity.
36 */
37static inline void set_bit(unsigned nr, volatile unsigned long *addr)
38{
39 _atomic_or(addr + BIT_WORD(nr), BIT_MASK(nr));
40}
41
42/**
43 * clear_bit - Clears a bit in memory
44 * @nr: Bit to clear
45 * @addr: Address to start counting from
46 *
47 * clear_bit() is atomic and may not be reordered.
48 * See __clear_bit() if you do not require the atomic guarantees.
49 * Note that @nr may be almost arbitrarily large; this function is not
50 * restricted to acting on a single-word quantity.
51 *
52 * clear_bit() may not contain a memory barrier, so if it is used for
53 * locking purposes, you should call smp_mb__before_clear_bit() and/or
54 * smp_mb__after_clear_bit() to ensure changes are visible on other cpus.
55 */
56static inline void clear_bit(unsigned nr, volatile unsigned long *addr)
57{
58 _atomic_andn(addr + BIT_WORD(nr), BIT_MASK(nr));
59}
60
61/**
62 * change_bit - Toggle a bit in memory
63 * @nr: Bit to change
64 * @addr: Address to start counting from
65 *
66 * change_bit() is atomic and may not be reordered.
67 * See __change_bit() if you do not require the atomic guarantees.
68 * Note that @nr may be almost arbitrarily large; this function is not
69 * restricted to acting on a single-word quantity.
70 */
71static inline void change_bit(unsigned nr, volatile unsigned long *addr)
72{
73 _atomic_xor(addr + BIT_WORD(nr), BIT_MASK(nr));
74}
75
76/**
77 * test_and_set_bit - Set a bit and return its old value
78 * @nr: Bit to set
79 * @addr: Address to count from
80 *
81 * This operation is atomic and cannot be reordered.
82 * It also implies a memory barrier.
83 */
84static inline int test_and_set_bit(unsigned nr, volatile unsigned long *addr)
85{
86 unsigned long mask = BIT_MASK(nr);
87 addr += BIT_WORD(nr);
88 smp_mb(); /* barrier for proper semantics */
89 return (_atomic_or(addr, mask) & mask) != 0;
90}
91
92/**
93 * test_and_clear_bit - Clear a bit and return its old value
94 * @nr: Bit to clear
95 * @addr: Address to count from
96 *
97 * This operation is atomic and cannot be reordered.
98 * It also implies a memory barrier.
99 */
100static inline int test_and_clear_bit(unsigned nr, volatile unsigned long *addr)
101{
102 unsigned long mask = BIT_MASK(nr);
103 addr += BIT_WORD(nr);
104 smp_mb(); /* barrier for proper semantics */
105 return (_atomic_andn(addr, mask) & mask) != 0;
106}
107
108/**
109 * test_and_change_bit - Change a bit and return its old value
110 * @nr: Bit to change
111 * @addr: Address to count from
112 *
113 * This operation is atomic and cannot be reordered.
114 * It also implies a memory barrier.
115 */
116static inline int test_and_change_bit(unsigned nr,
117 volatile unsigned long *addr)
118{
119 unsigned long mask = BIT_MASK(nr);
120 addr += BIT_WORD(nr);
121 smp_mb(); /* barrier for proper semantics */
122 return (_atomic_xor(addr, mask) & mask) != 0;
123}
124
125/* See discussion at smp_mb__before_atomic_dec() in <asm/atomic.h>. */
126#define smp_mb__before_clear_bit() smp_mb()
127#define smp_mb__after_clear_bit() do {} while (0)
128
129#include <asm-generic/bitops/non-atomic.h>
130#include <asm-generic/bitops/ext2-atomic.h>
131
132#endif /* _ASM_TILE_BITOPS_32_H */
diff --git a/arch/tile/include/asm/bitsperlong.h b/arch/tile/include/asm/bitsperlong.h
new file mode 100644
index 000000000000..58c771f2af2f
--- /dev/null
+++ b/arch/tile/include/asm/bitsperlong.h
@@ -0,0 +1,26 @@
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_BITSPERLONG_H
16#define _ASM_TILE_BITSPERLONG_H
17
18#ifdef __LP64__
19# define __BITS_PER_LONG 64
20#else
21# define __BITS_PER_LONG 32
22#endif
23
24#include <asm-generic/bitsperlong.h>
25
26#endif /* _ASM_TILE_BITSPERLONG_H */
diff --git a/arch/tile/include/asm/bug.h b/arch/tile/include/asm/bug.h
new file mode 100644
index 000000000000..b12fd89e42e9
--- /dev/null
+++ b/arch/tile/include/asm/bug.h
@@ -0,0 +1 @@
#include <asm-generic/bug.h>
diff --git a/arch/tile/include/asm/bugs.h b/arch/tile/include/asm/bugs.h
new file mode 100644
index 000000000000..61791e1ad9f5
--- /dev/null
+++ b/arch/tile/include/asm/bugs.h
@@ -0,0 +1 @@
#include <asm-generic/bugs.h>
diff --git a/arch/tile/include/asm/byteorder.h b/arch/tile/include/asm/byteorder.h
new file mode 100644
index 000000000000..9558416d578b
--- /dev/null
+++ b/arch/tile/include/asm/byteorder.h
@@ -0,0 +1 @@
#include <linux/byteorder/little_endian.h>
diff --git a/arch/tile/include/asm/cache.h b/arch/tile/include/asm/cache.h
new file mode 100644
index 000000000000..08a2815b5e4e
--- /dev/null
+++ b/arch/tile/include/asm/cache.h
@@ -0,0 +1,51 @@
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_CACHE_H
16#define _ASM_TILE_CACHE_H
17
18#include <arch/chip.h>
19
20/* bytes per L1 data cache line */
21#define L1_CACHE_SHIFT CHIP_L1D_LOG_LINE_SIZE()
22#define L1_CACHE_BYTES (1 << L1_CACHE_SHIFT)
23
24/* bytes per L2 cache line */
25#define L2_CACHE_SHIFT CHIP_L2_LOG_LINE_SIZE()
26#define L2_CACHE_BYTES (1 << L2_CACHE_SHIFT)
27#define L2_CACHE_ALIGN(x) (((x)+(L2_CACHE_BYTES-1)) & -L2_CACHE_BYTES)
28
29/*
30 * TILE-Gx is fully coherent so we don't need to define ARCH_DMA_MINALIGN.
31 */
32#ifndef __tilegx__
33#define ARCH_DMA_MINALIGN L2_CACHE_BYTES
34#endif
35
36/* use the cache line size for the L2, which is where it counts */
37#define SMP_CACHE_BYTES_SHIFT L2_CACHE_SHIFT
38#define SMP_CACHE_BYTES L2_CACHE_BYTES
39#define INTERNODE_CACHE_SHIFT L2_CACHE_SHIFT
40#define INTERNODE_CACHE_BYTES L2_CACHE_BYTES
41
42/* Group together read-mostly things to avoid cache false sharing */
43#define __read_mostly __attribute__((__section__(".data.read_mostly")))
44
45/*
46 * Attribute for data that is kept read/write coherent until the end of
47 * initialization, then bumped to read/only incoherent for performance.
48 */
49#define __write_once __attribute__((__section__(".w1data")))
50
51#endif /* _ASM_TILE_CACHE_H */
diff --git a/arch/tile/include/asm/cacheflush.h b/arch/tile/include/asm/cacheflush.h
new file mode 100644
index 000000000000..c5741da4eeac
--- /dev/null
+++ b/arch/tile/include/asm/cacheflush.h
@@ -0,0 +1,140 @@
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_CACHEFLUSH_H
16#define _ASM_TILE_CACHEFLUSH_H
17
18#include <arch/chip.h>
19
20/* Keep includes the same across arches. */
21#include <linux/mm.h>
22#include <linux/cache.h>
23#include <asm/system.h>
24#include <arch/icache.h>
25
26/* Caches are physically-indexed and so don't need special treatment */
27#define flush_cache_all() do { } while (0)
28#define flush_cache_mm(mm) do { } while (0)
29#define flush_cache_dup_mm(mm) do { } while (0)
30#define flush_cache_range(vma, start, end) do { } while (0)
31#define flush_cache_page(vma, vmaddr, pfn) do { } while (0)
32#define ARCH_IMPLEMENTS_FLUSH_DCACHE_PAGE 0
33#define flush_dcache_page(page) do { } while (0)
34#define flush_dcache_mmap_lock(mapping) do { } while (0)
35#define flush_dcache_mmap_unlock(mapping) do { } while (0)
36#define flush_cache_vmap(start, end) do { } while (0)
37#define flush_cache_vunmap(start, end) do { } while (0)
38#define flush_icache_page(vma, pg) do { } while (0)
39#define flush_icache_user_range(vma, pg, adr, len) do { } while (0)
40
41/* Flush the icache just on this cpu */
42extern void __flush_icache_range(unsigned long start, unsigned long end);
43
44/* Flush the entire icache on this cpu. */
45#define __flush_icache() __flush_icache_range(0, CHIP_L1I_CACHE_SIZE())
46
47#ifdef CONFIG_SMP
48/*
49 * When the kernel writes to its own text we need to do an SMP
50 * broadcast to make the L1I coherent everywhere. This includes
51 * module load and single step.
52 */
53extern void flush_icache_range(unsigned long start, unsigned long end);
54#else
55#define flush_icache_range __flush_icache_range
56#endif
57
58/*
59 * An update to an executable user page requires icache flushing.
60 * We could carefully update only tiles that are running this process,
61 * and rely on the fact that we flush the icache on every context
62 * switch to avoid doing extra work here. But for now, I'll be
63 * conservative and just do a global icache flush.
64 */
65static inline void copy_to_user_page(struct vm_area_struct *vma,
66 struct page *page, unsigned long vaddr,
67 void *dst, void *src, int len)
68{
69 memcpy(dst, src, len);
70 if (vma->vm_flags & VM_EXEC) {
71 flush_icache_range((unsigned long) dst,
72 (unsigned long) dst + len);
73 }
74}
75
76#define copy_from_user_page(vma, page, vaddr, dst, src, len) \
77 memcpy((dst), (src), (len))
78
79/*
80 * Invalidate a VA range; pads to L2 cacheline boundaries.
81 *
82 * Note that on TILE64, __inv_buffer() actually flushes modified
83 * cache lines in addition to invalidating them, i.e., it's the
84 * same as __finv_buffer().
85 */
86static inline void __inv_buffer(void *buffer, size_t size)
87{
88 char *next = (char *)((long)buffer & -L2_CACHE_BYTES);
89 char *finish = (char *)L2_CACHE_ALIGN((long)buffer + size);
90 while (next < finish) {
91 __insn_inv(next);
92 next += CHIP_INV_STRIDE();
93 }
94}
95
96/* Flush a VA range; pads to L2 cacheline boundaries. */
97static inline void __flush_buffer(void *buffer, size_t size)
98{
99 char *next = (char *)((long)buffer & -L2_CACHE_BYTES);
100 char *finish = (char *)L2_CACHE_ALIGN((long)buffer + size);
101 while (next < finish) {
102 __insn_flush(next);
103 next += CHIP_FLUSH_STRIDE();
104 }
105}
106
107/* Flush & invalidate a VA range; pads to L2 cacheline boundaries. */
108static inline void __finv_buffer(void *buffer, size_t size)
109{
110 char *next = (char *)((long)buffer & -L2_CACHE_BYTES);
111 char *finish = (char *)L2_CACHE_ALIGN((long)buffer + size);
112 while (next < finish) {
113 __insn_finv(next);
114 next += CHIP_FINV_STRIDE();
115 }
116}
117
118
119/* Invalidate a VA range, then memory fence. */
120static inline void inv_buffer(void *buffer, size_t size)
121{
122 __inv_buffer(buffer, size);
123 mb_incoherent();
124}
125
126/* Flush a VA range, then memory fence. */
127static inline void flush_buffer(void *buffer, size_t size)
128{
129 __flush_buffer(buffer, size);
130 mb_incoherent();
131}
132
133/* Flush & invalidate a VA range, then memory fence. */
134static inline void finv_buffer(void *buffer, size_t size)
135{
136 __finv_buffer(buffer, size);
137 mb_incoherent();
138}
139
140#endif /* _ASM_TILE_CACHEFLUSH_H */
diff --git a/arch/tile/include/asm/checksum.h b/arch/tile/include/asm/checksum.h
new file mode 100644
index 000000000000..a120766c7264
--- /dev/null
+++ b/arch/tile/include/asm/checksum.h
@@ -0,0 +1,24 @@
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_CHECKSUM_H
16#define _ASM_TILE_CHECKSUM_H
17
18#include <asm-generic/checksum.h>
19
20/* Allow us to provide a more optimized do_csum(). */
21__wsum do_csum(const unsigned char *buff, int len);
22#define do_csum do_csum
23
24#endif /* _ASM_TILE_CHECKSUM_H */
diff --git a/arch/tile/include/asm/compat.h b/arch/tile/include/asm/compat.h
new file mode 100644
index 000000000000..5a34da6cdd79
--- /dev/null
+++ b/arch/tile/include/asm/compat.h
@@ -0,0 +1,257 @@
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_COMPAT_H
16#define _ASM_TILE_COMPAT_H
17
18/*
19 * Architecture specific compatibility types
20 */
21#include <linux/types.h>
22#include <linux/sched.h>
23
24#define COMPAT_USER_HZ 100
25
26/* "long" and pointer-based types are different. */
27typedef s32 compat_long_t;
28typedef u32 compat_ulong_t;
29typedef u32 compat_size_t;
30typedef s32 compat_ssize_t;
31typedef s32 compat_off_t;
32typedef s32 compat_time_t;
33typedef s32 compat_clock_t;
34typedef u32 compat_ino_t;
35typedef u32 compat_caddr_t;
36typedef u32 compat_uptr_t;
37
38/* Many types are "int" or otherwise the same. */
39typedef __kernel_pid_t compat_pid_t;
40typedef __kernel_uid_t __compat_uid_t;
41typedef __kernel_gid_t __compat_gid_t;
42typedef __kernel_uid32_t __compat_uid32_t;
43typedef __kernel_uid32_t __compat_gid32_t;
44typedef __kernel_mode_t compat_mode_t;
45typedef __kernel_dev_t compat_dev_t;
46typedef __kernel_loff_t compat_loff_t;
47typedef __kernel_nlink_t compat_nlink_t;
48typedef __kernel_ipc_pid_t compat_ipc_pid_t;
49typedef __kernel_daddr_t compat_daddr_t;
50typedef __kernel_fsid_t compat_fsid_t;
51typedef __kernel_timer_t compat_timer_t;
52typedef __kernel_key_t compat_key_t;
53typedef int compat_int_t;
54typedef s64 compat_s64;
55typedef uint compat_uint_t;
56typedef u64 compat_u64;
57
58/* We use the same register dump format in 32-bit images. */
59typedef unsigned long compat_elf_greg_t;
60#define COMPAT_ELF_NGREG (sizeof(struct pt_regs) / sizeof(compat_elf_greg_t))
61typedef compat_elf_greg_t compat_elf_gregset_t[COMPAT_ELF_NGREG];
62
63struct compat_timespec {
64 compat_time_t tv_sec;
65 s32 tv_nsec;
66};
67
68struct compat_timeval {
69 compat_time_t tv_sec;
70 s32 tv_usec;
71};
72
73#define compat_stat stat
74#define compat_statfs statfs
75
76struct compat_sysctl {
77 unsigned int name;
78 int nlen;
79 unsigned int oldval;
80 unsigned int oldlenp;
81 unsigned int newval;
82 unsigned int newlen;
83 unsigned int __unused[4];
84};
85
86
87struct compat_flock {
88 short l_type;
89 short l_whence;
90 compat_off_t l_start;
91 compat_off_t l_len;
92 compat_pid_t l_pid;
93};
94
95#define F_GETLK64 12 /* using 'struct flock64' */
96#define F_SETLK64 13
97#define F_SETLKW64 14
98
99struct compat_flock64 {
100 short l_type;
101 short l_whence;
102 compat_loff_t l_start;
103 compat_loff_t l_len;
104 compat_pid_t l_pid;
105};
106
107#define COMPAT_RLIM_INFINITY 0xffffffff
108
109#define _COMPAT_NSIG 64
110#define _COMPAT_NSIG_BPW 32
111
112typedef u32 compat_sigset_word;
113
114#define COMPAT_OFF_T_MAX 0x7fffffff
115#define COMPAT_LOFF_T_MAX 0x7fffffffffffffffL
116
117struct compat_ipc64_perm {
118 compat_key_t key;
119 __compat_uid32_t uid;
120 __compat_gid32_t gid;
121 __compat_uid32_t cuid;
122 __compat_gid32_t cgid;
123 unsigned short mode;
124 unsigned short __pad1;
125 unsigned short seq;
126 unsigned short __pad2;
127 compat_ulong_t unused1;
128 compat_ulong_t unused2;
129};
130
131struct compat_semid64_ds {
132 struct compat_ipc64_perm sem_perm;
133 compat_time_t sem_otime;
134 compat_ulong_t __unused1;
135 compat_time_t sem_ctime;
136 compat_ulong_t __unused2;
137 compat_ulong_t sem_nsems;
138 compat_ulong_t __unused3;
139 compat_ulong_t __unused4;
140};
141
142struct compat_msqid64_ds {
143 struct compat_ipc64_perm msg_perm;
144 compat_time_t msg_stime;
145 compat_ulong_t __unused1;
146 compat_time_t msg_rtime;
147 compat_ulong_t __unused2;
148 compat_time_t msg_ctime;
149 compat_ulong_t __unused3;
150 compat_ulong_t msg_cbytes;
151 compat_ulong_t msg_qnum;
152 compat_ulong_t msg_qbytes;
153 compat_pid_t msg_lspid;
154 compat_pid_t msg_lrpid;
155 compat_ulong_t __unused4;
156 compat_ulong_t __unused5;
157};
158
159struct compat_shmid64_ds {
160 struct compat_ipc64_perm shm_perm;
161 compat_size_t shm_segsz;
162 compat_time_t shm_atime;
163 compat_ulong_t __unused1;
164 compat_time_t shm_dtime;
165 compat_ulong_t __unused2;
166 compat_time_t shm_ctime;
167 compat_ulong_t __unused3;
168 compat_pid_t shm_cpid;
169 compat_pid_t shm_lpid;
170 compat_ulong_t shm_nattch;
171 compat_ulong_t __unused4;
172 compat_ulong_t __unused5;
173};
174
175/*
176 * A pointer passed in from user mode. This should not
177 * be used for syscall parameters, just declare them
178 * as pointers because the syscall entry code will have
179 * appropriately converted them already.
180 */
181
182static inline void __user *compat_ptr(compat_uptr_t uptr)
183{
184 return (void __user *)(long)(s32)uptr;
185}
186
187static inline compat_uptr_t ptr_to_compat(void __user *uptr)
188{
189 return (u32)(unsigned long)uptr;
190}
191
192/* Sign-extend when storing a kernel pointer to a user's ptregs. */
193static inline unsigned long ptr_to_compat_reg(void __user *uptr)
194{
195 return (long)(int)(long __force)uptr;
196}
197
198static inline void __user *compat_alloc_user_space(long len)
199{
200 struct pt_regs *regs = task_pt_regs(current);
201 return (void __user *)regs->sp - len;
202}
203
204static inline int is_compat_task(void)
205{
206 return current_thread_info()->status & TS_COMPAT;
207}
208
209extern int compat_setup_rt_frame(int sig, struct k_sigaction *ka,
210 siginfo_t *info, sigset_t *set,
211 struct pt_regs *regs);
212
213/* Compat syscalls. */
214struct compat_sigaction;
215struct compat_siginfo;
216struct compat_sigaltstack;
217long compat_sys_execve(char __user *path, compat_uptr_t __user *argv,
218 compat_uptr_t __user *envp);
219long compat_sys_rt_sigaction(int sig, struct compat_sigaction __user *act,
220 struct compat_sigaction __user *oact,
221 size_t sigsetsize);
222long compat_sys_rt_sigqueueinfo(int pid, int sig,
223 struct compat_siginfo __user *uinfo);
224long compat_sys_rt_sigreturn(void);
225long compat_sys_sigaltstack(const struct compat_sigaltstack __user *uss_ptr,
226 struct compat_sigaltstack __user *uoss_ptr);
227long compat_sys_truncate64(char __user *filename, u32 dummy, u32 low, u32 high);
228long compat_sys_ftruncate64(unsigned int fd, u32 dummy, u32 low, u32 high);
229long compat_sys_pread64(unsigned int fd, char __user *ubuf, size_t count,
230 u32 dummy, u32 low, u32 high);
231long compat_sys_pwrite64(unsigned int fd, char __user *ubuf, size_t count,
232 u32 dummy, u32 low, u32 high);
233long compat_sys_lookup_dcookie(u32 low, u32 high, char __user *buf, size_t len);
234long compat_sys_sync_file_range2(int fd, unsigned int flags,
235 u32 offset_lo, u32 offset_hi,
236 u32 nbytes_lo, u32 nbytes_hi);
237long compat_sys_fallocate(int fd, int mode,
238 u32 offset_lo, u32 offset_hi,
239 u32 len_lo, u32 len_hi);
240long compat_sys_sched_rr_get_interval(compat_pid_t pid,
241 struct compat_timespec __user *interval);
242
243/* Versions of compat functions that differ from generic Linux. */
244struct compat_msgbuf;
245long tile_compat_sys_msgsnd(int msqid,
246 struct compat_msgbuf __user *msgp,
247 size_t msgsz, int msgflg);
248long tile_compat_sys_msgrcv(int msqid,
249 struct compat_msgbuf __user *msgp,
250 size_t msgsz, long msgtyp, int msgflg);
251long tile_compat_sys_ptrace(compat_long_t request, compat_long_t pid,
252 compat_long_t addr, compat_long_t data);
253
254/* Tilera Linux syscalls that don't have "compat" versions. */
255#define compat_sys_flush_cache sys_flush_cache
256
257#endif /* _ASM_TILE_COMPAT_H */
diff --git a/arch/tile/include/asm/cputime.h b/arch/tile/include/asm/cputime.h
new file mode 100644
index 000000000000..6d68ad7e0ea3
--- /dev/null
+++ b/arch/tile/include/asm/cputime.h
@@ -0,0 +1 @@
#include <asm-generic/cputime.h>
diff --git a/arch/tile/include/asm/current.h b/arch/tile/include/asm/current.h
new file mode 100644
index 000000000000..da21acf020d3
--- /dev/null
+++ b/arch/tile/include/asm/current.h
@@ -0,0 +1,31 @@
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_CURRENT_H
16#define _ASM_TILE_CURRENT_H
17
18#include <linux/thread_info.h>
19
20struct task_struct;
21
22static inline struct task_struct *get_current(void)
23{
24 return current_thread_info()->task;
25}
26#define current get_current()
27
28/* Return a usable "task_struct" pointer even if the real one is corrupt. */
29struct task_struct *validate_current(void);
30
31#endif /* _ASM_TILE_CURRENT_H */
diff --git a/arch/tile/include/asm/delay.h b/arch/tile/include/asm/delay.h
new file mode 100644
index 000000000000..97b0e69e704e
--- /dev/null
+++ b/arch/tile/include/asm/delay.h
@@ -0,0 +1,34 @@
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_DELAY_H
16#define _ASM_TILE_DELAY_H
17
18/* Undefined functions to get compile-time errors. */
19extern void __bad_udelay(void);
20extern void __bad_ndelay(void);
21
22extern void __udelay(unsigned long usecs);
23extern void __ndelay(unsigned long nsecs);
24extern void __delay(unsigned long loops);
25
26#define udelay(n) (__builtin_constant_p(n) ? \
27 ((n) > 20000 ? __bad_udelay() : __ndelay((n) * 1000)) : \
28 __udelay(n))
29
30#define ndelay(n) (__builtin_constant_p(n) ? \
31 ((n) > 20000 ? __bad_ndelay() : __ndelay(n)) : \
32 __ndelay(n))
33
34#endif /* _ASM_TILE_DELAY_H */
diff --git a/arch/tile/include/asm/device.h b/arch/tile/include/asm/device.h
new file mode 100644
index 000000000000..f0a4c256403b
--- /dev/null
+++ b/arch/tile/include/asm/device.h
@@ -0,0 +1 @@
#include <asm-generic/device.h>
diff --git a/arch/tile/include/asm/div64.h b/arch/tile/include/asm/div64.h
new file mode 100644
index 000000000000..6cd978cefb28
--- /dev/null
+++ b/arch/tile/include/asm/div64.h
@@ -0,0 +1 @@
#include <asm-generic/div64.h>
diff --git a/arch/tile/include/asm/dma-mapping.h b/arch/tile/include/asm/dma-mapping.h
new file mode 100644
index 000000000000..15e1dceecc64
--- /dev/null
+++ b/arch/tile/include/asm/dma-mapping.h
@@ -0,0 +1,93 @@
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_DMA_MAPPING_H
16#define _ASM_TILE_DMA_MAPPING_H
17
18#include <linux/mm.h>
19#include <linux/scatterlist.h>
20#include <linux/cache.h>
21#include <linux/io.h>
22
23/*
24 * Note that on x86 and powerpc, there is a "struct dma_mapping_ops"
25 * that is used for all the DMA operations. For now, we don't have an
26 * equivalent on tile, because we only have a single way of doing DMA.
27 * (Tilera bug 7994 to use dma_mapping_ops.)
28 */
29
30#define dma_alloc_noncoherent(d, s, h, f) dma_alloc_coherent(d, s, h, f)
31#define dma_free_noncoherent(d, s, v, h) dma_free_coherent(d, s, v, h)
32
33extern dma_addr_t dma_map_single(struct device *dev, void *ptr, size_t size,
34 enum dma_data_direction);
35extern void dma_unmap_single(struct device *dev, dma_addr_t dma_addr,
36 size_t size, enum dma_data_direction);
37extern int dma_map_sg(struct device *dev, struct scatterlist *sg, int nents,
38 enum dma_data_direction);
39extern void dma_unmap_sg(struct device *dev, struct scatterlist *sg,
40 int nhwentries, enum dma_data_direction);
41extern dma_addr_t dma_map_page(struct device *dev, struct page *page,
42 unsigned long offset, size_t size,
43 enum dma_data_direction);
44extern void dma_unmap_page(struct device *dev, dma_addr_t dma_address,
45 size_t size, enum dma_data_direction);
46extern void dma_sync_sg_for_cpu(struct device *dev, struct scatterlist *sg,
47 int nelems, enum dma_data_direction);
48extern void dma_sync_sg_for_device(struct device *dev, struct scatterlist *sg,
49 int nelems, enum dma_data_direction);
50
51
52void *dma_alloc_coherent(struct device *dev, size_t size,
53 dma_addr_t *dma_handle, gfp_t flag);
54
55void dma_free_coherent(struct device *dev, size_t size,
56 void *vaddr, dma_addr_t dma_handle);
57
58extern void dma_sync_single_for_cpu(struct device *, dma_addr_t, size_t,
59 enum dma_data_direction);
60extern void dma_sync_single_for_device(struct device *, dma_addr_t,
61 size_t, enum dma_data_direction);
62extern void dma_sync_single_range_for_cpu(struct device *, dma_addr_t,
63 unsigned long offset, size_t,
64 enum dma_data_direction);
65extern void dma_sync_single_range_for_device(struct device *, dma_addr_t,
66 unsigned long offset, size_t,
67 enum dma_data_direction);
68extern void dma_cache_sync(void *vaddr, size_t, enum dma_data_direction);
69
70static inline int
71dma_mapping_error(struct device *dev, dma_addr_t dma_addr)
72{
73 return 0;
74}
75
76static inline int
77dma_supported(struct device *dev, u64 mask)
78{
79 return 1;
80}
81
82static inline int
83dma_set_mask(struct device *dev, u64 mask)
84{
85 if (!dev->dma_mask || !dma_supported(dev, mask))
86 return -EIO;
87
88 *dev->dma_mask = mask;
89
90 return 0;
91}
92
93#endif /* _ASM_TILE_DMA_MAPPING_H */
diff --git a/arch/tile/include/asm/dma.h b/arch/tile/include/asm/dma.h
new file mode 100644
index 000000000000..12a7ca16d164
--- /dev/null
+++ b/arch/tile/include/asm/dma.h
@@ -0,0 +1,25 @@
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_DMA_H
16#define _ASM_TILE_DMA_H
17
18#include <asm-generic/dma.h>
19
20/* Needed by drivers/pci/quirks.c */
21#ifdef CONFIG_PCI
22extern int isa_dma_bridge_buggy;
23#endif
24
25#endif /* _ASM_TILE_DMA_H */
diff --git a/arch/tile/include/asm/elf.h b/arch/tile/include/asm/elf.h
new file mode 100644
index 000000000000..623a6bb741c1
--- /dev/null
+++ b/arch/tile/include/asm/elf.h
@@ -0,0 +1,167 @@
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_ELF_H
16#define _ASM_TILE_ELF_H
17
18/*
19 * ELF register definitions.
20 */
21
22#include <arch/chip.h>
23
24#include <linux/ptrace.h>
25#include <asm/byteorder.h>
26#include <asm/page.h>
27
28typedef unsigned long elf_greg_t;
29
30#define ELF_NGREG (sizeof(struct pt_regs) / sizeof(elf_greg_t))
31typedef elf_greg_t elf_gregset_t[ELF_NGREG];
32
33#define EM_TILE64 187
34#define EM_TILEPRO 188
35#define EM_TILEGX 191
36
37/* Provide a nominal data structure. */
38#define ELF_NFPREG 0
39typedef double elf_fpreg_t;
40typedef elf_fpreg_t elf_fpregset_t[ELF_NFPREG];
41
42#ifdef __tilegx__
43#define ELF_CLASS ELFCLASS64
44#else
45#define ELF_CLASS ELFCLASS32
46#endif
47#define ELF_DATA ELFDATA2LSB
48
49/*
50 * There seems to be a bug in how compat_binfmt_elf.c works: it
51 * #undefs ELF_ARCH, but it is then used in binfmt_elf.c for fill_note_info().
52 * Hack around this by providing an enum value of ELF_ARCH.
53 */
54enum { ELF_ARCH = CHIP_ELF_TYPE() };
55#define ELF_ARCH ELF_ARCH
56
57/*
58 * This is used to ensure we don't load something for the wrong architecture.
59 */
60#define elf_check_arch(x) \
61 ((x)->e_ident[EI_CLASS] == ELF_CLASS && \
62 (x)->e_machine == CHIP_ELF_TYPE())
63
64/* The module loader only handles a few relocation types. */
65#ifndef __tilegx__
66#define R_TILE_32 1
67#define R_TILE_JOFFLONG_X1 15
68#define R_TILE_IMM16_X0_LO 25
69#define R_TILE_IMM16_X1_LO 26
70#define R_TILE_IMM16_X0_HA 29
71#define R_TILE_IMM16_X1_HA 30
72#else
73#define R_TILEGX_64 1
74#define R_TILEGX_JUMPOFF_X1 21
75#define R_TILEGX_IMM16_X0_HW0 36
76#define R_TILEGX_IMM16_X1_HW0 37
77#define R_TILEGX_IMM16_X0_HW1 38
78#define R_TILEGX_IMM16_X1_HW1 39
79#define R_TILEGX_IMM16_X0_HW2_LAST 48
80#define R_TILEGX_IMM16_X1_HW2_LAST 49
81#endif
82
83/* Use standard page size for core dumps. */
84#define ELF_EXEC_PAGESIZE PAGE_SIZE
85
86/*
87 * This is the location that an ET_DYN program is loaded if exec'ed. Typical
88 * use of this is to invoke "./ld.so someprog" to test out a new version of
89 * the loader. We need to make sure that it is out of the way of the program
90 * that it will "exec", and that there is sufficient room for the brk.
91 */
92#define ELF_ET_DYN_BASE (TASK_SIZE / 3 * 2)
93
94#define ELF_CORE_COPY_REGS(_dest, _regs) \
95 memcpy((char *) &_dest, (char *) _regs, \
96 sizeof(struct pt_regs));
97
98/* No additional FP registers to copy. */
99#define ELF_CORE_COPY_FPREGS(t, fpu) 0
100
101/*
102 * This yields a mask that user programs can use to figure out what
103 * instruction set this CPU supports. This could be done in user space,
104 * but it's not easy, and we've already done it here.
105 */
106#define ELF_HWCAP (0)
107
108/*
109 * This yields a string that ld.so will use to load implementation
110 * specific libraries for optimization. This is more specific in
111 * intent than poking at uname or /proc/cpuinfo.
112 */
113#define ELF_PLATFORM (NULL)
114
115extern void elf_plat_init(struct pt_regs *regs, unsigned long load_addr);
116
117#define ELF_PLAT_INIT(_r, load_addr) elf_plat_init(_r, load_addr)
118
119extern int dump_task_regs(struct task_struct *, elf_gregset_t *);
120#define ELF_CORE_COPY_TASK_REGS(tsk, elf_regs) dump_task_regs(tsk, elf_regs)
121
122/* Tilera Linux has no personalities currently, so no need to do anything. */
123#define SET_PERSONALITY(ex) do { } while (0)
124
125#define ARCH_HAS_SETUP_ADDITIONAL_PAGES
126/* Support auto-mapping of the user interrupt vectors. */
127struct linux_binprm;
128extern int arch_setup_additional_pages(struct linux_binprm *bprm,
129 int executable_stack);
130#ifdef CONFIG_COMPAT
131
132#define COMPAT_ELF_PLATFORM "tilegx-m32"
133
134/*
135 * "Compat" binaries have the same machine type, but 32-bit class,
136 * since they're not a separate machine type, but just a 32-bit
137 * variant of the standard 64-bit architecture.
138 */
139#define compat_elf_check_arch(x) \
140 ((x)->e_ident[EI_CLASS] == ELFCLASS32 && \
141 (x)->e_machine == CHIP_ELF_TYPE())
142
143#define compat_start_thread(regs, ip, usp) do { \
144 regs->pc = ptr_to_compat_reg((void *)(ip)); \
145 regs->sp = ptr_to_compat_reg((void *)(usp)); \
146 } while (0)
147
148/*
149 * Use SET_PERSONALITY to indicate compatibility via TS_COMPAT.
150 */
151#undef SET_PERSONALITY
152#define SET_PERSONALITY(ex) \
153do { \
154 current->personality = PER_LINUX; \
155 current_thread_info()->status &= ~TS_COMPAT; \
156} while (0)
157#define COMPAT_SET_PERSONALITY(ex) \
158do { \
159 current->personality = PER_LINUX_32BIT; \
160 current_thread_info()->status |= TS_COMPAT; \
161} while (0)
162
163#define COMPAT_ELF_ET_DYN_BASE (0xffffffff / 3 * 2)
164
165#endif /* CONFIG_COMPAT */
166
167#endif /* _ASM_TILE_ELF_H */
diff --git a/arch/tile/include/asm/emergency-restart.h b/arch/tile/include/asm/emergency-restart.h
new file mode 100644
index 000000000000..3711bd9d50bd
--- /dev/null
+++ b/arch/tile/include/asm/emergency-restart.h
@@ -0,0 +1 @@
#include <asm-generic/emergency-restart.h>
diff --git a/arch/tile/include/asm/errno.h b/arch/tile/include/asm/errno.h
new file mode 100644
index 000000000000..4c82b503d92f
--- /dev/null
+++ b/arch/tile/include/asm/errno.h
@@ -0,0 +1 @@
#include <asm-generic/errno.h>
diff --git a/arch/tile/include/asm/fcntl.h b/arch/tile/include/asm/fcntl.h
new file mode 100644
index 000000000000..46ab12db5739
--- /dev/null
+++ b/arch/tile/include/asm/fcntl.h
@@ -0,0 +1 @@
#include <asm-generic/fcntl.h>
diff --git a/arch/tile/include/asm/fixmap.h b/arch/tile/include/asm/fixmap.h
new file mode 100644
index 000000000000..51537ff9265a
--- /dev/null
+++ b/arch/tile/include/asm/fixmap.h
@@ -0,0 +1,124 @@
1/*
2 * Copyright (C) 1998 Ingo Molnar
3 * Copyright 2010 Tilera Corporation. All Rights Reserved.
4 *
5 * This program is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU General Public License
7 * as published by the Free Software Foundation, version 2.
8 *
9 * This program is distributed in the hope that it will be useful, but
10 * WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, GOOD TITLE or
12 * NON INFRINGEMENT. See the GNU General Public License for
13 * more details.
14 */
15
16#ifndef _ASM_TILE_FIXMAP_H
17#define _ASM_TILE_FIXMAP_H
18
19#include <asm/page.h>
20
21#ifndef __ASSEMBLY__
22#include <linux/kernel.h>
23#ifdef CONFIG_HIGHMEM
24#include <linux/threads.h>
25#include <asm/kmap_types.h>
26#endif
27
28#define __fix_to_virt(x) (FIXADDR_TOP - ((x) << PAGE_SHIFT))
29#define __virt_to_fix(x) ((FIXADDR_TOP - ((x)&PAGE_MASK)) >> PAGE_SHIFT)
30
31/*
32 * Here we define all the compile-time 'special' virtual
33 * addresses. The point is to have a constant address at
34 * compile time, but to set the physical address only
35 * in the boot process. We allocate these special addresses
36 * from the end of supervisor virtual memory backwards.
37 * Also this lets us do fail-safe vmalloc(), we
38 * can guarantee that these special addresses and
39 * vmalloc()-ed addresses never overlap.
40 *
41 * these 'compile-time allocated' memory buffers are
42 * fixed-size 4k pages. (or larger if used with an increment
43 * higher than 1) use fixmap_set(idx,phys) to associate
44 * physical memory with fixmap indices.
45 *
46 * TLB entries of such buffers will not be flushed across
47 * task switches.
48 *
49 * We don't bother with a FIX_HOLE since above the fixmaps
50 * is unmapped memory in any case.
51 */
52enum fixed_addresses {
53#ifdef CONFIG_HIGHMEM
54 FIX_KMAP_BEGIN, /* reserved pte's for temporary kernel mappings */
55 FIX_KMAP_END = FIX_KMAP_BEGIN+(KM_TYPE_NR*NR_CPUS)-1,
56#endif
57 __end_of_permanent_fixed_addresses,
58
59 /*
60 * Temporary boot-time mappings, used before ioremap() is functional.
61 * Not currently needed by the Tile architecture.
62 */
63#define NR_FIX_BTMAPS 0
64#if NR_FIX_BTMAPS
65 FIX_BTMAP_END = __end_of_permanent_fixed_addresses,
66 FIX_BTMAP_BEGIN = FIX_BTMAP_END + NR_FIX_BTMAPS - 1,
67 __end_of_fixed_addresses
68#else
69 __end_of_fixed_addresses = __end_of_permanent_fixed_addresses
70#endif
71};
72
73extern void __set_fixmap(enum fixed_addresses idx,
74 unsigned long phys, pgprot_t flags);
75
76#define set_fixmap(idx, phys) \
77 __set_fixmap(idx, phys, PAGE_KERNEL)
78/*
79 * Some hardware wants to get fixmapped without caching.
80 */
81#define set_fixmap_nocache(idx, phys) \
82 __set_fixmap(idx, phys, PAGE_KERNEL_NOCACHE)
83
84#define clear_fixmap(idx) \
85 __set_fixmap(idx, 0, __pgprot(0))
86
87#define __FIXADDR_SIZE (__end_of_permanent_fixed_addresses << PAGE_SHIFT)
88#define __FIXADDR_BOOT_SIZE (__end_of_fixed_addresses << PAGE_SHIFT)
89#define FIXADDR_START (FIXADDR_TOP + PAGE_SIZE - __FIXADDR_SIZE)
90#define FIXADDR_BOOT_START (FIXADDR_TOP + PAGE_SIZE - __FIXADDR_BOOT_SIZE)
91
92extern void __this_fixmap_does_not_exist(void);
93
94/*
95 * 'index to address' translation. If anyone tries to use the idx
96 * directly without tranlation, we catch the bug with a NULL-deference
97 * kernel oops. Illegal ranges of incoming indices are caught too.
98 */
99static __always_inline unsigned long fix_to_virt(const unsigned int idx)
100{
101 /*
102 * this branch gets completely eliminated after inlining,
103 * except when someone tries to use fixaddr indices in an
104 * illegal way. (such as mixing up address types or using
105 * out-of-range indices).
106 *
107 * If it doesn't get removed, the linker will complain
108 * loudly with a reasonably clear error message..
109 */
110 if (idx >= __end_of_fixed_addresses)
111 __this_fixmap_does_not_exist();
112
113 return __fix_to_virt(idx);
114}
115
116static inline unsigned long virt_to_fix(const unsigned long vaddr)
117{
118 BUG_ON(vaddr >= FIXADDR_TOP || vaddr < FIXADDR_START);
119 return __virt_to_fix(vaddr);
120}
121
122#endif /* !__ASSEMBLY__ */
123
124#endif /* _ASM_TILE_FIXMAP_H */
diff --git a/arch/tile/include/asm/ftrace.h b/arch/tile/include/asm/ftrace.h
new file mode 100644
index 000000000000..461459b06d98
--- /dev/null
+++ b/arch/tile/include/asm/ftrace.h
@@ -0,0 +1,20 @@
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_FTRACE_H
16#define _ASM_TILE_FTRACE_H
17
18/* empty */
19
20#endif /* _ASM_TILE_FTRACE_H */
diff --git a/arch/tile/include/asm/futex.h b/arch/tile/include/asm/futex.h
new file mode 100644
index 000000000000..fe0d10dcae57
--- /dev/null
+++ b/arch/tile/include/asm/futex.h
@@ -0,0 +1,141 @@
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 * These routines make two important assumptions:
15 *
16 * 1. atomic_t is really an int and can be freely cast back and forth
17 * (validated in __init_atomic_per_cpu).
18 *
19 * 2. userspace uses sys_cmpxchg() for all atomic operations, thus using
20 * the same locking convention that all the kernel atomic routines use.
21 */
22
23#ifndef _ASM_TILE_FUTEX_H
24#define _ASM_TILE_FUTEX_H
25
26#ifndef __ASSEMBLY__
27
28#include <linux/futex.h>
29#include <linux/uaccess.h>
30#include <linux/errno.h>
31
32extern struct __get_user futex_set(int __user *v, int i);
33extern struct __get_user futex_add(int __user *v, int n);
34extern struct __get_user futex_or(int __user *v, int n);
35extern struct __get_user futex_andn(int __user *v, int n);
36extern struct __get_user futex_cmpxchg(int __user *v, int o, int n);
37
38#ifndef __tilegx__
39extern struct __get_user futex_xor(int __user *v, int n);
40#else
41static inline struct __get_user futex_xor(int __user *uaddr, int n)
42{
43 struct __get_user asm_ret = __get_user_4(uaddr);
44 if (!asm_ret.err) {
45 int oldval, newval;
46 do {
47 oldval = asm_ret.val;
48 newval = oldval ^ n;
49 asm_ret = futex_cmpxchg(uaddr, oldval, newval);
50 } while (asm_ret.err == 0 && oldval != asm_ret.val);
51 }
52 return asm_ret;
53}
54#endif
55
56static inline int futex_atomic_op_inuser(int encoded_op, int __user *uaddr)
57{
58 int op = (encoded_op >> 28) & 7;
59 int cmp = (encoded_op >> 24) & 15;
60 int oparg = (encoded_op << 8) >> 20;
61 int cmparg = (encoded_op << 20) >> 20;
62 int ret;
63 struct __get_user asm_ret;
64
65 if (encoded_op & (FUTEX_OP_OPARG_SHIFT << 28))
66 oparg = 1 << oparg;
67
68 if (!access_ok(VERIFY_WRITE, uaddr, sizeof(int)))
69 return -EFAULT;
70
71 pagefault_disable();
72 switch (op) {
73 case FUTEX_OP_SET:
74 asm_ret = futex_set(uaddr, oparg);
75 break;
76 case FUTEX_OP_ADD:
77 asm_ret = futex_add(uaddr, oparg);
78 break;
79 case FUTEX_OP_OR:
80 asm_ret = futex_or(uaddr, oparg);
81 break;
82 case FUTEX_OP_ANDN:
83 asm_ret = futex_andn(uaddr, oparg);
84 break;
85 case FUTEX_OP_XOR:
86 asm_ret = futex_xor(uaddr, oparg);
87 break;
88 default:
89 asm_ret.err = -ENOSYS;
90 }
91 pagefault_enable();
92
93 ret = asm_ret.err;
94
95 if (!ret) {
96 switch (cmp) {
97 case FUTEX_OP_CMP_EQ:
98 ret = (asm_ret.val == cmparg);
99 break;
100 case FUTEX_OP_CMP_NE:
101 ret = (asm_ret.val != cmparg);
102 break;
103 case FUTEX_OP_CMP_LT:
104 ret = (asm_ret.val < cmparg);
105 break;
106 case FUTEX_OP_CMP_GE:
107 ret = (asm_ret.val >= cmparg);
108 break;
109 case FUTEX_OP_CMP_LE:
110 ret = (asm_ret.val <= cmparg);
111 break;
112 case FUTEX_OP_CMP_GT:
113 ret = (asm_ret.val > cmparg);
114 break;
115 default:
116 ret = -ENOSYS;
117 }
118 }
119 return ret;
120}
121
122static inline int futex_atomic_cmpxchg_inatomic(int __user *uaddr, int oldval,
123 int newval)
124{
125 struct __get_user asm_ret;
126
127 if (!access_ok(VERIFY_WRITE, uaddr, sizeof(int)))
128 return -EFAULT;
129
130 asm_ret = futex_cmpxchg(uaddr, oldval, newval);
131 return asm_ret.err ? asm_ret.err : asm_ret.val;
132}
133
134#ifndef __tilegx__
135/* Return failure from the atomic wrappers. */
136struct __get_user __atomic_bad_address(int __user *addr);
137#endif
138
139#endif /* !__ASSEMBLY__ */
140
141#endif /* _ASM_TILE_FUTEX_H */
diff --git a/arch/tile/include/asm/hardirq.h b/arch/tile/include/asm/hardirq.h
new file mode 100644
index 000000000000..822390f9a154
--- /dev/null
+++ b/arch/tile/include/asm/hardirq.h
@@ -0,0 +1,47 @@
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_HARDIRQ_H
16#define _ASM_TILE_HARDIRQ_H
17
18#include <linux/threads.h>
19#include <linux/cache.h>
20
21#include <asm/irq.h>
22
23typedef struct {
24 unsigned int __softirq_pending;
25 long idle_timestamp;
26
27 /* Hard interrupt statistics. */
28 unsigned int irq_timer_count;
29 unsigned int irq_syscall_count;
30 unsigned int irq_resched_count;
31 unsigned int irq_hv_flush_count;
32 unsigned int irq_call_count;
33 unsigned int irq_hv_msg_count;
34 unsigned int irq_dev_intr_count;
35
36} ____cacheline_aligned irq_cpustat_t;
37
38DECLARE_PER_CPU(irq_cpustat_t, irq_stat);
39
40#define __ARCH_IRQ_STAT
41#define __IRQ_STAT(cpu, member) (per_cpu(irq_stat, cpu).member)
42
43#include <linux/irq_cpustat.h> /* Standard mappings for irq_cpustat_t above */
44
45#define HARDIRQ_BITS 8
46
47#endif /* _ASM_TILE_HARDIRQ_H */
diff --git a/arch/tile/include/asm/hardwall.h b/arch/tile/include/asm/hardwall.h
new file mode 100644
index 000000000000..0bed3ec7b42c
--- /dev/null
+++ b/arch/tile/include/asm/hardwall.h
@@ -0,0 +1,56 @@
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 * Provide methods for the HARDWALL_FILE for accessing the UDN.
15 */
16
17#ifndef _ASM_TILE_HARDWALL_H
18#define _ASM_TILE_HARDWALL_H
19
20#include <linux/ioctl.h>
21
22#define HARDWALL_IOCTL_BASE 0xa2
23
24/*
25 * The HARDWALL_CREATE() ioctl is a macro with a "size" argument.
26 * The resulting ioctl value is passed to the kernel in conjunction
27 * with a pointer to a little-endian bitmask of cpus, which must be
28 * physically in a rectangular configuration on the chip.
29 * The "size" is the number of bytes of cpu mask data.
30 */
31#define _HARDWALL_CREATE 1
32#define HARDWALL_CREATE(size) \
33 _IOC(_IOC_READ, HARDWALL_IOCTL_BASE, _HARDWALL_CREATE, (size))
34
35#define _HARDWALL_ACTIVATE 2
36#define HARDWALL_ACTIVATE \
37 _IO(HARDWALL_IOCTL_BASE, _HARDWALL_ACTIVATE)
38
39#define _HARDWALL_DEACTIVATE 3
40#define HARDWALL_DEACTIVATE \
41 _IO(HARDWALL_IOCTL_BASE, _HARDWALL_DEACTIVATE)
42
43#ifndef __KERNEL__
44
45/* This is the canonical name expected by userspace. */
46#define HARDWALL_FILE "/dev/hardwall"
47
48#else
49
50/* Hook for /proc/tile/hardwall. */
51struct seq_file;
52int proc_tile_hardwall_show(struct seq_file *sf, void *v);
53
54#endif
55
56#endif /* _ASM_TILE_HARDWALL_H */
diff --git a/arch/tile/include/asm/highmem.h b/arch/tile/include/asm/highmem.h
new file mode 100644
index 000000000000..d155db6fa9bd
--- /dev/null
+++ b/arch/tile/include/asm/highmem.h
@@ -0,0 +1,73 @@
1/*
2 * Copyright (C) 1999 Gerhard Wichert, Siemens AG
3 * Gerhard.Wichert@pdb.siemens.de
4 * Copyright 2010 Tilera Corporation. All Rights Reserved.
5 *
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public License
8 * as published by the Free Software Foundation, version 2.
9 *
10 * This program is distributed in the hope that it will be useful, but
11 * WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, GOOD TITLE or
13 * NON INFRINGEMENT. See the GNU General Public License for
14 * more details.
15 *
16 * Used in CONFIG_HIGHMEM systems for memory pages which
17 * are not addressable by direct kernel virtual addresses.
18 *
19 */
20
21#ifndef _ASM_TILE_HIGHMEM_H
22#define _ASM_TILE_HIGHMEM_H
23
24#include <linux/interrupt.h>
25#include <linux/threads.h>
26#include <asm/kmap_types.h>
27#include <asm/tlbflush.h>
28#include <asm/homecache.h>
29
30/* declarations for highmem.c */
31extern unsigned long highstart_pfn, highend_pfn;
32
33extern pte_t *pkmap_page_table;
34
35/*
36 * Ordering is:
37 *
38 * FIXADDR_TOP
39 * fixed_addresses
40 * FIXADDR_START
41 * temp fixed addresses
42 * FIXADDR_BOOT_START
43 * Persistent kmap area
44 * PKMAP_BASE
45 * VMALLOC_END
46 * Vmalloc area
47 * VMALLOC_START
48 * high_memory
49 */
50#define LAST_PKMAP_MASK (LAST_PKMAP-1)
51#define PKMAP_NR(virt) ((virt-PKMAP_BASE) >> PAGE_SHIFT)
52#define PKMAP_ADDR(nr) (PKMAP_BASE + ((nr) << PAGE_SHIFT))
53
54void *kmap_high(struct page *page);
55void kunmap_high(struct page *page);
56void *kmap(struct page *page);
57void kunmap(struct page *page);
58void *kmap_fix_kpte(struct page *page, int finished);
59
60/* This macro is used only in map_new_virtual() to map "page". */
61#define kmap_prot page_to_kpgprot(page)
62
63void kunmap_atomic_notypecheck(void *kvaddr, enum km_type type);
64void *kmap_atomic_pfn(unsigned long pfn, enum km_type type);
65void *kmap_atomic_prot_pfn(unsigned long pfn, enum km_type type, pgprot_t prot);
66struct page *kmap_atomic_to_page(void *ptr);
67void *kmap_atomic_prot(struct page *page, enum km_type type, pgprot_t prot);
68void *kmap_atomic(struct page *page, enum km_type type);
69void kmap_atomic_fix_kpte(struct page *page, int finished);
70
71#define flush_cache_kmaps() do { } while (0)
72
73#endif /* _ASM_TILE_HIGHMEM_H */
diff --git a/arch/tile/include/asm/homecache.h b/arch/tile/include/asm/homecache.h
new file mode 100644
index 000000000000..a8243865d49e
--- /dev/null
+++ b/arch/tile/include/asm/homecache.h
@@ -0,0 +1,125 @@
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 * Handle issues around the Tile "home cache" model of coherence.
15 */
16
17#ifndef _ASM_TILE_HOMECACHE_H
18#define _ASM_TILE_HOMECACHE_H
19
20#include <asm/page.h>
21#include <linux/cpumask.h>
22
23struct page;
24struct task_struct;
25struct vm_area_struct;
26struct zone;
27
28/*
29 * Coherence point for the page is its memory controller.
30 * It is not present in any cache (L1 or L2).
31 */
32#define PAGE_HOME_UNCACHED -1
33
34/*
35 * Is this page immutable (unwritable) and thus able to be cached more
36 * widely than would otherwise be possible? On tile64 this means we
37 * mark the PTE to cache locally; on tilepro it means we have "nc" set.
38 */
39#define PAGE_HOME_IMMUTABLE -2
40
41/*
42 * Each cpu considers its own cache to be the home for the page,
43 * which makes it incoherent.
44 */
45#define PAGE_HOME_INCOHERENT -3
46
47#if CHIP_HAS_CBOX_HOME_MAP()
48/* Home for the page is distributed via hash-for-home. */
49#define PAGE_HOME_HASH -4
50#endif
51
52/* Homing is unknown or unspecified. Not valid for page_home(). */
53#define PAGE_HOME_UNKNOWN -5
54
55/* Home on the current cpu. Not valid for page_home(). */
56#define PAGE_HOME_HERE -6
57
58/* Support wrapper to use instead of explicit hv_flush_remote(). */
59extern void flush_remote(unsigned long cache_pfn, unsigned long cache_length,
60 const struct cpumask *cache_cpumask,
61 HV_VirtAddr tlb_va, unsigned long tlb_length,
62 unsigned long tlb_pgsize,
63 const struct cpumask *tlb_cpumask,
64 HV_Remote_ASID *asids, int asidcount);
65
66/* Set homing-related bits in a PTE (can also pass a pgprot_t). */
67extern pte_t pte_set_home(pte_t pte, int home);
68
69/* Do a cache eviction on the specified cpus. */
70extern void homecache_evict(const struct cpumask *mask);
71
72/*
73 * Change a kernel page's homecache. It must not be mapped in user space.
74 * If !CONFIG_HOMECACHE, only usable on LOWMEM, and can only be called when
75 * no other cpu can reference the page, and causes a full-chip cache/TLB flush.
76 */
77extern void homecache_change_page_home(struct page *, int order, int home);
78
79/*
80 * Flush a page out of whatever cache(s) it is in.
81 * This is more than just finv, since it properly handles waiting
82 * for the data to reach memory on tilepro, but it can be quite
83 * heavyweight, particularly on hash-for-home memory.
84 */
85extern void homecache_flush_cache(struct page *, int order);
86
87/*
88 * Allocate a page with the given GFP flags, home, and optionally
89 * node. These routines are actually just wrappers around the normal
90 * alloc_pages() / alloc_pages_node() functions, which set and clear
91 * a per-cpu variable to communicate with homecache_new_kernel_page().
92 * If !CONFIG_HOMECACHE, uses homecache_change_page_home().
93 */
94extern struct page *homecache_alloc_pages(gfp_t gfp_mask,
95 unsigned int order, int home);
96extern struct page *homecache_alloc_pages_node(int nid, gfp_t gfp_mask,
97 unsigned int order, int home);
98#define homecache_alloc_page(gfp_mask, home) \
99 homecache_alloc_pages(gfp_mask, 0, home)
100
101/*
102 * These routines are just pass-throughs to free_pages() when
103 * we support full homecaching. If !CONFIG_HOMECACHE, then these
104 * routines use homecache_change_page_home() to reset the home
105 * back to the default before returning the page to the allocator.
106 */
107void homecache_free_pages(unsigned long addr, unsigned int order);
108#define homecache_free_page(page) \
109 homecache_free_pages((page), 0)
110
111
112
113/*
114 * Report the page home for LOWMEM pages by examining their kernel PTE,
115 * or for highmem pages as the default home.
116 */
117extern int page_home(struct page *);
118
119#define homecache_migrate_kthread() do {} while (0)
120
121#define homecache_kpte_lock() 0
122#define homecache_kpte_unlock(flags) do {} while (0)
123
124
125#endif /* _ASM_TILE_HOMECACHE_H */
diff --git a/arch/tile/include/asm/hugetlb.h b/arch/tile/include/asm/hugetlb.h
new file mode 100644
index 000000000000..0521c277bbde
--- /dev/null
+++ b/arch/tile/include/asm/hugetlb.h
@@ -0,0 +1,109 @@
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_HUGETLB_H
16#define _ASM_TILE_HUGETLB_H
17
18#include <asm/page.h>
19
20
21static inline int is_hugepage_only_range(struct mm_struct *mm,
22 unsigned long addr,
23 unsigned long len) {
24 return 0;
25}
26
27/*
28 * If the arch doesn't supply something else, assume that hugepage
29 * size aligned regions are ok without further preparation.
30 */
31static inline int prepare_hugepage_range(struct file *file,
32 unsigned long addr, unsigned long len)
33{
34 struct hstate *h = hstate_file(file);
35 if (len & ~huge_page_mask(h))
36 return -EINVAL;
37 if (addr & ~huge_page_mask(h))
38 return -EINVAL;
39 return 0;
40}
41
42static inline void hugetlb_prefault_arch_hook(struct mm_struct *mm)
43{
44}
45
46static inline void hugetlb_free_pgd_range(struct mmu_gather *tlb,
47 unsigned long addr, unsigned long end,
48 unsigned long floor,
49 unsigned long ceiling)
50{
51 free_pgd_range(tlb, addr, end, floor, ceiling);
52}
53
54static inline void set_huge_pte_at(struct mm_struct *mm, unsigned long addr,
55 pte_t *ptep, pte_t pte)
56{
57 set_pte_order(ptep, pte, HUGETLB_PAGE_ORDER);
58}
59
60static inline pte_t huge_ptep_get_and_clear(struct mm_struct *mm,
61 unsigned long addr, pte_t *ptep)
62{
63 return ptep_get_and_clear(mm, addr, ptep);
64}
65
66static inline void huge_ptep_clear_flush(struct vm_area_struct *vma,
67 unsigned long addr, pte_t *ptep)
68{
69 ptep_clear_flush(vma, addr, ptep);
70}
71
72static inline int huge_pte_none(pte_t pte)
73{
74 return pte_none(pte);
75}
76
77static inline pte_t huge_pte_wrprotect(pte_t pte)
78{
79 return pte_wrprotect(pte);
80}
81
82static inline void huge_ptep_set_wrprotect(struct mm_struct *mm,
83 unsigned long addr, pte_t *ptep)
84{
85 ptep_set_wrprotect(mm, addr, ptep);
86}
87
88static inline int huge_ptep_set_access_flags(struct vm_area_struct *vma,
89 unsigned long addr, pte_t *ptep,
90 pte_t pte, int dirty)
91{
92 return ptep_set_access_flags(vma, addr, ptep, pte, dirty);
93}
94
95static inline pte_t huge_ptep_get(pte_t *ptep)
96{
97 return *ptep;
98}
99
100static inline int arch_prepare_hugepage(struct page *page)
101{
102 return 0;
103}
104
105static inline void arch_release_hugepage(struct page *page)
106{
107}
108
109#endif /* _ASM_TILE_HUGETLB_H */
diff --git a/arch/tile/include/asm/hv_driver.h b/arch/tile/include/asm/hv_driver.h
new file mode 100644
index 000000000000..ad614de899b3
--- /dev/null
+++ b/arch/tile/include/asm/hv_driver.h
@@ -0,0 +1,60 @@
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 * This header defines a wrapper interface for managing hypervisor
15 * device calls that will result in an interrupt at some later time.
16 * In particular, this provides wrappers for hv_preada() and
17 * hv_pwritea().
18 */
19
20#ifndef _ASM_TILE_HV_DRIVER_H
21#define _ASM_TILE_HV_DRIVER_H
22
23#include <hv/hypervisor.h>
24
25struct hv_driver_cb;
26
27/* A callback to be invoked when an operation completes. */
28typedef void hv_driver_callback_t(struct hv_driver_cb *cb, __hv32 result);
29
30/*
31 * A structure to hold information about an outstanding call.
32 * The driver must allocate a separate structure for each call.
33 */
34struct hv_driver_cb {
35 hv_driver_callback_t *callback; /* Function to call on interrupt. */
36 void *dev; /* Driver-specific state variable. */
37};
38
39/* Wrapper for invoking hv_dev_preada(). */
40static inline int
41tile_hv_dev_preada(int devhdl, __hv32 flags, __hv32 sgl_len,
42 HV_SGL sgl[/* sgl_len */], __hv64 offset,
43 struct hv_driver_cb *callback)
44{
45 return hv_dev_preada(devhdl, flags, sgl_len, sgl,
46 offset, (HV_IntArg)callback);
47}
48
49/* Wrapper for invoking hv_dev_pwritea(). */
50static inline int
51tile_hv_dev_pwritea(int devhdl, __hv32 flags, __hv32 sgl_len,
52 HV_SGL sgl[/* sgl_len */], __hv64 offset,
53 struct hv_driver_cb *callback)
54{
55 return hv_dev_pwritea(devhdl, flags, sgl_len, sgl,
56 offset, (HV_IntArg)callback);
57}
58
59
60#endif /* _ASM_TILE_HV_DRIVER_H */
diff --git a/arch/tile/include/asm/hw_irq.h b/arch/tile/include/asm/hw_irq.h
new file mode 100644
index 000000000000..4fac5fbf333e
--- /dev/null
+++ b/arch/tile/include/asm/hw_irq.h
@@ -0,0 +1,18 @@
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_HW_IRQ_H
16#define _ASM_TILE_HW_IRQ_H
17
18#endif /* _ASM_TILE_HW_IRQ_H */
diff --git a/arch/tile/include/asm/ide.h b/arch/tile/include/asm/ide.h
new file mode 100644
index 000000000000..3c6f2ed894ce
--- /dev/null
+++ b/arch/tile/include/asm/ide.h
@@ -0,0 +1,25 @@
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_IDE_H
16#define _ASM_TILE_IDE_H
17
18/* For IDE on PCI */
19#define MAX_HWIFS 10
20
21#define ide_default_io_ctl(base) (0)
22
23#include <asm-generic/ide_iops.h>
24
25#endif /* _ASM_TILE_IDE_H */
diff --git a/arch/tile/include/asm/io.h b/arch/tile/include/asm/io.h
new file mode 100644
index 000000000000..8c95bef3fa45
--- /dev/null
+++ b/arch/tile/include/asm/io.h
@@ -0,0 +1,279 @@
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_IO_H
16#define _ASM_TILE_IO_H
17
18#include <linux/kernel.h>
19#include <linux/bug.h>
20#include <asm/page.h>
21
22#define IO_SPACE_LIMIT 0xfffffffful
23
24/*
25 * Convert a physical pointer to a virtual kernel pointer for /dev/mem
26 * access.
27 */
28#define xlate_dev_mem_ptr(p) __va(p)
29
30/*
31 * Convert a virtual cached pointer to an uncached pointer.
32 */
33#define xlate_dev_kmem_ptr(p) p
34
35/*
36 * Change "struct page" to physical address.
37 */
38#define page_to_phys(page) ((dma_addr_t)page_to_pfn(page) << PAGE_SHIFT)
39
40/*
41 * Some places try to pass in an loff_t for PHYSADDR (?!), so we cast it to
42 * long before casting it to a pointer to avoid compiler warnings.
43 */
44#if CHIP_HAS_MMIO()
45extern void __iomem *ioremap(resource_size_t offset, unsigned long size);
46extern void __iomem *ioremap_prot(resource_size_t offset, unsigned long size,
47 pgprot_t pgprot);
48extern void iounmap(volatile void __iomem *addr);
49#else
50#define ioremap(physaddr, size) ((void __iomem *)(unsigned long)(physaddr))
51#define iounmap(addr) ((void)0)
52#endif
53
54#define ioremap_nocache(physaddr, size) ioremap(physaddr, size)
55#define ioremap_writethrough(physaddr, size) ioremap(physaddr, size)
56#define ioremap_fullcache(physaddr, size) ioremap(physaddr, size)
57
58void __iomem *ioport_map(unsigned long port, unsigned int len);
59extern inline void ioport_unmap(void __iomem *addr) {}
60
61#define mmiowb()
62
63/* Conversion between virtual and physical mappings. */
64#define mm_ptov(addr) ((void *)phys_to_virt(addr))
65#define mm_vtop(addr) ((unsigned long)virt_to_phys(addr))
66
67#ifdef CONFIG_PCI
68
69extern u8 _tile_readb(unsigned long addr);
70extern u16 _tile_readw(unsigned long addr);
71extern u32 _tile_readl(unsigned long addr);
72extern u64 _tile_readq(unsigned long addr);
73extern void _tile_writeb(u8 val, unsigned long addr);
74extern void _tile_writew(u16 val, unsigned long addr);
75extern void _tile_writel(u32 val, unsigned long addr);
76extern void _tile_writeq(u64 val, unsigned long addr);
77
78#else
79
80/*
81 * The Tile architecture does not support IOMEM unless PCI is enabled.
82 * Unfortunately we can't yet simply not declare these methods,
83 * since some generic code that compiles into the kernel, but
84 * we never run, uses them unconditionally.
85 */
86
87static inline int iomem_panic(void)
88{
89 panic("readb/writeb and friends do not exist on tile without PCI");
90 return 0;
91}
92
93static inline u8 _tile_readb(unsigned long addr)
94{
95 return iomem_panic();
96}
97
98static inline u16 _tile_readw(unsigned long addr)
99{
100 return iomem_panic();
101}
102
103static inline u32 _tile_readl(unsigned long addr)
104{
105 return iomem_panic();
106}
107
108static inline u64 _tile_readq(unsigned long addr)
109{
110 return iomem_panic();
111}
112
113static inline void _tile_writeb(u8 val, unsigned long addr)
114{
115 iomem_panic();
116}
117
118static inline void _tile_writew(u16 val, unsigned long addr)
119{
120 iomem_panic();
121}
122
123static inline void _tile_writel(u32 val, unsigned long addr)
124{
125 iomem_panic();
126}
127
128static inline void _tile_writeq(u64 val, unsigned long addr)
129{
130 iomem_panic();
131}
132
133#endif
134
135#define readb(addr) _tile_readb((unsigned long)addr)
136#define readw(addr) _tile_readw((unsigned long)addr)
137#define readl(addr) _tile_readl((unsigned long)addr)
138#define readq(addr) _tile_readq((unsigned long)addr)
139#define writeb(val, addr) _tile_writeb(val, (unsigned long)addr)
140#define writew(val, addr) _tile_writew(val, (unsigned long)addr)
141#define writel(val, addr) _tile_writel(val, (unsigned long)addr)
142#define writeq(val, addr) _tile_writeq(val, (unsigned long)addr)
143
144#define __raw_readb readb
145#define __raw_readw readw
146#define __raw_readl readl
147#define __raw_readq readq
148#define __raw_writeb writeb
149#define __raw_writew writew
150#define __raw_writel writel
151#define __raw_writeq writeq
152
153#define readb_relaxed readb
154#define readw_relaxed readw
155#define readl_relaxed readl
156#define readq_relaxed readq
157
158#define ioread8 readb
159#define ioread16 readw
160#define ioread32 readl
161#define ioread64 readq
162#define iowrite8 writeb
163#define iowrite16 writew
164#define iowrite32 writel
165#define iowrite64 writeq
166
167static inline void *memcpy_fromio(void *dst, void *src, int len)
168{
169 int x;
170 BUG_ON((unsigned long)src & 0x3);
171 for (x = 0; x < len; x += 4)
172 *(u32 *)(dst + x) = readl(src + x);
173 return dst;
174}
175
176static inline void *memcpy_toio(void *dst, void *src, int len)
177{
178 int x;
179 BUG_ON((unsigned long)dst & 0x3);
180 for (x = 0; x < len; x += 4)
181 writel(*(u32 *)(src + x), dst + x);
182 return dst;
183}
184
185/*
186 * The Tile architecture does not support IOPORT, even with PCI.
187 * Unfortunately we can't yet simply not declare these methods,
188 * since some generic code that compiles into the kernel, but
189 * we never run, uses them unconditionally.
190 */
191
192static inline int ioport_panic(void)
193{
194 panic("inb/outb and friends do not exist on tile");
195 return 0;
196}
197
198static inline u8 inb(unsigned long addr)
199{
200 return ioport_panic();
201}
202
203static inline u16 inw(unsigned long addr)
204{
205 return ioport_panic();
206}
207
208static inline u32 inl(unsigned long addr)
209{
210 return ioport_panic();
211}
212
213static inline void outb(u8 b, unsigned long addr)
214{
215 ioport_panic();
216}
217
218static inline void outw(u16 b, unsigned long addr)
219{
220 ioport_panic();
221}
222
223static inline void outl(u32 b, unsigned long addr)
224{
225 ioport_panic();
226}
227
228#define inb_p(addr) inb(addr)
229#define inw_p(addr) inw(addr)
230#define inl_p(addr) inl(addr)
231#define outb_p(x, addr) outb((x), (addr))
232#define outw_p(x, addr) outw((x), (addr))
233#define outl_p(x, addr) outl((x), (addr))
234
235static inline void insb(unsigned long addr, void *buffer, int count)
236{
237 ioport_panic();
238}
239
240static inline void insw(unsigned long addr, void *buffer, int count)
241{
242 ioport_panic();
243}
244
245static inline void insl(unsigned long addr, void *buffer, int count)
246{
247 ioport_panic();
248}
249
250static inline void outsb(unsigned long addr, const void *buffer, int count)
251{
252 ioport_panic();
253}
254
255static inline void outsw(unsigned long addr, const void *buffer, int count)
256{
257 ioport_panic();
258}
259
260static inline void outsl(unsigned long addr, const void *buffer, int count)
261{
262 ioport_panic();
263}
264
265#define ioread8_rep(p, dst, count) \
266 insb((unsigned long) (p), (dst), (count))
267#define ioread16_rep(p, dst, count) \
268 insw((unsigned long) (p), (dst), (count))
269#define ioread32_rep(p, dst, count) \
270 insl((unsigned long) (p), (dst), (count))
271
272#define iowrite8_rep(p, src, count) \
273 outsb((unsigned long) (p), (src), (count))
274#define iowrite16_rep(p, src, count) \
275 outsw((unsigned long) (p), (src), (count))
276#define iowrite32_rep(p, src, count) \
277 outsl((unsigned long) (p), (src), (count))
278
279#endif /* _ASM_TILE_IO_H */
diff --git a/arch/tile/include/asm/ioctl.h b/arch/tile/include/asm/ioctl.h
new file mode 100644
index 000000000000..b279fe06dfe5
--- /dev/null
+++ b/arch/tile/include/asm/ioctl.h
@@ -0,0 +1 @@
#include <asm-generic/ioctl.h>
diff --git a/arch/tile/include/asm/ioctls.h b/arch/tile/include/asm/ioctls.h
new file mode 100644
index 000000000000..ec34c760665e
--- /dev/null
+++ b/arch/tile/include/asm/ioctls.h
@@ -0,0 +1 @@
#include <asm-generic/ioctls.h>
diff --git a/arch/tile/include/asm/ipc.h b/arch/tile/include/asm/ipc.h
new file mode 100644
index 000000000000..a46e3d9c2a3f
--- /dev/null
+++ b/arch/tile/include/asm/ipc.h
@@ -0,0 +1 @@
#include <asm-generic/ipc.h>
diff --git a/arch/tile/include/asm/ipcbuf.h b/arch/tile/include/asm/ipcbuf.h
new file mode 100644
index 000000000000..84c7e51cb6d0
--- /dev/null
+++ b/arch/tile/include/asm/ipcbuf.h
@@ -0,0 +1 @@
#include <asm-generic/ipcbuf.h>
diff --git a/arch/tile/include/asm/irq.h b/arch/tile/include/asm/irq.h
new file mode 100644
index 000000000000..572fd3ef1d73
--- /dev/null
+++ b/arch/tile/include/asm/irq.h
@@ -0,0 +1,87 @@
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_IRQ_H
16#define _ASM_TILE_IRQ_H
17
18#include <linux/hardirq.h>
19
20/* The hypervisor interface provides 32 IRQs. */
21#define NR_IRQS 32
22
23/* IRQ numbers used for linux IPIs. */
24#define IRQ_RESCHEDULE 1
25
26void ack_bad_irq(unsigned int irq);
27
28/*
29 * Different ways of handling interrupts. Tile interrupts are always
30 * per-cpu; there is no global interrupt controller to implement
31 * enable/disable. Most onboard devices can send their interrupts to
32 * many tiles at the same time, and Tile-specific drivers know how to
33 * deal with this.
34 *
35 * However, generic devices (usually PCIE based, sometimes GPIO)
36 * expect that interrupts will fire on a single core at a time and
37 * that the irq can be enabled or disabled from any core at any time.
38 * We implement this by directing such interrupts to a single core.
39 *
40 * One added wrinkle is that PCI interrupts can be either
41 * hardware-cleared (legacy interrupts) or software cleared (MSI).
42 * Other generic device systems (GPIO) are always software-cleared.
43 *
44 * The enums below are used by drivers for onboard devices, including
45 * the internals of PCI root complex and GPIO. They allow the driver
46 * to tell the generic irq code what kind of interrupt is mapped to a
47 * particular IRQ number.
48 */
49enum {
50 /* per-cpu interrupt; use enable/disable_percpu_irq() to mask */
51 TILE_IRQ_PERCPU,
52 /* global interrupt, hardware responsible for clearing. */
53 TILE_IRQ_HW_CLEAR,
54 /* global interrupt, software responsible for clearing. */
55 TILE_IRQ_SW_CLEAR,
56};
57
58
59/*
60 * Paravirtualized drivers should call this when they dynamically
61 * allocate a new IRQ or discover an IRQ that was pre-allocated by the
62 * hypervisor for use with their particular device. This gives the
63 * IRQ subsystem an opportunity to do interrupt-type-specific
64 * initialization.
65 *
66 * ISSUE: We should modify this API so that registering anything
67 * except percpu interrupts also requires providing callback methods
68 * for enabling and disabling the interrupt. This would allow the
69 * generic IRQ code to proxy enable/disable_irq() calls back into the
70 * PCI subsystem, which in turn could enable or disable the interrupt
71 * at the PCI shim.
72 */
73void tile_irq_activate(unsigned int irq, int tile_irq_type);
74
75/*
76 * For onboard, non-PCI (e.g. TILE_IRQ_PERCPU) devices, drivers know
77 * how to use enable/disable_percpu_irq() to manage interrupts on each
78 * core. We can't use the generic enable/disable_irq() because they
79 * use a single reference count per irq, rather than per cpu per irq.
80 */
81void enable_percpu_irq(unsigned int irq);
82void disable_percpu_irq(unsigned int irq);
83
84
85void setup_irq_regs(void);
86
87#endif /* _ASM_TILE_IRQ_H */
diff --git a/arch/tile/include/asm/irq_regs.h b/arch/tile/include/asm/irq_regs.h
new file mode 100644
index 000000000000..3dd9c0b70270
--- /dev/null
+++ b/arch/tile/include/asm/irq_regs.h
@@ -0,0 +1 @@
#include <asm-generic/irq_regs.h>
diff --git a/arch/tile/include/asm/irqflags.h b/arch/tile/include/asm/irqflags.h
new file mode 100644
index 000000000000..45cf67c2f286
--- /dev/null
+++ b/arch/tile/include/asm/irqflags.h
@@ -0,0 +1,266 @@
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_IRQFLAGS_H
16#define _ASM_TILE_IRQFLAGS_H
17
18#include <arch/interrupts.h>
19#include <arch/chip.h>
20
21/*
22 * The set of interrupts we want to allow when interrupts are nominally
23 * disabled. The remainder are effectively "NMI" interrupts from
24 * the point of view of the generic Linux code. Note that synchronous
25 * interrupts (aka "non-queued") are not blocked by the mask in any case.
26 */
27#if CHIP_HAS_AUX_PERF_COUNTERS()
28#define LINUX_MASKABLE_INTERRUPTS \
29 (~(INT_MASK(INT_PERF_COUNT) | INT_MASK(INT_AUX_PERF_COUNT)))
30#else
31#define LINUX_MASKABLE_INTERRUPTS \
32 (~(INT_MASK(INT_PERF_COUNT)))
33#endif
34
35#ifndef __ASSEMBLY__
36
37/* NOTE: we can't include <linux/percpu.h> due to #include dependencies. */
38#include <asm/percpu.h>
39#include <arch/spr_def.h>
40
41/* Set and clear kernel interrupt masks. */
42#if CHIP_HAS_SPLIT_INTR_MASK()
43#if INT_PERF_COUNT < 32 || INT_AUX_PERF_COUNT < 32 || INT_MEM_ERROR >= 32
44# error Fix assumptions about which word various interrupts are in
45#endif
46#define interrupt_mask_set(n) do { \
47 int __n = (n); \
48 int __mask = 1 << (__n & 0x1f); \
49 if (__n < 32) \
50 __insn_mtspr(SPR_INTERRUPT_MASK_SET_1_0, __mask); \
51 else \
52 __insn_mtspr(SPR_INTERRUPT_MASK_SET_1_1, __mask); \
53} while (0)
54#define interrupt_mask_reset(n) do { \
55 int __n = (n); \
56 int __mask = 1 << (__n & 0x1f); \
57 if (__n < 32) \
58 __insn_mtspr(SPR_INTERRUPT_MASK_RESET_1_0, __mask); \
59 else \
60 __insn_mtspr(SPR_INTERRUPT_MASK_RESET_1_1, __mask); \
61} while (0)
62#define interrupt_mask_check(n) ({ \
63 int __n = (n); \
64 (((__n < 32) ? \
65 __insn_mfspr(SPR_INTERRUPT_MASK_1_0) : \
66 __insn_mfspr(SPR_INTERRUPT_MASK_1_1)) \
67 >> (__n & 0x1f)) & 1; \
68})
69#define interrupt_mask_set_mask(mask) do { \
70 unsigned long long __m = (mask); \
71 __insn_mtspr(SPR_INTERRUPT_MASK_SET_1_0, (unsigned long)(__m)); \
72 __insn_mtspr(SPR_INTERRUPT_MASK_SET_1_1, (unsigned long)(__m>>32)); \
73} while (0)
74#define interrupt_mask_reset_mask(mask) do { \
75 unsigned long long __m = (mask); \
76 __insn_mtspr(SPR_INTERRUPT_MASK_RESET_1_0, (unsigned long)(__m)); \
77 __insn_mtspr(SPR_INTERRUPT_MASK_RESET_1_1, (unsigned long)(__m>>32)); \
78} while (0)
79#else
80#define interrupt_mask_set(n) \
81 __insn_mtspr(SPR_INTERRUPT_MASK_SET_1, (1UL << (n)))
82#define interrupt_mask_reset(n) \
83 __insn_mtspr(SPR_INTERRUPT_MASK_RESET_1, (1UL << (n)))
84#define interrupt_mask_check(n) \
85 ((__insn_mfspr(SPR_INTERRUPT_MASK_1) >> (n)) & 1)
86#define interrupt_mask_set_mask(mask) \
87 __insn_mtspr(SPR_INTERRUPT_MASK_SET_1, (mask))
88#define interrupt_mask_reset_mask(mask) \
89 __insn_mtspr(SPR_INTERRUPT_MASK_RESET_1, (mask))
90#endif
91
92/*
93 * The set of interrupts we want active if irqs are enabled.
94 * Note that in particular, the tile timer interrupt comes and goes
95 * from this set, since we have no other way to turn off the timer.
96 * Likewise, INTCTRL_1 is removed and re-added during device
97 * interrupts, as is the the hardwall UDN_FIREWALL interrupt.
98 * We use a low bit (MEM_ERROR) as our sentinel value and make sure it
99 * is always claimed as an "active interrupt" so we can query that bit
100 * to know our current state.
101 */
102DECLARE_PER_CPU(unsigned long long, interrupts_enabled_mask);
103#define INITIAL_INTERRUPTS_ENABLED INT_MASK(INT_MEM_ERROR)
104
105/* Disable interrupts. */
106#define raw_local_irq_disable() \
107 interrupt_mask_set_mask(LINUX_MASKABLE_INTERRUPTS)
108
109/* Disable all interrupts, including NMIs. */
110#define raw_local_irq_disable_all() \
111 interrupt_mask_set_mask(-1UL)
112
113/* Re-enable all maskable interrupts. */
114#define raw_local_irq_enable() \
115 interrupt_mask_reset_mask(__get_cpu_var(interrupts_enabled_mask))
116
117/* Disable or enable interrupts based on flag argument. */
118#define raw_local_irq_restore(disabled) do { \
119 if (disabled) \
120 raw_local_irq_disable(); \
121 else \
122 raw_local_irq_enable(); \
123} while (0)
124
125/* Return true if "flags" argument means interrupts are disabled. */
126#define raw_irqs_disabled_flags(flags) ((flags) != 0)
127
128/* Return true if interrupts are currently disabled. */
129#define raw_irqs_disabled() interrupt_mask_check(INT_MEM_ERROR)
130
131/* Save whether interrupts are currently disabled. */
132#define raw_local_save_flags(flags) ((flags) = raw_irqs_disabled())
133
134/* Save whether interrupts are currently disabled, then disable them. */
135#define raw_local_irq_save(flags) \
136 do { raw_local_save_flags(flags); raw_local_irq_disable(); } while (0)
137
138/* Prevent the given interrupt from being enabled next time we enable irqs. */
139#define raw_local_irq_mask(interrupt) \
140 (__get_cpu_var(interrupts_enabled_mask) &= ~INT_MASK(interrupt))
141
142/* Prevent the given interrupt from being enabled immediately. */
143#define raw_local_irq_mask_now(interrupt) do { \
144 raw_local_irq_mask(interrupt); \
145 interrupt_mask_set(interrupt); \
146} while (0)
147
148/* Allow the given interrupt to be enabled next time we enable irqs. */
149#define raw_local_irq_unmask(interrupt) \
150 (__get_cpu_var(interrupts_enabled_mask) |= INT_MASK(interrupt))
151
152/* Allow the given interrupt to be enabled immediately, if !irqs_disabled. */
153#define raw_local_irq_unmask_now(interrupt) do { \
154 raw_local_irq_unmask(interrupt); \
155 if (!irqs_disabled()) \
156 interrupt_mask_reset(interrupt); \
157} while (0)
158
159#else /* __ASSEMBLY__ */
160
161/* We provide a somewhat more restricted set for assembly. */
162
163#ifdef __tilegx__
164
165#if INT_MEM_ERROR != 0
166# error Fix IRQ_DISABLED() macro
167#endif
168
169/* Return 0 or 1 to indicate whether interrupts are currently disabled. */
170#define IRQS_DISABLED(tmp) \
171 mfspr tmp, INTERRUPT_MASK_1; \
172 andi tmp, tmp, 1
173
174/* Load up a pointer to &interrupts_enabled_mask. */
175#define GET_INTERRUPTS_ENABLED_MASK_PTR(reg) \
176 moveli reg, hw2_last(interrupts_enabled_mask); \
177 shl16insli reg, reg, hw1(interrupts_enabled_mask); \
178 shl16insli reg, reg, hw0(interrupts_enabled_mask); \
179 add reg, reg, tp
180
181/* Disable interrupts. */
182#define IRQ_DISABLE(tmp0, tmp1) \
183 moveli tmp0, hw2_last(LINUX_MASKABLE_INTERRUPTS); \
184 shl16insli tmp0, tmp0, hw1(LINUX_MASKABLE_INTERRUPTS); \
185 shl16insli tmp0, tmp0, hw0(LINUX_MASKABLE_INTERRUPTS); \
186 mtspr INTERRUPT_MASK_SET_1, tmp0
187
188/* Disable ALL synchronous interrupts (used by NMI entry). */
189#define IRQ_DISABLE_ALL(tmp) \
190 movei tmp, -1; \
191 mtspr INTERRUPT_MASK_SET_1, tmp
192
193/* Enable interrupts. */
194#define IRQ_ENABLE(tmp0, tmp1) \
195 GET_INTERRUPTS_ENABLED_MASK_PTR(tmp0); \
196 ld tmp0, tmp0; \
197 mtspr INTERRUPT_MASK_RESET_1, tmp0
198
199#else /* !__tilegx__ */
200
201/*
202 * Return 0 or 1 to indicate whether interrupts are currently disabled.
203 * Note that it's important that we use a bit from the "low" mask word,
204 * since when we are enabling, that is the word we write first, so if we
205 * are interrupted after only writing half of the mask, the interrupt
206 * handler will correctly observe that we have interrupts enabled, and
207 * will enable interrupts itself on return from the interrupt handler
208 * (making the original code's write of the "high" mask word idempotent).
209 */
210#define IRQS_DISABLED(tmp) \
211 mfspr tmp, INTERRUPT_MASK_1_0; \
212 shri tmp, tmp, INT_MEM_ERROR; \
213 andi tmp, tmp, 1
214
215/* Load up a pointer to &interrupts_enabled_mask. */
216#define GET_INTERRUPTS_ENABLED_MASK_PTR(reg) \
217 moveli reg, lo16(interrupts_enabled_mask); \
218 auli reg, reg, ha16(interrupts_enabled_mask);\
219 add reg, reg, tp
220
221/* Disable interrupts. */
222#define IRQ_DISABLE(tmp0, tmp1) \
223 { \
224 movei tmp0, -1; \
225 moveli tmp1, lo16(LINUX_MASKABLE_INTERRUPTS) \
226 }; \
227 { \
228 mtspr INTERRUPT_MASK_SET_1_0, tmp0; \
229 auli tmp1, tmp1, ha16(LINUX_MASKABLE_INTERRUPTS) \
230 }; \
231 mtspr INTERRUPT_MASK_SET_1_1, tmp1
232
233/* Disable ALL synchronous interrupts (used by NMI entry). */
234#define IRQ_DISABLE_ALL(tmp) \
235 movei tmp, -1; \
236 mtspr INTERRUPT_MASK_SET_1_0, tmp; \
237 mtspr INTERRUPT_MASK_SET_1_1, tmp
238
239/* Enable interrupts. */
240#define IRQ_ENABLE(tmp0, tmp1) \
241 GET_INTERRUPTS_ENABLED_MASK_PTR(tmp0); \
242 { \
243 lw tmp0, tmp0; \
244 addi tmp1, tmp0, 4 \
245 }; \
246 lw tmp1, tmp1; \
247 mtspr INTERRUPT_MASK_RESET_1_0, tmp0; \
248 mtspr INTERRUPT_MASK_RESET_1_1, tmp1
249#endif
250
251/*
252 * Do the CPU's IRQ-state tracing from assembly code. We call a
253 * C function, but almost everywhere we do, we don't mind clobbering
254 * all the caller-saved registers.
255 */
256#ifdef CONFIG_TRACE_IRQFLAGS
257# define TRACE_IRQS_ON jal trace_hardirqs_on
258# define TRACE_IRQS_OFF jal trace_hardirqs_off
259#else
260# define TRACE_IRQS_ON
261# define TRACE_IRQS_OFF
262#endif
263
264#endif /* __ASSEMBLY__ */
265
266#endif /* _ASM_TILE_IRQFLAGS_H */
diff --git a/arch/tile/include/asm/kdebug.h b/arch/tile/include/asm/kdebug.h
new file mode 100644
index 000000000000..6ece1b037665
--- /dev/null
+++ b/arch/tile/include/asm/kdebug.h
@@ -0,0 +1 @@
#include <asm-generic/kdebug.h>
diff --git a/arch/tile/include/asm/kexec.h b/arch/tile/include/asm/kexec.h
new file mode 100644
index 000000000000..c11a6cc73bb8
--- /dev/null
+++ b/arch/tile/include/asm/kexec.h
@@ -0,0 +1,53 @@
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 * based on kexec.h from other architectures in linux-2.6.18
15 */
16
17#ifndef _ASM_TILE_KEXEC_H
18#define _ASM_TILE_KEXEC_H
19
20#include <asm/page.h>
21
22/* Maximum physical address we can use pages from. */
23#define KEXEC_SOURCE_MEMORY_LIMIT TASK_SIZE
24/* Maximum address we can reach in physical address mode. */
25#define KEXEC_DESTINATION_MEMORY_LIMIT TASK_SIZE
26/* Maximum address we can use for the control code buffer. */
27#define KEXEC_CONTROL_MEMORY_LIMIT TASK_SIZE
28
29#define KEXEC_CONTROL_PAGE_SIZE PAGE_SIZE
30
31/*
32 * We don't bother to provide a unique identifier, since we can only
33 * reboot with a single type of kernel image anyway.
34 */
35#define KEXEC_ARCH KEXEC_ARCH_DEFAULT
36
37/* Use the tile override for the page allocator. */
38struct page *kimage_alloc_pages_arch(gfp_t gfp_mask, unsigned int order);
39#define kimage_alloc_pages_arch kimage_alloc_pages_arch
40
41#define MAX_NOTE_BYTES 1024
42
43/* Defined in arch/tile/kernel/relocate_kernel.S */
44extern const unsigned char relocate_new_kernel[];
45extern const unsigned long relocate_new_kernel_size;
46extern void relocate_new_kernel_end(void);
47
48/* Provide a dummy definition to avoid build failures. */
49static inline void crash_setup_regs(struct pt_regs *n, struct pt_regs *o)
50{
51}
52
53#endif /* _ASM_TILE_KEXEC_H */
diff --git a/arch/tile/include/asm/kmap_types.h b/arch/tile/include/asm/kmap_types.h
new file mode 100644
index 000000000000..1480106d1c05
--- /dev/null
+++ b/arch/tile/include/asm/kmap_types.h
@@ -0,0 +1,43 @@
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_KMAP_TYPES_H
16#define _ASM_TILE_KMAP_TYPES_H
17
18/*
19 * In TILE Linux each set of four of these uses another 16MB chunk of
20 * address space, given 64 tiles and 64KB pages, so we only enable
21 * ones that are required by the kernel configuration.
22 */
23enum km_type {
24 KM_BOUNCE_READ,
25 KM_SKB_SUNRPC_DATA,
26 KM_SKB_DATA_SOFTIRQ,
27 KM_USER0,
28 KM_USER1,
29 KM_BIO_SRC_IRQ,
30 KM_IRQ0,
31 KM_IRQ1,
32 KM_SOFTIRQ0,
33 KM_SOFTIRQ1,
34 KM_MEMCPY0,
35 KM_MEMCPY1,
36#if defined(CONFIG_HIGHPTE)
37 KM_PTE0,
38 KM_PTE1,
39#endif
40 KM_TYPE_NR
41};
42
43#endif /* _ASM_TILE_KMAP_TYPES_H */
diff --git a/arch/tile/include/asm/linkage.h b/arch/tile/include/asm/linkage.h
new file mode 100644
index 000000000000..e121c39751a7
--- /dev/null
+++ b/arch/tile/include/asm/linkage.h
@@ -0,0 +1,51 @@
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_LINKAGE_H
16#define _ASM_TILE_LINKAGE_H
17
18#include <feedback.h>
19
20#define __ALIGN .align 8
21
22/*
23 * The STD_ENTRY and STD_ENDPROC macros put the function in a
24 * self-named .text.foo section, and if linker feedback collection
25 * is enabled, add a suitable call to the feedback collection code.
26 * STD_ENTRY_SECTION lets you specify a non-standard section name.
27 */
28
29#define STD_ENTRY(name) \
30 .pushsection .text.##name, "ax"; \
31 ENTRY(name); \
32 FEEDBACK_ENTER(name)
33
34#define STD_ENTRY_SECTION(name, section) \
35 .pushsection section, "ax"; \
36 ENTRY(name); \
37 FEEDBACK_ENTER_EXPLICIT(name, section, .Lend_##name - name)
38
39#define STD_ENDPROC(name) \
40 ENDPROC(name); \
41 .Lend_##name:; \
42 .popsection
43
44/* Create a file-static function entry set up for feedback gathering. */
45#define STD_ENTRY_LOCAL(name) \
46 .pushsection .text.##name, "ax"; \
47 ALIGN; \
48 name:; \
49 FEEDBACK_ENTER(name)
50
51#endif /* _ASM_TILE_LINKAGE_H */
diff --git a/arch/tile/include/asm/local.h b/arch/tile/include/asm/local.h
new file mode 100644
index 000000000000..c11c530f74d0
--- /dev/null
+++ b/arch/tile/include/asm/local.h
@@ -0,0 +1 @@
#include <asm-generic/local.h>
diff --git a/arch/tile/include/asm/memprof.h b/arch/tile/include/asm/memprof.h
new file mode 100644
index 000000000000..359949be28c1
--- /dev/null
+++ b/arch/tile/include/asm/memprof.h
@@ -0,0 +1,33 @@
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 * The hypervisor's memory controller profiling infrastructure allows
15 * the programmer to find out what fraction of the available memory
16 * bandwidth is being consumed at each memory controller. The
17 * profiler provides start, stop, and clear operations to allows
18 * profiling over a specific time window, as well as an interface for
19 * reading the most recent profile values.
20 *
21 * This header declares IOCTL codes necessary to control memprof.
22 */
23#ifndef _ASM_TILE_MEMPROF_H
24#define _ASM_TILE_MEMPROF_H
25
26#include <linux/ioctl.h>
27
28#define MEMPROF_IOCTL_TYPE 0xB4
29#define MEMPROF_IOCTL_START _IO(MEMPROF_IOCTL_TYPE, 0)
30#define MEMPROF_IOCTL_STOP _IO(MEMPROF_IOCTL_TYPE, 1)
31#define MEMPROF_IOCTL_CLEAR _IO(MEMPROF_IOCTL_TYPE, 2)
32
33#endif /* _ASM_TILE_MEMPROF_H */
diff --git a/arch/tile/include/asm/mman.h b/arch/tile/include/asm/mman.h
new file mode 100644
index 000000000000..4c6811e3e8dc
--- /dev/null
+++ b/arch/tile/include/asm/mman.h
@@ -0,0 +1,40 @@
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_MMAN_H
16#define _ASM_TILE_MMAN_H
17
18#include <asm-generic/mman-common.h>
19#include <arch/chip.h>
20
21/* Standard Linux flags */
22
23#define MAP_POPULATE 0x0040 /* populate (prefault) pagetables */
24#define MAP_NONBLOCK 0x0080 /* do not block on IO */
25#define MAP_GROWSDOWN 0x0100 /* stack-like segment */
26#define MAP_LOCKED 0x0200 /* pages are locked */
27#define MAP_NORESERVE 0x0400 /* don't check for reservations */
28#define MAP_DENYWRITE 0x0800 /* ETXTBSY */
29#define MAP_EXECUTABLE 0x1000 /* mark it as an executable */
30#define MAP_HUGETLB 0x4000 /* create a huge page mapping */
31
32
33/*
34 * Flags for mlockall
35 */
36#define MCL_CURRENT 1 /* lock all current mappings */
37#define MCL_FUTURE 2 /* lock all future mappings */
38
39
40#endif /* _ASM_TILE_MMAN_H */
diff --git a/arch/tile/include/asm/mmu.h b/arch/tile/include/asm/mmu.h
new file mode 100644
index 000000000000..92f94c77b6e4
--- /dev/null
+++ b/arch/tile/include/asm/mmu.h
@@ -0,0 +1,31 @@
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_MMU_H
16#define _ASM_TILE_MMU_H
17
18/* Capture any arch- and mm-specific information. */
19struct mm_context {
20 /*
21 * Written under the mmap_sem semaphore; read without the
22 * semaphore but atomically, but it is conservatively set.
23 */
24 unsigned int priority_cached;
25};
26
27typedef struct mm_context mm_context_t;
28
29void leave_mm(int cpu);
30
31#endif /* _ASM_TILE_MMU_H */
diff --git a/arch/tile/include/asm/mmu_context.h b/arch/tile/include/asm/mmu_context.h
new file mode 100644
index 000000000000..9bc0d0725c28
--- /dev/null
+++ b/arch/tile/include/asm/mmu_context.h
@@ -0,0 +1,131 @@
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_MMU_CONTEXT_H
16#define _ASM_TILE_MMU_CONTEXT_H
17
18#include <linux/smp.h>
19#include <asm/setup.h>
20#include <asm/page.h>
21#include <asm/pgalloc.h>
22#include <asm/pgtable.h>
23#include <asm/tlbflush.h>
24#include <asm/homecache.h>
25#include <asm-generic/mm_hooks.h>
26
27static inline int
28init_new_context(struct task_struct *tsk, struct mm_struct *mm)
29{
30 return 0;
31}
32
33/* Note that arch/tile/kernel/head.S also calls hv_install_context() */
34static inline void __install_page_table(pgd_t *pgdir, int asid, pgprot_t prot)
35{
36 /* FIXME: DIRECTIO should not always be set. FIXME. */
37 int rc = hv_install_context(__pa(pgdir), prot, asid, HV_CTX_DIRECTIO);
38 if (rc < 0)
39 panic("hv_install_context failed: %d", rc);
40}
41
42static inline void install_page_table(pgd_t *pgdir, int asid)
43{
44 pte_t *ptep = virt_to_pte(NULL, (unsigned long)pgdir);
45 __install_page_table(pgdir, asid, *ptep);
46}
47
48/*
49 * "Lazy" TLB mode is entered when we are switching to a kernel task,
50 * which borrows the mm of the previous task. The goal of this
51 * optimization is to avoid having to install a new page table. On
52 * early x86 machines (where the concept originated) you couldn't do
53 * anything short of a full page table install for invalidation, so
54 * handling a remote TLB invalidate required doing a page table
55 * re-install. Someone clearly decided that it was silly to keep
56 * doing this while in "lazy" TLB mode, so the optimization involves
57 * installing the swapper page table instead the first time one
58 * occurs, and clearing the cpu out of cpu_vm_mask, so the cpu running
59 * the kernel task doesn't need to take any more interrupts. At that
60 * point it's then necessary to explicitly reinstall it when context
61 * switching back to the original mm.
62 *
63 * On Tile, we have to do a page-table install whenever DMA is enabled,
64 * so in that case lazy mode doesn't help anyway. And more generally,
65 * we have efficient per-page TLB shootdown, and don't expect to spend
66 * that much time in kernel tasks in general, so just leaving the
67 * kernel task borrowing the old page table, but handling TLB
68 * shootdowns, is a reasonable thing to do. And importantly, this
69 * lets us use the hypervisor's internal APIs for TLB shootdown, which
70 * means we don't have to worry about having TLB shootdowns blocked
71 * when Linux is disabling interrupts; see the page migration code for
72 * an example of where it's important for TLB shootdowns to complete
73 * even when interrupts are disabled at the Linux level.
74 */
75static inline void enter_lazy_tlb(struct mm_struct *mm, struct task_struct *t)
76{
77#if CHIP_HAS_TILE_DMA()
78 /*
79 * We have to do an "identity" page table switch in order to
80 * clear any pending DMA interrupts.
81 */
82 if (current->thread.tile_dma_state.enabled)
83 install_page_table(mm->pgd, __get_cpu_var(current_asid));
84#endif
85}
86
87static inline void switch_mm(struct mm_struct *prev, struct mm_struct *next,
88 struct task_struct *tsk)
89{
90 if (likely(prev != next)) {
91
92 int cpu = smp_processor_id();
93
94 /* Pick new ASID. */
95 int asid = __get_cpu_var(current_asid) + 1;
96 if (asid > max_asid) {
97 asid = min_asid;
98 local_flush_tlb();
99 }
100 __get_cpu_var(current_asid) = asid;
101
102 /* Clear cpu from the old mm, and set it in the new one. */
103 cpumask_clear_cpu(cpu, &prev->cpu_vm_mask);
104 cpumask_set_cpu(cpu, &next->cpu_vm_mask);
105
106 /* Re-load page tables */
107 install_page_table(next->pgd, asid);
108
109 /* See how we should set the red/black cache info */
110 check_mm_caching(prev, next);
111
112 /*
113 * Since we're changing to a new mm, we have to flush
114 * the icache in case some physical page now being mapped
115 * has subsequently been repurposed and has new code.
116 */
117 __flush_icache();
118
119 }
120}
121
122static inline void activate_mm(struct mm_struct *prev_mm,
123 struct mm_struct *next_mm)
124{
125 switch_mm(prev_mm, next_mm, NULL);
126}
127
128#define destroy_context(mm) do { } while (0)
129#define deactivate_mm(tsk, mm) do { } while (0)
130
131#endif /* _ASM_TILE_MMU_CONTEXT_H */
diff --git a/arch/tile/include/asm/mmzone.h b/arch/tile/include/asm/mmzone.h
new file mode 100644
index 000000000000..c6344c4f32ac
--- /dev/null
+++ b/arch/tile/include/asm/mmzone.h
@@ -0,0 +1,81 @@
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_MMZONE_H
16#define _ASM_TILE_MMZONE_H
17
18extern struct pglist_data node_data[];
19#define NODE_DATA(nid) (&node_data[nid])
20
21extern void get_memcfg_numa(void);
22
23#ifdef CONFIG_DISCONTIGMEM
24
25#include <asm/page.h>
26
27/*
28 * Generally, memory ranges are always doled out by the hypervisor in
29 * fixed-size, power-of-two increments. That would make computing the node
30 * very easy. We could just take a couple high bits of the PA, which
31 * denote the memory shim, and we'd be done. However, when we're doing
32 * memory striping, this may not be true; PAs with different high bit
33 * values might be in the same node. Thus, we keep a lookup table to
34 * translate the high bits of the PFN to the node number.
35 */
36extern int highbits_to_node[];
37
38static inline int pfn_to_nid(unsigned long pfn)
39{
40 return highbits_to_node[__pfn_to_highbits(pfn)];
41}
42
43/*
44 * Following are macros that each numa implmentation must define.
45 */
46
47#define node_start_pfn(nid) (NODE_DATA(nid)->node_start_pfn)
48#define node_end_pfn(nid) \
49({ \
50 pg_data_t *__pgdat = NODE_DATA(nid); \
51 __pgdat->node_start_pfn + __pgdat->node_spanned_pages; \
52})
53
54#define kern_addr_valid(kaddr) virt_addr_valid((void *)kaddr)
55
56static inline int pfn_valid(int pfn)
57{
58 int nid = pfn_to_nid(pfn);
59
60 if (nid >= 0)
61 return (pfn < node_end_pfn(nid));
62 return 0;
63}
64
65/* Information on the NUMA nodes that we compute early */
66extern unsigned long node_start_pfn[];
67extern unsigned long node_end_pfn[];
68extern unsigned long node_memmap_pfn[];
69extern unsigned long node_percpu_pfn[];
70extern unsigned long node_free_pfn[];
71#ifdef CONFIG_HIGHMEM
72extern unsigned long node_lowmem_end_pfn[];
73#endif
74#ifdef CONFIG_PCI
75extern unsigned long pci_reserve_start_pfn;
76extern unsigned long pci_reserve_end_pfn;
77#endif
78
79#endif /* CONFIG_DISCONTIGMEM */
80
81#endif /* _ASM_TILE_MMZONE_H */
diff --git a/arch/tile/include/asm/module.h b/arch/tile/include/asm/module.h
new file mode 100644
index 000000000000..1e4b79fe8584
--- /dev/null
+++ b/arch/tile/include/asm/module.h
@@ -0,0 +1 @@
#include <asm-generic/module.h>
diff --git a/arch/tile/include/asm/msgbuf.h b/arch/tile/include/asm/msgbuf.h
new file mode 100644
index 000000000000..809134c644a6
--- /dev/null
+++ b/arch/tile/include/asm/msgbuf.h
@@ -0,0 +1 @@
#include <asm-generic/msgbuf.h>
diff --git a/arch/tile/include/asm/mutex.h b/arch/tile/include/asm/mutex.h
new file mode 100644
index 000000000000..ff6101aa2c71
--- /dev/null
+++ b/arch/tile/include/asm/mutex.h
@@ -0,0 +1 @@
#include <asm-generic/mutex-dec.h>
diff --git a/arch/tile/include/asm/opcode-tile.h b/arch/tile/include/asm/opcode-tile.h
new file mode 100644
index 000000000000..ba38959137d7
--- /dev/null
+++ b/arch/tile/include/asm/opcode-tile.h
@@ -0,0 +1,30 @@
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_OPCODE_TILE_H
16#define _ASM_TILE_OPCODE_TILE_H
17
18#include <arch/chip.h>
19
20#if CHIP_WORD_SIZE() == 64
21#include <asm/opcode-tile_64.h>
22#else
23#include <asm/opcode-tile_32.h>
24#endif
25
26/* These definitions are not correct for TILE64, so just avoid them. */
27#undef TILE_ELF_MACHINE_CODE
28#undef TILE_ELF_NAME
29
30#endif /* _ASM_TILE_OPCODE_TILE_H */
diff --git a/arch/tile/include/asm/opcode-tile_32.h b/arch/tile/include/asm/opcode-tile_32.h
new file mode 100644
index 000000000000..eda60ecbae3d
--- /dev/null
+++ b/arch/tile/include/asm/opcode-tile_32.h
@@ -0,0 +1,1506 @@
1/* tile.h -- Header file for TILE opcode table
2 Copyright (C) 2005 Free Software Foundation, Inc.
3 Contributed by Tilera Corp. */
4
5#ifndef opcode_tile_h
6#define opcode_tile_h
7
8typedef unsigned long long tile_bundle_bits;
9
10
11enum
12{
13 TILE_MAX_OPERANDS = 5 /* mm */
14};
15
16typedef enum
17{
18 TILE_OPC_BPT,
19 TILE_OPC_INFO,
20 TILE_OPC_INFOL,
21 TILE_OPC_J,
22 TILE_OPC_JAL,
23 TILE_OPC_MOVE,
24 TILE_OPC_MOVE_SN,
25 TILE_OPC_MOVEI,
26 TILE_OPC_MOVEI_SN,
27 TILE_OPC_MOVELI,
28 TILE_OPC_MOVELI_SN,
29 TILE_OPC_MOVELIS,
30 TILE_OPC_PREFETCH,
31 TILE_OPC_RAISE,
32 TILE_OPC_ADD,
33 TILE_OPC_ADD_SN,
34 TILE_OPC_ADDB,
35 TILE_OPC_ADDB_SN,
36 TILE_OPC_ADDBS_U,
37 TILE_OPC_ADDBS_U_SN,
38 TILE_OPC_ADDH,
39 TILE_OPC_ADDH_SN,
40 TILE_OPC_ADDHS,
41 TILE_OPC_ADDHS_SN,
42 TILE_OPC_ADDI,
43 TILE_OPC_ADDI_SN,
44 TILE_OPC_ADDIB,
45 TILE_OPC_ADDIB_SN,
46 TILE_OPC_ADDIH,
47 TILE_OPC_ADDIH_SN,
48 TILE_OPC_ADDLI,
49 TILE_OPC_ADDLI_SN,
50 TILE_OPC_ADDLIS,
51 TILE_OPC_ADDS,
52 TILE_OPC_ADDS_SN,
53 TILE_OPC_ADIFFB_U,
54 TILE_OPC_ADIFFB_U_SN,
55 TILE_OPC_ADIFFH,
56 TILE_OPC_ADIFFH_SN,
57 TILE_OPC_AND,
58 TILE_OPC_AND_SN,
59 TILE_OPC_ANDI,
60 TILE_OPC_ANDI_SN,
61 TILE_OPC_AULI,
62 TILE_OPC_AVGB_U,
63 TILE_OPC_AVGB_U_SN,
64 TILE_OPC_AVGH,
65 TILE_OPC_AVGH_SN,
66 TILE_OPC_BBNS,
67 TILE_OPC_BBNS_SN,
68 TILE_OPC_BBNST,
69 TILE_OPC_BBNST_SN,
70 TILE_OPC_BBS,
71 TILE_OPC_BBS_SN,
72 TILE_OPC_BBST,
73 TILE_OPC_BBST_SN,
74 TILE_OPC_BGEZ,
75 TILE_OPC_BGEZ_SN,
76 TILE_OPC_BGEZT,
77 TILE_OPC_BGEZT_SN,
78 TILE_OPC_BGZ,
79 TILE_OPC_BGZ_SN,
80 TILE_OPC_BGZT,
81 TILE_OPC_BGZT_SN,
82 TILE_OPC_BITX,
83 TILE_OPC_BITX_SN,
84 TILE_OPC_BLEZ,
85 TILE_OPC_BLEZ_SN,
86 TILE_OPC_BLEZT,
87 TILE_OPC_BLEZT_SN,
88 TILE_OPC_BLZ,
89 TILE_OPC_BLZ_SN,
90 TILE_OPC_BLZT,
91 TILE_OPC_BLZT_SN,
92 TILE_OPC_BNZ,
93 TILE_OPC_BNZ_SN,
94 TILE_OPC_BNZT,
95 TILE_OPC_BNZT_SN,
96 TILE_OPC_BYTEX,
97 TILE_OPC_BYTEX_SN,
98 TILE_OPC_BZ,
99 TILE_OPC_BZ_SN,
100 TILE_OPC_BZT,
101 TILE_OPC_BZT_SN,
102 TILE_OPC_CLZ,
103 TILE_OPC_CLZ_SN,
104 TILE_OPC_CRC32_32,
105 TILE_OPC_CRC32_32_SN,
106 TILE_OPC_CRC32_8,
107 TILE_OPC_CRC32_8_SN,
108 TILE_OPC_CTZ,
109 TILE_OPC_CTZ_SN,
110 TILE_OPC_DRAIN,
111 TILE_OPC_DTLBPR,
112 TILE_OPC_DWORD_ALIGN,
113 TILE_OPC_DWORD_ALIGN_SN,
114 TILE_OPC_FINV,
115 TILE_OPC_FLUSH,
116 TILE_OPC_FNOP,
117 TILE_OPC_ICOH,
118 TILE_OPC_ILL,
119 TILE_OPC_INTHB,
120 TILE_OPC_INTHB_SN,
121 TILE_OPC_INTHH,
122 TILE_OPC_INTHH_SN,
123 TILE_OPC_INTLB,
124 TILE_OPC_INTLB_SN,
125 TILE_OPC_INTLH,
126 TILE_OPC_INTLH_SN,
127 TILE_OPC_INV,
128 TILE_OPC_IRET,
129 TILE_OPC_JALB,
130 TILE_OPC_JALF,
131 TILE_OPC_JALR,
132 TILE_OPC_JALRP,
133 TILE_OPC_JB,
134 TILE_OPC_JF,
135 TILE_OPC_JR,
136 TILE_OPC_JRP,
137 TILE_OPC_LB,
138 TILE_OPC_LB_SN,
139 TILE_OPC_LB_U,
140 TILE_OPC_LB_U_SN,
141 TILE_OPC_LBADD,
142 TILE_OPC_LBADD_SN,
143 TILE_OPC_LBADD_U,
144 TILE_OPC_LBADD_U_SN,
145 TILE_OPC_LH,
146 TILE_OPC_LH_SN,
147 TILE_OPC_LH_U,
148 TILE_OPC_LH_U_SN,
149 TILE_OPC_LHADD,
150 TILE_OPC_LHADD_SN,
151 TILE_OPC_LHADD_U,
152 TILE_OPC_LHADD_U_SN,
153 TILE_OPC_LNK,
154 TILE_OPC_LNK_SN,
155 TILE_OPC_LW,
156 TILE_OPC_LW_SN,
157 TILE_OPC_LW_NA,
158 TILE_OPC_LW_NA_SN,
159 TILE_OPC_LWADD,
160 TILE_OPC_LWADD_SN,
161 TILE_OPC_LWADD_NA,
162 TILE_OPC_LWADD_NA_SN,
163 TILE_OPC_MAXB_U,
164 TILE_OPC_MAXB_U_SN,
165 TILE_OPC_MAXH,
166 TILE_OPC_MAXH_SN,
167 TILE_OPC_MAXIB_U,
168 TILE_OPC_MAXIB_U_SN,
169 TILE_OPC_MAXIH,
170 TILE_OPC_MAXIH_SN,
171 TILE_OPC_MF,
172 TILE_OPC_MFSPR,
173 TILE_OPC_MINB_U,
174 TILE_OPC_MINB_U_SN,
175 TILE_OPC_MINH,
176 TILE_OPC_MINH_SN,
177 TILE_OPC_MINIB_U,
178 TILE_OPC_MINIB_U_SN,
179 TILE_OPC_MINIH,
180 TILE_OPC_MINIH_SN,
181 TILE_OPC_MM,
182 TILE_OPC_MNZ,
183 TILE_OPC_MNZ_SN,
184 TILE_OPC_MNZB,
185 TILE_OPC_MNZB_SN,
186 TILE_OPC_MNZH,
187 TILE_OPC_MNZH_SN,
188 TILE_OPC_MTSPR,
189 TILE_OPC_MULHH_SS,
190 TILE_OPC_MULHH_SS_SN,
191 TILE_OPC_MULHH_SU,
192 TILE_OPC_MULHH_SU_SN,
193 TILE_OPC_MULHH_UU,
194 TILE_OPC_MULHH_UU_SN,
195 TILE_OPC_MULHHA_SS,
196 TILE_OPC_MULHHA_SS_SN,
197 TILE_OPC_MULHHA_SU,
198 TILE_OPC_MULHHA_SU_SN,
199 TILE_OPC_MULHHA_UU,
200 TILE_OPC_MULHHA_UU_SN,
201 TILE_OPC_MULHHSA_UU,
202 TILE_OPC_MULHHSA_UU_SN,
203 TILE_OPC_MULHL_SS,
204 TILE_OPC_MULHL_SS_SN,
205 TILE_OPC_MULHL_SU,
206 TILE_OPC_MULHL_SU_SN,
207 TILE_OPC_MULHL_US,
208 TILE_OPC_MULHL_US_SN,
209 TILE_OPC_MULHL_UU,
210 TILE_OPC_MULHL_UU_SN,
211 TILE_OPC_MULHLA_SS,
212 TILE_OPC_MULHLA_SS_SN,
213 TILE_OPC_MULHLA_SU,
214 TILE_OPC_MULHLA_SU_SN,
215 TILE_OPC_MULHLA_US,
216 TILE_OPC_MULHLA_US_SN,
217 TILE_OPC_MULHLA_UU,
218 TILE_OPC_MULHLA_UU_SN,
219 TILE_OPC_MULHLSA_UU,
220 TILE_OPC_MULHLSA_UU_SN,
221 TILE_OPC_MULLL_SS,
222 TILE_OPC_MULLL_SS_SN,
223 TILE_OPC_MULLL_SU,
224 TILE_OPC_MULLL_SU_SN,
225 TILE_OPC_MULLL_UU,
226 TILE_OPC_MULLL_UU_SN,
227 TILE_OPC_MULLLA_SS,
228 TILE_OPC_MULLLA_SS_SN,
229 TILE_OPC_MULLLA_SU,
230 TILE_OPC_MULLLA_SU_SN,
231 TILE_OPC_MULLLA_UU,
232 TILE_OPC_MULLLA_UU_SN,
233 TILE_OPC_MULLLSA_UU,
234 TILE_OPC_MULLLSA_UU_SN,
235 TILE_OPC_MVNZ,
236 TILE_OPC_MVNZ_SN,
237 TILE_OPC_MVZ,
238 TILE_OPC_MVZ_SN,
239 TILE_OPC_MZ,
240 TILE_OPC_MZ_SN,
241 TILE_OPC_MZB,
242 TILE_OPC_MZB_SN,
243 TILE_OPC_MZH,
244 TILE_OPC_MZH_SN,
245 TILE_OPC_NAP,
246 TILE_OPC_NOP,
247 TILE_OPC_NOR,
248 TILE_OPC_NOR_SN,
249 TILE_OPC_OR,
250 TILE_OPC_OR_SN,
251 TILE_OPC_ORI,
252 TILE_OPC_ORI_SN,
253 TILE_OPC_PACKBS_U,
254 TILE_OPC_PACKBS_U_SN,
255 TILE_OPC_PACKHB,
256 TILE_OPC_PACKHB_SN,
257 TILE_OPC_PACKHS,
258 TILE_OPC_PACKHS_SN,
259 TILE_OPC_PACKLB,
260 TILE_OPC_PACKLB_SN,
261 TILE_OPC_PCNT,
262 TILE_OPC_PCNT_SN,
263 TILE_OPC_RL,
264 TILE_OPC_RL_SN,
265 TILE_OPC_RLI,
266 TILE_OPC_RLI_SN,
267 TILE_OPC_S1A,
268 TILE_OPC_S1A_SN,
269 TILE_OPC_S2A,
270 TILE_OPC_S2A_SN,
271 TILE_OPC_S3A,
272 TILE_OPC_S3A_SN,
273 TILE_OPC_SADAB_U,
274 TILE_OPC_SADAB_U_SN,
275 TILE_OPC_SADAH,
276 TILE_OPC_SADAH_SN,
277 TILE_OPC_SADAH_U,
278 TILE_OPC_SADAH_U_SN,
279 TILE_OPC_SADB_U,
280 TILE_OPC_SADB_U_SN,
281 TILE_OPC_SADH,
282 TILE_OPC_SADH_SN,
283 TILE_OPC_SADH_U,
284 TILE_OPC_SADH_U_SN,
285 TILE_OPC_SB,
286 TILE_OPC_SBADD,
287 TILE_OPC_SEQ,
288 TILE_OPC_SEQ_SN,
289 TILE_OPC_SEQB,
290 TILE_OPC_SEQB_SN,
291 TILE_OPC_SEQH,
292 TILE_OPC_SEQH_SN,
293 TILE_OPC_SEQI,
294 TILE_OPC_SEQI_SN,
295 TILE_OPC_SEQIB,
296 TILE_OPC_SEQIB_SN,
297 TILE_OPC_SEQIH,
298 TILE_OPC_SEQIH_SN,
299 TILE_OPC_SH,
300 TILE_OPC_SHADD,
301 TILE_OPC_SHL,
302 TILE_OPC_SHL_SN,
303 TILE_OPC_SHLB,
304 TILE_OPC_SHLB_SN,
305 TILE_OPC_SHLH,
306 TILE_OPC_SHLH_SN,
307 TILE_OPC_SHLI,
308 TILE_OPC_SHLI_SN,
309 TILE_OPC_SHLIB,
310 TILE_OPC_SHLIB_SN,
311 TILE_OPC_SHLIH,
312 TILE_OPC_SHLIH_SN,
313 TILE_OPC_SHR,
314 TILE_OPC_SHR_SN,
315 TILE_OPC_SHRB,
316 TILE_OPC_SHRB_SN,
317 TILE_OPC_SHRH,
318 TILE_OPC_SHRH_SN,
319 TILE_OPC_SHRI,
320 TILE_OPC_SHRI_SN,
321 TILE_OPC_SHRIB,
322 TILE_OPC_SHRIB_SN,
323 TILE_OPC_SHRIH,
324 TILE_OPC_SHRIH_SN,
325 TILE_OPC_SLT,
326 TILE_OPC_SLT_SN,
327 TILE_OPC_SLT_U,
328 TILE_OPC_SLT_U_SN,
329 TILE_OPC_SLTB,
330 TILE_OPC_SLTB_SN,
331 TILE_OPC_SLTB_U,
332 TILE_OPC_SLTB_U_SN,
333 TILE_OPC_SLTE,
334 TILE_OPC_SLTE_SN,
335 TILE_OPC_SLTE_U,
336 TILE_OPC_SLTE_U_SN,
337 TILE_OPC_SLTEB,
338 TILE_OPC_SLTEB_SN,
339 TILE_OPC_SLTEB_U,
340 TILE_OPC_SLTEB_U_SN,
341 TILE_OPC_SLTEH,
342 TILE_OPC_SLTEH_SN,
343 TILE_OPC_SLTEH_U,
344 TILE_OPC_SLTEH_U_SN,
345 TILE_OPC_SLTH,
346 TILE_OPC_SLTH_SN,
347 TILE_OPC_SLTH_U,
348 TILE_OPC_SLTH_U_SN,
349 TILE_OPC_SLTI,
350 TILE_OPC_SLTI_SN,
351 TILE_OPC_SLTI_U,
352 TILE_OPC_SLTI_U_SN,
353 TILE_OPC_SLTIB,
354 TILE_OPC_SLTIB_SN,
355 TILE_OPC_SLTIB_U,
356 TILE_OPC_SLTIB_U_SN,
357 TILE_OPC_SLTIH,
358 TILE_OPC_SLTIH_SN,
359 TILE_OPC_SLTIH_U,
360 TILE_OPC_SLTIH_U_SN,
361 TILE_OPC_SNE,
362 TILE_OPC_SNE_SN,
363 TILE_OPC_SNEB,
364 TILE_OPC_SNEB_SN,
365 TILE_OPC_SNEH,
366 TILE_OPC_SNEH_SN,
367 TILE_OPC_SRA,
368 TILE_OPC_SRA_SN,
369 TILE_OPC_SRAB,
370 TILE_OPC_SRAB_SN,
371 TILE_OPC_SRAH,
372 TILE_OPC_SRAH_SN,
373 TILE_OPC_SRAI,
374 TILE_OPC_SRAI_SN,
375 TILE_OPC_SRAIB,
376 TILE_OPC_SRAIB_SN,
377 TILE_OPC_SRAIH,
378 TILE_OPC_SRAIH_SN,
379 TILE_OPC_SUB,
380 TILE_OPC_SUB_SN,
381 TILE_OPC_SUBB,
382 TILE_OPC_SUBB_SN,
383 TILE_OPC_SUBBS_U,
384 TILE_OPC_SUBBS_U_SN,
385 TILE_OPC_SUBH,
386 TILE_OPC_SUBH_SN,
387 TILE_OPC_SUBHS,
388 TILE_OPC_SUBHS_SN,
389 TILE_OPC_SUBS,
390 TILE_OPC_SUBS_SN,
391 TILE_OPC_SW,
392 TILE_OPC_SWADD,
393 TILE_OPC_SWINT0,
394 TILE_OPC_SWINT1,
395 TILE_OPC_SWINT2,
396 TILE_OPC_SWINT3,
397 TILE_OPC_TBLIDXB0,
398 TILE_OPC_TBLIDXB0_SN,
399 TILE_OPC_TBLIDXB1,
400 TILE_OPC_TBLIDXB1_SN,
401 TILE_OPC_TBLIDXB2,
402 TILE_OPC_TBLIDXB2_SN,
403 TILE_OPC_TBLIDXB3,
404 TILE_OPC_TBLIDXB3_SN,
405 TILE_OPC_TNS,
406 TILE_OPC_TNS_SN,
407 TILE_OPC_WH64,
408 TILE_OPC_XOR,
409 TILE_OPC_XOR_SN,
410 TILE_OPC_XORI,
411 TILE_OPC_XORI_SN,
412 TILE_OPC_NONE
413} tile_mnemonic;
414
415/* 64-bit pattern for a { bpt ; nop } bundle. */
416#define TILE_BPT_BUNDLE 0x400b3cae70166000ULL
417
418
419#define TILE_ELF_MACHINE_CODE EM_TILEPRO
420
421#define TILE_ELF_NAME "elf32-tilepro"
422
423
424static __inline unsigned int
425get_BrOff_SN(tile_bundle_bits num)
426{
427 const unsigned int n = (unsigned int)num;
428 return (((n >> 0)) & 0x3ff);
429}
430
431static __inline unsigned int
432get_BrOff_X1(tile_bundle_bits n)
433{
434 return (((unsigned int)(n >> 43)) & 0x00007fff) |
435 (((unsigned int)(n >> 20)) & 0x00018000);
436}
437
438static __inline unsigned int
439get_BrType_X1(tile_bundle_bits n)
440{
441 return (((unsigned int)(n >> 31)) & 0xf);
442}
443
444static __inline unsigned int
445get_Dest_Imm8_X1(tile_bundle_bits n)
446{
447 return (((unsigned int)(n >> 31)) & 0x0000003f) |
448 (((unsigned int)(n >> 43)) & 0x000000c0);
449}
450
451static __inline unsigned int
452get_Dest_SN(tile_bundle_bits num)
453{
454 const unsigned int n = (unsigned int)num;
455 return (((n >> 2)) & 0x3);
456}
457
458static __inline unsigned int
459get_Dest_X0(tile_bundle_bits num)
460{
461 const unsigned int n = (unsigned int)num;
462 return (((n >> 0)) & 0x3f);
463}
464
465static __inline unsigned int
466get_Dest_X1(tile_bundle_bits n)
467{
468 return (((unsigned int)(n >> 31)) & 0x3f);
469}
470
471static __inline unsigned int
472get_Dest_Y0(tile_bundle_bits num)
473{
474 const unsigned int n = (unsigned int)num;
475 return (((n >> 0)) & 0x3f);
476}
477
478static __inline unsigned int
479get_Dest_Y1(tile_bundle_bits n)
480{
481 return (((unsigned int)(n >> 31)) & 0x3f);
482}
483
484static __inline unsigned int
485get_Imm16_X0(tile_bundle_bits num)
486{
487 const unsigned int n = (unsigned int)num;
488 return (((n >> 12)) & 0xffff);
489}
490
491static __inline unsigned int
492get_Imm16_X1(tile_bundle_bits n)
493{
494 return (((unsigned int)(n >> 43)) & 0xffff);
495}
496
497static __inline unsigned int
498get_Imm8_SN(tile_bundle_bits num)
499{
500 const unsigned int n = (unsigned int)num;
501 return (((n >> 0)) & 0xff);
502}
503
504static __inline unsigned int
505get_Imm8_X0(tile_bundle_bits num)
506{
507 const unsigned int n = (unsigned int)num;
508 return (((n >> 12)) & 0xff);
509}
510
511static __inline unsigned int
512get_Imm8_X1(tile_bundle_bits n)
513{
514 return (((unsigned int)(n >> 43)) & 0xff);
515}
516
517static __inline unsigned int
518get_Imm8_Y0(tile_bundle_bits num)
519{
520 const unsigned int n = (unsigned int)num;
521 return (((n >> 12)) & 0xff);
522}
523
524static __inline unsigned int
525get_Imm8_Y1(tile_bundle_bits n)
526{
527 return (((unsigned int)(n >> 43)) & 0xff);
528}
529
530static __inline unsigned int
531get_ImmOpcodeExtension_X0(tile_bundle_bits num)
532{
533 const unsigned int n = (unsigned int)num;
534 return (((n >> 20)) & 0x7f);
535}
536
537static __inline unsigned int
538get_ImmOpcodeExtension_X1(tile_bundle_bits n)
539{
540 return (((unsigned int)(n >> 51)) & 0x7f);
541}
542
543static __inline unsigned int
544get_ImmRROpcodeExtension_SN(tile_bundle_bits num)
545{
546 const unsigned int n = (unsigned int)num;
547 return (((n >> 8)) & 0x3);
548}
549
550static __inline unsigned int
551get_JOffLong_X1(tile_bundle_bits n)
552{
553 return (((unsigned int)(n >> 43)) & 0x00007fff) |
554 (((unsigned int)(n >> 20)) & 0x00018000) |
555 (((unsigned int)(n >> 14)) & 0x001e0000) |
556 (((unsigned int)(n >> 16)) & 0x07e00000) |
557 (((unsigned int)(n >> 31)) & 0x18000000);
558}
559
560static __inline unsigned int
561get_JOff_X1(tile_bundle_bits n)
562{
563 return (((unsigned int)(n >> 43)) & 0x00007fff) |
564 (((unsigned int)(n >> 20)) & 0x00018000) |
565 (((unsigned int)(n >> 14)) & 0x001e0000) |
566 (((unsigned int)(n >> 16)) & 0x07e00000) |
567 (((unsigned int)(n >> 31)) & 0x08000000);
568}
569
570static __inline unsigned int
571get_MF_Imm15_X1(tile_bundle_bits n)
572{
573 return (((unsigned int)(n >> 37)) & 0x00003fff) |
574 (((unsigned int)(n >> 44)) & 0x00004000);
575}
576
577static __inline unsigned int
578get_MMEnd_X0(tile_bundle_bits num)
579{
580 const unsigned int n = (unsigned int)num;
581 return (((n >> 18)) & 0x1f);
582}
583
584static __inline unsigned int
585get_MMEnd_X1(tile_bundle_bits n)
586{
587 return (((unsigned int)(n >> 49)) & 0x1f);
588}
589
590static __inline unsigned int
591get_MMStart_X0(tile_bundle_bits num)
592{
593 const unsigned int n = (unsigned int)num;
594 return (((n >> 23)) & 0x1f);
595}
596
597static __inline unsigned int
598get_MMStart_X1(tile_bundle_bits n)
599{
600 return (((unsigned int)(n >> 54)) & 0x1f);
601}
602
603static __inline unsigned int
604get_MT_Imm15_X1(tile_bundle_bits n)
605{
606 return (((unsigned int)(n >> 31)) & 0x0000003f) |
607 (((unsigned int)(n >> 37)) & 0x00003fc0) |
608 (((unsigned int)(n >> 44)) & 0x00004000);
609}
610
611static __inline unsigned int
612get_Mode(tile_bundle_bits n)
613{
614 return (((unsigned int)(n >> 63)) & 0x1);
615}
616
617static __inline unsigned int
618get_NoRegOpcodeExtension_SN(tile_bundle_bits num)
619{
620 const unsigned int n = (unsigned int)num;
621 return (((n >> 0)) & 0xf);
622}
623
624static __inline unsigned int
625get_Opcode_SN(tile_bundle_bits num)
626{
627 const unsigned int n = (unsigned int)num;
628 return (((n >> 10)) & 0x3f);
629}
630
631static __inline unsigned int
632get_Opcode_X0(tile_bundle_bits num)
633{
634 const unsigned int n = (unsigned int)num;
635 return (((n >> 28)) & 0x7);
636}
637
638static __inline unsigned int
639get_Opcode_X1(tile_bundle_bits n)
640{
641 return (((unsigned int)(n >> 59)) & 0xf);
642}
643
644static __inline unsigned int
645get_Opcode_Y0(tile_bundle_bits num)
646{
647 const unsigned int n = (unsigned int)num;
648 return (((n >> 27)) & 0xf);
649}
650
651static __inline unsigned int
652get_Opcode_Y1(tile_bundle_bits n)
653{
654 return (((unsigned int)(n >> 59)) & 0xf);
655}
656
657static __inline unsigned int
658get_Opcode_Y2(tile_bundle_bits n)
659{
660 return (((unsigned int)(n >> 56)) & 0x7);
661}
662
663static __inline unsigned int
664get_RROpcodeExtension_SN(tile_bundle_bits num)
665{
666 const unsigned int n = (unsigned int)num;
667 return (((n >> 4)) & 0xf);
668}
669
670static __inline unsigned int
671get_RRROpcodeExtension_X0(tile_bundle_bits num)
672{
673 const unsigned int n = (unsigned int)num;
674 return (((n >> 18)) & 0x1ff);
675}
676
677static __inline unsigned int
678get_RRROpcodeExtension_X1(tile_bundle_bits n)
679{
680 return (((unsigned int)(n >> 49)) & 0x1ff);
681}
682
683static __inline unsigned int
684get_RRROpcodeExtension_Y0(tile_bundle_bits num)
685{
686 const unsigned int n = (unsigned int)num;
687 return (((n >> 18)) & 0x3);
688}
689
690static __inline unsigned int
691get_RRROpcodeExtension_Y1(tile_bundle_bits n)
692{
693 return (((unsigned int)(n >> 49)) & 0x3);
694}
695
696static __inline unsigned int
697get_RouteOpcodeExtension_SN(tile_bundle_bits num)
698{
699 const unsigned int n = (unsigned int)num;
700 return (((n >> 0)) & 0x3ff);
701}
702
703static __inline unsigned int
704get_S_X0(tile_bundle_bits num)
705{
706 const unsigned int n = (unsigned int)num;
707 return (((n >> 27)) & 0x1);
708}
709
710static __inline unsigned int
711get_S_X1(tile_bundle_bits n)
712{
713 return (((unsigned int)(n >> 58)) & 0x1);
714}
715
716static __inline unsigned int
717get_ShAmt_X0(tile_bundle_bits num)
718{
719 const unsigned int n = (unsigned int)num;
720 return (((n >> 12)) & 0x1f);
721}
722
723static __inline unsigned int
724get_ShAmt_X1(tile_bundle_bits n)
725{
726 return (((unsigned int)(n >> 43)) & 0x1f);
727}
728
729static __inline unsigned int
730get_ShAmt_Y0(tile_bundle_bits num)
731{
732 const unsigned int n = (unsigned int)num;
733 return (((n >> 12)) & 0x1f);
734}
735
736static __inline unsigned int
737get_ShAmt_Y1(tile_bundle_bits n)
738{
739 return (((unsigned int)(n >> 43)) & 0x1f);
740}
741
742static __inline unsigned int
743get_SrcA_X0(tile_bundle_bits num)
744{
745 const unsigned int n = (unsigned int)num;
746 return (((n >> 6)) & 0x3f);
747}
748
749static __inline unsigned int
750get_SrcA_X1(tile_bundle_bits n)
751{
752 return (((unsigned int)(n >> 37)) & 0x3f);
753}
754
755static __inline unsigned int
756get_SrcA_Y0(tile_bundle_bits num)
757{
758 const unsigned int n = (unsigned int)num;
759 return (((n >> 6)) & 0x3f);
760}
761
762static __inline unsigned int
763get_SrcA_Y1(tile_bundle_bits n)
764{
765 return (((unsigned int)(n >> 37)) & 0x3f);
766}
767
768static __inline unsigned int
769get_SrcA_Y2(tile_bundle_bits n)
770{
771 return (((n >> 26)) & 0x00000001) |
772 (((unsigned int)(n >> 50)) & 0x0000003e);
773}
774
775static __inline unsigned int
776get_SrcBDest_Y2(tile_bundle_bits num)
777{
778 const unsigned int n = (unsigned int)num;
779 return (((n >> 20)) & 0x3f);
780}
781
782static __inline unsigned int
783get_SrcB_X0(tile_bundle_bits num)
784{
785 const unsigned int n = (unsigned int)num;
786 return (((n >> 12)) & 0x3f);
787}
788
789static __inline unsigned int
790get_SrcB_X1(tile_bundle_bits n)
791{
792 return (((unsigned int)(n >> 43)) & 0x3f);
793}
794
795static __inline unsigned int
796get_SrcB_Y0(tile_bundle_bits num)
797{
798 const unsigned int n = (unsigned int)num;
799 return (((n >> 12)) & 0x3f);
800}
801
802static __inline unsigned int
803get_SrcB_Y1(tile_bundle_bits n)
804{
805 return (((unsigned int)(n >> 43)) & 0x3f);
806}
807
808static __inline unsigned int
809get_Src_SN(tile_bundle_bits num)
810{
811 const unsigned int n = (unsigned int)num;
812 return (((n >> 0)) & 0x3);
813}
814
815static __inline unsigned int
816get_UnOpcodeExtension_X0(tile_bundle_bits num)
817{
818 const unsigned int n = (unsigned int)num;
819 return (((n >> 12)) & 0x1f);
820}
821
822static __inline unsigned int
823get_UnOpcodeExtension_X1(tile_bundle_bits n)
824{
825 return (((unsigned int)(n >> 43)) & 0x1f);
826}
827
828static __inline unsigned int
829get_UnOpcodeExtension_Y0(tile_bundle_bits num)
830{
831 const unsigned int n = (unsigned int)num;
832 return (((n >> 12)) & 0x1f);
833}
834
835static __inline unsigned int
836get_UnOpcodeExtension_Y1(tile_bundle_bits n)
837{
838 return (((unsigned int)(n >> 43)) & 0x1f);
839}
840
841static __inline unsigned int
842get_UnShOpcodeExtension_X0(tile_bundle_bits num)
843{
844 const unsigned int n = (unsigned int)num;
845 return (((n >> 17)) & 0x3ff);
846}
847
848static __inline unsigned int
849get_UnShOpcodeExtension_X1(tile_bundle_bits n)
850{
851 return (((unsigned int)(n >> 48)) & 0x3ff);
852}
853
854static __inline unsigned int
855get_UnShOpcodeExtension_Y0(tile_bundle_bits num)
856{
857 const unsigned int n = (unsigned int)num;
858 return (((n >> 17)) & 0x7);
859}
860
861static __inline unsigned int
862get_UnShOpcodeExtension_Y1(tile_bundle_bits n)
863{
864 return (((unsigned int)(n >> 48)) & 0x7);
865}
866
867
868static __inline int
869sign_extend(int n, int num_bits)
870{
871 int shift = (int)(sizeof(int) * 8 - num_bits);
872 return (n << shift) >> shift;
873}
874
875
876
877static __inline tile_bundle_bits
878create_BrOff_SN(int num)
879{
880 const unsigned int n = (unsigned int)num;
881 return ((n & 0x3ff) << 0);
882}
883
884static __inline tile_bundle_bits
885create_BrOff_X1(int num)
886{
887 const unsigned int n = (unsigned int)num;
888 return (((tile_bundle_bits)(n & 0x00007fff)) << 43) |
889 (((tile_bundle_bits)(n & 0x00018000)) << 20);
890}
891
892static __inline tile_bundle_bits
893create_BrType_X1(int num)
894{
895 const unsigned int n = (unsigned int)num;
896 return (((tile_bundle_bits)(n & 0xf)) << 31);
897}
898
899static __inline tile_bundle_bits
900create_Dest_Imm8_X1(int num)
901{
902 const unsigned int n = (unsigned int)num;
903 return (((tile_bundle_bits)(n & 0x0000003f)) << 31) |
904 (((tile_bundle_bits)(n & 0x000000c0)) << 43);
905}
906
907static __inline tile_bundle_bits
908create_Dest_SN(int num)
909{
910 const unsigned int n = (unsigned int)num;
911 return ((n & 0x3) << 2);
912}
913
914static __inline tile_bundle_bits
915create_Dest_X0(int num)
916{
917 const unsigned int n = (unsigned int)num;
918 return ((n & 0x3f) << 0);
919}
920
921static __inline tile_bundle_bits
922create_Dest_X1(int num)
923{
924 const unsigned int n = (unsigned int)num;
925 return (((tile_bundle_bits)(n & 0x3f)) << 31);
926}
927
928static __inline tile_bundle_bits
929create_Dest_Y0(int num)
930{
931 const unsigned int n = (unsigned int)num;
932 return ((n & 0x3f) << 0);
933}
934
935static __inline tile_bundle_bits
936create_Dest_Y1(int num)
937{
938 const unsigned int n = (unsigned int)num;
939 return (((tile_bundle_bits)(n & 0x3f)) << 31);
940}
941
942static __inline tile_bundle_bits
943create_Imm16_X0(int num)
944{
945 const unsigned int n = (unsigned int)num;
946 return ((n & 0xffff) << 12);
947}
948
949static __inline tile_bundle_bits
950create_Imm16_X1(int num)
951{
952 const unsigned int n = (unsigned int)num;
953 return (((tile_bundle_bits)(n & 0xffff)) << 43);
954}
955
956static __inline tile_bundle_bits
957create_Imm8_SN(int num)
958{
959 const unsigned int n = (unsigned int)num;
960 return ((n & 0xff) << 0);
961}
962
963static __inline tile_bundle_bits
964create_Imm8_X0(int num)
965{
966 const unsigned int n = (unsigned int)num;
967 return ((n & 0xff) << 12);
968}
969
970static __inline tile_bundle_bits
971create_Imm8_X1(int num)
972{
973 const unsigned int n = (unsigned int)num;
974 return (((tile_bundle_bits)(n & 0xff)) << 43);
975}
976
977static __inline tile_bundle_bits
978create_Imm8_Y0(int num)
979{
980 const unsigned int n = (unsigned int)num;
981 return ((n & 0xff) << 12);
982}
983
984static __inline tile_bundle_bits
985create_Imm8_Y1(int num)
986{
987 const unsigned int n = (unsigned int)num;
988 return (((tile_bundle_bits)(n & 0xff)) << 43);
989}
990
991static __inline tile_bundle_bits
992create_ImmOpcodeExtension_X0(int num)
993{
994 const unsigned int n = (unsigned int)num;
995 return ((n & 0x7f) << 20);
996}
997
998static __inline tile_bundle_bits
999create_ImmOpcodeExtension_X1(int num)
1000{
1001 const unsigned int n = (unsigned int)num;
1002 return (((tile_bundle_bits)(n & 0x7f)) << 51);
1003}
1004
1005static __inline tile_bundle_bits
1006create_ImmRROpcodeExtension_SN(int num)
1007{
1008 const unsigned int n = (unsigned int)num;
1009 return ((n & 0x3) << 8);
1010}
1011
1012static __inline tile_bundle_bits
1013create_JOffLong_X1(int num)
1014{
1015 const unsigned int n = (unsigned int)num;
1016 return (((tile_bundle_bits)(n & 0x00007fff)) << 43) |
1017 (((tile_bundle_bits)(n & 0x00018000)) << 20) |
1018 (((tile_bundle_bits)(n & 0x001e0000)) << 14) |
1019 (((tile_bundle_bits)(n & 0x07e00000)) << 16) |
1020 (((tile_bundle_bits)(n & 0x18000000)) << 31);
1021}
1022
1023static __inline tile_bundle_bits
1024create_JOff_X1(int num)
1025{
1026 const unsigned int n = (unsigned int)num;
1027 return (((tile_bundle_bits)(n & 0x00007fff)) << 43) |
1028 (((tile_bundle_bits)(n & 0x00018000)) << 20) |
1029 (((tile_bundle_bits)(n & 0x001e0000)) << 14) |
1030 (((tile_bundle_bits)(n & 0x07e00000)) << 16) |
1031 (((tile_bundle_bits)(n & 0x08000000)) << 31);
1032}
1033
1034static __inline tile_bundle_bits
1035create_MF_Imm15_X1(int num)
1036{
1037 const unsigned int n = (unsigned int)num;
1038 return (((tile_bundle_bits)(n & 0x00003fff)) << 37) |
1039 (((tile_bundle_bits)(n & 0x00004000)) << 44);
1040}
1041
1042static __inline tile_bundle_bits
1043create_MMEnd_X0(int num)
1044{
1045 const unsigned int n = (unsigned int)num;
1046 return ((n & 0x1f) << 18);
1047}
1048
1049static __inline tile_bundle_bits
1050create_MMEnd_X1(int num)
1051{
1052 const unsigned int n = (unsigned int)num;
1053 return (((tile_bundle_bits)(n & 0x1f)) << 49);
1054}
1055
1056static __inline tile_bundle_bits
1057create_MMStart_X0(int num)
1058{
1059 const unsigned int n = (unsigned int)num;
1060 return ((n & 0x1f) << 23);
1061}
1062
1063static __inline tile_bundle_bits
1064create_MMStart_X1(int num)
1065{
1066 const unsigned int n = (unsigned int)num;
1067 return (((tile_bundle_bits)(n & 0x1f)) << 54);
1068}
1069
1070static __inline tile_bundle_bits
1071create_MT_Imm15_X1(int num)
1072{
1073 const unsigned int n = (unsigned int)num;
1074 return (((tile_bundle_bits)(n & 0x0000003f)) << 31) |
1075 (((tile_bundle_bits)(n & 0x00003fc0)) << 37) |
1076 (((tile_bundle_bits)(n & 0x00004000)) << 44);
1077}
1078
1079static __inline tile_bundle_bits
1080create_Mode(int num)
1081{
1082 const unsigned int n = (unsigned int)num;
1083 return (((tile_bundle_bits)(n & 0x1)) << 63);
1084}
1085
1086static __inline tile_bundle_bits
1087create_NoRegOpcodeExtension_SN(int num)
1088{
1089 const unsigned int n = (unsigned int)num;
1090 return ((n & 0xf) << 0);
1091}
1092
1093static __inline tile_bundle_bits
1094create_Opcode_SN(int num)
1095{
1096 const unsigned int n = (unsigned int)num;
1097 return ((n & 0x3f) << 10);
1098}
1099
1100static __inline tile_bundle_bits
1101create_Opcode_X0(int num)
1102{
1103 const unsigned int n = (unsigned int)num;
1104 return ((n & 0x7) << 28);
1105}
1106
1107static __inline tile_bundle_bits
1108create_Opcode_X1(int num)
1109{
1110 const unsigned int n = (unsigned int)num;
1111 return (((tile_bundle_bits)(n & 0xf)) << 59);
1112}
1113
1114static __inline tile_bundle_bits
1115create_Opcode_Y0(int num)
1116{
1117 const unsigned int n = (unsigned int)num;
1118 return ((n & 0xf) << 27);
1119}
1120
1121static __inline tile_bundle_bits
1122create_Opcode_Y1(int num)
1123{
1124 const unsigned int n = (unsigned int)num;
1125 return (((tile_bundle_bits)(n & 0xf)) << 59);
1126}
1127
1128static __inline tile_bundle_bits
1129create_Opcode_Y2(int num)
1130{
1131 const unsigned int n = (unsigned int)num;
1132 return (((tile_bundle_bits)(n & 0x7)) << 56);
1133}
1134
1135static __inline tile_bundle_bits
1136create_RROpcodeExtension_SN(int num)
1137{
1138 const unsigned int n = (unsigned int)num;
1139 return ((n & 0xf) << 4);
1140}
1141
1142static __inline tile_bundle_bits
1143create_RRROpcodeExtension_X0(int num)
1144{
1145 const unsigned int n = (unsigned int)num;
1146 return ((n & 0x1ff) << 18);
1147}
1148
1149static __inline tile_bundle_bits
1150create_RRROpcodeExtension_X1(int num)
1151{
1152 const unsigned int n = (unsigned int)num;
1153 return (((tile_bundle_bits)(n & 0x1ff)) << 49);
1154}
1155
1156static __inline tile_bundle_bits
1157create_RRROpcodeExtension_Y0(int num)
1158{
1159 const unsigned int n = (unsigned int)num;
1160 return ((n & 0x3) << 18);
1161}
1162
1163static __inline tile_bundle_bits
1164create_RRROpcodeExtension_Y1(int num)
1165{
1166 const unsigned int n = (unsigned int)num;
1167 return (((tile_bundle_bits)(n & 0x3)) << 49);
1168}
1169
1170static __inline tile_bundle_bits
1171create_RouteOpcodeExtension_SN(int num)
1172{
1173 const unsigned int n = (unsigned int)num;
1174 return ((n & 0x3ff) << 0);
1175}
1176
1177static __inline tile_bundle_bits
1178create_S_X0(int num)
1179{
1180 const unsigned int n = (unsigned int)num;
1181 return ((n & 0x1) << 27);
1182}
1183
1184static __inline tile_bundle_bits
1185create_S_X1(int num)
1186{
1187 const unsigned int n = (unsigned int)num;
1188 return (((tile_bundle_bits)(n & 0x1)) << 58);
1189}
1190
1191static __inline tile_bundle_bits
1192create_ShAmt_X0(int num)
1193{
1194 const unsigned int n = (unsigned int)num;
1195 return ((n & 0x1f) << 12);
1196}
1197
1198static __inline tile_bundle_bits
1199create_ShAmt_X1(int num)
1200{
1201 const unsigned int n = (unsigned int)num;
1202 return (((tile_bundle_bits)(n & 0x1f)) << 43);
1203}
1204
1205static __inline tile_bundle_bits
1206create_ShAmt_Y0(int num)
1207{
1208 const unsigned int n = (unsigned int)num;
1209 return ((n & 0x1f) << 12);
1210}
1211
1212static __inline tile_bundle_bits
1213create_ShAmt_Y1(int num)
1214{
1215 const unsigned int n = (unsigned int)num;
1216 return (((tile_bundle_bits)(n & 0x1f)) << 43);
1217}
1218
1219static __inline tile_bundle_bits
1220create_SrcA_X0(int num)
1221{
1222 const unsigned int n = (unsigned int)num;
1223 return ((n & 0x3f) << 6);
1224}
1225
1226static __inline tile_bundle_bits
1227create_SrcA_X1(int num)
1228{
1229 const unsigned int n = (unsigned int)num;
1230 return (((tile_bundle_bits)(n & 0x3f)) << 37);
1231}
1232
1233static __inline tile_bundle_bits
1234create_SrcA_Y0(int num)
1235{
1236 const unsigned int n = (unsigned int)num;
1237 return ((n & 0x3f) << 6);
1238}
1239
1240static __inline tile_bundle_bits
1241create_SrcA_Y1(int num)
1242{
1243 const unsigned int n = (unsigned int)num;
1244 return (((tile_bundle_bits)(n & 0x3f)) << 37);
1245}
1246
1247static __inline tile_bundle_bits
1248create_SrcA_Y2(int num)
1249{
1250 const unsigned int n = (unsigned int)num;
1251 return ((n & 0x00000001) << 26) |
1252 (((tile_bundle_bits)(n & 0x0000003e)) << 50);
1253}
1254
1255static __inline tile_bundle_bits
1256create_SrcBDest_Y2(int num)
1257{
1258 const unsigned int n = (unsigned int)num;
1259 return ((n & 0x3f) << 20);
1260}
1261
1262static __inline tile_bundle_bits
1263create_SrcB_X0(int num)
1264{
1265 const unsigned int n = (unsigned int)num;
1266 return ((n & 0x3f) << 12);
1267}
1268
1269static __inline tile_bundle_bits
1270create_SrcB_X1(int num)
1271{
1272 const unsigned int n = (unsigned int)num;
1273 return (((tile_bundle_bits)(n & 0x3f)) << 43);
1274}
1275
1276static __inline tile_bundle_bits
1277create_SrcB_Y0(int num)
1278{
1279 const unsigned int n = (unsigned int)num;
1280 return ((n & 0x3f) << 12);
1281}
1282
1283static __inline tile_bundle_bits
1284create_SrcB_Y1(int num)
1285{
1286 const unsigned int n = (unsigned int)num;
1287 return (((tile_bundle_bits)(n & 0x3f)) << 43);
1288}
1289
1290static __inline tile_bundle_bits
1291create_Src_SN(int num)
1292{
1293 const unsigned int n = (unsigned int)num;
1294 return ((n & 0x3) << 0);
1295}
1296
1297static __inline tile_bundle_bits
1298create_UnOpcodeExtension_X0(int num)
1299{
1300 const unsigned int n = (unsigned int)num;
1301 return ((n & 0x1f) << 12);
1302}
1303
1304static __inline tile_bundle_bits
1305create_UnOpcodeExtension_X1(int num)
1306{
1307 const unsigned int n = (unsigned int)num;
1308 return (((tile_bundle_bits)(n & 0x1f)) << 43);
1309}
1310
1311static __inline tile_bundle_bits
1312create_UnOpcodeExtension_Y0(int num)
1313{
1314 const unsigned int n = (unsigned int)num;
1315 return ((n & 0x1f) << 12);
1316}
1317
1318static __inline tile_bundle_bits
1319create_UnOpcodeExtension_Y1(int num)
1320{
1321 const unsigned int n = (unsigned int)num;
1322 return (((tile_bundle_bits)(n & 0x1f)) << 43);
1323}
1324
1325static __inline tile_bundle_bits
1326create_UnShOpcodeExtension_X0(int num)
1327{
1328 const unsigned int n = (unsigned int)num;
1329 return ((n & 0x3ff) << 17);
1330}
1331
1332static __inline tile_bundle_bits
1333create_UnShOpcodeExtension_X1(int num)
1334{
1335 const unsigned int n = (unsigned int)num;
1336 return (((tile_bundle_bits)(n & 0x3ff)) << 48);
1337}
1338
1339static __inline tile_bundle_bits
1340create_UnShOpcodeExtension_Y0(int num)
1341{
1342 const unsigned int n = (unsigned int)num;
1343 return ((n & 0x7) << 17);
1344}
1345
1346static __inline tile_bundle_bits
1347create_UnShOpcodeExtension_Y1(int num)
1348{
1349 const unsigned int n = (unsigned int)num;
1350 return (((tile_bundle_bits)(n & 0x7)) << 48);
1351}
1352
1353
1354
1355typedef enum
1356{
1357 TILE_PIPELINE_X0,
1358 TILE_PIPELINE_X1,
1359 TILE_PIPELINE_Y0,
1360 TILE_PIPELINE_Y1,
1361 TILE_PIPELINE_Y2,
1362} tile_pipeline;
1363
1364#define tile_is_x_pipeline(p) ((int)(p) <= (int)TILE_PIPELINE_X1)
1365
1366typedef enum
1367{
1368 TILE_OP_TYPE_REGISTER,
1369 TILE_OP_TYPE_IMMEDIATE,
1370 TILE_OP_TYPE_ADDRESS,
1371 TILE_OP_TYPE_SPR
1372} tile_operand_type;
1373
1374/* This is the bit that determines if a bundle is in the Y encoding. */
1375#define TILE_BUNDLE_Y_ENCODING_MASK ((tile_bundle_bits)1 << 63)
1376
1377enum
1378{
1379 /* Maximum number of instructions in a bundle (2 for X, 3 for Y). */
1380 TILE_MAX_INSTRUCTIONS_PER_BUNDLE = 3,
1381
1382 /* How many different pipeline encodings are there? X0, X1, Y0, Y1, Y2. */
1383 TILE_NUM_PIPELINE_ENCODINGS = 5,
1384
1385 /* Log base 2 of TILE_BUNDLE_SIZE_IN_BYTES. */
1386 TILE_LOG2_BUNDLE_SIZE_IN_BYTES = 3,
1387
1388 /* Instructions take this many bytes. */
1389 TILE_BUNDLE_SIZE_IN_BYTES = 1 << TILE_LOG2_BUNDLE_SIZE_IN_BYTES,
1390
1391 /* Log base 2 of TILE_BUNDLE_ALIGNMENT_IN_BYTES. */
1392 TILE_LOG2_BUNDLE_ALIGNMENT_IN_BYTES = 3,
1393
1394 /* Bundles should be aligned modulo this number of bytes. */
1395 TILE_BUNDLE_ALIGNMENT_IN_BYTES =
1396 (1 << TILE_LOG2_BUNDLE_ALIGNMENT_IN_BYTES),
1397
1398 /* Log base 2 of TILE_SN_INSTRUCTION_SIZE_IN_BYTES. */
1399 TILE_LOG2_SN_INSTRUCTION_SIZE_IN_BYTES = 1,
1400
1401 /* Static network instructions take this many bytes. */
1402 TILE_SN_INSTRUCTION_SIZE_IN_BYTES =
1403 (1 << TILE_LOG2_SN_INSTRUCTION_SIZE_IN_BYTES),
1404
1405 /* Number of registers (some are magic, such as network I/O). */
1406 TILE_NUM_REGISTERS = 64,
1407
1408 /* Number of static network registers. */
1409 TILE_NUM_SN_REGISTERS = 4
1410};
1411
1412
1413struct tile_operand
1414{
1415 /* Is this operand a register, immediate or address? */
1416 tile_operand_type type;
1417
1418 /* The default relocation type for this operand. */
1419 signed int default_reloc : 16;
1420
1421 /* How many bits is this value? (used for range checking) */
1422 unsigned int num_bits : 5;
1423
1424 /* Is the value signed? (used for range checking) */
1425 unsigned int is_signed : 1;
1426
1427 /* Is this operand a source register? */
1428 unsigned int is_src_reg : 1;
1429
1430 /* Is this operand written? (i.e. is it a destination register) */
1431 unsigned int is_dest_reg : 1;
1432
1433 /* Is this operand PC-relative? */
1434 unsigned int is_pc_relative : 1;
1435
1436 /* By how many bits do we right shift the value before inserting? */
1437 unsigned int rightshift : 2;
1438
1439 /* Return the bits for this operand to be ORed into an existing bundle. */
1440 tile_bundle_bits (*insert) (int op);
1441
1442 /* Extract this operand and return it. */
1443 unsigned int (*extract) (tile_bundle_bits bundle);
1444};
1445
1446
1447extern const struct tile_operand tile_operands[];
1448
1449/* One finite-state machine per pipe for rapid instruction decoding. */
1450extern const unsigned short * const
1451tile_bundle_decoder_fsms[TILE_NUM_PIPELINE_ENCODINGS];
1452
1453
1454struct tile_opcode
1455{
1456 /* The opcode mnemonic, e.g. "add" */
1457 const char *name;
1458
1459 /* The enum value for this mnemonic. */
1460 tile_mnemonic mnemonic;
1461
1462 /* A bit mask of which of the five pipes this instruction
1463 is compatible with:
1464 X0 0x01
1465 X1 0x02
1466 Y0 0x04
1467 Y1 0x08
1468 Y2 0x10 */
1469 unsigned char pipes;
1470
1471 /* How many operands are there? */
1472 unsigned char num_operands;
1473
1474 /* Which register does this write implicitly, or TREG_ZERO if none? */
1475 unsigned char implicitly_written_register;
1476
1477 /* Can this be bundled with other instructions (almost always true). */
1478 unsigned char can_bundle;
1479
1480 /* The description of the operands. Each of these is an
1481 * index into the tile_operands[] table. */
1482 unsigned char operands[TILE_NUM_PIPELINE_ENCODINGS][TILE_MAX_OPERANDS];
1483
1484};
1485
1486extern const struct tile_opcode tile_opcodes[];
1487
1488
1489/* Used for non-textual disassembly into structs. */
1490struct tile_decoded_instruction
1491{
1492 const struct tile_opcode *opcode;
1493 const struct tile_operand *operands[TILE_MAX_OPERANDS];
1494 int operand_values[TILE_MAX_OPERANDS];
1495};
1496
1497
1498/* Disassemble a bundle into a struct for machine processing. */
1499extern int parse_insn_tile(tile_bundle_bits bits,
1500 unsigned int pc,
1501 struct tile_decoded_instruction
1502 decoded[TILE_MAX_INSTRUCTIONS_PER_BUNDLE]);
1503
1504
1505
1506#endif /* opcode_tile_h */
diff --git a/arch/tile/include/asm/opcode-tile_64.h b/arch/tile/include/asm/opcode-tile_64.h
new file mode 100644
index 000000000000..eda60ecbae3d
--- /dev/null
+++ b/arch/tile/include/asm/opcode-tile_64.h
@@ -0,0 +1,1506 @@
1/* tile.h -- Header file for TILE opcode table
2 Copyright (C) 2005 Free Software Foundation, Inc.
3 Contributed by Tilera Corp. */
4
5#ifndef opcode_tile_h
6#define opcode_tile_h
7
8typedef unsigned long long tile_bundle_bits;
9
10
11enum
12{
13 TILE_MAX_OPERANDS = 5 /* mm */
14};
15
16typedef enum
17{
18 TILE_OPC_BPT,
19 TILE_OPC_INFO,
20 TILE_OPC_INFOL,
21 TILE_OPC_J,
22 TILE_OPC_JAL,
23 TILE_OPC_MOVE,
24 TILE_OPC_MOVE_SN,
25 TILE_OPC_MOVEI,
26 TILE_OPC_MOVEI_SN,
27 TILE_OPC_MOVELI,
28 TILE_OPC_MOVELI_SN,
29 TILE_OPC_MOVELIS,
30 TILE_OPC_PREFETCH,
31 TILE_OPC_RAISE,
32 TILE_OPC_ADD,
33 TILE_OPC_ADD_SN,
34 TILE_OPC_ADDB,
35 TILE_OPC_ADDB_SN,
36 TILE_OPC_ADDBS_U,
37 TILE_OPC_ADDBS_U_SN,
38 TILE_OPC_ADDH,
39 TILE_OPC_ADDH_SN,
40 TILE_OPC_ADDHS,
41 TILE_OPC_ADDHS_SN,
42 TILE_OPC_ADDI,
43 TILE_OPC_ADDI_SN,
44 TILE_OPC_ADDIB,
45 TILE_OPC_ADDIB_SN,
46 TILE_OPC_ADDIH,
47 TILE_OPC_ADDIH_SN,
48 TILE_OPC_ADDLI,
49 TILE_OPC_ADDLI_SN,
50 TILE_OPC_ADDLIS,
51 TILE_OPC_ADDS,
52 TILE_OPC_ADDS_SN,
53 TILE_OPC_ADIFFB_U,
54 TILE_OPC_ADIFFB_U_SN,
55 TILE_OPC_ADIFFH,
56 TILE_OPC_ADIFFH_SN,
57 TILE_OPC_AND,
58 TILE_OPC_AND_SN,
59 TILE_OPC_ANDI,
60 TILE_OPC_ANDI_SN,
61 TILE_OPC_AULI,
62 TILE_OPC_AVGB_U,
63 TILE_OPC_AVGB_U_SN,
64 TILE_OPC_AVGH,
65 TILE_OPC_AVGH_SN,
66 TILE_OPC_BBNS,
67 TILE_OPC_BBNS_SN,
68 TILE_OPC_BBNST,
69 TILE_OPC_BBNST_SN,
70 TILE_OPC_BBS,
71 TILE_OPC_BBS_SN,
72 TILE_OPC_BBST,
73 TILE_OPC_BBST_SN,
74 TILE_OPC_BGEZ,
75 TILE_OPC_BGEZ_SN,
76 TILE_OPC_BGEZT,
77 TILE_OPC_BGEZT_SN,
78 TILE_OPC_BGZ,
79 TILE_OPC_BGZ_SN,
80 TILE_OPC_BGZT,
81 TILE_OPC_BGZT_SN,
82 TILE_OPC_BITX,
83 TILE_OPC_BITX_SN,
84 TILE_OPC_BLEZ,
85 TILE_OPC_BLEZ_SN,
86 TILE_OPC_BLEZT,
87 TILE_OPC_BLEZT_SN,
88 TILE_OPC_BLZ,
89 TILE_OPC_BLZ_SN,
90 TILE_OPC_BLZT,
91 TILE_OPC_BLZT_SN,
92 TILE_OPC_BNZ,
93 TILE_OPC_BNZ_SN,
94 TILE_OPC_BNZT,
95 TILE_OPC_BNZT_SN,
96 TILE_OPC_BYTEX,
97 TILE_OPC_BYTEX_SN,
98 TILE_OPC_BZ,
99 TILE_OPC_BZ_SN,
100 TILE_OPC_BZT,
101 TILE_OPC_BZT_SN,
102 TILE_OPC_CLZ,
103 TILE_OPC_CLZ_SN,
104 TILE_OPC_CRC32_32,
105 TILE_OPC_CRC32_32_SN,
106 TILE_OPC_CRC32_8,
107 TILE_OPC_CRC32_8_SN,
108 TILE_OPC_CTZ,
109 TILE_OPC_CTZ_SN,
110 TILE_OPC_DRAIN,
111 TILE_OPC_DTLBPR,
112 TILE_OPC_DWORD_ALIGN,
113 TILE_OPC_DWORD_ALIGN_SN,
114 TILE_OPC_FINV,
115 TILE_OPC_FLUSH,
116 TILE_OPC_FNOP,
117 TILE_OPC_ICOH,
118 TILE_OPC_ILL,
119 TILE_OPC_INTHB,
120 TILE_OPC_INTHB_SN,
121 TILE_OPC_INTHH,
122 TILE_OPC_INTHH_SN,
123 TILE_OPC_INTLB,
124 TILE_OPC_INTLB_SN,
125 TILE_OPC_INTLH,
126 TILE_OPC_INTLH_SN,
127 TILE_OPC_INV,
128 TILE_OPC_IRET,
129 TILE_OPC_JALB,
130 TILE_OPC_JALF,
131 TILE_OPC_JALR,
132 TILE_OPC_JALRP,
133 TILE_OPC_JB,
134 TILE_OPC_JF,
135 TILE_OPC_JR,
136 TILE_OPC_JRP,
137 TILE_OPC_LB,
138 TILE_OPC_LB_SN,
139 TILE_OPC_LB_U,
140 TILE_OPC_LB_U_SN,
141 TILE_OPC_LBADD,
142 TILE_OPC_LBADD_SN,
143 TILE_OPC_LBADD_U,
144 TILE_OPC_LBADD_U_SN,
145 TILE_OPC_LH,
146 TILE_OPC_LH_SN,
147 TILE_OPC_LH_U,
148 TILE_OPC_LH_U_SN,
149 TILE_OPC_LHADD,
150 TILE_OPC_LHADD_SN,
151 TILE_OPC_LHADD_U,
152 TILE_OPC_LHADD_U_SN,
153 TILE_OPC_LNK,
154 TILE_OPC_LNK_SN,
155 TILE_OPC_LW,
156 TILE_OPC_LW_SN,
157 TILE_OPC_LW_NA,
158 TILE_OPC_LW_NA_SN,
159 TILE_OPC_LWADD,
160 TILE_OPC_LWADD_SN,
161 TILE_OPC_LWADD_NA,
162 TILE_OPC_LWADD_NA_SN,
163 TILE_OPC_MAXB_U,
164 TILE_OPC_MAXB_U_SN,
165 TILE_OPC_MAXH,
166 TILE_OPC_MAXH_SN,
167 TILE_OPC_MAXIB_U,
168 TILE_OPC_MAXIB_U_SN,
169 TILE_OPC_MAXIH,
170 TILE_OPC_MAXIH_SN,
171 TILE_OPC_MF,
172 TILE_OPC_MFSPR,
173 TILE_OPC_MINB_U,
174 TILE_OPC_MINB_U_SN,
175 TILE_OPC_MINH,
176 TILE_OPC_MINH_SN,
177 TILE_OPC_MINIB_U,
178 TILE_OPC_MINIB_U_SN,
179 TILE_OPC_MINIH,
180 TILE_OPC_MINIH_SN,
181 TILE_OPC_MM,
182 TILE_OPC_MNZ,
183 TILE_OPC_MNZ_SN,
184 TILE_OPC_MNZB,
185 TILE_OPC_MNZB_SN,
186 TILE_OPC_MNZH,
187 TILE_OPC_MNZH_SN,
188 TILE_OPC_MTSPR,
189 TILE_OPC_MULHH_SS,
190 TILE_OPC_MULHH_SS_SN,
191 TILE_OPC_MULHH_SU,
192 TILE_OPC_MULHH_SU_SN,
193 TILE_OPC_MULHH_UU,
194 TILE_OPC_MULHH_UU_SN,
195 TILE_OPC_MULHHA_SS,
196 TILE_OPC_MULHHA_SS_SN,
197 TILE_OPC_MULHHA_SU,
198 TILE_OPC_MULHHA_SU_SN,
199 TILE_OPC_MULHHA_UU,
200 TILE_OPC_MULHHA_UU_SN,
201 TILE_OPC_MULHHSA_UU,
202 TILE_OPC_MULHHSA_UU_SN,
203 TILE_OPC_MULHL_SS,
204 TILE_OPC_MULHL_SS_SN,
205 TILE_OPC_MULHL_SU,
206 TILE_OPC_MULHL_SU_SN,
207 TILE_OPC_MULHL_US,
208 TILE_OPC_MULHL_US_SN,
209 TILE_OPC_MULHL_UU,
210 TILE_OPC_MULHL_UU_SN,
211 TILE_OPC_MULHLA_SS,
212 TILE_OPC_MULHLA_SS_SN,
213 TILE_OPC_MULHLA_SU,
214 TILE_OPC_MULHLA_SU_SN,
215 TILE_OPC_MULHLA_US,
216 TILE_OPC_MULHLA_US_SN,
217 TILE_OPC_MULHLA_UU,
218 TILE_OPC_MULHLA_UU_SN,
219 TILE_OPC_MULHLSA_UU,
220 TILE_OPC_MULHLSA_UU_SN,
221 TILE_OPC_MULLL_SS,
222 TILE_OPC_MULLL_SS_SN,
223 TILE_OPC_MULLL_SU,
224 TILE_OPC_MULLL_SU_SN,
225 TILE_OPC_MULLL_UU,
226 TILE_OPC_MULLL_UU_SN,
227 TILE_OPC_MULLLA_SS,
228 TILE_OPC_MULLLA_SS_SN,
229 TILE_OPC_MULLLA_SU,
230 TILE_OPC_MULLLA_SU_SN,
231 TILE_OPC_MULLLA_UU,
232 TILE_OPC_MULLLA_UU_SN,
233 TILE_OPC_MULLLSA_UU,
234 TILE_OPC_MULLLSA_UU_SN,
235 TILE_OPC_MVNZ,
236 TILE_OPC_MVNZ_SN,
237 TILE_OPC_MVZ,
238 TILE_OPC_MVZ_SN,
239 TILE_OPC_MZ,
240 TILE_OPC_MZ_SN,
241 TILE_OPC_MZB,
242 TILE_OPC_MZB_SN,
243 TILE_OPC_MZH,
244 TILE_OPC_MZH_SN,
245 TILE_OPC_NAP,
246 TILE_OPC_NOP,
247 TILE_OPC_NOR,
248 TILE_OPC_NOR_SN,
249 TILE_OPC_OR,
250 TILE_OPC_OR_SN,
251 TILE_OPC_ORI,
252 TILE_OPC_ORI_SN,
253 TILE_OPC_PACKBS_U,
254 TILE_OPC_PACKBS_U_SN,
255 TILE_OPC_PACKHB,
256 TILE_OPC_PACKHB_SN,
257 TILE_OPC_PACKHS,
258 TILE_OPC_PACKHS_SN,
259 TILE_OPC_PACKLB,
260 TILE_OPC_PACKLB_SN,
261 TILE_OPC_PCNT,
262 TILE_OPC_PCNT_SN,
263 TILE_OPC_RL,
264 TILE_OPC_RL_SN,
265 TILE_OPC_RLI,
266 TILE_OPC_RLI_SN,
267 TILE_OPC_S1A,
268 TILE_OPC_S1A_SN,
269 TILE_OPC_S2A,
270 TILE_OPC_S2A_SN,
271 TILE_OPC_S3A,
272 TILE_OPC_S3A_SN,
273 TILE_OPC_SADAB_U,
274 TILE_OPC_SADAB_U_SN,
275 TILE_OPC_SADAH,
276 TILE_OPC_SADAH_SN,
277 TILE_OPC_SADAH_U,
278 TILE_OPC_SADAH_U_SN,
279 TILE_OPC_SADB_U,
280 TILE_OPC_SADB_U_SN,
281 TILE_OPC_SADH,
282 TILE_OPC_SADH_SN,
283 TILE_OPC_SADH_U,
284 TILE_OPC_SADH_U_SN,
285 TILE_OPC_SB,
286 TILE_OPC_SBADD,
287 TILE_OPC_SEQ,
288 TILE_OPC_SEQ_SN,
289 TILE_OPC_SEQB,
290 TILE_OPC_SEQB_SN,
291 TILE_OPC_SEQH,
292 TILE_OPC_SEQH_SN,
293 TILE_OPC_SEQI,
294 TILE_OPC_SEQI_SN,
295 TILE_OPC_SEQIB,
296 TILE_OPC_SEQIB_SN,
297 TILE_OPC_SEQIH,
298 TILE_OPC_SEQIH_SN,
299 TILE_OPC_SH,
300 TILE_OPC_SHADD,
301 TILE_OPC_SHL,
302 TILE_OPC_SHL_SN,
303 TILE_OPC_SHLB,
304 TILE_OPC_SHLB_SN,
305 TILE_OPC_SHLH,
306 TILE_OPC_SHLH_SN,
307 TILE_OPC_SHLI,
308 TILE_OPC_SHLI_SN,
309 TILE_OPC_SHLIB,
310 TILE_OPC_SHLIB_SN,
311 TILE_OPC_SHLIH,
312 TILE_OPC_SHLIH_SN,
313 TILE_OPC_SHR,
314 TILE_OPC_SHR_SN,
315 TILE_OPC_SHRB,
316 TILE_OPC_SHRB_SN,
317 TILE_OPC_SHRH,
318 TILE_OPC_SHRH_SN,
319 TILE_OPC_SHRI,
320 TILE_OPC_SHRI_SN,
321 TILE_OPC_SHRIB,
322 TILE_OPC_SHRIB_SN,
323 TILE_OPC_SHRIH,
324 TILE_OPC_SHRIH_SN,
325 TILE_OPC_SLT,
326 TILE_OPC_SLT_SN,
327 TILE_OPC_SLT_U,
328 TILE_OPC_SLT_U_SN,
329 TILE_OPC_SLTB,
330 TILE_OPC_SLTB_SN,
331 TILE_OPC_SLTB_U,
332 TILE_OPC_SLTB_U_SN,
333 TILE_OPC_SLTE,
334 TILE_OPC_SLTE_SN,
335 TILE_OPC_SLTE_U,
336 TILE_OPC_SLTE_U_SN,
337 TILE_OPC_SLTEB,
338 TILE_OPC_SLTEB_SN,
339 TILE_OPC_SLTEB_U,
340 TILE_OPC_SLTEB_U_SN,
341 TILE_OPC_SLTEH,
342 TILE_OPC_SLTEH_SN,
343 TILE_OPC_SLTEH_U,
344 TILE_OPC_SLTEH_U_SN,
345 TILE_OPC_SLTH,
346 TILE_OPC_SLTH_SN,
347 TILE_OPC_SLTH_U,
348 TILE_OPC_SLTH_U_SN,
349 TILE_OPC_SLTI,
350 TILE_OPC_SLTI_SN,
351 TILE_OPC_SLTI_U,
352 TILE_OPC_SLTI_U_SN,
353 TILE_OPC_SLTIB,
354 TILE_OPC_SLTIB_SN,
355 TILE_OPC_SLTIB_U,
356 TILE_OPC_SLTIB_U_SN,
357 TILE_OPC_SLTIH,
358 TILE_OPC_SLTIH_SN,
359 TILE_OPC_SLTIH_U,
360 TILE_OPC_SLTIH_U_SN,
361 TILE_OPC_SNE,
362 TILE_OPC_SNE_SN,
363 TILE_OPC_SNEB,
364 TILE_OPC_SNEB_SN,
365 TILE_OPC_SNEH,
366 TILE_OPC_SNEH_SN,
367 TILE_OPC_SRA,
368 TILE_OPC_SRA_SN,
369 TILE_OPC_SRAB,
370 TILE_OPC_SRAB_SN,
371 TILE_OPC_SRAH,
372 TILE_OPC_SRAH_SN,
373 TILE_OPC_SRAI,
374 TILE_OPC_SRAI_SN,
375 TILE_OPC_SRAIB,
376 TILE_OPC_SRAIB_SN,
377 TILE_OPC_SRAIH,
378 TILE_OPC_SRAIH_SN,
379 TILE_OPC_SUB,
380 TILE_OPC_SUB_SN,
381 TILE_OPC_SUBB,
382 TILE_OPC_SUBB_SN,
383 TILE_OPC_SUBBS_U,
384 TILE_OPC_SUBBS_U_SN,
385 TILE_OPC_SUBH,
386 TILE_OPC_SUBH_SN,
387 TILE_OPC_SUBHS,
388 TILE_OPC_SUBHS_SN,
389 TILE_OPC_SUBS,
390 TILE_OPC_SUBS_SN,
391 TILE_OPC_SW,
392 TILE_OPC_SWADD,
393 TILE_OPC_SWINT0,
394 TILE_OPC_SWINT1,
395 TILE_OPC_SWINT2,
396 TILE_OPC_SWINT3,
397 TILE_OPC_TBLIDXB0,
398 TILE_OPC_TBLIDXB0_SN,
399 TILE_OPC_TBLIDXB1,
400 TILE_OPC_TBLIDXB1_SN,
401 TILE_OPC_TBLIDXB2,
402 TILE_OPC_TBLIDXB2_SN,
403 TILE_OPC_TBLIDXB3,
404 TILE_OPC_TBLIDXB3_SN,
405 TILE_OPC_TNS,
406 TILE_OPC_TNS_SN,
407 TILE_OPC_WH64,
408 TILE_OPC_XOR,
409 TILE_OPC_XOR_SN,
410 TILE_OPC_XORI,
411 TILE_OPC_XORI_SN,
412 TILE_OPC_NONE
413} tile_mnemonic;
414
415/* 64-bit pattern for a { bpt ; nop } bundle. */
416#define TILE_BPT_BUNDLE 0x400b3cae70166000ULL
417
418
419#define TILE_ELF_MACHINE_CODE EM_TILEPRO
420
421#define TILE_ELF_NAME "elf32-tilepro"
422
423
424static __inline unsigned int
425get_BrOff_SN(tile_bundle_bits num)
426{
427 const unsigned int n = (unsigned int)num;
428 return (((n >> 0)) & 0x3ff);
429}
430
431static __inline unsigned int
432get_BrOff_X1(tile_bundle_bits n)
433{
434 return (((unsigned int)(n >> 43)) & 0x00007fff) |
435 (((unsigned int)(n >> 20)) & 0x00018000);
436}
437
438static __inline unsigned int
439get_BrType_X1(tile_bundle_bits n)
440{
441 return (((unsigned int)(n >> 31)) & 0xf);
442}
443
444static __inline unsigned int
445get_Dest_Imm8_X1(tile_bundle_bits n)
446{
447 return (((unsigned int)(n >> 31)) & 0x0000003f) |
448 (((unsigned int)(n >> 43)) & 0x000000c0);
449}
450
451static __inline unsigned int
452get_Dest_SN(tile_bundle_bits num)
453{
454 const unsigned int n = (unsigned int)num;
455 return (((n >> 2)) & 0x3);
456}
457
458static __inline unsigned int
459get_Dest_X0(tile_bundle_bits num)
460{
461 const unsigned int n = (unsigned int)num;
462 return (((n >> 0)) & 0x3f);
463}
464
465static __inline unsigned int
466get_Dest_X1(tile_bundle_bits n)
467{
468 return (((unsigned int)(n >> 31)) & 0x3f);
469}
470
471static __inline unsigned int
472get_Dest_Y0(tile_bundle_bits num)
473{
474 const unsigned int n = (unsigned int)num;
475 return (((n >> 0)) & 0x3f);
476}
477
478static __inline unsigned int
479get_Dest_Y1(tile_bundle_bits n)
480{
481 return (((unsigned int)(n >> 31)) & 0x3f);
482}
483
484static __inline unsigned int
485get_Imm16_X0(tile_bundle_bits num)
486{
487 const unsigned int n = (unsigned int)num;
488 return (((n >> 12)) & 0xffff);
489}
490
491static __inline unsigned int
492get_Imm16_X1(tile_bundle_bits n)
493{
494 return (((unsigned int)(n >> 43)) & 0xffff);
495}
496
497static __inline unsigned int
498get_Imm8_SN(tile_bundle_bits num)
499{
500 const unsigned int n = (unsigned int)num;
501 return (((n >> 0)) & 0xff);
502}
503
504static __inline unsigned int
505get_Imm8_X0(tile_bundle_bits num)
506{
507 const unsigned int n = (unsigned int)num;
508 return (((n >> 12)) & 0xff);
509}
510
511static __inline unsigned int
512get_Imm8_X1(tile_bundle_bits n)
513{
514 return (((unsigned int)(n >> 43)) & 0xff);
515}
516
517static __inline unsigned int
518get_Imm8_Y0(tile_bundle_bits num)
519{
520 const unsigned int n = (unsigned int)num;
521 return (((n >> 12)) & 0xff);
522}
523
524static __inline unsigned int
525get_Imm8_Y1(tile_bundle_bits n)
526{
527 return (((unsigned int)(n >> 43)) & 0xff);
528}
529
530static __inline unsigned int
531get_ImmOpcodeExtension_X0(tile_bundle_bits num)
532{
533 const unsigned int n = (unsigned int)num;
534 return (((n >> 20)) & 0x7f);
535}
536
537static __inline unsigned int
538get_ImmOpcodeExtension_X1(tile_bundle_bits n)
539{
540 return (((unsigned int)(n >> 51)) & 0x7f);
541}
542
543static __inline unsigned int
544get_ImmRROpcodeExtension_SN(tile_bundle_bits num)
545{
546 const unsigned int n = (unsigned int)num;
547 return (((n >> 8)) & 0x3);
548}
549
550static __inline unsigned int
551get_JOffLong_X1(tile_bundle_bits n)
552{
553 return (((unsigned int)(n >> 43)) & 0x00007fff) |
554 (((unsigned int)(n >> 20)) & 0x00018000) |
555 (((unsigned int)(n >> 14)) & 0x001e0000) |
556 (((unsigned int)(n >> 16)) & 0x07e00000) |
557 (((unsigned int)(n >> 31)) & 0x18000000);
558}
559
560static __inline unsigned int
561get_JOff_X1(tile_bundle_bits n)
562{
563 return (((unsigned int)(n >> 43)) & 0x00007fff) |
564 (((unsigned int)(n >> 20)) & 0x00018000) |
565 (((unsigned int)(n >> 14)) & 0x001e0000) |
566 (((unsigned int)(n >> 16)) & 0x07e00000) |
567 (((unsigned int)(n >> 31)) & 0x08000000);
568}
569
570static __inline unsigned int
571get_MF_Imm15_X1(tile_bundle_bits n)
572{
573 return (((unsigned int)(n >> 37)) & 0x00003fff) |
574 (((unsigned int)(n >> 44)) & 0x00004000);
575}
576
577static __inline unsigned int
578get_MMEnd_X0(tile_bundle_bits num)
579{
580 const unsigned int n = (unsigned int)num;
581 return (((n >> 18)) & 0x1f);
582}
583
584static __inline unsigned int
585get_MMEnd_X1(tile_bundle_bits n)
586{
587 return (((unsigned int)(n >> 49)) & 0x1f);
588}
589
590static __inline unsigned int
591get_MMStart_X0(tile_bundle_bits num)
592{
593 const unsigned int n = (unsigned int)num;
594 return (((n >> 23)) & 0x1f);
595}
596
597static __inline unsigned int
598get_MMStart_X1(tile_bundle_bits n)
599{
600 return (((unsigned int)(n >> 54)) & 0x1f);
601}
602
603static __inline unsigned int
604get_MT_Imm15_X1(tile_bundle_bits n)
605{
606 return (((unsigned int)(n >> 31)) & 0x0000003f) |
607 (((unsigned int)(n >> 37)) & 0x00003fc0) |
608 (((unsigned int)(n >> 44)) & 0x00004000);
609}
610
611static __inline unsigned int
612get_Mode(tile_bundle_bits n)
613{
614 return (((unsigned int)(n >> 63)) & 0x1);
615}
616
617static __inline unsigned int
618get_NoRegOpcodeExtension_SN(tile_bundle_bits num)
619{
620 const unsigned int n = (unsigned int)num;
621 return (((n >> 0)) & 0xf);
622}
623
624static __inline unsigned int
625get_Opcode_SN(tile_bundle_bits num)
626{
627 const unsigned int n = (unsigned int)num;
628 return (((n >> 10)) & 0x3f);
629}
630
631static __inline unsigned int
632get_Opcode_X0(tile_bundle_bits num)
633{
634 const unsigned int n = (unsigned int)num;
635 return (((n >> 28)) & 0x7);
636}
637
638static __inline unsigned int
639get_Opcode_X1(tile_bundle_bits n)
640{
641 return (((unsigned int)(n >> 59)) & 0xf);
642}
643
644static __inline unsigned int
645get_Opcode_Y0(tile_bundle_bits num)
646{
647 const unsigned int n = (unsigned int)num;
648 return (((n >> 27)) & 0xf);
649}
650
651static __inline unsigned int
652get_Opcode_Y1(tile_bundle_bits n)
653{
654 return (((unsigned int)(n >> 59)) & 0xf);
655}
656
657static __inline unsigned int
658get_Opcode_Y2(tile_bundle_bits n)
659{
660 return (((unsigned int)(n >> 56)) & 0x7);
661}
662
663static __inline unsigned int
664get_RROpcodeExtension_SN(tile_bundle_bits num)
665{
666 const unsigned int n = (unsigned int)num;
667 return (((n >> 4)) & 0xf);
668}
669
670static __inline unsigned int
671get_RRROpcodeExtension_X0(tile_bundle_bits num)
672{
673 const unsigned int n = (unsigned int)num;
674 return (((n >> 18)) & 0x1ff);
675}
676
677static __inline unsigned int
678get_RRROpcodeExtension_X1(tile_bundle_bits n)
679{
680 return (((unsigned int)(n >> 49)) & 0x1ff);
681}
682
683static __inline unsigned int
684get_RRROpcodeExtension_Y0(tile_bundle_bits num)
685{
686 const unsigned int n = (unsigned int)num;
687 return (((n >> 18)) & 0x3);
688}
689
690static __inline unsigned int
691get_RRROpcodeExtension_Y1(tile_bundle_bits n)
692{
693 return (((unsigned int)(n >> 49)) & 0x3);
694}
695
696static __inline unsigned int
697get_RouteOpcodeExtension_SN(tile_bundle_bits num)
698{
699 const unsigned int n = (unsigned int)num;
700 return (((n >> 0)) & 0x3ff);
701}
702
703static __inline unsigned int
704get_S_X0(tile_bundle_bits num)
705{
706 const unsigned int n = (unsigned int)num;
707 return (((n >> 27)) & 0x1);
708}
709
710static __inline unsigned int
711get_S_X1(tile_bundle_bits n)
712{
713 return (((unsigned int)(n >> 58)) & 0x1);
714}
715
716static __inline unsigned int
717get_ShAmt_X0(tile_bundle_bits num)
718{
719 const unsigned int n = (unsigned int)num;
720 return (((n >> 12)) & 0x1f);
721}
722
723static __inline unsigned int
724get_ShAmt_X1(tile_bundle_bits n)
725{
726 return (((unsigned int)(n >> 43)) & 0x1f);
727}
728
729static __inline unsigned int
730get_ShAmt_Y0(tile_bundle_bits num)
731{
732 const unsigned int n = (unsigned int)num;
733 return (((n >> 12)) & 0x1f);
734}
735
736static __inline unsigned int
737get_ShAmt_Y1(tile_bundle_bits n)
738{
739 return (((unsigned int)(n >> 43)) & 0x1f);
740}
741
742static __inline unsigned int
743get_SrcA_X0(tile_bundle_bits num)
744{
745 const unsigned int n = (unsigned int)num;
746 return (((n >> 6)) & 0x3f);
747}
748
749static __inline unsigned int
750get_SrcA_X1(tile_bundle_bits n)
751{
752 return (((unsigned int)(n >> 37)) & 0x3f);
753}
754
755static __inline unsigned int
756get_SrcA_Y0(tile_bundle_bits num)
757{
758 const unsigned int n = (unsigned int)num;
759 return (((n >> 6)) & 0x3f);
760}
761
762static __inline unsigned int
763get_SrcA_Y1(tile_bundle_bits n)
764{
765 return (((unsigned int)(n >> 37)) & 0x3f);
766}
767
768static __inline unsigned int
769get_SrcA_Y2(tile_bundle_bits n)
770{
771 return (((n >> 26)) & 0x00000001) |
772 (((unsigned int)(n >> 50)) & 0x0000003e);
773}
774
775static __inline unsigned int
776get_SrcBDest_Y2(tile_bundle_bits num)
777{
778 const unsigned int n = (unsigned int)num;
779 return (((n >> 20)) & 0x3f);
780}
781
782static __inline unsigned int
783get_SrcB_X0(tile_bundle_bits num)
784{
785 const unsigned int n = (unsigned int)num;
786 return (((n >> 12)) & 0x3f);
787}
788
789static __inline unsigned int
790get_SrcB_X1(tile_bundle_bits n)
791{
792 return (((unsigned int)(n >> 43)) & 0x3f);
793}
794
795static __inline unsigned int
796get_SrcB_Y0(tile_bundle_bits num)
797{
798 const unsigned int n = (unsigned int)num;
799 return (((n >> 12)) & 0x3f);
800}
801
802static __inline unsigned int
803get_SrcB_Y1(tile_bundle_bits n)
804{
805 return (((unsigned int)(n >> 43)) & 0x3f);
806}
807
808static __inline unsigned int
809get_Src_SN(tile_bundle_bits num)
810{
811 const unsigned int n = (unsigned int)num;
812 return (((n >> 0)) & 0x3);
813}
814
815static __inline unsigned int
816get_UnOpcodeExtension_X0(tile_bundle_bits num)
817{
818 const unsigned int n = (unsigned int)num;
819 return (((n >> 12)) & 0x1f);
820}
821
822static __inline unsigned int
823get_UnOpcodeExtension_X1(tile_bundle_bits n)
824{
825 return (((unsigned int)(n >> 43)) & 0x1f);
826}
827
828static __inline unsigned int
829get_UnOpcodeExtension_Y0(tile_bundle_bits num)
830{
831 const unsigned int n = (unsigned int)num;
832 return (((n >> 12)) & 0x1f);
833}
834
835static __inline unsigned int
836get_UnOpcodeExtension_Y1(tile_bundle_bits n)
837{
838 return (((unsigned int)(n >> 43)) & 0x1f);
839}
840
841static __inline unsigned int
842get_UnShOpcodeExtension_X0(tile_bundle_bits num)
843{
844 const unsigned int n = (unsigned int)num;
845 return (((n >> 17)) & 0x3ff);
846}
847
848static __inline unsigned int
849get_UnShOpcodeExtension_X1(tile_bundle_bits n)
850{
851 return (((unsigned int)(n >> 48)) & 0x3ff);
852}
853
854static __inline unsigned int
855get_UnShOpcodeExtension_Y0(tile_bundle_bits num)
856{
857 const unsigned int n = (unsigned int)num;
858 return (((n >> 17)) & 0x7);
859}
860
861static __inline unsigned int
862get_UnShOpcodeExtension_Y1(tile_bundle_bits n)
863{
864 return (((unsigned int)(n >> 48)) & 0x7);
865}
866
867
868static __inline int
869sign_extend(int n, int num_bits)
870{
871 int shift = (int)(sizeof(int) * 8 - num_bits);
872 return (n << shift) >> shift;
873}
874
875
876
877static __inline tile_bundle_bits
878create_BrOff_SN(int num)
879{
880 const unsigned int n = (unsigned int)num;
881 return ((n & 0x3ff) << 0);
882}
883
884static __inline tile_bundle_bits
885create_BrOff_X1(int num)
886{
887 const unsigned int n = (unsigned int)num;
888 return (((tile_bundle_bits)(n & 0x00007fff)) << 43) |
889 (((tile_bundle_bits)(n & 0x00018000)) << 20);
890}
891
892static __inline tile_bundle_bits
893create_BrType_X1(int num)
894{
895 const unsigned int n = (unsigned int)num;
896 return (((tile_bundle_bits)(n & 0xf)) << 31);
897}
898
899static __inline tile_bundle_bits
900create_Dest_Imm8_X1(int num)
901{
902 const unsigned int n = (unsigned int)num;
903 return (((tile_bundle_bits)(n & 0x0000003f)) << 31) |
904 (((tile_bundle_bits)(n & 0x000000c0)) << 43);
905}
906
907static __inline tile_bundle_bits
908create_Dest_SN(int num)
909{
910 const unsigned int n = (unsigned int)num;
911 return ((n & 0x3) << 2);
912}
913
914static __inline tile_bundle_bits
915create_Dest_X0(int num)
916{
917 const unsigned int n = (unsigned int)num;
918 return ((n & 0x3f) << 0);
919}
920
921static __inline tile_bundle_bits
922create_Dest_X1(int num)
923{
924 const unsigned int n = (unsigned int)num;
925 return (((tile_bundle_bits)(n & 0x3f)) << 31);
926}
927
928static __inline tile_bundle_bits
929create_Dest_Y0(int num)
930{
931 const unsigned int n = (unsigned int)num;
932 return ((n & 0x3f) << 0);
933}
934
935static __inline tile_bundle_bits
936create_Dest_Y1(int num)
937{
938 const unsigned int n = (unsigned int)num;
939 return (((tile_bundle_bits)(n & 0x3f)) << 31);
940}
941
942static __inline tile_bundle_bits
943create_Imm16_X0(int num)
944{
945 const unsigned int n = (unsigned int)num;
946 return ((n & 0xffff) << 12);
947}
948
949static __inline tile_bundle_bits
950create_Imm16_X1(int num)
951{
952 const unsigned int n = (unsigned int)num;
953 return (((tile_bundle_bits)(n & 0xffff)) << 43);
954}
955
956static __inline tile_bundle_bits
957create_Imm8_SN(int num)
958{
959 const unsigned int n = (unsigned int)num;
960 return ((n & 0xff) << 0);
961}
962
963static __inline tile_bundle_bits
964create_Imm8_X0(int num)
965{
966 const unsigned int n = (unsigned int)num;
967 return ((n & 0xff) << 12);
968}
969
970static __inline tile_bundle_bits
971create_Imm8_X1(int num)
972{
973 const unsigned int n = (unsigned int)num;
974 return (((tile_bundle_bits)(n & 0xff)) << 43);
975}
976
977static __inline tile_bundle_bits
978create_Imm8_Y0(int num)
979{
980 const unsigned int n = (unsigned int)num;
981 return ((n & 0xff) << 12);
982}
983
984static __inline tile_bundle_bits
985create_Imm8_Y1(int num)
986{
987 const unsigned int n = (unsigned int)num;
988 return (((tile_bundle_bits)(n & 0xff)) << 43);
989}
990
991static __inline tile_bundle_bits
992create_ImmOpcodeExtension_X0(int num)
993{
994 const unsigned int n = (unsigned int)num;
995 return ((n & 0x7f) << 20);
996}
997
998static __inline tile_bundle_bits
999create_ImmOpcodeExtension_X1(int num)
1000{
1001 const unsigned int n = (unsigned int)num;
1002 return (((tile_bundle_bits)(n & 0x7f)) << 51);
1003}
1004
1005static __inline tile_bundle_bits
1006create_ImmRROpcodeExtension_SN(int num)
1007{
1008 const unsigned int n = (unsigned int)num;
1009 return ((n & 0x3) << 8);
1010}
1011
1012static __inline tile_bundle_bits
1013create_JOffLong_X1(int num)
1014{
1015 const unsigned int n = (unsigned int)num;
1016 return (((tile_bundle_bits)(n & 0x00007fff)) << 43) |
1017 (((tile_bundle_bits)(n & 0x00018000)) << 20) |
1018 (((tile_bundle_bits)(n & 0x001e0000)) << 14) |
1019 (((tile_bundle_bits)(n & 0x07e00000)) << 16) |
1020 (((tile_bundle_bits)(n & 0x18000000)) << 31);
1021}
1022
1023static __inline tile_bundle_bits
1024create_JOff_X1(int num)
1025{
1026 const unsigned int n = (unsigned int)num;
1027 return (((tile_bundle_bits)(n & 0x00007fff)) << 43) |
1028 (((tile_bundle_bits)(n & 0x00018000)) << 20) |
1029 (((tile_bundle_bits)(n & 0x001e0000)) << 14) |
1030 (((tile_bundle_bits)(n & 0x07e00000)) << 16) |
1031 (((tile_bundle_bits)(n & 0x08000000)) << 31);
1032}
1033
1034static __inline tile_bundle_bits
1035create_MF_Imm15_X1(int num)
1036{
1037 const unsigned int n = (unsigned int)num;
1038 return (((tile_bundle_bits)(n & 0x00003fff)) << 37) |
1039 (((tile_bundle_bits)(n & 0x00004000)) << 44);
1040}
1041
1042static __inline tile_bundle_bits
1043create_MMEnd_X0(int num)
1044{
1045 const unsigned int n = (unsigned int)num;
1046 return ((n & 0x1f) << 18);
1047}
1048
1049static __inline tile_bundle_bits
1050create_MMEnd_X1(int num)
1051{
1052 const unsigned int n = (unsigned int)num;
1053 return (((tile_bundle_bits)(n & 0x1f)) << 49);
1054}
1055
1056static __inline tile_bundle_bits
1057create_MMStart_X0(int num)
1058{
1059 const unsigned int n = (unsigned int)num;
1060 return ((n & 0x1f) << 23);
1061}
1062
1063static __inline tile_bundle_bits
1064create_MMStart_X1(int num)
1065{
1066 const unsigned int n = (unsigned int)num;
1067 return (((tile_bundle_bits)(n & 0x1f)) << 54);
1068}
1069
1070static __inline tile_bundle_bits
1071create_MT_Imm15_X1(int num)
1072{
1073 const unsigned int n = (unsigned int)num;
1074 return (((tile_bundle_bits)(n & 0x0000003f)) << 31) |
1075 (((tile_bundle_bits)(n & 0x00003fc0)) << 37) |
1076 (((tile_bundle_bits)(n & 0x00004000)) << 44);
1077}
1078
1079static __inline tile_bundle_bits
1080create_Mode(int num)
1081{
1082 const unsigned int n = (unsigned int)num;
1083 return (((tile_bundle_bits)(n & 0x1)) << 63);
1084}
1085
1086static __inline tile_bundle_bits
1087create_NoRegOpcodeExtension_SN(int num)
1088{
1089 const unsigned int n = (unsigned int)num;
1090 return ((n & 0xf) << 0);
1091}
1092
1093static __inline tile_bundle_bits
1094create_Opcode_SN(int num)
1095{
1096 const unsigned int n = (unsigned int)num;
1097 return ((n & 0x3f) << 10);
1098}
1099
1100static __inline tile_bundle_bits
1101create_Opcode_X0(int num)
1102{
1103 const unsigned int n = (unsigned int)num;
1104 return ((n & 0x7) << 28);
1105}
1106
1107static __inline tile_bundle_bits
1108create_Opcode_X1(int num)
1109{
1110 const unsigned int n = (unsigned int)num;
1111 return (((tile_bundle_bits)(n & 0xf)) << 59);
1112}
1113
1114static __inline tile_bundle_bits
1115create_Opcode_Y0(int num)
1116{
1117 const unsigned int n = (unsigned int)num;
1118 return ((n & 0xf) << 27);
1119}
1120
1121static __inline tile_bundle_bits
1122create_Opcode_Y1(int num)
1123{
1124 const unsigned int n = (unsigned int)num;
1125 return (((tile_bundle_bits)(n & 0xf)) << 59);
1126}
1127
1128static __inline tile_bundle_bits
1129create_Opcode_Y2(int num)
1130{
1131 const unsigned int n = (unsigned int)num;
1132 return (((tile_bundle_bits)(n & 0x7)) << 56);
1133}
1134
1135static __inline tile_bundle_bits
1136create_RROpcodeExtension_SN(int num)
1137{
1138 const unsigned int n = (unsigned int)num;
1139 return ((n & 0xf) << 4);
1140}
1141
1142static __inline tile_bundle_bits
1143create_RRROpcodeExtension_X0(int num)
1144{
1145 const unsigned int n = (unsigned int)num;
1146 return ((n & 0x1ff) << 18);
1147}
1148
1149static __inline tile_bundle_bits
1150create_RRROpcodeExtension_X1(int num)
1151{
1152 const unsigned int n = (unsigned int)num;
1153 return (((tile_bundle_bits)(n & 0x1ff)) << 49);
1154}
1155
1156static __inline tile_bundle_bits
1157create_RRROpcodeExtension_Y0(int num)
1158{
1159 const unsigned int n = (unsigned int)num;
1160 return ((n & 0x3) << 18);
1161}
1162
1163static __inline tile_bundle_bits
1164create_RRROpcodeExtension_Y1(int num)
1165{
1166 const unsigned int n = (unsigned int)num;
1167 return (((tile_bundle_bits)(n & 0x3)) << 49);
1168}
1169
1170static __inline tile_bundle_bits
1171create_RouteOpcodeExtension_SN(int num)
1172{
1173 const unsigned int n = (unsigned int)num;
1174 return ((n & 0x3ff) << 0);
1175}
1176
1177static __inline tile_bundle_bits
1178create_S_X0(int num)
1179{
1180 const unsigned int n = (unsigned int)num;
1181 return ((n & 0x1) << 27);
1182}
1183
1184static __inline tile_bundle_bits
1185create_S_X1(int num)
1186{
1187 const unsigned int n = (unsigned int)num;
1188 return (((tile_bundle_bits)(n & 0x1)) << 58);
1189}
1190
1191static __inline tile_bundle_bits
1192create_ShAmt_X0(int num)
1193{
1194 const unsigned int n = (unsigned int)num;
1195 return ((n & 0x1f) << 12);
1196}
1197
1198static __inline tile_bundle_bits
1199create_ShAmt_X1(int num)
1200{
1201 const unsigned int n = (unsigned int)num;
1202 return (((tile_bundle_bits)(n & 0x1f)) << 43);
1203}
1204
1205static __inline tile_bundle_bits
1206create_ShAmt_Y0(int num)
1207{
1208 const unsigned int n = (unsigned int)num;
1209 return ((n & 0x1f) << 12);
1210}
1211
1212static __inline tile_bundle_bits
1213create_ShAmt_Y1(int num)
1214{
1215 const unsigned int n = (unsigned int)num;
1216 return (((tile_bundle_bits)(n & 0x1f)) << 43);
1217}
1218
1219static __inline tile_bundle_bits
1220create_SrcA_X0(int num)
1221{
1222 const unsigned int n = (unsigned int)num;
1223 return ((n & 0x3f) << 6);
1224}
1225
1226static __inline tile_bundle_bits
1227create_SrcA_X1(int num)
1228{
1229 const unsigned int n = (unsigned int)num;
1230 return (((tile_bundle_bits)(n & 0x3f)) << 37);
1231}
1232
1233static __inline tile_bundle_bits
1234create_SrcA_Y0(int num)
1235{
1236 const unsigned int n = (unsigned int)num;
1237 return ((n & 0x3f) << 6);
1238}
1239
1240static __inline tile_bundle_bits
1241create_SrcA_Y1(int num)
1242{
1243 const unsigned int n = (unsigned int)num;
1244 return (((tile_bundle_bits)(n & 0x3f)) << 37);
1245}
1246
1247static __inline tile_bundle_bits
1248create_SrcA_Y2(int num)
1249{
1250 const unsigned int n = (unsigned int)num;
1251 return ((n & 0x00000001) << 26) |
1252 (((tile_bundle_bits)(n & 0x0000003e)) << 50);
1253}
1254
1255static __inline tile_bundle_bits
1256create_SrcBDest_Y2(int num)
1257{
1258 const unsigned int n = (unsigned int)num;
1259 return ((n & 0x3f) << 20);
1260}
1261
1262static __inline tile_bundle_bits
1263create_SrcB_X0(int num)
1264{
1265 const unsigned int n = (unsigned int)num;
1266 return ((n & 0x3f) << 12);
1267}
1268
1269static __inline tile_bundle_bits
1270create_SrcB_X1(int num)
1271{
1272 const unsigned int n = (unsigned int)num;
1273 return (((tile_bundle_bits)(n & 0x3f)) << 43);
1274}
1275
1276static __inline tile_bundle_bits
1277create_SrcB_Y0(int num)
1278{
1279 const unsigned int n = (unsigned int)num;
1280 return ((n & 0x3f) << 12);
1281}
1282
1283static __inline tile_bundle_bits
1284create_SrcB_Y1(int num)
1285{
1286 const unsigned int n = (unsigned int)num;
1287 return (((tile_bundle_bits)(n & 0x3f)) << 43);
1288}
1289
1290static __inline tile_bundle_bits
1291create_Src_SN(int num)
1292{
1293 const unsigned int n = (unsigned int)num;
1294 return ((n & 0x3) << 0);
1295}
1296
1297static __inline tile_bundle_bits
1298create_UnOpcodeExtension_X0(int num)
1299{
1300 const unsigned int n = (unsigned int)num;
1301 return ((n & 0x1f) << 12);
1302}
1303
1304static __inline tile_bundle_bits
1305create_UnOpcodeExtension_X1(int num)
1306{
1307 const unsigned int n = (unsigned int)num;
1308 return (((tile_bundle_bits)(n & 0x1f)) << 43);
1309}
1310
1311static __inline tile_bundle_bits
1312create_UnOpcodeExtension_Y0(int num)
1313{
1314 const unsigned int n = (unsigned int)num;
1315 return ((n & 0x1f) << 12);
1316}
1317
1318static __inline tile_bundle_bits
1319create_UnOpcodeExtension_Y1(int num)
1320{
1321 const unsigned int n = (unsigned int)num;
1322 return (((tile_bundle_bits)(n & 0x1f)) << 43);
1323}
1324
1325static __inline tile_bundle_bits
1326create_UnShOpcodeExtension_X0(int num)
1327{
1328 const unsigned int n = (unsigned int)num;
1329 return ((n & 0x3ff) << 17);
1330}
1331
1332static __inline tile_bundle_bits
1333create_UnShOpcodeExtension_X1(int num)
1334{
1335 const unsigned int n = (unsigned int)num;
1336 return (((tile_bundle_bits)(n & 0x3ff)) << 48);
1337}
1338
1339static __inline tile_bundle_bits
1340create_UnShOpcodeExtension_Y0(int num)
1341{
1342 const unsigned int n = (unsigned int)num;
1343 return ((n & 0x7) << 17);
1344}
1345
1346static __inline tile_bundle_bits
1347create_UnShOpcodeExtension_Y1(int num)
1348{
1349 const unsigned int n = (unsigned int)num;
1350 return (((tile_bundle_bits)(n & 0x7)) << 48);
1351}
1352
1353
1354
1355typedef enum
1356{
1357 TILE_PIPELINE_X0,
1358 TILE_PIPELINE_X1,
1359 TILE_PIPELINE_Y0,
1360 TILE_PIPELINE_Y1,
1361 TILE_PIPELINE_Y2,
1362} tile_pipeline;
1363
1364#define tile_is_x_pipeline(p) ((int)(p) <= (int)TILE_PIPELINE_X1)
1365
1366typedef enum
1367{
1368 TILE_OP_TYPE_REGISTER,
1369 TILE_OP_TYPE_IMMEDIATE,
1370 TILE_OP_TYPE_ADDRESS,
1371 TILE_OP_TYPE_SPR
1372} tile_operand_type;
1373
1374/* This is the bit that determines if a bundle is in the Y encoding. */
1375#define TILE_BUNDLE_Y_ENCODING_MASK ((tile_bundle_bits)1 << 63)
1376
1377enum
1378{
1379 /* Maximum number of instructions in a bundle (2 for X, 3 for Y). */
1380 TILE_MAX_INSTRUCTIONS_PER_BUNDLE = 3,
1381
1382 /* How many different pipeline encodings are there? X0, X1, Y0, Y1, Y2. */
1383 TILE_NUM_PIPELINE_ENCODINGS = 5,
1384
1385 /* Log base 2 of TILE_BUNDLE_SIZE_IN_BYTES. */
1386 TILE_LOG2_BUNDLE_SIZE_IN_BYTES = 3,
1387
1388 /* Instructions take this many bytes. */
1389 TILE_BUNDLE_SIZE_IN_BYTES = 1 << TILE_LOG2_BUNDLE_SIZE_IN_BYTES,
1390
1391 /* Log base 2 of TILE_BUNDLE_ALIGNMENT_IN_BYTES. */
1392 TILE_LOG2_BUNDLE_ALIGNMENT_IN_BYTES = 3,
1393
1394 /* Bundles should be aligned modulo this number of bytes. */
1395 TILE_BUNDLE_ALIGNMENT_IN_BYTES =
1396 (1 << TILE_LOG2_BUNDLE_ALIGNMENT_IN_BYTES),
1397
1398 /* Log base 2 of TILE_SN_INSTRUCTION_SIZE_IN_BYTES. */
1399 TILE_LOG2_SN_INSTRUCTION_SIZE_IN_BYTES = 1,
1400
1401 /* Static network instructions take this many bytes. */
1402 TILE_SN_INSTRUCTION_SIZE_IN_BYTES =
1403 (1 << TILE_LOG2_SN_INSTRUCTION_SIZE_IN_BYTES),
1404
1405 /* Number of registers (some are magic, such as network I/O). */
1406 TILE_NUM_REGISTERS = 64,
1407
1408 /* Number of static network registers. */
1409 TILE_NUM_SN_REGISTERS = 4
1410};
1411
1412
1413struct tile_operand
1414{
1415 /* Is this operand a register, immediate or address? */
1416 tile_operand_type type;
1417
1418 /* The default relocation type for this operand. */
1419 signed int default_reloc : 16;
1420
1421 /* How many bits is this value? (used for range checking) */
1422 unsigned int num_bits : 5;
1423
1424 /* Is the value signed? (used for range checking) */
1425 unsigned int is_signed : 1;
1426
1427 /* Is this operand a source register? */
1428 unsigned int is_src_reg : 1;
1429
1430 /* Is this operand written? (i.e. is it a destination register) */
1431 unsigned int is_dest_reg : 1;
1432
1433 /* Is this operand PC-relative? */
1434 unsigned int is_pc_relative : 1;
1435
1436 /* By how many bits do we right shift the value before inserting? */
1437 unsigned int rightshift : 2;
1438
1439 /* Return the bits for this operand to be ORed into an existing bundle. */
1440 tile_bundle_bits (*insert) (int op);
1441
1442 /* Extract this operand and return it. */
1443 unsigned int (*extract) (tile_bundle_bits bundle);
1444};
1445
1446
1447extern const struct tile_operand tile_operands[];
1448
1449/* One finite-state machine per pipe for rapid instruction decoding. */
1450extern const unsigned short * const
1451tile_bundle_decoder_fsms[TILE_NUM_PIPELINE_ENCODINGS];
1452
1453
1454struct tile_opcode
1455{
1456 /* The opcode mnemonic, e.g. "add" */
1457 const char *name;
1458
1459 /* The enum value for this mnemonic. */
1460 tile_mnemonic mnemonic;
1461
1462 /* A bit mask of which of the five pipes this instruction
1463 is compatible with:
1464 X0 0x01
1465 X1 0x02
1466 Y0 0x04
1467 Y1 0x08
1468 Y2 0x10 */
1469 unsigned char pipes;
1470
1471 /* How many operands are there? */
1472 unsigned char num_operands;
1473
1474 /* Which register does this write implicitly, or TREG_ZERO if none? */
1475 unsigned char implicitly_written_register;
1476
1477 /* Can this be bundled with other instructions (almost always true). */
1478 unsigned char can_bundle;
1479
1480 /* The description of the operands. Each of these is an
1481 * index into the tile_operands[] table. */
1482 unsigned char operands[TILE_NUM_PIPELINE_ENCODINGS][TILE_MAX_OPERANDS];
1483
1484};
1485
1486extern const struct tile_opcode tile_opcodes[];
1487
1488
1489/* Used for non-textual disassembly into structs. */
1490struct tile_decoded_instruction
1491{
1492 const struct tile_opcode *opcode;
1493 const struct tile_operand *operands[TILE_MAX_OPERANDS];
1494 int operand_values[TILE_MAX_OPERANDS];
1495};
1496
1497
1498/* Disassemble a bundle into a struct for machine processing. */
1499extern int parse_insn_tile(tile_bundle_bits bits,
1500 unsigned int pc,
1501 struct tile_decoded_instruction
1502 decoded[TILE_MAX_INSTRUCTIONS_PER_BUNDLE]);
1503
1504
1505
1506#endif /* opcode_tile_h */
diff --git a/arch/tile/include/asm/opcode_constants.h b/arch/tile/include/asm/opcode_constants.h
new file mode 100644
index 000000000000..37a9f2958cb1
--- /dev/null
+++ b/arch/tile/include/asm/opcode_constants.h
@@ -0,0 +1,26 @@
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_OPCODE_CONSTANTS_H
16#define _ASM_TILE_OPCODE_CONSTANTS_H
17
18#include <arch/chip.h>
19
20#if CHIP_WORD_SIZE() == 64
21#include <asm/opcode_constants_64.h>
22#else
23#include <asm/opcode_constants_32.h>
24#endif
25
26#endif /* _ASM_TILE_OPCODE_CONSTANTS_H */
diff --git a/arch/tile/include/asm/opcode_constants_32.h b/arch/tile/include/asm/opcode_constants_32.h
new file mode 100644
index 000000000000..227d033b180c
--- /dev/null
+++ b/arch/tile/include/asm/opcode_constants_32.h
@@ -0,0 +1,480 @@
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/* This file is machine-generated; DO NOT EDIT! */
16
17
18#ifndef _TILE_OPCODE_CONSTANTS_H
19#define _TILE_OPCODE_CONSTANTS_H
20enum
21{
22 ADDBS_U_SPECIAL_0_OPCODE_X0 = 98,
23 ADDBS_U_SPECIAL_0_OPCODE_X1 = 68,
24 ADDB_SPECIAL_0_OPCODE_X0 = 1,
25 ADDB_SPECIAL_0_OPCODE_X1 = 1,
26 ADDHS_SPECIAL_0_OPCODE_X0 = 99,
27 ADDHS_SPECIAL_0_OPCODE_X1 = 69,
28 ADDH_SPECIAL_0_OPCODE_X0 = 2,
29 ADDH_SPECIAL_0_OPCODE_X1 = 2,
30 ADDIB_IMM_0_OPCODE_X0 = 1,
31 ADDIB_IMM_0_OPCODE_X1 = 1,
32 ADDIH_IMM_0_OPCODE_X0 = 2,
33 ADDIH_IMM_0_OPCODE_X1 = 2,
34 ADDI_IMM_0_OPCODE_X0 = 3,
35 ADDI_IMM_0_OPCODE_X1 = 3,
36 ADDI_IMM_1_OPCODE_SN = 1,
37 ADDI_OPCODE_Y0 = 9,
38 ADDI_OPCODE_Y1 = 7,
39 ADDLIS_OPCODE_X0 = 1,
40 ADDLIS_OPCODE_X1 = 2,
41 ADDLI_OPCODE_X0 = 2,
42 ADDLI_OPCODE_X1 = 3,
43 ADDS_SPECIAL_0_OPCODE_X0 = 96,
44 ADDS_SPECIAL_0_OPCODE_X1 = 66,
45 ADD_SPECIAL_0_OPCODE_X0 = 3,
46 ADD_SPECIAL_0_OPCODE_X1 = 3,
47 ADD_SPECIAL_0_OPCODE_Y0 = 0,
48 ADD_SPECIAL_0_OPCODE_Y1 = 0,
49 ADIFFB_U_SPECIAL_0_OPCODE_X0 = 4,
50 ADIFFH_SPECIAL_0_OPCODE_X0 = 5,
51 ANDI_IMM_0_OPCODE_X0 = 1,
52 ANDI_IMM_0_OPCODE_X1 = 4,
53 ANDI_OPCODE_Y0 = 10,
54 ANDI_OPCODE_Y1 = 8,
55 AND_SPECIAL_0_OPCODE_X0 = 6,
56 AND_SPECIAL_0_OPCODE_X1 = 4,
57 AND_SPECIAL_2_OPCODE_Y0 = 0,
58 AND_SPECIAL_2_OPCODE_Y1 = 0,
59 AULI_OPCODE_X0 = 3,
60 AULI_OPCODE_X1 = 4,
61 AVGB_U_SPECIAL_0_OPCODE_X0 = 7,
62 AVGH_SPECIAL_0_OPCODE_X0 = 8,
63 BBNST_BRANCH_OPCODE_X1 = 15,
64 BBNS_BRANCH_OPCODE_X1 = 14,
65 BBNS_OPCODE_SN = 63,
66 BBST_BRANCH_OPCODE_X1 = 13,
67 BBS_BRANCH_OPCODE_X1 = 12,
68 BBS_OPCODE_SN = 62,
69 BGEZT_BRANCH_OPCODE_X1 = 7,
70 BGEZ_BRANCH_OPCODE_X1 = 6,
71 BGEZ_OPCODE_SN = 61,
72 BGZT_BRANCH_OPCODE_X1 = 5,
73 BGZ_BRANCH_OPCODE_X1 = 4,
74 BGZ_OPCODE_SN = 58,
75 BITX_UN_0_SHUN_0_OPCODE_X0 = 1,
76 BITX_UN_0_SHUN_0_OPCODE_Y0 = 1,
77 BLEZT_BRANCH_OPCODE_X1 = 11,
78 BLEZ_BRANCH_OPCODE_X1 = 10,
79 BLEZ_OPCODE_SN = 59,
80 BLZT_BRANCH_OPCODE_X1 = 9,
81 BLZ_BRANCH_OPCODE_X1 = 8,
82 BLZ_OPCODE_SN = 60,
83 BNZT_BRANCH_OPCODE_X1 = 3,
84 BNZ_BRANCH_OPCODE_X1 = 2,
85 BNZ_OPCODE_SN = 57,
86 BPT_NOREG_RR_IMM_0_OPCODE_SN = 1,
87 BRANCH_OPCODE_X1 = 5,
88 BYTEX_UN_0_SHUN_0_OPCODE_X0 = 2,
89 BYTEX_UN_0_SHUN_0_OPCODE_Y0 = 2,
90 BZT_BRANCH_OPCODE_X1 = 1,
91 BZ_BRANCH_OPCODE_X1 = 0,
92 BZ_OPCODE_SN = 56,
93 CLZ_UN_0_SHUN_0_OPCODE_X0 = 3,
94 CLZ_UN_0_SHUN_0_OPCODE_Y0 = 3,
95 CRC32_32_SPECIAL_0_OPCODE_X0 = 9,
96 CRC32_8_SPECIAL_0_OPCODE_X0 = 10,
97 CTZ_UN_0_SHUN_0_OPCODE_X0 = 4,
98 CTZ_UN_0_SHUN_0_OPCODE_Y0 = 4,
99 DRAIN_UN_0_SHUN_0_OPCODE_X1 = 1,
100 DTLBPR_UN_0_SHUN_0_OPCODE_X1 = 2,
101 DWORD_ALIGN_SPECIAL_0_OPCODE_X0 = 95,
102 FINV_UN_0_SHUN_0_OPCODE_X1 = 3,
103 FLUSH_UN_0_SHUN_0_OPCODE_X1 = 4,
104 FNOP_NOREG_RR_IMM_0_OPCODE_SN = 3,
105 FNOP_UN_0_SHUN_0_OPCODE_X0 = 5,
106 FNOP_UN_0_SHUN_0_OPCODE_X1 = 5,
107 FNOP_UN_0_SHUN_0_OPCODE_Y0 = 5,
108 FNOP_UN_0_SHUN_0_OPCODE_Y1 = 1,
109 HALT_NOREG_RR_IMM_0_OPCODE_SN = 0,
110 ICOH_UN_0_SHUN_0_OPCODE_X1 = 6,
111 ILL_UN_0_SHUN_0_OPCODE_X1 = 7,
112 ILL_UN_0_SHUN_0_OPCODE_Y1 = 2,
113 IMM_0_OPCODE_SN = 0,
114 IMM_0_OPCODE_X0 = 4,
115 IMM_0_OPCODE_X1 = 6,
116 IMM_1_OPCODE_SN = 1,
117 IMM_OPCODE_0_X0 = 5,
118 INTHB_SPECIAL_0_OPCODE_X0 = 11,
119 INTHB_SPECIAL_0_OPCODE_X1 = 5,
120 INTHH_SPECIAL_0_OPCODE_X0 = 12,
121 INTHH_SPECIAL_0_OPCODE_X1 = 6,
122 INTLB_SPECIAL_0_OPCODE_X0 = 13,
123 INTLB_SPECIAL_0_OPCODE_X1 = 7,
124 INTLH_SPECIAL_0_OPCODE_X0 = 14,
125 INTLH_SPECIAL_0_OPCODE_X1 = 8,
126 INV_UN_0_SHUN_0_OPCODE_X1 = 8,
127 IRET_UN_0_SHUN_0_OPCODE_X1 = 9,
128 JALB_OPCODE_X1 = 13,
129 JALF_OPCODE_X1 = 12,
130 JALRP_SPECIAL_0_OPCODE_X1 = 9,
131 JALRR_IMM_1_OPCODE_SN = 3,
132 JALR_RR_IMM_0_OPCODE_SN = 5,
133 JALR_SPECIAL_0_OPCODE_X1 = 10,
134 JB_OPCODE_X1 = 11,
135 JF_OPCODE_X1 = 10,
136 JRP_SPECIAL_0_OPCODE_X1 = 11,
137 JRR_IMM_1_OPCODE_SN = 2,
138 JR_RR_IMM_0_OPCODE_SN = 4,
139 JR_SPECIAL_0_OPCODE_X1 = 12,
140 LBADD_IMM_0_OPCODE_X1 = 22,
141 LBADD_U_IMM_0_OPCODE_X1 = 23,
142 LB_OPCODE_Y2 = 0,
143 LB_UN_0_SHUN_0_OPCODE_X1 = 10,
144 LB_U_OPCODE_Y2 = 1,
145 LB_U_UN_0_SHUN_0_OPCODE_X1 = 11,
146 LHADD_IMM_0_OPCODE_X1 = 24,
147 LHADD_U_IMM_0_OPCODE_X1 = 25,
148 LH_OPCODE_Y2 = 2,
149 LH_UN_0_SHUN_0_OPCODE_X1 = 12,
150 LH_U_OPCODE_Y2 = 3,
151 LH_U_UN_0_SHUN_0_OPCODE_X1 = 13,
152 LNK_SPECIAL_0_OPCODE_X1 = 13,
153 LWADD_IMM_0_OPCODE_X1 = 26,
154 LWADD_NA_IMM_0_OPCODE_X1 = 27,
155 LW_NA_UN_0_SHUN_0_OPCODE_X1 = 24,
156 LW_OPCODE_Y2 = 4,
157 LW_UN_0_SHUN_0_OPCODE_X1 = 14,
158 MAXB_U_SPECIAL_0_OPCODE_X0 = 15,
159 MAXB_U_SPECIAL_0_OPCODE_X1 = 14,
160 MAXH_SPECIAL_0_OPCODE_X0 = 16,
161 MAXH_SPECIAL_0_OPCODE_X1 = 15,
162 MAXIB_U_IMM_0_OPCODE_X0 = 4,
163 MAXIB_U_IMM_0_OPCODE_X1 = 5,
164 MAXIH_IMM_0_OPCODE_X0 = 5,
165 MAXIH_IMM_0_OPCODE_X1 = 6,
166 MFSPR_IMM_0_OPCODE_X1 = 7,
167 MF_UN_0_SHUN_0_OPCODE_X1 = 15,
168 MINB_U_SPECIAL_0_OPCODE_X0 = 17,
169 MINB_U_SPECIAL_0_OPCODE_X1 = 16,
170 MINH_SPECIAL_0_OPCODE_X0 = 18,
171 MINH_SPECIAL_0_OPCODE_X1 = 17,
172 MINIB_U_IMM_0_OPCODE_X0 = 6,
173 MINIB_U_IMM_0_OPCODE_X1 = 8,
174 MINIH_IMM_0_OPCODE_X0 = 7,
175 MINIH_IMM_0_OPCODE_X1 = 9,
176 MM_OPCODE_X0 = 6,
177 MM_OPCODE_X1 = 7,
178 MNZB_SPECIAL_0_OPCODE_X0 = 19,
179 MNZB_SPECIAL_0_OPCODE_X1 = 18,
180 MNZH_SPECIAL_0_OPCODE_X0 = 20,
181 MNZH_SPECIAL_0_OPCODE_X1 = 19,
182 MNZ_SPECIAL_0_OPCODE_X0 = 21,
183 MNZ_SPECIAL_0_OPCODE_X1 = 20,
184 MNZ_SPECIAL_1_OPCODE_Y0 = 0,
185 MNZ_SPECIAL_1_OPCODE_Y1 = 1,
186 MOVEI_IMM_1_OPCODE_SN = 0,
187 MOVE_RR_IMM_0_OPCODE_SN = 8,
188 MTSPR_IMM_0_OPCODE_X1 = 10,
189 MULHHA_SS_SPECIAL_0_OPCODE_X0 = 22,
190 MULHHA_SS_SPECIAL_7_OPCODE_Y0 = 0,
191 MULHHA_SU_SPECIAL_0_OPCODE_X0 = 23,
192 MULHHA_UU_SPECIAL_0_OPCODE_X0 = 24,
193 MULHHA_UU_SPECIAL_7_OPCODE_Y0 = 1,
194 MULHHSA_UU_SPECIAL_0_OPCODE_X0 = 25,
195 MULHH_SS_SPECIAL_0_OPCODE_X0 = 26,
196 MULHH_SS_SPECIAL_6_OPCODE_Y0 = 0,
197 MULHH_SU_SPECIAL_0_OPCODE_X0 = 27,
198 MULHH_UU_SPECIAL_0_OPCODE_X0 = 28,
199 MULHH_UU_SPECIAL_6_OPCODE_Y0 = 1,
200 MULHLA_SS_SPECIAL_0_OPCODE_X0 = 29,
201 MULHLA_SU_SPECIAL_0_OPCODE_X0 = 30,
202 MULHLA_US_SPECIAL_0_OPCODE_X0 = 31,
203 MULHLA_UU_SPECIAL_0_OPCODE_X0 = 32,
204 MULHLSA_UU_SPECIAL_0_OPCODE_X0 = 33,
205 MULHLSA_UU_SPECIAL_5_OPCODE_Y0 = 0,
206 MULHL_SS_SPECIAL_0_OPCODE_X0 = 34,
207 MULHL_SU_SPECIAL_0_OPCODE_X0 = 35,
208 MULHL_US_SPECIAL_0_OPCODE_X0 = 36,
209 MULHL_UU_SPECIAL_0_OPCODE_X0 = 37,
210 MULLLA_SS_SPECIAL_0_OPCODE_X0 = 38,
211 MULLLA_SS_SPECIAL_7_OPCODE_Y0 = 2,
212 MULLLA_SU_SPECIAL_0_OPCODE_X0 = 39,
213 MULLLA_UU_SPECIAL_0_OPCODE_X0 = 40,
214 MULLLA_UU_SPECIAL_7_OPCODE_Y0 = 3,
215 MULLLSA_UU_SPECIAL_0_OPCODE_X0 = 41,
216 MULLL_SS_SPECIAL_0_OPCODE_X0 = 42,
217 MULLL_SS_SPECIAL_6_OPCODE_Y0 = 2,
218 MULLL_SU_SPECIAL_0_OPCODE_X0 = 43,
219 MULLL_UU_SPECIAL_0_OPCODE_X0 = 44,
220 MULLL_UU_SPECIAL_6_OPCODE_Y0 = 3,
221 MVNZ_SPECIAL_0_OPCODE_X0 = 45,
222 MVNZ_SPECIAL_1_OPCODE_Y0 = 1,
223 MVZ_SPECIAL_0_OPCODE_X0 = 46,
224 MVZ_SPECIAL_1_OPCODE_Y0 = 2,
225 MZB_SPECIAL_0_OPCODE_X0 = 47,
226 MZB_SPECIAL_0_OPCODE_X1 = 21,
227 MZH_SPECIAL_0_OPCODE_X0 = 48,
228 MZH_SPECIAL_0_OPCODE_X1 = 22,
229 MZ_SPECIAL_0_OPCODE_X0 = 49,
230 MZ_SPECIAL_0_OPCODE_X1 = 23,
231 MZ_SPECIAL_1_OPCODE_Y0 = 3,
232 MZ_SPECIAL_1_OPCODE_Y1 = 2,
233 NAP_UN_0_SHUN_0_OPCODE_X1 = 16,
234 NOP_NOREG_RR_IMM_0_OPCODE_SN = 2,
235 NOP_UN_0_SHUN_0_OPCODE_X0 = 6,
236 NOP_UN_0_SHUN_0_OPCODE_X1 = 17,
237 NOP_UN_0_SHUN_0_OPCODE_Y0 = 6,
238 NOP_UN_0_SHUN_0_OPCODE_Y1 = 3,
239 NOREG_RR_IMM_0_OPCODE_SN = 0,
240 NOR_SPECIAL_0_OPCODE_X0 = 50,
241 NOR_SPECIAL_0_OPCODE_X1 = 24,
242 NOR_SPECIAL_2_OPCODE_Y0 = 1,
243 NOR_SPECIAL_2_OPCODE_Y1 = 1,
244 ORI_IMM_0_OPCODE_X0 = 8,
245 ORI_IMM_0_OPCODE_X1 = 11,
246 ORI_OPCODE_Y0 = 11,
247 ORI_OPCODE_Y1 = 9,
248 OR_SPECIAL_0_OPCODE_X0 = 51,
249 OR_SPECIAL_0_OPCODE_X1 = 25,
250 OR_SPECIAL_2_OPCODE_Y0 = 2,
251 OR_SPECIAL_2_OPCODE_Y1 = 2,
252 PACKBS_U_SPECIAL_0_OPCODE_X0 = 103,
253 PACKBS_U_SPECIAL_0_OPCODE_X1 = 73,
254 PACKHB_SPECIAL_0_OPCODE_X0 = 52,
255 PACKHB_SPECIAL_0_OPCODE_X1 = 26,
256 PACKHS_SPECIAL_0_OPCODE_X0 = 102,
257 PACKHS_SPECIAL_0_OPCODE_X1 = 72,
258 PACKLB_SPECIAL_0_OPCODE_X0 = 53,
259 PACKLB_SPECIAL_0_OPCODE_X1 = 27,
260 PCNT_UN_0_SHUN_0_OPCODE_X0 = 7,
261 PCNT_UN_0_SHUN_0_OPCODE_Y0 = 7,
262 RLI_SHUN_0_OPCODE_X0 = 1,
263 RLI_SHUN_0_OPCODE_X1 = 1,
264 RLI_SHUN_0_OPCODE_Y0 = 1,
265 RLI_SHUN_0_OPCODE_Y1 = 1,
266 RL_SPECIAL_0_OPCODE_X0 = 54,
267 RL_SPECIAL_0_OPCODE_X1 = 28,
268 RL_SPECIAL_3_OPCODE_Y0 = 0,
269 RL_SPECIAL_3_OPCODE_Y1 = 0,
270 RR_IMM_0_OPCODE_SN = 0,
271 S1A_SPECIAL_0_OPCODE_X0 = 55,
272 S1A_SPECIAL_0_OPCODE_X1 = 29,
273 S1A_SPECIAL_0_OPCODE_Y0 = 1,
274 S1A_SPECIAL_0_OPCODE_Y1 = 1,
275 S2A_SPECIAL_0_OPCODE_X0 = 56,
276 S2A_SPECIAL_0_OPCODE_X1 = 30,
277 S2A_SPECIAL_0_OPCODE_Y0 = 2,
278 S2A_SPECIAL_0_OPCODE_Y1 = 2,
279 S3A_SPECIAL_0_OPCODE_X0 = 57,
280 S3A_SPECIAL_0_OPCODE_X1 = 31,
281 S3A_SPECIAL_5_OPCODE_Y0 = 1,
282 S3A_SPECIAL_5_OPCODE_Y1 = 1,
283 SADAB_U_SPECIAL_0_OPCODE_X0 = 58,
284 SADAH_SPECIAL_0_OPCODE_X0 = 59,
285 SADAH_U_SPECIAL_0_OPCODE_X0 = 60,
286 SADB_U_SPECIAL_0_OPCODE_X0 = 61,
287 SADH_SPECIAL_0_OPCODE_X0 = 62,
288 SADH_U_SPECIAL_0_OPCODE_X0 = 63,
289 SBADD_IMM_0_OPCODE_X1 = 28,
290 SB_OPCODE_Y2 = 5,
291 SB_SPECIAL_0_OPCODE_X1 = 32,
292 SEQB_SPECIAL_0_OPCODE_X0 = 64,
293 SEQB_SPECIAL_0_OPCODE_X1 = 33,
294 SEQH_SPECIAL_0_OPCODE_X0 = 65,
295 SEQH_SPECIAL_0_OPCODE_X1 = 34,
296 SEQIB_IMM_0_OPCODE_X0 = 9,
297 SEQIB_IMM_0_OPCODE_X1 = 12,
298 SEQIH_IMM_0_OPCODE_X0 = 10,
299 SEQIH_IMM_0_OPCODE_X1 = 13,
300 SEQI_IMM_0_OPCODE_X0 = 11,
301 SEQI_IMM_0_OPCODE_X1 = 14,
302 SEQI_OPCODE_Y0 = 12,
303 SEQI_OPCODE_Y1 = 10,
304 SEQ_SPECIAL_0_OPCODE_X0 = 66,
305 SEQ_SPECIAL_0_OPCODE_X1 = 35,
306 SEQ_SPECIAL_5_OPCODE_Y0 = 2,
307 SEQ_SPECIAL_5_OPCODE_Y1 = 2,
308 SHADD_IMM_0_OPCODE_X1 = 29,
309 SHL8II_IMM_0_OPCODE_SN = 3,
310 SHLB_SPECIAL_0_OPCODE_X0 = 67,
311 SHLB_SPECIAL_0_OPCODE_X1 = 36,
312 SHLH_SPECIAL_0_OPCODE_X0 = 68,
313 SHLH_SPECIAL_0_OPCODE_X1 = 37,
314 SHLIB_SHUN_0_OPCODE_X0 = 2,
315 SHLIB_SHUN_0_OPCODE_X1 = 2,
316 SHLIH_SHUN_0_OPCODE_X0 = 3,
317 SHLIH_SHUN_0_OPCODE_X1 = 3,
318 SHLI_SHUN_0_OPCODE_X0 = 4,
319 SHLI_SHUN_0_OPCODE_X1 = 4,
320 SHLI_SHUN_0_OPCODE_Y0 = 2,
321 SHLI_SHUN_0_OPCODE_Y1 = 2,
322 SHL_SPECIAL_0_OPCODE_X0 = 69,
323 SHL_SPECIAL_0_OPCODE_X1 = 38,
324 SHL_SPECIAL_3_OPCODE_Y0 = 1,
325 SHL_SPECIAL_3_OPCODE_Y1 = 1,
326 SHR1_RR_IMM_0_OPCODE_SN = 9,
327 SHRB_SPECIAL_0_OPCODE_X0 = 70,
328 SHRB_SPECIAL_0_OPCODE_X1 = 39,
329 SHRH_SPECIAL_0_OPCODE_X0 = 71,
330 SHRH_SPECIAL_0_OPCODE_X1 = 40,
331 SHRIB_SHUN_0_OPCODE_X0 = 5,
332 SHRIB_SHUN_0_OPCODE_X1 = 5,
333 SHRIH_SHUN_0_OPCODE_X0 = 6,
334 SHRIH_SHUN_0_OPCODE_X1 = 6,
335 SHRI_SHUN_0_OPCODE_X0 = 7,
336 SHRI_SHUN_0_OPCODE_X1 = 7,
337 SHRI_SHUN_0_OPCODE_Y0 = 3,
338 SHRI_SHUN_0_OPCODE_Y1 = 3,
339 SHR_SPECIAL_0_OPCODE_X0 = 72,
340 SHR_SPECIAL_0_OPCODE_X1 = 41,
341 SHR_SPECIAL_3_OPCODE_Y0 = 2,
342 SHR_SPECIAL_3_OPCODE_Y1 = 2,
343 SHUN_0_OPCODE_X0 = 7,
344 SHUN_0_OPCODE_X1 = 8,
345 SHUN_0_OPCODE_Y0 = 13,
346 SHUN_0_OPCODE_Y1 = 11,
347 SH_OPCODE_Y2 = 6,
348 SH_SPECIAL_0_OPCODE_X1 = 42,
349 SLTB_SPECIAL_0_OPCODE_X0 = 73,
350 SLTB_SPECIAL_0_OPCODE_X1 = 43,
351 SLTB_U_SPECIAL_0_OPCODE_X0 = 74,
352 SLTB_U_SPECIAL_0_OPCODE_X1 = 44,
353 SLTEB_SPECIAL_0_OPCODE_X0 = 75,
354 SLTEB_SPECIAL_0_OPCODE_X1 = 45,
355 SLTEB_U_SPECIAL_0_OPCODE_X0 = 76,
356 SLTEB_U_SPECIAL_0_OPCODE_X1 = 46,
357 SLTEH_SPECIAL_0_OPCODE_X0 = 77,
358 SLTEH_SPECIAL_0_OPCODE_X1 = 47,
359 SLTEH_U_SPECIAL_0_OPCODE_X0 = 78,
360 SLTEH_U_SPECIAL_0_OPCODE_X1 = 48,
361 SLTE_SPECIAL_0_OPCODE_X0 = 79,
362 SLTE_SPECIAL_0_OPCODE_X1 = 49,
363 SLTE_SPECIAL_4_OPCODE_Y0 = 0,
364 SLTE_SPECIAL_4_OPCODE_Y1 = 0,
365 SLTE_U_SPECIAL_0_OPCODE_X0 = 80,
366 SLTE_U_SPECIAL_0_OPCODE_X1 = 50,
367 SLTE_U_SPECIAL_4_OPCODE_Y0 = 1,
368 SLTE_U_SPECIAL_4_OPCODE_Y1 = 1,
369 SLTH_SPECIAL_0_OPCODE_X0 = 81,
370 SLTH_SPECIAL_0_OPCODE_X1 = 51,
371 SLTH_U_SPECIAL_0_OPCODE_X0 = 82,
372 SLTH_U_SPECIAL_0_OPCODE_X1 = 52,
373 SLTIB_IMM_0_OPCODE_X0 = 12,
374 SLTIB_IMM_0_OPCODE_X1 = 15,
375 SLTIB_U_IMM_0_OPCODE_X0 = 13,
376 SLTIB_U_IMM_0_OPCODE_X1 = 16,
377 SLTIH_IMM_0_OPCODE_X0 = 14,
378 SLTIH_IMM_0_OPCODE_X1 = 17,
379 SLTIH_U_IMM_0_OPCODE_X0 = 15,
380 SLTIH_U_IMM_0_OPCODE_X1 = 18,
381 SLTI_IMM_0_OPCODE_X0 = 16,
382 SLTI_IMM_0_OPCODE_X1 = 19,
383 SLTI_OPCODE_Y0 = 14,
384 SLTI_OPCODE_Y1 = 12,
385 SLTI_U_IMM_0_OPCODE_X0 = 17,
386 SLTI_U_IMM_0_OPCODE_X1 = 20,
387 SLTI_U_OPCODE_Y0 = 15,
388 SLTI_U_OPCODE_Y1 = 13,
389 SLT_SPECIAL_0_OPCODE_X0 = 83,
390 SLT_SPECIAL_0_OPCODE_X1 = 53,
391 SLT_SPECIAL_4_OPCODE_Y0 = 2,
392 SLT_SPECIAL_4_OPCODE_Y1 = 2,
393 SLT_U_SPECIAL_0_OPCODE_X0 = 84,
394 SLT_U_SPECIAL_0_OPCODE_X1 = 54,
395 SLT_U_SPECIAL_4_OPCODE_Y0 = 3,
396 SLT_U_SPECIAL_4_OPCODE_Y1 = 3,
397 SNEB_SPECIAL_0_OPCODE_X0 = 85,
398 SNEB_SPECIAL_0_OPCODE_X1 = 55,
399 SNEH_SPECIAL_0_OPCODE_X0 = 86,
400 SNEH_SPECIAL_0_OPCODE_X1 = 56,
401 SNE_SPECIAL_0_OPCODE_X0 = 87,
402 SNE_SPECIAL_0_OPCODE_X1 = 57,
403 SNE_SPECIAL_5_OPCODE_Y0 = 3,
404 SNE_SPECIAL_5_OPCODE_Y1 = 3,
405 SPECIAL_0_OPCODE_X0 = 0,
406 SPECIAL_0_OPCODE_X1 = 1,
407 SPECIAL_0_OPCODE_Y0 = 1,
408 SPECIAL_0_OPCODE_Y1 = 1,
409 SPECIAL_1_OPCODE_Y0 = 2,
410 SPECIAL_1_OPCODE_Y1 = 2,
411 SPECIAL_2_OPCODE_Y0 = 3,
412 SPECIAL_2_OPCODE_Y1 = 3,
413 SPECIAL_3_OPCODE_Y0 = 4,
414 SPECIAL_3_OPCODE_Y1 = 4,
415 SPECIAL_4_OPCODE_Y0 = 5,
416 SPECIAL_4_OPCODE_Y1 = 5,
417 SPECIAL_5_OPCODE_Y0 = 6,
418 SPECIAL_5_OPCODE_Y1 = 6,
419 SPECIAL_6_OPCODE_Y0 = 7,
420 SPECIAL_7_OPCODE_Y0 = 8,
421 SRAB_SPECIAL_0_OPCODE_X0 = 88,
422 SRAB_SPECIAL_0_OPCODE_X1 = 58,
423 SRAH_SPECIAL_0_OPCODE_X0 = 89,
424 SRAH_SPECIAL_0_OPCODE_X1 = 59,
425 SRAIB_SHUN_0_OPCODE_X0 = 8,
426 SRAIB_SHUN_0_OPCODE_X1 = 8,
427 SRAIH_SHUN_0_OPCODE_X0 = 9,
428 SRAIH_SHUN_0_OPCODE_X1 = 9,
429 SRAI_SHUN_0_OPCODE_X0 = 10,
430 SRAI_SHUN_0_OPCODE_X1 = 10,
431 SRAI_SHUN_0_OPCODE_Y0 = 4,
432 SRAI_SHUN_0_OPCODE_Y1 = 4,
433 SRA_SPECIAL_0_OPCODE_X0 = 90,
434 SRA_SPECIAL_0_OPCODE_X1 = 60,
435 SRA_SPECIAL_3_OPCODE_Y0 = 3,
436 SRA_SPECIAL_3_OPCODE_Y1 = 3,
437 SUBBS_U_SPECIAL_0_OPCODE_X0 = 100,
438 SUBBS_U_SPECIAL_0_OPCODE_X1 = 70,
439 SUBB_SPECIAL_0_OPCODE_X0 = 91,
440 SUBB_SPECIAL_0_OPCODE_X1 = 61,
441 SUBHS_SPECIAL_0_OPCODE_X0 = 101,
442 SUBHS_SPECIAL_0_OPCODE_X1 = 71,
443 SUBH_SPECIAL_0_OPCODE_X0 = 92,
444 SUBH_SPECIAL_0_OPCODE_X1 = 62,
445 SUBS_SPECIAL_0_OPCODE_X0 = 97,
446 SUBS_SPECIAL_0_OPCODE_X1 = 67,
447 SUB_SPECIAL_0_OPCODE_X0 = 93,
448 SUB_SPECIAL_0_OPCODE_X1 = 63,
449 SUB_SPECIAL_0_OPCODE_Y0 = 3,
450 SUB_SPECIAL_0_OPCODE_Y1 = 3,
451 SWADD_IMM_0_OPCODE_X1 = 30,
452 SWINT0_UN_0_SHUN_0_OPCODE_X1 = 18,
453 SWINT1_UN_0_SHUN_0_OPCODE_X1 = 19,
454 SWINT2_UN_0_SHUN_0_OPCODE_X1 = 20,
455 SWINT3_UN_0_SHUN_0_OPCODE_X1 = 21,
456 SW_OPCODE_Y2 = 7,
457 SW_SPECIAL_0_OPCODE_X1 = 64,
458 TBLIDXB0_UN_0_SHUN_0_OPCODE_X0 = 8,
459 TBLIDXB0_UN_0_SHUN_0_OPCODE_Y0 = 8,
460 TBLIDXB1_UN_0_SHUN_0_OPCODE_X0 = 9,
461 TBLIDXB1_UN_0_SHUN_0_OPCODE_Y0 = 9,
462 TBLIDXB2_UN_0_SHUN_0_OPCODE_X0 = 10,
463 TBLIDXB2_UN_0_SHUN_0_OPCODE_Y0 = 10,
464 TBLIDXB3_UN_0_SHUN_0_OPCODE_X0 = 11,
465 TBLIDXB3_UN_0_SHUN_0_OPCODE_Y0 = 11,
466 TNS_UN_0_SHUN_0_OPCODE_X1 = 22,
467 UN_0_SHUN_0_OPCODE_X0 = 11,
468 UN_0_SHUN_0_OPCODE_X1 = 11,
469 UN_0_SHUN_0_OPCODE_Y0 = 5,
470 UN_0_SHUN_0_OPCODE_Y1 = 5,
471 WH64_UN_0_SHUN_0_OPCODE_X1 = 23,
472 XORI_IMM_0_OPCODE_X0 = 2,
473 XORI_IMM_0_OPCODE_X1 = 21,
474 XOR_SPECIAL_0_OPCODE_X0 = 94,
475 XOR_SPECIAL_0_OPCODE_X1 = 65,
476 XOR_SPECIAL_2_OPCODE_Y0 = 3,
477 XOR_SPECIAL_2_OPCODE_Y1 = 3
478};
479
480#endif /* !_TILE_OPCODE_CONSTANTS_H */
diff --git a/arch/tile/include/asm/opcode_constants_64.h b/arch/tile/include/asm/opcode_constants_64.h
new file mode 100644
index 000000000000..227d033b180c
--- /dev/null
+++ b/arch/tile/include/asm/opcode_constants_64.h
@@ -0,0 +1,480 @@
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/* This file is machine-generated; DO NOT EDIT! */
16
17
18#ifndef _TILE_OPCODE_CONSTANTS_H
19#define _TILE_OPCODE_CONSTANTS_H
20enum
21{
22 ADDBS_U_SPECIAL_0_OPCODE_X0 = 98,
23 ADDBS_U_SPECIAL_0_OPCODE_X1 = 68,
24 ADDB_SPECIAL_0_OPCODE_X0 = 1,
25 ADDB_SPECIAL_0_OPCODE_X1 = 1,
26 ADDHS_SPECIAL_0_OPCODE_X0 = 99,
27 ADDHS_SPECIAL_0_OPCODE_X1 = 69,
28 ADDH_SPECIAL_0_OPCODE_X0 = 2,
29 ADDH_SPECIAL_0_OPCODE_X1 = 2,
30 ADDIB_IMM_0_OPCODE_X0 = 1,
31 ADDIB_IMM_0_OPCODE_X1 = 1,
32 ADDIH_IMM_0_OPCODE_X0 = 2,
33 ADDIH_IMM_0_OPCODE_X1 = 2,
34 ADDI_IMM_0_OPCODE_X0 = 3,
35 ADDI_IMM_0_OPCODE_X1 = 3,
36 ADDI_IMM_1_OPCODE_SN = 1,
37 ADDI_OPCODE_Y0 = 9,
38 ADDI_OPCODE_Y1 = 7,
39 ADDLIS_OPCODE_X0 = 1,
40 ADDLIS_OPCODE_X1 = 2,
41 ADDLI_OPCODE_X0 = 2,
42 ADDLI_OPCODE_X1 = 3,
43 ADDS_SPECIAL_0_OPCODE_X0 = 96,
44 ADDS_SPECIAL_0_OPCODE_X1 = 66,
45 ADD_SPECIAL_0_OPCODE_X0 = 3,
46 ADD_SPECIAL_0_OPCODE_X1 = 3,
47 ADD_SPECIAL_0_OPCODE_Y0 = 0,
48 ADD_SPECIAL_0_OPCODE_Y1 = 0,
49 ADIFFB_U_SPECIAL_0_OPCODE_X0 = 4,
50 ADIFFH_SPECIAL_0_OPCODE_X0 = 5,
51 ANDI_IMM_0_OPCODE_X0 = 1,
52 ANDI_IMM_0_OPCODE_X1 = 4,
53 ANDI_OPCODE_Y0 = 10,
54 ANDI_OPCODE_Y1 = 8,
55 AND_SPECIAL_0_OPCODE_X0 = 6,
56 AND_SPECIAL_0_OPCODE_X1 = 4,
57 AND_SPECIAL_2_OPCODE_Y0 = 0,
58 AND_SPECIAL_2_OPCODE_Y1 = 0,
59 AULI_OPCODE_X0 = 3,
60 AULI_OPCODE_X1 = 4,
61 AVGB_U_SPECIAL_0_OPCODE_X0 = 7,
62 AVGH_SPECIAL_0_OPCODE_X0 = 8,
63 BBNST_BRANCH_OPCODE_X1 = 15,
64 BBNS_BRANCH_OPCODE_X1 = 14,
65 BBNS_OPCODE_SN = 63,
66 BBST_BRANCH_OPCODE_X1 = 13,
67 BBS_BRANCH_OPCODE_X1 = 12,
68 BBS_OPCODE_SN = 62,
69 BGEZT_BRANCH_OPCODE_X1 = 7,
70 BGEZ_BRANCH_OPCODE_X1 = 6,
71 BGEZ_OPCODE_SN = 61,
72 BGZT_BRANCH_OPCODE_X1 = 5,
73 BGZ_BRANCH_OPCODE_X1 = 4,
74 BGZ_OPCODE_SN = 58,
75 BITX_UN_0_SHUN_0_OPCODE_X0 = 1,
76 BITX_UN_0_SHUN_0_OPCODE_Y0 = 1,
77 BLEZT_BRANCH_OPCODE_X1 = 11,
78 BLEZ_BRANCH_OPCODE_X1 = 10,
79 BLEZ_OPCODE_SN = 59,
80 BLZT_BRANCH_OPCODE_X1 = 9,
81 BLZ_BRANCH_OPCODE_X1 = 8,
82 BLZ_OPCODE_SN = 60,
83 BNZT_BRANCH_OPCODE_X1 = 3,
84 BNZ_BRANCH_OPCODE_X1 = 2,
85 BNZ_OPCODE_SN = 57,
86 BPT_NOREG_RR_IMM_0_OPCODE_SN = 1,
87 BRANCH_OPCODE_X1 = 5,
88 BYTEX_UN_0_SHUN_0_OPCODE_X0 = 2,
89 BYTEX_UN_0_SHUN_0_OPCODE_Y0 = 2,
90 BZT_BRANCH_OPCODE_X1 = 1,
91 BZ_BRANCH_OPCODE_X1 = 0,
92 BZ_OPCODE_SN = 56,
93 CLZ_UN_0_SHUN_0_OPCODE_X0 = 3,
94 CLZ_UN_0_SHUN_0_OPCODE_Y0 = 3,
95 CRC32_32_SPECIAL_0_OPCODE_X0 = 9,
96 CRC32_8_SPECIAL_0_OPCODE_X0 = 10,
97 CTZ_UN_0_SHUN_0_OPCODE_X0 = 4,
98 CTZ_UN_0_SHUN_0_OPCODE_Y0 = 4,
99 DRAIN_UN_0_SHUN_0_OPCODE_X1 = 1,
100 DTLBPR_UN_0_SHUN_0_OPCODE_X1 = 2,
101 DWORD_ALIGN_SPECIAL_0_OPCODE_X0 = 95,
102 FINV_UN_0_SHUN_0_OPCODE_X1 = 3,
103 FLUSH_UN_0_SHUN_0_OPCODE_X1 = 4,
104 FNOP_NOREG_RR_IMM_0_OPCODE_SN = 3,
105 FNOP_UN_0_SHUN_0_OPCODE_X0 = 5,
106 FNOP_UN_0_SHUN_0_OPCODE_X1 = 5,
107 FNOP_UN_0_SHUN_0_OPCODE_Y0 = 5,
108 FNOP_UN_0_SHUN_0_OPCODE_Y1 = 1,
109 HALT_NOREG_RR_IMM_0_OPCODE_SN = 0,
110 ICOH_UN_0_SHUN_0_OPCODE_X1 = 6,
111 ILL_UN_0_SHUN_0_OPCODE_X1 = 7,
112 ILL_UN_0_SHUN_0_OPCODE_Y1 = 2,
113 IMM_0_OPCODE_SN = 0,
114 IMM_0_OPCODE_X0 = 4,
115 IMM_0_OPCODE_X1 = 6,
116 IMM_1_OPCODE_SN = 1,
117 IMM_OPCODE_0_X0 = 5,
118 INTHB_SPECIAL_0_OPCODE_X0 = 11,
119 INTHB_SPECIAL_0_OPCODE_X1 = 5,
120 INTHH_SPECIAL_0_OPCODE_X0 = 12,
121 INTHH_SPECIAL_0_OPCODE_X1 = 6,
122 INTLB_SPECIAL_0_OPCODE_X0 = 13,
123 INTLB_SPECIAL_0_OPCODE_X1 = 7,
124 INTLH_SPECIAL_0_OPCODE_X0 = 14,
125 INTLH_SPECIAL_0_OPCODE_X1 = 8,
126 INV_UN_0_SHUN_0_OPCODE_X1 = 8,
127 IRET_UN_0_SHUN_0_OPCODE_X1 = 9,
128 JALB_OPCODE_X1 = 13,
129 JALF_OPCODE_X1 = 12,
130 JALRP_SPECIAL_0_OPCODE_X1 = 9,
131 JALRR_IMM_1_OPCODE_SN = 3,
132 JALR_RR_IMM_0_OPCODE_SN = 5,
133 JALR_SPECIAL_0_OPCODE_X1 = 10,
134 JB_OPCODE_X1 = 11,
135 JF_OPCODE_X1 = 10,
136 JRP_SPECIAL_0_OPCODE_X1 = 11,
137 JRR_IMM_1_OPCODE_SN = 2,
138 JR_RR_IMM_0_OPCODE_SN = 4,
139 JR_SPECIAL_0_OPCODE_X1 = 12,
140 LBADD_IMM_0_OPCODE_X1 = 22,
141 LBADD_U_IMM_0_OPCODE_X1 = 23,
142 LB_OPCODE_Y2 = 0,
143 LB_UN_0_SHUN_0_OPCODE_X1 = 10,
144 LB_U_OPCODE_Y2 = 1,
145 LB_U_UN_0_SHUN_0_OPCODE_X1 = 11,
146 LHADD_IMM_0_OPCODE_X1 = 24,
147 LHADD_U_IMM_0_OPCODE_X1 = 25,
148 LH_OPCODE_Y2 = 2,
149 LH_UN_0_SHUN_0_OPCODE_X1 = 12,
150 LH_U_OPCODE_Y2 = 3,
151 LH_U_UN_0_SHUN_0_OPCODE_X1 = 13,
152 LNK_SPECIAL_0_OPCODE_X1 = 13,
153 LWADD_IMM_0_OPCODE_X1 = 26,
154 LWADD_NA_IMM_0_OPCODE_X1 = 27,
155 LW_NA_UN_0_SHUN_0_OPCODE_X1 = 24,
156 LW_OPCODE_Y2 = 4,
157 LW_UN_0_SHUN_0_OPCODE_X1 = 14,
158 MAXB_U_SPECIAL_0_OPCODE_X0 = 15,
159 MAXB_U_SPECIAL_0_OPCODE_X1 = 14,
160 MAXH_SPECIAL_0_OPCODE_X0 = 16,
161 MAXH_SPECIAL_0_OPCODE_X1 = 15,
162 MAXIB_U_IMM_0_OPCODE_X0 = 4,
163 MAXIB_U_IMM_0_OPCODE_X1 = 5,
164 MAXIH_IMM_0_OPCODE_X0 = 5,
165 MAXIH_IMM_0_OPCODE_X1 = 6,
166 MFSPR_IMM_0_OPCODE_X1 = 7,
167 MF_UN_0_SHUN_0_OPCODE_X1 = 15,
168 MINB_U_SPECIAL_0_OPCODE_X0 = 17,
169 MINB_U_SPECIAL_0_OPCODE_X1 = 16,
170 MINH_SPECIAL_0_OPCODE_X0 = 18,
171 MINH_SPECIAL_0_OPCODE_X1 = 17,
172 MINIB_U_IMM_0_OPCODE_X0 = 6,
173 MINIB_U_IMM_0_OPCODE_X1 = 8,
174 MINIH_IMM_0_OPCODE_X0 = 7,
175 MINIH_IMM_0_OPCODE_X1 = 9,
176 MM_OPCODE_X0 = 6,
177 MM_OPCODE_X1 = 7,
178 MNZB_SPECIAL_0_OPCODE_X0 = 19,
179 MNZB_SPECIAL_0_OPCODE_X1 = 18,
180 MNZH_SPECIAL_0_OPCODE_X0 = 20,
181 MNZH_SPECIAL_0_OPCODE_X1 = 19,
182 MNZ_SPECIAL_0_OPCODE_X0 = 21,
183 MNZ_SPECIAL_0_OPCODE_X1 = 20,
184 MNZ_SPECIAL_1_OPCODE_Y0 = 0,
185 MNZ_SPECIAL_1_OPCODE_Y1 = 1,
186 MOVEI_IMM_1_OPCODE_SN = 0,
187 MOVE_RR_IMM_0_OPCODE_SN = 8,
188 MTSPR_IMM_0_OPCODE_X1 = 10,
189 MULHHA_SS_SPECIAL_0_OPCODE_X0 = 22,
190 MULHHA_SS_SPECIAL_7_OPCODE_Y0 = 0,
191 MULHHA_SU_SPECIAL_0_OPCODE_X0 = 23,
192 MULHHA_UU_SPECIAL_0_OPCODE_X0 = 24,
193 MULHHA_UU_SPECIAL_7_OPCODE_Y0 = 1,
194 MULHHSA_UU_SPECIAL_0_OPCODE_X0 = 25,
195 MULHH_SS_SPECIAL_0_OPCODE_X0 = 26,
196 MULHH_SS_SPECIAL_6_OPCODE_Y0 = 0,
197 MULHH_SU_SPECIAL_0_OPCODE_X0 = 27,
198 MULHH_UU_SPECIAL_0_OPCODE_X0 = 28,
199 MULHH_UU_SPECIAL_6_OPCODE_Y0 = 1,
200 MULHLA_SS_SPECIAL_0_OPCODE_X0 = 29,
201 MULHLA_SU_SPECIAL_0_OPCODE_X0 = 30,
202 MULHLA_US_SPECIAL_0_OPCODE_X0 = 31,
203 MULHLA_UU_SPECIAL_0_OPCODE_X0 = 32,
204 MULHLSA_UU_SPECIAL_0_OPCODE_X0 = 33,
205 MULHLSA_UU_SPECIAL_5_OPCODE_Y0 = 0,
206 MULHL_SS_SPECIAL_0_OPCODE_X0 = 34,
207 MULHL_SU_SPECIAL_0_OPCODE_X0 = 35,
208 MULHL_US_SPECIAL_0_OPCODE_X0 = 36,
209 MULHL_UU_SPECIAL_0_OPCODE_X0 = 37,
210 MULLLA_SS_SPECIAL_0_OPCODE_X0 = 38,
211 MULLLA_SS_SPECIAL_7_OPCODE_Y0 = 2,
212 MULLLA_SU_SPECIAL_0_OPCODE_X0 = 39,
213 MULLLA_UU_SPECIAL_0_OPCODE_X0 = 40,
214 MULLLA_UU_SPECIAL_7_OPCODE_Y0 = 3,
215 MULLLSA_UU_SPECIAL_0_OPCODE_X0 = 41,
216 MULLL_SS_SPECIAL_0_OPCODE_X0 = 42,
217 MULLL_SS_SPECIAL_6_OPCODE_Y0 = 2,
218 MULLL_SU_SPECIAL_0_OPCODE_X0 = 43,
219 MULLL_UU_SPECIAL_0_OPCODE_X0 = 44,
220 MULLL_UU_SPECIAL_6_OPCODE_Y0 = 3,
221 MVNZ_SPECIAL_0_OPCODE_X0 = 45,
222 MVNZ_SPECIAL_1_OPCODE_Y0 = 1,
223 MVZ_SPECIAL_0_OPCODE_X0 = 46,
224 MVZ_SPECIAL_1_OPCODE_Y0 = 2,
225 MZB_SPECIAL_0_OPCODE_X0 = 47,
226 MZB_SPECIAL_0_OPCODE_X1 = 21,
227 MZH_SPECIAL_0_OPCODE_X0 = 48,
228 MZH_SPECIAL_0_OPCODE_X1 = 22,
229 MZ_SPECIAL_0_OPCODE_X0 = 49,
230 MZ_SPECIAL_0_OPCODE_X1 = 23,
231 MZ_SPECIAL_1_OPCODE_Y0 = 3,
232 MZ_SPECIAL_1_OPCODE_Y1 = 2,
233 NAP_UN_0_SHUN_0_OPCODE_X1 = 16,
234 NOP_NOREG_RR_IMM_0_OPCODE_SN = 2,
235 NOP_UN_0_SHUN_0_OPCODE_X0 = 6,
236 NOP_UN_0_SHUN_0_OPCODE_X1 = 17,
237 NOP_UN_0_SHUN_0_OPCODE_Y0 = 6,
238 NOP_UN_0_SHUN_0_OPCODE_Y1 = 3,
239 NOREG_RR_IMM_0_OPCODE_SN = 0,
240 NOR_SPECIAL_0_OPCODE_X0 = 50,
241 NOR_SPECIAL_0_OPCODE_X1 = 24,
242 NOR_SPECIAL_2_OPCODE_Y0 = 1,
243 NOR_SPECIAL_2_OPCODE_Y1 = 1,
244 ORI_IMM_0_OPCODE_X0 = 8,
245 ORI_IMM_0_OPCODE_X1 = 11,
246 ORI_OPCODE_Y0 = 11,
247 ORI_OPCODE_Y1 = 9,
248 OR_SPECIAL_0_OPCODE_X0 = 51,
249 OR_SPECIAL_0_OPCODE_X1 = 25,
250 OR_SPECIAL_2_OPCODE_Y0 = 2,
251 OR_SPECIAL_2_OPCODE_Y1 = 2,
252 PACKBS_U_SPECIAL_0_OPCODE_X0 = 103,
253 PACKBS_U_SPECIAL_0_OPCODE_X1 = 73,
254 PACKHB_SPECIAL_0_OPCODE_X0 = 52,
255 PACKHB_SPECIAL_0_OPCODE_X1 = 26,
256 PACKHS_SPECIAL_0_OPCODE_X0 = 102,
257 PACKHS_SPECIAL_0_OPCODE_X1 = 72,
258 PACKLB_SPECIAL_0_OPCODE_X0 = 53,
259 PACKLB_SPECIAL_0_OPCODE_X1 = 27,
260 PCNT_UN_0_SHUN_0_OPCODE_X0 = 7,
261 PCNT_UN_0_SHUN_0_OPCODE_Y0 = 7,
262 RLI_SHUN_0_OPCODE_X0 = 1,
263 RLI_SHUN_0_OPCODE_X1 = 1,
264 RLI_SHUN_0_OPCODE_Y0 = 1,
265 RLI_SHUN_0_OPCODE_Y1 = 1,
266 RL_SPECIAL_0_OPCODE_X0 = 54,
267 RL_SPECIAL_0_OPCODE_X1 = 28,
268 RL_SPECIAL_3_OPCODE_Y0 = 0,
269 RL_SPECIAL_3_OPCODE_Y1 = 0,
270 RR_IMM_0_OPCODE_SN = 0,
271 S1A_SPECIAL_0_OPCODE_X0 = 55,
272 S1A_SPECIAL_0_OPCODE_X1 = 29,
273 S1A_SPECIAL_0_OPCODE_Y0 = 1,
274 S1A_SPECIAL_0_OPCODE_Y1 = 1,
275 S2A_SPECIAL_0_OPCODE_X0 = 56,
276 S2A_SPECIAL_0_OPCODE_X1 = 30,
277 S2A_SPECIAL_0_OPCODE_Y0 = 2,
278 S2A_SPECIAL_0_OPCODE_Y1 = 2,
279 S3A_SPECIAL_0_OPCODE_X0 = 57,
280 S3A_SPECIAL_0_OPCODE_X1 = 31,
281 S3A_SPECIAL_5_OPCODE_Y0 = 1,
282 S3A_SPECIAL_5_OPCODE_Y1 = 1,
283 SADAB_U_SPECIAL_0_OPCODE_X0 = 58,
284 SADAH_SPECIAL_0_OPCODE_X0 = 59,
285 SADAH_U_SPECIAL_0_OPCODE_X0 = 60,
286 SADB_U_SPECIAL_0_OPCODE_X0 = 61,
287 SADH_SPECIAL_0_OPCODE_X0 = 62,
288 SADH_U_SPECIAL_0_OPCODE_X0 = 63,
289 SBADD_IMM_0_OPCODE_X1 = 28,
290 SB_OPCODE_Y2 = 5,
291 SB_SPECIAL_0_OPCODE_X1 = 32,
292 SEQB_SPECIAL_0_OPCODE_X0 = 64,
293 SEQB_SPECIAL_0_OPCODE_X1 = 33,
294 SEQH_SPECIAL_0_OPCODE_X0 = 65,
295 SEQH_SPECIAL_0_OPCODE_X1 = 34,
296 SEQIB_IMM_0_OPCODE_X0 = 9,
297 SEQIB_IMM_0_OPCODE_X1 = 12,
298 SEQIH_IMM_0_OPCODE_X0 = 10,
299 SEQIH_IMM_0_OPCODE_X1 = 13,
300 SEQI_IMM_0_OPCODE_X0 = 11,
301 SEQI_IMM_0_OPCODE_X1 = 14,
302 SEQI_OPCODE_Y0 = 12,
303 SEQI_OPCODE_Y1 = 10,
304 SEQ_SPECIAL_0_OPCODE_X0 = 66,
305 SEQ_SPECIAL_0_OPCODE_X1 = 35,
306 SEQ_SPECIAL_5_OPCODE_Y0 = 2,
307 SEQ_SPECIAL_5_OPCODE_Y1 = 2,
308 SHADD_IMM_0_OPCODE_X1 = 29,
309 SHL8II_IMM_0_OPCODE_SN = 3,
310 SHLB_SPECIAL_0_OPCODE_X0 = 67,
311 SHLB_SPECIAL_0_OPCODE_X1 = 36,
312 SHLH_SPECIAL_0_OPCODE_X0 = 68,
313 SHLH_SPECIAL_0_OPCODE_X1 = 37,
314 SHLIB_SHUN_0_OPCODE_X0 = 2,
315 SHLIB_SHUN_0_OPCODE_X1 = 2,
316 SHLIH_SHUN_0_OPCODE_X0 = 3,
317 SHLIH_SHUN_0_OPCODE_X1 = 3,
318 SHLI_SHUN_0_OPCODE_X0 = 4,
319 SHLI_SHUN_0_OPCODE_X1 = 4,
320 SHLI_SHUN_0_OPCODE_Y0 = 2,
321 SHLI_SHUN_0_OPCODE_Y1 = 2,
322 SHL_SPECIAL_0_OPCODE_X0 = 69,
323 SHL_SPECIAL_0_OPCODE_X1 = 38,
324 SHL_SPECIAL_3_OPCODE_Y0 = 1,
325 SHL_SPECIAL_3_OPCODE_Y1 = 1,
326 SHR1_RR_IMM_0_OPCODE_SN = 9,
327 SHRB_SPECIAL_0_OPCODE_X0 = 70,
328 SHRB_SPECIAL_0_OPCODE_X1 = 39,
329 SHRH_SPECIAL_0_OPCODE_X0 = 71,
330 SHRH_SPECIAL_0_OPCODE_X1 = 40,
331 SHRIB_SHUN_0_OPCODE_X0 = 5,
332 SHRIB_SHUN_0_OPCODE_X1 = 5,
333 SHRIH_SHUN_0_OPCODE_X0 = 6,
334 SHRIH_SHUN_0_OPCODE_X1 = 6,
335 SHRI_SHUN_0_OPCODE_X0 = 7,
336 SHRI_SHUN_0_OPCODE_X1 = 7,
337 SHRI_SHUN_0_OPCODE_Y0 = 3,
338 SHRI_SHUN_0_OPCODE_Y1 = 3,
339 SHR_SPECIAL_0_OPCODE_X0 = 72,
340 SHR_SPECIAL_0_OPCODE_X1 = 41,
341 SHR_SPECIAL_3_OPCODE_Y0 = 2,
342 SHR_SPECIAL_3_OPCODE_Y1 = 2,
343 SHUN_0_OPCODE_X0 = 7,
344 SHUN_0_OPCODE_X1 = 8,
345 SHUN_0_OPCODE_Y0 = 13,
346 SHUN_0_OPCODE_Y1 = 11,
347 SH_OPCODE_Y2 = 6,
348 SH_SPECIAL_0_OPCODE_X1 = 42,
349 SLTB_SPECIAL_0_OPCODE_X0 = 73,
350 SLTB_SPECIAL_0_OPCODE_X1 = 43,
351 SLTB_U_SPECIAL_0_OPCODE_X0 = 74,
352 SLTB_U_SPECIAL_0_OPCODE_X1 = 44,
353 SLTEB_SPECIAL_0_OPCODE_X0 = 75,
354 SLTEB_SPECIAL_0_OPCODE_X1 = 45,
355 SLTEB_U_SPECIAL_0_OPCODE_X0 = 76,
356 SLTEB_U_SPECIAL_0_OPCODE_X1 = 46,
357 SLTEH_SPECIAL_0_OPCODE_X0 = 77,
358 SLTEH_SPECIAL_0_OPCODE_X1 = 47,
359 SLTEH_U_SPECIAL_0_OPCODE_X0 = 78,
360 SLTEH_U_SPECIAL_0_OPCODE_X1 = 48,
361 SLTE_SPECIAL_0_OPCODE_X0 = 79,
362 SLTE_SPECIAL_0_OPCODE_X1 = 49,
363 SLTE_SPECIAL_4_OPCODE_Y0 = 0,
364 SLTE_SPECIAL_4_OPCODE_Y1 = 0,
365 SLTE_U_SPECIAL_0_OPCODE_X0 = 80,
366 SLTE_U_SPECIAL_0_OPCODE_X1 = 50,
367 SLTE_U_SPECIAL_4_OPCODE_Y0 = 1,
368 SLTE_U_SPECIAL_4_OPCODE_Y1 = 1,
369 SLTH_SPECIAL_0_OPCODE_X0 = 81,
370 SLTH_SPECIAL_0_OPCODE_X1 = 51,
371 SLTH_U_SPECIAL_0_OPCODE_X0 = 82,
372 SLTH_U_SPECIAL_0_OPCODE_X1 = 52,
373 SLTIB_IMM_0_OPCODE_X0 = 12,
374 SLTIB_IMM_0_OPCODE_X1 = 15,
375 SLTIB_U_IMM_0_OPCODE_X0 = 13,
376 SLTIB_U_IMM_0_OPCODE_X1 = 16,
377 SLTIH_IMM_0_OPCODE_X0 = 14,
378 SLTIH_IMM_0_OPCODE_X1 = 17,
379 SLTIH_U_IMM_0_OPCODE_X0 = 15,
380 SLTIH_U_IMM_0_OPCODE_X1 = 18,
381 SLTI_IMM_0_OPCODE_X0 = 16,
382 SLTI_IMM_0_OPCODE_X1 = 19,
383 SLTI_OPCODE_Y0 = 14,
384 SLTI_OPCODE_Y1 = 12,
385 SLTI_U_IMM_0_OPCODE_X0 = 17,
386 SLTI_U_IMM_0_OPCODE_X1 = 20,
387 SLTI_U_OPCODE_Y0 = 15,
388 SLTI_U_OPCODE_Y1 = 13,
389 SLT_SPECIAL_0_OPCODE_X0 = 83,
390 SLT_SPECIAL_0_OPCODE_X1 = 53,
391 SLT_SPECIAL_4_OPCODE_Y0 = 2,
392 SLT_SPECIAL_4_OPCODE_Y1 = 2,
393 SLT_U_SPECIAL_0_OPCODE_X0 = 84,
394 SLT_U_SPECIAL_0_OPCODE_X1 = 54,
395 SLT_U_SPECIAL_4_OPCODE_Y0 = 3,
396 SLT_U_SPECIAL_4_OPCODE_Y1 = 3,
397 SNEB_SPECIAL_0_OPCODE_X0 = 85,
398 SNEB_SPECIAL_0_OPCODE_X1 = 55,
399 SNEH_SPECIAL_0_OPCODE_X0 = 86,
400 SNEH_SPECIAL_0_OPCODE_X1 = 56,
401 SNE_SPECIAL_0_OPCODE_X0 = 87,
402 SNE_SPECIAL_0_OPCODE_X1 = 57,
403 SNE_SPECIAL_5_OPCODE_Y0 = 3,
404 SNE_SPECIAL_5_OPCODE_Y1 = 3,
405 SPECIAL_0_OPCODE_X0 = 0,
406 SPECIAL_0_OPCODE_X1 = 1,
407 SPECIAL_0_OPCODE_Y0 = 1,
408 SPECIAL_0_OPCODE_Y1 = 1,
409 SPECIAL_1_OPCODE_Y0 = 2,
410 SPECIAL_1_OPCODE_Y1 = 2,
411 SPECIAL_2_OPCODE_Y0 = 3,
412 SPECIAL_2_OPCODE_Y1 = 3,
413 SPECIAL_3_OPCODE_Y0 = 4,
414 SPECIAL_3_OPCODE_Y1 = 4,
415 SPECIAL_4_OPCODE_Y0 = 5,
416 SPECIAL_4_OPCODE_Y1 = 5,
417 SPECIAL_5_OPCODE_Y0 = 6,
418 SPECIAL_5_OPCODE_Y1 = 6,
419 SPECIAL_6_OPCODE_Y0 = 7,
420 SPECIAL_7_OPCODE_Y0 = 8,
421 SRAB_SPECIAL_0_OPCODE_X0 = 88,
422 SRAB_SPECIAL_0_OPCODE_X1 = 58,
423 SRAH_SPECIAL_0_OPCODE_X0 = 89,
424 SRAH_SPECIAL_0_OPCODE_X1 = 59,
425 SRAIB_SHUN_0_OPCODE_X0 = 8,
426 SRAIB_SHUN_0_OPCODE_X1 = 8,
427 SRAIH_SHUN_0_OPCODE_X0 = 9,
428 SRAIH_SHUN_0_OPCODE_X1 = 9,
429 SRAI_SHUN_0_OPCODE_X0 = 10,
430 SRAI_SHUN_0_OPCODE_X1 = 10,
431 SRAI_SHUN_0_OPCODE_Y0 = 4,
432 SRAI_SHUN_0_OPCODE_Y1 = 4,
433 SRA_SPECIAL_0_OPCODE_X0 = 90,
434 SRA_SPECIAL_0_OPCODE_X1 = 60,
435 SRA_SPECIAL_3_OPCODE_Y0 = 3,
436 SRA_SPECIAL_3_OPCODE_Y1 = 3,
437 SUBBS_U_SPECIAL_0_OPCODE_X0 = 100,
438 SUBBS_U_SPECIAL_0_OPCODE_X1 = 70,
439 SUBB_SPECIAL_0_OPCODE_X0 = 91,
440 SUBB_SPECIAL_0_OPCODE_X1 = 61,
441 SUBHS_SPECIAL_0_OPCODE_X0 = 101,
442 SUBHS_SPECIAL_0_OPCODE_X1 = 71,
443 SUBH_SPECIAL_0_OPCODE_X0 = 92,
444 SUBH_SPECIAL_0_OPCODE_X1 = 62,
445 SUBS_SPECIAL_0_OPCODE_X0 = 97,
446 SUBS_SPECIAL_0_OPCODE_X1 = 67,
447 SUB_SPECIAL_0_OPCODE_X0 = 93,
448 SUB_SPECIAL_0_OPCODE_X1 = 63,
449 SUB_SPECIAL_0_OPCODE_Y0 = 3,
450 SUB_SPECIAL_0_OPCODE_Y1 = 3,
451 SWADD_IMM_0_OPCODE_X1 = 30,
452 SWINT0_UN_0_SHUN_0_OPCODE_X1 = 18,
453 SWINT1_UN_0_SHUN_0_OPCODE_X1 = 19,
454 SWINT2_UN_0_SHUN_0_OPCODE_X1 = 20,
455 SWINT3_UN_0_SHUN_0_OPCODE_X1 = 21,
456 SW_OPCODE_Y2 = 7,
457 SW_SPECIAL_0_OPCODE_X1 = 64,
458 TBLIDXB0_UN_0_SHUN_0_OPCODE_X0 = 8,
459 TBLIDXB0_UN_0_SHUN_0_OPCODE_Y0 = 8,
460 TBLIDXB1_UN_0_SHUN_0_OPCODE_X0 = 9,
461 TBLIDXB1_UN_0_SHUN_0_OPCODE_Y0 = 9,
462 TBLIDXB2_UN_0_SHUN_0_OPCODE_X0 = 10,
463 TBLIDXB2_UN_0_SHUN_0_OPCODE_Y0 = 10,
464 TBLIDXB3_UN_0_SHUN_0_OPCODE_X0 = 11,
465 TBLIDXB3_UN_0_SHUN_0_OPCODE_Y0 = 11,
466 TNS_UN_0_SHUN_0_OPCODE_X1 = 22,
467 UN_0_SHUN_0_OPCODE_X0 = 11,
468 UN_0_SHUN_0_OPCODE_X1 = 11,
469 UN_0_SHUN_0_OPCODE_Y0 = 5,
470 UN_0_SHUN_0_OPCODE_Y1 = 5,
471 WH64_UN_0_SHUN_0_OPCODE_X1 = 23,
472 XORI_IMM_0_OPCODE_X0 = 2,
473 XORI_IMM_0_OPCODE_X1 = 21,
474 XOR_SPECIAL_0_OPCODE_X0 = 94,
475 XOR_SPECIAL_0_OPCODE_X1 = 65,
476 XOR_SPECIAL_2_OPCODE_Y0 = 3,
477 XOR_SPECIAL_2_OPCODE_Y1 = 3
478};
479
480#endif /* !_TILE_OPCODE_CONSTANTS_H */
diff --git a/arch/tile/include/asm/page.h b/arch/tile/include/asm/page.h
new file mode 100644
index 000000000000..7d90641cf18d
--- /dev/null
+++ b/arch/tile/include/asm/page.h
@@ -0,0 +1,343 @@
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_PAGE_H
16#define _ASM_TILE_PAGE_H
17
18#include <linux/const.h>
19
20/* PAGE_SHIFT and HPAGE_SHIFT determine the page sizes. */
21#define PAGE_SHIFT 16
22#define HPAGE_SHIFT 24
23
24#define PAGE_SIZE (_AC(1, UL) << PAGE_SHIFT)
25#define HPAGE_SIZE (_AC(1, UL) << HPAGE_SHIFT)
26
27#define PAGE_MASK (~(PAGE_SIZE - 1))
28#define HPAGE_MASK (~(HPAGE_SIZE - 1))
29
30#ifdef __KERNEL__
31
32#include <hv/hypervisor.h>
33#include <arch/chip.h>
34
35/*
36 * The {,H}PAGE_SHIFT values must match the HV_LOG2_PAGE_SIZE_xxx
37 * definitions in <hv/hypervisor.h>. We validate this at build time
38 * here, and again at runtime during early boot. We provide a
39 * separate definition since userspace doesn't have <hv/hypervisor.h>.
40 *
41 * Be careful to distinguish PAGE_SHIFT from HV_PTE_INDEX_PFN, since
42 * they are the same on i386 but not TILE.
43 */
44#if HV_LOG2_PAGE_SIZE_SMALL != PAGE_SHIFT
45# error Small page size mismatch in Linux
46#endif
47#if HV_LOG2_PAGE_SIZE_LARGE != HPAGE_SHIFT
48# error Huge page size mismatch in Linux
49#endif
50
51#ifndef __ASSEMBLY__
52
53#include <linux/types.h>
54#include <linux/string.h>
55
56struct page;
57
58static inline void clear_page(void *page)
59{
60 memset(page, 0, PAGE_SIZE);
61}
62
63static inline void copy_page(void *to, void *from)
64{
65 memcpy(to, from, PAGE_SIZE);
66}
67
68static inline void clear_user_page(void *page, unsigned long vaddr,
69 struct page *pg)
70{
71 clear_page(page);
72}
73
74static inline void copy_user_page(void *to, void *from, unsigned long vaddr,
75 struct page *topage)
76{
77 copy_page(to, from);
78}
79
80/*
81 * Hypervisor page tables are made of the same basic structure.
82 */
83
84typedef __u64 pteval_t;
85typedef __u64 pmdval_t;
86typedef __u64 pudval_t;
87typedef __u64 pgdval_t;
88typedef __u64 pgprotval_t;
89
90typedef HV_PTE pte_t;
91typedef HV_PTE pgd_t;
92typedef HV_PTE pgprot_t;
93
94/*
95 * User L2 page tables are managed as one L2 page table per page,
96 * because we use the page allocator for them. This keeps the allocation
97 * simple and makes it potentially useful to implement HIGHPTE at some point.
98 * However, it's also inefficient, since L2 page tables are much smaller
99 * than pages (currently 2KB vs 64KB). So we should revisit this.
100 */
101typedef struct page *pgtable_t;
102
103/* Must be a macro since it is used to create constants. */
104#define __pgprot(val) hv_pte(val)
105
106static inline u64 pgprot_val(pgprot_t pgprot)
107{
108 return hv_pte_val(pgprot);
109}
110
111static inline u64 pte_val(pte_t pte)
112{
113 return hv_pte_val(pte);
114}
115
116static inline u64 pgd_val(pgd_t pgd)
117{
118 return hv_pte_val(pgd);
119}
120
121#ifdef __tilegx__
122
123typedef HV_PTE pmd_t;
124
125static inline u64 pmd_val(pmd_t pmd)
126{
127 return hv_pte_val(pmd);
128}
129
130#endif
131
132static inline __attribute_const__ int get_order(unsigned long size)
133{
134 return BITS_PER_LONG - __builtin_clzl((size - 1) >> PAGE_SHIFT);
135}
136
137#endif /* !__ASSEMBLY__ */
138
139#define HUGETLB_PAGE_ORDER (HPAGE_SHIFT - PAGE_SHIFT)
140
141#define HUGE_MAX_HSTATE 2
142
143#ifdef CONFIG_HUGETLB_PAGE
144#define HAVE_ARCH_HUGETLB_UNMAPPED_AREA
145#endif
146
147/* Each memory controller has PAs distinct in their high bits. */
148#define NR_PA_HIGHBIT_SHIFT (CHIP_PA_WIDTH() - CHIP_LOG_NUM_MSHIMS())
149#define NR_PA_HIGHBIT_VALUES (1 << CHIP_LOG_NUM_MSHIMS())
150#define __pa_to_highbits(pa) ((phys_addr_t)(pa) >> NR_PA_HIGHBIT_SHIFT)
151#define __pfn_to_highbits(pfn) ((pfn) >> (NR_PA_HIGHBIT_SHIFT - PAGE_SHIFT))
152
153#ifdef __tilegx__
154
155/*
156 * We reserve the lower half of memory for user-space programs, and the
157 * upper half for system code. We re-map all of physical memory in the
158 * upper half, which takes a quarter of our VA space. Then we have
159 * the vmalloc regions. The supervisor code lives at 0xfffffff700000000,
160 * with the hypervisor above that.
161 *
162 * Loadable kernel modules are placed immediately after the static
163 * supervisor code, with each being allocated a 256MB region of
164 * address space, so we don't have to worry about the range of "jal"
165 * and other branch instructions.
166 *
167 * For now we keep life simple and just allocate one pmd (4GB) for vmalloc.
168 * Similarly, for now we don't play any struct page mapping games.
169 */
170
171#if CHIP_PA_WIDTH() + 2 > CHIP_VA_WIDTH()
172# error Too much PA to map with the VA available!
173#endif
174#define HALF_VA_SPACE (_AC(1, UL) << (CHIP_VA_WIDTH() - 1))
175
176#define MEM_LOW_END (HALF_VA_SPACE - 1) /* low half */
177#define MEM_HIGH_START (-HALF_VA_SPACE) /* high half */
178#define PAGE_OFFSET MEM_HIGH_START
179#define _VMALLOC_START _AC(0xfffffff500000000, UL) /* 4 GB */
180#define HUGE_VMAP_BASE _AC(0xfffffff600000000, UL) /* 4 GB */
181#define MEM_SV_START _AC(0xfffffff700000000, UL) /* 256 MB */
182#define MEM_SV_INTRPT MEM_SV_START
183#define MEM_MODULE_START _AC(0xfffffff710000000, UL) /* 256 MB */
184#define MEM_MODULE_END (MEM_MODULE_START + (256*1024*1024))
185#define MEM_HV_START _AC(0xfffffff800000000, UL) /* 32 GB */
186
187/* Highest DTLB address we will use */
188#define KERNEL_HIGH_VADDR MEM_SV_START
189
190/* Since we don't currently provide any fixmaps, we use an impossible VA. */
191#define FIXADDR_TOP MEM_HV_START
192
193#else /* !__tilegx__ */
194
195/*
196 * A PAGE_OFFSET of 0xC0000000 means that the kernel has
197 * a virtual address space of one gigabyte, which limits the
198 * amount of physical memory you can use to about 768MB.
199 * If you want more physical memory than this then see the CONFIG_HIGHMEM
200 * option in the kernel configuration.
201 *
202 * The top two 16MB chunks in the table below (VIRT and HV) are
203 * unavailable to Linux. Since the kernel interrupt vectors must live
204 * at 0xfd000000, we map all of the bottom of RAM at this address with
205 * a huge page table entry to minimize its ITLB footprint (as well as
206 * at PAGE_OFFSET). The last architected requirement is that user
207 * interrupt vectors live at 0xfc000000, so we make that range of
208 * memory available to user processes. The remaining regions are sized
209 * as shown; after the first four addresses, we show "typical" values,
210 * since the actual addresses depend on kernel #defines.
211 *
212 * MEM_VIRT_INTRPT 0xff000000
213 * MEM_HV_INTRPT 0xfe000000
214 * MEM_SV_INTRPT (kernel code) 0xfd000000
215 * MEM_USER_INTRPT (user vector) 0xfc000000
216 * FIX_KMAP_xxx 0xf8000000 (via NR_CPUS * KM_TYPE_NR)
217 * PKMAP_BASE 0xf7000000 (via LAST_PKMAP)
218 * HUGE_VMAP 0xf3000000 (via CONFIG_NR_HUGE_VMAPS)
219 * VMALLOC_START 0xf0000000 (via __VMALLOC_RESERVE)
220 * mapped LOWMEM 0xc0000000
221 */
222
223#define MEM_USER_INTRPT _AC(0xfc000000, UL)
224#define MEM_SV_INTRPT _AC(0xfd000000, UL)
225#define MEM_HV_INTRPT _AC(0xfe000000, UL)
226#define MEM_VIRT_INTRPT _AC(0xff000000, UL)
227
228#define INTRPT_SIZE 0x4000
229
230/* Tolerate page size larger than the architecture interrupt region size. */
231#if PAGE_SIZE > INTRPT_SIZE
232#undef INTRPT_SIZE
233#define INTRPT_SIZE PAGE_SIZE
234#endif
235
236#define KERNEL_HIGH_VADDR MEM_USER_INTRPT
237#define FIXADDR_TOP (KERNEL_HIGH_VADDR - PAGE_SIZE)
238
239#define PAGE_OFFSET _AC(CONFIG_PAGE_OFFSET, UL)
240
241/* On 32-bit architectures we mix kernel modules in with other vmaps. */
242#define MEM_MODULE_START VMALLOC_START
243#define MEM_MODULE_END VMALLOC_END
244
245#endif /* __tilegx__ */
246
247#ifndef __ASSEMBLY__
248
249#ifdef CONFIG_HIGHMEM
250
251/* Map kernel virtual addresses to page frames, in HPAGE_SIZE chunks. */
252extern unsigned long pbase_map[];
253extern void *vbase_map[];
254
255static inline unsigned long kaddr_to_pfn(const volatile void *_kaddr)
256{
257 unsigned long kaddr = (unsigned long)_kaddr;
258 return pbase_map[kaddr >> HPAGE_SHIFT] +
259 ((kaddr & (HPAGE_SIZE - 1)) >> PAGE_SHIFT);
260}
261
262static inline void *pfn_to_kaddr(unsigned long pfn)
263{
264 return vbase_map[__pfn_to_highbits(pfn)] + (pfn << PAGE_SHIFT);
265}
266
267static inline phys_addr_t virt_to_phys(const volatile void *kaddr)
268{
269 unsigned long pfn = kaddr_to_pfn(kaddr);
270 return ((phys_addr_t)pfn << PAGE_SHIFT) +
271 ((unsigned long)kaddr & (PAGE_SIZE-1));
272}
273
274static inline void *phys_to_virt(phys_addr_t paddr)
275{
276 return pfn_to_kaddr(paddr >> PAGE_SHIFT) + (paddr & (PAGE_SIZE-1));
277}
278
279/* With HIGHMEM, we pack PAGE_OFFSET through high_memory with all valid VAs. */
280static inline int virt_addr_valid(const volatile void *kaddr)
281{
282 extern void *high_memory; /* copied from <linux/mm.h> */
283 return ((unsigned long)kaddr >= PAGE_OFFSET && kaddr < high_memory);
284}
285
286#else /* !CONFIG_HIGHMEM */
287
288static inline unsigned long kaddr_to_pfn(const volatile void *kaddr)
289{
290 return ((unsigned long)kaddr - PAGE_OFFSET) >> PAGE_SHIFT;
291}
292
293static inline void *pfn_to_kaddr(unsigned long pfn)
294{
295 return (void *)((pfn << PAGE_SHIFT) + PAGE_OFFSET);
296}
297
298static inline phys_addr_t virt_to_phys(const volatile void *kaddr)
299{
300 return (phys_addr_t)((unsigned long)kaddr - PAGE_OFFSET);
301}
302
303static inline void *phys_to_virt(phys_addr_t paddr)
304{
305 return (void *)((unsigned long)paddr + PAGE_OFFSET);
306}
307
308/* Check that the given address is within some mapped range of PAs. */
309#define virt_addr_valid(kaddr) pfn_valid(kaddr_to_pfn(kaddr))
310
311#endif /* !CONFIG_HIGHMEM */
312
313/* All callers are not consistent in how they call these functions. */
314#define __pa(kaddr) virt_to_phys((void *)(unsigned long)(kaddr))
315#define __va(paddr) phys_to_virt((phys_addr_t)(paddr))
316
317extern int devmem_is_allowed(unsigned long pagenr);
318
319#ifdef CONFIG_FLATMEM
320static inline int pfn_valid(unsigned long pfn)
321{
322 return pfn < max_mapnr;
323}
324#endif
325
326/* Provide as macros since these require some other headers included. */
327#define page_to_pa(page) ((phys_addr_t)(page_to_pfn(page)) << PAGE_SHIFT)
328#define virt_to_page(kaddr) pfn_to_page(kaddr_to_pfn(kaddr))
329#define page_to_virt(page) pfn_to_kaddr(page_to_pfn(page))
330
331struct mm_struct;
332extern pte_t *virt_to_pte(struct mm_struct *mm, unsigned long addr);
333
334#endif /* !__ASSEMBLY__ */
335
336#define VM_DATA_DEFAULT_FLAGS \
337 (VM_READ | VM_WRITE | VM_MAYREAD | VM_MAYWRITE | VM_MAYEXEC)
338
339#include <asm-generic/memory_model.h>
340
341#endif /* __KERNEL__ */
342
343#endif /* _ASM_TILE_PAGE_H */
diff --git a/arch/tile/include/asm/param.h b/arch/tile/include/asm/param.h
new file mode 100644
index 000000000000..965d45427975
--- /dev/null
+++ b/arch/tile/include/asm/param.h
@@ -0,0 +1 @@
#include <asm-generic/param.h>
diff --git a/arch/tile/include/asm/pci-bridge.h b/arch/tile/include/asm/pci-bridge.h
new file mode 100644
index 000000000000..e853b0e2793b
--- /dev/null
+++ b/arch/tile/include/asm/pci-bridge.h
@@ -0,0 +1,117 @@
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_PCI_BRIDGE_H
16#define _ASM_TILE_PCI_BRIDGE_H
17
18#include <linux/ioport.h>
19#include <linux/pci.h>
20
21struct device_node;
22struct pci_controller;
23
24/*
25 * pci_io_base returns the memory address at which you can access
26 * the I/O space for PCI bus number `bus' (or NULL on error).
27 */
28extern void __iomem *pci_bus_io_base(unsigned int bus);
29extern unsigned long pci_bus_io_base_phys(unsigned int bus);
30extern unsigned long pci_bus_mem_base_phys(unsigned int bus);
31
32/* Allocate a new PCI host bridge structure */
33extern struct pci_controller *pcibios_alloc_controller(void);
34
35/* Helper function for setting up resources */
36extern void pci_init_resource(struct resource *res, unsigned long start,
37 unsigned long end, int flags, char *name);
38
39/* Get the PCI host controller for a bus */
40extern struct pci_controller *pci_bus_to_hose(int bus);
41
42/*
43 * Structure of a PCI controller (host bridge)
44 */
45struct pci_controller {
46 int index; /* PCI domain number */
47 struct pci_bus *root_bus;
48
49 int first_busno;
50 int last_busno;
51
52 int hv_cfg_fd[2]; /* config{0,1} fds for this PCIe controller */
53 int hv_mem_fd; /* fd to Hypervisor for MMIO operations */
54
55 struct pci_ops *ops;
56
57 int irq_base; /* Base IRQ from the Hypervisor */
58 int plx_gen1; /* flag for PLX Gen 1 configuration */
59
60 /* Address ranges that are routed to this controller/bridge. */
61 struct resource mem_resources[3];
62};
63
64static inline struct pci_controller *pci_bus_to_host(struct pci_bus *bus)
65{
66 return bus->sysdata;
67}
68
69extern void setup_indirect_pci_nomap(struct pci_controller *hose,
70 void __iomem *cfg_addr, void __iomem *cfg_data);
71extern void setup_indirect_pci(struct pci_controller *hose,
72 u32 cfg_addr, u32 cfg_data);
73extern void setup_grackle(struct pci_controller *hose);
74
75extern unsigned char common_swizzle(struct pci_dev *, unsigned char *);
76
77/*
78 * The following code swizzles for exactly one bridge. The routine
79 * common_swizzle below handles multiple bridges. But there are a
80 * some boards that don't follow the PCI spec's suggestion so we
81 * break this piece out separately.
82 */
83static inline unsigned char bridge_swizzle(unsigned char pin,
84 unsigned char idsel)
85{
86 return (((pin-1) + idsel) % 4) + 1;
87}
88
89/*
90 * The following macro is used to lookup irqs in a standard table
91 * format for those PPC systems that do not already have PCI
92 * interrupts properly routed.
93 */
94/* FIXME - double check this */
95#define PCI_IRQ_TABLE_LOOKUP ({ \
96 long _ctl_ = -1; \
97 if (idsel >= min_idsel && idsel <= max_idsel && pin <= irqs_per_slot) \
98 _ctl_ = pci_irq_table[idsel - min_idsel][pin-1]; \
99 _ctl_; \
100})
101
102/*
103 * Scan the buses below a given PCI host bridge and assign suitable
104 * resources to all devices found.
105 */
106extern int pciauto_bus_scan(struct pci_controller *, int);
107
108#ifdef CONFIG_PCI
109extern unsigned long pci_address_to_pio(phys_addr_t address);
110#else
111static inline unsigned long pci_address_to_pio(phys_addr_t address)
112{
113 return (unsigned long)-1;
114}
115#endif
116
117#endif /* _ASM_TILE_PCI_BRIDGE_H */
diff --git a/arch/tile/include/asm/pci.h b/arch/tile/include/asm/pci.h
new file mode 100644
index 000000000000..b0c15da2d5d5
--- /dev/null
+++ b/arch/tile/include/asm/pci.h
@@ -0,0 +1,128 @@
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_PCI_H
16#define _ASM_TILE_PCI_H
17
18#include <asm/pci-bridge.h>
19
20/*
21 * The hypervisor maps the entirety of CPA-space as bus addresses, so
22 * bus addresses are physical addresses. The networking and block
23 * device layers use this boolean for bounce buffer decisions.
24 */
25#define PCI_DMA_BUS_IS_PHYS 1
26
27struct pci_controller *pci_bus_to_hose(int bus);
28unsigned char __init common_swizzle(struct pci_dev *dev, unsigned char *pinp);
29int __init tile_pci_init(void);
30void pci_iounmap(struct pci_dev *dev, void __iomem *addr);
31void __iomem *pci_iomap(struct pci_dev *dev, int bar, unsigned long max);
32void __devinit pcibios_fixup_bus(struct pci_bus *bus);
33
34int __devinit _tile_cfg_read(struct pci_controller *hose,
35 int bus,
36 int slot,
37 int function,
38 int offset,
39 int size,
40 u32 *val);
41int __devinit _tile_cfg_write(struct pci_controller *hose,
42 int bus,
43 int slot,
44 int function,
45 int offset,
46 int size,
47 u32 val);
48
49/*
50 * These are used to to config reads and writes in the early stages of
51 * setup before the driver infrastructure has been set up enough to be
52 * able to do config reads and writes.
53 */
54#define early_cfg_read(where, size, value) \
55 _tile_cfg_read(controller, \
56 current_bus, \
57 pci_slot, \
58 pci_fn, \
59 where, \
60 size, \
61 value)
62
63#define early_cfg_write(where, size, value) \
64 _tile_cfg_write(controller, \
65 current_bus, \
66 pci_slot, \
67 pci_fn, \
68 where, \
69 size, \
70 value)
71
72
73
74#define PCICFG_BYTE 1
75#define PCICFG_WORD 2
76#define PCICFG_DWORD 4
77
78#define TILE_NUM_PCIE 2
79
80#define pci_domain_nr(bus) (((struct pci_controller *)(bus)->sysdata)->index)
81
82/*
83 * This decides whether to display the domain number in /proc.
84 */
85static inline int pci_proc_domain(struct pci_bus *bus)
86{
87 return 1;
88}
89
90/*
91 * I/O space is currently not supported.
92 */
93
94#define TILE_PCIE_LOWER_IO 0x0
95#define TILE_PCIE_UPPER_IO 0x10000
96#define TILE_PCIE_PCIE_IO_SIZE 0x0000FFFF
97
98#define _PAGE_NO_CACHE 0
99#define _PAGE_GUARDED 0
100
101
102#define pcibios_assign_all_busses() pci_assign_all_buses
103extern int pci_assign_all_buses;
104
105static inline void pcibios_set_master(struct pci_dev *dev)
106{
107 /* No special bus mastering setup handling */
108}
109
110#define PCIBIOS_MIN_MEM 0
111#define PCIBIOS_MIN_IO TILE_PCIE_LOWER_IO
112
113/*
114 * This flag tells if the platform is TILEmpower that needs
115 * special configuration for the PLX switch chip.
116 */
117extern int blade_pci;
118
119/* implement the pci_ DMA API in terms of the generic device dma_ one */
120#include <asm-generic/pci-dma-compat.h>
121
122/* generic pci stuff */
123#include <asm-generic/pci.h>
124
125/* Use any cpu for PCI. */
126#define cpumask_of_pcibus(bus) cpu_online_mask
127
128#endif /* _ASM_TILE_PCI_H */
diff --git a/arch/tile/include/asm/percpu.h b/arch/tile/include/asm/percpu.h
new file mode 100644
index 000000000000..63294f5a8efb
--- /dev/null
+++ b/arch/tile/include/asm/percpu.h
@@ -0,0 +1,24 @@
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_PERCPU_H
16#define _ASM_TILE_PERCPU_H
17
18register unsigned long __my_cpu_offset __asm__("tp");
19#define __my_cpu_offset __my_cpu_offset
20#define set_my_cpu_offset(tp) (__my_cpu_offset = (tp))
21
22#include <asm-generic/percpu.h>
23
24#endif /* _ASM_TILE_PERCPU_H */
diff --git a/arch/tile/include/asm/pgalloc.h b/arch/tile/include/asm/pgalloc.h
new file mode 100644
index 000000000000..cf52791a5501
--- /dev/null
+++ b/arch/tile/include/asm/pgalloc.h
@@ -0,0 +1,119 @@
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_PGALLOC_H
16#define _ASM_TILE_PGALLOC_H
17
18#include <linux/threads.h>
19#include <linux/mm.h>
20#include <linux/mmzone.h>
21#include <asm/fixmap.h>
22#include <hv/hypervisor.h>
23
24/* Bits for the size of the second-level page table. */
25#define L2_KERNEL_PGTABLE_SHIFT \
26 (HV_LOG2_PAGE_SIZE_LARGE - HV_LOG2_PAGE_SIZE_SMALL + HV_LOG2_PTE_SIZE)
27
28/* We currently allocate user L2 page tables by page (unlike kernel L2s). */
29#if L2_KERNEL_PGTABLE_SHIFT < HV_LOG2_PAGE_SIZE_SMALL
30#define L2_USER_PGTABLE_SHIFT HV_LOG2_PAGE_SIZE_SMALL
31#else
32#define L2_USER_PGTABLE_SHIFT L2_KERNEL_PGTABLE_SHIFT
33#endif
34
35/* How many pages do we need, as an "order", for a user L2 page table? */
36#define L2_USER_PGTABLE_ORDER (L2_USER_PGTABLE_SHIFT - HV_LOG2_PAGE_SIZE_SMALL)
37
38/* How big is a kernel L2 page table? */
39#define L2_KERNEL_PGTABLE_SIZE (1 << L2_KERNEL_PGTABLE_SHIFT)
40
41static inline void set_pmd(pmd_t *pmdp, pmd_t pmd)
42{
43#ifdef CONFIG_64BIT
44 set_pte_order(pmdp, pmd, L2_USER_PGTABLE_ORDER);
45#else
46 set_pte_order(&pmdp->pud.pgd, pmd.pud.pgd, L2_USER_PGTABLE_ORDER);
47#endif
48}
49
50static inline void pmd_populate_kernel(struct mm_struct *mm,
51 pmd_t *pmd, pte_t *ptep)
52{
53 set_pmd(pmd, ptfn_pmd(__pa(ptep) >> HV_LOG2_PAGE_TABLE_ALIGN,
54 __pgprot(_PAGE_PRESENT)));
55}
56
57static inline void pmd_populate(struct mm_struct *mm, pmd_t *pmd,
58 pgtable_t page)
59{
60 set_pmd(pmd, ptfn_pmd(HV_PFN_TO_PTFN(page_to_pfn(page)),
61 __pgprot(_PAGE_PRESENT)));
62}
63
64/*
65 * Allocate and free page tables.
66 */
67
68extern pgd_t *pgd_alloc(struct mm_struct *mm);
69extern void pgd_free(struct mm_struct *mm, pgd_t *pgd);
70
71extern pgtable_t pte_alloc_one(struct mm_struct *mm, unsigned long address);
72extern void pte_free(struct mm_struct *mm, struct page *pte);
73
74#define pmd_pgtable(pmd) pmd_page(pmd)
75
76static inline pte_t *
77pte_alloc_one_kernel(struct mm_struct *mm, unsigned long address)
78{
79 return pfn_to_kaddr(page_to_pfn(pte_alloc_one(mm, address)));
80}
81
82static inline void pte_free_kernel(struct mm_struct *mm, pte_t *pte)
83{
84 BUG_ON((unsigned long)pte & (PAGE_SIZE-1));
85 pte_free(mm, virt_to_page(pte));
86}
87
88extern void __pte_free_tlb(struct mmu_gather *tlb, struct page *pte,
89 unsigned long address);
90
91#define check_pgt_cache() do { } while (0)
92
93/*
94 * Get the small-page pte_t lowmem entry for a given pfn.
95 * This may or may not be in use, depending on whether the initial
96 * huge-page entry for the page has already been shattered.
97 */
98pte_t *get_prealloc_pte(unsigned long pfn);
99
100/* During init, we can shatter kernel huge pages if needed. */
101void shatter_pmd(pmd_t *pmd);
102
103#ifdef __tilegx__
104/* We share a single page allocator for both L1 and L2 page tables. */
105#if HV_L1_SIZE != HV_L2_SIZE
106# error Rework assumption that L1 and L2 page tables are same size.
107#endif
108#define L1_USER_PGTABLE_ORDER L2_USER_PGTABLE_ORDER
109#define pud_populate(mm, pud, pmd) \
110 pmd_populate_kernel((mm), (pmd_t *)(pud), (pte_t *)(pmd))
111#define pmd_alloc_one(mm, addr) \
112 ((pmd_t *)page_to_virt(pte_alloc_one((mm), (addr))))
113#define pmd_free(mm, pmdp) \
114 pte_free((mm), virt_to_page(pmdp))
115#define __pmd_free_tlb(tlb, pmdp, address) \
116 __pte_free_tlb((tlb), virt_to_page(pmdp), (address))
117#endif
118
119#endif /* _ASM_TILE_PGALLOC_H */
diff --git a/arch/tile/include/asm/pgtable.h b/arch/tile/include/asm/pgtable.h
new file mode 100644
index 000000000000..b3367379d537
--- /dev/null
+++ b/arch/tile/include/asm/pgtable.h
@@ -0,0 +1,480 @@
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 * This file contains the functions and defines necessary to modify and use
15 * the TILE page table tree.
16 */
17
18#ifndef _ASM_TILE_PGTABLE_H
19#define _ASM_TILE_PGTABLE_H
20
21#include <hv/hypervisor.h>
22
23#ifndef __ASSEMBLY__
24
25#include <linux/bitops.h>
26#include <linux/threads.h>
27#include <linux/slab.h>
28#include <linux/list.h>
29#include <linux/spinlock.h>
30#include <asm/processor.h>
31#include <asm/fixmap.h>
32#include <asm/system.h>
33
34struct mm_struct;
35struct vm_area_struct;
36
37/*
38 * ZERO_PAGE is a global shared page that is always zero: used
39 * for zero-mapped memory areas etc..
40 */
41extern unsigned long empty_zero_page[PAGE_SIZE/sizeof(unsigned long)];
42#define ZERO_PAGE(vaddr) (virt_to_page(empty_zero_page))
43
44extern pgd_t swapper_pg_dir[];
45extern pgprot_t swapper_pgprot;
46extern struct kmem_cache *pgd_cache;
47extern spinlock_t pgd_lock;
48extern struct list_head pgd_list;
49
50/*
51 * The very last slots in the pgd_t are for addresses unusable by Linux
52 * (pgd_addr_invalid() returns true). So we use them for the list structure.
53 * The x86 code we are modelled on uses the page->private/index fields
54 * (older 2.6 kernels) or the lru list (newer 2.6 kernels), but since
55 * our pgds are so much smaller than a page, it seems a waste to
56 * spend a whole page on each pgd.
57 */
58#define PGD_LIST_OFFSET \
59 ((PTRS_PER_PGD * sizeof(pgd_t)) - sizeof(struct list_head))
60#define pgd_to_list(pgd) \
61 ((struct list_head *)((char *)(pgd) + PGD_LIST_OFFSET))
62#define list_to_pgd(list) \
63 ((pgd_t *)((char *)(list) - PGD_LIST_OFFSET))
64
65extern void pgtable_cache_init(void);
66extern void paging_init(void);
67extern void set_page_homes(void);
68
69#define FIRST_USER_ADDRESS 0
70
71#define _PAGE_PRESENT HV_PTE_PRESENT
72#define _PAGE_HUGE_PAGE HV_PTE_PAGE
73#define _PAGE_READABLE HV_PTE_READABLE
74#define _PAGE_WRITABLE HV_PTE_WRITABLE
75#define _PAGE_EXECUTABLE HV_PTE_EXECUTABLE
76#define _PAGE_ACCESSED HV_PTE_ACCESSED
77#define _PAGE_DIRTY HV_PTE_DIRTY
78#define _PAGE_GLOBAL HV_PTE_GLOBAL
79#define _PAGE_USER HV_PTE_USER
80
81/*
82 * All the "standard" bits. Cache-control bits are managed elsewhere.
83 * This is used to test for valid level-2 page table pointers by checking
84 * all the bits, and to mask away the cache control bits for mprotect.
85 */
86#define _PAGE_ALL (\
87 _PAGE_PRESENT | \
88 _PAGE_HUGE_PAGE | \
89 _PAGE_READABLE | \
90 _PAGE_WRITABLE | \
91 _PAGE_EXECUTABLE | \
92 _PAGE_ACCESSED | \
93 _PAGE_DIRTY | \
94 _PAGE_GLOBAL | \
95 _PAGE_USER \
96)
97
98#define PAGE_NONE \
99 __pgprot(_PAGE_PRESENT | _PAGE_ACCESSED)
100#define PAGE_SHARED \
101 __pgprot(_PAGE_PRESENT | _PAGE_READABLE | _PAGE_WRITABLE | \
102 _PAGE_USER | _PAGE_ACCESSED)
103
104#define PAGE_SHARED_EXEC \
105 __pgprot(_PAGE_PRESENT | _PAGE_READABLE | _PAGE_WRITABLE | \
106 _PAGE_EXECUTABLE | _PAGE_USER | _PAGE_ACCESSED)
107#define PAGE_COPY_NOEXEC \
108 __pgprot(_PAGE_PRESENT | _PAGE_USER | _PAGE_ACCESSED | _PAGE_READABLE)
109#define PAGE_COPY_EXEC \
110 __pgprot(_PAGE_PRESENT | _PAGE_USER | _PAGE_ACCESSED | \
111 _PAGE_READABLE | _PAGE_EXECUTABLE)
112#define PAGE_COPY \
113 PAGE_COPY_NOEXEC
114#define PAGE_READONLY \
115 __pgprot(_PAGE_PRESENT | _PAGE_USER | _PAGE_ACCESSED | _PAGE_READABLE)
116#define PAGE_READONLY_EXEC \
117 __pgprot(_PAGE_PRESENT | _PAGE_USER | _PAGE_ACCESSED | \
118 _PAGE_READABLE | _PAGE_EXECUTABLE)
119
120#define _PAGE_KERNEL_RO \
121 (_PAGE_PRESENT | _PAGE_GLOBAL | _PAGE_READABLE | _PAGE_ACCESSED)
122#define _PAGE_KERNEL \
123 (_PAGE_KERNEL_RO | _PAGE_WRITABLE | _PAGE_DIRTY)
124#define _PAGE_KERNEL_EXEC (_PAGE_KERNEL_RO | _PAGE_EXECUTABLE)
125
126#define PAGE_KERNEL __pgprot(_PAGE_KERNEL)
127#define PAGE_KERNEL_RO __pgprot(_PAGE_KERNEL_RO)
128#define PAGE_KERNEL_EXEC __pgprot(_PAGE_KERNEL_EXEC)
129
130#define page_to_kpgprot(p) PAGE_KERNEL
131
132/*
133 * We could tighten these up, but for now writable or executable
134 * implies readable.
135 */
136#define __P000 PAGE_NONE
137#define __P001 PAGE_READONLY
138#define __P010 PAGE_COPY /* this is write-only, which we won't support */
139#define __P011 PAGE_COPY
140#define __P100 PAGE_READONLY_EXEC
141#define __P101 PAGE_READONLY_EXEC
142#define __P110 PAGE_COPY_EXEC
143#define __P111 PAGE_COPY_EXEC
144
145#define __S000 PAGE_NONE
146#define __S001 PAGE_READONLY
147#define __S010 PAGE_SHARED
148#define __S011 PAGE_SHARED
149#define __S100 PAGE_READONLY_EXEC
150#define __S101 PAGE_READONLY_EXEC
151#define __S110 PAGE_SHARED_EXEC
152#define __S111 PAGE_SHARED_EXEC
153
154/*
155 * All the normal _PAGE_ALL bits are ignored for PMDs, except PAGE_PRESENT
156 * and PAGE_HUGE_PAGE, which must be one and zero, respectively.
157 * We set the ignored bits to zero.
158 */
159#define _PAGE_TABLE _PAGE_PRESENT
160
161/* Inherit the caching flags from the old protection bits. */
162#define pgprot_modify(oldprot, newprot) \
163 (pgprot_t) { ((oldprot).val & ~_PAGE_ALL) | (newprot).val }
164
165/* Just setting the PFN to zero suffices. */
166#define pte_pgprot(x) hv_pte_set_pfn((x), 0)
167
168/*
169 * For PTEs and PDEs, we must clear the Present bit first when
170 * clearing a page table entry, so clear the bottom half first and
171 * enforce ordering with a barrier.
172 */
173static inline void __pte_clear(pte_t *ptep)
174{
175#ifdef __tilegx__
176 ptep->val = 0;
177#else
178 u32 *tmp = (u32 *)ptep;
179 tmp[0] = 0;
180 barrier();
181 tmp[1] = 0;
182#endif
183}
184#define pte_clear(mm, addr, ptep) __pte_clear(ptep)
185
186/*
187 * The following only work if pte_present() is true.
188 * Undefined behaviour if not..
189 */
190#define pte_present hv_pte_get_present
191#define pte_user hv_pte_get_user
192#define pte_read hv_pte_get_readable
193#define pte_dirty hv_pte_get_dirty
194#define pte_young hv_pte_get_accessed
195#define pte_write hv_pte_get_writable
196#define pte_exec hv_pte_get_executable
197#define pte_huge hv_pte_get_page
198#define pte_rdprotect hv_pte_clear_readable
199#define pte_exprotect hv_pte_clear_executable
200#define pte_mkclean hv_pte_clear_dirty
201#define pte_mkold hv_pte_clear_accessed
202#define pte_wrprotect hv_pte_clear_writable
203#define pte_mksmall hv_pte_clear_page
204#define pte_mkread hv_pte_set_readable
205#define pte_mkexec hv_pte_set_executable
206#define pte_mkdirty hv_pte_set_dirty
207#define pte_mkyoung hv_pte_set_accessed
208#define pte_mkwrite hv_pte_set_writable
209#define pte_mkhuge hv_pte_set_page
210
211#define pte_special(pte) 0
212#define pte_mkspecial(pte) (pte)
213
214/*
215 * Use some spare bits in the PTE for user-caching tags.
216 */
217#define pte_set_forcecache hv_pte_set_client0
218#define pte_get_forcecache hv_pte_get_client0
219#define pte_clear_forcecache hv_pte_clear_client0
220#define pte_set_anyhome hv_pte_set_client1
221#define pte_get_anyhome hv_pte_get_client1
222#define pte_clear_anyhome hv_pte_clear_client1
223
224/*
225 * A migrating PTE has PAGE_PRESENT clear but all the other bits preserved.
226 */
227#define pte_migrating hv_pte_get_migrating
228#define pte_mkmigrate(x) hv_pte_set_migrating(hv_pte_clear_present(x))
229#define pte_donemigrate(x) hv_pte_set_present(hv_pte_clear_migrating(x))
230
231#define pte_ERROR(e) \
232 pr_err("%s:%d: bad pte 0x%016llx.\n", __FILE__, __LINE__, pte_val(e))
233#define pgd_ERROR(e) \
234 pr_err("%s:%d: bad pgd 0x%016llx.\n", __FILE__, __LINE__, pgd_val(e))
235
236/*
237 * set_pte_order() sets the given PTE and also sanity-checks the
238 * requested PTE against the page homecaching. Unspecified parts
239 * of the PTE are filled in when it is written to memory, i.e. all
240 * caching attributes if "!forcecache", or the home cpu if "anyhome".
241 */
242extern void set_pte_order(pte_t *ptep, pte_t pte, int order);
243
244#define set_pte(ptep, pteval) set_pte_order(ptep, pteval, 0)
245#define set_pte_at(mm, addr, ptep, pteval) set_pte(ptep, pteval)
246#define set_pte_atomic(pteptr, pteval) set_pte(pteptr, pteval)
247
248#define pte_page(x) pfn_to_page(pte_pfn(x))
249
250static inline int pte_none(pte_t pte)
251{
252 return !pte.val;
253}
254
255static inline unsigned long pte_pfn(pte_t pte)
256{
257 return hv_pte_get_pfn(pte);
258}
259
260/* Set or get the remote cache cpu in a pgprot with remote caching. */
261extern pgprot_t set_remote_cache_cpu(pgprot_t prot, int cpu);
262extern int get_remote_cache_cpu(pgprot_t prot);
263
264static inline pte_t pfn_pte(unsigned long pfn, pgprot_t prot)
265{
266 return hv_pte_set_pfn(prot, pfn);
267}
268
269/* Support for priority mappings. */
270extern void start_mm_caching(struct mm_struct *mm);
271extern void check_mm_caching(struct mm_struct *prev, struct mm_struct *next);
272
273/*
274 * Support non-linear file mappings (see sys_remap_file_pages).
275 * This is defined by CLIENT1 set but CLIENT0 and _PAGE_PRESENT clear, and the
276 * file offset in the 32 high bits.
277 */
278#define _PAGE_FILE HV_PTE_CLIENT1
279#define PTE_FILE_MAX_BITS 32
280#define pte_file(pte) (hv_pte_get_client1(pte) && !hv_pte_get_client0(pte))
281#define pte_to_pgoff(pte) ((pte).val >> 32)
282#define pgoff_to_pte(off) ((pte_t) { (((long long)(off)) << 32) | _PAGE_FILE })
283
284/*
285 * Encode and de-code a swap entry (see <linux/swapops.h>).
286 * We put the swap file type+offset in the 32 high bits;
287 * I believe we can just leave the low bits clear.
288 */
289#define __swp_type(swp) ((swp).val & 0x1f)
290#define __swp_offset(swp) ((swp).val >> 5)
291#define __swp_entry(type, off) ((swp_entry_t) { (type) | ((off) << 5) })
292#define __pte_to_swp_entry(pte) ((swp_entry_t) { (pte).val >> 32 })
293#define __swp_entry_to_pte(swp) ((pte_t) { (((long long) ((swp).val)) << 32) })
294
295/*
296 * clone_pgd_range(pgd_t *dst, pgd_t *src, int count);
297 *
298 * dst - pointer to pgd range anwhere on a pgd page
299 * src - ""
300 * count - the number of pgds to copy.
301 *
302 * dst and src can be on the same page, but the range must not overlap,
303 * and must not cross a page boundary.
304 */
305static inline void clone_pgd_range(pgd_t *dst, pgd_t *src, int count)
306{
307 memcpy(dst, src, count * sizeof(pgd_t));
308}
309
310/*
311 * Conversion functions: convert a page and protection to a page entry,
312 * and a page entry and page directory to the page they refer to.
313 */
314
315#define mk_pte(page, pgprot) pfn_pte(page_to_pfn(page), (pgprot))
316
317/*
318 * If we are doing an mprotect(), just accept the new vma->vm_page_prot
319 * value and combine it with the PFN from the old PTE to get a new PTE.
320 */
321static inline pte_t pte_modify(pte_t pte, pgprot_t newprot)
322{
323 return pfn_pte(hv_pte_get_pfn(pte), newprot);
324}
325
326/*
327 * The pgd page can be thought of an array like this: pgd_t[PTRS_PER_PGD]
328 *
329 * This macro returns the index of the entry in the pgd page which would
330 * control the given virtual address.
331 */
332#define pgd_index(address) (((address) >> PGDIR_SHIFT) & (PTRS_PER_PGD - 1))
333
334/*
335 * pgd_offset() returns a (pgd_t *)
336 * pgd_index() is used get the offset into the pgd page's array of pgd_t's.
337 */
338#define pgd_offset(mm, address) ((mm)->pgd + pgd_index(address))
339
340/*
341 * A shortcut which implies the use of the kernel's pgd, instead
342 * of a process's.
343 */
344#define pgd_offset_k(address) pgd_offset(&init_mm, address)
345
346#if defined(CONFIG_HIGHPTE)
347extern pte_t *_pte_offset_map(pmd_t *, unsigned long address, enum km_type);
348#define pte_offset_map(dir, address) \
349 _pte_offset_map(dir, address, KM_PTE0)
350#define pte_offset_map_nested(dir, address) \
351 _pte_offset_map(dir, address, KM_PTE1)
352#define pte_unmap(pte) kunmap_atomic(pte, KM_PTE0)
353#define pte_unmap_nested(pte) kunmap_atomic(pte, KM_PTE1)
354#else
355#define pte_offset_map(dir, address) pte_offset_kernel(dir, address)
356#define pte_offset_map_nested(dir, address) pte_offset_map(dir, address)
357#define pte_unmap(pte) do { } while (0)
358#define pte_unmap_nested(pte) do { } while (0)
359#endif
360
361/* Clear a non-executable kernel PTE and flush it from the TLB. */
362#define kpte_clear_flush(ptep, vaddr) \
363do { \
364 pte_clear(&init_mm, (vaddr), (ptep)); \
365 local_flush_tlb_page(FLUSH_NONEXEC, (vaddr), PAGE_SIZE); \
366} while (0)
367
368/*
369 * The kernel page tables contain what we need, and we flush when we
370 * change specific page table entries.
371 */
372#define update_mmu_cache(vma, address, pte) do { } while (0)
373
374#ifdef CONFIG_FLATMEM
375#define kern_addr_valid(addr) (1)
376#endif /* CONFIG_FLATMEM */
377
378#define io_remap_pfn_range(vma, vaddr, pfn, size, prot) \
379 remap_pfn_range(vma, vaddr, pfn, size, prot)
380
381extern void vmalloc_sync_all(void);
382
383#endif /* !__ASSEMBLY__ */
384
385#ifdef __tilegx__
386#include <asm/pgtable_64.h>
387#else
388#include <asm/pgtable_32.h>
389#endif
390
391#ifndef __ASSEMBLY__
392
393static inline int pmd_none(pmd_t pmd)
394{
395 /*
396 * Only check low word on 32-bit platforms, since it might be
397 * out of sync with upper half.
398 */
399 return (unsigned long)pmd_val(pmd) == 0;
400}
401
402static inline int pmd_present(pmd_t pmd)
403{
404 return pmd_val(pmd) & _PAGE_PRESENT;
405}
406
407static inline int pmd_bad(pmd_t pmd)
408{
409 return ((pmd_val(pmd) & _PAGE_ALL) != _PAGE_TABLE);
410}
411
412static inline unsigned long pages_to_mb(unsigned long npg)
413{
414 return npg >> (20 - PAGE_SHIFT);
415}
416
417/*
418 * The pmd can be thought of an array like this: pmd_t[PTRS_PER_PMD]
419 *
420 * This function returns the index of the entry in the pmd which would
421 * control the given virtual address.
422 */
423static inline unsigned long pmd_index(unsigned long address)
424{
425 return (address >> PMD_SHIFT) & (PTRS_PER_PMD - 1);
426}
427
428/*
429 * A given kernel pmd_t maps to a specific virtual address (either a
430 * kernel huge page or a kernel pte_t table). Since kernel pte_t
431 * tables can be aligned at sub-page granularity, this function can
432 * return non-page-aligned pointers, despite its name.
433 */
434static inline unsigned long pmd_page_vaddr(pmd_t pmd)
435{
436 phys_addr_t pa =
437 (phys_addr_t)pmd_ptfn(pmd) << HV_LOG2_PAGE_TABLE_ALIGN;
438 return (unsigned long)__va(pa);
439}
440
441/*
442 * A pmd_t points to the base of a huge page or to a pte_t array.
443 * If a pte_t array, since we can have multiple per page, we don't
444 * have a one-to-one mapping of pmd_t's to pages. However, this is
445 * OK for pte_lockptr(), since we just end up with potentially one
446 * lock being used for several pte_t arrays.
447 */
448#define pmd_page(pmd) pfn_to_page(HV_PTFN_TO_PFN(pmd_ptfn(pmd)))
449
450/*
451 * The pte page can be thought of an array like this: pte_t[PTRS_PER_PTE]
452 *
453 * This macro returns the index of the entry in the pte page which would
454 * control the given virtual address.
455 */
456static inline unsigned long pte_index(unsigned long address)
457{
458 return (address >> PAGE_SHIFT) & (PTRS_PER_PTE - 1);
459}
460
461static inline pte_t *pte_offset_kernel(pmd_t *pmd, unsigned long address)
462{
463 return (pte_t *)pmd_page_vaddr(*pmd) + pte_index(address);
464}
465
466static inline int pmd_huge_page(pmd_t pmd)
467{
468 return pmd_val(pmd) & _PAGE_HUGE_PAGE;
469}
470
471#include <asm-generic/pgtable.h>
472
473/* Support /proc/NN/pgtable API. */
474struct seq_file;
475int arch_proc_pgtable_show(struct seq_file *m, struct mm_struct *mm,
476 unsigned long vaddr, pte_t *ptep, void **datap);
477
478#endif /* !__ASSEMBLY__ */
479
480#endif /* _ASM_TILE_PGTABLE_H */
diff --git a/arch/tile/include/asm/pgtable_32.h b/arch/tile/include/asm/pgtable_32.h
new file mode 100644
index 000000000000..53ec34884744
--- /dev/null
+++ b/arch/tile/include/asm/pgtable_32.h
@@ -0,0 +1,129 @@
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
16#ifndef _ASM_TILE_PGTABLE_32_H
17#define _ASM_TILE_PGTABLE_32_H
18
19/*
20 * The level-1 index is defined by the huge page size. A PGD is composed
21 * of PTRS_PER_PGD pgd_t's and is the top level of the page table.
22 */
23#define PGDIR_SHIFT HV_LOG2_PAGE_SIZE_LARGE
24#define PGDIR_SIZE HV_PAGE_SIZE_LARGE
25#define PGDIR_MASK (~(PGDIR_SIZE-1))
26#define PTRS_PER_PGD (1 << (32 - PGDIR_SHIFT))
27
28/*
29 * The level-2 index is defined by the difference between the huge
30 * page size and the normal page size. A PTE is composed of
31 * PTRS_PER_PTE pte_t's and is the bottom level of the page table.
32 * Note that the hypervisor docs use PTE for what we call pte_t, so
33 * this nomenclature is somewhat confusing.
34 */
35#define PTRS_PER_PTE (1 << (HV_LOG2_PAGE_SIZE_LARGE - HV_LOG2_PAGE_SIZE_SMALL))
36
37#ifndef __ASSEMBLY__
38
39/*
40 * Right now we initialize only a single pte table. It can be extended
41 * easily, subsequent pte tables have to be allocated in one physical
42 * chunk of RAM.
43 *
44 * HOWEVER, if we are using an allocation scheme with slop after the
45 * end of the page table (e.g. where our L2 page tables are 2KB but
46 * our pages are 64KB and we are allocating via the page allocator)
47 * we can't extend it easily.
48 */
49#define LAST_PKMAP PTRS_PER_PTE
50
51#define PKMAP_BASE ((FIXADDR_BOOT_START - PAGE_SIZE*LAST_PKMAP) & PGDIR_MASK)
52
53#ifdef CONFIG_HIGHMEM
54# define __VMAPPING_END (PKMAP_BASE & ~(HPAGE_SIZE-1))
55#else
56# define __VMAPPING_END (FIXADDR_START & ~(HPAGE_SIZE-1))
57#endif
58
59#ifdef CONFIG_HUGEVMAP
60#define HUGE_VMAP_END __VMAPPING_END
61#define HUGE_VMAP_BASE (HUGE_VMAP_END - CONFIG_NR_HUGE_VMAPS * HPAGE_SIZE)
62#define _VMALLOC_END HUGE_VMAP_BASE
63#else
64#define _VMALLOC_END __VMAPPING_END
65#endif
66
67/*
68 * Align the vmalloc area to an L2 page table, and leave a guard page
69 * at the beginning and end. The vmalloc code also puts in an internal
70 * guard page between each allocation.
71 */
72#define VMALLOC_END (_VMALLOC_END - PAGE_SIZE)
73extern unsigned long VMALLOC_RESERVE /* = CONFIG_VMALLOC_RESERVE */;
74#define _VMALLOC_START (_VMALLOC_END - VMALLOC_RESERVE)
75#define VMALLOC_START (_VMALLOC_START + PAGE_SIZE)
76
77/* This is the maximum possible amount of lowmem. */
78#define MAXMEM (_VMALLOC_START - PAGE_OFFSET)
79
80/* We have no pmd or pud since we are strictly a two-level page table */
81#include <asm-generic/pgtable-nopmd.h>
82
83/* We don't define any pgds for these addresses. */
84static inline int pgd_addr_invalid(unsigned long addr)
85{
86 return addr >= MEM_HV_INTRPT;
87}
88
89/*
90 * Provide versions of these routines that can be used safely when
91 * the hypervisor may be asynchronously modifying dirty/accessed bits.
92 * ptep_get_and_clear() matches the generic one but we provide it to
93 * be parallel with the 64-bit code.
94 */
95#define __HAVE_ARCH_PTEP_TEST_AND_CLEAR_YOUNG
96#define __HAVE_ARCH_PTEP_SET_WRPROTECT
97#define __HAVE_ARCH_PTEP_GET_AND_CLEAR
98
99extern int ptep_test_and_clear_young(struct vm_area_struct *,
100 unsigned long addr, pte_t *);
101extern void ptep_set_wrprotect(struct mm_struct *,
102 unsigned long addr, pte_t *);
103
104#define __HAVE_ARCH_PTEP_GET_AND_CLEAR
105static inline pte_t ptep_get_and_clear(struct mm_struct *mm,
106 unsigned long addr, pte_t *ptep)
107{
108 pte_t pte = *ptep;
109 pte_clear(_mm, addr, ptep);
110 return pte;
111}
112
113/* Create a pmd from a PTFN. */
114static inline pmd_t ptfn_pmd(unsigned long ptfn, pgprot_t prot)
115{
116 return (pmd_t){ { hv_pte_set_ptfn(prot, ptfn) } };
117}
118
119/* Return the page-table frame number (ptfn) that a pmd_t points at. */
120#define pmd_ptfn(pmd) hv_pte_get_ptfn((pmd).pud.pgd)
121
122static inline void pmd_clear(pmd_t *pmdp)
123{
124 __pte_clear(&pmdp->pud.pgd);
125}
126
127#endif /* __ASSEMBLY__ */
128
129#endif /* _ASM_TILE_PGTABLE_32_H */
diff --git a/arch/tile/include/asm/poll.h b/arch/tile/include/asm/poll.h
new file mode 100644
index 000000000000..c98509d3149e
--- /dev/null
+++ b/arch/tile/include/asm/poll.h
@@ -0,0 +1 @@
#include <asm-generic/poll.h>
diff --git a/arch/tile/include/asm/posix_types.h b/arch/tile/include/asm/posix_types.h
new file mode 100644
index 000000000000..22cae6230ceb
--- /dev/null
+++ b/arch/tile/include/asm/posix_types.h
@@ -0,0 +1 @@
#include <asm-generic/posix_types.h>
diff --git a/arch/tile/include/asm/processor.h b/arch/tile/include/asm/processor.h
new file mode 100644
index 000000000000..d942d09b252e
--- /dev/null
+++ b/arch/tile/include/asm/processor.h
@@ -0,0 +1,338 @@
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 <linux/types.h>
25#include <asm/ptrace.h>
26#include <asm/percpu.h>
27
28#include <arch/chip.h>
29#include <arch/spr_def.h>
30
31struct task_struct;
32struct thread_struct;
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#ifdef CONFIG_HARDWALL
78struct hardwall_info;
79#endif
80
81struct thread_struct {
82 /* kernel stack pointer */
83 unsigned long ksp;
84 /* kernel PC */
85 unsigned long pc;
86 /* starting user stack pointer (for page migration) */
87 unsigned long usp0;
88 /* pid of process that created this one */
89 pid_t creator_pid;
90#if CHIP_HAS_TILE_DMA()
91 /* DMA info for suspended threads (byte == 0 means no DMA state) */
92 struct tile_dma_state tile_dma_state;
93#endif
94 /* User EX_CONTEXT registers */
95 unsigned long ex_context[2];
96 /* User SYSTEM_SAVE registers */
97 unsigned long system_save[4];
98 /* User interrupt mask */
99 unsigned long long interrupt_mask;
100 /* User interrupt-control 0 state */
101 unsigned long intctrl_0;
102#if CHIP_HAS_PROC_STATUS_SPR()
103 /* Any other miscellaneous processor state bits */
104 unsigned long proc_status;
105#endif
106#ifdef CONFIG_HARDWALL
107 /* Is this task tied to an activated hardwall? */
108 struct hardwall_info *hardwall;
109 /* Chains this task into the list at hardwall->list. */
110 struct list_head hardwall_list;
111#endif
112#if CHIP_HAS_TILE_DMA()
113 /* Async DMA TLB fault information */
114 struct async_tlb dma_async_tlb;
115#endif
116#if CHIP_HAS_SN_PROC()
117 /* Was static network processor when we were switched out? */
118 int sn_proc_running;
119 /* Async SNI TLB fault information */
120 struct async_tlb sn_async_tlb;
121#endif
122};
123
124#endif /* !__ASSEMBLY__ */
125
126/*
127 * Start with "sp" this many bytes below the top of the kernel stack.
128 * This preserves the invariant that a called function may write to *sp.
129 */
130#define STACK_TOP_DELTA 8
131
132/*
133 * When entering the kernel via a fault, start with the top of the
134 * pt_regs structure this many bytes below the top of the page.
135 * This aligns the pt_regs structure optimally for cache-line access.
136 */
137#ifdef __tilegx__
138#define KSTK_PTREGS_GAP 48
139#else
140#define KSTK_PTREGS_GAP 56
141#endif
142
143#ifndef __ASSEMBLY__
144
145#ifdef __tilegx__
146#define TASK_SIZE_MAX (MEM_LOW_END + 1)
147#else
148#define TASK_SIZE_MAX PAGE_OFFSET
149#endif
150
151/* TASK_SIZE and related variables are always checked in "current" context. */
152#ifdef CONFIG_COMPAT
153#define COMPAT_TASK_SIZE (1UL << 31)
154#define TASK_SIZE ((current_thread_info()->status & TS_COMPAT) ?\
155 COMPAT_TASK_SIZE : TASK_SIZE_MAX)
156#else
157#define TASK_SIZE TASK_SIZE_MAX
158#endif
159
160/* We provide a minimal "vdso" a la x86; just the sigreturn code for now. */
161#define VDSO_BASE (TASK_SIZE - PAGE_SIZE)
162
163#define STACK_TOP VDSO_BASE
164
165/* STACK_TOP_MAX is used temporarily in execve and should not check COMPAT. */
166#define STACK_TOP_MAX TASK_SIZE_MAX
167
168/*
169 * This decides where the kernel will search for a free chunk of vm
170 * space during mmap's, if it is using bottom-up mapping.
171 */
172#define TASK_UNMAPPED_BASE (PAGE_ALIGN(TASK_SIZE / 3))
173
174#define HAVE_ARCH_PICK_MMAP_LAYOUT
175
176#define INIT_THREAD { \
177 .ksp = (unsigned long)init_stack + THREAD_SIZE - STACK_TOP_DELTA, \
178 .interrupt_mask = -1ULL \
179}
180
181/* Kernel stack top for the task that first boots on this cpu. */
182DECLARE_PER_CPU(unsigned long, boot_sp);
183
184/* PC to boot from on this cpu. */
185DECLARE_PER_CPU(unsigned long, boot_pc);
186
187/* Do necessary setup to start up a newly executed thread. */
188static inline void start_thread(struct pt_regs *regs,
189 unsigned long pc, unsigned long usp)
190{
191 regs->pc = pc;
192 regs->sp = usp;
193}
194
195/* Free all resources held by a thread. */
196static inline void release_thread(struct task_struct *dead_task)
197{
198 /* Nothing for now */
199}
200
201/* Prepare to copy thread state - unlazy all lazy status. */
202#define prepare_to_copy(tsk) do { } while (0)
203
204extern int kernel_thread(int (*fn)(void *), void *arg, unsigned long flags);
205
206
207/*
208 * Return saved (kernel) PC of a blocked thread.
209 * Only used in a printk() in kernel/sched.c, so don't work too hard.
210 */
211#define thread_saved_pc(t) ((t)->thread.pc)
212
213unsigned long get_wchan(struct task_struct *p);
214
215/* Return initial ksp value for given task. */
216#define task_ksp0(task) ((unsigned long)(task)->stack + THREAD_SIZE)
217
218/* Return some info about the user process TASK. */
219#define KSTK_TOP(task) (task_ksp0(task) - STACK_TOP_DELTA)
220#define task_pt_regs(task) \
221 ((struct pt_regs *)(task_ksp0(task) - KSTK_PTREGS_GAP) - 1)
222#define task_sp(task) (task_pt_regs(task)->sp)
223#define task_pc(task) (task_pt_regs(task)->pc)
224/* Aliases for pc and sp (used in fs/proc/array.c) */
225#define KSTK_EIP(task) task_pc(task)
226#define KSTK_ESP(task) task_sp(task)
227
228/* Standard format for printing registers and other word-size data. */
229#ifdef __tilegx__
230# define REGFMT "0x%016lx"
231#else
232# define REGFMT "0x%08lx"
233#endif
234
235/*
236 * Do some slow action (e.g. read a slow SPR).
237 * Note that this must also have compiler-barrier semantics since
238 * it may be used in a busy loop reading memory.
239 */
240static inline void cpu_relax(void)
241{
242 __insn_mfspr(SPR_PASS);
243 barrier();
244}
245
246struct siginfo;
247extern void arch_coredump_signal(struct siginfo *, struct pt_regs *);
248#define arch_coredump_signal arch_coredump_signal
249
250/* Info on this processor (see fs/proc/cpuinfo.c) */
251struct seq_operations;
252extern const struct seq_operations cpuinfo_op;
253
254/* Provide information about the chip model. */
255extern char chip_model[64];
256
257/* Data on which physical memory controller corresponds to which NUMA node. */
258extern int node_controller[];
259
260
261/* Do we dump information to the console when a user application crashes? */
262extern int show_crashinfo;
263
264#if CHIP_HAS_CBOX_HOME_MAP()
265/* Does the heap allocator return hash-for-home pages by default? */
266extern int hash_default;
267
268/* Should kernel stack pages be hash-for-home? */
269extern int kstack_hash;
270
271/* Does MAP_ANONYMOUS return hash-for-home pages by default? */
272#define uheap_hash hash_default
273
274#else
275#define hash_default 0
276#define kstack_hash 0
277#define uheap_hash 0
278#endif
279
280/* Are we using huge pages in the TLB for kernel data? */
281extern int kdata_huge;
282
283#define PREFETCH_STRIDE CHIP_L2_LINE_SIZE()
284
285#else /* __ASSEMBLY__ */
286
287/* Do some slow action (e.g. read a slow SPR). */
288#define CPU_RELAX mfspr zero, SPR_PASS
289
290#endif /* !__ASSEMBLY__ */
291
292/* Assembly code assumes that the PL is in the low bits. */
293#if SPR_EX_CONTEXT_1_1__PL_SHIFT != 0
294# error Fix assembly assumptions about PL
295#endif
296
297/* We sometimes use these macros for EX_CONTEXT_0_1 as well. */
298#if SPR_EX_CONTEXT_1_1__PL_SHIFT != SPR_EX_CONTEXT_0_1__PL_SHIFT || \
299 SPR_EX_CONTEXT_1_1__PL_RMASK != SPR_EX_CONTEXT_0_1__PL_RMASK || \
300 SPR_EX_CONTEXT_1_1__ICS_SHIFT != SPR_EX_CONTEXT_0_1__ICS_SHIFT || \
301 SPR_EX_CONTEXT_1_1__ICS_RMASK != SPR_EX_CONTEXT_0_1__ICS_RMASK
302# error Fix assumptions that EX1 macros work for both PL0 and PL1
303#endif
304
305/* Allow pulling apart and recombining the PL and ICS bits in EX_CONTEXT. */
306#define EX1_PL(ex1) \
307 (((ex1) >> SPR_EX_CONTEXT_1_1__PL_SHIFT) & SPR_EX_CONTEXT_1_1__PL_RMASK)
308#define EX1_ICS(ex1) \
309 (((ex1) >> SPR_EX_CONTEXT_1_1__ICS_SHIFT) & SPR_EX_CONTEXT_1_1__ICS_RMASK)
310#define PL_ICS_EX1(pl, ics) \
311 (((pl) << SPR_EX_CONTEXT_1_1__PL_SHIFT) | \
312 ((ics) << SPR_EX_CONTEXT_1_1__ICS_SHIFT))
313
314/*
315 * Provide symbolic constants for PLs.
316 * Note that assembly code assumes that USER_PL is zero.
317 */
318#define USER_PL 0
319#define KERNEL_PL 1
320
321/* SYSTEM_SAVE_1_0 holds the current cpu number ORed with ksp0. */
322#define CPU_LOG_MASK_VALUE 12
323#define CPU_MASK_VALUE ((1 << CPU_LOG_MASK_VALUE) - 1)
324#if CONFIG_NR_CPUS > CPU_MASK_VALUE
325# error Too many cpus!
326#endif
327#define raw_smp_processor_id() \
328 ((int)__insn_mfspr(SPR_SYSTEM_SAVE_1_0) & CPU_MASK_VALUE)
329#define get_current_ksp0() \
330 (__insn_mfspr(SPR_SYSTEM_SAVE_1_0) & ~CPU_MASK_VALUE)
331#define next_current_ksp0(task) ({ \
332 unsigned long __ksp0 = task_ksp0(task); \
333 int __cpu = raw_smp_processor_id(); \
334 BUG_ON(__ksp0 & CPU_MASK_VALUE); \
335 __ksp0 | __cpu; \
336})
337
338#endif /* _ASM_TILE_PROCESSOR_H */
diff --git a/arch/tile/include/asm/ptrace.h b/arch/tile/include/asm/ptrace.h
new file mode 100644
index 000000000000..acdae814e016
--- /dev/null
+++ b/arch/tile/include/asm/ptrace.h
@@ -0,0 +1,166 @@
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_PTRACE_H
16#define _ASM_TILE_PTRACE_H
17
18#include <arch/chip.h>
19#include <arch/abi.h>
20
21/* These must match struct pt_regs, below. */
22#if CHIP_WORD_SIZE() == 32
23#define PTREGS_OFFSET_REG(n) ((n)*4)
24#else
25#define PTREGS_OFFSET_REG(n) ((n)*8)
26#endif
27#define PTREGS_OFFSET_BASE 0
28#define PTREGS_OFFSET_TP PTREGS_OFFSET_REG(53)
29#define PTREGS_OFFSET_SP PTREGS_OFFSET_REG(54)
30#define PTREGS_OFFSET_LR PTREGS_OFFSET_REG(55)
31#define PTREGS_NR_GPRS 56
32#define PTREGS_OFFSET_PC PTREGS_OFFSET_REG(56)
33#define PTREGS_OFFSET_EX1 PTREGS_OFFSET_REG(57)
34#define PTREGS_OFFSET_FAULTNUM PTREGS_OFFSET_REG(58)
35#define PTREGS_OFFSET_ORIG_R0 PTREGS_OFFSET_REG(59)
36#define PTREGS_OFFSET_FLAGS PTREGS_OFFSET_REG(60)
37#if CHIP_HAS_CMPEXCH()
38#define PTREGS_OFFSET_CMPEXCH PTREGS_OFFSET_REG(61)
39#endif
40#define PTREGS_SIZE PTREGS_OFFSET_REG(64)
41
42#ifndef __ASSEMBLY__
43
44#ifdef __KERNEL__
45/* Benefit from consistent use of "long" on all chips. */
46typedef unsigned long pt_reg_t;
47#else
48/* Provide appropriate length type to userspace regardless of -m32/-m64. */
49typedef uint_reg_t pt_reg_t;
50#endif
51
52/*
53 * This struct defines the way the registers are stored on the stack during a
54 * system call/exception. It should be a multiple of 8 bytes to preserve
55 * normal stack alignment rules.
56 *
57 * Must track <sys/ucontext.h> and <sys/procfs.h>
58 */
59struct pt_regs {
60 /* Saved main processor registers; 56..63 are special. */
61 /* tp, sp, and lr must immediately follow regs[] for aliasing. */
62 pt_reg_t regs[53];
63 pt_reg_t tp; /* aliases regs[TREG_TP] */
64 pt_reg_t sp; /* aliases regs[TREG_SP] */
65 pt_reg_t lr; /* aliases regs[TREG_LR] */
66
67 /* Saved special registers. */
68 pt_reg_t pc; /* stored in EX_CONTEXT_1_0 */
69 pt_reg_t ex1; /* stored in EX_CONTEXT_1_1 (PL and ICS bit) */
70 pt_reg_t faultnum; /* fault number (INT_SWINT_1 for syscall) */
71 pt_reg_t orig_r0; /* r0 at syscall entry, else zero */
72 pt_reg_t flags; /* flags (see below) */
73#if !CHIP_HAS_CMPEXCH()
74 pt_reg_t pad[3];
75#else
76 pt_reg_t cmpexch; /* value of CMPEXCH_VALUE SPR at interrupt */
77 pt_reg_t pad[2];
78#endif
79};
80
81#endif /* __ASSEMBLY__ */
82
83/* Flag bits in pt_regs.flags */
84#define PT_FLAGS_DISABLE_IRQ 1 /* on return to kernel, disable irqs */
85#define PT_FLAGS_CALLER_SAVES 2 /* caller-save registers are valid */
86#define PT_FLAGS_RESTORE_REGS 4 /* restore callee-save regs on return */
87
88#define PTRACE_GETREGS 12
89#define PTRACE_SETREGS 13
90#define PTRACE_GETFPREGS 14
91#define PTRACE_SETFPREGS 15
92
93/* Support TILE-specific ptrace options, with events starting at 16. */
94#define PTRACE_O_TRACEMIGRATE 0x00010000
95#define PTRACE_EVENT_MIGRATE 16
96#ifdef __KERNEL__
97#define PTRACE_O_MASK_TILE (PTRACE_O_TRACEMIGRATE)
98#define PT_TRACE_MIGRATE 0x00080000
99#define PT_TRACE_MASK_TILE (PT_TRACE_MIGRATE)
100#endif
101
102#ifdef __KERNEL__
103
104#ifndef __ASSEMBLY__
105
106#define instruction_pointer(regs) ((regs)->pc)
107#define profile_pc(regs) instruction_pointer(regs)
108
109/* Does the process account for user or for system time? */
110#define user_mode(regs) (EX1_PL((regs)->ex1) == USER_PL)
111
112/* Fill in a struct pt_regs with the current kernel registers. */
113struct pt_regs *get_pt_regs(struct pt_regs *);
114
115/* Trace the current syscall. */
116extern void do_syscall_trace(void);
117
118extern void show_regs(struct pt_regs *);
119
120#define arch_has_single_step() (1)
121
122/*
123 * A structure for all single-stepper state.
124 *
125 * Also update defines in assembler section if it changes
126 */
127struct single_step_state {
128 /* the page to which we will write hacked-up bundles */
129 void __user *buffer;
130
131 union {
132 int flags;
133 struct {
134 unsigned long is_enabled:1, update:1, update_reg:6;
135 };
136 };
137
138 unsigned long orig_pc; /* the original PC */
139 unsigned long next_pc; /* return PC if no branch (PC + 1) */
140 unsigned long branch_next_pc; /* return PC if we did branch/jump */
141 unsigned long update_value; /* value to restore to update_target */
142};
143
144/* Single-step the instruction at regs->pc */
145extern void single_step_once(struct pt_regs *regs);
146
147struct task_struct;
148
149extern void send_sigtrap(struct task_struct *tsk, struct pt_regs *regs,
150 int error_code);
151
152#ifdef __tilegx__
153/* We need this since sigval_t has a user pointer in it, for GETSIGINFO etc. */
154#define __ARCH_WANT_COMPAT_SYS_PTRACE
155#endif
156
157#endif /* !__ASSEMBLY__ */
158
159#define SINGLESTEP_STATE_MASK_IS_ENABLED 0x1
160#define SINGLESTEP_STATE_MASK_UPDATE 0x2
161#define SINGLESTEP_STATE_TARGET_LB 2
162#define SINGLESTEP_STATE_TARGET_UB 7
163
164#endif /* !__KERNEL__ */
165
166#endif /* _ASM_TILE_PTRACE_H */
diff --git a/arch/tile/include/asm/resource.h b/arch/tile/include/asm/resource.h
new file mode 100644
index 000000000000..04bc4db8921b
--- /dev/null
+++ b/arch/tile/include/asm/resource.h
@@ -0,0 +1 @@
#include <asm-generic/resource.h>
diff --git a/arch/tile/include/asm/scatterlist.h b/arch/tile/include/asm/scatterlist.h
new file mode 100644
index 000000000000..35d786fe93ae
--- /dev/null
+++ b/arch/tile/include/asm/scatterlist.h
@@ -0,0 +1 @@
#include <asm-generic/scatterlist.h>
diff --git a/arch/tile/include/asm/sections.h b/arch/tile/include/asm/sections.h
new file mode 100644
index 000000000000..d062d463fca9
--- /dev/null
+++ b/arch/tile/include/asm/sections.h
@@ -0,0 +1,44 @@
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_SECTIONS_H
16#define _ASM_TILE_SECTIONS_H
17
18#define arch_is_kernel_data arch_is_kernel_data
19
20#include <asm-generic/sections.h>
21
22/* Text and data are at different areas in the kernel VA space. */
23extern char _sinitdata[], _einitdata[];
24
25/* Write-once data is writable only till the end of initialization. */
26extern char __w1data_begin[], __w1data_end[];
27
28
29/* Not exactly sections, but PC comparison points in the code. */
30extern char __rt_sigreturn[], __rt_sigreturn_end[];
31#ifndef __tilegx__
32extern char sys_cmpxchg[], __sys_cmpxchg_end[];
33extern char __sys_cmpxchg_grab_lock[];
34extern char __start_atomic_asm_code[], __end_atomic_asm_code[];
35#endif
36
37/* Handle the discontiguity between _sdata and _stext. */
38static inline int arch_is_kernel_data(unsigned long addr)
39{
40 return addr >= (unsigned long)_sdata &&
41 addr < (unsigned long)_end;
42}
43
44#endif /* _ASM_TILE_SECTIONS_H */
diff --git a/arch/tile/include/asm/sembuf.h b/arch/tile/include/asm/sembuf.h
new file mode 100644
index 000000000000..7673b83cfef7
--- /dev/null
+++ b/arch/tile/include/asm/sembuf.h
@@ -0,0 +1 @@
#include <asm-generic/sembuf.h>
diff --git a/arch/tile/include/asm/setup.h b/arch/tile/include/asm/setup.h
new file mode 100644
index 000000000000..7caf0f36b030
--- /dev/null
+++ b/arch/tile/include/asm/setup.h
@@ -0,0 +1,36 @@
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_SETUP_H
16#define _ASM_TILE_SETUP_H
17
18#define COMMAND_LINE_SIZE 2048
19
20#ifdef __KERNEL__
21
22#include <linux/pfn.h>
23#include <linux/init.h>
24
25/*
26 * Reserved space for vmalloc and iomap - defined in asm/page.h
27 */
28#define MAXMEM_PFN PFN_DOWN(MAXMEM)
29
30void early_panic(const char *fmt, ...);
31void warn_early_printk(void);
32void __init disable_early_printk(void);
33
34#endif /* __KERNEL__ */
35
36#endif /* _ASM_TILE_SETUP_H */
diff --git a/arch/tile/include/asm/shmbuf.h b/arch/tile/include/asm/shmbuf.h
new file mode 100644
index 000000000000..83c05fc2de38
--- /dev/null
+++ b/arch/tile/include/asm/shmbuf.h
@@ -0,0 +1 @@
#include <asm-generic/shmbuf.h>
diff --git a/arch/tile/include/asm/shmparam.h b/arch/tile/include/asm/shmparam.h
new file mode 100644
index 000000000000..93f30deb95d0
--- /dev/null
+++ b/arch/tile/include/asm/shmparam.h
@@ -0,0 +1 @@
#include <asm-generic/shmparam.h>
diff --git a/arch/tile/include/asm/sigcontext.h b/arch/tile/include/asm/sigcontext.h
new file mode 100644
index 000000000000..7cd7672e3ad4
--- /dev/null
+++ b/arch/tile/include/asm/sigcontext.h
@@ -0,0 +1,27 @@
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_SIGCONTEXT_H
16#define _ASM_TILE_SIGCONTEXT_H
17
18/* NOTE: we can't include <linux/ptrace.h> due to #include dependencies. */
19#include <asm/ptrace.h>
20
21/* Must track <sys/ucontext.h> */
22
23struct sigcontext {
24 struct pt_regs regs;
25};
26
27#endif /* _ASM_TILE_SIGCONTEXT_H */
diff --git a/arch/tile/include/asm/sigframe.h b/arch/tile/include/asm/sigframe.h
new file mode 100644
index 000000000000..994d3d30205f
--- /dev/null
+++ b/arch/tile/include/asm/sigframe.h
@@ -0,0 +1,33 @@
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_SIGFRAME_H
16#define _ASM_TILE_SIGFRAME_H
17
18/* Indicate that syscall return should not examine r0 */
19#define INT_SWINT_1_SIGRETURN (~0)
20
21#ifndef __ASSEMBLY__
22
23#include <arch/abi.h>
24
25struct rt_sigframe {
26 unsigned char save_area[C_ABI_SAVE_AREA_SIZE]; /* caller save area */
27 struct siginfo info;
28 struct ucontext uc;
29};
30
31#endif /* !__ASSEMBLY__ */
32
33#endif /* _ASM_TILE_SIGFRAME_H */
diff --git a/arch/tile/include/asm/siginfo.h b/arch/tile/include/asm/siginfo.h
new file mode 100644
index 000000000000..56d661bb010b
--- /dev/null
+++ b/arch/tile/include/asm/siginfo.h
@@ -0,0 +1,34 @@
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_SIGINFO_H
16#define _ASM_TILE_SIGINFO_H
17
18#define __ARCH_SI_TRAPNO
19
20#ifdef __LP64__
21# define __ARCH_SI_PREAMBLE_SIZE (4 * sizeof(int))
22#endif
23
24#include <asm-generic/siginfo.h>
25
26/*
27 * Additional Tile-specific SIGILL si_codes
28 */
29#define ILL_DBLFLT (__SI_FAULT|9) /* double fault */
30#define ILL_HARDWALL (__SI_FAULT|10) /* user networks hardwall violation */
31#undef NSIGILL
32#define NSIGILL 10
33
34#endif /* _ASM_TILE_SIGINFO_H */
diff --git a/arch/tile/include/asm/signal.h b/arch/tile/include/asm/signal.h
new file mode 100644
index 000000000000..eb0253f32202
--- /dev/null
+++ b/arch/tile/include/asm/signal.h
@@ -0,0 +1,32 @@
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_SIGNAL_H
16#define _ASM_TILE_SIGNAL_H
17
18/* Do not notify a ptracer when this signal is handled. */
19#define SA_NOPTRACE 0x02000000u
20
21/* Used in earlier Tilera releases, so keeping for binary compatibility. */
22#define SA_RESTORER 0x04000000u
23
24#include <asm-generic/signal.h>
25
26#if defined(__KERNEL__) && !defined(__ASSEMBLY__)
27int restore_sigcontext(struct pt_regs *, struct sigcontext __user *, long *);
28int setup_sigcontext(struct sigcontext __user *, struct pt_regs *);
29void do_signal(struct pt_regs *regs);
30#endif
31
32#endif /* _ASM_TILE_SIGNAL_H */
diff --git a/arch/tile/include/asm/smp.h b/arch/tile/include/asm/smp.h
new file mode 100644
index 000000000000..532124ae4b12
--- /dev/null
+++ b/arch/tile/include/asm/smp.h
@@ -0,0 +1,147 @@
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_SMP_H
16#define _ASM_TILE_SMP_H
17
18#ifdef CONFIG_SMP
19
20#include <asm/processor.h>
21#include <linux/cpumask.h>
22#include <linux/irqreturn.h>
23#include <hv/hypervisor.h>
24
25/* Set up this tile to support receiving hypervisor messages */
26void init_messaging(void);
27
28/* Set up this tile to support receiving device interrupts and IPIs. */
29void init_per_tile_IRQs(void);
30
31/* Send a message to processors specified in mask */
32void send_IPI_many(const struct cpumask *mask, int tag);
33
34/* Send a message to all but the sending processor */
35void send_IPI_allbutself(int tag);
36
37/* Send a message to a specific processor */
38void send_IPI_single(int dest, int tag);
39
40/* Process an IPI message */
41void evaluate_message(int tag);
42
43/* Boot a secondary cpu */
44void online_secondary(void);
45
46/* Call a function on a specified set of CPUs (may include this one). */
47extern void on_each_cpu_mask(const struct cpumask *mask,
48 void (*func)(void *), void *info, bool wait);
49
50/* Topology of the supervisor tile grid, and coordinates of boot processor */
51extern HV_Topology smp_topology;
52
53/* Accessors for grid size */
54#define smp_height (smp_topology.height)
55#define smp_width (smp_topology.width)
56
57/* Convenience functions for converting cpu <-> coords. */
58static inline int cpu_x(int cpu)
59{
60 return cpu % smp_width;
61}
62static inline int cpu_y(int cpu)
63{
64 return cpu / smp_width;
65}
66static inline int xy_to_cpu(int x, int y)
67{
68 return y * smp_width + x;
69}
70
71/* Hypervisor message tags sent via the tile send_IPI*() routines. */
72#define MSG_TAG_START_CPU 1
73#define MSG_TAG_STOP_CPU 2
74#define MSG_TAG_CALL_FUNCTION_MANY 3
75#define MSG_TAG_CALL_FUNCTION_SINGLE 4
76
77/* Hook for the generic smp_call_function_many() routine. */
78static inline void arch_send_call_function_ipi_mask(struct cpumask *mask)
79{
80 send_IPI_many(mask, MSG_TAG_CALL_FUNCTION_MANY);
81}
82
83/* Hook for the generic smp_call_function_single() routine. */
84static inline void arch_send_call_function_single_ipi(int cpu)
85{
86 send_IPI_single(cpu, MSG_TAG_CALL_FUNCTION_SINGLE);
87}
88
89/* Print out the boot string describing which cpus were disabled. */
90void print_disabled_cpus(void);
91
92#else /* !CONFIG_SMP */
93
94#define on_each_cpu_mask(mask, func, info, wait) \
95 do { if (cpumask_test_cpu(0, (mask))) func(info); } while (0)
96
97#define smp_master_cpu 0
98#define smp_height 1
99#define smp_width 1
100#define cpu_x(cpu) 0
101#define cpu_y(cpu) 0
102#define xy_to_cpu(x, y) 0
103
104#endif /* !CONFIG_SMP */
105
106
107/* Which cpus may be used as the lotar in a page table entry. */
108extern struct cpumask cpu_lotar_map;
109#define cpu_is_valid_lotar(cpu) cpumask_test_cpu((cpu), &cpu_lotar_map)
110
111#if CHIP_HAS_CBOX_HOME_MAP()
112/* Which processors are used for hash-for-home mapping */
113extern struct cpumask hash_for_home_map;
114#endif
115
116/* Which cpus can have their cache flushed by hv_flush_remote(). */
117extern struct cpumask cpu_cacheable_map;
118#define cpu_cacheable(cpu) cpumask_test_cpu((cpu), &cpu_cacheable_map)
119
120/* Convert an HV_LOTAR value into a cpu. */
121static inline int hv_lotar_to_cpu(HV_LOTAR lotar)
122{
123 return HV_LOTAR_X(lotar) + (HV_LOTAR_Y(lotar) * smp_width);
124}
125
126/*
127 * Extension of <linux/cpumask.h> functionality when you just want
128 * to express a mask or suppression or inclusion region without
129 * being too concerned about exactly which cpus are valid in that region.
130 */
131int bitmap_parselist_crop(const char *bp, unsigned long *maskp, int nmaskbits);
132
133#define cpulist_parse_crop(buf, dst) \
134 __cpulist_parse_crop((buf), (dst), NR_CPUS)
135static inline int __cpulist_parse_crop(const char *buf, struct cpumask *dstp,
136 int nbits)
137{
138 return bitmap_parselist_crop(buf, cpumask_bits(dstp), nbits);
139}
140
141/* Initialize the IPI subsystem. */
142void ipi_init(void);
143
144/* Function for start-cpu message to cause us to jump to. */
145extern unsigned long start_cpu_function_addr;
146
147#endif /* _ASM_TILE_SMP_H */
diff --git a/arch/tile/include/asm/socket.h b/arch/tile/include/asm/socket.h
new file mode 100644
index 000000000000..6b71384b9d8b
--- /dev/null
+++ b/arch/tile/include/asm/socket.h
@@ -0,0 +1 @@
#include <asm-generic/socket.h>
diff --git a/arch/tile/include/asm/sockios.h b/arch/tile/include/asm/sockios.h
new file mode 100644
index 000000000000..def6d4746ee7
--- /dev/null
+++ b/arch/tile/include/asm/sockios.h
@@ -0,0 +1 @@
#include <asm-generic/sockios.h>
diff --git a/arch/tile/include/asm/spinlock.h b/arch/tile/include/asm/spinlock.h
new file mode 100644
index 000000000000..1a8bd4740c28
--- /dev/null
+++ b/arch/tile/include/asm/spinlock.h
@@ -0,0 +1,24 @@
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_SPINLOCK_H
16#define _ASM_TILE_SPINLOCK_H
17
18#ifdef __tilegx__
19#include <asm/spinlock_64.h>
20#else
21#include <asm/spinlock_32.h>
22#endif
23
24#endif /* _ASM_TILE_SPINLOCK_H */
diff --git a/arch/tile/include/asm/spinlock_32.h b/arch/tile/include/asm/spinlock_32.h
new file mode 100644
index 000000000000..88efdde8dd2b
--- /dev/null
+++ b/arch/tile/include/asm/spinlock_32.h
@@ -0,0 +1,199 @@
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 * 32-bit SMP spinlocks.
15 */
16
17#ifndef _ASM_TILE_SPINLOCK_32_H
18#define _ASM_TILE_SPINLOCK_32_H
19
20#include <asm/atomic.h>
21#include <asm/page.h>
22#include <asm/system.h>
23#include <linux/compiler.h>
24
25/*
26 * We only use even ticket numbers so the '1' inserted by a tns is
27 * an unambiguous "ticket is busy" flag.
28 */
29#define TICKET_QUANTUM 2
30
31
32/*
33 * SMP ticket spinlocks, allowing only a single CPU anywhere
34 *
35 * (the type definitions are in asm/spinlock_types.h)
36 */
37static inline int arch_spin_is_locked(arch_spinlock_t *lock)
38{
39 /*
40 * Note that even if a new ticket is in the process of being
41 * acquired, so lock->next_ticket is 1, it's still reasonable
42 * to claim the lock is held, since it will be momentarily
43 * if not already. There's no need to wait for a "valid"
44 * lock->next_ticket to become available.
45 */
46 return lock->next_ticket != lock->current_ticket;
47}
48
49void arch_spin_lock(arch_spinlock_t *lock);
50
51/* We cannot take an interrupt after getting a ticket, so don't enable them. */
52#define arch_spin_lock_flags(lock, flags) arch_spin_lock(lock)
53
54int arch_spin_trylock(arch_spinlock_t *lock);
55
56static inline void arch_spin_unlock(arch_spinlock_t *lock)
57{
58 /* For efficiency, overlap fetching the old ticket with the wmb(). */
59 int old_ticket = lock->current_ticket;
60 wmb(); /* guarantee anything modified under the lock is visible */
61 lock->current_ticket = old_ticket + TICKET_QUANTUM;
62}
63
64void arch_spin_unlock_wait(arch_spinlock_t *lock);
65
66/*
67 * Read-write spinlocks, allowing multiple readers
68 * but only one writer.
69 *
70 * We use a "tns/store-back" technique on a single word to manage
71 * the lock state, looping around to retry if the tns returns 1.
72 */
73
74/* Internal layout of the word; do not use. */
75#define _WR_NEXT_SHIFT 8
76#define _WR_CURR_SHIFT 16
77#define _WR_WIDTH 8
78#define _RD_COUNT_SHIFT 24
79#define _RD_COUNT_WIDTH 8
80
81/* Internal functions; do not use. */
82void arch_read_lock_slow(arch_rwlock_t *, u32);
83int arch_read_trylock_slow(arch_rwlock_t *);
84void arch_read_unlock_slow(arch_rwlock_t *);
85void arch_write_lock_slow(arch_rwlock_t *, u32);
86void arch_write_unlock_slow(arch_rwlock_t *, u32);
87
88/**
89 * arch_read_can_lock() - would read_trylock() succeed?
90 */
91static inline int arch_read_can_lock(arch_rwlock_t *rwlock)
92{
93 return (rwlock->lock << _RD_COUNT_WIDTH) == 0;
94}
95
96/**
97 * arch_write_can_lock() - would write_trylock() succeed?
98 */
99static inline int arch_write_can_lock(arch_rwlock_t *rwlock)
100{
101 return rwlock->lock == 0;
102}
103
104/**
105 * arch_read_lock() - acquire a read lock.
106 */
107static inline void arch_read_lock(arch_rwlock_t *rwlock)
108{
109 u32 val = __insn_tns((int *)&rwlock->lock);
110 if (unlikely(val << _RD_COUNT_WIDTH)) {
111 arch_read_lock_slow(rwlock, val);
112 return;
113 }
114 rwlock->lock = val + (1 << _RD_COUNT_SHIFT);
115}
116
117/**
118 * arch_read_lock() - acquire a write lock.
119 */
120static inline void arch_write_lock(arch_rwlock_t *rwlock)
121{
122 u32 val = __insn_tns((int *)&rwlock->lock);
123 if (unlikely(val != 0)) {
124 arch_write_lock_slow(rwlock, val);
125 return;
126 }
127 rwlock->lock = 1 << _WR_NEXT_SHIFT;
128}
129
130/**
131 * arch_read_trylock() - try to acquire a read lock.
132 */
133static inline int arch_read_trylock(arch_rwlock_t *rwlock)
134{
135 int locked;
136 u32 val = __insn_tns((int *)&rwlock->lock);
137 if (unlikely(val & 1))
138 return arch_read_trylock_slow(rwlock);
139 locked = (val << _RD_COUNT_WIDTH) == 0;
140 rwlock->lock = val + (locked << _RD_COUNT_SHIFT);
141 return locked;
142}
143
144/**
145 * arch_write_trylock() - try to acquire a write lock.
146 */
147static inline int arch_write_trylock(arch_rwlock_t *rwlock)
148{
149 u32 val = __insn_tns((int *)&rwlock->lock);
150
151 /*
152 * If a tns is in progress, or there's a waiting or active locker,
153 * or active readers, we can't take the lock, so give up.
154 */
155 if (unlikely(val != 0)) {
156 if (!(val & 1))
157 rwlock->lock = val;
158 return 0;
159 }
160
161 /* Set the "next" field to mark it locked. */
162 rwlock->lock = 1 << _WR_NEXT_SHIFT;
163 return 1;
164}
165
166/**
167 * arch_read_unlock() - release a read lock.
168 */
169static inline void arch_read_unlock(arch_rwlock_t *rwlock)
170{
171 u32 val;
172 mb(); /* guarantee anything modified under the lock is visible */
173 val = __insn_tns((int *)&rwlock->lock);
174 if (unlikely(val & 1)) {
175 arch_read_unlock_slow(rwlock);
176 return;
177 }
178 rwlock->lock = val - (1 << _RD_COUNT_SHIFT);
179}
180
181/**
182 * arch_write_unlock() - release a write lock.
183 */
184static inline void arch_write_unlock(arch_rwlock_t *rwlock)
185{
186 u32 val;
187 mb(); /* guarantee anything modified under the lock is visible */
188 val = __insn_tns((int *)&rwlock->lock);
189 if (unlikely(val != (1 << _WR_NEXT_SHIFT))) {
190 arch_write_unlock_slow(rwlock, val);
191 return;
192 }
193 rwlock->lock = 0;
194}
195
196#define arch_read_lock_flags(lock, flags) arch_read_lock(lock)
197#define arch_write_lock_flags(lock, flags) arch_write_lock(lock)
198
199#endif /* _ASM_TILE_SPINLOCK_32_H */
diff --git a/arch/tile/include/asm/spinlock_types.h b/arch/tile/include/asm/spinlock_types.h
new file mode 100644
index 000000000000..a71f59b49c50
--- /dev/null
+++ b/arch/tile/include/asm/spinlock_types.h
@@ -0,0 +1,60 @@
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_SPINLOCK_TYPES_H
16#define _ASM_TILE_SPINLOCK_TYPES_H
17
18#ifndef __LINUX_SPINLOCK_TYPES_H
19# error "please don't include this file directly"
20#endif
21
22#ifdef __tilegx__
23
24/* Low 15 bits are "next"; high 15 bits are "current". */
25typedef struct arch_spinlock {
26 unsigned int lock;
27} arch_spinlock_t;
28
29#define __ARCH_SPIN_LOCK_UNLOCKED { 0 }
30
31/* High bit is "writer owns"; low 31 bits are a count of readers. */
32typedef struct arch_rwlock {
33 unsigned int lock;
34} arch_rwlock_t;
35
36#define __ARCH_RW_LOCK_UNLOCKED { 0 }
37
38#else
39
40typedef struct arch_spinlock {
41 /* Next ticket number to hand out. */
42 int next_ticket;
43 /* The ticket number that currently owns this lock. */
44 int current_ticket;
45} arch_spinlock_t;
46
47#define __ARCH_SPIN_LOCK_UNLOCKED { 0, 0 }
48
49/*
50 * Byte 0 for tns (only the low bit is used), byte 1 for ticket-lock "next",
51 * byte 2 for ticket-lock "current", byte 3 for reader count.
52 */
53typedef struct arch_rwlock {
54 unsigned int lock;
55} arch_rwlock_t;
56
57#define __ARCH_RW_LOCK_UNLOCKED { 0 }
58
59#endif
60#endif /* _ASM_TILE_SPINLOCK_TYPES_H */
diff --git a/arch/tile/include/asm/stack.h b/arch/tile/include/asm/stack.h
new file mode 100644
index 000000000000..f908473c322d
--- /dev/null
+++ b/arch/tile/include/asm/stack.h
@@ -0,0 +1,74 @@
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_STACK_H
16#define _ASM_TILE_STACK_H
17
18#include <linux/types.h>
19#include <linux/sched.h>
20#include <asm/backtrace.h>
21#include <hv/hypervisor.h>
22
23/* Everything we need to keep track of a backtrace iteration */
24struct KBacktraceIterator {
25 BacktraceIterator it;
26 struct task_struct *task; /* task we are backtracing */
27 HV_PTE *pgtable; /* page table for user space access */
28 int end; /* iteration complete. */
29 int new_context; /* new context is starting */
30 int profile; /* profiling, so stop on async intrpt */
31 int verbose; /* printk extra info (don't want to
32 * do this for profiling) */
33 int is_current; /* backtracing current task */
34};
35
36/* Iteration methods for kernel backtraces */
37
38/*
39 * Initialize a KBacktraceIterator from a task_struct, and optionally from
40 * a set of registers. If the registers are omitted, the process is
41 * assumed to be descheduled, and registers are read from the process's
42 * thread_struct and stack. "verbose" means to printk some additional
43 * information about fault handlers as we pass them on the stack.
44 */
45extern void KBacktraceIterator_init(struct KBacktraceIterator *kbt,
46 struct task_struct *, struct pt_regs *);
47
48/* Initialize iterator based on current stack. */
49extern void KBacktraceIterator_init_current(struct KBacktraceIterator *kbt);
50
51/* Helper method for above. */
52extern void _KBacktraceIterator_init_current(struct KBacktraceIterator *kbt,
53 ulong pc, ulong lr, ulong sp, ulong r52);
54
55/* No more frames? */
56extern int KBacktraceIterator_end(struct KBacktraceIterator *kbt);
57
58/* Advance to the next frame. */
59extern void KBacktraceIterator_next(struct KBacktraceIterator *kbt);
60
61/*
62 * Dump stack given complete register info. Use only from the
63 * architecture-specific code; show_stack()
64 * and dump_stack() (in entry.S) are architecture-independent entry points.
65 */
66extern void tile_show_stack(struct KBacktraceIterator *, int headers);
67
68/* Dump stack of current process, with registers to seed the backtrace. */
69extern void dump_stack_regs(struct pt_regs *);
70
71/* Helper method for assembly dump_stack(). */
72extern void _dump_stack(int dummy, ulong pc, ulong lr, ulong sp, ulong r52);
73
74#endif /* _ASM_TILE_STACK_H */
diff --git a/arch/tile/include/asm/stat.h b/arch/tile/include/asm/stat.h
new file mode 100644
index 000000000000..3dc90fa92c70
--- /dev/null
+++ b/arch/tile/include/asm/stat.h
@@ -0,0 +1 @@
#include <asm-generic/stat.h>
diff --git a/arch/tile/include/asm/statfs.h b/arch/tile/include/asm/statfs.h
new file mode 100644
index 000000000000..0b91fe198c20
--- /dev/null
+++ b/arch/tile/include/asm/statfs.h
@@ -0,0 +1 @@
#include <asm-generic/statfs.h>
diff --git a/arch/tile/include/asm/string.h b/arch/tile/include/asm/string.h
new file mode 100644
index 000000000000..7535cf1a30e4
--- /dev/null
+++ b/arch/tile/include/asm/string.h
@@ -0,0 +1,32 @@
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_STRING_H
16#define _ASM_TILE_STRING_H
17
18#define __HAVE_ARCH_MEMCHR
19#define __HAVE_ARCH_MEMSET
20#define __HAVE_ARCH_MEMCPY
21#define __HAVE_ARCH_MEMMOVE
22#define __HAVE_ARCH_STRCHR
23#define __HAVE_ARCH_STRLEN
24
25extern __kernel_size_t strlen(const char *);
26extern char *strchr(const char *s, int c);
27extern void *memchr(const void *s, int c, size_t n);
28extern void *memset(void *, int, __kernel_size_t);
29extern void *memcpy(void *, const void *, __kernel_size_t);
30extern void *memmove(void *, const void *, __kernel_size_t);
31
32#endif /* _ASM_TILE_STRING_H */
diff --git a/arch/tile/include/asm/swab.h b/arch/tile/include/asm/swab.h
new file mode 100644
index 000000000000..25c686a00f1d
--- /dev/null
+++ b/arch/tile/include/asm/swab.h
@@ -0,0 +1,29 @@
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_SWAB_H
16#define _ASM_TILE_SWAB_H
17
18/* Tile gcc is always >= 4.3.0, so we use __builtin_bswap. */
19#define __arch_swab32(x) __builtin_bswap32(x)
20#define __arch_swab64(x) __builtin_bswap64(x)
21
22/* Use the variant that is natural for the wordsize. */
23#ifdef CONFIG_64BIT
24#define __arch_swab16(x) (__builtin_bswap64(x) >> 48)
25#else
26#define __arch_swab16(x) (__builtin_bswap32(x) >> 16)
27#endif
28
29#endif /* _ASM_TILE_SWAB_H */
diff --git a/arch/tile/include/asm/syscall.h b/arch/tile/include/asm/syscall.h
new file mode 100644
index 000000000000..d35e0dcb67b1
--- /dev/null
+++ b/arch/tile/include/asm/syscall.h
@@ -0,0 +1,79 @@
1/*
2 * Copyright (C) 2008-2009 Red Hat, Inc. All rights reserved.
3 * Copyright 2010 Tilera Corporation. All Rights Reserved.
4 *
5 * This program is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU General Public License
7 * as published by the Free Software Foundation, version 2.
8 *
9 * This program is distributed in the hope that it will be useful, but
10 * WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, GOOD TITLE or
12 * NON INFRINGEMENT. See the GNU General Public License for
13 * more details.
14 *
15 * See asm-generic/syscall.h for descriptions of what we must do here.
16 */
17
18#ifndef _ASM_TILE_SYSCALL_H
19#define _ASM_TILE_SYSCALL_H
20
21#include <linux/sched.h>
22#include <linux/err.h>
23#include <arch/abi.h>
24
25/*
26 * Only the low 32 bits of orig_r0 are meaningful, so we return int.
27 * This importantly ignores the high bits on 64-bit, so comparisons
28 * sign-extend the low 32 bits.
29 */
30static inline int syscall_get_nr(struct task_struct *t, struct pt_regs *regs)
31{
32 return regs->regs[TREG_SYSCALL_NR];
33}
34
35static inline void syscall_rollback(struct task_struct *task,
36 struct pt_regs *regs)
37{
38 regs->regs[0] = regs->orig_r0;
39}
40
41static inline long syscall_get_error(struct task_struct *task,
42 struct pt_regs *regs)
43{
44 unsigned long error = regs->regs[0];
45 return IS_ERR_VALUE(error) ? error : 0;
46}
47
48static inline long syscall_get_return_value(struct task_struct *task,
49 struct pt_regs *regs)
50{
51 return regs->regs[0];
52}
53
54static inline void syscall_set_return_value(struct task_struct *task,
55 struct pt_regs *regs,
56 int error, long val)
57{
58 regs->regs[0] = (long) error ?: val;
59}
60
61static inline void syscall_get_arguments(struct task_struct *task,
62 struct pt_regs *regs,
63 unsigned int i, unsigned int n,
64 unsigned long *args)
65{
66 BUG_ON(i + n > 6);
67 memcpy(args, &regs[i], n * sizeof(args[0]));
68}
69
70static inline void syscall_set_arguments(struct task_struct *task,
71 struct pt_regs *regs,
72 unsigned int i, unsigned int n,
73 const unsigned long *args)
74{
75 BUG_ON(i + n > 6);
76 memcpy(&regs[i], args, n * sizeof(args[0]));
77}
78
79#endif /* _ASM_TILE_SYSCALL_H */
diff --git a/arch/tile/include/asm/syscalls.h b/arch/tile/include/asm/syscalls.h
new file mode 100644
index 000000000000..af165a74537f
--- /dev/null
+++ b/arch/tile/include/asm/syscalls.h
@@ -0,0 +1,108 @@
1/*
2 * syscalls.h - Linux syscall interfaces (arch-specific)
3 *
4 * Copyright (c) 2008 Jaswinder Singh Rajput
5 * Copyright 2010 Tilera Corporation. All Rights Reserved.
6 *
7 * This program is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU General Public License
9 * as published by the Free Software Foundation, version 2.
10 *
11 * This program is distributed in the hope that it will be useful, but
12 * WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, GOOD TITLE or
14 * NON INFRINGEMENT. See the GNU General Public License for
15 * more details.
16 */
17
18#ifndef _ASM_TILE_SYSCALLS_H
19#define _ASM_TILE_SYSCALLS_H
20
21#include <linux/compiler.h>
22#include <linux/linkage.h>
23#include <linux/signal.h>
24#include <linux/types.h>
25#include <linux/compat.h>
26
27/* The array of function pointers for syscalls. */
28extern void *sys_call_table[];
29#ifdef CONFIG_COMPAT
30extern void *compat_sys_call_table[];
31#endif
32
33/*
34 * Note that by convention, any syscall which requires the current
35 * register set takes an additional "struct pt_regs *" pointer; the
36 * sys_xxx() function just adds the pointer and tail-calls to _sys_xxx().
37 */
38
39/* kernel/sys.c */
40ssize_t sys32_readahead(int fd, u32 offset_lo, u32 offset_hi, u32 count);
41long sys32_fadvise64(int fd, u32 offset_lo, u32 offset_hi,
42 u32 len, int advice);
43int sys32_fadvise64_64(int fd, u32 offset_lo, u32 offset_hi,
44 u32 len_lo, u32 len_hi, int advice);
45long sys_flush_cache(void);
46long sys_mmap2(unsigned long addr, unsigned long len,
47 unsigned long prot, unsigned long flags,
48 unsigned long fd, unsigned long pgoff);
49#ifdef __tilegx__
50long sys_mmap(unsigned long addr, unsigned long len,
51 unsigned long prot, unsigned long flags,
52 unsigned long fd, off_t pgoff);
53#endif
54
55/* kernel/process.c */
56long sys_clone(unsigned long clone_flags, unsigned long newsp,
57 void __user *parent_tid, void __user *child_tid);
58long _sys_clone(unsigned long clone_flags, unsigned long newsp,
59 void __user *parent_tid, void __user *child_tid,
60 struct pt_regs *regs);
61long sys_fork(void);
62long _sys_fork(struct pt_regs *regs);
63long sys_vfork(void);
64long _sys_vfork(struct pt_regs *regs);
65long sys_execve(char __user *filename, char __user * __user *argv,
66 char __user * __user *envp);
67long _sys_execve(char __user *filename, char __user * __user *argv,
68 char __user * __user *envp, struct pt_regs *regs);
69
70/* kernel/signal.c */
71long sys_sigaltstack(const stack_t __user *, stack_t __user *);
72long _sys_sigaltstack(const stack_t __user *, stack_t __user *,
73 struct pt_regs *);
74long sys_rt_sigreturn(void);
75long _sys_rt_sigreturn(struct pt_regs *regs);
76
77/* platform-independent functions */
78long sys_rt_sigsuspend(sigset_t __user *unewset, size_t sigsetsize);
79long sys_rt_sigaction(int sig, const struct sigaction __user *act,
80 struct sigaction __user *oact, size_t sigsetsize);
81
82#ifndef __tilegx__
83/* mm/fault.c */
84int sys_cmpxchg_badaddr(unsigned long address);
85int _sys_cmpxchg_badaddr(unsigned long address, struct pt_regs *);
86#endif
87
88#ifdef CONFIG_COMPAT
89long compat_sys_execve(char __user *path, compat_uptr_t __user *argv,
90 compat_uptr_t __user *envp);
91long _compat_sys_execve(char __user *path, compat_uptr_t __user *argv,
92 compat_uptr_t __user *envp, struct pt_regs *regs);
93long compat_sys_sigaltstack(const struct compat_sigaltstack __user *uss_ptr,
94 struct compat_sigaltstack __user *uoss_ptr);
95long _compat_sys_sigaltstack(const struct compat_sigaltstack __user *uss_ptr,
96 struct compat_sigaltstack __user *uoss_ptr,
97 struct pt_regs *regs);
98long compat_sys_rt_sigreturn(void);
99long _compat_sys_rt_sigreturn(struct pt_regs *regs);
100
101/* These four are not defined for 64-bit, but serve as "compat" syscalls. */
102long sys_fcntl64(unsigned int fd, unsigned int cmd, unsigned long arg);
103long sys_fstat64(unsigned long fd, struct stat64 __user *statbuf);
104long sys_truncate64(const char __user *path, loff_t length);
105long sys_ftruncate64(unsigned int fd, loff_t length);
106#endif
107
108#endif /* _ASM_TILE_SYSCALLS_H */
diff --git a/arch/tile/include/asm/system.h b/arch/tile/include/asm/system.h
new file mode 100644
index 000000000000..f749be327ce0
--- /dev/null
+++ b/arch/tile/include/asm/system.h
@@ -0,0 +1,248 @@
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_SYSTEM_H
16#define _ASM_TILE_SYSTEM_H
17
18#ifndef __ASSEMBLY__
19
20#include <linux/types.h>
21#include <linux/irqflags.h>
22
23/* NOTE: we can't include <linux/ptrace.h> due to #include dependencies. */
24#include <asm/ptrace.h>
25
26#include <arch/chip.h>
27#include <arch/sim_def.h>
28#include <arch/spr_def.h>
29
30/*
31 * read_barrier_depends - Flush all pending reads that subsequents reads
32 * depend on.
33 *
34 * No data-dependent reads from memory-like regions are ever reordered
35 * over this barrier. All reads preceding this primitive are guaranteed
36 * to access memory (but not necessarily other CPUs' caches) before any
37 * reads following this primitive that depend on the data return by
38 * any of the preceding reads. This primitive is much lighter weight than
39 * rmb() on most CPUs, and is never heavier weight than is
40 * rmb().
41 *
42 * These ordering constraints are respected by both the local CPU
43 * and the compiler.
44 *
45 * Ordering is not guaranteed by anything other than these primitives,
46 * not even by data dependencies. See the documentation for
47 * memory_barrier() for examples and URLs to more information.
48 *
49 * For example, the following code would force ordering (the initial
50 * value of "a" is zero, "b" is one, and "p" is "&a"):
51 *
52 * <programlisting>
53 * CPU 0 CPU 1
54 *
55 * b = 2;
56 * memory_barrier();
57 * p = &b; q = p;
58 * read_barrier_depends();
59 * d = *q;
60 * </programlisting>
61 *
62 * because the read of "*q" depends on the read of "p" and these
63 * two reads are separated by a read_barrier_depends(). However,
64 * the following code, with the same initial values for "a" and "b":
65 *
66 * <programlisting>
67 * CPU 0 CPU 1
68 *
69 * a = 2;
70 * memory_barrier();
71 * b = 3; y = b;
72 * read_barrier_depends();
73 * x = a;
74 * </programlisting>
75 *
76 * does not enforce ordering, since there is no data dependency between
77 * the read of "a" and the read of "b". Therefore, on some CPUs, such
78 * as Alpha, "y" could be set to 3 and "x" to 0. Use rmb()
79 * in cases like this where there are no data dependencies.
80 */
81
82#define read_barrier_depends() do { } while (0)
83
84#define __sync() __insn_mf()
85
86#if CHIP_HAS_SPLIT_CYCLE()
87#define get_cycles_low() __insn_mfspr(SPR_CYCLE_LOW)
88#else
89#define get_cycles_low() __insn_mfspr(SPR_CYCLE) /* just get all 64 bits */
90#endif
91
92/* Fence to guarantee visibility of stores to incoherent memory. */
93static inline void
94mb_incoherent(void)
95{
96 __insn_mf();
97
98#if !CHIP_HAS_MF_WAITS_FOR_VICTIMS()
99 {
100 int __mb_incoherent(void);
101#if CHIP_HAS_TILE_WRITE_PENDING()
102 const unsigned long WRITE_TIMEOUT_CYCLES = 400;
103 unsigned long start = get_cycles_low();
104 do {
105 if (__insn_mfspr(SPR_TILE_WRITE_PENDING) == 0)
106 return;
107 } while ((get_cycles_low() - start) < WRITE_TIMEOUT_CYCLES);
108#endif /* CHIP_HAS_TILE_WRITE_PENDING() */
109 (void) __mb_incoherent();
110 }
111#endif /* CHIP_HAS_MF_WAITS_FOR_VICTIMS() */
112}
113
114#define fast_wmb() __sync()
115#define fast_rmb() __sync()
116#define fast_mb() __sync()
117#define fast_iob() mb_incoherent()
118
119#define wmb() fast_wmb()
120#define rmb() fast_rmb()
121#define mb() fast_mb()
122#define iob() fast_iob()
123
124#ifdef CONFIG_SMP
125#define smp_mb() mb()
126#define smp_rmb() rmb()
127#define smp_wmb() wmb()
128#define smp_read_barrier_depends() read_barrier_depends()
129#else
130#define smp_mb() barrier()
131#define smp_rmb() barrier()
132#define smp_wmb() barrier()
133#define smp_read_barrier_depends() do { } while (0)
134#endif
135
136#define set_mb(var, value) \
137 do { var = value; mb(); } while (0)
138
139/*
140 * Pause the DMA engine and static network before task switching.
141 */
142#define prepare_arch_switch(next) _prepare_arch_switch(next)
143void _prepare_arch_switch(struct task_struct *next);
144
145
146/*
147 * switch_to(n) should switch tasks to task nr n, first
148 * checking that n isn't the current task, in which case it does nothing.
149 * The number of callee-saved registers saved on the kernel stack
150 * is defined here for use in copy_thread() and must agree with __switch_to().
151 */
152#endif /* !__ASSEMBLY__ */
153#define CALLEE_SAVED_FIRST_REG 30
154#define CALLEE_SAVED_REGS_COUNT 24 /* r30 to r52, plus an empty to align */
155#ifndef __ASSEMBLY__
156struct task_struct;
157#define switch_to(prev, next, last) ((last) = _switch_to((prev), (next)))
158extern struct task_struct *_switch_to(struct task_struct *prev,
159 struct task_struct *next);
160
161/* Helper function for _switch_to(). */
162extern struct task_struct *__switch_to(struct task_struct *prev,
163 struct task_struct *next,
164 unsigned long new_system_save_1_0);
165
166/* Address that switched-away from tasks are at. */
167extern unsigned long get_switch_to_pc(void);
168
169/*
170 * On SMP systems, when the scheduler does migration-cost autodetection,
171 * it needs a way to flush as much of the CPU's caches as possible:
172 *
173 * TODO: fill this in!
174 */
175static inline void sched_cacheflush(void)
176{
177}
178
179#define arch_align_stack(x) (x)
180
181/*
182 * Is the kernel doing fixups of unaligned accesses? If <0, no kernel
183 * intervention occurs and SIGBUS is delivered with no data address
184 * info. If 0, the kernel single-steps the instruction to discover
185 * the data address to provide with the SIGBUS. If 1, the kernel does
186 * a fixup.
187 */
188extern int unaligned_fixup;
189
190/* Is the kernel printing on each unaligned fixup? */
191extern int unaligned_printk;
192
193/* Number of unaligned fixups performed */
194extern unsigned int unaligned_fixup_count;
195
196/* Init-time routine to do tile-specific per-cpu setup. */
197void setup_cpu(int boot);
198
199/* User-level DMA management functions */
200void grant_dma_mpls(void);
201void restrict_dma_mpls(void);
202
203#ifdef CONFIG_HARDWALL
204/* User-level network management functions */
205void reset_network_state(void);
206void grant_network_mpls(void);
207void restrict_network_mpls(void);
208int hardwall_deactivate(struct task_struct *task);
209
210/* Hook hardwall code into changes in affinity. */
211#define arch_set_cpus_allowed(p, new_mask) do { \
212 if (p->thread.hardwall && !cpumask_equal(&p->cpus_allowed, new_mask)) \
213 hardwall_deactivate(p); \
214} while (0)
215#endif
216
217/* Invoke the simulator "syscall" mechanism (see arch/tile/kernel/entry.S). */
218extern int _sim_syscall(int syscall_num, ...);
219#define sim_syscall(syscall_num, ...) \
220 _sim_syscall(SIM_CONTROL_SYSCALL + \
221 ((syscall_num) << _SIM_CONTROL_OPERATOR_BITS), \
222 ## __VA_ARGS__)
223
224/*
225 * Kernel threads can check to see if they need to migrate their
226 * stack whenever they return from a context switch; for user
227 * threads, we defer until they are returning to user-space.
228 */
229#define finish_arch_switch(prev) do { \
230 if (unlikely((prev)->state == TASK_DEAD)) \
231 __insn_mtspr(SPR_SIM_CONTROL, SIM_CONTROL_OS_EXIT | \
232 ((prev)->pid << _SIM_CONTROL_OPERATOR_BITS)); \
233 __insn_mtspr(SPR_SIM_CONTROL, SIM_CONTROL_OS_SWITCH | \
234 (current->pid << _SIM_CONTROL_OPERATOR_BITS)); \
235 if (current->mm == NULL && !kstack_hash && \
236 current_thread_info()->homecache_cpu != smp_processor_id()) \
237 homecache_migrate_kthread(); \
238} while (0)
239
240/* Support function for forking a new task. */
241void ret_from_fork(void);
242
243/* Called from ret_from_fork() when a new process starts up. */
244struct task_struct *sim_notify_fork(struct task_struct *prev);
245
246#endif /* !__ASSEMBLY__ */
247
248#endif /* _ASM_TILE_SYSTEM_H */
diff --git a/arch/tile/include/asm/termbits.h b/arch/tile/include/asm/termbits.h
new file mode 100644
index 000000000000..3935b106de79
--- /dev/null
+++ b/arch/tile/include/asm/termbits.h
@@ -0,0 +1 @@
#include <asm-generic/termbits.h>
diff --git a/arch/tile/include/asm/termios.h b/arch/tile/include/asm/termios.h
new file mode 100644
index 000000000000..280d78a9d966
--- /dev/null
+++ b/arch/tile/include/asm/termios.h
@@ -0,0 +1 @@
#include <asm-generic/termios.h>
diff --git a/arch/tile/include/asm/thread_info.h b/arch/tile/include/asm/thread_info.h
new file mode 100644
index 000000000000..3872f2b345d2
--- /dev/null
+++ b/arch/tile/include/asm/thread_info.h
@@ -0,0 +1,166 @@
1/*
2 * Copyright (C) 2002 David Howells (dhowells@redhat.com)
3 * Copyright 2010 Tilera Corporation. All Rights Reserved.
4 *
5 * This program is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU General Public License
7 * as published by the Free Software Foundation, version 2.
8 *
9 * This program is distributed in the hope that it will be useful, but
10 * WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, GOOD TITLE or
12 * NON INFRINGEMENT. See the GNU General Public License for
13 * more details.
14 */
15
16#ifndef _ASM_TILE_THREAD_INFO_H
17#define _ASM_TILE_THREAD_INFO_H
18
19#include <asm/processor.h>
20#include <asm/page.h>
21#ifndef __ASSEMBLY__
22
23/*
24 * Low level task data that assembly code needs immediate access to.
25 * The structure is placed at the bottom of the supervisor stack.
26 */
27struct thread_info {
28 struct task_struct *task; /* main task structure */
29 struct exec_domain *exec_domain; /* execution domain */
30 unsigned long flags; /* low level flags */
31 unsigned long status; /* thread-synchronous flags */
32 __u32 homecache_cpu; /* CPU we are homecached on */
33 __u32 cpu; /* current CPU */
34 int preempt_count; /* 0 => preemptable,
35 <0 => BUG */
36
37 mm_segment_t addr_limit; /* thread address space
38 (KERNEL_DS or USER_DS) */
39 struct restart_block restart_block;
40 struct single_step_state *step_state; /* single step state
41 (if non-zero) */
42};
43
44/*
45 * macros/functions for gaining access to the thread information structure.
46 */
47#define INIT_THREAD_INFO(tsk) \
48{ \
49 .task = &tsk, \
50 .exec_domain = &default_exec_domain, \
51 .flags = 0, \
52 .cpu = 0, \
53 .preempt_count = INIT_PREEMPT_COUNT, \
54 .addr_limit = KERNEL_DS, \
55 .restart_block = { \
56 .fn = do_no_restart_syscall, \
57 }, \
58 .step_state = NULL, \
59}
60
61#define init_thread_info (init_thread_union.thread_info)
62#define init_stack (init_thread_union.stack)
63
64#endif /* !__ASSEMBLY__ */
65
66#if PAGE_SIZE < 8192
67#define THREAD_SIZE_ORDER (13 - PAGE_SHIFT)
68#else
69#define THREAD_SIZE_ORDER (0)
70#endif
71
72#define THREAD_SIZE (PAGE_SIZE << THREAD_SIZE_ORDER)
73#define LOG2_THREAD_SIZE (PAGE_SHIFT + THREAD_SIZE_ORDER)
74
75#define STACK_WARN (THREAD_SIZE/8)
76
77#ifndef __ASSEMBLY__
78
79/* How to get the thread information struct from C. */
80register unsigned long stack_pointer __asm__("sp");
81
82#define current_thread_info() \
83 ((struct thread_info *)(stack_pointer & -THREAD_SIZE))
84
85#define __HAVE_ARCH_THREAD_INFO_ALLOCATOR
86extern struct thread_info *alloc_thread_info(struct task_struct *task);
87extern void free_thread_info(struct thread_info *info);
88
89/* Sit on a nap instruction until interrupted. */
90extern void smp_nap(void);
91
92/* Enable interrupts racelessly and nap forever: helper for cpu_idle(). */
93extern void _cpu_idle(void);
94
95/* Switch boot idle thread to a freshly-allocated stack and free old stack. */
96extern void cpu_idle_on_new_stack(struct thread_info *old_ti,
97 unsigned long new_sp,
98 unsigned long new_ss10);
99
100#else /* __ASSEMBLY__ */
101
102/* how to get the thread information struct from ASM */
103#ifdef __tilegx__
104#define GET_THREAD_INFO(reg) move reg, sp; mm reg, zero, LOG2_THREAD_SIZE, 63
105#else
106#define GET_THREAD_INFO(reg) mm reg, sp, zero, LOG2_THREAD_SIZE, 31
107#endif
108
109#endif /* !__ASSEMBLY__ */
110
111#define PREEMPT_ACTIVE 0x10000000
112
113/*
114 * Thread information flags that various assembly files may need to access.
115 * Keep flags accessed frequently in low bits, particular since it makes
116 * it easier to build constants in assembly.
117 */
118#define TIF_SIGPENDING 0 /* signal pending */
119#define TIF_NEED_RESCHED 1 /* rescheduling necessary */
120#define TIF_SINGLESTEP 2 /* restore singlestep on return to
121 user mode */
122#define TIF_ASYNC_TLB 3 /* got an async TLB fault in kernel */
123#define TIF_SYSCALL_TRACE 4 /* syscall trace active */
124#define TIF_SYSCALL_AUDIT 5 /* syscall auditing active */
125#define TIF_SECCOMP 6 /* secure computing */
126#define TIF_MEMDIE 7 /* OOM killer at work */
127
128#define _TIF_SIGPENDING (1<<TIF_SIGPENDING)
129#define _TIF_NEED_RESCHED (1<<TIF_NEED_RESCHED)
130#define _TIF_SINGLESTEP (1<<TIF_SINGLESTEP)
131#define _TIF_ASYNC_TLB (1<<TIF_ASYNC_TLB)
132#define _TIF_SYSCALL_TRACE (1<<TIF_SYSCALL_TRACE)
133#define _TIF_SYSCALL_AUDIT (1<<TIF_SYSCALL_AUDIT)
134#define _TIF_SECCOMP (1<<TIF_SECCOMP)
135#define _TIF_MEMDIE (1<<TIF_MEMDIE)
136
137/* Work to do on any return to user space. */
138#define _TIF_ALLWORK_MASK \
139 (_TIF_SIGPENDING|_TIF_NEED_RESCHED|_TIF_SINGLESTEP|_TIF_ASYNC_TLB)
140
141/*
142 * Thread-synchronous status.
143 *
144 * This is different from the flags in that nobody else
145 * ever touches our thread-synchronous status, so we don't
146 * have to worry about atomic accesses.
147 */
148#ifdef __tilegx__
149#define TS_COMPAT 0x0001 /* 32-bit compatibility mode */
150#endif
151#define TS_POLLING 0x0004 /* in idle loop but not sleeping */
152#define TS_RESTORE_SIGMASK 0x0008 /* restore signal mask in do_signal */
153
154#define tsk_is_polling(t) (task_thread_info(t)->status & TS_POLLING)
155
156#ifndef __ASSEMBLY__
157#define HAVE_SET_RESTORE_SIGMASK 1
158static inline void set_restore_sigmask(void)
159{
160 struct thread_info *ti = current_thread_info();
161 ti->status |= TS_RESTORE_SIGMASK;
162 set_bit(TIF_SIGPENDING, &ti->flags);
163}
164#endif /* !__ASSEMBLY__ */
165
166#endif /* _ASM_TILE_THREAD_INFO_H */
diff --git a/arch/tile/include/asm/timex.h b/arch/tile/include/asm/timex.h
new file mode 100644
index 000000000000..3baf5fc4c0a1
--- /dev/null
+++ b/arch/tile/include/asm/timex.h
@@ -0,0 +1,47 @@
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_TIMEX_H
16#define _ASM_TILE_TIMEX_H
17
18/*
19 * This rate should be a multiple of the possible HZ values (100, 250, 1000)
20 * and a fraction of the possible hardware timer frequencies. Our timer
21 * frequency is highly tunable but also quite precise, so for the primary use
22 * of this value (setting ACT_HZ from HZ) we just pick a value that causes
23 * ACT_HZ to be set to HZ. We make the value somewhat large just to be
24 * more robust in case someone tries out a new value of HZ.
25 */
26#define CLOCK_TICK_RATE 1000000
27
28typedef unsigned long long cycles_t;
29
30#if CHIP_HAS_SPLIT_CYCLE()
31cycles_t get_cycles(void);
32#else
33static inline cycles_t get_cycles(void)
34{
35 return __insn_mfspr(SPR_CYCLE);
36}
37#endif
38
39cycles_t get_clock_rate(void);
40
41/* Called at cpu initialization to set some low-level constants. */
42void setup_clock(void);
43
44/* Called at cpu initialization to start the tile-timer clock device. */
45void setup_tile_timer(void);
46
47#endif /* _ASM_TILE_TIMEX_H */
diff --git a/arch/tile/include/asm/tlb.h b/arch/tile/include/asm/tlb.h
new file mode 100644
index 000000000000..4a891a1a8df3
--- /dev/null
+++ b/arch/tile/include/asm/tlb.h
@@ -0,0 +1,25 @@
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_TLB_H
16#define _ASM_TILE_TLB_H
17
18#define tlb_start_vma(tlb, vma) do { } while (0)
19#define tlb_end_vma(tlb, vma) do { } while (0)
20#define __tlb_remove_tlb_entry(tlb, ptep, address) do { } while (0)
21#define tlb_flush(tlb) flush_tlb_mm((tlb)->mm)
22
23#include <asm-generic/tlb.h>
24
25#endif /* _ASM_TILE_TLB_H */
diff --git a/arch/tile/include/asm/tlbflush.h b/arch/tile/include/asm/tlbflush.h
new file mode 100644
index 000000000000..96199d214fb8
--- /dev/null
+++ b/arch/tile/include/asm/tlbflush.h
@@ -0,0 +1,128 @@
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_TLBFLUSH_H
16#define _ASM_TILE_TLBFLUSH_H
17
18#include <linux/mm.h>
19#include <linux/sched.h>
20#include <linux/smp.h>
21#include <asm/cacheflush.h>
22#include <asm/page.h>
23#include <hv/hypervisor.h>
24
25/*
26 * Rather than associating each mm with its own ASID, we just use
27 * ASIDs to allow us to lazily flush the TLB when we switch mms.
28 * This way we only have to do an actual TLB flush on mm switch
29 * every time we wrap ASIDs, not every single time we switch.
30 *
31 * FIXME: We might improve performance by keeping ASIDs around
32 * properly, though since the hypervisor direct-maps VAs to TSB
33 * entries, we're likely to have lost at least the executable page
34 * mappings by the time we switch back to the original mm.
35 */
36DECLARE_PER_CPU(int, current_asid);
37
38/* The hypervisor tells us what ASIDs are available to us. */
39extern int min_asid, max_asid;
40
41static inline unsigned long hv_page_size(const struct vm_area_struct *vma)
42{
43 return (vma->vm_flags & VM_HUGETLB) ? HPAGE_SIZE : PAGE_SIZE;
44}
45
46/* Pass as vma pointer for non-executable mapping, if no vma available. */
47#define FLUSH_NONEXEC ((const struct vm_area_struct *)-1UL)
48
49/* Flush a single user page on this cpu. */
50static inline void local_flush_tlb_page(const struct vm_area_struct *vma,
51 unsigned long addr,
52 unsigned long page_size)
53{
54 int rc = hv_flush_page(addr, page_size);
55 if (rc < 0)
56 panic("hv_flush_page(%#lx,%#lx) failed: %d",
57 addr, page_size, rc);
58 if (!vma || (vma != FLUSH_NONEXEC && (vma->vm_flags & VM_EXEC)))
59 __flush_icache();
60}
61
62/* Flush range of user pages on this cpu. */
63static inline void local_flush_tlb_pages(const struct vm_area_struct *vma,
64 unsigned long addr,
65 unsigned long page_size,
66 unsigned long len)
67{
68 int rc = hv_flush_pages(addr, page_size, len);
69 if (rc < 0)
70 panic("hv_flush_pages(%#lx,%#lx,%#lx) failed: %d",
71 addr, page_size, len, rc);
72 if (!vma || (vma != FLUSH_NONEXEC && (vma->vm_flags & VM_EXEC)))
73 __flush_icache();
74}
75
76/* Flush all user pages on this cpu. */
77static inline void local_flush_tlb(void)
78{
79 int rc = hv_flush_all(1); /* preserve global mappings */
80 if (rc < 0)
81 panic("hv_flush_all(1) failed: %d", rc);
82 __flush_icache();
83}
84
85/*
86 * Global pages have to be flushed a bit differently. Not a real
87 * performance problem because this does not happen often.
88 */
89static inline void local_flush_tlb_all(void)
90{
91 int i;
92 for (i = 0; ; ++i) {
93 HV_VirtAddrRange r = hv_inquire_virtual(i);
94 if (r.size == 0)
95 break;
96 local_flush_tlb_pages(NULL, r.start, PAGE_SIZE, r.size);
97 local_flush_tlb_pages(NULL, r.start, HPAGE_SIZE, r.size);
98 }
99}
100
101/*
102 * TLB flushing:
103 *
104 * - flush_tlb() flushes the current mm struct TLBs
105 * - flush_tlb_all() flushes all processes TLBs
106 * - flush_tlb_mm(mm) flushes the specified mm context TLB's
107 * - flush_tlb_page(vma, vmaddr) flushes one page
108 * - flush_tlb_range(vma, start, end) flushes a range of pages
109 * - flush_tlb_kernel_range(start, end) flushes a range of kernel pages
110 * - flush_tlb_others(cpumask, mm, va) flushes TLBs on other cpus
111 *
112 * Here (as in vm_area_struct), "end" means the first byte after
113 * our end address.
114 */
115
116extern void flush_tlb_all(void);
117extern void flush_tlb_kernel_range(unsigned long start, unsigned long end);
118extern void flush_tlb_current_task(void);
119extern void flush_tlb_mm(struct mm_struct *);
120extern void flush_tlb_page(const struct vm_area_struct *, unsigned long);
121extern void flush_tlb_page_mm(const struct vm_area_struct *,
122 struct mm_struct *, unsigned long);
123extern void flush_tlb_range(const struct vm_area_struct *,
124 unsigned long start, unsigned long end);
125
126#define flush_tlb() flush_tlb_current_task()
127
128#endif /* _ASM_TILE_TLBFLUSH_H */
diff --git a/arch/tile/include/asm/topology.h b/arch/tile/include/asm/topology.h
new file mode 100644
index 000000000000..343172d422a9
--- /dev/null
+++ b/arch/tile/include/asm/topology.h
@@ -0,0 +1,85 @@
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_TOPOLOGY_H
16#define _ASM_TILE_TOPOLOGY_H
17
18#ifdef CONFIG_NUMA
19
20#include <linux/cpumask.h>
21
22/* Mappings between logical cpu number and node number. */
23extern struct cpumask node_2_cpu_mask[];
24extern char cpu_2_node[];
25
26/* Returns the number of the node containing CPU 'cpu'. */
27static inline int cpu_to_node(int cpu)
28{
29 return cpu_2_node[cpu];
30}
31
32/*
33 * Returns the number of the node containing Node 'node'.
34 * This architecture is flat, so it is a pretty simple function!
35 */
36#define parent_node(node) (node)
37
38/* Returns a bitmask of CPUs on Node 'node'. */
39static inline const struct cpumask *cpumask_of_node(int node)
40{
41 return &node_2_cpu_mask[node];
42}
43
44/* For now, use numa node -1 for global allocation. */
45#define pcibus_to_node(bus) ((void)(bus), -1)
46
47/* sched_domains SD_NODE_INIT for TILE architecture */
48#define SD_NODE_INIT (struct sched_domain) { \
49 .min_interval = 8, \
50 .max_interval = 32, \
51 .busy_factor = 32, \
52 .imbalance_pct = 125, \
53 .cache_nice_tries = 1, \
54 .busy_idx = 3, \
55 .idle_idx = 1, \
56 .newidle_idx = 2, \
57 .wake_idx = 1, \
58 .flags = SD_LOAD_BALANCE \
59 | SD_BALANCE_NEWIDLE \
60 | SD_BALANCE_EXEC \
61 | SD_BALANCE_FORK \
62 | SD_WAKE_AFFINE \
63 | SD_SERIALIZE, \
64 .last_balance = jiffies, \
65 .balance_interval = 1, \
66}
67
68/* By definition, we create nodes based on online memory. */
69#define node_has_online_mem(nid) 1
70
71#endif /* CONFIG_NUMA */
72
73#include <asm-generic/topology.h>
74
75#ifdef CONFIG_SMP
76#define topology_physical_package_id(cpu) ((void)(cpu), 0)
77#define topology_core_id(cpu) (cpu)
78#define topology_core_cpumask(cpu) ((void)(cpu), cpu_online_mask)
79#define topology_thread_cpumask(cpu) cpumask_of(cpu)
80
81/* indicates that pointers to the topology struct cpumask maps are valid */
82#define arch_provides_topology_pointers yes
83#endif
84
85#endif /* _ASM_TILE_TOPOLOGY_H */
diff --git a/arch/tile/include/asm/traps.h b/arch/tile/include/asm/traps.h
new file mode 100644
index 000000000000..432a9c15c8a2
--- /dev/null
+++ b/arch/tile/include/asm/traps.h
@@ -0,0 +1,62 @@
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_TRAPS_H
16#define _ASM_TILE_TRAPS_H
17
18/* mm/fault.c */
19void do_page_fault(struct pt_regs *, int fault_num,
20 unsigned long address, unsigned long write);
21void do_async_page_fault(struct pt_regs *);
22
23#ifndef __tilegx__
24/*
25 * We return this structure in registers to avoid having to write
26 * additional save/restore code in the intvec.S caller.
27 */
28struct intvec_state {
29 void *handler;
30 unsigned long vecnum;
31 unsigned long fault_num;
32 unsigned long info;
33 unsigned long retval;
34};
35struct intvec_state do_page_fault_ics(struct pt_regs *regs, int fault_num,
36 unsigned long address,
37 unsigned long info);
38#endif
39
40/* kernel/traps.c */
41void do_trap(struct pt_regs *, int fault_num, unsigned long reason);
42void kernel_double_fault(int dummy, ulong pc, ulong lr, ulong sp, ulong r52);
43
44/* kernel/time.c */
45void do_timer_interrupt(struct pt_regs *, int fault_num);
46
47/* kernel/messaging.c */
48void hv_message_intr(struct pt_regs *, int intnum);
49
50/* kernel/irq.c */
51void tile_dev_intr(struct pt_regs *, int intnum);
52
53#ifdef CONFIG_HARDWALL
54/* kernel/hardwall.c */
55void do_hardwall_trap(struct pt_regs *, int fault_num);
56#endif
57
58/* kernel/ptrace.c */
59void do_breakpoint(struct pt_regs *, int fault_num);
60
61
62#endif /* _ASM_TILE_SYSCALLS_H */
diff --git a/arch/tile/include/asm/types.h b/arch/tile/include/asm/types.h
new file mode 100644
index 000000000000..b9e79bc580dd
--- /dev/null
+++ b/arch/tile/include/asm/types.h
@@ -0,0 +1 @@
#include <asm-generic/types.h>
diff --git a/arch/tile/include/asm/uaccess.h b/arch/tile/include/asm/uaccess.h
new file mode 100644
index 000000000000..ef34d2caa5b1
--- /dev/null
+++ b/arch/tile/include/asm/uaccess.h
@@ -0,0 +1,580 @@
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_UACCESS_H
16#define _ASM_TILE_UACCESS_H
17
18/*
19 * User space memory access functions
20 */
21#include <linux/sched.h>
22#include <linux/mm.h>
23#include <asm-generic/uaccess-unaligned.h>
24#include <asm/processor.h>
25#include <asm/page.h>
26
27#define VERIFY_READ 0
28#define VERIFY_WRITE 1
29
30/*
31 * The fs value determines whether argument validity checking should be
32 * performed or not. If get_fs() == USER_DS, checking is performed, with
33 * get_fs() == KERNEL_DS, checking is bypassed.
34 *
35 * For historical reasons, these macros are grossly misnamed.
36 */
37#define MAKE_MM_SEG(a) ((mm_segment_t) { (a) })
38
39#define KERNEL_DS MAKE_MM_SEG(-1UL)
40#define USER_DS MAKE_MM_SEG(PAGE_OFFSET)
41
42#define get_ds() (KERNEL_DS)
43#define get_fs() (current_thread_info()->addr_limit)
44#define set_fs(x) (current_thread_info()->addr_limit = (x))
45
46#define segment_eq(a, b) ((a).seg == (b).seg)
47
48#ifndef __tilegx__
49/*
50 * We could allow mapping all 16 MB at 0xfc000000, but we set up a
51 * special hack in arch_setup_additional_pages() to auto-create a mapping
52 * for the first 16 KB, and it would seem strange to have different
53 * user-accessible semantics for memory at 0xfc000000 and above 0xfc004000.
54 */
55static inline int is_arch_mappable_range(unsigned long addr,
56 unsigned long size)
57{
58 return (addr >= MEM_USER_INTRPT &&
59 addr < (MEM_USER_INTRPT + INTRPT_SIZE) &&
60 size <= (MEM_USER_INTRPT + INTRPT_SIZE) - addr);
61}
62#define is_arch_mappable_range is_arch_mappable_range
63#else
64#define is_arch_mappable_range(addr, size) 0
65#endif
66
67/*
68 * Test whether a block of memory is a valid user space address.
69 * Returns 0 if the range is valid, nonzero otherwise.
70 */
71int __range_ok(unsigned long addr, unsigned long size);
72
73/**
74 * access_ok: - Checks if a user space pointer is valid
75 * @type: Type of access: %VERIFY_READ or %VERIFY_WRITE. Note that
76 * %VERIFY_WRITE is a superset of %VERIFY_READ - if it is safe
77 * to write to a block, it is always safe to read from it.
78 * @addr: User space pointer to start of block to check
79 * @size: Size of block to check
80 *
81 * Context: User context only. This function may sleep.
82 *
83 * Checks if a pointer to a block of memory in user space is valid.
84 *
85 * Returns true (nonzero) if the memory block may be valid, false (zero)
86 * if it is definitely invalid.
87 *
88 * Note that, depending on architecture, this function probably just
89 * checks that the pointer is in the user space range - after calling
90 * this function, memory access functions may still return -EFAULT.
91 */
92#define access_ok(type, addr, size) ({ \
93 __chk_user_ptr(addr); \
94 likely(__range_ok((unsigned long)(addr), (size)) == 0); \
95})
96
97/*
98 * The exception table consists of pairs of addresses: the first is the
99 * address of an instruction that is allowed to fault, and the second is
100 * the address at which the program should continue. No registers are
101 * modified, so it is entirely up to the continuation code to figure out
102 * what to do.
103 *
104 * All the routines below use bits of fixup code that are out of line
105 * with the main instruction path. This means when everything is well,
106 * we don't even have to jump over them. Further, they do not intrude
107 * on our cache or tlb entries.
108 */
109
110struct exception_table_entry {
111 unsigned long insn, fixup;
112};
113
114extern int fixup_exception(struct pt_regs *regs);
115
116/*
117 * We return the __get_user_N function results in a structure,
118 * thus in r0 and r1. If "err" is zero, "val" is the result
119 * of the read; otherwise, "err" is -EFAULT.
120 *
121 * We rarely need 8-byte values on a 32-bit architecture, but
122 * we size the structure to accommodate. In practice, for the
123 * the smaller reads, we can zero the high word for free, and
124 * the caller will ignore it by virtue of casting anyway.
125 */
126struct __get_user {
127 unsigned long long val;
128 int err;
129};
130
131/*
132 * FIXME: we should express these as inline extended assembler, since
133 * they're fundamentally just a variable dereference and some
134 * supporting exception_table gunk. Note that (a la i386) we can
135 * extend the copy_to_user and copy_from_user routines to call into
136 * such extended assembler routines, though we will have to use a
137 * different return code in that case (1, 2, or 4, rather than -EFAULT).
138 */
139extern struct __get_user __get_user_1(const void __user *);
140extern struct __get_user __get_user_2(const void __user *);
141extern struct __get_user __get_user_4(const void __user *);
142extern struct __get_user __get_user_8(const void __user *);
143extern int __put_user_1(long, void __user *);
144extern int __put_user_2(long, void __user *);
145extern int __put_user_4(long, void __user *);
146extern int __put_user_8(long long, void __user *);
147
148/* Unimplemented routines to cause linker failures */
149extern struct __get_user __get_user_bad(void);
150extern int __put_user_bad(void);
151
152/*
153 * Careful: we have to cast the result to the type of the pointer
154 * for sign reasons.
155 */
156/**
157 * __get_user: - Get a simple variable from user space, with less checking.
158 * @x: Variable to store result.
159 * @ptr: Source address, in user space.
160 *
161 * Context: User context only. This function may sleep.
162 *
163 * This macro copies a single simple variable from user space to kernel
164 * space. It supports simple types like char and int, but not larger
165 * data types like structures or arrays.
166 *
167 * @ptr must have pointer-to-simple-variable type, and the result of
168 * dereferencing @ptr must be assignable to @x without a cast.
169 *
170 * Returns zero on success, or -EFAULT on error.
171 * On error, the variable @x is set to zero.
172 *
173 * Caller must check the pointer with access_ok() before calling this
174 * function.
175 */
176#define __get_user(x, ptr) \
177({ struct __get_user __ret; \
178 __typeof__(*(ptr)) const __user *__gu_addr = (ptr); \
179 __chk_user_ptr(__gu_addr); \
180 switch (sizeof(*(__gu_addr))) { \
181 case 1: \
182 __ret = __get_user_1(__gu_addr); \
183 break; \
184 case 2: \
185 __ret = __get_user_2(__gu_addr); \
186 break; \
187 case 4: \
188 __ret = __get_user_4(__gu_addr); \
189 break; \
190 case 8: \
191 __ret = __get_user_8(__gu_addr); \
192 break; \
193 default: \
194 __ret = __get_user_bad(); \
195 break; \
196 } \
197 (x) = (__typeof__(*__gu_addr)) (__typeof__(*__gu_addr - *__gu_addr)) \
198 __ret.val; \
199 __ret.err; \
200})
201
202/**
203 * __put_user: - Write a simple value into user space, with less checking.
204 * @x: Value to copy to user space.
205 * @ptr: Destination address, in user space.
206 *
207 * Context: User context only. This function may sleep.
208 *
209 * This macro copies a single simple value from kernel space to user
210 * space. It supports simple types like char and int, but not larger
211 * data types like structures or arrays.
212 *
213 * @ptr must have pointer-to-simple-variable type, and @x must be assignable
214 * to the result of dereferencing @ptr.
215 *
216 * Caller must check the pointer with access_ok() before calling this
217 * function.
218 *
219 * Returns zero on success, or -EFAULT on error.
220 *
221 * Implementation note: The "case 8" logic of casting to the type of
222 * the result of subtracting the value from itself is basically a way
223 * of keeping all integer types the same, but casting any pointers to
224 * ptrdiff_t, i.e. also an integer type. This way there are no
225 * questionable casts seen by the compiler on an ILP32 platform.
226 */
227#define __put_user(x, ptr) \
228({ \
229 int __pu_err = 0; \
230 __typeof__(*(ptr)) __user *__pu_addr = (ptr); \
231 typeof(*__pu_addr) __pu_val = (x); \
232 __chk_user_ptr(__pu_addr); \
233 switch (sizeof(__pu_val)) { \
234 case 1: \
235 __pu_err = __put_user_1((long)__pu_val, __pu_addr); \
236 break; \
237 case 2: \
238 __pu_err = __put_user_2((long)__pu_val, __pu_addr); \
239 break; \
240 case 4: \
241 __pu_err = __put_user_4((long)__pu_val, __pu_addr); \
242 break; \
243 case 8: \
244 __pu_err = \
245 __put_user_8((__typeof__(__pu_val - __pu_val))__pu_val,\
246 __pu_addr); \
247 break; \
248 default: \
249 __pu_err = __put_user_bad(); \
250 break; \
251 } \
252 __pu_err; \
253})
254
255/*
256 * The versions of get_user and put_user without initial underscores
257 * check the address of their arguments to make sure they are not
258 * in kernel space.
259 */
260#define put_user(x, ptr) \
261({ \
262 __typeof__(*(ptr)) __user *__Pu_addr = (ptr); \
263 access_ok(VERIFY_WRITE, (__Pu_addr), sizeof(*(__Pu_addr))) ? \
264 __put_user((x), (__Pu_addr)) : \
265 -EFAULT; \
266})
267
268#define get_user(x, ptr) \
269({ \
270 __typeof__(*(ptr)) const __user *__Gu_addr = (ptr); \
271 access_ok(VERIFY_READ, (__Gu_addr), sizeof(*(__Gu_addr))) ? \
272 __get_user((x), (__Gu_addr)) : \
273 ((x) = 0, -EFAULT); \
274})
275
276/**
277 * __copy_to_user() - copy data into user space, with less checking.
278 * @to: Destination address, in user space.
279 * @from: Source address, in kernel space.
280 * @n: Number of bytes to copy.
281 *
282 * Context: User context only. This function may sleep.
283 *
284 * Copy data from kernel space to user space. Caller must check
285 * the specified block with access_ok() before calling this function.
286 *
287 * Returns number of bytes that could not be copied.
288 * On success, this will be zero.
289 *
290 * An alternate version - __copy_to_user_inatomic() - is designed
291 * to be called from atomic context, typically bracketed by calls
292 * to pagefault_disable() and pagefault_enable().
293 */
294extern unsigned long __must_check __copy_to_user_inatomic(
295 void __user *to, const void *from, unsigned long n);
296
297static inline unsigned long __must_check
298__copy_to_user(void __user *to, const void *from, unsigned long n)
299{
300 might_fault();
301 return __copy_to_user_inatomic(to, from, n);
302}
303
304static inline unsigned long __must_check
305copy_to_user(void __user *to, const void *from, unsigned long n)
306{
307 if (access_ok(VERIFY_WRITE, to, n))
308 n = __copy_to_user(to, from, n);
309 return n;
310}
311
312/**
313 * __copy_from_user() - copy data from user space, with less checking.
314 * @to: Destination address, in kernel space.
315 * @from: Source address, in user space.
316 * @n: Number of bytes to copy.
317 *
318 * Context: User context only. This function may sleep.
319 *
320 * Copy data from user space to kernel space. Caller must check
321 * the specified block with access_ok() before calling this function.
322 *
323 * Returns number of bytes that could not be copied.
324 * On success, this will be zero.
325 *
326 * If some data could not be copied, this function will pad the copied
327 * data to the requested size using zero bytes.
328 *
329 * An alternate version - __copy_from_user_inatomic() - is designed
330 * to be called from atomic context, typically bracketed by calls
331 * to pagefault_disable() and pagefault_enable(). This version
332 * does *NOT* pad with zeros.
333 */
334extern unsigned long __must_check __copy_from_user_inatomic(
335 void *to, const void __user *from, unsigned long n);
336extern unsigned long __must_check __copy_from_user_zeroing(
337 void *to, const void __user *from, unsigned long n);
338
339static inline unsigned long __must_check
340__copy_from_user(void *to, const void __user *from, unsigned long n)
341{
342 might_fault();
343 return __copy_from_user_zeroing(to, from, n);
344}
345
346static inline unsigned long __must_check
347_copy_from_user(void *to, const void __user *from, unsigned long n)
348{
349 if (access_ok(VERIFY_READ, from, n))
350 n = __copy_from_user(to, from, n);
351 else
352 memset(to, 0, n);
353 return n;
354}
355
356#ifdef CONFIG_DEBUG_COPY_FROM_USER
357extern void copy_from_user_overflow(void)
358 __compiletime_warning("copy_from_user() size is not provably correct");
359
360static inline unsigned long __must_check copy_from_user(void *to,
361 const void __user *from,
362 unsigned long n)
363{
364 int sz = __compiletime_object_size(to);
365
366 if (likely(sz == -1 || sz >= n))
367 n = _copy_from_user(to, from, n);
368 else
369 copy_from_user_overflow();
370
371 return n;
372}
373#else
374#define copy_from_user _copy_from_user
375#endif
376
377#ifdef __tilegx__
378/**
379 * __copy_in_user() - copy data within user space, with less checking.
380 * @to: Destination address, in user space.
381 * @from: Source address, in kernel space.
382 * @n: Number of bytes to copy.
383 *
384 * Context: User context only. This function may sleep.
385 *
386 * Copy data from user space to user space. Caller must check
387 * the specified blocks with access_ok() before calling this function.
388 *
389 * Returns number of bytes that could not be copied.
390 * On success, this will be zero.
391 */
392extern unsigned long __copy_in_user_inatomic(
393 void __user *to, const void __user *from, unsigned long n);
394
395static inline unsigned long __must_check
396__copy_in_user(void __user *to, const void __user *from, unsigned long n)
397{
398 might_sleep();
399 return __copy_in_user_inatomic(to, from, n);
400}
401
402static inline unsigned long __must_check
403copy_in_user(void __user *to, const void __user *from, unsigned long n)
404{
405 if (access_ok(VERIFY_WRITE, to, n) && access_ok(VERIFY_READ, from, n))
406 n = __copy_in_user(to, from, n);
407 return n;
408}
409#endif
410
411
412/**
413 * strlen_user: - Get the size of a string in user space.
414 * @str: The string to measure.
415 *
416 * Context: User context only. This function may sleep.
417 *
418 * Get the size of a NUL-terminated string in user space.
419 *
420 * Returns the size of the string INCLUDING the terminating NUL.
421 * On exception, returns 0.
422 *
423 * If there is a limit on the length of a valid string, you may wish to
424 * consider using strnlen_user() instead.
425 */
426extern long strnlen_user_asm(const char __user *str, long n);
427static inline long __must_check strnlen_user(const char __user *str, long n)
428{
429 might_fault();
430 return strnlen_user_asm(str, n);
431}
432#define strlen_user(str) strnlen_user(str, LONG_MAX)
433
434/**
435 * strncpy_from_user: - Copy a NUL terminated string from userspace, with less checking.
436 * @dst: Destination address, in kernel space. This buffer must be at
437 * least @count bytes long.
438 * @src: Source address, in user space.
439 * @count: Maximum number of bytes to copy, including the trailing NUL.
440 *
441 * Copies a NUL-terminated string from userspace to kernel space.
442 * Caller must check the specified block with access_ok() before calling
443 * this function.
444 *
445 * On success, returns the length of the string (not including the trailing
446 * NUL).
447 *
448 * If access to userspace fails, returns -EFAULT (some data may have been
449 * copied).
450 *
451 * If @count is smaller than the length of the string, copies @count bytes
452 * and returns @count.
453 */
454extern long strncpy_from_user_asm(char *dst, const char __user *src, long);
455static inline long __must_check __strncpy_from_user(
456 char *dst, const char __user *src, long count)
457{
458 might_fault();
459 return strncpy_from_user_asm(dst, src, count);
460}
461static inline long __must_check strncpy_from_user(
462 char *dst, const char __user *src, long count)
463{
464 if (access_ok(VERIFY_READ, src, 1))
465 return __strncpy_from_user(dst, src, count);
466 return -EFAULT;
467}
468
469/**
470 * clear_user: - Zero a block of memory in user space.
471 * @mem: Destination address, in user space.
472 * @len: Number of bytes to zero.
473 *
474 * Zero a block of memory in user space.
475 *
476 * Returns number of bytes that could not be cleared.
477 * On success, this will be zero.
478 */
479extern unsigned long clear_user_asm(void __user *mem, unsigned long len);
480static inline unsigned long __must_check __clear_user(
481 void __user *mem, unsigned long len)
482{
483 might_fault();
484 return clear_user_asm(mem, len);
485}
486static inline unsigned long __must_check clear_user(
487 void __user *mem, unsigned long len)
488{
489 if (access_ok(VERIFY_WRITE, mem, len))
490 return __clear_user(mem, len);
491 return len;
492}
493
494/**
495 * flush_user: - Flush a block of memory in user space from cache.
496 * @mem: Destination address, in user space.
497 * @len: Number of bytes to flush.
498 *
499 * Returns number of bytes that could not be flushed.
500 * On success, this will be zero.
501 */
502extern unsigned long flush_user_asm(void __user *mem, unsigned long len);
503static inline unsigned long __must_check __flush_user(
504 void __user *mem, unsigned long len)
505{
506 int retval;
507
508 might_fault();
509 retval = flush_user_asm(mem, len);
510 mb_incoherent();
511 return retval;
512}
513
514static inline unsigned long __must_check flush_user(
515 void __user *mem, unsigned long len)
516{
517 if (access_ok(VERIFY_WRITE, mem, len))
518 return __flush_user(mem, len);
519 return len;
520}
521
522/**
523 * inv_user: - Invalidate a block of memory in user space from cache.
524 * @mem: Destination address, in user space.
525 * @len: Number of bytes to invalidate.
526 *
527 * Returns number of bytes that could not be invalidated.
528 * On success, this will be zero.
529 *
530 * Note that on Tile64, the "inv" operation is in fact a
531 * "flush and invalidate", so cache write-backs will occur prior
532 * to the cache being marked invalid.
533 */
534extern unsigned long inv_user_asm(void __user *mem, unsigned long len);
535static inline unsigned long __must_check __inv_user(
536 void __user *mem, unsigned long len)
537{
538 int retval;
539
540 might_fault();
541 retval = inv_user_asm(mem, len);
542 mb_incoherent();
543 return retval;
544}
545static inline unsigned long __must_check inv_user(
546 void __user *mem, unsigned long len)
547{
548 if (access_ok(VERIFY_WRITE, mem, len))
549 return __inv_user(mem, len);
550 return len;
551}
552
553/**
554 * finv_user: - Flush-inval a block of memory in user space from cache.
555 * @mem: Destination address, in user space.
556 * @len: Number of bytes to invalidate.
557 *
558 * Returns number of bytes that could not be flush-invalidated.
559 * On success, this will be zero.
560 */
561extern unsigned long finv_user_asm(void __user *mem, unsigned long len);
562static inline unsigned long __must_check __finv_user(
563 void __user *mem, unsigned long len)
564{
565 int retval;
566
567 might_fault();
568 retval = finv_user_asm(mem, len);
569 mb_incoherent();
570 return retval;
571}
572static inline unsigned long __must_check finv_user(
573 void __user *mem, unsigned long len)
574{
575 if (access_ok(VERIFY_WRITE, mem, len))
576 return __finv_user(mem, len);
577 return len;
578}
579
580#endif /* _ASM_TILE_UACCESS_H */
diff --git a/arch/tile/include/asm/ucontext.h b/arch/tile/include/asm/ucontext.h
new file mode 100644
index 000000000000..9bc07b9f30fb
--- /dev/null
+++ b/arch/tile/include/asm/ucontext.h
@@ -0,0 +1 @@
#include <asm-generic/ucontext.h>
diff --git a/arch/tile/include/asm/unaligned.h b/arch/tile/include/asm/unaligned.h
new file mode 100644
index 000000000000..137e2de5b102
--- /dev/null
+++ b/arch/tile/include/asm/unaligned.h
@@ -0,0 +1,24 @@
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_UNALIGNED_H
16#define _ASM_TILE_UNALIGNED_H
17
18#include <linux/unaligned/le_struct.h>
19#include <linux/unaligned/be_byteshift.h>
20#include <linux/unaligned/generic.h>
21#define get_unaligned __get_unaligned_le
22#define put_unaligned __put_unaligned_le
23
24#endif /* _ASM_TILE_UNALIGNED_H */
diff --git a/arch/tile/include/asm/unistd.h b/arch/tile/include/asm/unistd.h
new file mode 100644
index 000000000000..f2e3ff485333
--- /dev/null
+++ b/arch/tile/include/asm/unistd.h
@@ -0,0 +1,46 @@
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#if !defined(_ASM_TILE_UNISTD_H) || defined(__SYSCALL)
16#define _ASM_TILE_UNISTD_H
17
18#ifndef __LP64__
19/* Use the flavor of this syscall that matches the 32-bit API better. */
20#define __ARCH_WANT_SYNC_FILE_RANGE2
21#endif
22
23/* Use the standard ABI for syscalls. */
24#include <asm-generic/unistd.h>
25
26/* Additional Tilera-specific syscalls. */
27#define __NR_flush_cache (__NR_arch_specific_syscall + 1)
28__SYSCALL(__NR_flush_cache, sys_flush_cache)
29
30#ifndef __tilegx__
31/* "Fast" syscalls provide atomic support for 32-bit chips. */
32#define __NR_FAST_cmpxchg -1
33#define __NR_FAST_atomic_update -2
34#define __NR_FAST_cmpxchg64 -3
35#define __NR_cmpxchg_badaddr (__NR_arch_specific_syscall + 0)
36__SYSCALL(__NR_cmpxchg_badaddr, sys_cmpxchg_badaddr)
37#endif
38
39#ifdef __KERNEL__
40/* In compat mode, we use sys_llseek() for compat_sys_llseek(). */
41#ifdef CONFIG_COMPAT
42#define __ARCH_WANT_SYS_LLSEEK
43#endif
44#endif
45
46#endif /* _ASM_TILE_UNISTD_H */
diff --git a/arch/tile/include/asm/user.h b/arch/tile/include/asm/user.h
new file mode 100644
index 000000000000..cbc8b4d5a5ce
--- /dev/null
+++ b/arch/tile/include/asm/user.h
@@ -0,0 +1,21 @@
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
16#ifndef _ASM_TILE_USER_H
17#define _ASM_TILE_USER_H
18
19/* This header is for a.out file formats, which TILE does not support. */
20
21#endif /* _ASM_TILE_USER_H */
diff --git a/arch/tile/include/asm/xor.h b/arch/tile/include/asm/xor.h
new file mode 100644
index 000000000000..c82eb12a5b18
--- /dev/null
+++ b/arch/tile/include/asm/xor.h
@@ -0,0 +1 @@
#include <asm-generic/xor.h>
diff --git a/arch/tile/include/hv/drv_pcie_rc_intf.h b/arch/tile/include/hv/drv_pcie_rc_intf.h
new file mode 100644
index 000000000000..9bd2243bece0
--- /dev/null
+++ b/arch/tile/include/hv/drv_pcie_rc_intf.h
@@ -0,0 +1,38 @@
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/**
16 * @file drv_pcie_rc_intf.h
17 * Interface definitions for the PCIE Root Complex.
18 */
19
20#ifndef _SYS_HV_DRV_PCIE_RC_INTF_H
21#define _SYS_HV_DRV_PCIE_RC_INTF_H
22
23/** File offset for reading the interrupt base number used for PCIE legacy
24 interrupts and PLX Gen 1 requirement flag */
25#define PCIE_RC_CONFIG_MASK_OFF 0
26
27
28/**
29 * Structure used for obtaining PCIe config information, read from the PCIE
30 * subsystem /ctl file at initialization
31 */
32typedef struct pcie_rc_config
33{
34 int intr; /**< interrupt number used for downcall */
35 int plx_gen1; /**< flag for PLX Gen 1 configuration */
36} pcie_rc_config_t;
37
38#endif /* _SYS_HV_DRV_PCIE_RC_INTF_H */
diff --git a/arch/tile/include/hv/hypervisor.h b/arch/tile/include/hv/hypervisor.h
new file mode 100644
index 000000000000..9bd303a141b2
--- /dev/null
+++ b/arch/tile/include/hv/hypervisor.h
@@ -0,0 +1,2375 @@
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/**
16 * @file hypervisor.h
17 * The hypervisor's public API.
18 */
19
20#ifndef _TILE_HV_H
21#define _TILE_HV_H
22
23#include <arch/chip.h>
24
25#include <hv/pagesize.h>
26
27/* Linux builds want unsigned long constants, but assembler wants numbers */
28#ifdef __ASSEMBLER__
29/** One, for assembler */
30#define __HV_SIZE_ONE 1
31#elif !defined(__tile__) && CHIP_VA_WIDTH() > 32
32/** One, for 64-bit on host */
33#define __HV_SIZE_ONE 1ULL
34#else
35/** One, for Linux */
36#define __HV_SIZE_ONE 1UL
37#endif
38
39/** The log2 of the span of a level-1 page table, in bytes.
40 */
41#define HV_LOG2_L1_SPAN 32
42
43/** The span of a level-1 page table, in bytes.
44 */
45#define HV_L1_SPAN (__HV_SIZE_ONE << HV_LOG2_L1_SPAN)
46
47/** The size of small pages, in bytes. This value should be verified
48 * at runtime by calling hv_sysconf(HV_SYSCONF_PAGE_SIZE_SMALL).
49 */
50#define HV_PAGE_SIZE_SMALL (__HV_SIZE_ONE << HV_LOG2_PAGE_SIZE_SMALL)
51
52/** The size of large pages, in bytes. This value should be verified
53 * at runtime by calling hv_sysconf(HV_SYSCONF_PAGE_SIZE_LARGE).
54 */
55#define HV_PAGE_SIZE_LARGE (__HV_SIZE_ONE << HV_LOG2_PAGE_SIZE_LARGE)
56
57/** The log2 of the granularity at which page tables must be aligned;
58 * in other words, the CPA for a page table must have this many zero
59 * bits at the bottom of the address.
60 */
61#define HV_LOG2_PAGE_TABLE_ALIGN 11
62
63/** The granularity at which page tables must be aligned.
64 */
65#define HV_PAGE_TABLE_ALIGN (__HV_SIZE_ONE << HV_LOG2_PAGE_TABLE_ALIGN)
66
67/** Normal start of hypervisor glue in client physical memory. */
68#define HV_GLUE_START_CPA 0x10000
69
70/** This much space is reserved at HV_GLUE_START_CPA
71 * for the hypervisor glue. The client program must start at
72 * some address higher than this, and in particular the address of
73 * its text section should be equal to zero modulo HV_PAGE_SIZE_LARGE
74 * so that relative offsets to the HV glue are correct.
75 */
76#define HV_GLUE_RESERVED_SIZE 0x10000
77
78/** Each entry in the hv dispatch array takes this many bytes. */
79#define HV_DISPATCH_ENTRY_SIZE 32
80
81/** Version of the hypervisor interface defined by this file */
82#define _HV_VERSION 11
83
84/* Index into hypervisor interface dispatch code blocks.
85 *
86 * Hypervisor calls are invoked from user space by calling code
87 * at an address HV_BASE_ADDRESS + (index) * HV_DISPATCH_ENTRY_SIZE,
88 * where index is one of these enum values.
89 *
90 * Normally a supervisor is expected to produce a set of symbols
91 * starting at HV_BASE_ADDRESS that obey this convention, but a user
92 * program could call directly through function pointers if desired.
93 *
94 * These numbers are part of the binary API and will not be changed
95 * without updating HV_VERSION, which should be a rare event.
96 */
97
98/** reserved. */
99#define _HV_DISPATCH_RESERVED 0
100
101/** hv_init */
102#define HV_DISPATCH_INIT 1
103
104/** hv_install_context */
105#define HV_DISPATCH_INSTALL_CONTEXT 2
106
107/** hv_sysconf */
108#define HV_DISPATCH_SYSCONF 3
109
110/** hv_get_rtc */
111#define HV_DISPATCH_GET_RTC 4
112
113/** hv_set_rtc */
114#define HV_DISPATCH_SET_RTC 5
115
116/** hv_flush_asid */
117#define HV_DISPATCH_FLUSH_ASID 6
118
119/** hv_flush_page */
120#define HV_DISPATCH_FLUSH_PAGE 7
121
122/** hv_flush_pages */
123#define HV_DISPATCH_FLUSH_PAGES 8
124
125/** hv_restart */
126#define HV_DISPATCH_RESTART 9
127
128/** hv_halt */
129#define HV_DISPATCH_HALT 10
130
131/** hv_power_off */
132#define HV_DISPATCH_POWER_OFF 11
133
134/** hv_inquire_physical */
135#define HV_DISPATCH_INQUIRE_PHYSICAL 12
136
137/** hv_inquire_memory_controller */
138#define HV_DISPATCH_INQUIRE_MEMORY_CONTROLLER 13
139
140/** hv_inquire_virtual */
141#define HV_DISPATCH_INQUIRE_VIRTUAL 14
142
143/** hv_inquire_asid */
144#define HV_DISPATCH_INQUIRE_ASID 15
145
146/** hv_nanosleep */
147#define HV_DISPATCH_NANOSLEEP 16
148
149/** hv_console_read_if_ready */
150#define HV_DISPATCH_CONSOLE_READ_IF_READY 17
151
152/** hv_console_write */
153#define HV_DISPATCH_CONSOLE_WRITE 18
154
155/** hv_downcall_dispatch */
156#define HV_DISPATCH_DOWNCALL_DISPATCH 19
157
158/** hv_inquire_topology */
159#define HV_DISPATCH_INQUIRE_TOPOLOGY 20
160
161/** hv_fs_findfile */
162#define HV_DISPATCH_FS_FINDFILE 21
163
164/** hv_fs_fstat */
165#define HV_DISPATCH_FS_FSTAT 22
166
167/** hv_fs_pread */
168#define HV_DISPATCH_FS_PREAD 23
169
170/** hv_physaddr_read64 */
171#define HV_DISPATCH_PHYSADDR_READ64 24
172
173/** hv_physaddr_write64 */
174#define HV_DISPATCH_PHYSADDR_WRITE64 25
175
176/** hv_get_command_line */
177#define HV_DISPATCH_GET_COMMAND_LINE 26
178
179/** hv_set_caching */
180#define HV_DISPATCH_SET_CACHING 27
181
182/** hv_bzero_page */
183#define HV_DISPATCH_BZERO_PAGE 28
184
185/** hv_register_message_state */
186#define HV_DISPATCH_REGISTER_MESSAGE_STATE 29
187
188/** hv_send_message */
189#define HV_DISPATCH_SEND_MESSAGE 30
190
191/** hv_receive_message */
192#define HV_DISPATCH_RECEIVE_MESSAGE 31
193
194/** hv_inquire_context */
195#define HV_DISPATCH_INQUIRE_CONTEXT 32
196
197/** hv_start_all_tiles */
198#define HV_DISPATCH_START_ALL_TILES 33
199
200/** hv_dev_open */
201#define HV_DISPATCH_DEV_OPEN 34
202
203/** hv_dev_close */
204#define HV_DISPATCH_DEV_CLOSE 35
205
206/** hv_dev_pread */
207#define HV_DISPATCH_DEV_PREAD 36
208
209/** hv_dev_pwrite */
210#define HV_DISPATCH_DEV_PWRITE 37
211
212/** hv_dev_poll */
213#define HV_DISPATCH_DEV_POLL 38
214
215/** hv_dev_poll_cancel */
216#define HV_DISPATCH_DEV_POLL_CANCEL 39
217
218/** hv_dev_preada */
219#define HV_DISPATCH_DEV_PREADA 40
220
221/** hv_dev_pwritea */
222#define HV_DISPATCH_DEV_PWRITEA 41
223
224/** hv_flush_remote */
225#define HV_DISPATCH_FLUSH_REMOTE 42
226
227/** hv_console_putc */
228#define HV_DISPATCH_CONSOLE_PUTC 43
229
230/** hv_inquire_tiles */
231#define HV_DISPATCH_INQUIRE_TILES 44
232
233/** hv_confstr */
234#define HV_DISPATCH_CONFSTR 45
235
236/** hv_reexec */
237#define HV_DISPATCH_REEXEC 46
238
239/** hv_set_command_line */
240#define HV_DISPATCH_SET_COMMAND_LINE 47
241
242#if !CHIP_HAS_IPI()
243
244/** hv_clear_intr */
245#define HV_DISPATCH_CLEAR_INTR 48
246
247/** hv_enable_intr */
248#define HV_DISPATCH_ENABLE_INTR 49
249
250/** hv_disable_intr */
251#define HV_DISPATCH_DISABLE_INTR 50
252
253/** hv_raise_intr */
254#define HV_DISPATCH_RAISE_INTR 51
255
256/** hv_trigger_ipi */
257#define HV_DISPATCH_TRIGGER_IPI 52
258
259#endif /* !CHIP_HAS_IPI() */
260
261/** hv_store_mapping */
262#define HV_DISPATCH_STORE_MAPPING 53
263
264/** hv_inquire_realpa */
265#define HV_DISPATCH_INQUIRE_REALPA 54
266
267/** hv_flush_all */
268#define HV_DISPATCH_FLUSH_ALL 55
269
270#if CHIP_HAS_IPI()
271/** hv_get_ipi_pte */
272#define HV_DISPATCH_GET_IPI_PTE 56
273#endif
274
275/** One more than the largest dispatch value */
276#define _HV_DISPATCH_END 57
277
278
279#ifndef __ASSEMBLER__
280
281#ifdef __KERNEL__
282#include <asm/types.h>
283typedef u32 __hv32; /**< 32-bit value */
284typedef u64 __hv64; /**< 64-bit value */
285#else
286#include <stdint.h>
287typedef uint32_t __hv32; /**< 32-bit value */
288typedef uint64_t __hv64; /**< 64-bit value */
289#endif
290
291
292/** Hypervisor physical address. */
293typedef __hv64 HV_PhysAddr;
294
295#if CHIP_VA_WIDTH() > 32
296/** Hypervisor virtual address. */
297typedef __hv64 HV_VirtAddr;
298#else
299/** Hypervisor virtual address. */
300typedef __hv32 HV_VirtAddr;
301#endif /* CHIP_VA_WIDTH() > 32 */
302
303/** Hypervisor ASID. */
304typedef unsigned int HV_ASID;
305
306/** Hypervisor tile location for a memory access
307 * ("location overridden target").
308 */
309typedef unsigned int HV_LOTAR;
310
311/** Hypervisor size of a page. */
312typedef unsigned long HV_PageSize;
313
314/** A page table entry.
315 */
316typedef struct
317{
318 __hv64 val; /**< Value of PTE */
319} HV_PTE;
320
321/** Hypervisor error code. */
322typedef int HV_Errno;
323
324#endif /* !__ASSEMBLER__ */
325
326#define HV_OK 0 /**< No error */
327#define HV_EINVAL -801 /**< Invalid argument */
328#define HV_ENODEV -802 /**< No such device */
329#define HV_ENOENT -803 /**< No such file or directory */
330#define HV_EBADF -804 /**< Bad file number */
331#define HV_EFAULT -805 /**< Bad address */
332#define HV_ERECIP -806 /**< Bad recipients */
333#define HV_E2BIG -807 /**< Message too big */
334#define HV_ENOTSUP -808 /**< Service not supported */
335#define HV_EBUSY -809 /**< Device busy */
336#define HV_ENOSYS -810 /**< Invalid syscall */
337#define HV_EPERM -811 /**< No permission */
338#define HV_ENOTREADY -812 /**< Device not ready */
339#define HV_EIO -813 /**< I/O error */
340#define HV_ENOMEM -814 /**< Out of memory */
341
342#define HV_ERR_MAX -801 /**< Largest HV error code */
343#define HV_ERR_MIN -814 /**< Smallest HV error code */
344
345#ifndef __ASSEMBLER__
346
347/** Pass HV_VERSION to hv_init to request this version of the interface. */
348typedef enum { HV_VERSION = _HV_VERSION } HV_VersionNumber;
349
350/** Initializes the hypervisor.
351 *
352 * @param interface_version_number The version of the hypervisor interface
353 * that this program expects, typically HV_VERSION.
354 * @param chip_num Architecture number of the chip the client was built for.
355 * @param chip_rev_num Revision number of the chip the client was built for.
356 */
357void hv_init(HV_VersionNumber interface_version_number,
358 int chip_num, int chip_rev_num);
359
360
361/** Queries we can make for hv_sysconf().
362 *
363 * These numbers are part of the binary API and guaranteed not to change.
364 */
365typedef enum {
366 /** An invalid value; do not use. */
367 _HV_SYSCONF_RESERVED = 0,
368
369 /** The length of the glue section containing the hv_ procs, in bytes. */
370 HV_SYSCONF_GLUE_SIZE = 1,
371
372 /** The size of small pages, in bytes. */
373 HV_SYSCONF_PAGE_SIZE_SMALL = 2,
374
375 /** The size of large pages, in bytes. */
376 HV_SYSCONF_PAGE_SIZE_LARGE = 3,
377
378 /** Processor clock speed, in hertz. */
379 HV_SYSCONF_CPU_SPEED = 4,
380
381 /** Processor temperature, in degrees Kelvin. The value
382 * HV_SYSCONF_TEMP_KTOC may be subtracted from this to get degrees
383 * Celsius. If that Celsius value is HV_SYSCONF_OVERTEMP, this indicates
384 * that the temperature has hit an upper limit and is no longer being
385 * accurately tracked.
386 */
387 HV_SYSCONF_CPU_TEMP = 5,
388
389 /** Board temperature, in degrees Kelvin. The value
390 * HV_SYSCONF_TEMP_KTOC may be subtracted from this to get degrees
391 * Celsius. If that Celsius value is HV_SYSCONF_OVERTEMP, this indicates
392 * that the temperature has hit an upper limit and is no longer being
393 * accurately tracked.
394 */
395 HV_SYSCONF_BOARD_TEMP = 6
396
397} HV_SysconfQuery;
398
399/** Offset to subtract from returned Kelvin temperature to get degrees
400 Celsius. */
401#define HV_SYSCONF_TEMP_KTOC 273
402
403/** Pseudo-temperature value indicating that the temperature has
404 * pegged at its upper limit and is no longer accurate; note that this is
405 * the value after subtracting HV_SYSCONF_TEMP_KTOC. */
406#define HV_SYSCONF_OVERTEMP 999
407
408/** Query a configuration value from the hypervisor.
409 * @param query Which value is requested (HV_SYSCONF_xxx).
410 * @return The requested value, or -1 the requested value is illegal or
411 * unavailable.
412 */
413long hv_sysconf(HV_SysconfQuery query);
414
415
416/** Queries we can make for hv_confstr().
417 *
418 * These numbers are part of the binary API and guaranteed not to change.
419 */
420typedef enum {
421 /** An invalid value; do not use. */
422 _HV_CONFSTR_RESERVED = 0,
423
424 /** Board part number. */
425 HV_CONFSTR_BOARD_PART_NUM = 1,
426
427 /** Board serial number. */
428 HV_CONFSTR_BOARD_SERIAL_NUM = 2,
429
430 /** Chip serial number. */
431 HV_CONFSTR_CHIP_SERIAL_NUM = 3,
432
433 /** Board revision level. */
434 HV_CONFSTR_BOARD_REV = 4,
435
436 /** Hypervisor software version. */
437 HV_CONFSTR_HV_SW_VER = 5,
438
439 /** The name for this chip model. */
440 HV_CONFSTR_CHIP_MODEL = 6,
441
442 /** Human-readable board description. */
443 HV_CONFSTR_BOARD_DESC = 7,
444
445 /** Human-readable description of the hypervisor configuration. */
446 HV_CONFSTR_HV_CONFIG = 8,
447
448 /** Human-readable version string for the boot image (for instance,
449 * who built it and when, what configuration file was used). */
450 HV_CONFSTR_HV_CONFIG_VER = 9,
451
452 /** Mezzanine part number. */
453 HV_CONFSTR_MEZZ_PART_NUM = 10,
454
455 /** Mezzanine serial number. */
456 HV_CONFSTR_MEZZ_SERIAL_NUM = 11,
457
458 /** Mezzanine revision level. */
459 HV_CONFSTR_MEZZ_REV = 12,
460
461 /** Human-readable mezzanine description. */
462 HV_CONFSTR_MEZZ_DESC = 13,
463
464 /** Control path for the onboard network switch. */
465 HV_CONFSTR_SWITCH_CONTROL = 14,
466
467 /** Chip revision level. */
468 HV_CONFSTR_CHIP_REV = 15
469
470} HV_ConfstrQuery;
471
472/** Query a configuration string from the hypervisor.
473 *
474 * @param query Identifier for the specific string to be retrieved
475 * (HV_CONFSTR_xxx).
476 * @param buf Buffer in which to place the string.
477 * @param len Length of the buffer.
478 * @return If query is valid, then the length of the corresponding string,
479 * including the trailing null; if this is greater than len, the string
480 * was truncated. If query is invalid, HV_EINVAL. If the specified
481 * buffer is not writable by the client, HV_EFAULT.
482 */
483int hv_confstr(HV_ConfstrQuery query, HV_VirtAddr buf, int len);
484
485/** Tile coordinate */
486typedef struct
487{
488 /** X coordinate, relative to supervisor's top-left coordinate */
489 int x;
490
491 /** Y coordinate, relative to supervisor's top-left coordinate */
492 int y;
493} HV_Coord;
494
495
496#if CHIP_HAS_IPI()
497
498/** Get the PTE for sending an IPI to a particular tile.
499 *
500 * @param tile Tile which will receive the IPI.
501 * @param pl Indicates which IPI registers: 0 = IPI_0, 1 = IPI_1.
502 * @param pte Filled with resulting PTE.
503 * @result Zero if no error, non-zero for invalid parameters.
504 */
505int hv_get_ipi_pte(HV_Coord tile, int pl, HV_PTE* pte);
506
507#else /* !CHIP_HAS_IPI() */
508
509/** A set of interrupts. */
510typedef __hv32 HV_IntrMask;
511
512/** The low interrupt numbers are reserved for use by the client in
513 * delivering IPIs. Any interrupt numbers higher than this value are
514 * reserved for use by HV device drivers. */
515#define HV_MAX_IPI_INTERRUPT 7
516
517/** Enable a set of device interrupts.
518 *
519 * @param enab_mask Bitmap of interrupts to enable.
520 */
521void hv_enable_intr(HV_IntrMask enab_mask);
522
523/** Disable a set of device interrupts.
524 *
525 * @param disab_mask Bitmap of interrupts to disable.
526 */
527void hv_disable_intr(HV_IntrMask disab_mask);
528
529/** Clear a set of device interrupts.
530 *
531 * @param clear_mask Bitmap of interrupts to clear.
532 */
533void hv_clear_intr(HV_IntrMask clear_mask);
534
535/** Raise a set of device interrupts.
536 *
537 * @param raise_mask Bitmap of interrupts to raise.
538 */
539void hv_raise_intr(HV_IntrMask raise_mask);
540
541/** Trigger a one-shot interrupt on some tile
542 *
543 * @param tile Which tile to interrupt.
544 * @param interrupt Interrupt number to trigger; must be between 0 and
545 * HV_MAX_IPI_INTERRUPT.
546 * @return HV_OK on success, or a hypervisor error code.
547 */
548HV_Errno hv_trigger_ipi(HV_Coord tile, int interrupt);
549
550#endif /* !CHIP_HAS_IPI() */
551
552/** Store memory mapping in debug memory so that external debugger can read it.
553 * A maximum of 16 entries can be stored.
554 *
555 * @param va VA of memory that is mapped.
556 * @param len Length of mapped memory.
557 * @param pa PA of memory that is mapped.
558 * @return 0 on success, -1 if the maximum number of mappings is exceeded.
559 */
560int hv_store_mapping(HV_VirtAddr va, unsigned int len, HV_PhysAddr pa);
561
562/** Given a client PA and a length, return its real (HV) PA.
563 *
564 * @param cpa Client physical address.
565 * @param len Length of mapped memory.
566 * @return physical address, or -1 if cpa or len is not valid.
567 */
568HV_PhysAddr hv_inquire_realpa(HV_PhysAddr cpa, unsigned int len);
569
570/** RTC return flag for no RTC chip present.
571 */
572#define HV_RTC_NO_CHIP 0x1
573
574/** RTC return flag for low-voltage condition, indicating that battery had
575 * died and time read is unreliable.
576 */
577#define HV_RTC_LOW_VOLTAGE 0x2
578
579/** Date/Time of day */
580typedef struct {
581#if CHIP_WORD_SIZE() > 32
582 __hv64 tm_sec; /**< Seconds, 0-59 */
583 __hv64 tm_min; /**< Minutes, 0-59 */
584 __hv64 tm_hour; /**< Hours, 0-23 */
585 __hv64 tm_mday; /**< Day of month, 0-30 */
586 __hv64 tm_mon; /**< Month, 0-11 */
587 __hv64 tm_year; /**< Years since 1900, 0-199 */
588 __hv64 flags; /**< Return flags, 0 if no error */
589#else
590 __hv32 tm_sec; /**< Seconds, 0-59 */
591 __hv32 tm_min; /**< Minutes, 0-59 */
592 __hv32 tm_hour; /**< Hours, 0-23 */
593 __hv32 tm_mday; /**< Day of month, 0-30 */
594 __hv32 tm_mon; /**< Month, 0-11 */
595 __hv32 tm_year; /**< Years since 1900, 0-199 */
596 __hv32 flags; /**< Return flags, 0 if no error */
597#endif
598} HV_RTCTime;
599
600/** Read the current time-of-day clock.
601 * @return HV_RTCTime of current time (GMT).
602 */
603HV_RTCTime hv_get_rtc(void);
604
605
606/** Set the current time-of-day clock.
607 * @param time time to reset time-of-day to (GMT).
608 */
609void hv_set_rtc(HV_RTCTime time);
610
611/** Installs a context, comprising a page table and other attributes.
612 *
613 * Once this service completes, page_table will be used to translate
614 * subsequent virtual address references to physical memory.
615 *
616 * Installing a context does not cause an implicit TLB flush. Before
617 * reusing an ASID value for a different address space, the client is
618 * expected to flush old references from the TLB with hv_flush_asid().
619 * (Alternately, hv_flush_all() may be used to flush many ASIDs at once.)
620 * After invalidating a page table entry, changing its attributes, or
621 * changing its target CPA, the client is expected to flush old references
622 * from the TLB with hv_flush_page() or hv_flush_pages(). Making a
623 * previously invalid page valid does not require a flush.
624 *
625 * Specifying an invalid ASID, or an invalid CPA (client physical address)
626 * (either as page_table_pointer, or within the referenced table),
627 * or another page table data item documented as above as illegal may
628 * lead to client termination; since the validation of the table is
629 * done as needed, this may happen before the service returns, or at
630 * some later time, or never, depending upon the client's pattern of
631 * memory references. Page table entries which supply translations for
632 * invalid virtual addresses may result in client termination, or may
633 * be silently ignored. "Invalid" in this context means a value which
634 * was not provided to the client via the appropriate hv_inquire_* routine.
635 *
636 * To support changing the instruction VAs at the same time as
637 * installing the new page table, this call explicitly supports
638 * setting the "lr" register to a different address and then jumping
639 * directly to the hv_install_context() routine. In this case, the
640 * new page table does not need to contain any mapping for the
641 * hv_install_context address itself.
642 *
643 * @param page_table Root of the page table.
644 * @param access PTE providing info on how to read the page table. This
645 * value must be consistent between multiple tiles sharing a page table,
646 * and must also be consistent with any virtual mappings the client
647 * may be using to access the page table.
648 * @param asid HV_ASID the page table is to be used for.
649 * @param flags Context flags, denoting attributes or privileges of the
650 * current context (HV_CTX_xxx).
651 * @return Zero on success, or a hypervisor error code on failure.
652 */
653int hv_install_context(HV_PhysAddr page_table, HV_PTE access, HV_ASID asid,
654 __hv32 flags);
655
656#endif /* !__ASSEMBLER__ */
657
658#define HV_CTX_DIRECTIO 0x1 /**< Direct I/O requests are accepted from
659 PL0. */
660
661#ifndef __ASSEMBLER__
662
663/** Value returned from hv_inquire_context(). */
664typedef struct
665{
666 /** Physical address of page table */
667 HV_PhysAddr page_table;
668
669 /** PTE which defines access method for top of page table */
670 HV_PTE access;
671
672 /** ASID associated with this page table */
673 HV_ASID asid;
674
675 /** Context flags */
676 __hv32 flags;
677} HV_Context;
678
679/** Retrieve information about the currently installed context.
680 * @return The data passed to the last successful hv_install_context call.
681 */
682HV_Context hv_inquire_context(void);
683
684
685/** Flushes all translations associated with the named address space
686 * identifier from the TLB and any other hypervisor data structures.
687 * Translations installed with the "global" bit are not flushed.
688 *
689 * Specifying an invalid ASID may lead to client termination. "Invalid"
690 * in this context means a value which was not provided to the client
691 * via <tt>hv_inquire_asid()</tt>.
692 *
693 * @param asid HV_ASID whose entries are to be flushed.
694 * @return Zero on success, or a hypervisor error code on failure.
695*/
696int hv_flush_asid(HV_ASID asid);
697
698
699/** Flushes all translations associated with the named virtual address
700 * and page size from the TLB and other hypervisor data structures. Only
701 * pages visible to the current ASID are affected; note that this includes
702 * global pages in addition to pages specific to the current ASID.
703 *
704 * The supplied VA need not be aligned; it may be anywhere in the
705 * subject page.
706 *
707 * Specifying an invalid virtual address may lead to client termination,
708 * or may silently succeed. "Invalid" in this context means a value
709 * which was not provided to the client via hv_inquire_virtual.
710 *
711 * @param address Address of the page to flush.
712 * @param page_size Size of pages to assume.
713 * @return Zero on success, or a hypervisor error code on failure.
714 */
715int hv_flush_page(HV_VirtAddr address, HV_PageSize page_size);
716
717
718/** Flushes all translations associated with the named virtual address range
719 * and page size from the TLB and other hypervisor data structures. Only
720 * pages visible to the current ASID are affected; note that this includes
721 * global pages in addition to pages specific to the current ASID.
722 *
723 * The supplied VA need not be aligned; it may be anywhere in the
724 * subject page.
725 *
726 * Specifying an invalid virtual address may lead to client termination,
727 * or may silently succeed. "Invalid" in this context means a value
728 * which was not provided to the client via hv_inquire_virtual.
729 *
730 * @param start Address to flush.
731 * @param page_size Size of pages to assume.
732 * @param size The number of bytes to flush. Any page in the range
733 * [start, start + size) will be flushed from the TLB.
734 * @return Zero on success, or a hypervisor error code on failure.
735 */
736int hv_flush_pages(HV_VirtAddr start, HV_PageSize page_size,
737 unsigned long size);
738
739
740/** Flushes all non-global translations (if preserve_global is true),
741 * or absolutely all translations (if preserve_global is false).
742 *
743 * @param preserve_global Non-zero if we want to preserve "global" mappings.
744 * @return Zero on success, or a hypervisor error code on failure.
745*/
746int hv_flush_all(int preserve_global);
747
748
749/** Restart machine with optional restart command and optional args.
750 * @param cmd Const pointer to command to restart with, or NULL
751 * @param args Const pointer to argument string to restart with, or NULL
752 */
753void hv_restart(HV_VirtAddr cmd, HV_VirtAddr args);
754
755
756/** Halt machine. */
757void hv_halt(void);
758
759
760/** Power off machine. */
761void hv_power_off(void);
762
763
764/** Re-enter virtual-is-physical memory translation mode and restart
765 * execution at a given address.
766 * @param entry Client physical address at which to begin execution.
767 * @return A hypervisor error code on failure; if the operation is
768 * successful the call does not return.
769 */
770int hv_reexec(HV_PhysAddr entry);
771
772
773/** Chip topology */
774typedef struct
775{
776 /** Relative coordinates of the querying tile */
777 HV_Coord coord;
778
779 /** Width of the querying supervisor's tile rectangle. */
780 int width;
781
782 /** Height of the querying supervisor's tile rectangle. */
783 int height;
784
785} HV_Topology;
786
787/** Returns information about the tile coordinate system.
788 *
789 * Each supervisor is given a rectangle of tiles it potentially controls.
790 * These tiles are labeled using a relative coordinate system with (0,0) as
791 * the upper left tile regardless of their physical location on the chip.
792 *
793 * This call returns both the size of that rectangle and the position
794 * within that rectangle of the querying tile.
795 *
796 * Not all tiles within that rectangle may be available to the supervisor;
797 * to get the precise set of available tiles, you must also call
798 * hv_inquire_tiles(HV_INQ_TILES_AVAIL, ...).
799 **/
800HV_Topology hv_inquire_topology(void);
801
802/** Sets of tiles we can retrieve with hv_inquire_tiles().
803 *
804 * These numbers are part of the binary API and guaranteed not to change.
805 */
806typedef enum {
807 /** An invalid value; do not use. */
808 _HV_INQ_TILES_RESERVED = 0,
809
810 /** All available tiles within the supervisor's tile rectangle. */
811 HV_INQ_TILES_AVAIL = 1,
812
813 /** The set of tiles used for hash-for-home caching. */
814 HV_INQ_TILES_HFH_CACHE = 2,
815
816 /** The set of tiles that can be legally used as a LOTAR for a PTE. */
817 HV_INQ_TILES_LOTAR = 3
818} HV_InqTileSet;
819
820/** Returns specific information about various sets of tiles within the
821 * supervisor's tile rectangle.
822 *
823 * @param set Which set of tiles to retrieve.
824 * @param cpumask Pointer to a returned bitmask (in row-major order,
825 * supervisor-relative) of tiles. The low bit of the first word
826 * corresponds to the tile at the upper left-hand corner of the
827 * supervisor's rectangle. In order for the supervisor to know the
828 * buffer length to supply, it should first call hv_inquire_topology.
829 * @param length Number of bytes available for the returned bitmask.
830 **/
831HV_Errno hv_inquire_tiles(HV_InqTileSet set, HV_VirtAddr cpumask, int length);
832
833
834/** An identifier for a memory controller. Multiple memory controllers
835 * may be connected to one chip, and this uniquely identifies each one.
836 */
837typedef int HV_MemoryController;
838
839/** A range of physical memory. */
840typedef struct
841{
842 HV_PhysAddr start; /**< Starting address. */
843 __hv64 size; /**< Size in bytes. */
844 HV_MemoryController controller; /**< Which memory controller owns this. */
845} HV_PhysAddrRange;
846
847/** Returns information about a range of physical memory.
848 *
849 * hv_inquire_physical() returns one of the ranges of client
850 * physical addresses which are available to this client.
851 *
852 * The first range is retrieved by specifying an idx of 0, and
853 * successive ranges are returned with subsequent idx values. Ranges
854 * are ordered by increasing start address (i.e., as idx increases,
855 * so does start), do not overlap, and do not touch (i.e., the
856 * available memory is described with the fewest possible ranges).
857 *
858 * If an out-of-range idx value is specified, the returned size will be zero.
859 * A client can count the number of ranges by increasing idx until the
860 * returned size is zero. There will always be at least one valid range.
861 *
862 * Some clients might not be prepared to deal with more than one
863 * physical address range; they still ought to call this routine and
864 * issue a warning message if they're given more than one range, on the
865 * theory that whoever configured the hypervisor to provide that memory
866 * should know that it's being wasted.
867 */
868HV_PhysAddrRange hv_inquire_physical(int idx);
869
870
871/** Memory controller information. */
872typedef struct
873{
874 HV_Coord coord; /**< Relative tile coordinates of the port used by a
875 specified tile to communicate with this controller. */
876 __hv64 speed; /**< Speed of this controller in bytes per second. */
877} HV_MemoryControllerInfo;
878
879/** Returns information about a particular memory controller.
880 *
881 * hv_inquire_memory_controller(coord,idx) returns information about a
882 * particular controller. Two pieces of information are returned:
883 * - The relative coordinates of the port on the controller that the specified
884 * tile would use to contact it. The relative coordinates may lie
885 * outside the supervisor's rectangle, i.e. the controller may not
886 * be attached to a node managed by the querying node's supervisor.
887 * In particular note that x or y may be negative.
888 * - The speed of the memory controller. (This is a not-to-exceed value
889 * based on the raw hardware data rate, and may not be achievable in
890 * practice; it is provided to give clients information on the relative
891 * performance of the available controllers.)
892 *
893 * Clients should avoid calling this interface with invalid values.
894 * A client who does may be terminated.
895 * @param coord Tile for which to calculate the relative port position.
896 * @param controller Index of the controller; identical to value returned
897 * from other routines like hv_inquire_physical.
898 * @return Information about the controller.
899 */
900HV_MemoryControllerInfo hv_inquire_memory_controller(HV_Coord coord,
901 int controller);
902
903
904/** A range of virtual memory. */
905typedef struct
906{
907 HV_VirtAddr start; /**< Starting address. */
908 __hv64 size; /**< Size in bytes. */
909} HV_VirtAddrRange;
910
911/** Returns information about a range of virtual memory.
912 *
913 * hv_inquire_virtual() returns one of the ranges of client
914 * virtual addresses which are available to this client.
915 *
916 * The first range is retrieved by specifying an idx of 0, and
917 * successive ranges are returned with subsequent idx values. Ranges
918 * are ordered by increasing start address (i.e., as idx increases,
919 * so does start), do not overlap, and do not touch (i.e., the
920 * available memory is described with the fewest possible ranges).
921 *
922 * If an out-of-range idx value is specified, the returned size will be zero.
923 * A client can count the number of ranges by increasing idx until the
924 * returned size is zero. There will always be at least one valid range.
925 *
926 * Some clients may well have various virtual addresses hardwired
927 * into themselves; for instance, their instruction stream may
928 * have been compiled expecting to live at a particular address.
929 * Such clients should use this interface to verify they've been
930 * given the virtual address space they expect, and issue a (potentially
931 * fatal) warning message otherwise.
932 *
933 * Note that the returned size is a __hv64, not a __hv32, so it is
934 * possible to express a single range spanning the entire 32-bit
935 * address space.
936 */
937HV_VirtAddrRange hv_inquire_virtual(int idx);
938
939
940/** A range of ASID values. */
941typedef struct
942{
943 HV_ASID start; /**< First ASID in the range. */
944 unsigned int size; /**< Number of ASIDs. Zero for an invalid range. */
945} HV_ASIDRange;
946
947/** Returns information about a range of ASIDs.
948 *
949 * hv_inquire_asid() returns one of the ranges of address
950 * space identifiers which are available to this client.
951 *
952 * The first range is retrieved by specifying an idx of 0, and
953 * successive ranges are returned with subsequent idx values. Ranges
954 * are ordered by increasing start value (i.e., as idx increases,
955 * so does start), do not overlap, and do not touch (i.e., the
956 * available ASIDs are described with the fewest possible ranges).
957 *
958 * If an out-of-range idx value is specified, the returned size will be zero.
959 * A client can count the number of ranges by increasing idx until the
960 * returned size is zero. There will always be at least one valid range.
961 */
962HV_ASIDRange hv_inquire_asid(int idx);
963
964
965/** Waits for at least the specified number of nanoseconds then returns.
966 *
967 * @param nanosecs The number of nanoseconds to sleep.
968 */
969void hv_nanosleep(int nanosecs);
970
971
972/** Reads a character from the console without blocking.
973 *
974 * @return A value from 0-255 indicates the value successfully read.
975 * A negative value means no value was ready.
976 */
977int hv_console_read_if_ready(void);
978
979
980/** Writes a character to the console, blocking if the console is busy.
981 *
982 * This call cannot fail. If the console is broken for some reason,
983 * output will simply vanish.
984 * @param byte Character to write.
985 */
986void hv_console_putc(int byte);
987
988
989/** Writes a string to the console, blocking if the console is busy.
990 * @param bytes Pointer to characters to write.
991 * @param len Number of characters to write.
992 * @return Number of characters written, or HV_EFAULT if the buffer is invalid.
993 */
994int hv_console_write(HV_VirtAddr bytes, int len);
995
996
997/** Dispatch the next interrupt from the client downcall mechanism.
998 *
999 * The hypervisor uses downcalls to notify the client of asynchronous
1000 * events. Some of these events are hypervisor-created (like incoming
1001 * messages). Some are regular interrupts which initially occur in
1002 * the hypervisor, and are normally handled directly by the client;
1003 * when these occur in a client's interrupt critical section, they must
1004 * be delivered through the downcall mechanism.
1005 *
1006 * A downcall is initially delivered to the client as an INTCTRL_1
1007 * interrupt. Upon entry to the INTCTRL_1 vector, the client must
1008 * immediately invoke the hv_downcall_dispatch service. This service
1009 * will not return; instead it will cause one of the client's actual
1010 * downcall-handling interrupt vectors to be entered. The EX_CONTEXT
1011 * registers in the client will be set so that when the client irets,
1012 * it will return to the code which was interrupted by the INTCTRL_1
1013 * interrupt.
1014 *
1015 * Under some circumstances, the firing of INTCTRL_1 can race with
1016 * the lowering of a device interrupt. In such a case, the
1017 * hv_downcall_dispatch service may issue an iret instruction instead
1018 * of entering one of the client's actual downcall-handling interrupt
1019 * vectors. This will return execution to the location that was
1020 * interrupted by INTCTRL_1.
1021 *
1022 * Any saving of registers should be done by the actual handling
1023 * vectors; no registers should be changed by the INTCTRL_1 handler.
1024 * In particular, the client should not use a jal instruction to invoke
1025 * the hv_downcall_dispatch service, as that would overwrite the client's
1026 * lr register. Note that the hv_downcall_dispatch service may overwrite
1027 * one or more of the client's system save registers.
1028 *
1029 * The client must not modify the INTCTRL_1_STATUS SPR. The hypervisor
1030 * will set this register to cause a downcall to happen, and will clear
1031 * it when no further downcalls are pending.
1032 *
1033 * When a downcall vector is entered, the INTCTRL_1 interrupt will be
1034 * masked. When the client is done processing a downcall, and is ready
1035 * to accept another, it must unmask this interrupt; if more downcalls
1036 * are pending, this will cause the INTCTRL_1 vector to be reentered.
1037 * Currently the following interrupt vectors can be entered through a
1038 * downcall:
1039 *
1040 * INT_MESSAGE_RCV_DWNCL (hypervisor message available)
1041 * INT_DMATLB_MISS_DWNCL (DMA TLB miss)
1042 * INT_SNITLB_MISS_DWNCL (SNI TLB miss)
1043 * INT_DMATLB_ACCESS_DWNCL (DMA TLB access violation)
1044 */
1045void hv_downcall_dispatch(void);
1046
1047#endif /* !__ASSEMBLER__ */
1048
1049/** We use actual interrupt vectors which never occur (they're only there
1050 * to allow setting MPLs for related SPRs) for our downcall vectors.
1051 */
1052/** Message receive downcall interrupt vector */
1053#define INT_MESSAGE_RCV_DWNCL INT_BOOT_ACCESS
1054/** DMA TLB miss downcall interrupt vector */
1055#define INT_DMATLB_MISS_DWNCL INT_DMA_ASID
1056/** Static nework processor instruction TLB miss interrupt vector */
1057#define INT_SNITLB_MISS_DWNCL INT_SNI_ASID
1058/** DMA TLB access violation downcall interrupt vector */
1059#define INT_DMATLB_ACCESS_DWNCL INT_DMA_CPL
1060/** Device interrupt downcall interrupt vector */
1061#define INT_DEV_INTR_DWNCL INT_WORLD_ACCESS
1062
1063#ifndef __ASSEMBLER__
1064
1065/** Requests the inode for a specific full pathname.
1066 *
1067 * Performs a lookup in the hypervisor filesystem for a given filename.
1068 * Multiple calls with the same filename will always return the same inode.
1069 * If there is no such filename, HV_ENOENT is returned.
1070 * A bad filename pointer may result in HV_EFAULT instead.
1071 *
1072 * @param filename Constant pointer to name of requested file
1073 * @return Inode of requested file
1074 */
1075int hv_fs_findfile(HV_VirtAddr filename);
1076
1077
1078/** Data returned from an fstat request.
1079 * Note that this structure should be no more than 40 bytes in size so
1080 * that it can always be returned completely in registers.
1081 */
1082typedef struct
1083{
1084 int size; /**< Size of file (or HV_Errno on error) */
1085 unsigned int flags; /**< Flags (see HV_FS_FSTAT_FLAGS) */
1086} HV_FS_StatInfo;
1087
1088/** Bitmask flags for fstat request */
1089typedef enum
1090{
1091 HV_FS_ISDIR = 0x0001 /**< Is the entry a directory? */
1092} HV_FS_FSTAT_FLAGS;
1093
1094/** Get stat information on a given file inode.
1095 *
1096 * Return information on the file with the given inode.
1097 *
1098 * IF the HV_FS_ISDIR bit is set, the "file" is a directory. Reading
1099 * it will return NUL-separated filenames (no directory part) relative
1100 * to the path to the inode of the directory "file". These can be
1101 * appended to the path to the directory "file" after a forward slash
1102 * to create additional filenames. Note that it is not required
1103 * that all valid paths be decomposable into valid parent directories;
1104 * a filesystem may validly have just a few files, none of which have
1105 * HV_FS_ISDIR set. However, if clients may wish to enumerate the
1106 * files in the filesystem, it is recommended to include all the
1107 * appropriate parent directory "files" to give a consistent view.
1108 *
1109 * An invalid file inode will cause an HV_EBADF error to be returned.
1110 *
1111 * @param inode The inode number of the query
1112 * @return An HV_FS_StatInfo structure
1113 */
1114HV_FS_StatInfo hv_fs_fstat(int inode);
1115
1116
1117/** Read data from a specific hypervisor file.
1118 * On error, may return HV_EBADF for a bad inode or HV_EFAULT for a bad buf.
1119 * Reads near the end of the file will return fewer bytes than requested.
1120 * Reads at or beyond the end of a file will return zero.
1121 *
1122 * @param inode the hypervisor file to read
1123 * @param buf the buffer to read data into
1124 * @param length the number of bytes of data to read
1125 * @param offset the offset into the file to read the data from
1126 * @return number of bytes successfully read, or an HV_Errno code
1127 */
1128int hv_fs_pread(int inode, HV_VirtAddr buf, int length, int offset);
1129
1130
1131/** Read a 64-bit word from the specified physical address.
1132 * The address must be 8-byte aligned.
1133 * Specifying an invalid physical address will lead to client termination.
1134 * @param addr The physical address to read
1135 * @param access The PTE describing how to read the memory
1136 * @return The 64-bit value read from the given address
1137 */
1138unsigned long long hv_physaddr_read64(HV_PhysAddr addr, HV_PTE access);
1139
1140
1141/** Write a 64-bit word to the specified physical address.
1142 * The address must be 8-byte aligned.
1143 * Specifying an invalid physical address will lead to client termination.
1144 * @param addr The physical address to write
1145 * @param access The PTE that says how to write the memory
1146 * @param val The 64-bit value to write to the given address
1147 */
1148void hv_physaddr_write64(HV_PhysAddr addr, HV_PTE access,
1149 unsigned long long val);
1150
1151
1152/** Get the value of the command-line for the supervisor, if any.
1153 * This will not include the filename of the booted supervisor, but may
1154 * include configured-in boot arguments or the hv_restart() arguments.
1155 * If the buffer is not long enough the hypervisor will NUL the first
1156 * character of the buffer but not write any other data.
1157 * @param buf The virtual address to write the command-line string to.
1158 * @param length The length of buf, in characters.
1159 * @return The actual length of the command line, including the trailing NUL
1160 * (may be larger than "length").
1161 */
1162int hv_get_command_line(HV_VirtAddr buf, int length);
1163
1164
1165/** Set a new value for the command-line for the supervisor, which will
1166 * be returned from subsequent invocations of hv_get_command_line() on
1167 * this tile.
1168 * @param buf The virtual address to read the command-line string from.
1169 * @param length The length of buf, in characters; must be no more than
1170 * HV_COMMAND_LINE_LEN.
1171 * @return Zero if successful, or a hypervisor error code.
1172 */
1173HV_Errno hv_set_command_line(HV_VirtAddr buf, int length);
1174
1175/** Maximum size of a command line passed to hv_set_command_line(); note
1176 * that a line returned from hv_get_command_line() could be larger than
1177 * this.*/
1178#define HV_COMMAND_LINE_LEN 256
1179
1180/** Tell the hypervisor how to cache non-priority pages
1181 * (its own as well as pages explicitly represented in page tables).
1182 * Normally these will be represented as red/black pages, but
1183 * when the supervisor starts to allocate "priority" pages in the PTE
1184 * the hypervisor will need to start marking those pages as (e.g.) "red"
1185 * and non-priority pages as either "black" (if they cache-alias
1186 * with the existing priority pages) or "red/black" (if they don't).
1187 * The bitmask provides information on which parts of the cache
1188 * have been used for pinned pages so far on this tile; if (1 << N)
1189 * appears in the bitmask, that indicates that a page has been marked
1190 * "priority" whose PFN equals N, mod 8.
1191 * @param bitmask A bitmap of priority page set values
1192 */
1193void hv_set_caching(unsigned int bitmask);
1194
1195
1196/** Zero out a specified number of pages.
1197 * The va and size must both be multiples of 4096.
1198 * Caches are bypassed and memory is directly set to zero.
1199 * This API is implemented only in the magic hypervisor and is intended
1200 * to provide a performance boost to the minimal supervisor by
1201 * giving it a fast way to zero memory pages when allocating them.
1202 * @param va Virtual address where the page has been mapped
1203 * @param size Number of bytes (must be a page size multiple)
1204 */
1205void hv_bzero_page(HV_VirtAddr va, unsigned int size);
1206
1207
1208/** State object for the hypervisor messaging subsystem. */
1209typedef struct
1210{
1211#if CHIP_VA_WIDTH() > 32
1212 __hv64 opaque[2]; /**< No user-serviceable parts inside */
1213#else
1214 __hv32 opaque[2]; /**< No user-serviceable parts inside */
1215#endif
1216}
1217HV_MsgState;
1218
1219/** Register to receive incoming messages.
1220 *
1221 * This routine configures the current tile so that it can receive
1222 * incoming messages. It must be called before the client can receive
1223 * messages with the hv_receive_message routine, and must be called on
1224 * each tile which will receive messages.
1225 *
1226 * msgstate is the virtual address of a state object of type HV_MsgState.
1227 * Once the state is registered, the client must not read or write the
1228 * state object; doing so will cause undefined results.
1229 *
1230 * If this routine is called with msgstate set to 0, the client's message
1231 * state will be freed and it will no longer be able to receive messages.
1232 * Note that this may cause the loss of any as-yet-undelivered messages
1233 * for the client.
1234 *
1235 * If another client attempts to send a message to a client which has
1236 * not yet called hv_register_message_state, or which has freed its
1237 * message state, the message will not be delivered, as if the client
1238 * had insufficient buffering.
1239 *
1240 * This routine returns HV_OK if the registration was successful, and
1241 * HV_EINVAL if the supplied state object is unsuitable. Note that some
1242 * errors may not be detected during this routine, but might be detected
1243 * during a subsequent message delivery.
1244 * @param msgstate State object.
1245 **/
1246HV_Errno hv_register_message_state(HV_MsgState* msgstate);
1247
1248/** Possible message recipient states. */
1249typedef enum
1250{
1251 HV_TO_BE_SENT, /**< Not sent (not attempted, or recipient not ready) */
1252 HV_SENT, /**< Successfully sent */
1253 HV_BAD_RECIP /**< Bad recipient coordinates (permanent error) */
1254} HV_Recip_State;
1255
1256/** Message recipient. */
1257typedef struct
1258{
1259 /** X coordinate, relative to supervisor's top-left coordinate */
1260 unsigned int x:11;
1261
1262 /** Y coordinate, relative to supervisor's top-left coordinate */
1263 unsigned int y:11;
1264
1265 /** Status of this recipient */
1266 HV_Recip_State state:10;
1267} HV_Recipient;
1268
1269/** Send a message to a set of recipients.
1270 *
1271 * This routine sends a message to a set of recipients.
1272 *
1273 * recips is an array of HV_Recipient structures. Each specifies a tile,
1274 * and a message state; initially, it is expected that the state will
1275 * be set to HV_TO_BE_SENT. nrecip specifies the number of recipients
1276 * in the recips array.
1277 *
1278 * For each recipient whose state is HV_TO_BE_SENT, the hypervisor attempts
1279 * to send that tile the specified message. In order to successfully
1280 * receive the message, the receiver must be a valid tile to which the
1281 * sender has access, must not be the sending tile itself, and must have
1282 * sufficient free buffer space. (The hypervisor guarantees that each
1283 * tile which has called hv_register_message_state() will be able to
1284 * buffer one message from every other tile which can legally send to it;
1285 * more space may be provided but is not guaranteed.) If an invalid tile
1286 * is specified, the recipient's state is set to HV_BAD_RECIP; this is a
1287 * permanent delivery error. If the message is successfully delivered
1288 * to the recipient's buffer, the recipient's state is set to HV_SENT.
1289 * Otherwise, the recipient's state is unchanged. Message delivery is
1290 * synchronous; all attempts to send messages are completed before this
1291 * routine returns.
1292 *
1293 * If no permanent delivery errors were encountered, the routine returns
1294 * the number of messages successfully sent: that is, the number of
1295 * recipients whose states changed from HV_TO_BE_SENT to HV_SENT during
1296 * this operation. If any permanent delivery errors were encountered,
1297 * the routine returns HV_ERECIP. In the event of permanent delivery
1298 * errors, it may be the case that delivery was not attempted to all
1299 * recipients; if any messages were succesfully delivered, however,
1300 * recipients' state values will be updated appropriately.
1301 *
1302 * It is explicitly legal to specify a recipient structure whose state
1303 * is not HV_TO_BE_SENT; such a recipient is ignored. One suggested way
1304 * of using hv_send_message to send a message to multiple tiles is to set
1305 * up a list of recipients, and then call the routine repeatedly with the
1306 * same list, each time accumulating the number of messages successfully
1307 * sent, until all messages are sent, a permanent error is encountered,
1308 * or the desired number of attempts have been made. When used in this
1309 * way, the routine will deliver each message no more than once to each
1310 * recipient.
1311 *
1312 * Note that a message being successfully delivered to the recipient's
1313 * buffer space does not guarantee that it is received by the recipient,
1314 * either immediately or at any time in the future; the recipient might
1315 * never call hv_receive_message, or could register a different state
1316 * buffer, losing the message.
1317 *
1318 * Specifiying the same recipient more than once in the recipient list
1319 * is an error, which will not result in an error return but which may
1320 * or may not result in more than one message being delivered to the
1321 * recipient tile.
1322 *
1323 * buf and buflen specify the message to be sent. buf is a virtual address
1324 * which must be currently mapped in the client's page table; if not, the
1325 * routine returns HV_EFAULT. buflen must be greater than zero and less
1326 * than or equal to HV_MAX_MESSAGE_SIZE, and nrecip must be less than the
1327 * number of tiles to which the sender has access; if not, the routine
1328 * returns HV_EINVAL.
1329 * @param recips List of recipients.
1330 * @param nrecip Number of recipients.
1331 * @param buf Address of message data.
1332 * @param buflen Length of message data.
1333 **/
1334int hv_send_message(HV_Recipient *recips, int nrecip,
1335 HV_VirtAddr buf, int buflen);
1336
1337/** Maximum hypervisor message size, in bytes */
1338#define HV_MAX_MESSAGE_SIZE 28
1339
1340
1341/** Return value from hv_receive_message() */
1342typedef struct
1343{
1344 int msglen; /**< Message length in bytes, or an error code */
1345 __hv32 source; /**< Code identifying message sender (HV_MSG_xxx) */
1346} HV_RcvMsgInfo;
1347
1348#define HV_MSG_TILE 0x0 /**< Message source is another tile */
1349#define HV_MSG_INTR 0x1 /**< Message source is a driver interrupt */
1350
1351/** Receive a message.
1352 *
1353 * This routine retrieves a message from the client's incoming message
1354 * buffer.
1355 *
1356 * Multiple messages sent from a particular sending tile to a particular
1357 * receiving tile are received in the order that they were sent; however,
1358 * no ordering is guaranteed between messages sent by different tiles.
1359 *
1360 * Whenever the a client's message buffer is empty, the first message
1361 * subsequently received will cause the client's MESSAGE_RCV_DWNCL
1362 * interrupt vector to be invoked through the interrupt downcall mechanism
1363 * (see the description of the hv_downcall_dispatch() routine for details
1364 * on downcalls).
1365 *
1366 * Another message-available downcall will not occur until a call to
1367 * this routine is made when the message buffer is empty, and a message
1368 * subsequently arrives. Note that such a downcall could occur while
1369 * this routine is executing. If the calling code does not wish this
1370 * to happen, it is recommended that this routine be called with the
1371 * INTCTRL_1 interrupt masked, or inside an interrupt critical section.
1372 *
1373 * msgstate is the value previously passed to hv_register_message_state().
1374 * buf is the virtual address of the buffer into which the message will
1375 * be written; buflen is the length of the buffer.
1376 *
1377 * This routine returns an HV_RcvMsgInfo structure. The msglen member
1378 * of that structure is the length of the message received, zero if no
1379 * message is available, or HV_E2BIG if the message is too large for the
1380 * specified buffer. If the message is too large, it is not consumed,
1381 * and may be retrieved by a subsequent call to this routine specifying
1382 * a sufficiently large buffer. A buffer which is HV_MAX_MESSAGE_SIZE
1383 * bytes long is guaranteed to be able to receive any possible message.
1384 *
1385 * The source member of the HV_RcvMsgInfo structure describes the sender
1386 * of the message. For messages sent by another client tile via an
1387 * hv_send_message() call, this value is HV_MSG_TILE; for messages sent
1388 * as a result of a device interrupt, this value is HV_MSG_INTR.
1389 */
1390
1391HV_RcvMsgInfo hv_receive_message(HV_MsgState msgstate, HV_VirtAddr buf,
1392 int buflen);
1393
1394
1395/** Start remaining tiles owned by this supervisor. Initially, only one tile
1396 * executes the client program; after it calls this service, the other tiles
1397 * are started. This allows the initial tile to do one-time configuration
1398 * of shared data structures without having to lock them against simultaneous
1399 * access.
1400 */
1401void hv_start_all_tiles(void);
1402
1403
1404/** Open a hypervisor device.
1405 *
1406 * This service initializes an I/O device and its hypervisor driver software,
1407 * and makes it available for use. The open operation is per-device per-chip;
1408 * once it has been performed, the device handle returned may be used in other
1409 * device services calls made by any tile.
1410 *
1411 * @param name Name of the device. A base device name is just a text string
1412 * (say, "pcie"). If there is more than one instance of a device, the
1413 * base name is followed by a slash and a device number (say, "pcie/0").
1414 * Some devices may support further structure beneath those components;
1415 * most notably, devices which require control operations do so by
1416 * supporting reads and/or writes to a control device whose name
1417 * includes a trailing "/ctl" (say, "pcie/0/ctl").
1418 * @param flags Flags (HV_DEV_xxx).
1419 * @return A positive integer device handle, or a negative error code.
1420 */
1421int hv_dev_open(HV_VirtAddr name, __hv32 flags);
1422
1423
1424/** Close a hypervisor device.
1425 *
1426 * This service uninitializes an I/O device and its hypervisor driver
1427 * software, and makes it unavailable for use. The close operation is
1428 * per-device per-chip; once it has been performed, the device is no longer
1429 * available. Normally there is no need to ever call the close service.
1430 *
1431 * @param devhdl Device handle of the device to be closed.
1432 * @return Zero if the close is successful, otherwise, a negative error code.
1433 */
1434int hv_dev_close(int devhdl);
1435
1436
1437/** Read data from a hypervisor device synchronously.
1438 *
1439 * This service transfers data from a hypervisor device to a memory buffer.
1440 * When the service returns, the data has been written from the memory buffer,
1441 * and the buffer will not be further modified by the driver.
1442 *
1443 * No ordering is guaranteed between requests issued from different tiles.
1444 *
1445 * Devices may choose to support both the synchronous and asynchronous read
1446 * operations, only one of them, or neither of them.
1447 *
1448 * @param devhdl Device handle of the device to be read from.
1449 * @param flags Flags (HV_DEV_xxx).
1450 * @param va Virtual address of the target data buffer. This buffer must
1451 * be mapped in the currently installed page table; if not, HV_EFAULT
1452 * may be returned.
1453 * @param len Number of bytes to be transferred.
1454 * @param offset Driver-dependent offset. For a random-access device, this is
1455 * often a byte offset from the beginning of the device; in other cases,
1456 * like on a control device, it may have a different meaning.
1457 * @return A non-negative value if the read was at least partially successful;
1458 * otherwise, a negative error code. The precise interpretation of
1459 * the return value is driver-dependent, but many drivers will return
1460 * the number of bytes successfully transferred.
1461 */
1462int hv_dev_pread(int devhdl, __hv32 flags, HV_VirtAddr va, __hv32 len,
1463 __hv64 offset);
1464
1465#define HV_DEV_NB_EMPTY 0x1 /**< Don't block when no bytes of data can
1466 be transferred. */
1467#define HV_DEV_NB_PARTIAL 0x2 /**< Don't block when some bytes, but not all
1468 of the requested bytes, can be
1469 transferred. */
1470#define HV_DEV_NOCACHE 0x4 /**< The caller warrants that none of the
1471 cache lines which might contain data
1472 from the requested buffer are valid.
1473 Useful with asynchronous operations
1474 only. */
1475
1476#define HV_DEV_ALLFLAGS (HV_DEV_NB_EMPTY | HV_DEV_NB_PARTIAL | \
1477 HV_DEV_NOCACHE) /**< All HV_DEV_xxx flags */
1478
1479/** Write data to a hypervisor device synchronously.
1480 *
1481 * This service transfers data from a memory buffer to a hypervisor device.
1482 * When the service returns, the data has been read from the memory buffer,
1483 * and the buffer may be overwritten by the client; the data may not
1484 * necessarily have been conveyed to the actual hardware I/O interface.
1485 *
1486 * No ordering is guaranteed between requests issued from different tiles.
1487 *
1488 * Devices may choose to support both the synchronous and asynchronous write
1489 * operations, only one of them, or neither of them.
1490 *
1491 * @param devhdl Device handle of the device to be written to.
1492 * @param flags Flags (HV_DEV_xxx).
1493 * @param va Virtual address of the source data buffer. This buffer must
1494 * be mapped in the currently installed page table; if not, HV_EFAULT
1495 * may be returned.
1496 * @param len Number of bytes to be transferred.
1497 * @param offset Driver-dependent offset. For a random-access device, this is
1498 * often a byte offset from the beginning of the device; in other cases,
1499 * like on a control device, it may have a different meaning.
1500 * @return A non-negative value if the write was at least partially successful;
1501 * otherwise, a negative error code. The precise interpretation of
1502 * the return value is driver-dependent, but many drivers will return
1503 * the number of bytes successfully transferred.
1504 */
1505int hv_dev_pwrite(int devhdl, __hv32 flags, HV_VirtAddr va, __hv32 len,
1506 __hv64 offset);
1507
1508
1509/** Interrupt arguments, used in the asynchronous I/O interfaces. */
1510#if CHIP_VA_WIDTH() > 32
1511typedef __hv64 HV_IntArg;
1512#else
1513typedef __hv32 HV_IntArg;
1514#endif
1515
1516/** Interrupt messages are delivered via the mechanism as normal messages,
1517 * but have a message source of HV_DEV_INTR. The message is formatted
1518 * as an HV_IntrMsg structure.
1519 */
1520
1521typedef struct
1522{
1523 HV_IntArg intarg; /**< Interrupt argument, passed to the poll/preada/pwritea
1524 services */
1525 HV_IntArg intdata; /**< Interrupt-specific interrupt data */
1526} HV_IntrMsg;
1527
1528/** Request an interrupt message when a device condition is satisfied.
1529 *
1530 * This service requests that an interrupt message be delivered to the
1531 * requesting tile when a device becomes readable or writable, or when any
1532 * data queued to the device via previous write operations from this tile
1533 * has been actually sent out on the hardware I/O interface. Devices may
1534 * choose to support any, all, or none of the available conditions.
1535 *
1536 * If multiple conditions are specified, only one message will be
1537 * delivered. If the event mask delivered to that interrupt handler
1538 * indicates that some of the conditions have not yet occurred, the
1539 * client must issue another poll() call if it wishes to wait for those
1540 * conditions.
1541 *
1542 * Only one poll may be outstanding per device handle per tile. If more than
1543 * one tile is polling on the same device and condition, they will all be
1544 * notified when it happens. Because of this, clients may not assume that
1545 * the condition signaled is necessarily still true when they request a
1546 * subsequent service; for instance, the readable data which caused the
1547 * poll call to interrupt may have been read by another tile in the interim.
1548 *
1549 * The notification interrupt message could come directly, or via the
1550 * downcall (intctrl1) method, depending on what the tile is doing
1551 * when the condition is satisfied. Note that it is possible for the
1552 * requested interrupt to be delivered after this service is called but
1553 * before it returns.
1554 *
1555 * @param devhdl Device handle of the device to be polled.
1556 * @param events Flags denoting the events which will cause the interrupt to
1557 * be delivered (HV_DEVPOLL_xxx).
1558 * @param intarg Value which will be delivered as the intarg member of the
1559 * eventual interrupt message; the intdata member will be set to a
1560 * mask of HV_DEVPOLL_xxx values indicating which conditions have been
1561 * satisifed.
1562 * @return Zero if the interrupt was successfully scheduled; otherwise, a
1563 * negative error code.
1564 */
1565int hv_dev_poll(int devhdl, __hv32 events, HV_IntArg intarg);
1566
1567#define HV_DEVPOLL_READ 0x1 /**< Test device for readability */
1568#define HV_DEVPOLL_WRITE 0x2 /**< Test device for writability */
1569#define HV_DEVPOLL_FLUSH 0x4 /**< Test device for output drained */
1570
1571
1572/** Cancel a request for an interrupt when a device event occurs.
1573 *
1574 * This service requests that no interrupt be delivered when the events
1575 * noted in the last-issued poll() call happen. Once this service returns,
1576 * the interrupt has been canceled; however, it is possible for the interrupt
1577 * to be delivered after this service is called but before it returns.
1578 *
1579 * @param devhdl Device handle of the device on which to cancel polling.
1580 * @return Zero if the poll was successfully canceled; otherwise, a negative
1581 * error code.
1582 */
1583int hv_dev_poll_cancel(int devhdl);
1584
1585
1586/** Scatter-gather list for preada/pwritea calls. */
1587typedef struct
1588#if CHIP_VA_WIDTH() <= 32
1589__attribute__ ((packed, aligned(4)))
1590#endif
1591{
1592 HV_PhysAddr pa; /**< Client physical address of the buffer segment. */
1593 HV_PTE pte; /**< Page table entry describing the caching and location
1594 override characteristics of the buffer segment. Some
1595 drivers ignore this element and will require that
1596 the NOCACHE flag be set on their requests. */
1597 __hv32 len; /**< Length of the buffer segment. */
1598} HV_SGL;
1599
1600#define HV_SGL_MAXLEN 16 /**< Maximum number of entries in a scatter-gather
1601 list */
1602
1603/** Read data from a hypervisor device asynchronously.
1604 *
1605 * This service transfers data from a hypervisor device to a memory buffer.
1606 * When the service returns, the read has been scheduled. When the read
1607 * completes, an interrupt message will be delivered, and the buffer will
1608 * not be further modified by the driver.
1609 *
1610 * The number of possible outstanding asynchronous requests is defined by
1611 * each driver, but it is recommended that it be at least two requests
1612 * per tile per device.
1613 *
1614 * No ordering is guaranteed between synchronous and asynchronous requests,
1615 * even those issued on the same tile.
1616 *
1617 * The completion interrupt message could come directly, or via the downcall
1618 * (intctrl1) method, depending on what the tile is doing when the read
1619 * completes. Interrupts do not coalesce; one is delivered for each
1620 * asynchronous I/O request. Note that it is possible for the requested
1621 * interrupt to be delivered after this service is called but before it
1622 * returns.
1623 *
1624 * Devices may choose to support both the synchronous and asynchronous read
1625 * operations, only one of them, or neither of them.
1626 *
1627 * @param devhdl Device handle of the device to be read from.
1628 * @param flags Flags (HV_DEV_xxx).
1629 * @param sgl_len Number of elements in the scatter-gather list.
1630 * @param sgl Scatter-gather list describing the memory to which data will be
1631 * written.
1632 * @param offset Driver-dependent offset. For a random-access device, this is
1633 * often a byte offset from the beginning of the device; in other cases,
1634 * like on a control device, it may have a different meaning.
1635 * @param intarg Value which will be delivered as the intarg member of the
1636 * eventual interrupt message; the intdata member will be set to the
1637 * normal return value from the read request.
1638 * @return Zero if the read was successfully scheduled; otherwise, a negative
1639 * error code. Note that some drivers may choose to pre-validate
1640 * their arguments, and may thus detect certain device error
1641 * conditions at this time rather than when the completion notification
1642 * occurs, but this is not required.
1643 */
1644int hv_dev_preada(int devhdl, __hv32 flags, __hv32 sgl_len,
1645 HV_SGL sgl[/* sgl_len */], __hv64 offset, HV_IntArg intarg);
1646
1647
1648/** Write data to a hypervisor device asynchronously.
1649 *
1650 * This service transfers data from a memory buffer to a hypervisor
1651 * device. When the service returns, the write has been scheduled.
1652 * When the write completes, an interrupt message will be delivered,
1653 * and the buffer may be overwritten by the client; the data may not
1654 * necessarily have been conveyed to the actual hardware I/O interface.
1655 *
1656 * The number of possible outstanding asynchronous requests is defined by
1657 * each driver, but it is recommended that it be at least two requests
1658 * per tile per device.
1659 *
1660 * No ordering is guaranteed between synchronous and asynchronous requests,
1661 * even those issued on the same tile.
1662 *
1663 * The completion interrupt message could come directly, or via the downcall
1664 * (intctrl1) method, depending on what the tile is doing when the read
1665 * completes. Interrupts do not coalesce; one is delivered for each
1666 * asynchronous I/O request. Note that it is possible for the requested
1667 * interrupt to be delivered after this service is called but before it
1668 * returns.
1669 *
1670 * Devices may choose to support both the synchronous and asynchronous write
1671 * operations, only one of them, or neither of them.
1672 *
1673 * @param devhdl Device handle of the device to be read from.
1674 * @param flags Flags (HV_DEV_xxx).
1675 * @param sgl_len Number of elements in the scatter-gather list.
1676 * @param sgl Scatter-gather list describing the memory from which data will be
1677 * read.
1678 * @param offset Driver-dependent offset. For a random-access device, this is
1679 * often a byte offset from the beginning of the device; in other cases,
1680 * like on a control device, it may have a different meaning.
1681 * @param intarg Value which will be delivered as the intarg member of the
1682 * eventual interrupt message; the intdata member will be set to the
1683 * normal return value from the write request.
1684 * @return Zero if the write was successfully scheduled; otherwise, a negative
1685 * error code. Note that some drivers may choose to pre-validate
1686 * their arguments, and may thus detect certain device error
1687 * conditions at this time rather than when the completion notification
1688 * occurs, but this is not required.
1689 */
1690int hv_dev_pwritea(int devhdl, __hv32 flags, __hv32 sgl_len,
1691 HV_SGL sgl[/* sgl_len */], __hv64 offset, HV_IntArg intarg);
1692
1693
1694/** Define a pair of tile and ASID to identify a user process context. */
1695typedef struct
1696{
1697 /** X coordinate, relative to supervisor's top-left coordinate */
1698 unsigned int x:11;
1699
1700 /** Y coordinate, relative to supervisor's top-left coordinate */
1701 unsigned int y:11;
1702
1703 /** ASID of the process on this x,y tile */
1704 HV_ASID asid:10;
1705} HV_Remote_ASID;
1706
1707/** Flush cache and/or TLB state on remote tiles.
1708 *
1709 * @param cache_pa Client physical address to flush from cache (ignored if
1710 * the length encoded in cache_control is zero, or if
1711 * HV_FLUSH_EVICT_L2 is set, or if cache_cpumask is NULL).
1712 * @param cache_control This argument allows you to specify a length of
1713 * physical address space to flush (maximum HV_FLUSH_MAX_CACHE_LEN).
1714 * You can "or" in HV_FLUSH_EVICT_L2 to flush the whole L2 cache.
1715 * You can "or" in HV_FLUSH_EVICT_L1I to flush the whole L1I cache.
1716 * HV_FLUSH_ALL flushes all caches.
1717 * @param cache_cpumask Bitmask (in row-major order, supervisor-relative) of
1718 * tile indices to perform cache flush on. The low bit of the first
1719 * word corresponds to the tile at the upper left-hand corner of the
1720 * supervisor's rectangle. If passed as a NULL pointer, equivalent
1721 * to an empty bitmask. On chips which support hash-for-home caching,
1722 * if passed as -1, equivalent to a mask containing tiles which could
1723 * be doing hash-for-home caching.
1724 * @param tlb_va Virtual address to flush from TLB (ignored if
1725 * tlb_length is zero or tlb_cpumask is NULL).
1726 * @param tlb_length Number of bytes of data to flush from the TLB.
1727 * @param tlb_pgsize Page size to use for TLB flushes.
1728 * tlb_va and tlb_length need not be aligned to this size.
1729 * @param tlb_cpumask Bitmask for tlb flush, like cache_cpumask.
1730 * If passed as a NULL pointer, equivalent to an empty bitmask.
1731 * @param asids Pointer to an HV_Remote_ASID array of tile/ASID pairs to flush.
1732 * @param asidcount Number of HV_Remote_ASID entries in asids[].
1733 * @return Zero for success, or else HV_EINVAL or HV_EFAULT for errors that
1734 * are detected while parsing the arguments.
1735 */
1736int hv_flush_remote(HV_PhysAddr cache_pa, unsigned long cache_control,
1737 unsigned long* cache_cpumask,
1738 HV_VirtAddr tlb_va, unsigned long tlb_length,
1739 unsigned long tlb_pgsize, unsigned long* tlb_cpumask,
1740 HV_Remote_ASID* asids, int asidcount);
1741
1742/** Include in cache_control to ensure a flush of the entire L2. */
1743#define HV_FLUSH_EVICT_L2 (1UL << 31)
1744
1745/** Include in cache_control to ensure a flush of the entire L1I. */
1746#define HV_FLUSH_EVICT_L1I (1UL << 30)
1747
1748/** Maximum legal size to use for the "length" component of cache_control. */
1749#define HV_FLUSH_MAX_CACHE_LEN ((1UL << 30) - 1)
1750
1751/** Use for cache_control to ensure a flush of all caches. */
1752#define HV_FLUSH_ALL -1UL
1753
1754#else /* __ASSEMBLER__ */
1755
1756/** Include in cache_control to ensure a flush of the entire L2. */
1757#define HV_FLUSH_EVICT_L2 (1 << 31)
1758
1759/** Include in cache_control to ensure a flush of the entire L1I. */
1760#define HV_FLUSH_EVICT_L1I (1 << 30)
1761
1762/** Maximum legal size to use for the "length" component of cache_control. */
1763#define HV_FLUSH_MAX_CACHE_LEN ((1 << 30) - 1)
1764
1765/** Use for cache_control to ensure a flush of all caches. */
1766#define HV_FLUSH_ALL -1
1767
1768#endif /* __ASSEMBLER__ */
1769
1770#ifndef __ASSEMBLER__
1771
1772/** Return a 64-bit value corresponding to the PTE if needed */
1773#define hv_pte_val(pte) ((pte).val)
1774
1775/** Cast a 64-bit value to an HV_PTE */
1776#define hv_pte(val) ((HV_PTE) { val })
1777
1778#endif /* !__ASSEMBLER__ */
1779
1780
1781/** Bits in the size of an HV_PTE */
1782#define HV_LOG2_PTE_SIZE 3
1783
1784/** Size of an HV_PTE */
1785#define HV_PTE_SIZE (1 << HV_LOG2_PTE_SIZE)
1786
1787
1788/* Bits in HV_PTE's low word. */
1789#define HV_PTE_INDEX_PRESENT 0 /**< PTE is valid */
1790#define HV_PTE_INDEX_MIGRATING 1 /**< Page is migrating */
1791#define HV_PTE_INDEX_CLIENT0 2 /**< Page client state 0 */
1792#define HV_PTE_INDEX_CLIENT1 3 /**< Page client state 1 */
1793#define HV_PTE_INDEX_NC 4 /**< L1$/L2$ incoherent with L3$ */
1794#define HV_PTE_INDEX_NO_ALLOC_L1 5 /**< Page is uncached in local L1$ */
1795#define HV_PTE_INDEX_NO_ALLOC_L2 6 /**< Page is uncached in local L2$ */
1796#define HV_PTE_INDEX_CACHED_PRIORITY 7 /**< Page is priority cached */
1797#define HV_PTE_INDEX_PAGE 8 /**< PTE describes a page */
1798#define HV_PTE_INDEX_GLOBAL 9 /**< Page is global */
1799#define HV_PTE_INDEX_USER 10 /**< Page is user-accessible */
1800#define HV_PTE_INDEX_ACCESSED 11 /**< Page has been accessed */
1801#define HV_PTE_INDEX_DIRTY 12 /**< Page has been written */
1802 /* Bits 13-15 are reserved for
1803 future use. */
1804#define HV_PTE_INDEX_MODE 16 /**< Page mode; see HV_PTE_MODE_xxx */
1805#define HV_PTE_MODE_BITS 3 /**< Number of bits in mode */
1806 /* Bit 19 is reserved for
1807 future use. */
1808#define HV_PTE_INDEX_LOTAR 20 /**< Page's LOTAR; must be high bits
1809 of word */
1810#define HV_PTE_LOTAR_BITS 12 /**< Number of bits in a LOTAR */
1811
1812/* Bits in HV_PTE's high word. */
1813#define HV_PTE_INDEX_READABLE 32 /**< Page is readable */
1814#define HV_PTE_INDEX_WRITABLE 33 /**< Page is writable */
1815#define HV_PTE_INDEX_EXECUTABLE 34 /**< Page is executable */
1816#define HV_PTE_INDEX_PTFN 35 /**< Page's PTFN; must be high bits
1817 of word */
1818#define HV_PTE_PTFN_BITS 29 /**< Number of bits in a PTFN */
1819
1820/** Position of the PFN field within the PTE (subset of the PTFN). */
1821#define HV_PTE_INDEX_PFN (HV_PTE_INDEX_PTFN + (HV_LOG2_PAGE_SIZE_SMALL - \
1822 HV_LOG2_PAGE_TABLE_ALIGN))
1823
1824/** Length of the PFN field within the PTE (subset of the PTFN). */
1825#define HV_PTE_INDEX_PFN_BITS (HV_PTE_INDEX_PTFN_BITS - \
1826 (HV_LOG2_PAGE_SIZE_SMALL - \
1827 HV_LOG2_PAGE_TABLE_ALIGN))
1828
1829/*
1830 * Legal values for the PTE's mode field
1831 */
1832/** Data is not resident in any caches; loads and stores access memory
1833 * directly.
1834 */
1835#define HV_PTE_MODE_UNCACHED 1
1836
1837/** Data is resident in the tile's local L1 and/or L2 caches; if a load
1838 * or store misses there, it goes to memory.
1839 *
1840 * The copy in the local L1$/L2$ is not invalidated when the copy in
1841 * memory is changed.
1842 */
1843#define HV_PTE_MODE_CACHE_NO_L3 2
1844
1845/** Data is resident in the tile's local L1 and/or L2 caches. If a load
1846 * or store misses there, it goes to an L3 cache in a designated tile;
1847 * if it misses there, it goes to memory.
1848 *
1849 * If the NC bit is not set, the copy in the local L1$/L2$ is invalidated
1850 * when the copy in the remote L3$ is changed. Otherwise, such
1851 * invalidation will not occur.
1852 *
1853 * Chips for which CHIP_HAS_COHERENT_LOCAL_CACHE() is 0 do not support
1854 * invalidation from an L3$ to another tile's L1$/L2$. If the NC bit is
1855 * clear on such a chip, no copy is kept in the local L1$/L2$ in this mode.
1856 */
1857#define HV_PTE_MODE_CACHE_TILE_L3 3
1858
1859/** Data is resident in the tile's local L1 and/or L2 caches. If a load
1860 * or store misses there, it goes to an L3 cache in one of a set of
1861 * designated tiles; if it misses there, it goes to memory. Which tile
1862 * is chosen from the set depends upon a hash function applied to the
1863 * physical address. This mode is not supported on chips for which
1864 * CHIP_HAS_CBOX_HOME_MAP() is 0.
1865 *
1866 * If the NC bit is not set, the copy in the local L1$/L2$ is invalidated
1867 * when the copy in the remote L3$ is changed. Otherwise, such
1868 * invalidation will not occur.
1869 *
1870 * Chips for which CHIP_HAS_COHERENT_LOCAL_CACHE() is 0 do not support
1871 * invalidation from an L3$ to another tile's L1$/L2$. If the NC bit is
1872 * clear on such a chip, no copy is kept in the local L1$/L2$ in this mode.
1873 */
1874#define HV_PTE_MODE_CACHE_HASH_L3 4
1875
1876/** Data is not resident in memory; accesses are instead made to an I/O
1877 * device, whose tile coordinates are given by the PTE's LOTAR field.
1878 * This mode is only supported on chips for which CHIP_HAS_MMIO() is 1.
1879 * The EXECUTABLE bit may not be set in an MMIO PTE.
1880 */
1881#define HV_PTE_MODE_MMIO 5
1882
1883
1884/* C wants 1ULL so it is typed as __hv64, but the assembler needs just numbers.
1885 * The assembler can't handle shifts greater than 31, but treats them
1886 * as shifts mod 32, so assembler code must be aware of which word
1887 * the bit belongs in when using these macros.
1888 */
1889#ifdef __ASSEMBLER__
1890#define __HV_PTE_ONE 1 /**< One, for assembler */
1891#else
1892#define __HV_PTE_ONE 1ULL /**< One, for C */
1893#endif
1894
1895/** Is this PTE present?
1896 *
1897 * If this bit is set, this PTE represents a valid translation or level-2
1898 * page table pointer. Otherwise, the page table does not contain a
1899 * translation for the subject virtual pages.
1900 *
1901 * If this bit is not set, the other bits in the PTE are not
1902 * interpreted by the hypervisor, and may contain any value.
1903 */
1904#define HV_PTE_PRESENT (__HV_PTE_ONE << HV_PTE_INDEX_PRESENT)
1905
1906/** Does this PTE map a page?
1907 *
1908 * If this bit is set in the level-1 page table, the entry should be
1909 * interpreted as a level-2 page table entry mapping a large page.
1910 *
1911 * This bit should not be modified by the client while PRESENT is set, as
1912 * doing so may race with the hypervisor's update of ACCESSED and DIRTY bits.
1913 *
1914 * In a level-2 page table, this bit is ignored and must be zero.
1915 */
1916#define HV_PTE_PAGE (__HV_PTE_ONE << HV_PTE_INDEX_PAGE)
1917
1918/** Is this a global (non-ASID) mapping?
1919 *
1920 * If this bit is set, the translations established by this PTE will
1921 * not be flushed from the TLB by the hv_flush_asid() service; they
1922 * will be flushed by the hv_flush_page() or hv_flush_pages() services.
1923 *
1924 * Setting this bit for translations which are identical in all page
1925 * tables (for instance, code and data belonging to a client OS) can
1926 * be very beneficial, as it will reduce the number of TLB misses.
1927 * Note that, while it is not an error which will be detected by the
1928 * hypervisor, it is an extremely bad idea to set this bit for
1929 * translations which are _not_ identical in all page tables.
1930 *
1931 * This bit should not be modified by the client while PRESENT is set, as
1932 * doing so may race with the hypervisor's update of ACCESSED and DIRTY bits.
1933 *
1934 * This bit is ignored in level-1 PTEs unless the Page bit is set.
1935 */
1936#define HV_PTE_GLOBAL (__HV_PTE_ONE << HV_PTE_INDEX_GLOBAL)
1937
1938/** Is this mapping accessible to users?
1939 *
1940 * If this bit is set, code running at any PL will be permitted to
1941 * access the virtual addresses mapped by this PTE. Otherwise, only
1942 * code running at PL 1 or above will be allowed to do so.
1943 *
1944 * This bit should not be modified by the client while PRESENT is set, as
1945 * doing so may race with the hypervisor's update of ACCESSED and DIRTY bits.
1946 *
1947 * This bit is ignored in level-1 PTEs unless the Page bit is set.
1948 */
1949#define HV_PTE_USER (__HV_PTE_ONE << HV_PTE_INDEX_USER)
1950
1951/** Has this mapping been accessed?
1952 *
1953 * This bit is set by the hypervisor when the memory described by the
1954 * translation is accessed for the first time. It is never cleared by
1955 * the hypervisor, but may be cleared by the client. After the bit
1956 * has been cleared, subsequent references are not guaranteed to set
1957 * it again until the translation has been flushed from the TLB.
1958 *
1959 * This bit is ignored in level-1 PTEs unless the Page bit is set.
1960 */
1961#define HV_PTE_ACCESSED (__HV_PTE_ONE << HV_PTE_INDEX_ACCESSED)
1962
1963/** Is this mapping dirty?
1964 *
1965 * This bit is set by the hypervisor when the memory described by the
1966 * translation is written for the first time. It is never cleared by
1967 * the hypervisor, but may be cleared by the client. After the bit
1968 * has been cleared, subsequent references are not guaranteed to set
1969 * it again until the translation has been flushed from the TLB.
1970 *
1971 * This bit is ignored in level-1 PTEs unless the Page bit is set.
1972 */
1973#define HV_PTE_DIRTY (__HV_PTE_ONE << HV_PTE_INDEX_DIRTY)
1974
1975/** Migrating bit in PTE.
1976 *
1977 * This bit is guaranteed not to be inspected or modified by the
1978 * hypervisor. The name is indicative of the suggested use by the client
1979 * to tag pages whose L3 cache is being migrated from one cpu to another.
1980 */
1981#define HV_PTE_MIGRATING (__HV_PTE_ONE << HV_PTE_INDEX_MIGRATING)
1982
1983/** Client-private bit in PTE.
1984 *
1985 * This bit is guaranteed not to be inspected or modified by the
1986 * hypervisor.
1987 */
1988#define HV_PTE_CLIENT0 (__HV_PTE_ONE << HV_PTE_INDEX_CLIENT0)
1989
1990/** Client-private bit in PTE.
1991 *
1992 * This bit is guaranteed not to be inspected or modified by the
1993 * hypervisor.
1994 */
1995#define HV_PTE_CLIENT1 (__HV_PTE_ONE << HV_PTE_INDEX_CLIENT1)
1996
1997/** Non-coherent (NC) bit in PTE.
1998 *
1999 * If this bit is set, the mapping that is set up will be non-coherent
2000 * (also known as non-inclusive). This means that changes to the L3
2001 * cache will not cause a local copy to be invalidated. It is generally
2002 * recommended only for read-only mappings.
2003 *
2004 * In level-1 PTEs, if the Page bit is clear, this bit determines how the
2005 * level-2 page table is accessed.
2006 */
2007#define HV_PTE_NC (__HV_PTE_ONE << HV_PTE_INDEX_NC)
2008
2009/** Is this page prevented from filling the L1$?
2010 *
2011 * If this bit is set, the page described by the PTE will not be cached
2012 * the local cpu's L1 cache.
2013 *
2014 * If CHIP_HAS_NC_AND_NOALLOC_BITS() is not true in <chip.h> for this chip,
2015 * it is illegal to use this attribute, and may cause client termination.
2016 *
2017 * In level-1 PTEs, if the Page bit is clear, this bit
2018 * determines how the level-2 page table is accessed.
2019 */
2020#define HV_PTE_NO_ALLOC_L1 (__HV_PTE_ONE << HV_PTE_INDEX_NO_ALLOC_L1)
2021
2022/** Is this page prevented from filling the L2$?
2023 *
2024 * If this bit is set, the page described by the PTE will not be cached
2025 * the local cpu's L2 cache.
2026 *
2027 * If CHIP_HAS_NC_AND_NOALLOC_BITS() is not true in <chip.h> for this chip,
2028 * it is illegal to use this attribute, and may cause client termination.
2029 *
2030 * In level-1 PTEs, if the Page bit is clear, this bit determines how the
2031 * level-2 page table is accessed.
2032 */
2033#define HV_PTE_NO_ALLOC_L2 (__HV_PTE_ONE << HV_PTE_INDEX_NO_ALLOC_L2)
2034
2035/** Is this a priority page?
2036 *
2037 * If this bit is set, the page described by the PTE will be given
2038 * priority in the cache. Normally this translates into allowing the
2039 * page to use only the "red" half of the cache. The client may wish to
2040 * then use the hv_set_caching service to specify that other pages which
2041 * alias this page will use only the "black" half of the cache.
2042 *
2043 * If the Cached Priority bit is clear, the hypervisor uses the
2044 * current hv_set_caching() value to choose how to cache the page.
2045 *
2046 * It is illegal to set the Cached Priority bit if the Non-Cached bit
2047 * is set and the Cached Remotely bit is clear, i.e. if requests to
2048 * the page map directly to memory.
2049 *
2050 * This bit is ignored in level-1 PTEs unless the Page bit is set.
2051 */
2052#define HV_PTE_CACHED_PRIORITY (__HV_PTE_ONE << \
2053 HV_PTE_INDEX_CACHED_PRIORITY)
2054
2055/** Is this a readable mapping?
2056 *
2057 * If this bit is set, code will be permitted to read from (e.g.,
2058 * issue load instructions against) the virtual addresses mapped by
2059 * this PTE.
2060 *
2061 * It is illegal for this bit to be clear if the Writable bit is set.
2062 *
2063 * This bit is ignored in level-1 PTEs unless the Page bit is set.
2064 */
2065#define HV_PTE_READABLE (__HV_PTE_ONE << HV_PTE_INDEX_READABLE)
2066
2067/** Is this a writable mapping?
2068 *
2069 * If this bit is set, code will be permitted to write to (e.g., issue
2070 * store instructions against) the virtual addresses mapped by this
2071 * PTE.
2072 *
2073 * This bit is ignored in level-1 PTEs unless the Page bit is set.
2074 */
2075#define HV_PTE_WRITABLE (__HV_PTE_ONE << HV_PTE_INDEX_WRITABLE)
2076
2077/** Is this an executable mapping?
2078 *
2079 * If this bit is set, code will be permitted to execute from
2080 * (e.g., jump to) the virtual addresses mapped by this PTE.
2081 *
2082 * This bit applies to any processor on the tile, if there are more
2083 * than one.
2084 *
2085 * This bit is ignored in level-1 PTEs unless the Page bit is set.
2086 */
2087#define HV_PTE_EXECUTABLE (__HV_PTE_ONE << HV_PTE_INDEX_EXECUTABLE)
2088
2089/** The width of a LOTAR's x or y bitfield. */
2090#define HV_LOTAR_WIDTH 11
2091
2092/** Converts an x,y pair to a LOTAR value. */
2093#define HV_XY_TO_LOTAR(x, y) ((HV_LOTAR)(((x) << HV_LOTAR_WIDTH) | (y)))
2094
2095/** Extracts the X component of a lotar. */
2096#define HV_LOTAR_X(lotar) ((lotar) >> HV_LOTAR_WIDTH)
2097
2098/** Extracts the Y component of a lotar. */
2099#define HV_LOTAR_Y(lotar) ((lotar) & ((1 << HV_LOTAR_WIDTH) - 1))
2100
2101#ifndef __ASSEMBLER__
2102
2103/** Define accessor functions for a PTE bit. */
2104#define _HV_BIT(name, bit) \
2105static __inline int \
2106hv_pte_get_##name(HV_PTE pte) \
2107{ \
2108 return (pte.val >> HV_PTE_INDEX_##bit) & 1; \
2109} \
2110 \
2111static __inline HV_PTE \
2112hv_pte_set_##name(HV_PTE pte) \
2113{ \
2114 pte.val |= 1ULL << HV_PTE_INDEX_##bit; \
2115 return pte; \
2116} \
2117 \
2118static __inline HV_PTE \
2119hv_pte_clear_##name(HV_PTE pte) \
2120{ \
2121 pte.val &= ~(1ULL << HV_PTE_INDEX_##bit); \
2122 return pte; \
2123}
2124
2125/* Generate accessors to get, set, and clear various PTE flags.
2126 */
2127_HV_BIT(present, PRESENT)
2128_HV_BIT(page, PAGE)
2129_HV_BIT(client0, CLIENT0)
2130_HV_BIT(client1, CLIENT1)
2131_HV_BIT(migrating, MIGRATING)
2132_HV_BIT(nc, NC)
2133_HV_BIT(readable, READABLE)
2134_HV_BIT(writable, WRITABLE)
2135_HV_BIT(executable, EXECUTABLE)
2136_HV_BIT(accessed, ACCESSED)
2137_HV_BIT(dirty, DIRTY)
2138_HV_BIT(no_alloc_l1, NO_ALLOC_L1)
2139_HV_BIT(no_alloc_l2, NO_ALLOC_L2)
2140_HV_BIT(cached_priority, CACHED_PRIORITY)
2141_HV_BIT(global, GLOBAL)
2142_HV_BIT(user, USER)
2143
2144#undef _HV_BIT
2145
2146/** Get the page mode from the PTE.
2147 *
2148 * This field generally determines whether and how accesses to the page
2149 * are cached; the HV_PTE_MODE_xxx symbols define the legal values for the
2150 * page mode. The NC, NO_ALLOC_L1, and NO_ALLOC_L2 bits modify this
2151 * general policy.
2152 */
2153static __inline unsigned int
2154hv_pte_get_mode(const HV_PTE pte)
2155{
2156 return (((__hv32) pte.val) >> HV_PTE_INDEX_MODE) &
2157 ((1 << HV_PTE_MODE_BITS) - 1);
2158}
2159
2160/** Set the page mode into a PTE. See hv_pte_get_mode. */
2161static __inline HV_PTE
2162hv_pte_set_mode(HV_PTE pte, unsigned int val)
2163{
2164 pte.val &= ~(((1ULL << HV_PTE_MODE_BITS) - 1) << HV_PTE_INDEX_MODE);
2165 pte.val |= val << HV_PTE_INDEX_MODE;
2166 return pte;
2167}
2168
2169/** Get the page frame number from the PTE.
2170 *
2171 * This field contains the upper bits of the CPA (client physical
2172 * address) of the target page; the complete CPA is this field with
2173 * HV_LOG2_PAGE_SIZE_SMALL zero bits appended to it.
2174 *
2175 * For PTEs in a level-1 page table where the Page bit is set, the
2176 * CPA must be aligned modulo the large page size.
2177 */
2178static __inline unsigned int
2179hv_pte_get_pfn(const HV_PTE pte)
2180{
2181 return pte.val >> HV_PTE_INDEX_PFN;
2182}
2183
2184
2185/** Set the page frame number into a PTE. See hv_pte_get_pfn. */
2186static __inline HV_PTE
2187hv_pte_set_pfn(HV_PTE pte, unsigned int val)
2188{
2189 /*
2190 * Note that the use of "PTFN" in the next line is intentional; we
2191 * don't want any garbage lower bits left in that field.
2192 */
2193 pte.val &= ~(((1ULL << HV_PTE_PTFN_BITS) - 1) << HV_PTE_INDEX_PTFN);
2194 pte.val |= (__hv64) val << HV_PTE_INDEX_PFN;
2195 return pte;
2196}
2197
2198/** Get the page table frame number from the PTE.
2199 *
2200 * This field contains the upper bits of the CPA (client physical
2201 * address) of the target page table; the complete CPA is this field with
2202 * with HV_PAGE_TABLE_ALIGN zero bits appended to it.
2203 *
2204 * For PTEs in a level-1 page table when the Page bit is not set, the
2205 * CPA must be aligned modulo the sticter of HV_PAGE_TABLE_ALIGN and
2206 * the level-2 page table size.
2207 */
2208static __inline unsigned long
2209hv_pte_get_ptfn(const HV_PTE pte)
2210{
2211 return pte.val >> HV_PTE_INDEX_PTFN;
2212}
2213
2214
2215/** Set the page table frame number into a PTE. See hv_pte_get_ptfn. */
2216static __inline HV_PTE
2217hv_pte_set_ptfn(HV_PTE pte, unsigned long val)
2218{
2219 pte.val &= ~(((1ULL << HV_PTE_PTFN_BITS)-1) << HV_PTE_INDEX_PTFN);
2220 pte.val |= (__hv64) val << HV_PTE_INDEX_PTFN;
2221 return pte;
2222}
2223
2224
2225/** Get the remote tile caching this page.
2226 *
2227 * Specifies the remote tile which is providing the L3 cache for this page.
2228 *
2229 * This field is ignored unless the page mode is HV_PTE_MODE_CACHE_TILE_L3.
2230 *
2231 * In level-1 PTEs, if the Page bit is clear, this field determines how the
2232 * level-2 page table is accessed.
2233 */
2234static __inline unsigned int
2235hv_pte_get_lotar(const HV_PTE pte)
2236{
2237 unsigned int lotar = ((__hv32) pte.val) >> HV_PTE_INDEX_LOTAR;
2238
2239 return HV_XY_TO_LOTAR( (lotar >> (HV_PTE_LOTAR_BITS / 2)),
2240 (lotar & ((1 << (HV_PTE_LOTAR_BITS / 2)) - 1)) );
2241}
2242
2243
2244/** Set the remote tile caching a page into a PTE. See hv_pte_get_lotar. */
2245static __inline HV_PTE
2246hv_pte_set_lotar(HV_PTE pte, unsigned int val)
2247{
2248 unsigned int x = HV_LOTAR_X(val);
2249 unsigned int y = HV_LOTAR_Y(val);
2250
2251 pte.val &= ~(((1ULL << HV_PTE_LOTAR_BITS)-1) << HV_PTE_INDEX_LOTAR);
2252 pte.val |= (x << (HV_PTE_INDEX_LOTAR + HV_PTE_LOTAR_BITS / 2)) |
2253 (y << HV_PTE_INDEX_LOTAR);
2254 return pte;
2255}
2256
2257#endif /* !__ASSEMBLER__ */
2258
2259/** Converts a client physical address to a pfn. */
2260#define HV_CPA_TO_PFN(p) ((p) >> HV_LOG2_PAGE_SIZE_SMALL)
2261
2262/** Converts a pfn to a client physical address. */
2263#define HV_PFN_TO_CPA(p) (((HV_PhysAddr)(p)) << HV_LOG2_PAGE_SIZE_SMALL)
2264
2265/** Converts a client physical address to a ptfn. */
2266#define HV_CPA_TO_PTFN(p) ((p) >> HV_LOG2_PAGE_TABLE_ALIGN)
2267
2268/** Converts a ptfn to a client physical address. */
2269#define HV_PTFN_TO_CPA(p) (((HV_PhysAddr)(p)) << HV_LOG2_PAGE_TABLE_ALIGN)
2270
2271/** Converts a ptfn to a pfn. */
2272#define HV_PTFN_TO_PFN(p) \
2273 ((p) >> (HV_LOG2_PAGE_SIZE_SMALL - HV_LOG2_PAGE_TABLE_ALIGN))
2274
2275/** Converts a pfn to a ptfn. */
2276#define HV_PFN_TO_PTFN(p) \
2277 ((p) << (HV_LOG2_PAGE_SIZE_SMALL - HV_LOG2_PAGE_TABLE_ALIGN))
2278
2279#if CHIP_VA_WIDTH() > 32
2280
2281/** Log number of HV_PTE entries in L0 page table */
2282#define HV_LOG2_L0_ENTRIES (CHIP_VA_WIDTH() - HV_LOG2_L1_SPAN)
2283
2284/** Number of HV_PTE entries in L0 page table */
2285#define HV_L0_ENTRIES (1 << HV_LOG2_L0_ENTRIES)
2286
2287/** Log size of L0 page table in bytes */
2288#define HV_LOG2_L0_SIZE (HV_LOG2_PTE_SIZE + HV_LOG2_L0_ENTRIES)
2289
2290/** Size of L0 page table in bytes */
2291#define HV_L0_SIZE (1 << HV_LOG2_L0_SIZE)
2292
2293#ifdef __ASSEMBLER__
2294
2295/** Index in L0 for a specific VA */
2296#define HV_L0_INDEX(va) \
2297 (((va) >> HV_LOG2_L1_SPAN) & (HV_L0_ENTRIES - 1))
2298
2299#else
2300
2301/** Index in L1 for a specific VA */
2302#define HV_L0_INDEX(va) \
2303 (((HV_VirtAddr)(va) >> HV_LOG2_L1_SPAN) & (HV_L0_ENTRIES - 1))
2304
2305#endif
2306
2307#endif /* CHIP_VA_WIDTH() > 32 */
2308
2309/** Log number of HV_PTE entries in L1 page table */
2310#define HV_LOG2_L1_ENTRIES (HV_LOG2_L1_SPAN - HV_LOG2_PAGE_SIZE_LARGE)
2311
2312/** Number of HV_PTE entries in L1 page table */
2313#define HV_L1_ENTRIES (1 << HV_LOG2_L1_ENTRIES)
2314
2315/** Log size of L1 page table in bytes */
2316#define HV_LOG2_L1_SIZE (HV_LOG2_PTE_SIZE + HV_LOG2_L1_ENTRIES)
2317
2318/** Size of L1 page table in bytes */
2319#define HV_L1_SIZE (1 << HV_LOG2_L1_SIZE)
2320
2321/** Log number of HV_PTE entries in level-2 page table */
2322#define HV_LOG2_L2_ENTRIES (HV_LOG2_PAGE_SIZE_LARGE - HV_LOG2_PAGE_SIZE_SMALL)
2323
2324/** Number of HV_PTE entries in level-2 page table */
2325#define HV_L2_ENTRIES (1 << HV_LOG2_L2_ENTRIES)
2326
2327/** Log size of level-2 page table in bytes */
2328#define HV_LOG2_L2_SIZE (HV_LOG2_PTE_SIZE + HV_LOG2_L2_ENTRIES)
2329
2330/** Size of level-2 page table in bytes */
2331#define HV_L2_SIZE (1 << HV_LOG2_L2_SIZE)
2332
2333#ifdef __ASSEMBLER__
2334
2335#if CHIP_VA_WIDTH() > 32
2336
2337/** Index in L1 for a specific VA */
2338#define HV_L1_INDEX(va) \
2339 (((va) >> HV_LOG2_PAGE_SIZE_LARGE) & (HV_L1_ENTRIES - 1))
2340
2341#else /* CHIP_VA_WIDTH() > 32 */
2342
2343/** Index in L1 for a specific VA */
2344#define HV_L1_INDEX(va) \
2345 (((va) >> HV_LOG2_PAGE_SIZE_LARGE))
2346
2347#endif /* CHIP_VA_WIDTH() > 32 */
2348
2349/** Index in level-2 page table for a specific VA */
2350#define HV_L2_INDEX(va) \
2351 (((va) >> HV_LOG2_PAGE_SIZE_SMALL) & (HV_L2_ENTRIES - 1))
2352
2353#else /* __ASSEMBLER __ */
2354
2355#if CHIP_VA_WIDTH() > 32
2356
2357/** Index in L1 for a specific VA */
2358#define HV_L1_INDEX(va) \
2359 (((HV_VirtAddr)(va) >> HV_LOG2_PAGE_SIZE_LARGE) & (HV_L1_ENTRIES - 1))
2360
2361#else /* CHIP_VA_WIDTH() > 32 */
2362
2363/** Index in L1 for a specific VA */
2364#define HV_L1_INDEX(va) \
2365 (((HV_VirtAddr)(va) >> HV_LOG2_PAGE_SIZE_LARGE))
2366
2367#endif /* CHIP_VA_WIDTH() > 32 */
2368
2369/** Index in level-2 page table for a specific VA */
2370#define HV_L2_INDEX(va) \
2371 (((HV_VirtAddr)(va) >> HV_LOG2_PAGE_SIZE_SMALL) & (HV_L2_ENTRIES - 1))
2372
2373#endif /* __ASSEMBLER __ */
2374
2375#endif /* _TILE_HV_H */
diff --git a/arch/tile/include/hv/pagesize.h b/arch/tile/include/hv/pagesize.h
new file mode 100644
index 000000000000..58bed114fedd
--- /dev/null
+++ b/arch/tile/include/hv/pagesize.h
@@ -0,0 +1,32 @@
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/**
16 * @file pagesize.h
17 */
18
19#ifndef _HV_PAGESIZE_H
20#define _HV_PAGESIZE_H
21
22/** The log2 of the size of small pages, in bytes. This value should
23 * be verified at runtime by calling hv_sysconf(HV_SYSCONF_PAGE_SIZE_SMALL).
24 */
25#define HV_LOG2_PAGE_SIZE_SMALL 16
26
27/** The log2 of the size of large pages, in bytes. This value should be
28 * verified at runtime by calling hv_sysconf(HV_SYSCONF_PAGE_SIZE_LARGE).
29 */
30#define HV_LOG2_PAGE_SIZE_LARGE 24
31
32#endif /* _HV_PAGESIZE_H */
diff --git a/arch/tile/include/hv/syscall_public.h b/arch/tile/include/hv/syscall_public.h
new file mode 100644
index 000000000000..9cc0837e69fd
--- /dev/null
+++ b/arch/tile/include/hv/syscall_public.h
@@ -0,0 +1,42 @@
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/**
16 * @file syscall.h
17 * Indices for the hypervisor system calls that are intended to be called
18 * directly, rather than only through hypervisor-generated "glue" code.
19 */
20
21#ifndef _SYS_HV_INCLUDE_SYSCALL_PUBLIC_H
22#define _SYS_HV_INCLUDE_SYSCALL_PUBLIC_H
23
24/** Fast syscall flag bit location. When this bit is set, the hypervisor
25 * handles the syscall specially.
26 */
27#define HV_SYS_FAST_SHIFT 14
28
29/** Fast syscall flag bit mask. */
30#define HV_SYS_FAST_MASK (1 << HV_SYS_FAST_SHIFT)
31
32/** Bit location for flagging fast syscalls that can be called from PL0. */
33#define HV_SYS_FAST_PLO_SHIFT 13
34
35/** Fast syscall allowing PL0 bit mask. */
36#define HV_SYS_FAST_PL0_MASK (1 << HV_SYS_FAST_PLO_SHIFT)
37
38/** Perform an MF that waits for all victims to reach DRAM. */
39#define HV_SYS_fence_incoherent (51 | HV_SYS_FAST_MASK \
40 | HV_SYS_FAST_PL0_MASK)
41
42#endif /* !_SYS_HV_INCLUDE_SYSCALL_PUBLIC_H */
diff --git a/arch/tile/kernel/Makefile b/arch/tile/kernel/Makefile
new file mode 100644
index 000000000000..112b1e248f05
--- /dev/null
+++ b/arch/tile/kernel/Makefile
@@ -0,0 +1,17 @@
1#
2# Makefile for the Linux/TILE kernel.
3#
4
5extra-y := vmlinux.lds head_$(BITS).o
6obj-y := backtrace.o entry.o init_task.o irq.o messaging.o \
7 pci-dma.o proc.o process.o ptrace.o reboot.o \
8 setup.o signal.o single_step.o stack.o sys.o time.o traps.o \
9 intvec_$(BITS).o regs_$(BITS).o tile-desc_$(BITS).o
10
11obj-$(CONFIG_HARDWALL) += hardwall.o
12obj-$(CONFIG_TILEGX) += futex_64.o
13obj-$(CONFIG_COMPAT) += compat.o compat_signal.o
14obj-$(CONFIG_SMP) += smpboot.o smp.o tlb.o
15obj-$(CONFIG_MODULES) += module.o
16obj-$(CONFIG_EARLY_PRINTK) += early_printk.o
17obj-$(CONFIG_KEXEC) += machine_kexec.o relocate_kernel.o
diff --git a/arch/tile/kernel/asm-offsets.c b/arch/tile/kernel/asm-offsets.c
new file mode 100644
index 000000000000..01ddf19cc36d
--- /dev/null
+++ b/arch/tile/kernel/asm-offsets.c
@@ -0,0 +1,76 @@
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 * Generates definitions from c-type structures used by assembly sources.
15 */
16
17#include <linux/kbuild.h>
18#include <linux/thread_info.h>
19#include <linux/sched.h>
20#include <linux/hardirq.h>
21#include <linux/ptrace.h>
22#include <hv/hypervisor.h>
23
24/* Check for compatible compiler early in the build. */
25#ifdef CONFIG_TILEGX
26# ifndef __tilegx__
27# error Can only build TILE-Gx configurations with tilegx compiler
28# endif
29# ifndef __LP64__
30# error Must not specify -m32 when building the TILE-Gx kernel
31# endif
32#else
33# ifdef __tilegx__
34# error Can not build TILEPro/TILE64 configurations with tilegx compiler
35# endif
36#endif
37
38void foo(void)
39{
40 DEFINE(SINGLESTEP_STATE_BUFFER_OFFSET, \
41 offsetof(struct single_step_state, buffer));
42 DEFINE(SINGLESTEP_STATE_FLAGS_OFFSET, \
43 offsetof(struct single_step_state, flags));
44 DEFINE(SINGLESTEP_STATE_ORIG_PC_OFFSET, \
45 offsetof(struct single_step_state, orig_pc));
46 DEFINE(SINGLESTEP_STATE_NEXT_PC_OFFSET, \
47 offsetof(struct single_step_state, next_pc));
48 DEFINE(SINGLESTEP_STATE_BRANCH_NEXT_PC_OFFSET, \
49 offsetof(struct single_step_state, branch_next_pc));
50 DEFINE(SINGLESTEP_STATE_UPDATE_VALUE_OFFSET, \
51 offsetof(struct single_step_state, update_value));
52
53 DEFINE(THREAD_INFO_TASK_OFFSET, \
54 offsetof(struct thread_info, task));
55 DEFINE(THREAD_INFO_FLAGS_OFFSET, \
56 offsetof(struct thread_info, flags));
57 DEFINE(THREAD_INFO_STATUS_OFFSET, \
58 offsetof(struct thread_info, status));
59 DEFINE(THREAD_INFO_HOMECACHE_CPU_OFFSET, \
60 offsetof(struct thread_info, homecache_cpu));
61 DEFINE(THREAD_INFO_STEP_STATE_OFFSET, \
62 offsetof(struct thread_info, step_state));
63
64 DEFINE(TASK_STRUCT_THREAD_KSP_OFFSET,
65 offsetof(struct task_struct, thread.ksp));
66 DEFINE(TASK_STRUCT_THREAD_PC_OFFSET,
67 offsetof(struct task_struct, thread.pc));
68
69 DEFINE(HV_TOPOLOGY_WIDTH_OFFSET, \
70 offsetof(HV_Topology, width));
71 DEFINE(HV_TOPOLOGY_HEIGHT_OFFSET, \
72 offsetof(HV_Topology, height));
73
74 DEFINE(IRQ_CPUSTAT_SYSCALL_COUNT_OFFSET, \
75 offsetof(irq_cpustat_t, irq_syscall_count));
76}
diff --git a/arch/tile/kernel/backtrace.c b/arch/tile/kernel/backtrace.c
new file mode 100644
index 000000000000..d3c41c1ff6bd
--- /dev/null
+++ b/arch/tile/kernel/backtrace.c
@@ -0,0 +1,682 @@
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#include <linux/kernel.h>
16#include <linux/string.h>
17
18#include <asm/backtrace.h>
19
20#include <arch/chip.h>
21
22#include <asm/opcode-tile.h>
23
24
25#define TREG_SP 54
26#define TREG_LR 55
27
28
29#if TILE_CHIP >= 10
30#define tile_bundle_bits tilegx_bundle_bits
31#define TILE_MAX_INSTRUCTIONS_PER_BUNDLE TILEGX_MAX_INSTRUCTIONS_PER_BUNDLE
32#define TILE_BUNDLE_ALIGNMENT_IN_BYTES TILEGX_BUNDLE_ALIGNMENT_IN_BYTES
33#define tile_decoded_instruction tilegx_decoded_instruction
34#define tile_mnemonic tilegx_mnemonic
35#define parse_insn_tile parse_insn_tilegx
36#define TILE_OPC_IRET TILEGX_OPC_IRET
37#define TILE_OPC_ADDI TILEGX_OPC_ADDI
38#define TILE_OPC_ADDLI TILEGX_OPC_ADDLI
39#define TILE_OPC_INFO TILEGX_OPC_INFO
40#define TILE_OPC_INFOL TILEGX_OPC_INFOL
41#define TILE_OPC_JRP TILEGX_OPC_JRP
42#define TILE_OPC_MOVE TILEGX_OPC_MOVE
43#define OPCODE_STORE TILEGX_OPC_ST
44typedef long long bt_int_reg_t;
45#else
46#define OPCODE_STORE TILE_OPC_SW
47typedef int bt_int_reg_t;
48#endif
49
50/** A decoded bundle used for backtracer analysis. */
51struct BacktraceBundle {
52 tile_bundle_bits bits;
53 int num_insns;
54 struct tile_decoded_instruction
55 insns[TILE_MAX_INSTRUCTIONS_PER_BUNDLE];
56};
57
58
59/* This implementation only makes sense for native tools. */
60/** Default function to read memory. */
61static bool bt_read_memory(void *result, VirtualAddress addr,
62 unsigned int size, void *extra)
63{
64 /* FIXME: this should do some horrible signal stuff to catch
65 * SEGV cleanly and fail.
66 *
67 * Or else the caller should do the setjmp for efficiency.
68 */
69
70 memcpy(result, (const void *)addr, size);
71 return true;
72}
73
74
75/** Locates an instruction inside the given bundle that
76 * has the specified mnemonic, and whose first 'num_operands_to_match'
77 * operands exactly match those in 'operand_values'.
78 */
79static const struct tile_decoded_instruction *find_matching_insn(
80 const struct BacktraceBundle *bundle,
81 tile_mnemonic mnemonic,
82 const int *operand_values,
83 int num_operands_to_match)
84{
85 int i, j;
86 bool match;
87
88 for (i = 0; i < bundle->num_insns; i++) {
89 const struct tile_decoded_instruction *insn =
90 &bundle->insns[i];
91
92 if (insn->opcode->mnemonic != mnemonic)
93 continue;
94
95 match = true;
96 for (j = 0; j < num_operands_to_match; j++) {
97 if (operand_values[j] != insn->operand_values[j]) {
98 match = false;
99 break;
100 }
101 }
102
103 if (match)
104 return insn;
105 }
106
107 return NULL;
108}
109
110/** Does this bundle contain an 'iret' instruction? */
111static inline bool bt_has_iret(const struct BacktraceBundle *bundle)
112{
113 return find_matching_insn(bundle, TILE_OPC_IRET, NULL, 0) != NULL;
114}
115
116/** Does this bundle contain an 'addi sp, sp, OFFSET' or
117 * 'addli sp, sp, OFFSET' instruction, and if so, what is OFFSET?
118 */
119static bool bt_has_addi_sp(const struct BacktraceBundle *bundle, int *adjust)
120{
121 static const int vals[2] = { TREG_SP, TREG_SP };
122
123 const struct tile_decoded_instruction *insn =
124 find_matching_insn(bundle, TILE_OPC_ADDI, vals, 2);
125 if (insn == NULL)
126 insn = find_matching_insn(bundle, TILE_OPC_ADDLI, vals, 2);
127#if TILE_CHIP >= 10
128 if (insn == NULL)
129 insn = find_matching_insn(bundle, TILEGX_OPC_ADDXLI, vals, 2);
130 if (insn == NULL)
131 insn = find_matching_insn(bundle, TILEGX_OPC_ADDXI, vals, 2);
132#endif
133 if (insn == NULL)
134 return false;
135
136 *adjust = insn->operand_values[2];
137 return true;
138}
139
140/** Does this bundle contain any 'info OP' or 'infol OP'
141 * instruction, and if so, what are their OP? Note that OP is interpreted
142 * as an unsigned value by this code since that's what the caller wants.
143 * Returns the number of info ops found.
144 */
145static int bt_get_info_ops(const struct BacktraceBundle *bundle,
146 int operands[MAX_INFO_OPS_PER_BUNDLE])
147{
148 int num_ops = 0;
149 int i;
150
151 for (i = 0; i < bundle->num_insns; i++) {
152 const struct tile_decoded_instruction *insn =
153 &bundle->insns[i];
154
155 if (insn->opcode->mnemonic == TILE_OPC_INFO ||
156 insn->opcode->mnemonic == TILE_OPC_INFOL) {
157 operands[num_ops++] = insn->operand_values[0];
158 }
159 }
160
161 return num_ops;
162}
163
164/** Does this bundle contain a jrp instruction, and if so, to which
165 * register is it jumping?
166 */
167static bool bt_has_jrp(const struct BacktraceBundle *bundle, int *target_reg)
168{
169 const struct tile_decoded_instruction *insn =
170 find_matching_insn(bundle, TILE_OPC_JRP, NULL, 0);
171 if (insn == NULL)
172 return false;
173
174 *target_reg = insn->operand_values[0];
175 return true;
176}
177
178/** Does this bundle modify the specified register in any way? */
179static bool bt_modifies_reg(const struct BacktraceBundle *bundle, int reg)
180{
181 int i, j;
182 for (i = 0; i < bundle->num_insns; i++) {
183 const struct tile_decoded_instruction *insn =
184 &bundle->insns[i];
185
186 if (insn->opcode->implicitly_written_register == reg)
187 return true;
188
189 for (j = 0; j < insn->opcode->num_operands; j++)
190 if (insn->operands[j]->is_dest_reg &&
191 insn->operand_values[j] == reg)
192 return true;
193 }
194
195 return false;
196}
197
198/** Does this bundle modify sp? */
199static inline bool bt_modifies_sp(const struct BacktraceBundle *bundle)
200{
201 return bt_modifies_reg(bundle, TREG_SP);
202}
203
204/** Does this bundle modify lr? */
205static inline bool bt_modifies_lr(const struct BacktraceBundle *bundle)
206{
207 return bt_modifies_reg(bundle, TREG_LR);
208}
209
210/** Does this bundle contain the instruction 'move fp, sp'? */
211static inline bool bt_has_move_r52_sp(const struct BacktraceBundle *bundle)
212{
213 static const int vals[2] = { 52, TREG_SP };
214 return find_matching_insn(bundle, TILE_OPC_MOVE, vals, 2) != NULL;
215}
216
217/** Does this bundle contain a store of lr to sp? */
218static inline bool bt_has_sw_sp_lr(const struct BacktraceBundle *bundle)
219{
220 static const int vals[2] = { TREG_SP, TREG_LR };
221 return find_matching_insn(bundle, OPCODE_STORE, vals, 2) != NULL;
222}
223
224#if TILE_CHIP >= 10
225/** Track moveli values placed into registers. */
226static inline void bt_update_moveli(const struct BacktraceBundle *bundle,
227 int moveli_args[])
228{
229 int i;
230 for (i = 0; i < bundle->num_insns; i++) {
231 const struct tile_decoded_instruction *insn =
232 &bundle->insns[i];
233
234 if (insn->opcode->mnemonic == TILEGX_OPC_MOVELI) {
235 int reg = insn->operand_values[0];
236 moveli_args[reg] = insn->operand_values[1];
237 }
238 }
239}
240
241/** Does this bundle contain an 'add sp, sp, reg' instruction
242 * from a register that we saw a moveli into, and if so, what
243 * is the value in the register?
244 */
245static bool bt_has_add_sp(const struct BacktraceBundle *bundle, int *adjust,
246 int moveli_args[])
247{
248 static const int vals[2] = { TREG_SP, TREG_SP };
249
250 const struct tile_decoded_instruction *insn =
251 find_matching_insn(bundle, TILEGX_OPC_ADDX, vals, 2);
252 if (insn) {
253 int reg = insn->operand_values[2];
254 if (moveli_args[reg]) {
255 *adjust = moveli_args[reg];
256 return true;
257 }
258 }
259 return false;
260}
261#endif
262
263/** Locates the caller's PC and SP for a program starting at the
264 * given address.
265 */
266static void find_caller_pc_and_caller_sp(CallerLocation *location,
267 const VirtualAddress start_pc,
268 BacktraceMemoryReader read_memory_func,
269 void *read_memory_func_extra)
270{
271 /* Have we explicitly decided what the sp is,
272 * rather than just the default?
273 */
274 bool sp_determined = false;
275
276 /* Has any bundle seen so far modified lr? */
277 bool lr_modified = false;
278
279 /* Have we seen a move from sp to fp? */
280 bool sp_moved_to_r52 = false;
281
282 /* Have we seen a terminating bundle? */
283 bool seen_terminating_bundle = false;
284
285 /* Cut down on round-trip reading overhead by reading several
286 * bundles at a time.
287 */
288 tile_bundle_bits prefetched_bundles[32];
289 int num_bundles_prefetched = 0;
290 int next_bundle = 0;
291 VirtualAddress pc;
292
293#if TILE_CHIP >= 10
294 /* Naively try to track moveli values to support addx for -m32. */
295 int moveli_args[TILEGX_NUM_REGISTERS] = { 0 };
296#endif
297
298 /* Default to assuming that the caller's sp is the current sp.
299 * This is necessary to handle the case where we start backtracing
300 * right at the end of the epilog.
301 */
302 location->sp_location = SP_LOC_OFFSET;
303 location->sp_offset = 0;
304
305 /* Default to having no idea where the caller PC is. */
306 location->pc_location = PC_LOC_UNKNOWN;
307
308 /* Don't even try if the PC is not aligned. */
309 if (start_pc % TILE_BUNDLE_ALIGNMENT_IN_BYTES != 0)
310 return;
311
312 for (pc = start_pc;; pc += sizeof(tile_bundle_bits)) {
313
314 struct BacktraceBundle bundle;
315 int num_info_ops, info_operands[MAX_INFO_OPS_PER_BUNDLE];
316 int one_ago, jrp_reg;
317 bool has_jrp;
318
319 if (next_bundle >= num_bundles_prefetched) {
320 /* Prefetch some bytes, but don't cross a page
321 * boundary since that might cause a read failure we
322 * don't care about if we only need the first few
323 * bytes. Note: we don't care what the actual page
324 * size is; using the minimum possible page size will
325 * prevent any problems.
326 */
327 unsigned int bytes_to_prefetch = 4096 - (pc & 4095);
328 if (bytes_to_prefetch > sizeof prefetched_bundles)
329 bytes_to_prefetch = sizeof prefetched_bundles;
330
331 if (!read_memory_func(prefetched_bundles, pc,
332 bytes_to_prefetch,
333 read_memory_func_extra)) {
334 if (pc == start_pc) {
335 /* The program probably called a bad
336 * address, such as a NULL pointer.
337 * So treat this as if we are at the
338 * start of the function prolog so the
339 * backtrace will show how we got here.
340 */
341 location->pc_location = PC_LOC_IN_LR;
342 return;
343 }
344
345 /* Unreadable address. Give up. */
346 break;
347 }
348
349 next_bundle = 0;
350 num_bundles_prefetched =
351 bytes_to_prefetch / sizeof(tile_bundle_bits);
352 }
353
354 /* Decode the next bundle. */
355 bundle.bits = prefetched_bundles[next_bundle++];
356 bundle.num_insns =
357 parse_insn_tile(bundle.bits, pc, bundle.insns);
358 num_info_ops = bt_get_info_ops(&bundle, info_operands);
359
360 /* First look at any one_ago info ops if they are interesting,
361 * since they should shadow any non-one-ago info ops.
362 */
363 for (one_ago = (pc != start_pc) ? 1 : 0;
364 one_ago >= 0; one_ago--) {
365 int i;
366 for (i = 0; i < num_info_ops; i++) {
367 int info_operand = info_operands[i];
368 if (info_operand < CALLER_UNKNOWN_BASE) {
369 /* Weird; reserved value, ignore it. */
370 continue;
371 }
372
373 /* Skip info ops which are not in the
374 * "one_ago" mode we want right now.
375 */
376 if (((info_operand & ONE_BUNDLE_AGO_FLAG) != 0)
377 != (one_ago != 0))
378 continue;
379
380 /* Clear the flag to make later checking
381 * easier. */
382 info_operand &= ~ONE_BUNDLE_AGO_FLAG;
383
384 /* Default to looking at PC_IN_LR_FLAG. */
385 if (info_operand & PC_IN_LR_FLAG)
386 location->pc_location =
387 PC_LOC_IN_LR;
388 else
389 location->pc_location =
390 PC_LOC_ON_STACK;
391
392 switch (info_operand) {
393 case CALLER_UNKNOWN_BASE:
394 location->pc_location = PC_LOC_UNKNOWN;
395 location->sp_location = SP_LOC_UNKNOWN;
396 return;
397
398 case CALLER_SP_IN_R52_BASE:
399 case CALLER_SP_IN_R52_BASE | PC_IN_LR_FLAG:
400 location->sp_location = SP_LOC_IN_R52;
401 return;
402
403 default:
404 {
405 const unsigned int val = info_operand
406 - CALLER_SP_OFFSET_BASE;
407 const unsigned int sp_offset =
408 (val >> NUM_INFO_OP_FLAGS) * 8;
409 if (sp_offset < 32768) {
410 /* This is a properly encoded
411 * SP offset. */
412 location->sp_location =
413 SP_LOC_OFFSET;
414 location->sp_offset =
415 sp_offset;
416 return;
417 } else {
418 /* This looked like an SP
419 * offset, but it's outside
420 * the legal range, so this
421 * must be an unrecognized
422 * info operand. Ignore it.
423 */
424 }
425 }
426 break;
427 }
428 }
429 }
430
431 if (seen_terminating_bundle) {
432 /* We saw a terminating bundle during the previous
433 * iteration, so we were only looking for an info op.
434 */
435 break;
436 }
437
438 if (bundle.bits == 0) {
439 /* Wacky terminating bundle. Stop looping, and hope
440 * we've already seen enough to find the caller.
441 */
442 break;
443 }
444
445 /*
446 * Try to determine caller's SP.
447 */
448
449 if (!sp_determined) {
450 int adjust;
451 if (bt_has_addi_sp(&bundle, &adjust)
452#if TILE_CHIP >= 10
453 || bt_has_add_sp(&bundle, &adjust, moveli_args)
454#endif
455 ) {
456 location->sp_location = SP_LOC_OFFSET;
457
458 if (adjust <= 0) {
459 /* We are in prolog about to adjust
460 * SP. */
461 location->sp_offset = 0;
462 } else {
463 /* We are in epilog restoring SP. */
464 location->sp_offset = adjust;
465 }
466
467 sp_determined = true;
468 } else {
469 if (bt_has_move_r52_sp(&bundle)) {
470 /* Maybe in prolog, creating an
471 * alloca-style frame. But maybe in
472 * the middle of a fixed-size frame
473 * clobbering r52 with SP.
474 */
475 sp_moved_to_r52 = true;
476 }
477
478 if (bt_modifies_sp(&bundle)) {
479 if (sp_moved_to_r52) {
480 /* We saw SP get saved into
481 * r52 earlier (or now), which
482 * must have been in the
483 * prolog, so we now know that
484 * SP is still holding the
485 * caller's sp value.
486 */
487 location->sp_location =
488 SP_LOC_OFFSET;
489 location->sp_offset = 0;
490 } else {
491 /* Someone must have saved
492 * aside the caller's SP value
493 * into r52, so r52 holds the
494 * current value.
495 */
496 location->sp_location =
497 SP_LOC_IN_R52;
498 }
499 sp_determined = true;
500 }
501 }
502
503#if TILE_CHIP >= 10
504 /* Track moveli arguments for -m32 mode. */
505 bt_update_moveli(&bundle, moveli_args);
506#endif
507 }
508
509 if (bt_has_iret(&bundle)) {
510 /* This is a terminating bundle. */
511 seen_terminating_bundle = true;
512 continue;
513 }
514
515 /*
516 * Try to determine caller's PC.
517 */
518
519 jrp_reg = -1;
520 has_jrp = bt_has_jrp(&bundle, &jrp_reg);
521 if (has_jrp)
522 seen_terminating_bundle = true;
523
524 if (location->pc_location == PC_LOC_UNKNOWN) {
525 if (has_jrp) {
526 if (jrp_reg == TREG_LR && !lr_modified) {
527 /* Looks like a leaf function, or else
528 * lr is already restored. */
529 location->pc_location =
530 PC_LOC_IN_LR;
531 } else {
532 location->pc_location =
533 PC_LOC_ON_STACK;
534 }
535 } else if (bt_has_sw_sp_lr(&bundle)) {
536 /* In prolog, spilling initial lr to stack. */
537 location->pc_location = PC_LOC_IN_LR;
538 } else if (bt_modifies_lr(&bundle)) {
539 lr_modified = true;
540 }
541 }
542 }
543}
544
545void backtrace_init(BacktraceIterator *state,
546 BacktraceMemoryReader read_memory_func,
547 void *read_memory_func_extra,
548 VirtualAddress pc, VirtualAddress lr,
549 VirtualAddress sp, VirtualAddress r52)
550{
551 CallerLocation location;
552 VirtualAddress fp, initial_frame_caller_pc;
553
554 if (read_memory_func == NULL) {
555 read_memory_func = bt_read_memory;
556 }
557
558 /* Find out where we are in the initial frame. */
559 find_caller_pc_and_caller_sp(&location, pc,
560 read_memory_func, read_memory_func_extra);
561
562 switch (location.sp_location) {
563 case SP_LOC_UNKNOWN:
564 /* Give up. */
565 fp = -1;
566 break;
567
568 case SP_LOC_IN_R52:
569 fp = r52;
570 break;
571
572 case SP_LOC_OFFSET:
573 fp = sp + location.sp_offset;
574 break;
575
576 default:
577 /* Give up. */
578 fp = -1;
579 break;
580 }
581
582 /* If the frame pointer is not aligned to the basic word size
583 * something terrible happened and we should mark it as invalid.
584 */
585 if (fp % sizeof(bt_int_reg_t) != 0)
586 fp = -1;
587
588 /* -1 means "don't know initial_frame_caller_pc". */
589 initial_frame_caller_pc = -1;
590
591 switch (location.pc_location) {
592 case PC_LOC_UNKNOWN:
593 /* Give up. */
594 fp = -1;
595 break;
596
597 case PC_LOC_IN_LR:
598 if (lr == 0 || lr % TILE_BUNDLE_ALIGNMENT_IN_BYTES != 0) {
599 /* Give up. */
600 fp = -1;
601 } else {
602 initial_frame_caller_pc = lr;
603 }
604 break;
605
606 case PC_LOC_ON_STACK:
607 /* Leave initial_frame_caller_pc as -1,
608 * meaning check the stack.
609 */
610 break;
611
612 default:
613 /* Give up. */
614 fp = -1;
615 break;
616 }
617
618 state->pc = pc;
619 state->sp = sp;
620 state->fp = fp;
621 state->initial_frame_caller_pc = initial_frame_caller_pc;
622 state->read_memory_func = read_memory_func;
623 state->read_memory_func_extra = read_memory_func_extra;
624}
625
626/* Handle the case where the register holds more bits than the VA. */
627static bool valid_addr_reg(bt_int_reg_t reg)
628{
629 return ((VirtualAddress)reg == reg);
630}
631
632bool backtrace_next(BacktraceIterator *state)
633{
634 VirtualAddress next_fp, next_pc;
635 bt_int_reg_t next_frame[2];
636
637 if (state->fp == -1) {
638 /* No parent frame. */
639 return false;
640 }
641
642 /* Try to read the frame linkage data chaining to the next function. */
643 if (!state->read_memory_func(&next_frame, state->fp, sizeof next_frame,
644 state->read_memory_func_extra)) {
645 return false;
646 }
647
648 next_fp = next_frame[1];
649 if (!valid_addr_reg(next_frame[1]) ||
650 next_fp % sizeof(bt_int_reg_t) != 0) {
651 /* Caller's frame pointer is suspect, so give up. */
652 return false;
653 }
654
655 if (state->initial_frame_caller_pc != -1) {
656 /* We must be in the initial stack frame and already know the
657 * caller PC.
658 */
659 next_pc = state->initial_frame_caller_pc;
660
661 /* Force reading stack next time, in case we were in the
662 * initial frame. We don't do this above just to paranoidly
663 * avoid changing the struct at all when we return false.
664 */
665 state->initial_frame_caller_pc = -1;
666 } else {
667 /* Get the caller PC from the frame linkage area. */
668 next_pc = next_frame[0];
669 if (!valid_addr_reg(next_frame[0]) || next_pc == 0 ||
670 next_pc % TILE_BUNDLE_ALIGNMENT_IN_BYTES != 0) {
671 /* The PC is suspect, so give up. */
672 return false;
673 }
674 }
675
676 /* Update state to become the caller's stack frame. */
677 state->pc = next_pc;
678 state->sp = state->fp;
679 state->fp = next_fp;
680
681 return true;
682}
diff --git a/arch/tile/kernel/compat.c b/arch/tile/kernel/compat.c
new file mode 100644
index 000000000000..b1e06d041555
--- /dev/null
+++ b/arch/tile/kernel/compat.c
@@ -0,0 +1,167 @@
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/* Adjust unistd.h to provide 32-bit numbers and functions. */
16#define __SYSCALL_COMPAT
17
18#include <linux/compat.h>
19#include <linux/msg.h>
20#include <linux/syscalls.h>
21#include <linux/kdev_t.h>
22#include <linux/fs.h>
23#include <linux/fcntl.h>
24#include <linux/smp_lock.h>
25#include <linux/uaccess.h>
26#include <linux/signal.h>
27#include <asm/syscalls.h>
28
29/*
30 * Syscalls that take 64-bit numbers traditionally take them in 32-bit
31 * "high" and "low" value parts on 32-bit architectures.
32 * In principle, one could imagine passing some register arguments as
33 * fully 64-bit on TILE-Gx in 32-bit mode, but it seems easier to
34 * adapt the usual convention.
35 */
36
37long compat_sys_truncate64(char __user *filename, u32 dummy, u32 low, u32 high)
38{
39 return sys_truncate(filename, ((loff_t)high << 32) | low);
40}
41
42long compat_sys_ftruncate64(unsigned int fd, u32 dummy, u32 low, u32 high)
43{
44 return sys_ftruncate(fd, ((loff_t)high << 32) | low);
45}
46
47long compat_sys_pread64(unsigned int fd, char __user *ubuf, size_t count,
48 u32 dummy, u32 low, u32 high)
49{
50 return sys_pread64(fd, ubuf, count, ((loff_t)high << 32) | low);
51}
52
53long compat_sys_pwrite64(unsigned int fd, char __user *ubuf, size_t count,
54 u32 dummy, u32 low, u32 high)
55{
56 return sys_pwrite64(fd, ubuf, count, ((loff_t)high << 32) | low);
57}
58
59long compat_sys_lookup_dcookie(u32 low, u32 high, char __user *buf, size_t len)
60{
61 return sys_lookup_dcookie(((loff_t)high << 32) | low, buf, len);
62}
63
64long compat_sys_sync_file_range2(int fd, unsigned int flags,
65 u32 offset_lo, u32 offset_hi,
66 u32 nbytes_lo, u32 nbytes_hi)
67{
68 return sys_sync_file_range(fd, ((loff_t)offset_hi << 32) | offset_lo,
69 ((loff_t)nbytes_hi << 32) | nbytes_lo,
70 flags);
71}
72
73long compat_sys_fallocate(int fd, int mode,
74 u32 offset_lo, u32 offset_hi,
75 u32 len_lo, u32 len_hi)
76{
77 return sys_fallocate(fd, mode, ((loff_t)offset_hi << 32) | offset_lo,
78 ((loff_t)len_hi << 32) | len_lo);
79}
80
81
82
83long compat_sys_sched_rr_get_interval(compat_pid_t pid,
84 struct compat_timespec __user *interval)
85{
86 struct timespec t;
87 int ret;
88 mm_segment_t old_fs = get_fs();
89
90 set_fs(KERNEL_DS);
91 ret = sys_sched_rr_get_interval(pid,
92 (struct timespec __force __user *)&t);
93 set_fs(old_fs);
94 if (put_compat_timespec(&t, interval))
95 return -EFAULT;
96 return ret;
97}
98
99/*
100 * The usual compat_sys_msgsnd() and _msgrcv() seem to be assuming
101 * some different calling convention than our normal 32-bit tile code.
102 */
103
104/* Already defined in ipc/compat.c, but we need it here. */
105struct compat_msgbuf {
106 compat_long_t mtype;
107 char mtext[1];
108};
109
110long tile_compat_sys_msgsnd(int msqid,
111 struct compat_msgbuf __user *msgp,
112 size_t msgsz, int msgflg)
113{
114 compat_long_t mtype;
115
116 if (get_user(mtype, &msgp->mtype))
117 return -EFAULT;
118 return do_msgsnd(msqid, mtype, msgp->mtext, msgsz, msgflg);
119}
120
121long tile_compat_sys_msgrcv(int msqid,
122 struct compat_msgbuf __user *msgp,
123 size_t msgsz, long msgtyp, int msgflg)
124{
125 long err, mtype;
126
127 err = do_msgrcv(msqid, &mtype, msgp->mtext, msgsz, msgtyp, msgflg);
128 if (err < 0)
129 goto out;
130
131 if (put_user(mtype, &msgp->mtype))
132 err = -EFAULT;
133 out:
134 return err;
135}
136
137/* Provide the compat syscall number to call mapping. */
138#undef __SYSCALL
139#define __SYSCALL(nr, call) [nr] = (compat_##call),
140
141/* The generic versions of these don't work for Tile. */
142#define compat_sys_msgrcv tile_compat_sys_msgrcv
143#define compat_sys_msgsnd tile_compat_sys_msgsnd
144
145/* See comments in sys.c */
146#define compat_sys_fadvise64 sys32_fadvise64
147#define compat_sys_fadvise64_64 sys32_fadvise64_64
148#define compat_sys_readahead sys32_readahead
149#define compat_sys_sync_file_range compat_sys_sync_file_range2
150
151/* The native 64-bit "struct stat" matches the 32-bit "struct stat64". */
152#define compat_sys_stat64 sys_newstat
153#define compat_sys_lstat64 sys_newlstat
154#define compat_sys_fstat64 sys_newfstat
155#define compat_sys_fstatat64 sys_newfstatat
156
157/* Pass full 64-bit values through ptrace. */
158#define compat_sys_ptrace tile_compat_sys_ptrace
159
160/*
161 * Note that we can't include <linux/unistd.h> here since the header
162 * guard will defeat us; <asm/unistd.h> checks for __SYSCALL as well.
163 */
164void *compat_sys_call_table[__NR_syscalls] = {
165 [0 ... __NR_syscalls-1] = sys_ni_syscall,
166#include <asm/unistd.h>
167};
diff --git a/arch/tile/kernel/compat_signal.c b/arch/tile/kernel/compat_signal.c
new file mode 100644
index 000000000000..9c710db43f13
--- /dev/null
+++ b/arch/tile/kernel/compat_signal.c
@@ -0,0 +1,437 @@
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#include <linux/sched.h>
16#include <linux/mm.h>
17#include <linux/smp.h>
18#include <linux/smp_lock.h>
19#include <linux/kernel.h>
20#include <linux/signal.h>
21#include <linux/errno.h>
22#include <linux/wait.h>
23#include <linux/unistd.h>
24#include <linux/stddef.h>
25#include <linux/personality.h>
26#include <linux/suspend.h>
27#include <linux/ptrace.h>
28#include <linux/elf.h>
29#include <linux/compat.h>
30#include <linux/syscalls.h>
31#include <linux/uaccess.h>
32#include <asm/processor.h>
33#include <asm/ucontext.h>
34#include <asm/sigframe.h>
35#include <asm/syscalls.h>
36#include <arch/interrupts.h>
37
38struct compat_sigaction {
39 compat_uptr_t sa_handler;
40 compat_ulong_t sa_flags;
41 compat_uptr_t sa_restorer;
42 sigset_t sa_mask __packed;
43};
44
45struct compat_sigaltstack {
46 compat_uptr_t ss_sp;
47 int ss_flags;
48 compat_size_t ss_size;
49};
50
51struct compat_ucontext {
52 compat_ulong_t uc_flags;
53 compat_uptr_t uc_link;
54 struct compat_sigaltstack uc_stack;
55 struct sigcontext uc_mcontext;
56 sigset_t uc_sigmask; /* mask last for extensibility */
57};
58
59#define COMPAT_SI_PAD_SIZE ((SI_MAX_SIZE - 3 * sizeof(int)) / sizeof(int))
60
61struct compat_siginfo {
62 int si_signo;
63 int si_errno;
64 int si_code;
65
66 union {
67 int _pad[COMPAT_SI_PAD_SIZE];
68
69 /* kill() */
70 struct {
71 unsigned int _pid; /* sender's pid */
72 unsigned int _uid; /* sender's uid */
73 } _kill;
74
75 /* POSIX.1b timers */
76 struct {
77 compat_timer_t _tid; /* timer id */
78 int _overrun; /* overrun count */
79 compat_sigval_t _sigval; /* same as below */
80 int _sys_private; /* not to be passed to user */
81 int _overrun_incr; /* amount to add to overrun */
82 } _timer;
83
84 /* POSIX.1b signals */
85 struct {
86 unsigned int _pid; /* sender's pid */
87 unsigned int _uid; /* sender's uid */
88 compat_sigval_t _sigval;
89 } _rt;
90
91 /* SIGCHLD */
92 struct {
93 unsigned int _pid; /* which child */
94 unsigned int _uid; /* sender's uid */
95 int _status; /* exit code */
96 compat_clock_t _utime;
97 compat_clock_t _stime;
98 } _sigchld;
99
100 /* SIGILL, SIGFPE, SIGSEGV, SIGBUS */
101 struct {
102 unsigned int _addr; /* faulting insn/memory ref. */
103#ifdef __ARCH_SI_TRAPNO
104 int _trapno; /* TRAP # which caused the signal */
105#endif
106 } _sigfault;
107
108 /* SIGPOLL */
109 struct {
110 int _band; /* POLL_IN, POLL_OUT, POLL_MSG */
111 int _fd;
112 } _sigpoll;
113 } _sifields;
114};
115
116struct compat_rt_sigframe {
117 unsigned char save_area[C_ABI_SAVE_AREA_SIZE]; /* caller save area */
118 struct compat_siginfo info;
119 struct compat_ucontext uc;
120};
121
122#define _BLOCKABLE (~(sigmask(SIGKILL) | sigmask(SIGSTOP)))
123
124long compat_sys_rt_sigaction(int sig, struct compat_sigaction __user *act,
125 struct compat_sigaction __user *oact,
126 size_t sigsetsize)
127{
128 struct k_sigaction new_sa, old_sa;
129 int ret = -EINVAL;
130
131 /* XXX: Don't preclude handling different sized sigset_t's. */
132 if (sigsetsize != sizeof(sigset_t))
133 goto out;
134
135 if (act) {
136 compat_uptr_t handler, restorer;
137
138 if (!access_ok(VERIFY_READ, act, sizeof(*act)) ||
139 __get_user(handler, &act->sa_handler) ||
140 __get_user(new_sa.sa.sa_flags, &act->sa_flags) ||
141 __get_user(restorer, &act->sa_restorer) ||
142 __copy_from_user(&new_sa.sa.sa_mask, &act->sa_mask,
143 sizeof(sigset_t)))
144 return -EFAULT;
145 new_sa.sa.sa_handler = compat_ptr(handler);
146 new_sa.sa.sa_restorer = compat_ptr(restorer);
147 }
148
149 ret = do_sigaction(sig, act ? &new_sa : NULL, oact ? &old_sa : NULL);
150
151 if (!ret && oact) {
152 if (!access_ok(VERIFY_WRITE, oact, sizeof(*oact)) ||
153 __put_user(ptr_to_compat(old_sa.sa.sa_handler),
154 &oact->sa_handler) ||
155 __put_user(ptr_to_compat(old_sa.sa.sa_restorer),
156 &oact->sa_restorer) ||
157 __put_user(old_sa.sa.sa_flags, &oact->sa_flags) ||
158 __copy_to_user(&oact->sa_mask, &old_sa.sa.sa_mask,
159 sizeof(sigset_t)))
160 return -EFAULT;
161 }
162out:
163 return ret;
164}
165
166long compat_sys_rt_sigqueueinfo(int pid, int sig,
167 struct compat_siginfo __user *uinfo)
168{
169 siginfo_t info;
170 int ret;
171 mm_segment_t old_fs = get_fs();
172
173 if (copy_siginfo_from_user32(&info, uinfo))
174 return -EFAULT;
175 set_fs(KERNEL_DS);
176 ret = sys_rt_sigqueueinfo(pid, sig, (siginfo_t __force __user *)&info);
177 set_fs(old_fs);
178 return ret;
179}
180
181int copy_siginfo_to_user32(struct compat_siginfo __user *to, siginfo_t *from)
182{
183 int err;
184
185 if (!access_ok(VERIFY_WRITE, to, sizeof(struct compat_siginfo)))
186 return -EFAULT;
187
188 /* If you change siginfo_t structure, please make sure that
189 this code is fixed accordingly.
190 It should never copy any pad contained in the structure
191 to avoid security leaks, but must copy the generic
192 3 ints plus the relevant union member. */
193 err = __put_user(from->si_signo, &to->si_signo);
194 err |= __put_user(from->si_errno, &to->si_errno);
195 err |= __put_user((short)from->si_code, &to->si_code);
196
197 if (from->si_code < 0) {
198 err |= __put_user(from->si_pid, &to->si_pid);
199 err |= __put_user(from->si_uid, &to->si_uid);
200 err |= __put_user(ptr_to_compat(from->si_ptr), &to->si_ptr);
201 } else {
202 /*
203 * First 32bits of unions are always present:
204 * si_pid === si_band === si_tid === si_addr(LS half)
205 */
206 err |= __put_user(from->_sifields._pad[0],
207 &to->_sifields._pad[0]);
208 switch (from->si_code >> 16) {
209 case __SI_FAULT >> 16:
210 break;
211 case __SI_CHLD >> 16:
212 err |= __put_user(from->si_utime, &to->si_utime);
213 err |= __put_user(from->si_stime, &to->si_stime);
214 err |= __put_user(from->si_status, &to->si_status);
215 /* FALL THROUGH */
216 default:
217 case __SI_KILL >> 16:
218 err |= __put_user(from->si_uid, &to->si_uid);
219 break;
220 case __SI_POLL >> 16:
221 err |= __put_user(from->si_fd, &to->si_fd);
222 break;
223 case __SI_TIMER >> 16:
224 err |= __put_user(from->si_overrun, &to->si_overrun);
225 err |= __put_user(ptr_to_compat(from->si_ptr),
226 &to->si_ptr);
227 break;
228 /* This is not generated by the kernel as of now. */
229 case __SI_RT >> 16:
230 case __SI_MESGQ >> 16:
231 err |= __put_user(from->si_uid, &to->si_uid);
232 err |= __put_user(from->si_int, &to->si_int);
233 break;
234 }
235 }
236 return err;
237}
238
239int copy_siginfo_from_user32(siginfo_t *to, struct compat_siginfo __user *from)
240{
241 int err;
242 u32 ptr32;
243
244 if (!access_ok(VERIFY_READ, from, sizeof(struct compat_siginfo)))
245 return -EFAULT;
246
247 err = __get_user(to->si_signo, &from->si_signo);
248 err |= __get_user(to->si_errno, &from->si_errno);
249 err |= __get_user(to->si_code, &from->si_code);
250
251 err |= __get_user(to->si_pid, &from->si_pid);
252 err |= __get_user(to->si_uid, &from->si_uid);
253 err |= __get_user(ptr32, &from->si_ptr);
254 to->si_ptr = compat_ptr(ptr32);
255
256 return err;
257}
258
259long _compat_sys_sigaltstack(const struct compat_sigaltstack __user *uss_ptr,
260 struct compat_sigaltstack __user *uoss_ptr,
261 struct pt_regs *regs)
262{
263 stack_t uss, uoss;
264 int ret;
265 mm_segment_t seg;
266
267 if (uss_ptr) {
268 u32 ptr;
269
270 memset(&uss, 0, sizeof(stack_t));
271 if (!access_ok(VERIFY_READ, uss_ptr, sizeof(*uss_ptr)) ||
272 __get_user(ptr, &uss_ptr->ss_sp) ||
273 __get_user(uss.ss_flags, &uss_ptr->ss_flags) ||
274 __get_user(uss.ss_size, &uss_ptr->ss_size))
275 return -EFAULT;
276 uss.ss_sp = compat_ptr(ptr);
277 }
278 seg = get_fs();
279 set_fs(KERNEL_DS);
280 ret = do_sigaltstack(uss_ptr ? (stack_t __user __force *)&uss : NULL,
281 (stack_t __user __force *)&uoss,
282 (unsigned long)compat_ptr(regs->sp));
283 set_fs(seg);
284 if (ret >= 0 && uoss_ptr) {
285 if (!access_ok(VERIFY_WRITE, uoss_ptr, sizeof(*uoss_ptr)) ||
286 __put_user(ptr_to_compat(uoss.ss_sp), &uoss_ptr->ss_sp) ||
287 __put_user(uoss.ss_flags, &uoss_ptr->ss_flags) ||
288 __put_user(uoss.ss_size, &uoss_ptr->ss_size))
289 ret = -EFAULT;
290 }
291 return ret;
292}
293
294long _compat_sys_rt_sigreturn(struct pt_regs *regs)
295{
296 struct compat_rt_sigframe __user *frame =
297 (struct compat_rt_sigframe __user *) compat_ptr(regs->sp);
298 sigset_t set;
299 long r0;
300
301 if (!access_ok(VERIFY_READ, frame, sizeof(*frame)))
302 goto badframe;
303 if (__copy_from_user(&set, &frame->uc.uc_sigmask, sizeof(set)))
304 goto badframe;
305
306 sigdelsetmask(&set, ~_BLOCKABLE);
307 spin_lock_irq(&current->sighand->siglock);
308 current->blocked = set;
309 recalc_sigpending();
310 spin_unlock_irq(&current->sighand->siglock);
311
312 if (restore_sigcontext(regs, &frame->uc.uc_mcontext, &r0))
313 goto badframe;
314
315 if (_compat_sys_sigaltstack(&frame->uc.uc_stack, NULL, regs) != 0)
316 goto badframe;
317
318 return r0;
319
320badframe:
321 force_sig(SIGSEGV, current);
322 return 0;
323}
324
325/*
326 * Determine which stack to use..
327 */
328static inline void __user *compat_get_sigframe(struct k_sigaction *ka,
329 struct pt_regs *regs,
330 size_t frame_size)
331{
332 unsigned long sp;
333
334 /* Default to using normal stack */
335 sp = (unsigned long)compat_ptr(regs->sp);
336
337 /*
338 * If we are on the alternate signal stack and would overflow
339 * it, don't. Return an always-bogus address instead so we
340 * will die with SIGSEGV.
341 */
342 if (on_sig_stack(sp) && !likely(on_sig_stack(sp - frame_size)))
343 return (void __user __force *)-1UL;
344
345 /* This is the X/Open sanctioned signal stack switching. */
346 if (ka->sa.sa_flags & SA_ONSTACK) {
347 if (sas_ss_flags(sp) == 0)
348 sp = current->sas_ss_sp + current->sas_ss_size;
349 }
350
351 sp -= frame_size;
352 /*
353 * Align the stack pointer according to the TILE ABI,
354 * i.e. so that on function entry (sp & 15) == 0.
355 */
356 sp &= -16UL;
357 return (void __user *) sp;
358}
359
360int compat_setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info,
361 sigset_t *set, struct pt_regs *regs)
362{
363 unsigned long restorer;
364 struct compat_rt_sigframe __user *frame;
365 int err = 0;
366 int usig;
367
368 frame = compat_get_sigframe(ka, regs, sizeof(*frame));
369
370 if (!access_ok(VERIFY_WRITE, frame, sizeof(*frame)))
371 goto give_sigsegv;
372
373 usig = current_thread_info()->exec_domain
374 && current_thread_info()->exec_domain->signal_invmap
375 && sig < 32
376 ? current_thread_info()->exec_domain->signal_invmap[sig]
377 : sig;
378
379 /* Always write at least the signal number for the stack backtracer. */
380 if (ka->sa.sa_flags & SA_SIGINFO) {
381 /* At sigreturn time, restore the callee-save registers too. */
382 err |= copy_siginfo_to_user32(&frame->info, info);
383 regs->flags |= PT_FLAGS_RESTORE_REGS;
384 } else {
385 err |= __put_user(info->si_signo, &frame->info.si_signo);
386 }
387
388 /* Create the ucontext. */
389 err |= __clear_user(&frame->save_area, sizeof(frame->save_area));
390 err |= __put_user(0, &frame->uc.uc_flags);
391 err |= __put_user(0, &frame->uc.uc_link);
392 err |= __put_user(ptr_to_compat((void *)(current->sas_ss_sp)),
393 &frame->uc.uc_stack.ss_sp);
394 err |= __put_user(sas_ss_flags(regs->sp),
395 &frame->uc.uc_stack.ss_flags);
396 err |= __put_user(current->sas_ss_size, &frame->uc.uc_stack.ss_size);
397 err |= setup_sigcontext(&frame->uc.uc_mcontext, regs);
398 err |= __copy_to_user(&frame->uc.uc_sigmask, set, sizeof(*set));
399 if (err)
400 goto give_sigsegv;
401
402 restorer = VDSO_BASE;
403 if (ka->sa.sa_flags & SA_RESTORER)
404 restorer = ptr_to_compat_reg(ka->sa.sa_restorer);
405
406 /*
407 * Set up registers for signal handler.
408 * Registers that we don't modify keep the value they had from
409 * user-space at the time we took the signal.
410 */
411 regs->pc = ptr_to_compat_reg(ka->sa.sa_handler);
412 regs->ex1 = PL_ICS_EX1(USER_PL, 1); /* set crit sec in handler */
413 regs->sp = ptr_to_compat_reg(frame);
414 regs->lr = restorer;
415 regs->regs[0] = (unsigned long) usig;
416
417 if (ka->sa.sa_flags & SA_SIGINFO) {
418 /* Need extra arguments, so mark to restore caller-saves. */
419 regs->regs[1] = ptr_to_compat_reg(&frame->info);
420 regs->regs[2] = ptr_to_compat_reg(&frame->uc);
421 regs->flags |= PT_FLAGS_CALLER_SAVES;
422 }
423
424 /*
425 * Notify any tracer that was single-stepping it.
426 * The tracer may want to single-step inside the
427 * handler too.
428 */
429 if (test_thread_flag(TIF_SINGLESTEP))
430 ptrace_notify(SIGTRAP);
431
432 return 0;
433
434give_sigsegv:
435 force_sigsegv(sig, current);
436 return -EFAULT;
437}
diff --git a/arch/tile/kernel/early_printk.c b/arch/tile/kernel/early_printk.c
new file mode 100644
index 000000000000..2c54fd43a8a0
--- /dev/null
+++ b/arch/tile/kernel/early_printk.c
@@ -0,0 +1,109 @@
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#include <linux/console.h>
16#include <linux/kernel.h>
17#include <linux/init.h>
18#include <linux/string.h>
19#include <asm/setup.h>
20#include <hv/hypervisor.h>
21
22static void early_hv_write(struct console *con, const char *s, unsigned n)
23{
24 hv_console_write((HV_VirtAddr) s, n);
25}
26
27static struct console early_hv_console = {
28 .name = "earlyhv",
29 .write = early_hv_write,
30 .flags = CON_PRINTBUFFER,
31 .index = -1,
32};
33
34/* Direct interface for emergencies */
35static struct console *early_console = &early_hv_console;
36static int early_console_initialized;
37static int early_console_complete;
38
39static void early_vprintk(const char *fmt, va_list ap)
40{
41 char buf[512];
42 int n = vscnprintf(buf, sizeof(buf), fmt, ap);
43 early_console->write(early_console, buf, n);
44}
45
46void early_printk(const char *fmt, ...)
47{
48 va_list ap;
49 va_start(ap, fmt);
50 early_vprintk(fmt, ap);
51 va_end(ap);
52}
53
54void early_panic(const char *fmt, ...)
55{
56 va_list ap;
57 raw_local_irq_disable_all();
58 va_start(ap, fmt);
59 early_printk("Kernel panic - not syncing: ");
60 early_vprintk(fmt, ap);
61 early_console->write(early_console, "\n", 1);
62 va_end(ap);
63 dump_stack();
64 hv_halt();
65}
66
67static int __initdata keep_early;
68
69static int __init setup_early_printk(char *str)
70{
71 if (early_console_initialized)
72 return 1;
73
74 if (str != NULL && strncmp(str, "keep", 4) == 0)
75 keep_early = 1;
76
77 early_console = &early_hv_console;
78 early_console_initialized = 1;
79 register_console(early_console);
80
81 return 0;
82}
83
84void __init disable_early_printk(void)
85{
86 early_console_complete = 1;
87 if (!early_console_initialized || !early_console)
88 return;
89 if (!keep_early) {
90 early_printk("disabling early console\n");
91 unregister_console(early_console);
92 early_console_initialized = 0;
93 } else {
94 early_printk("keeping early console\n");
95 }
96}
97
98void warn_early_printk(void)
99{
100 if (early_console_complete || early_console_initialized)
101 return;
102 early_printk("\
103Machine shutting down before console output is fully initialized.\n\
104You may wish to reboot and add the option 'earlyprintk' to your\n\
105boot command line to see any diagnostic early console output.\n\
106");
107}
108
109early_param("earlyprintk", setup_early_printk);
diff --git a/arch/tile/kernel/entry.S b/arch/tile/kernel/entry.S
new file mode 100644
index 000000000000..3d01383b1b0e
--- /dev/null
+++ b/arch/tile/kernel/entry.S
@@ -0,0 +1,141 @@
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#include <linux/linkage.h>
16#include <linux/unistd.h>
17#include <asm/irqflags.h>
18#include <arch/abi.h>
19
20#ifdef __tilegx__
21#define bnzt bnezt
22#endif
23
24STD_ENTRY(current_text_addr)
25 { move r0, lr; jrp lr }
26 STD_ENDPROC(current_text_addr)
27
28STD_ENTRY(_sim_syscall)
29 /*
30 * Wait for r0-r9 to be ready (and lr on the off chance we
31 * want the syscall to locate its caller), then make a magic
32 * simulator syscall.
33 *
34 * We carefully stall until the registers are readable in case they
35 * are the target of a slow load, etc. so that tile-sim will
36 * definitely be able to read all of them inside the magic syscall.
37 *
38 * Technically this is wrong for r3-r9 and lr, since an interrupt
39 * could come in and restore the registers with a slow load right
40 * before executing the mtspr. We may need to modify tile-sim to
41 * explicitly stall for this case, but we do not yet have
42 * a way to implement such a stall.
43 */
44 { and zero, lr, r9 ; and zero, r8, r7 }
45 { and zero, r6, r5 ; and zero, r4, r3 }
46 { and zero, r2, r1 ; mtspr SIM_CONTROL, r0 }
47 { jrp lr }
48 STD_ENDPROC(_sim_syscall)
49
50/*
51 * Implement execve(). The i386 code has a note that forking from kernel
52 * space results in no copy on write until the execve, so we should be
53 * careful not to write to the stack here.
54 */
55STD_ENTRY(kernel_execve)
56 moveli TREG_SYSCALL_NR_NAME, __NR_execve
57 swint1
58 jrp lr
59 STD_ENDPROC(kernel_execve)
60
61/* Delay a fixed number of cycles. */
62STD_ENTRY(__delay)
63 { addi r0, r0, -1; bnzt r0, . }
64 jrp lr
65 STD_ENDPROC(__delay)
66
67/*
68 * We don't run this function directly, but instead copy it to a page
69 * we map into every user process. See vdso_setup().
70 *
71 * Note that libc has a copy of this function that it uses to compare
72 * against the PC when a stack backtrace ends, so if this code is
73 * changed, the libc implementation(s) should also be updated.
74 */
75 .pushsection .data
76ENTRY(__rt_sigreturn)
77 moveli TREG_SYSCALL_NR_NAME,__NR_rt_sigreturn
78 swint1
79 ENDPROC(__rt_sigreturn)
80 ENTRY(__rt_sigreturn_end)
81 .popsection
82
83STD_ENTRY(dump_stack)
84 { move r2, lr; lnk r1 }
85 { move r4, r52; addli r1, r1, dump_stack - . }
86 { move r3, sp; j _dump_stack }
87 jrp lr /* keep backtracer happy */
88 STD_ENDPROC(dump_stack)
89
90STD_ENTRY(KBacktraceIterator_init_current)
91 { move r2, lr; lnk r1 }
92 { move r4, r52; addli r1, r1, KBacktraceIterator_init_current - . }
93 { move r3, sp; j _KBacktraceIterator_init_current }
94 jrp lr /* keep backtracer happy */
95 STD_ENDPROC(KBacktraceIterator_init_current)
96
97/*
98 * Reset our stack to r1/r2 (sp and ksp0+cpu respectively), then
99 * free the old stack (passed in r0) and re-invoke cpu_idle().
100 * We update sp and ksp0 simultaneously to avoid backtracer warnings.
101 */
102STD_ENTRY(cpu_idle_on_new_stack)
103 {
104 move sp, r1
105 mtspr SYSTEM_SAVE_1_0, r2
106 }
107 jal free_thread_info
108 j cpu_idle
109 STD_ENDPROC(cpu_idle_on_new_stack)
110
111/* Loop forever on a nap during SMP boot. */
112STD_ENTRY(smp_nap)
113 nap
114 j smp_nap /* we are not architecturally guaranteed not to exit nap */
115 jrp lr /* clue in the backtracer */
116 STD_ENDPROC(smp_nap)
117
118/*
119 * Enable interrupts racelessly and then nap until interrupted.
120 * This function's _cpu_idle_nap address is special; see intvec.S.
121 * When interrupted at _cpu_idle_nap, we bump the PC forward 8, and
122 * as a result return to the function that called _cpu_idle().
123 */
124STD_ENTRY(_cpu_idle)
125 {
126 lnk r0
127 movei r1, 1
128 }
129 {
130 addli r0, r0, _cpu_idle_nap - .
131 mtspr INTERRUPT_CRITICAL_SECTION, r1
132 }
133 IRQ_ENABLE(r2, r3) /* unmask, but still with ICS set */
134 mtspr EX_CONTEXT_1_1, r1 /* PL1, ICS clear */
135 mtspr EX_CONTEXT_1_0, r0
136 iret
137 .global _cpu_idle_nap
138_cpu_idle_nap:
139 nap
140 jrp lr
141 STD_ENDPROC(_cpu_idle)
diff --git a/arch/tile/kernel/hardwall.c b/arch/tile/kernel/hardwall.c
new file mode 100644
index 000000000000..584b965dc824
--- /dev/null
+++ b/arch/tile/kernel/hardwall.c
@@ -0,0 +1,796 @@
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#include <linux/fs.h>
16#include <linux/proc_fs.h>
17#include <linux/seq_file.h>
18#include <linux/rwsem.h>
19#include <linux/kprobes.h>
20#include <linux/sched.h>
21#include <linux/hardirq.h>
22#include <linux/uaccess.h>
23#include <linux/smp.h>
24#include <linux/cdev.h>
25#include <linux/compat.h>
26#include <asm/hardwall.h>
27#include <asm/traps.h>
28#include <asm/siginfo.h>
29#include <asm/irq_regs.h>
30
31#include <arch/interrupts.h>
32#include <arch/spr_def.h>
33
34
35/*
36 * This data structure tracks the rectangle data, etc., associated
37 * one-to-one with a "struct file *" from opening HARDWALL_FILE.
38 * Note that the file's private data points back to this structure.
39 */
40struct hardwall_info {
41 struct list_head list; /* "rectangles" list */
42 struct list_head task_head; /* head of tasks in this hardwall */
43 int ulhc_x; /* upper left hand corner x coord */
44 int ulhc_y; /* upper left hand corner y coord */
45 int width; /* rectangle width */
46 int height; /* rectangle height */
47 int teardown_in_progress; /* are we tearing this one down? */
48};
49
50/* Currently allocated hardwall rectangles */
51static LIST_HEAD(rectangles);
52
53/*
54 * Guard changes to the hardwall data structures.
55 * This could be finer grained (e.g. one lock for the list of hardwall
56 * rectangles, then separate embedded locks for each one's list of tasks),
57 * but there are subtle correctness issues when trying to start with
58 * a task's "hardwall" pointer and lock the correct rectangle's embedded
59 * lock in the presence of a simultaneous deactivation, so it seems
60 * easier to have a single lock, given that none of these data
61 * structures are touched very frequently during normal operation.
62 */
63static DEFINE_SPINLOCK(hardwall_lock);
64
65/* Allow disabling UDN access. */
66static int udn_disabled;
67static int __init noudn(char *str)
68{
69 pr_info("User-space UDN access is disabled\n");
70 udn_disabled = 1;
71 return 0;
72}
73early_param("noudn", noudn);
74
75
76/*
77 * Low-level primitives
78 */
79
80/* Set a CPU bit if the CPU is online. */
81#define cpu_online_set(cpu, dst) do { \
82 if (cpu_online(cpu)) \
83 cpumask_set_cpu(cpu, dst); \
84} while (0)
85
86
87/* Does the given rectangle contain the given x,y coordinate? */
88static int contains(struct hardwall_info *r, int x, int y)
89{
90 return (x >= r->ulhc_x && x < r->ulhc_x + r->width) &&
91 (y >= r->ulhc_y && y < r->ulhc_y + r->height);
92}
93
94/* Compute the rectangle parameters and validate the cpumask. */
95static int setup_rectangle(struct hardwall_info *r, struct cpumask *mask)
96{
97 int x, y, cpu, ulhc, lrhc;
98
99 /* The first cpu is the ULHC, the last the LRHC. */
100 ulhc = find_first_bit(cpumask_bits(mask), nr_cpumask_bits);
101 lrhc = find_last_bit(cpumask_bits(mask), nr_cpumask_bits);
102
103 /* Compute the rectangle attributes from the cpus. */
104 r->ulhc_x = cpu_x(ulhc);
105 r->ulhc_y = cpu_y(ulhc);
106 r->width = cpu_x(lrhc) - r->ulhc_x + 1;
107 r->height = cpu_y(lrhc) - r->ulhc_y + 1;
108
109 /* Width and height must be positive */
110 if (r->width <= 0 || r->height <= 0)
111 return -EINVAL;
112
113 /* Confirm that the cpumask is exactly the rectangle. */
114 for (y = 0, cpu = 0; y < smp_height; ++y)
115 for (x = 0; x < smp_width; ++x, ++cpu)
116 if (cpumask_test_cpu(cpu, mask) != contains(r, x, y))
117 return -EINVAL;
118
119 /*
120 * Note that offline cpus can't be drained when this UDN
121 * rectangle eventually closes. We used to detect this
122 * situation and print a warning, but it annoyed users and
123 * they ignored it anyway, so now we just return without a
124 * warning.
125 */
126 return 0;
127}
128
129/* Do the two given rectangles overlap on any cpu? */
130static int overlaps(struct hardwall_info *a, struct hardwall_info *b)
131{
132 return a->ulhc_x + a->width > b->ulhc_x && /* A not to the left */
133 b->ulhc_x + b->width > a->ulhc_x && /* B not to the left */
134 a->ulhc_y + a->height > b->ulhc_y && /* A not above */
135 b->ulhc_y + b->height > a->ulhc_y; /* B not above */
136}
137
138
139/*
140 * Hardware management of hardwall setup, teardown, trapping,
141 * and enabling/disabling PL0 access to the networks.
142 */
143
144/* Bit field values to mask together for writes to SPR_XDN_DIRECTION_PROTECT */
145enum direction_protect {
146 N_PROTECT = (1 << 0),
147 E_PROTECT = (1 << 1),
148 S_PROTECT = (1 << 2),
149 W_PROTECT = (1 << 3)
150};
151
152static void enable_firewall_interrupts(void)
153{
154 raw_local_irq_unmask_now(INT_UDN_FIREWALL);
155}
156
157static void disable_firewall_interrupts(void)
158{
159 raw_local_irq_mask_now(INT_UDN_FIREWALL);
160}
161
162/* Set up hardwall on this cpu based on the passed hardwall_info. */
163static void hardwall_setup_ipi_func(void *info)
164{
165 struct hardwall_info *r = info;
166 int cpu = smp_processor_id();
167 int x = cpu % smp_width;
168 int y = cpu / smp_width;
169 int bits = 0;
170 if (x == r->ulhc_x)
171 bits |= W_PROTECT;
172 if (x == r->ulhc_x + r->width - 1)
173 bits |= E_PROTECT;
174 if (y == r->ulhc_y)
175 bits |= N_PROTECT;
176 if (y == r->ulhc_y + r->height - 1)
177 bits |= S_PROTECT;
178 BUG_ON(bits == 0);
179 __insn_mtspr(SPR_UDN_DIRECTION_PROTECT, bits);
180 enable_firewall_interrupts();
181
182}
183
184/* Set up all cpus on edge of rectangle to enable/disable hardwall SPRs. */
185static void hardwall_setup(struct hardwall_info *r)
186{
187 int x, y, cpu, delta;
188 struct cpumask rect_cpus;
189
190 cpumask_clear(&rect_cpus);
191
192 /* First include the top and bottom edges */
193 cpu = r->ulhc_y * smp_width + r->ulhc_x;
194 delta = (r->height - 1) * smp_width;
195 for (x = 0; x < r->width; ++x, ++cpu) {
196 cpu_online_set(cpu, &rect_cpus);
197 cpu_online_set(cpu + delta, &rect_cpus);
198 }
199
200 /* Then the left and right edges */
201 cpu -= r->width;
202 delta = r->width - 1;
203 for (y = 0; y < r->height; ++y, cpu += smp_width) {
204 cpu_online_set(cpu, &rect_cpus);
205 cpu_online_set(cpu + delta, &rect_cpus);
206 }
207
208 /* Then tell all the cpus to set up their protection SPR */
209 on_each_cpu_mask(&rect_cpus, hardwall_setup_ipi_func, r, 1);
210}
211
212void __kprobes do_hardwall_trap(struct pt_regs* regs, int fault_num)
213{
214 struct hardwall_info *rect;
215 struct task_struct *p;
216 struct siginfo info;
217 int x, y;
218 int cpu = smp_processor_id();
219 int found_processes;
220 unsigned long flags;
221
222 struct pt_regs *old_regs = set_irq_regs(regs);
223 irq_enter();
224
225 /* This tile trapped a network access; find the rectangle. */
226 x = cpu % smp_width;
227 y = cpu / smp_width;
228 spin_lock_irqsave(&hardwall_lock, flags);
229 list_for_each_entry(rect, &rectangles, list) {
230 if (contains(rect, x, y))
231 break;
232 }
233
234 /*
235 * It shouldn't be possible not to find this cpu on the
236 * rectangle list, since only cpus in rectangles get hardwalled.
237 * The hardwall is only removed after the UDN is drained.
238 */
239 BUG_ON(&rect->list == &rectangles);
240
241 /*
242 * If we already started teardown on this hardwall, don't worry;
243 * the abort signal has been sent and we are just waiting for things
244 * to quiesce.
245 */
246 if (rect->teardown_in_progress) {
247 pr_notice("cpu %d: detected hardwall violation %#lx"
248 " while teardown already in progress\n",
249 cpu, (long) __insn_mfspr(SPR_UDN_DIRECTION_PROTECT));
250 goto done;
251 }
252
253 /*
254 * Kill off any process that is activated in this rectangle.
255 * We bypass security to deliver the signal, since it must be
256 * one of the activated processes that generated the UDN
257 * message that caused this trap, and all the activated
258 * processes shared a single open file so are pretty tightly
259 * bound together from a security point of view to begin with.
260 */
261 rect->teardown_in_progress = 1;
262 wmb(); /* Ensure visibility of rectangle before notifying processes. */
263 pr_notice("cpu %d: detected hardwall violation %#lx...\n",
264 cpu, (long) __insn_mfspr(SPR_UDN_DIRECTION_PROTECT));
265 info.si_signo = SIGILL;
266 info.si_errno = 0;
267 info.si_code = ILL_HARDWALL;
268 found_processes = 0;
269 list_for_each_entry(p, &rect->task_head, thread.hardwall_list) {
270 BUG_ON(p->thread.hardwall != rect);
271 if (p->sighand) {
272 found_processes = 1;
273 pr_notice("hardwall: killing %d\n", p->pid);
274 spin_lock(&p->sighand->siglock);
275 __group_send_sig_info(info.si_signo, &info, p);
276 spin_unlock(&p->sighand->siglock);
277 }
278 }
279 if (!found_processes)
280 pr_notice("hardwall: no associated processes!\n");
281
282 done:
283 spin_unlock_irqrestore(&hardwall_lock, flags);
284
285 /*
286 * We have to disable firewall interrupts now, or else when we
287 * return from this handler, we will simply re-interrupt back to
288 * it. However, we can't clear the protection bits, since we
289 * haven't yet drained the network, and that would allow packets
290 * to cross out of the hardwall region.
291 */
292 disable_firewall_interrupts();
293
294 irq_exit();
295 set_irq_regs(old_regs);
296}
297
298/* Allow access from user space to the UDN. */
299void grant_network_mpls(void)
300{
301 __insn_mtspr(SPR_MPL_UDN_ACCESS_SET_0, 1);
302 __insn_mtspr(SPR_MPL_UDN_AVAIL_SET_0, 1);
303 __insn_mtspr(SPR_MPL_UDN_COMPLETE_SET_0, 1);
304 __insn_mtspr(SPR_MPL_UDN_TIMER_SET_0, 1);
305#if !CHIP_HAS_REV1_XDN()
306 __insn_mtspr(SPR_MPL_UDN_REFILL_SET_0, 1);
307 __insn_mtspr(SPR_MPL_UDN_CA_SET_0, 1);
308#endif
309}
310
311/* Deny access from user space to the UDN. */
312void restrict_network_mpls(void)
313{
314 __insn_mtspr(SPR_MPL_UDN_ACCESS_SET_1, 1);
315 __insn_mtspr(SPR_MPL_UDN_AVAIL_SET_1, 1);
316 __insn_mtspr(SPR_MPL_UDN_COMPLETE_SET_1, 1);
317 __insn_mtspr(SPR_MPL_UDN_TIMER_SET_1, 1);
318#if !CHIP_HAS_REV1_XDN()
319 __insn_mtspr(SPR_MPL_UDN_REFILL_SET_1, 1);
320 __insn_mtspr(SPR_MPL_UDN_CA_SET_1, 1);
321#endif
322}
323
324
325/*
326 * Code to create, activate, deactivate, and destroy hardwall rectangles.
327 */
328
329/* Create a hardwall for the given rectangle */
330static struct hardwall_info *hardwall_create(
331 size_t size, const unsigned char __user *bits)
332{
333 struct hardwall_info *iter, *rect;
334 struct cpumask mask;
335 unsigned long flags;
336 int rc;
337
338 /* Reject crazy sizes out of hand, a la sys_mbind(). */
339 if (size > PAGE_SIZE)
340 return ERR_PTR(-EINVAL);
341
342 /* Copy whatever fits into a cpumask. */
343 if (copy_from_user(&mask, bits, min(sizeof(struct cpumask), size)))
344 return ERR_PTR(-EFAULT);
345
346 /*
347 * If the size was short, clear the rest of the mask;
348 * otherwise validate that the rest of the user mask was zero
349 * (we don't try hard to be efficient when validating huge masks).
350 */
351 if (size < sizeof(struct cpumask)) {
352 memset((char *)&mask + size, 0, sizeof(struct cpumask) - size);
353 } else if (size > sizeof(struct cpumask)) {
354 size_t i;
355 for (i = sizeof(struct cpumask); i < size; ++i) {
356 char c;
357 if (get_user(c, &bits[i]))
358 return ERR_PTR(-EFAULT);
359 if (c)
360 return ERR_PTR(-EINVAL);
361 }
362 }
363
364 /* Allocate a new rectangle optimistically. */
365 rect = kmalloc(sizeof(struct hardwall_info),
366 GFP_KERNEL | __GFP_ZERO);
367 if (rect == NULL)
368 return ERR_PTR(-ENOMEM);
369 INIT_LIST_HEAD(&rect->task_head);
370
371 /* Compute the rectangle size and validate that it's plausible. */
372 rc = setup_rectangle(rect, &mask);
373 if (rc != 0) {
374 kfree(rect);
375 return ERR_PTR(rc);
376 }
377
378 /* Confirm it doesn't overlap and add it to the list. */
379 spin_lock_irqsave(&hardwall_lock, flags);
380 list_for_each_entry(iter, &rectangles, list) {
381 if (overlaps(iter, rect)) {
382 spin_unlock_irqrestore(&hardwall_lock, flags);
383 kfree(rect);
384 return ERR_PTR(-EBUSY);
385 }
386 }
387 list_add_tail(&rect->list, &rectangles);
388 spin_unlock_irqrestore(&hardwall_lock, flags);
389
390 /* Set up appropriate hardwalling on all affected cpus. */
391 hardwall_setup(rect);
392
393 return rect;
394}
395
396/* Activate a given hardwall on this cpu for this process. */
397static int hardwall_activate(struct hardwall_info *rect)
398{
399 int cpu, x, y;
400 unsigned long flags;
401 struct task_struct *p = current;
402 struct thread_struct *ts = &p->thread;
403
404 /* Require a rectangle. */
405 if (rect == NULL)
406 return -ENODATA;
407
408 /* Not allowed to activate a rectangle that is being torn down. */
409 if (rect->teardown_in_progress)
410 return -EINVAL;
411
412 /*
413 * Get our affinity; if we're not bound to this tile uniquely,
414 * we can't access the network registers.
415 */
416 if (cpumask_weight(&p->cpus_allowed) != 1)
417 return -EPERM;
418
419 /* Make sure we are bound to a cpu in this rectangle. */
420 cpu = smp_processor_id();
421 BUG_ON(cpumask_first(&p->cpus_allowed) != cpu);
422 x = cpu_x(cpu);
423 y = cpu_y(cpu);
424 if (!contains(rect, x, y))
425 return -EINVAL;
426
427 /* If we are already bound to this hardwall, it's a no-op. */
428 if (ts->hardwall) {
429 BUG_ON(ts->hardwall != rect);
430 return 0;
431 }
432
433 /* Success! This process gets to use the user networks on this cpu. */
434 ts->hardwall = rect;
435 spin_lock_irqsave(&hardwall_lock, flags);
436 list_add(&ts->hardwall_list, &rect->task_head);
437 spin_unlock_irqrestore(&hardwall_lock, flags);
438 grant_network_mpls();
439 printk(KERN_DEBUG "Pid %d (%s) activated for hardwall: cpu %d\n",
440 p->pid, p->comm, cpu);
441 return 0;
442}
443
444/*
445 * Deactivate a task's hardwall. Must hold hardwall_lock.
446 * This method may be called from free_task(), so we don't want to
447 * rely on too many fields of struct task_struct still being valid.
448 * We assume the cpus_allowed, pid, and comm fields are still valid.
449 */
450static void _hardwall_deactivate(struct task_struct *task)
451{
452 struct thread_struct *ts = &task->thread;
453
454 if (cpumask_weight(&task->cpus_allowed) != 1) {
455 pr_err("pid %d (%s) releasing networks with"
456 " an affinity mask containing %d cpus!\n",
457 task->pid, task->comm,
458 cpumask_weight(&task->cpus_allowed));
459 BUG();
460 }
461
462 BUG_ON(ts->hardwall == NULL);
463 ts->hardwall = NULL;
464 list_del(&ts->hardwall_list);
465 if (task == current)
466 restrict_network_mpls();
467}
468
469/* Deactivate a task's hardwall. */
470int hardwall_deactivate(struct task_struct *task)
471{
472 unsigned long flags;
473 int activated;
474
475 spin_lock_irqsave(&hardwall_lock, flags);
476 activated = (task->thread.hardwall != NULL);
477 if (activated)
478 _hardwall_deactivate(task);
479 spin_unlock_irqrestore(&hardwall_lock, flags);
480
481 if (!activated)
482 return -EINVAL;
483
484 printk(KERN_DEBUG "Pid %d (%s) deactivated for hardwall: cpu %d\n",
485 task->pid, task->comm, smp_processor_id());
486 return 0;
487}
488
489/* Stop a UDN switch before draining the network. */
490static void stop_udn_switch(void *ignored)
491{
492#if !CHIP_HAS_REV1_XDN()
493 /* Freeze the switch and the demux. */
494 __insn_mtspr(SPR_UDN_SP_FREEZE,
495 SPR_UDN_SP_FREEZE__SP_FRZ_MASK |
496 SPR_UDN_SP_FREEZE__DEMUX_FRZ_MASK |
497 SPR_UDN_SP_FREEZE__NON_DEST_EXT_MASK);
498#endif
499}
500
501/* Drain all the state from a stopped switch. */
502static void drain_udn_switch(void *ignored)
503{
504#if !CHIP_HAS_REV1_XDN()
505 int i;
506 int from_tile_words, ca_count;
507
508 /* Empty out the 5 switch point fifos. */
509 for (i = 0; i < 5; i++) {
510 int words, j;
511 __insn_mtspr(SPR_UDN_SP_FIFO_SEL, i);
512 words = __insn_mfspr(SPR_UDN_SP_STATE) & 0xF;
513 for (j = 0; j < words; j++)
514 (void) __insn_mfspr(SPR_UDN_SP_FIFO_DATA);
515 BUG_ON((__insn_mfspr(SPR_UDN_SP_STATE) & 0xF) != 0);
516 }
517
518 /* Dump out the 3 word fifo at top. */
519 from_tile_words = (__insn_mfspr(SPR_UDN_DEMUX_STATUS) >> 10) & 0x3;
520 for (i = 0; i < from_tile_words; i++)
521 (void) __insn_mfspr(SPR_UDN_DEMUX_WRITE_FIFO);
522
523 /* Empty out demuxes. */
524 while (__insn_mfspr(SPR_UDN_DATA_AVAIL) & (1 << 0))
525 (void) __tile_udn0_receive();
526 while (__insn_mfspr(SPR_UDN_DATA_AVAIL) & (1 << 1))
527 (void) __tile_udn1_receive();
528 while (__insn_mfspr(SPR_UDN_DATA_AVAIL) & (1 << 2))
529 (void) __tile_udn2_receive();
530 while (__insn_mfspr(SPR_UDN_DATA_AVAIL) & (1 << 3))
531 (void) __tile_udn3_receive();
532 BUG_ON((__insn_mfspr(SPR_UDN_DATA_AVAIL) & 0xF) != 0);
533
534 /* Empty out catch all. */
535 ca_count = __insn_mfspr(SPR_UDN_DEMUX_CA_COUNT);
536 for (i = 0; i < ca_count; i++)
537 (void) __insn_mfspr(SPR_UDN_CA_DATA);
538 BUG_ON(__insn_mfspr(SPR_UDN_DEMUX_CA_COUNT) != 0);
539
540 /* Clear demux logic. */
541 __insn_mtspr(SPR_UDN_DEMUX_CTL, 1);
542
543 /*
544 * Write switch state; experimentation indicates that 0xc3000
545 * is an idle switch point.
546 */
547 for (i = 0; i < 5; i++) {
548 __insn_mtspr(SPR_UDN_SP_FIFO_SEL, i);
549 __insn_mtspr(SPR_UDN_SP_STATE, 0xc3000);
550 }
551#endif
552}
553
554/* Reset random UDN state registers at boot up and during hardwall teardown. */
555void reset_network_state(void)
556{
557#if !CHIP_HAS_REV1_XDN()
558 /* Reset UDN coordinates to their standard value */
559 unsigned int cpu = smp_processor_id();
560 unsigned int x = cpu % smp_width;
561 unsigned int y = cpu / smp_width;
562#endif
563
564 if (udn_disabled)
565 return;
566
567#if !CHIP_HAS_REV1_XDN()
568 __insn_mtspr(SPR_UDN_TILE_COORD, (x << 18) | (y << 7));
569
570 /* Set demux tags to predefined values and enable them. */
571 __insn_mtspr(SPR_UDN_TAG_VALID, 0xf);
572 __insn_mtspr(SPR_UDN_TAG_0, (1 << 0));
573 __insn_mtspr(SPR_UDN_TAG_1, (1 << 1));
574 __insn_mtspr(SPR_UDN_TAG_2, (1 << 2));
575 __insn_mtspr(SPR_UDN_TAG_3, (1 << 3));
576#endif
577
578 /* Clear out other random registers so we have a clean slate. */
579 __insn_mtspr(SPR_UDN_AVAIL_EN, 0);
580 __insn_mtspr(SPR_UDN_DEADLOCK_TIMEOUT, 0);
581#if !CHIP_HAS_REV1_XDN()
582 __insn_mtspr(SPR_UDN_REFILL_EN, 0);
583 __insn_mtspr(SPR_UDN_DEMUX_QUEUE_SEL, 0);
584 __insn_mtspr(SPR_UDN_SP_FIFO_SEL, 0);
585#endif
586
587 /* Start the switch and demux. */
588#if !CHIP_HAS_REV1_XDN()
589 __insn_mtspr(SPR_UDN_SP_FREEZE, 0);
590#endif
591}
592
593/* Restart a UDN switch after draining. */
594static void restart_udn_switch(void *ignored)
595{
596 reset_network_state();
597
598 /* Disable firewall interrupts. */
599 __insn_mtspr(SPR_UDN_DIRECTION_PROTECT, 0);
600 disable_firewall_interrupts();
601}
602
603/* Build a struct cpumask containing all valid tiles in bounding rectangle. */
604static void fill_mask(struct hardwall_info *r, struct cpumask *result)
605{
606 int x, y, cpu;
607
608 cpumask_clear(result);
609
610 cpu = r->ulhc_y * smp_width + r->ulhc_x;
611 for (y = 0; y < r->height; ++y, cpu += smp_width - r->width) {
612 for (x = 0; x < r->width; ++x, ++cpu)
613 cpu_online_set(cpu, result);
614 }
615}
616
617/* Last reference to a hardwall is gone, so clear the network. */
618static void hardwall_destroy(struct hardwall_info *rect)
619{
620 struct task_struct *task;
621 unsigned long flags;
622 struct cpumask mask;
623
624 /* Make sure this file actually represents a rectangle. */
625 if (rect == NULL)
626 return;
627
628 /*
629 * Deactivate any remaining tasks. It's possible to race with
630 * some other thread that is exiting and hasn't yet called
631 * deactivate (when freeing its thread_info), so we carefully
632 * deactivate any remaining tasks before freeing the
633 * hardwall_info object itself.
634 */
635 spin_lock_irqsave(&hardwall_lock, flags);
636 list_for_each_entry(task, &rect->task_head, thread.hardwall_list)
637 _hardwall_deactivate(task);
638 spin_unlock_irqrestore(&hardwall_lock, flags);
639
640 /* Drain the UDN. */
641 printk(KERN_DEBUG "Clearing hardwall rectangle %dx%d %d,%d\n",
642 rect->width, rect->height, rect->ulhc_x, rect->ulhc_y);
643 fill_mask(rect, &mask);
644 on_each_cpu_mask(&mask, stop_udn_switch, NULL, 1);
645 on_each_cpu_mask(&mask, drain_udn_switch, NULL, 1);
646
647 /* Restart switch and disable firewall. */
648 on_each_cpu_mask(&mask, restart_udn_switch, NULL, 1);
649
650 /* Now free the rectangle from the list. */
651 spin_lock_irqsave(&hardwall_lock, flags);
652 BUG_ON(!list_empty(&rect->task_head));
653 list_del(&rect->list);
654 spin_unlock_irqrestore(&hardwall_lock, flags);
655 kfree(rect);
656}
657
658
659/*
660 * Dump hardwall state via /proc; initialized in arch/tile/sys/proc.c.
661 */
662int proc_tile_hardwall_show(struct seq_file *sf, void *v)
663{
664 struct hardwall_info *r;
665
666 if (udn_disabled) {
667 seq_printf(sf, "%dx%d 0,0 pids:\n", smp_width, smp_height);
668 return 0;
669 }
670
671 spin_lock_irq(&hardwall_lock);
672 list_for_each_entry(r, &rectangles, list) {
673 struct task_struct *p;
674 seq_printf(sf, "%dx%d %d,%d pids:",
675 r->width, r->height, r->ulhc_x, r->ulhc_y);
676 list_for_each_entry(p, &r->task_head, thread.hardwall_list) {
677 unsigned int cpu = cpumask_first(&p->cpus_allowed);
678 unsigned int x = cpu % smp_width;
679 unsigned int y = cpu / smp_width;
680 seq_printf(sf, " %d@%d,%d", p->pid, x, y);
681 }
682 seq_printf(sf, "\n");
683 }
684 spin_unlock_irq(&hardwall_lock);
685 return 0;
686}
687
688
689/*
690 * Character device support via ioctl/close.
691 */
692
693static long hardwall_ioctl(struct file *file, unsigned int a, unsigned long b)
694{
695 struct hardwall_info *rect = file->private_data;
696
697 if (_IOC_TYPE(a) != HARDWALL_IOCTL_BASE)
698 return -EINVAL;
699
700 switch (_IOC_NR(a)) {
701 case _HARDWALL_CREATE:
702 if (udn_disabled)
703 return -ENOSYS;
704 if (rect != NULL)
705 return -EALREADY;
706 rect = hardwall_create(_IOC_SIZE(a),
707 (const unsigned char __user *)b);
708 if (IS_ERR(rect))
709 return PTR_ERR(rect);
710 file->private_data = rect;
711 return 0;
712
713 case _HARDWALL_ACTIVATE:
714 return hardwall_activate(rect);
715
716 case _HARDWALL_DEACTIVATE:
717 if (current->thread.hardwall != rect)
718 return -EINVAL;
719 return hardwall_deactivate(current);
720
721 default:
722 return -EINVAL;
723 }
724}
725
726#ifdef CONFIG_COMPAT
727static long hardwall_compat_ioctl(struct file *file,
728 unsigned int a, unsigned long b)
729{
730 /* Sign-extend the argument so it can be used as a pointer. */
731 return hardwall_ioctl(file, a, (unsigned long)compat_ptr(b));
732}
733#endif
734
735/* The user process closed the file; revoke access to user networks. */
736static int hardwall_flush(struct file *file, fl_owner_t owner)
737{
738 struct hardwall_info *rect = file->private_data;
739 struct task_struct *task, *tmp;
740 unsigned long flags;
741
742 if (rect) {
743 /*
744 * NOTE: if multiple threads are activated on this hardwall
745 * file, the other threads will continue having access to the
746 * UDN until they are context-switched out and back in again.
747 *
748 * NOTE: A NULL files pointer means the task is being torn
749 * down, so in that case we also deactivate it.
750 */
751 spin_lock_irqsave(&hardwall_lock, flags);
752 list_for_each_entry_safe(task, tmp, &rect->task_head,
753 thread.hardwall_list) {
754 if (task->files == owner || task->files == NULL)
755 _hardwall_deactivate(task);
756 }
757 spin_unlock_irqrestore(&hardwall_lock, flags);
758 }
759
760 return 0;
761}
762
763/* This hardwall is gone, so destroy it. */
764static int hardwall_release(struct inode *inode, struct file *file)
765{
766 hardwall_destroy(file->private_data);
767 return 0;
768}
769
770static const struct file_operations dev_hardwall_fops = {
771 .unlocked_ioctl = hardwall_ioctl,
772#ifdef CONFIG_COMPAT
773 .compat_ioctl = hardwall_compat_ioctl,
774#endif
775 .flush = hardwall_flush,
776 .release = hardwall_release,
777};
778
779static struct cdev hardwall_dev;
780
781static int __init dev_hardwall_init(void)
782{
783 int rc;
784 dev_t dev;
785
786 rc = alloc_chrdev_region(&dev, 0, 1, "hardwall");
787 if (rc < 0)
788 return rc;
789 cdev_init(&hardwall_dev, &dev_hardwall_fops);
790 rc = cdev_add(&hardwall_dev, dev, 1);
791 if (rc < 0)
792 return rc;
793
794 return 0;
795}
796late_initcall(dev_hardwall_init);
diff --git a/arch/tile/kernel/head_32.S b/arch/tile/kernel/head_32.S
new file mode 100644
index 000000000000..2b4f6c091701
--- /dev/null
+++ b/arch/tile/kernel/head_32.S
@@ -0,0 +1,180 @@
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 * TILE startup code.
15 */
16
17#include <linux/linkage.h>
18#include <linux/init.h>
19#include <asm/page.h>
20#include <asm/pgtable.h>
21#include <asm/thread_info.h>
22#include <asm/processor.h>
23#include <asm/asm-offsets.h>
24#include <hv/hypervisor.h>
25#include <arch/chip.h>
26
27/*
28 * This module contains the entry code for kernel images. It performs the
29 * minimal setup needed to call the generic C routines.
30 */
31
32 __HEAD
33ENTRY(_start)
34 /* Notify the hypervisor of what version of the API we want */
35 {
36 movei r1, TILE_CHIP
37 movei r2, TILE_CHIP_REV
38 }
39 {
40 moveli r0, _HV_VERSION
41 jal hv_init
42 }
43 /* Get a reasonable default ASID in r0 */
44 {
45 move r0, zero
46 jal hv_inquire_asid
47 }
48 /* Install the default page table */
49 {
50 moveli r6, lo16(swapper_pgprot - PAGE_OFFSET)
51 move r4, r0 /* use starting ASID of range for this page table */
52 }
53 {
54 moveli r0, lo16(swapper_pg_dir - PAGE_OFFSET)
55 auli r6, r6, ha16(swapper_pgprot - PAGE_OFFSET)
56 }
57 {
58 lw r2, r6
59 addi r6, r6, 4
60 }
61 {
62 lw r3, r6
63 auli r0, r0, ha16(swapper_pg_dir - PAGE_OFFSET)
64 }
65 {
66 inv r6
67 move r1, zero /* high 32 bits of CPA is zero */
68 }
69 {
70 moveli lr, lo16(1f)
71 move r5, zero
72 }
73 {
74 auli lr, lr, ha16(1f)
75 j hv_install_context
76 }
771:
78
79 /* Get our processor number and save it away in SAVE_1_0. */
80 jal hv_inquire_topology
81 mulll_uu r4, r1, r2 /* r1 == y, r2 == width */
82 add r4, r4, r0 /* r0 == x, so r4 == cpu == y*width + x */
83
84#ifdef CONFIG_SMP
85 /*
86 * Load up our per-cpu offset. When the first (master) tile
87 * boots, this value is still zero, so we will load boot_pc
88 * with start_kernel, and boot_sp with init_stack + THREAD_SIZE.
89 * The master tile initializes the per-cpu offset array, so that
90 * when subsequent (secondary) tiles boot, they will instead load
91 * from their per-cpu versions of boot_sp and boot_pc.
92 */
93 moveli r5, lo16(__per_cpu_offset)
94 auli r5, r5, ha16(__per_cpu_offset)
95 s2a r5, r4, r5
96 lw r5, r5
97 bnz r5, 1f
98
99 /*
100 * Save the width and height to the smp_topology variable
101 * for later use.
102 */
103 moveli r0, lo16(smp_topology + HV_TOPOLOGY_WIDTH_OFFSET)
104 auli r0, r0, ha16(smp_topology + HV_TOPOLOGY_WIDTH_OFFSET)
105 {
106 sw r0, r2
107 addi r0, r0, (HV_TOPOLOGY_HEIGHT_OFFSET - HV_TOPOLOGY_WIDTH_OFFSET)
108 }
109 sw r0, r3
1101:
111#else
112 move r5, zero
113#endif
114
115 /* Load and go with the correct pc and sp. */
116 {
117 addli r1, r5, lo16(boot_sp)
118 addli r0, r5, lo16(boot_pc)
119 }
120 {
121 auli r1, r1, ha16(boot_sp)
122 auli r0, r0, ha16(boot_pc)
123 }
124 lw r0, r0
125 lw sp, r1
126 or r4, sp, r4
127 mtspr SYSTEM_SAVE_1_0, r4 /* save ksp0 + cpu */
128 addi sp, sp, -STACK_TOP_DELTA
129 {
130 move lr, zero /* stop backtraces in the called function */
131 jr r0
132 }
133 ENDPROC(_start)
134
135.section ".bss.page_aligned","w"
136 .align PAGE_SIZE
137ENTRY(empty_zero_page)
138 .fill PAGE_SIZE,1,0
139 END(empty_zero_page)
140
141 .macro PTE va, cpa, bits1, no_org=0
142 .ifeq \no_org
143 .org swapper_pg_dir + HV_L1_INDEX(\va) * HV_PTE_SIZE
144 .endif
145 .word HV_PTE_PAGE | HV_PTE_DIRTY | HV_PTE_PRESENT | HV_PTE_ACCESSED | \
146 (HV_PTE_MODE_CACHE_NO_L3 << HV_PTE_INDEX_MODE)
147 .word (\bits1) | (HV_CPA_TO_PFN(\cpa) << HV_PTE_INDEX_PFN)
148 .endm
149
150.section ".data.page_aligned","wa"
151 .align PAGE_SIZE
152ENTRY(swapper_pg_dir)
153 /*
154 * All data pages from PAGE_OFFSET to MEM_USER_INTRPT are mapped as
155 * VA = PA + PAGE_OFFSET. We remap things with more precise access
156 * permissions and more respect for size of RAM later.
157 */
158 .set addr, 0
159 .rept (MEM_USER_INTRPT - PAGE_OFFSET) >> PGDIR_SHIFT
160 PTE addr + PAGE_OFFSET, addr, HV_PTE_READABLE | HV_PTE_WRITABLE
161 .set addr, addr + PGDIR_SIZE
162 .endr
163
164 /* The true text VAs are mapped as VA = PA + MEM_SV_INTRPT */
165 PTE MEM_SV_INTRPT, 0, HV_PTE_READABLE | HV_PTE_EXECUTABLE
166 .org swapper_pg_dir + HV_L1_SIZE
167 END(swapper_pg_dir)
168
169 /*
170 * Isolate swapper_pgprot to its own cache line, since each cpu
171 * starting up will read it using VA-is-PA and local homing.
172 * This would otherwise likely conflict with other data on the cache
173 * line, once we have set its permanent home in the page tables.
174 */
175 __INITDATA
176 .align CHIP_L2_LINE_SIZE()
177ENTRY(swapper_pgprot)
178 PTE 0, 0, HV_PTE_READABLE | HV_PTE_WRITABLE, 1
179 .align CHIP_L2_LINE_SIZE()
180 END(swapper_pgprot)
diff --git a/arch/tile/kernel/hvglue.lds b/arch/tile/kernel/hvglue.lds
new file mode 100644
index 000000000000..2b7cd0a659a9
--- /dev/null
+++ b/arch/tile/kernel/hvglue.lds
@@ -0,0 +1,58 @@
1/* Hypervisor call vector addresses; see <hv/hypervisor.h> */
2hv_init = TEXT_OFFSET + 0x10020;
3hv_install_context = TEXT_OFFSET + 0x10040;
4hv_sysconf = TEXT_OFFSET + 0x10060;
5hv_get_rtc = TEXT_OFFSET + 0x10080;
6hv_set_rtc = TEXT_OFFSET + 0x100a0;
7hv_flush_asid = TEXT_OFFSET + 0x100c0;
8hv_flush_page = TEXT_OFFSET + 0x100e0;
9hv_flush_pages = TEXT_OFFSET + 0x10100;
10hv_restart = TEXT_OFFSET + 0x10120;
11hv_halt = TEXT_OFFSET + 0x10140;
12hv_power_off = TEXT_OFFSET + 0x10160;
13hv_inquire_physical = TEXT_OFFSET + 0x10180;
14hv_inquire_memory_controller = TEXT_OFFSET + 0x101a0;
15hv_inquire_virtual = TEXT_OFFSET + 0x101c0;
16hv_inquire_asid = TEXT_OFFSET + 0x101e0;
17hv_nanosleep = TEXT_OFFSET + 0x10200;
18hv_console_read_if_ready = TEXT_OFFSET + 0x10220;
19hv_console_write = TEXT_OFFSET + 0x10240;
20hv_downcall_dispatch = TEXT_OFFSET + 0x10260;
21hv_inquire_topology = TEXT_OFFSET + 0x10280;
22hv_fs_findfile = TEXT_OFFSET + 0x102a0;
23hv_fs_fstat = TEXT_OFFSET + 0x102c0;
24hv_fs_pread = TEXT_OFFSET + 0x102e0;
25hv_physaddr_read64 = TEXT_OFFSET + 0x10300;
26hv_physaddr_write64 = TEXT_OFFSET + 0x10320;
27hv_get_command_line = TEXT_OFFSET + 0x10340;
28hv_set_caching = TEXT_OFFSET + 0x10360;
29hv_bzero_page = TEXT_OFFSET + 0x10380;
30hv_register_message_state = TEXT_OFFSET + 0x103a0;
31hv_send_message = TEXT_OFFSET + 0x103c0;
32hv_receive_message = TEXT_OFFSET + 0x103e0;
33hv_inquire_context = TEXT_OFFSET + 0x10400;
34hv_start_all_tiles = TEXT_OFFSET + 0x10420;
35hv_dev_open = TEXT_OFFSET + 0x10440;
36hv_dev_close = TEXT_OFFSET + 0x10460;
37hv_dev_pread = TEXT_OFFSET + 0x10480;
38hv_dev_pwrite = TEXT_OFFSET + 0x104a0;
39hv_dev_poll = TEXT_OFFSET + 0x104c0;
40hv_dev_poll_cancel = TEXT_OFFSET + 0x104e0;
41hv_dev_preada = TEXT_OFFSET + 0x10500;
42hv_dev_pwritea = TEXT_OFFSET + 0x10520;
43hv_flush_remote = TEXT_OFFSET + 0x10540;
44hv_console_putc = TEXT_OFFSET + 0x10560;
45hv_inquire_tiles = TEXT_OFFSET + 0x10580;
46hv_confstr = TEXT_OFFSET + 0x105a0;
47hv_reexec = TEXT_OFFSET + 0x105c0;
48hv_set_command_line = TEXT_OFFSET + 0x105e0;
49hv_clear_intr = TEXT_OFFSET + 0x10600;
50hv_enable_intr = TEXT_OFFSET + 0x10620;
51hv_disable_intr = TEXT_OFFSET + 0x10640;
52hv_raise_intr = TEXT_OFFSET + 0x10660;
53hv_trigger_ipi = TEXT_OFFSET + 0x10680;
54hv_store_mapping = TEXT_OFFSET + 0x106a0;
55hv_inquire_realpa = TEXT_OFFSET + 0x106c0;
56hv_flush_all = TEXT_OFFSET + 0x106e0;
57hv_get_ipi_pte = TEXT_OFFSET + 0x10700;
58hv_glue_internals = TEXT_OFFSET + 0x10720;
diff --git a/arch/tile/kernel/init_task.c b/arch/tile/kernel/init_task.c
new file mode 100644
index 000000000000..928b31870669
--- /dev/null
+++ b/arch/tile/kernel/init_task.c
@@ -0,0 +1,59 @@
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#include <linux/mm.h>
16#include <linux/fs.h>
17#include <linux/init_task.h>
18#include <linux/mqueue.h>
19#include <linux/module.h>
20#include <linux/start_kernel.h>
21#include <linux/uaccess.h>
22
23static struct signal_struct init_signals = INIT_SIGNALS(init_signals);
24static struct sighand_struct init_sighand = INIT_SIGHAND(init_sighand);
25
26/*
27 * Initial thread structure.
28 *
29 * We need to make sure that this is THREAD_SIZE aligned due to the
30 * way process stacks are handled. This is done by having a special
31 * "init_task" linker map entry..
32 */
33union thread_union init_thread_union __init_task_data = {
34 INIT_THREAD_INFO(init_task)
35};
36
37/*
38 * Initial task structure.
39 *
40 * All other task structs will be allocated on slabs in fork.c
41 */
42struct task_struct init_task = INIT_TASK(init_task);
43EXPORT_SYMBOL(init_task);
44
45/*
46 * per-CPU stack and boot info.
47 */
48DEFINE_PER_CPU(unsigned long, boot_sp) =
49 (unsigned long)init_stack + THREAD_SIZE;
50
51#ifdef CONFIG_SMP
52DEFINE_PER_CPU(unsigned long, boot_pc) = (unsigned long)start_kernel;
53#else
54/*
55 * The variable must be __initdata since it references __init code.
56 * With CONFIG_SMP it is per-cpu data, which is exempt from validation.
57 */
58unsigned long __initdata boot_pc = (unsigned long)start_kernel;
59#endif
diff --git a/arch/tile/kernel/intvec_32.S b/arch/tile/kernel/intvec_32.S
new file mode 100644
index 000000000000..84f296ca9e63
--- /dev/null
+++ b/arch/tile/kernel/intvec_32.S
@@ -0,0 +1,2018 @@
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 * Linux interrupt vectors.
15 */
16
17#include <linux/linkage.h>
18#include <linux/errno.h>
19#include <linux/init.h>
20#include <linux/unistd.h>
21#include <asm/ptrace.h>
22#include <asm/thread_info.h>
23#include <asm/irqflags.h>
24#include <asm/atomic.h>
25#include <asm/asm-offsets.h>
26#include <hv/hypervisor.h>
27#include <arch/abi.h>
28#include <arch/interrupts.h>
29#include <arch/spr_def.h>
30
31#ifdef CONFIG_PREEMPT
32# error "No support for kernel preemption currently"
33#endif
34
35#if INT_INTCTRL_1 < 32 || INT_INTCTRL_1 >= 48
36# error INT_INTCTRL_1 coded to set high interrupt mask
37#endif
38
39#define PTREGS_PTR(reg, ptreg) addli reg, sp, C_ABI_SAVE_AREA_SIZE + (ptreg)
40
41#define PTREGS_OFFSET_SYSCALL PTREGS_OFFSET_REG(TREG_SYSCALL_NR)
42
43#if !CHIP_HAS_WH64()
44 /* By making this an empty macro, we can use wh64 in the code. */
45 .macro wh64 reg
46 .endm
47#endif
48
49 .macro push_reg reg, ptr=sp, delta=-4
50 {
51 sw \ptr, \reg
52 addli \ptr, \ptr, \delta
53 }
54 .endm
55
56 .macro pop_reg reg, ptr=sp, delta=4
57 {
58 lw \reg, \ptr
59 addli \ptr, \ptr, \delta
60 }
61 .endm
62
63 .macro pop_reg_zero reg, zreg, ptr=sp, delta=4
64 {
65 move \zreg, zero
66 lw \reg, \ptr
67 addi \ptr, \ptr, \delta
68 }
69 .endm
70
71 .macro push_extra_callee_saves reg
72 PTREGS_PTR(\reg, PTREGS_OFFSET_REG(51))
73 push_reg r51, \reg
74 push_reg r50, \reg
75 push_reg r49, \reg
76 push_reg r48, \reg
77 push_reg r47, \reg
78 push_reg r46, \reg
79 push_reg r45, \reg
80 push_reg r44, \reg
81 push_reg r43, \reg
82 push_reg r42, \reg
83 push_reg r41, \reg
84 push_reg r40, \reg
85 push_reg r39, \reg
86 push_reg r38, \reg
87 push_reg r37, \reg
88 push_reg r36, \reg
89 push_reg r35, \reg
90 push_reg r34, \reg, PTREGS_OFFSET_BASE - PTREGS_OFFSET_REG(34)
91 .endm
92
93 .macro panic str
94 .pushsection .rodata, "a"
951:
96 .asciz "\str"
97 .popsection
98 {
99 moveli r0, lo16(1b)
100 }
101 {
102 auli r0, r0, ha16(1b)
103 jal panic
104 }
105 .endm
106
107#ifdef __COLLECT_LINKER_FEEDBACK__
108 .pushsection .text.intvec_feedback,"ax"
109intvec_feedback:
110 .popsection
111#endif
112
113 /*
114 * Default interrupt handler.
115 *
116 * vecnum is where we'll put this code.
117 * c_routine is the C routine we'll call.
118 *
119 * The C routine is passed two arguments:
120 * - A pointer to the pt_regs state.
121 * - The interrupt vector number.
122 *
123 * The "processing" argument specifies the code for processing
124 * the interrupt. Defaults to "handle_interrupt".
125 */
126 .macro int_hand vecnum, vecname, c_routine, processing=handle_interrupt
127 .org (\vecnum << 8)
128intvec_\vecname:
129 .ifc \vecnum, INT_SWINT_1
130 blz TREG_SYSCALL_NR_NAME, sys_cmpxchg
131 .endif
132
133 /* Temporarily save a register so we have somewhere to work. */
134
135 mtspr SYSTEM_SAVE_1_1, r0
136 mfspr r0, EX_CONTEXT_1_1
137
138 /* The cmpxchg code clears sp to force us to reset it here on fault. */
139 {
140 bz sp, 2f
141 andi r0, r0, SPR_EX_CONTEXT_1_1__PL_MASK /* mask off ICS */
142 }
143
144 .ifc \vecnum, INT_DOUBLE_FAULT
145 /*
146 * For double-faults from user-space, fall through to the normal
147 * register save and stack setup path. Otherwise, it's the
148 * hypervisor giving us one last chance to dump diagnostics, and we
149 * branch to the kernel_double_fault routine to do so.
150 */
151 bz r0, 1f
152 j _kernel_double_fault
1531:
154 .else
155 /*
156 * If we're coming from user-space, then set sp to the top of
157 * the kernel stack. Otherwise, assume sp is already valid.
158 */
159 {
160 bnz r0, 0f
161 move r0, sp
162 }
163 .endif
164
165 .ifc \c_routine, do_page_fault
166 /*
167 * The page_fault handler may be downcalled directly by the
168 * hypervisor even when Linux is running and has ICS set.
169 *
170 * In this case the contents of EX_CONTEXT_1_1 reflect the
171 * previous fault and can't be relied on to choose whether or
172 * not to reinitialize the stack pointer. So we add a test
173 * to see whether SYSTEM_SAVE_1_2 has the high bit set,
174 * and if so we don't reinitialize sp, since we must be coming
175 * from Linux. (In fact the precise case is !(val & ~1),
176 * but any Linux PC has to have the high bit set.)
177 *
178 * Note that the hypervisor *always* sets SYSTEM_SAVE_1_2 for
179 * any path that turns into a downcall to one of our TLB handlers.
180 */
181 mfspr r0, SYSTEM_SAVE_1_2
182 {
183 blz r0, 0f /* high bit in S_S_1_2 is for a PC to use */
184 move r0, sp
185 }
186 .endif
187
1882:
189 /*
190 * SYSTEM_SAVE_1_0 holds the cpu number in the low bits, and
191 * the current stack top in the higher bits. So we recover
192 * our stack top by just masking off the low bits, then
193 * point sp at the top aligned address on the actual stack page.
194 */
195 mfspr r0, SYSTEM_SAVE_1_0
196 mm r0, r0, zero, LOG2_THREAD_SIZE, 31
197
1980:
199 /*
200 * Align the stack mod 64 so we can properly predict what
201 * cache lines we need to write-hint to reduce memory fetch
202 * latency as we enter the kernel. The layout of memory is
203 * as follows, with cache line 0 at the lowest VA, and cache
204 * line 4 just below the r0 value this "andi" computes.
205 * Note that we never write to cache line 4, and we skip
206 * cache line 1 for syscalls.
207 *
208 * cache line 4: ptregs padding (two words)
209 * cache line 3: r46...lr, pc, ex1, faultnum, orig_r0, flags, pad
210 * cache line 2: r30...r45
211 * cache line 1: r14...r29
212 * cache line 0: 2 x frame, r0..r13
213 */
214 andi r0, r0, -64
215
216 /*
217 * Push the first four registers on the stack, so that we can set
218 * them to vector-unique values before we jump to the common code.
219 *
220 * Registers are pushed on the stack as a struct pt_regs,
221 * with the sp initially just above the struct, and when we're
222 * done, sp points to the base of the struct, minus
223 * C_ABI_SAVE_AREA_SIZE, so we can directly jal to C code.
224 *
225 * This routine saves just the first four registers, plus the
226 * stack context so we can do proper backtracing right away,
227 * and defers to handle_interrupt to save the rest.
228 * The backtracer needs pc, ex1, lr, sp, r52, and faultnum.
229 */
230 addli r0, r0, PTREGS_OFFSET_LR - (PTREGS_SIZE + KSTK_PTREGS_GAP)
231 wh64 r0 /* cache line 3 */
232 {
233 sw r0, lr
234 addli r0, r0, PTREGS_OFFSET_SP - PTREGS_OFFSET_LR
235 }
236 {
237 sw r0, sp
238 addli sp, r0, PTREGS_OFFSET_REG(52) - PTREGS_OFFSET_SP
239 }
240 {
241 sw sp, r52
242 addli sp, sp, PTREGS_OFFSET_REG(1) - PTREGS_OFFSET_REG(52)
243 }
244 wh64 sp /* cache line 0 */
245 {
246 sw sp, r1
247 addli sp, sp, PTREGS_OFFSET_REG(2) - PTREGS_OFFSET_REG(1)
248 }
249 {
250 sw sp, r2
251 addli sp, sp, PTREGS_OFFSET_REG(3) - PTREGS_OFFSET_REG(2)
252 }
253 {
254 sw sp, r3
255 addli sp, sp, PTREGS_OFFSET_PC - PTREGS_OFFSET_REG(3)
256 }
257 mfspr r0, EX_CONTEXT_1_0
258 .ifc \processing,handle_syscall
259 /*
260 * Bump the saved PC by one bundle so that when we return, we won't
261 * execute the same swint instruction again. We need to do this while
262 * we're in the critical section.
263 */
264 addi r0, r0, 8
265 .endif
266 {
267 sw sp, r0
268 addli sp, sp, PTREGS_OFFSET_EX1 - PTREGS_OFFSET_PC
269 }
270 mfspr r0, EX_CONTEXT_1_1
271 {
272 sw sp, r0
273 addi sp, sp, PTREGS_OFFSET_FAULTNUM - PTREGS_OFFSET_EX1
274 /*
275 * Use r0 for syscalls so it's a temporary; use r1 for interrupts
276 * so that it gets passed through unchanged to the handler routine.
277 * Note that the .if conditional confusingly spans bundles.
278 */
279 .ifc \processing,handle_syscall
280 movei r0, \vecnum
281 }
282 {
283 sw sp, r0
284 .else
285 movei r1, \vecnum
286 }
287 {
288 sw sp, r1
289 .endif
290 addli sp, sp, PTREGS_OFFSET_REG(0) - PTREGS_OFFSET_FAULTNUM
291 }
292 mfspr r0, SYSTEM_SAVE_1_1 /* Original r0 */
293 {
294 sw sp, r0
295 addi sp, sp, -PTREGS_OFFSET_REG(0) - 4
296 }
297 {
298 sw sp, zero /* write zero into "Next SP" frame pointer */
299 addi sp, sp, -4 /* leave SP pointing at bottom of frame */
300 }
301 .ifc \processing,handle_syscall
302 j handle_syscall
303 .else
304 /*
305 * Capture per-interrupt SPR context to registers.
306 * We overload the meaning of r3 on this path such that if its bit 31
307 * is set, we have to mask all interrupts including NMIs before
308 * clearing the interrupt critical section bit.
309 * See discussion below at "finish_interrupt_save".
310 */
311 .ifc \c_routine, do_page_fault
312 mfspr r2, SYSTEM_SAVE_1_3 /* address of page fault */
313 mfspr r3, SYSTEM_SAVE_1_2 /* info about page fault */
314 .else
315 .ifc \vecnum, INT_DOUBLE_FAULT
316 {
317 mfspr r2, SYSTEM_SAVE_1_2 /* double fault info from HV */
318 movei r3, 0
319 }
320 .else
321 .ifc \c_routine, do_trap
322 {
323 mfspr r2, GPV_REASON
324 movei r3, 0
325 }
326 .else
327 .ifc \c_routine, op_handle_perf_interrupt
328 {
329 mfspr r2, PERF_COUNT_STS
330 movei r3, -1 /* not used, but set for consistency */
331 }
332 .else
333#if CHIP_HAS_AUX_PERF_COUNTERS()
334 .ifc \c_routine, op_handle_aux_perf_interrupt
335 {
336 mfspr r2, AUX_PERF_COUNT_STS
337 movei r3, -1 /* not used, but set for consistency */
338 }
339 .else
340#endif
341 movei r3, 0
342#if CHIP_HAS_AUX_PERF_COUNTERS()
343 .endif
344#endif
345 .endif
346 .endif
347 .endif
348 .endif
349 /* Put function pointer in r0 */
350 moveli r0, lo16(\c_routine)
351 {
352 auli r0, r0, ha16(\c_routine)
353 j \processing
354 }
355 .endif
356 ENDPROC(intvec_\vecname)
357
358#ifdef __COLLECT_LINKER_FEEDBACK__
359 .pushsection .text.intvec_feedback,"ax"
360 .org (\vecnum << 5)
361 FEEDBACK_ENTER_EXPLICIT(intvec_\vecname, .intrpt1, 1 << 8)
362 jrp lr
363 .popsection
364#endif
365
366 .endm
367
368
369 /*
370 * Save the rest of the registers that we didn't save in the actual
371 * vector itself. We can't use r0-r10 inclusive here.
372 */
373 .macro finish_interrupt_save, function
374
375 /* If it's a syscall, save a proper orig_r0, otherwise just zero. */
376 PTREGS_PTR(r52, PTREGS_OFFSET_ORIG_R0)
377 {
378 .ifc \function,handle_syscall
379 sw r52, r0
380 .else
381 sw r52, zero
382 .endif
383 PTREGS_PTR(r52, PTREGS_OFFSET_TP)
384 }
385
386 /*
387 * For ordinary syscalls, we save neither caller- nor callee-
388 * save registers, since the syscall invoker doesn't expect the
389 * caller-saves to be saved, and the called kernel functions will
390 * take care of saving the callee-saves for us.
391 *
392 * For interrupts we save just the caller-save registers. Saving
393 * them is required (since the "caller" can't save them). Again,
394 * the called kernel functions will restore the callee-save
395 * registers for us appropriately.
396 *
397 * On return, we normally restore nothing special for syscalls,
398 * and just the caller-save registers for interrupts.
399 *
400 * However, there are some important caveats to all this:
401 *
402 * - We always save a few callee-save registers to give us
403 * some scratchpad registers to carry across function calls.
404 *
405 * - fork/vfork/etc require us to save all the callee-save
406 * registers, which we do in PTREGS_SYSCALL_ALL_REGS, below.
407 *
408 * - We always save r0..r5 and r10 for syscalls, since we need
409 * to reload them a bit later for the actual kernel call, and
410 * since we might need them for -ERESTARTNOINTR, etc.
411 *
412 * - Before invoking a signal handler, we save the unsaved
413 * callee-save registers so they are visible to the
414 * signal handler or any ptracer.
415 *
416 * - If the unsaved callee-save registers are modified, we set
417 * a bit in pt_regs so we know to reload them from pt_regs
418 * and not just rely on the kernel function unwinding.
419 * (Done for ptrace register writes and SA_SIGINFO handler.)
420 */
421 {
422 sw r52, tp
423 PTREGS_PTR(r52, PTREGS_OFFSET_REG(33))
424 }
425 wh64 r52 /* cache line 2 */
426 push_reg r33, r52
427 push_reg r32, r52
428 push_reg r31, r52
429 .ifc \function,handle_syscall
430 push_reg r30, r52, PTREGS_OFFSET_SYSCALL - PTREGS_OFFSET_REG(30)
431 push_reg TREG_SYSCALL_NR_NAME, r52, \
432 PTREGS_OFFSET_REG(5) - PTREGS_OFFSET_SYSCALL
433 .else
434
435 push_reg r30, r52, PTREGS_OFFSET_REG(29) - PTREGS_OFFSET_REG(30)
436 wh64 r52 /* cache line 1 */
437 push_reg r29, r52
438 push_reg r28, r52
439 push_reg r27, r52
440 push_reg r26, r52
441 push_reg r25, r52
442 push_reg r24, r52
443 push_reg r23, r52
444 push_reg r22, r52
445 push_reg r21, r52
446 push_reg r20, r52
447 push_reg r19, r52
448 push_reg r18, r52
449 push_reg r17, r52
450 push_reg r16, r52
451 push_reg r15, r52
452 push_reg r14, r52
453 push_reg r13, r52
454 push_reg r12, r52
455 push_reg r11, r52
456 push_reg r10, r52
457 push_reg r9, r52
458 push_reg r8, r52
459 push_reg r7, r52
460 push_reg r6, r52
461
462 .endif
463
464 push_reg r5, r52
465 sw r52, r4
466
467 /* Load tp with our per-cpu offset. */
468#ifdef CONFIG_SMP
469 {
470 mfspr r20, SYSTEM_SAVE_1_0
471 moveli r21, lo16(__per_cpu_offset)
472 }
473 {
474 auli r21, r21, ha16(__per_cpu_offset)
475 mm r20, r20, zero, 0, LOG2_THREAD_SIZE-1
476 }
477 s2a r20, r20, r21
478 lw tp, r20
479#else
480 move tp, zero
481#endif
482
483 /*
484 * If we will be returning to the kernel, we will need to
485 * reset the interrupt masks to the state they had before.
486 * Set DISABLE_IRQ in flags iff we came from PL1 with irqs disabled.
487 * We load flags in r32 here so we can jump to .Lrestore_regs
488 * directly after do_page_fault_ics() if necessary.
489 */
490 mfspr r32, EX_CONTEXT_1_1
491 {
492 andi r32, r32, SPR_EX_CONTEXT_1_1__PL_MASK /* mask off ICS */
493 PTREGS_PTR(r21, PTREGS_OFFSET_FLAGS)
494 }
495 bzt r32, 1f /* zero if from user space */
496 IRQS_DISABLED(r32) /* zero if irqs enabled */
497#if PT_FLAGS_DISABLE_IRQ != 1
498# error Value of IRQS_DISABLED used to set PT_FLAGS_DISABLE_IRQ; fix
499#endif
5001:
501 .ifnc \function,handle_syscall
502 /* Record the fact that we saved the caller-save registers above. */
503 ori r32, r32, PT_FLAGS_CALLER_SAVES
504 .endif
505 sw r21, r32
506
507#ifdef __COLLECT_LINKER_FEEDBACK__
508 /*
509 * Notify the feedback routines that we were in the
510 * appropriate fixed interrupt vector area. Note that we
511 * still have ICS set at this point, so we can't invoke any
512 * atomic operations or we will panic. The feedback
513 * routines internally preserve r0..r10 and r30 up.
514 */
515 .ifnc \function,handle_syscall
516 shli r20, r1, 5
517 .else
518 moveli r20, INT_SWINT_1 << 5
519 .endif
520 addli r20, r20, lo16(intvec_feedback)
521 auli r20, r20, ha16(intvec_feedback)
522 jalr r20
523
524 /* And now notify the feedback routines that we are here. */
525 FEEDBACK_ENTER(\function)
526#endif
527
528 /*
529 * we've captured enough state to the stack (including in
530 * particular our EX_CONTEXT state) that we can now release
531 * the interrupt critical section and replace it with our
532 * standard "interrupts disabled" mask value. This allows
533 * synchronous interrupts (and profile interrupts) to punch
534 * through from this point onwards.
535 *
536 * If bit 31 of r3 is set during a non-NMI interrupt, we know we
537 * are on the path where the hypervisor has punched through our
538 * ICS with a page fault, so we call out to do_page_fault_ics()
539 * to figure out what to do with it. If the fault was in
540 * an atomic op, we unlock the atomic lock, adjust the
541 * saved register state a little, and return "zero" in r4,
542 * falling through into the normal page-fault interrupt code.
543 * If the fault was in a kernel-space atomic operation, then
544 * do_page_fault_ics() resolves it itself, returns "one" in r4,
545 * and as a result goes directly to restoring registers and iret,
546 * without trying to adjust the interrupt masks at all.
547 * The do_page_fault_ics() API involves passing and returning
548 * a five-word struct (in registers) to avoid writing the
549 * save and restore code here.
550 */
551 .ifc \function,handle_nmi
552 IRQ_DISABLE_ALL(r20)
553 .else
554 .ifnc \function,handle_syscall
555 bgezt r3, 1f
556 {
557 PTREGS_PTR(r0, PTREGS_OFFSET_BASE)
558 jal do_page_fault_ics
559 }
560 FEEDBACK_REENTER(\function)
561 bzt r4, 1f
562 j .Lrestore_regs
5631:
564 .endif
565 IRQ_DISABLE(r20, r21)
566 .endif
567 mtspr INTERRUPT_CRITICAL_SECTION, zero
568
569#if CHIP_HAS_WH64()
570 /*
571 * Prepare the first 256 stack bytes to be rapidly accessible
572 * without having to fetch the background data. We don't really
573 * know how far to write-hint, but kernel stacks generally
574 * aren't that big, and write-hinting here does take some time.
575 */
576 addi r52, sp, -64
577 {
578 wh64 r52
579 addi r52, r52, -64
580 }
581 {
582 wh64 r52
583 addi r52, r52, -64
584 }
585 {
586 wh64 r52
587 addi r52, r52, -64
588 }
589 wh64 r52
590#endif
591
592#ifdef CONFIG_TRACE_IRQFLAGS
593 .ifnc \function,handle_nmi
594 /*
595 * We finally have enough state set up to notify the irq
596 * tracing code that irqs were disabled on entry to the handler.
597 * The TRACE_IRQS_OFF call clobbers registers r0-r29.
598 * For syscalls, we already have the register state saved away
599 * on the stack, so we don't bother to do any register saves here,
600 * and later we pop the registers back off the kernel stack.
601 * For interrupt handlers, save r0-r3 in callee-saved registers.
602 */
603 .ifnc \function,handle_syscall
604 { move r30, r0; move r31, r1 }
605 { move r32, r2; move r33, r3 }
606 .endif
607 TRACE_IRQS_OFF
608 .ifnc \function,handle_syscall
609 { move r0, r30; move r1, r31 }
610 { move r2, r32; move r3, r33 }
611 .endif
612 .endif
613#endif
614
615 .endm
616
617 .macro check_single_stepping, kind, not_single_stepping
618 /*
619 * Check for single stepping in user-level priv
620 * kind can be "normal", "ill", or "syscall"
621 * At end, if fall-thru
622 * r29: thread_info->step_state
623 * r28: &pt_regs->pc
624 * r27: pt_regs->pc
625 * r26: thread_info->step_state->buffer
626 */
627
628 /* Check for single stepping */
629 GET_THREAD_INFO(r29)
630 {
631 /* Get pointer to field holding step state */
632 addi r29, r29, THREAD_INFO_STEP_STATE_OFFSET
633
634 /* Get pointer to EX1 in register state */
635 PTREGS_PTR(r27, PTREGS_OFFSET_EX1)
636 }
637 {
638 /* Get pointer to field holding PC */
639 PTREGS_PTR(r28, PTREGS_OFFSET_PC)
640
641 /* Load the pointer to the step state */
642 lw r29, r29
643 }
644 /* Load EX1 */
645 lw r27, r27
646 {
647 /* Points to flags */
648 addi r23, r29, SINGLESTEP_STATE_FLAGS_OFFSET
649
650 /* No single stepping if there is no step state structure */
651 bzt r29, \not_single_stepping
652 }
653 {
654 /* mask off ICS and any other high bits */
655 andi r27, r27, SPR_EX_CONTEXT_1_1__PL_MASK
656
657 /* Load pointer to single step instruction buffer */
658 lw r26, r29
659 }
660 /* Check priv state */
661 bnz r27, \not_single_stepping
662
663 /* Get flags */
664 lw r22, r23
665 {
666 /* Branch if single-step mode not enabled */
667 bbnst r22, \not_single_stepping
668
669 /* Clear enabled flag */
670 andi r22, r22, ~SINGLESTEP_STATE_MASK_IS_ENABLED
671 }
672 .ifc \kind,normal
673 {
674 /* Load PC */
675 lw r27, r28
676
677 /* Point to the entry containing the original PC */
678 addi r24, r29, SINGLESTEP_STATE_ORIG_PC_OFFSET
679 }
680 {
681 /* Disable single stepping flag */
682 sw r23, r22
683 }
684 {
685 /* Get the original pc */
686 lw r24, r24
687
688 /* See if the PC is at the start of the single step buffer */
689 seq r25, r26, r27
690 }
691 /*
692 * NOTE: it is really expected that the PC be in the single step buffer
693 * at this point
694 */
695 bzt r25, \not_single_stepping
696
697 /* Restore the original PC */
698 sw r28, r24
699 .else
700 .ifc \kind,syscall
701 {
702 /* Load PC */
703 lw r27, r28
704
705 /* Point to the entry containing the next PC */
706 addi r24, r29, SINGLESTEP_STATE_NEXT_PC_OFFSET
707 }
708 {
709 /* Increment the stopped PC by the bundle size */
710 addi r26, r26, 8
711
712 /* Disable single stepping flag */
713 sw r23, r22
714 }
715 {
716 /* Get the next pc */
717 lw r24, r24
718
719 /*
720 * See if the PC is one bundle past the start of the
721 * single step buffer
722 */
723 seq r25, r26, r27
724 }
725 {
726 /*
727 * NOTE: it is really expected that the PC be in the
728 * single step buffer at this point
729 */
730 bzt r25, \not_single_stepping
731 }
732 /* Set to the next PC */
733 sw r28, r24
734 .else
735 {
736 /* Point to 3rd bundle in buffer */
737 addi r25, r26, 16
738
739 /* Load PC */
740 lw r27, r28
741 }
742 {
743 /* Disable single stepping flag */
744 sw r23, r22
745
746 /* See if the PC is in the single step buffer */
747 slte_u r24, r26, r27
748 }
749 {
750 slte_u r25, r27, r25
751
752 /*
753 * NOTE: it is really expected that the PC be in the
754 * single step buffer at this point
755 */
756 bzt r24, \not_single_stepping
757 }
758 bzt r25, \not_single_stepping
759 .endif
760 .endif
761 .endm
762
763 /*
764 * Redispatch a downcall.
765 */
766 .macro dc_dispatch vecnum, vecname
767 .org (\vecnum << 8)
768intvec_\vecname:
769 j hv_downcall_dispatch
770 ENDPROC(intvec_\vecname)
771 .endm
772
773 /*
774 * Common code for most interrupts. The C function we're eventually
775 * going to is in r0, and the faultnum is in r1; the original
776 * values for those registers are on the stack.
777 */
778 .pushsection .text.handle_interrupt,"ax"
779handle_interrupt:
780 finish_interrupt_save handle_interrupt
781
782 /*
783 * Check for if we are single stepping in user level. If so, then
784 * we need to restore the PC.
785 */
786
787 check_single_stepping normal, .Ldispatch_interrupt
788.Ldispatch_interrupt:
789
790 /* Jump to the C routine; it should enable irqs as soon as possible. */
791 {
792 jalr r0
793 PTREGS_PTR(r0, PTREGS_OFFSET_BASE)
794 }
795 FEEDBACK_REENTER(handle_interrupt)
796 {
797 movei r30, 0 /* not an NMI */
798 j interrupt_return
799 }
800 STD_ENDPROC(handle_interrupt)
801
802/*
803 * This routine takes a boolean in r30 indicating if this is an NMI.
804 * If so, we also expect a boolean in r31 indicating whether to
805 * re-enable the oprofile interrupts.
806 */
807STD_ENTRY(interrupt_return)
808 /* If we're resuming to kernel space, don't check thread flags. */
809 {
810 bnz r30, .Lrestore_all /* NMIs don't special-case user-space */
811 PTREGS_PTR(r29, PTREGS_OFFSET_EX1)
812 }
813 lw r29, r29
814 andi r29, r29, SPR_EX_CONTEXT_1_1__PL_MASK /* mask off ICS */
815 {
816 bzt r29, .Lresume_userspace
817 PTREGS_PTR(r29, PTREGS_OFFSET_PC)
818 }
819
820 /* If we're resuming to _cpu_idle_nap, bump PC forward by 8. */
821 {
822 lw r28, r29
823 moveli r27, lo16(_cpu_idle_nap)
824 }
825 {
826 auli r27, r27, ha16(_cpu_idle_nap)
827 }
828 {
829 seq r27, r27, r28
830 }
831 {
832 bbns r27, .Lrestore_all
833 addi r28, r28, 8
834 }
835 sw r29, r28
836 j .Lrestore_all
837
838.Lresume_userspace:
839 FEEDBACK_REENTER(interrupt_return)
840
841 /*
842 * Disable interrupts so as to make sure we don't
843 * miss an interrupt that sets any of the thread flags (like
844 * need_resched or sigpending) between sampling and the iret.
845 * Routines like schedule() or do_signal() may re-enable
846 * interrupts before returning.
847 */
848 IRQ_DISABLE(r20, r21)
849 TRACE_IRQS_OFF /* Note: clobbers registers r0-r29 */
850
851 /* Get base of stack in r32; note r30/31 are used as arguments here. */
852 GET_THREAD_INFO(r32)
853
854
855 /* Check to see if there is any work to do before returning to user. */
856 {
857 addi r29, r32, THREAD_INFO_FLAGS_OFFSET
858 moveli r28, lo16(_TIF_ALLWORK_MASK)
859 }
860 {
861 lw r29, r29
862 auli r28, r28, ha16(_TIF_ALLWORK_MASK)
863 }
864 and r28, r29, r28
865 bnz r28, .Lwork_pending
866
867 /*
868 * In the NMI case we
869 * omit the call to single_process_check_nohz, which normally checks
870 * to see if we should start or stop the scheduler tick, because
871 * we can't call arbitrary Linux code from an NMI context.
872 * We always call the homecache TLB deferral code to re-trigger
873 * the deferral mechanism.
874 *
875 * The other chunk of responsibility this code has is to reset the
876 * interrupt masks appropriately to reset irqs and NMIs. We have
877 * to call TRACE_IRQS_OFF and TRACE_IRQS_ON to support all the
878 * lockdep-type stuff, but we can't set ICS until afterwards, since
879 * ICS can only be used in very tight chunks of code to avoid
880 * tripping over various assertions that it is off.
881 *
882 * (There is what looks like a window of vulnerability here since
883 * we might take a profile interrupt between the two SPR writes
884 * that set the mask, but since we write the low SPR word first,
885 * and our interrupt entry code checks the low SPR word, any
886 * profile interrupt will actually disable interrupts in both SPRs
887 * before returning, which is OK.)
888 */
889.Lrestore_all:
890 PTREGS_PTR(r0, PTREGS_OFFSET_EX1)
891 {
892 lw r0, r0
893 PTREGS_PTR(r32, PTREGS_OFFSET_FLAGS)
894 }
895 {
896 andi r0, r0, SPR_EX_CONTEXT_1_1__PL_MASK
897 lw r32, r32
898 }
899 bnz r0, 1f
900 j 2f
901#if PT_FLAGS_DISABLE_IRQ != 1
902# error Assuming PT_FLAGS_DISABLE_IRQ == 1 so we can use bbnst below
903#endif
9041: bbnst r32, 2f
905 IRQ_DISABLE(r20,r21)
906 TRACE_IRQS_OFF
907 movei r0, 1
908 mtspr INTERRUPT_CRITICAL_SECTION, r0
909 bzt r30, .Lrestore_regs
910 j 3f
9112: TRACE_IRQS_ON
912 movei r0, 1
913 mtspr INTERRUPT_CRITICAL_SECTION, r0
914 IRQ_ENABLE(r20, r21)
915 bzt r30, .Lrestore_regs
9163:
917
918
919 /*
920 * We now commit to returning from this interrupt, since we will be
921 * doing things like setting EX_CONTEXT SPRs and unwinding the stack
922 * frame. No calls should be made to any other code after this point.
923 * This code should only be entered with ICS set.
924 * r32 must still be set to ptregs.flags.
925 * We launch loads to each cache line separately first, so we can
926 * get some parallelism out of the memory subsystem.
927 * We start zeroing caller-saved registers throughout, since
928 * that will save some cycles if this turns out to be a syscall.
929 */
930.Lrestore_regs:
931 FEEDBACK_REENTER(interrupt_return) /* called from elsewhere */
932
933 /*
934 * Rotate so we have one high bit and one low bit to test.
935 * - low bit says whether to restore all the callee-saved registers,
936 * or just r30-r33, and r52 up.
937 * - high bit (i.e. sign bit) says whether to restore all the
938 * caller-saved registers, or just r0.
939 */
940#if PT_FLAGS_CALLER_SAVES != 2 || PT_FLAGS_RESTORE_REGS != 4
941# error Rotate trick does not work :-)
942#endif
943 {
944 rli r20, r32, 30
945 PTREGS_PTR(sp, PTREGS_OFFSET_REG(0))
946 }
947
948 /*
949 * Load cache lines 0, 2, and 3 in that order, then use
950 * the last loaded value, which makes it likely that the other
951 * cache lines have also loaded, at which point we should be
952 * able to safely read all the remaining words on those cache
953 * lines without waiting for the memory subsystem.
954 */
955 pop_reg_zero r0, r28, sp, PTREGS_OFFSET_REG(30) - PTREGS_OFFSET_REG(0)
956 pop_reg_zero r30, r2, sp, PTREGS_OFFSET_PC - PTREGS_OFFSET_REG(30)
957 pop_reg_zero r21, r3, sp, PTREGS_OFFSET_EX1 - PTREGS_OFFSET_PC
958 pop_reg_zero lr, r4, sp, PTREGS_OFFSET_REG(52) - PTREGS_OFFSET_EX1
959 {
960 mtspr EX_CONTEXT_1_0, r21
961 move r5, zero
962 }
963 {
964 mtspr EX_CONTEXT_1_1, lr
965 andi lr, lr, SPR_EX_CONTEXT_1_1__PL_MASK /* mask off ICS */
966 }
967
968 /* Restore callee-saveds that we actually use. */
969 pop_reg_zero r52, r6, sp, PTREGS_OFFSET_REG(31) - PTREGS_OFFSET_REG(52)
970 pop_reg_zero r31, r7
971 pop_reg_zero r32, r8
972 pop_reg_zero r33, r9, sp, PTREGS_OFFSET_REG(29) - PTREGS_OFFSET_REG(33)
973
974 /*
975 * If we modified other callee-saveds, restore them now.
976 * This is rare, but could be via ptrace or signal handler.
977 */
978 {
979 move r10, zero
980 bbs r20, .Lrestore_callees
981 }
982.Lcontinue_restore_regs:
983
984 /* Check if we're returning from a syscall. */
985 {
986 move r11, zero
987 blzt r20, 1f /* no, so go restore callee-save registers */
988 }
989
990 /*
991 * Check if we're returning to userspace.
992 * Note that if we're not, we don't worry about zeroing everything.
993 */
994 {
995 addli sp, sp, PTREGS_OFFSET_LR - PTREGS_OFFSET_REG(29)
996 bnz lr, .Lkernel_return
997 }
998
999 /*
1000 * On return from syscall, we've restored r0 from pt_regs, but we
1001 * clear the remainder of the caller-saved registers. We could
1002 * restore the syscall arguments, but there's not much point,
1003 * and it ensures user programs aren't trying to use the
1004 * caller-saves if we clear them, as well as avoiding leaking
1005 * kernel pointers into userspace.
1006 */
1007 pop_reg_zero lr, r12, sp, PTREGS_OFFSET_TP - PTREGS_OFFSET_LR
1008 pop_reg_zero tp, r13, sp, PTREGS_OFFSET_SP - PTREGS_OFFSET_TP
1009 {
1010 lw sp, sp
1011 move r14, zero
1012 move r15, zero
1013 }
1014 { move r16, zero; move r17, zero }
1015 { move r18, zero; move r19, zero }
1016 { move r20, zero; move r21, zero }
1017 { move r22, zero; move r23, zero }
1018 { move r24, zero; move r25, zero }
1019 { move r26, zero; move r27, zero }
1020
1021 /* Set r1 to errno if we are returning an error, otherwise zero. */
1022 {
1023 moveli r29, 1024
1024 sub r1, zero, r0
1025 }
1026 slt_u r29, r1, r29
1027 {
1028 mnz r1, r29, r1
1029 move r29, zero
1030 }
1031 iret
1032
1033 /*
1034 * Not a syscall, so restore caller-saved registers.
1035 * First kick off a load for cache line 1, which we're touching
1036 * for the first time here.
1037 */
1038 .align 64
10391: pop_reg r29, sp, PTREGS_OFFSET_REG(1) - PTREGS_OFFSET_REG(29)
1040 pop_reg r1
1041 pop_reg r2
1042 pop_reg r3
1043 pop_reg r4
1044 pop_reg r5
1045 pop_reg r6
1046 pop_reg r7
1047 pop_reg r8
1048 pop_reg r9
1049 pop_reg r10
1050 pop_reg r11
1051 pop_reg r12
1052 pop_reg r13
1053 pop_reg r14
1054 pop_reg r15
1055 pop_reg r16
1056 pop_reg r17
1057 pop_reg r18
1058 pop_reg r19
1059 pop_reg r20
1060 pop_reg r21
1061 pop_reg r22
1062 pop_reg r23
1063 pop_reg r24
1064 pop_reg r25
1065 pop_reg r26
1066 pop_reg r27
1067 pop_reg r28, sp, PTREGS_OFFSET_LR - PTREGS_OFFSET_REG(28)
1068 /* r29 already restored above */
1069 bnz lr, .Lkernel_return
1070 pop_reg lr, sp, PTREGS_OFFSET_TP - PTREGS_OFFSET_LR
1071 pop_reg tp, sp, PTREGS_OFFSET_SP - PTREGS_OFFSET_TP
1072 lw sp, sp
1073 iret
1074
1075 /*
1076 * We can't restore tp when in kernel mode, since a thread might
1077 * have migrated from another cpu and brought a stale tp value.
1078 */
1079.Lkernel_return:
1080 pop_reg lr, sp, PTREGS_OFFSET_SP - PTREGS_OFFSET_LR
1081 lw sp, sp
1082 iret
1083
1084 /* Restore callee-saved registers from r34 to r51. */
1085.Lrestore_callees:
1086 addli sp, sp, PTREGS_OFFSET_REG(34) - PTREGS_OFFSET_REG(29)
1087 pop_reg r34
1088 pop_reg r35
1089 pop_reg r36
1090 pop_reg r37
1091 pop_reg r38
1092 pop_reg r39
1093 pop_reg r40
1094 pop_reg r41
1095 pop_reg r42
1096 pop_reg r43
1097 pop_reg r44
1098 pop_reg r45
1099 pop_reg r46
1100 pop_reg r47
1101 pop_reg r48
1102 pop_reg r49
1103 pop_reg r50
1104 pop_reg r51, sp, PTREGS_OFFSET_REG(29) - PTREGS_OFFSET_REG(51)
1105 j .Lcontinue_restore_regs
1106
1107.Lwork_pending:
1108 /* Mask the reschedule flag */
1109 andi r28, r29, _TIF_NEED_RESCHED
1110
1111 {
1112 /*
1113 * If the NEED_RESCHED flag is called, we call schedule(), which
1114 * may drop this context right here and go do something else.
1115 * On return, jump back to .Lresume_userspace and recheck.
1116 */
1117 bz r28, .Lasync_tlb
1118
1119 /* Mask the async-tlb flag */
1120 andi r28, r29, _TIF_ASYNC_TLB
1121 }
1122
1123 jal schedule
1124 FEEDBACK_REENTER(interrupt_return)
1125
1126 /* Reload the flags and check again */
1127 j .Lresume_userspace
1128
1129.Lasync_tlb:
1130 {
1131 bz r28, .Lneed_sigpending
1132
1133 /* Mask the sigpending flag */
1134 andi r28, r29, _TIF_SIGPENDING
1135 }
1136
1137 PTREGS_PTR(r0, PTREGS_OFFSET_BASE)
1138 jal do_async_page_fault
1139 FEEDBACK_REENTER(interrupt_return)
1140
1141 /*
1142 * Go restart the "resume userspace" process. We may have
1143 * fired a signal, and we need to disable interrupts again.
1144 */
1145 j .Lresume_userspace
1146
1147.Lneed_sigpending:
1148 /*
1149 * At this point we are either doing signal handling or single-step,
1150 * so either way make sure we have all the registers saved.
1151 */
1152 push_extra_callee_saves r0
1153
1154 {
1155 /* If no signal pending, skip to singlestep check */
1156 bz r28, .Lneed_singlestep
1157
1158 /* Mask the singlestep flag */
1159 andi r28, r29, _TIF_SINGLESTEP
1160 }
1161
1162 jal do_signal
1163 FEEDBACK_REENTER(interrupt_return)
1164
1165 /* Reload the flags and check again */
1166 j .Lresume_userspace
1167
1168.Lneed_singlestep:
1169 {
1170 /* Get a pointer to the EX1 field */
1171 PTREGS_PTR(r29, PTREGS_OFFSET_EX1)
1172
1173 /* If we get here, our bit must be set. */
1174 bz r28, .Lwork_confusion
1175 }
1176 /* If we are in priv mode, don't single step */
1177 lw r28, r29
1178 andi r28, r28, SPR_EX_CONTEXT_1_1__PL_MASK /* mask off ICS */
1179 bnz r28, .Lrestore_all
1180
1181 /* Allow interrupts within the single step code */
1182 TRACE_IRQS_ON /* Note: clobbers registers r0-r29 */
1183 IRQ_ENABLE(r20, r21)
1184
1185 /* try to single-step the current instruction */
1186 PTREGS_PTR(r0, PTREGS_OFFSET_BASE)
1187 jal single_step_once
1188 FEEDBACK_REENTER(interrupt_return)
1189
1190 /* Re-disable interrupts. TRACE_IRQS_OFF in .Lrestore_all. */
1191 IRQ_DISABLE(r20,r21)
1192
1193 j .Lrestore_all
1194
1195.Lwork_confusion:
1196 move r0, r28
1197 panic "thread_info allwork flags unhandled on userspace resume: %#x"
1198
1199 STD_ENDPROC(interrupt_return)
1200
1201 /*
1202 * This interrupt variant clears the INT_INTCTRL_1 interrupt mask bit
1203 * before returning, so we can properly get more downcalls.
1204 */
1205 .pushsection .text.handle_interrupt_downcall,"ax"
1206handle_interrupt_downcall:
1207 finish_interrupt_save handle_interrupt_downcall
1208 check_single_stepping normal, .Ldispatch_downcall
1209.Ldispatch_downcall:
1210
1211 /* Clear INTCTRL_1 from the set of interrupts we ever enable. */
1212 GET_INTERRUPTS_ENABLED_MASK_PTR(r30)
1213 {
1214 addi r30, r30, 4
1215 movei r31, INT_MASK(INT_INTCTRL_1)
1216 }
1217 {
1218 lw r20, r30
1219 nor r21, r31, zero
1220 }
1221 and r20, r20, r21
1222 sw r30, r20
1223
1224 {
1225 jalr r0
1226 PTREGS_PTR(r0, PTREGS_OFFSET_BASE)
1227 }
1228 FEEDBACK_REENTER(handle_interrupt_downcall)
1229
1230 /* Allow INTCTRL_1 to be enabled next time we enable interrupts. */
1231 lw r20, r30
1232 or r20, r20, r31
1233 sw r30, r20
1234
1235 {
1236 movei r30, 0 /* not an NMI */
1237 j interrupt_return
1238 }
1239 STD_ENDPROC(handle_interrupt_downcall)
1240
1241 /*
1242 * Some interrupts don't check for single stepping
1243 */
1244 .pushsection .text.handle_interrupt_no_single_step,"ax"
1245handle_interrupt_no_single_step:
1246 finish_interrupt_save handle_interrupt_no_single_step
1247 {
1248 jalr r0
1249 PTREGS_PTR(r0, PTREGS_OFFSET_BASE)
1250 }
1251 FEEDBACK_REENTER(handle_interrupt_no_single_step)
1252 {
1253 movei r30, 0 /* not an NMI */
1254 j interrupt_return
1255 }
1256 STD_ENDPROC(handle_interrupt_no_single_step)
1257
1258 /*
1259 * "NMI" interrupts mask ALL interrupts before calling the
1260 * handler, and don't check thread flags, etc., on the way
1261 * back out. In general, the only things we do here for NMIs
1262 * are the register save/restore, fixing the PC if we were
1263 * doing single step, and the dataplane kernel-TLB management.
1264 * We don't (for example) deal with start/stop of the sched tick.
1265 */
1266 .pushsection .text.handle_nmi,"ax"
1267handle_nmi:
1268 finish_interrupt_save handle_nmi
1269 check_single_stepping normal, .Ldispatch_nmi
1270.Ldispatch_nmi:
1271 {
1272 jalr r0
1273 PTREGS_PTR(r0, PTREGS_OFFSET_BASE)
1274 }
1275 FEEDBACK_REENTER(handle_nmi)
1276 j interrupt_return
1277 STD_ENDPROC(handle_nmi)
1278
1279 /*
1280 * Parallel code for syscalls to handle_interrupt.
1281 */
1282 .pushsection .text.handle_syscall,"ax"
1283handle_syscall:
1284 finish_interrupt_save handle_syscall
1285
1286 /*
1287 * Check for if we are single stepping in user level. If so, then
1288 * we need to restore the PC.
1289 */
1290 check_single_stepping syscall, .Ldispatch_syscall
1291.Ldispatch_syscall:
1292
1293 /* Enable irqs. */
1294 TRACE_IRQS_ON
1295 IRQ_ENABLE(r20, r21)
1296
1297 /* Bump the counter for syscalls made on this tile. */
1298 moveli r20, lo16(irq_stat + IRQ_CPUSTAT_SYSCALL_COUNT_OFFSET)
1299 auli r20, r20, ha16(irq_stat + IRQ_CPUSTAT_SYSCALL_COUNT_OFFSET)
1300 add r20, r20, tp
1301 lw r21, r20
1302 addi r21, r21, 1
1303 sw r20, r21
1304
1305 /* Trace syscalls, if requested. */
1306 GET_THREAD_INFO(r31)
1307 addi r31, r31, THREAD_INFO_FLAGS_OFFSET
1308 lw r30, r31
1309 andi r30, r30, _TIF_SYSCALL_TRACE
1310 bzt r30, .Lrestore_syscall_regs
1311 jal do_syscall_trace
1312 FEEDBACK_REENTER(handle_syscall)
1313
1314 /*
1315 * We always reload our registers from the stack at this
1316 * point. They might be valid, if we didn't build with
1317 * TRACE_IRQFLAGS, and this isn't a dataplane tile, and we're not
1318 * doing syscall tracing, but there are enough cases now that it
1319 * seems simplest just to do the reload unconditionally.
1320 */
1321.Lrestore_syscall_regs:
1322 PTREGS_PTR(r11, PTREGS_OFFSET_REG(0))
1323 pop_reg r0, r11
1324 pop_reg r1, r11
1325 pop_reg r2, r11
1326 pop_reg r3, r11
1327 pop_reg r4, r11
1328 pop_reg r5, r11, PTREGS_OFFSET_SYSCALL - PTREGS_OFFSET_REG(5)
1329 pop_reg TREG_SYSCALL_NR_NAME, r11
1330
1331 /* Ensure that the syscall number is within the legal range. */
1332 moveli r21, __NR_syscalls
1333 {
1334 slt_u r21, TREG_SYSCALL_NR_NAME, r21
1335 moveli r20, lo16(sys_call_table)
1336 }
1337 {
1338 bbns r21, .Linvalid_syscall
1339 auli r20, r20, ha16(sys_call_table)
1340 }
1341 s2a r20, TREG_SYSCALL_NR_NAME, r20
1342 lw r20, r20
1343
1344 /* Jump to syscall handler. */
1345 jalr r20; .Lhandle_syscall_link:
1346 FEEDBACK_REENTER(handle_syscall)
1347
1348 /*
1349 * Write our r0 onto the stack so it gets restored instead
1350 * of whatever the user had there before.
1351 */
1352 PTREGS_PTR(r29, PTREGS_OFFSET_REG(0))
1353 sw r29, r0
1354
1355 /* Do syscall trace again, if requested. */
1356 lw r30, r31
1357 andi r30, r30, _TIF_SYSCALL_TRACE
1358 bzt r30, 1f
1359 jal do_syscall_trace
1360 FEEDBACK_REENTER(handle_syscall)
13611: j .Lresume_userspace /* jump into middle of interrupt_return */
1362
1363.Linvalid_syscall:
1364 /* Report an invalid syscall back to the user program */
1365 {
1366 PTREGS_PTR(r29, PTREGS_OFFSET_REG(0))
1367 movei r28, -ENOSYS
1368 }
1369 sw r29, r28
1370 j .Lresume_userspace /* jump into middle of interrupt_return */
1371 STD_ENDPROC(handle_syscall)
1372
1373 /* Return the address for oprofile to suppress in backtraces. */
1374STD_ENTRY_SECTION(handle_syscall_link_address, .text.handle_syscall)
1375 lnk r0
1376 {
1377 addli r0, r0, .Lhandle_syscall_link - .
1378 jrp lr
1379 }
1380 STD_ENDPROC(handle_syscall_link_address)
1381
1382STD_ENTRY(ret_from_fork)
1383 jal sim_notify_fork
1384 jal schedule_tail
1385 FEEDBACK_REENTER(ret_from_fork)
1386 j .Lresume_userspace /* jump into middle of interrupt_return */
1387 STD_ENDPROC(ret_from_fork)
1388
1389 /*
1390 * Code for ill interrupt.
1391 */
1392 .pushsection .text.handle_ill,"ax"
1393handle_ill:
1394 finish_interrupt_save handle_ill
1395
1396 /*
1397 * Check for if we are single stepping in user level. If so, then
1398 * we need to restore the PC.
1399 */
1400 check_single_stepping ill, .Ldispatch_normal_ill
1401
1402 {
1403 /* See if the PC is the 1st bundle in the buffer */
1404 seq r25, r27, r26
1405
1406 /* Point to the 2nd bundle in the buffer */
1407 addi r26, r26, 8
1408 }
1409 {
1410 /* Point to the original pc */
1411 addi r24, r29, SINGLESTEP_STATE_ORIG_PC_OFFSET
1412
1413 /* Branch if the PC is the 1st bundle in the buffer */
1414 bnz r25, 3f
1415 }
1416 {
1417 /* See if the PC is the 2nd bundle of the buffer */
1418 seq r25, r27, r26
1419
1420 /* Set PC to next instruction */
1421 addi r24, r29, SINGLESTEP_STATE_NEXT_PC_OFFSET
1422 }
1423 {
1424 /* Point to flags */
1425 addi r25, r29, SINGLESTEP_STATE_FLAGS_OFFSET
1426
1427 /* Branch if PC is in the second bundle */
1428 bz r25, 2f
1429 }
1430 /* Load flags */
1431 lw r25, r25
1432 {
1433 /*
1434 * Get the offset for the register to restore
1435 * Note: the lower bound is 2, so we have implicit scaling by 4.
1436 * No multiplication of the register number by the size of a register
1437 * is needed.
1438 */
1439 mm r27, r25, zero, SINGLESTEP_STATE_TARGET_LB, \
1440 SINGLESTEP_STATE_TARGET_UB
1441
1442 /* Mask Rewrite_LR */
1443 andi r25, r25, SINGLESTEP_STATE_MASK_UPDATE
1444 }
1445 {
1446 addi r29, r29, SINGLESTEP_STATE_UPDATE_VALUE_OFFSET
1447
1448 /* Don't rewrite temp register */
1449 bz r25, 3f
1450 }
1451 {
1452 /* Get the temp value */
1453 lw r29, r29
1454
1455 /* Point to where the register is stored */
1456 add r27, r27, sp
1457 }
1458
1459 /* Add in the C ABI save area size to the register offset */
1460 addi r27, r27, C_ABI_SAVE_AREA_SIZE
1461
1462 /* Restore the user's register with the temp value */
1463 sw r27, r29
1464 j 3f
1465
14662:
1467 /* Must be in the third bundle */
1468 addi r24, r29, SINGLESTEP_STATE_BRANCH_NEXT_PC_OFFSET
1469
14703:
1471 /* set PC and continue */
1472 lw r26, r24
1473 sw r28, r26
1474
1475 /* Clear TIF_SINGLESTEP */
1476 GET_THREAD_INFO(r0)
1477
1478 addi r1, r0, THREAD_INFO_FLAGS_OFFSET
1479 {
1480 lw r2, r1
1481 addi r0, r0, THREAD_INFO_TASK_OFFSET /* currently a no-op */
1482 }
1483 andi r2, r2, ~_TIF_SINGLESTEP
1484 sw r1, r2
1485
1486 /* Issue a sigtrap */
1487 {
1488 lw r0, r0 /* indirect thru thread_info to get task_info*/
1489 addi r1, sp, C_ABI_SAVE_AREA_SIZE /* put ptregs pointer into r1 */
1490 move r2, zero /* load error code into r2 */
1491 }
1492
1493 jal send_sigtrap /* issue a SIGTRAP */
1494 FEEDBACK_REENTER(handle_ill)
1495 j .Lresume_userspace /* jump into middle of interrupt_return */
1496
1497.Ldispatch_normal_ill:
1498 {
1499 jalr r0
1500 PTREGS_PTR(r0, PTREGS_OFFSET_BASE)
1501 }
1502 FEEDBACK_REENTER(handle_ill)
1503 {
1504 movei r30, 0 /* not an NMI */
1505 j interrupt_return
1506 }
1507 STD_ENDPROC(handle_ill)
1508
1509 .pushsection .rodata, "a"
1510 .align 8
1511bpt_code:
1512 bpt
1513 ENDPROC(bpt_code)
1514 .popsection
1515
1516/* Various stub interrupt handlers and syscall handlers */
1517
1518STD_ENTRY_LOCAL(_kernel_double_fault)
1519 mfspr r1, EX_CONTEXT_1_0
1520 move r2, lr
1521 move r3, sp
1522 move r4, r52
1523 addi sp, sp, -C_ABI_SAVE_AREA_SIZE
1524 j kernel_double_fault
1525 STD_ENDPROC(_kernel_double_fault)
1526
1527STD_ENTRY_LOCAL(bad_intr)
1528 mfspr r2, EX_CONTEXT_1_0
1529 panic "Unhandled interrupt %#x: PC %#lx"
1530 STD_ENDPROC(bad_intr)
1531
1532/* Put address of pt_regs in reg and jump. */
1533#define PTREGS_SYSCALL(x, reg) \
1534 STD_ENTRY(x); \
1535 { \
1536 PTREGS_PTR(reg, PTREGS_OFFSET_BASE); \
1537 j _##x \
1538 }; \
1539 STD_ENDPROC(x)
1540
1541PTREGS_SYSCALL(sys_execve, r3)
1542PTREGS_SYSCALL(sys_sigaltstack, r2)
1543PTREGS_SYSCALL(sys_rt_sigreturn, r0)
1544
1545/* Save additional callee-saves to pt_regs, put address in reg and jump. */
1546#define PTREGS_SYSCALL_ALL_REGS(x, reg) \
1547 STD_ENTRY(x); \
1548 push_extra_callee_saves reg; \
1549 j _##x; \
1550 STD_ENDPROC(x)
1551
1552PTREGS_SYSCALL_ALL_REGS(sys_fork, r0)
1553PTREGS_SYSCALL_ALL_REGS(sys_vfork, r0)
1554PTREGS_SYSCALL_ALL_REGS(sys_clone, r4)
1555PTREGS_SYSCALL_ALL_REGS(sys_cmpxchg_badaddr, r1)
1556
1557/*
1558 * This entrypoint is taken for the cmpxchg and atomic_update fast
1559 * swints. We may wish to generalize it to other fast swints at some
1560 * point, but for now there are just two very similar ones, which
1561 * makes it faster.
1562 *
1563 * The fast swint code is designed to have a small footprint. It does
1564 * not save or restore any GPRs, counting on the caller-save registers
1565 * to be available to it on entry. It does not modify any callee-save
1566 * registers (including "lr"). It does not check what PL it is being
1567 * called at, so you'd better not call it other than at PL0.
1568 *
1569 * It does not use the stack, but since it might be re-interrupted by
1570 * a page fault which would assume the stack was valid, it does
1571 * save/restore the stack pointer and zero it out to make sure it gets reset.
1572 * Since we always keep interrupts disabled, the hypervisor won't
1573 * clobber our EX_CONTEXT_1_x registers, so we don't save/restore them
1574 * (other than to advance the PC on return).
1575 *
1576 * We have to manually validate the user vs kernel address range
1577 * (since at PL1 we can read/write both), and for performance reasons
1578 * we don't allow cmpxchg on the fc000000 memory region, since we only
1579 * validate that the user address is below PAGE_OFFSET.
1580 *
1581 * We place it in the __HEAD section to ensure it is relatively
1582 * near to the intvec_SWINT_1 code (reachable by a conditional branch).
1583 *
1584 * Must match register usage in do_page_fault().
1585 */
1586 __HEAD
1587 .align 64
1588 /* Align much later jump on the start of a cache line. */
1589#if !ATOMIC_LOCKS_FOUND_VIA_TABLE()
1590 nop; nop
1591#endif
1592ENTRY(sys_cmpxchg)
1593
1594 /*
1595 * Save "sp" and set it zero for any possible page fault.
1596 *
1597 * HACK: We want to both zero sp and check r0's alignment,
1598 * so we do both at once. If "sp" becomes nonzero we
1599 * know r0 is unaligned and branch to the error handler that
1600 * restores sp, so this is OK.
1601 *
1602 * ICS is disabled right now so having a garbage but nonzero
1603 * sp is OK, since we won't execute any faulting instructions
1604 * when it is nonzero.
1605 */
1606 {
1607 move r27, sp
1608 andi sp, r0, 3
1609 }
1610
1611 /*
1612 * Get the lock address in ATOMIC_LOCK_REG, and also validate that the
1613 * address is less than PAGE_OFFSET, since that won't trap at PL1.
1614 * We only use bits less than PAGE_SHIFT to avoid having to worry
1615 * about aliasing among multiple mappings of the same physical page,
1616 * and we ignore the low 3 bits so we have one lock that covers
1617 * both a cmpxchg64() and a cmpxchg() on either its low or high word.
1618 * NOTE: this code must match __atomic_hashed_lock() in lib/atomic.c.
1619 */
1620
1621#if ATOMIC_LOCKS_FOUND_VIA_TABLE()
1622 {
1623 /* Check for unaligned input. */
1624 bnz sp, .Lcmpxchg_badaddr
1625 mm r25, r0, zero, 3, PAGE_SHIFT-1
1626 }
1627 {
1628 crc32_32 r25, zero, r25
1629 moveli r21, lo16(atomic_lock_ptr)
1630 }
1631 {
1632 auli r21, r21, ha16(atomic_lock_ptr)
1633 auli r23, zero, hi16(PAGE_OFFSET) /* hugepage-aligned */
1634 }
1635 {
1636 shri r20, r25, 32 - ATOMIC_HASH_L1_SHIFT
1637 slt_u r23, r0, r23
1638
1639 /*
1640 * Ensure that the TLB is loaded before we take out the lock.
1641 * On TILEPro, this will start fetching the value all the way
1642 * into our L1 as well (and if it gets modified before we
1643 * grab the lock, it will be invalidated from our cache
1644 * before we reload it). On tile64, we'll start fetching it
1645 * into our L1 if we're the home, and if we're not, we'll
1646 * still at least start fetching it into the home's L2.
1647 */
1648 lw r26, r0
1649 }
1650 {
1651 s2a r21, r20, r21
1652 bbns r23, .Lcmpxchg_badaddr
1653 }
1654 {
1655 lw r21, r21
1656 seqi r23, TREG_SYSCALL_NR_NAME, __NR_FAST_cmpxchg64
1657 andi r25, r25, ATOMIC_HASH_L2_SIZE - 1
1658 }
1659 {
1660 /* Branch away at this point if we're doing a 64-bit cmpxchg. */
1661 bbs r23, .Lcmpxchg64
1662 andi r23, r0, 7 /* Precompute alignment for cmpxchg64. */
1663 }
1664
1665 {
1666 /*
1667 * We very carefully align the code that actually runs with
1668 * the lock held (nine bundles) so that we know it is all in
1669 * the icache when we start. This instruction (the jump) is
1670 * at the start of the first cache line, address zero mod 64;
1671 * we jump to somewhere in the second cache line to issue the
1672 * tns, then jump back to finish up.
1673 */
1674 s2a ATOMIC_LOCK_REG_NAME, r25, r21
1675 j .Lcmpxchg32_tns
1676 }
1677
1678#else /* ATOMIC_LOCKS_FOUND_VIA_TABLE() */
1679 {
1680 /* Check for unaligned input. */
1681 bnz sp, .Lcmpxchg_badaddr
1682 auli r23, zero, hi16(PAGE_OFFSET) /* hugepage-aligned */
1683 }
1684 {
1685 /*
1686 * Slide bits into position for 'mm'. We want to ignore
1687 * the low 3 bits of r0, and consider only the next
1688 * ATOMIC_HASH_SHIFT bits.
1689 * Because of C pointer arithmetic, we want to compute this:
1690 *
1691 * ((char*)atomic_locks +
1692 * (((r0 >> 3) & (1 << (ATOMIC_HASH_SIZE - 1))) << 2))
1693 *
1694 * Instead of two shifts we just ">> 1", and use 'mm'
1695 * to ignore the low and high bits we don't want.
1696 */
1697 shri r25, r0, 1
1698
1699 slt_u r23, r0, r23
1700
1701 /*
1702 * Ensure that the TLB is loaded before we take out the lock.
1703 * On tilepro, this will start fetching the value all the way
1704 * into our L1 as well (and if it gets modified before we
1705 * grab the lock, it will be invalidated from our cache
1706 * before we reload it). On tile64, we'll start fetching it
1707 * into our L1 if we're the home, and if we're not, we'll
1708 * still at least start fetching it into the home's L2.
1709 */
1710 lw r26, r0
1711 }
1712 {
1713 /* atomic_locks is page aligned so this suffices to get its addr. */
1714 auli r21, zero, hi16(atomic_locks)
1715
1716 bbns r23, .Lcmpxchg_badaddr
1717 }
1718 {
1719 /*
1720 * Insert the hash bits into the page-aligned pointer.
1721 * ATOMIC_HASH_SHIFT is so big that we don't actually hash
1722 * the unmasked address bits, as that may cause unnecessary
1723 * collisions.
1724 */
1725 mm ATOMIC_LOCK_REG_NAME, r25, r21, 2, (ATOMIC_HASH_SHIFT + 2) - 1
1726
1727 seqi r23, TREG_SYSCALL_NR_NAME, __NR_FAST_cmpxchg64
1728 }
1729 {
1730 /* Branch away at this point if we're doing a 64-bit cmpxchg. */
1731 bbs r23, .Lcmpxchg64
1732 andi r23, r0, 7 /* Precompute alignment for cmpxchg64. */
1733 }
1734 {
1735 /*
1736 * We very carefully align the code that actually runs with
1737 * the lock held (nine bundles) so that we know it is all in
1738 * the icache when we start. This instruction (the jump) is
1739 * at the start of the first cache line, address zero mod 64;
1740 * we jump to somewhere in the second cache line to issue the
1741 * tns, then jump back to finish up.
1742 */
1743 j .Lcmpxchg32_tns
1744 }
1745
1746#endif /* ATOMIC_LOCKS_FOUND_VIA_TABLE() */
1747
1748 ENTRY(__sys_cmpxchg_grab_lock)
1749
1750 /*
1751 * Perform the actual cmpxchg or atomic_update.
1752 * Note that __futex_mark_unlocked() in uClibc relies on
1753 * atomic_update() to always perform an "mf", so don't make
1754 * it optional or conditional without modifying that code.
1755 */
1756.Ldo_cmpxchg32:
1757 {
1758 lw r21, r0
1759 seqi r23, TREG_SYSCALL_NR_NAME, __NR_FAST_atomic_update
1760 move r24, r2
1761 }
1762 {
1763 seq r22, r21, r1 /* See if cmpxchg matches. */
1764 and r25, r21, r1 /* If atomic_update, compute (*mem & mask) */
1765 }
1766 {
1767 or r22, r22, r23 /* Skip compare branch for atomic_update. */
1768 add r25, r25, r2 /* Compute (*mem & mask) + addend. */
1769 }
1770 {
1771 mvnz r24, r23, r25 /* Use atomic_update value if appropriate. */
1772 bbns r22, .Lcmpxchg32_mismatch
1773 }
1774 sw r0, r24
1775
1776 /* Do slow mtspr here so the following "mf" waits less. */
1777 {
1778 move sp, r27
1779 mtspr EX_CONTEXT_1_0, r28
1780 }
1781 mf
1782
1783 /* The following instruction is the start of the second cache line. */
1784 {
1785 move r0, r21
1786 sw ATOMIC_LOCK_REG_NAME, zero
1787 }
1788 iret
1789
1790 /* Duplicated code here in the case where we don't overlap "mf" */
1791.Lcmpxchg32_mismatch:
1792 {
1793 move r0, r21
1794 sw ATOMIC_LOCK_REG_NAME, zero
1795 }
1796 {
1797 move sp, r27
1798 mtspr EX_CONTEXT_1_0, r28
1799 }
1800 iret
1801
1802 /*
1803 * The locking code is the same for 32-bit cmpxchg/atomic_update,
1804 * and for 64-bit cmpxchg. We provide it as a macro and put
1805 * it into both versions. We can't share the code literally
1806 * since it depends on having the right branch-back address.
1807 * Note that the first few instructions should share the cache
1808 * line with the second half of the actual locked code.
1809 */
1810 .macro cmpxchg_lock, bitwidth
1811
1812 /* Lock; if we succeed, jump back up to the read-modify-write. */
1813#ifdef CONFIG_SMP
1814 tns r21, ATOMIC_LOCK_REG_NAME
1815#else
1816 /*
1817 * Non-SMP preserves all the lock infrastructure, to keep the
1818 * code simpler for the interesting (SMP) case. However, we do
1819 * one small optimization here and in atomic_asm.S, which is
1820 * to fake out acquiring the actual lock in the atomic_lock table.
1821 */
1822 movei r21, 0
1823#endif
1824
1825 /* Issue the slow SPR here while the tns result is in flight. */
1826 mfspr r28, EX_CONTEXT_1_0
1827
1828 {
1829 addi r28, r28, 8 /* return to the instruction after the swint1 */
1830 bzt r21, .Ldo_cmpxchg\bitwidth
1831 }
1832 /*
1833 * The preceding instruction is the last thing that must be
1834 * on the second cache line.
1835 */
1836
1837#ifdef CONFIG_SMP
1838 /*
1839 * We failed to acquire the tns lock on our first try. Now use
1840 * bounded exponential backoff to retry, like __atomic_spinlock().
1841 */
1842 {
1843 moveli r23, 2048 /* maximum backoff time in cycles */
1844 moveli r25, 32 /* starting backoff time in cycles */
1845 }
18461: mfspr r26, CYCLE_LOW /* get start point for this backoff */
18472: mfspr r22, CYCLE_LOW /* test to see if we've backed off enough */
1848 sub r22, r22, r26
1849 slt r22, r22, r25
1850 bbst r22, 2b
1851 {
1852 shli r25, r25, 1 /* double the backoff; retry the tns */
1853 tns r21, ATOMIC_LOCK_REG_NAME
1854 }
1855 slt r26, r23, r25 /* is the proposed backoff too big? */
1856 {
1857 mvnz r25, r26, r23
1858 bzt r21, .Ldo_cmpxchg\bitwidth
1859 }
1860 j 1b
1861#endif /* CONFIG_SMP */
1862 .endm
1863
1864.Lcmpxchg32_tns:
1865 cmpxchg_lock 32
1866
1867 /*
1868 * This code is invoked from sys_cmpxchg after most of the
1869 * preconditions have been checked. We still need to check
1870 * that r0 is 8-byte aligned, since if it's not we won't
1871 * actually be atomic. However, ATOMIC_LOCK_REG has the atomic
1872 * lock pointer and r27/r28 have the saved SP/PC.
1873 * r23 is holding "r0 & 7" so we can test for alignment.
1874 * The compare value is in r2/r3; the new value is in r4/r5.
1875 * On return, we must put the old value in r0/r1.
1876 */
1877 .align 64
1878.Lcmpxchg64:
1879 {
1880#if ATOMIC_LOCKS_FOUND_VIA_TABLE()
1881 s2a ATOMIC_LOCK_REG_NAME, r25, r21
1882#endif
1883 bzt r23, .Lcmpxchg64_tns
1884 }
1885 j .Lcmpxchg_badaddr
1886
1887.Ldo_cmpxchg64:
1888 {
1889 lw r21, r0
1890 addi r25, r0, 4
1891 }
1892 {
1893 lw r1, r25
1894 }
1895 seq r26, r21, r2
1896 {
1897 bz r26, .Lcmpxchg64_mismatch
1898 seq r26, r1, r3
1899 }
1900 {
1901 bz r26, .Lcmpxchg64_mismatch
1902 }
1903 sw r0, r4
1904 sw r25, r5
1905
1906 /*
1907 * The 32-bit path provides optimized "match" and "mismatch"
1908 * iret paths, but we don't have enough bundles in this cache line
1909 * to do that, so we just make even the "mismatch" path do an "mf".
1910 */
1911.Lcmpxchg64_mismatch:
1912 {
1913 move sp, r27
1914 mtspr EX_CONTEXT_1_0, r28
1915 }
1916 mf
1917 {
1918 move r0, r21
1919 sw ATOMIC_LOCK_REG_NAME, zero
1920 }
1921 iret
1922
1923.Lcmpxchg64_tns:
1924 cmpxchg_lock 64
1925
1926
1927 /*
1928 * Reset sp and revector to sys_cmpxchg_badaddr(), which will
1929 * just raise the appropriate signal and exit. Doing it this
1930 * way means we don't have to duplicate the code in intvec.S's
1931 * int_hand macro that locates the top of the stack.
1932 */
1933.Lcmpxchg_badaddr:
1934 {
1935 moveli TREG_SYSCALL_NR_NAME, __NR_cmpxchg_badaddr
1936 move sp, r27
1937 }
1938 j intvec_SWINT_1
1939 ENDPROC(sys_cmpxchg)
1940 ENTRY(__sys_cmpxchg_end)
1941
1942
1943/* The single-step support may need to read all the registers. */
1944int_unalign:
1945 push_extra_callee_saves r0
1946 j do_trap
1947
1948/* Include .intrpt1 array of interrupt vectors */
1949 .section ".intrpt1", "ax"
1950
1951#define op_handle_perf_interrupt bad_intr
1952#define op_handle_aux_perf_interrupt bad_intr
1953
1954#ifndef CONFIG_HARDWALL
1955#define do_hardwall_trap bad_intr
1956#endif
1957
1958 int_hand INT_ITLB_MISS, ITLB_MISS, \
1959 do_page_fault, handle_interrupt_no_single_step
1960 int_hand INT_MEM_ERROR, MEM_ERROR, bad_intr
1961 int_hand INT_ILL, ILL, do_trap, handle_ill
1962 int_hand INT_GPV, GPV, do_trap
1963 int_hand INT_SN_ACCESS, SN_ACCESS, do_trap
1964 int_hand INT_IDN_ACCESS, IDN_ACCESS, do_trap
1965 int_hand INT_UDN_ACCESS, UDN_ACCESS, do_trap
1966 int_hand INT_IDN_REFILL, IDN_REFILL, bad_intr
1967 int_hand INT_UDN_REFILL, UDN_REFILL, bad_intr
1968 int_hand INT_IDN_COMPLETE, IDN_COMPLETE, bad_intr
1969 int_hand INT_UDN_COMPLETE, UDN_COMPLETE, bad_intr
1970 int_hand INT_SWINT_3, SWINT_3, do_trap
1971 int_hand INT_SWINT_2, SWINT_2, do_trap
1972 int_hand INT_SWINT_1, SWINT_1, SYSCALL, handle_syscall
1973 int_hand INT_SWINT_0, SWINT_0, do_trap
1974 int_hand INT_UNALIGN_DATA, UNALIGN_DATA, int_unalign
1975 int_hand INT_DTLB_MISS, DTLB_MISS, do_page_fault
1976 int_hand INT_DTLB_ACCESS, DTLB_ACCESS, do_page_fault
1977 int_hand INT_DMATLB_MISS, DMATLB_MISS, do_page_fault
1978 int_hand INT_DMATLB_ACCESS, DMATLB_ACCESS, do_page_fault
1979 int_hand INT_SNITLB_MISS, SNITLB_MISS, do_page_fault
1980 int_hand INT_SN_NOTIFY, SN_NOTIFY, bad_intr
1981 int_hand INT_SN_FIREWALL, SN_FIREWALL, do_hardwall_trap
1982 int_hand INT_IDN_FIREWALL, IDN_FIREWALL, bad_intr
1983 int_hand INT_UDN_FIREWALL, UDN_FIREWALL, do_hardwall_trap
1984 int_hand INT_TILE_TIMER, TILE_TIMER, do_timer_interrupt
1985 int_hand INT_IDN_TIMER, IDN_TIMER, bad_intr
1986 int_hand INT_UDN_TIMER, UDN_TIMER, bad_intr
1987 int_hand INT_DMA_NOTIFY, DMA_NOTIFY, bad_intr
1988 int_hand INT_IDN_CA, IDN_CA, bad_intr
1989 int_hand INT_UDN_CA, UDN_CA, bad_intr
1990 int_hand INT_IDN_AVAIL, IDN_AVAIL, bad_intr
1991 int_hand INT_UDN_AVAIL, UDN_AVAIL, bad_intr
1992 int_hand INT_PERF_COUNT, PERF_COUNT, \
1993 op_handle_perf_interrupt, handle_nmi
1994 int_hand INT_INTCTRL_3, INTCTRL_3, bad_intr
1995 int_hand INT_INTCTRL_2, INTCTRL_2, bad_intr
1996 dc_dispatch INT_INTCTRL_1, INTCTRL_1
1997 int_hand INT_INTCTRL_0, INTCTRL_0, bad_intr
1998 int_hand INT_MESSAGE_RCV_DWNCL, MESSAGE_RCV_DWNCL, \
1999 hv_message_intr, handle_interrupt_downcall
2000 int_hand INT_DEV_INTR_DWNCL, DEV_INTR_DWNCL, \
2001 tile_dev_intr, handle_interrupt_downcall
2002 int_hand INT_I_ASID, I_ASID, bad_intr
2003 int_hand INT_D_ASID, D_ASID, bad_intr
2004 int_hand INT_DMATLB_MISS_DWNCL, DMATLB_MISS_DWNCL, \
2005 do_page_fault, handle_interrupt_downcall
2006 int_hand INT_SNITLB_MISS_DWNCL, SNITLB_MISS_DWNCL, \
2007 do_page_fault, handle_interrupt_downcall
2008 int_hand INT_DMATLB_ACCESS_DWNCL, DMATLB_ACCESS_DWNCL, \
2009 do_page_fault, handle_interrupt_downcall
2010 int_hand INT_SN_CPL, SN_CPL, bad_intr
2011 int_hand INT_DOUBLE_FAULT, DOUBLE_FAULT, do_trap
2012#if CHIP_HAS_AUX_PERF_COUNTERS()
2013 int_hand INT_AUX_PERF_COUNT, AUX_PERF_COUNT, \
2014 op_handle_aux_perf_interrupt, handle_nmi
2015#endif
2016
2017 /* Synthetic interrupt delivered only by the simulator */
2018 int_hand INT_BREAKPOINT, BREAKPOINT, do_breakpoint
diff --git a/arch/tile/kernel/irq.c b/arch/tile/kernel/irq.c
new file mode 100644
index 000000000000..596c60086930
--- /dev/null
+++ b/arch/tile/kernel/irq.c
@@ -0,0 +1,334 @@
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#include <linux/module.h>
16#include <linux/seq_file.h>
17#include <linux/interrupt.h>
18#include <linux/irq.h>
19#include <linux/kernel_stat.h>
20#include <linux/uaccess.h>
21#include <hv/drv_pcie_rc_intf.h>
22#include <arch/spr_def.h>
23#include <asm/traps.h>
24
25/* Bit-flag stored in irq_desc->chip_data to indicate HW-cleared irqs. */
26#define IS_HW_CLEARED 1
27
28/*
29 * The set of interrupts we enable for raw_local_irq_enable().
30 * This is initialized to have just a single interrupt that the kernel
31 * doesn't actually use as a sentinel. During kernel init,
32 * interrupts are added as the kernel gets prepared to support them.
33 * NOTE: we could probably initialize them all statically up front.
34 */
35DEFINE_PER_CPU(unsigned long long, interrupts_enabled_mask) =
36 INITIAL_INTERRUPTS_ENABLED;
37EXPORT_PER_CPU_SYMBOL(interrupts_enabled_mask);
38
39/* Define per-tile device interrupt statistics state. */
40DEFINE_PER_CPU(irq_cpustat_t, irq_stat) ____cacheline_internodealigned_in_smp;
41EXPORT_PER_CPU_SYMBOL(irq_stat);
42
43/*
44 * Define per-tile irq disable mask; the hardware/HV only has a single
45 * mask that we use to implement both masking and disabling.
46 */
47static DEFINE_PER_CPU(unsigned long, irq_disable_mask)
48 ____cacheline_internodealigned_in_smp;
49
50/*
51 * Per-tile IRQ nesting depth. Used to make sure we enable newly
52 * enabled IRQs before exiting the outermost interrupt.
53 */
54static DEFINE_PER_CPU(int, irq_depth);
55
56/* State for allocating IRQs on Gx. */
57#if CHIP_HAS_IPI()
58static unsigned long available_irqs = ~(1UL << IRQ_RESCHEDULE);
59static DEFINE_SPINLOCK(available_irqs_lock);
60#endif
61
62#if CHIP_HAS_IPI()
63/* Use SPRs to manipulate device interrupts. */
64#define mask_irqs(irq_mask) __insn_mtspr(SPR_IPI_MASK_SET_1, irq_mask)
65#define unmask_irqs(irq_mask) __insn_mtspr(SPR_IPI_MASK_RESET_1, irq_mask)
66#define clear_irqs(irq_mask) __insn_mtspr(SPR_IPI_EVENT_RESET_1, irq_mask)
67#else
68/* Use HV to manipulate device interrupts. */
69#define mask_irqs(irq_mask) hv_disable_intr(irq_mask)
70#define unmask_irqs(irq_mask) hv_enable_intr(irq_mask)
71#define clear_irqs(irq_mask) hv_clear_intr(irq_mask)
72#endif
73
74/*
75 * The interrupt handling path, implemented in terms of HV interrupt
76 * emulation on TILE64 and TILEPro, and IPI hardware on TILE-Gx.
77 */
78void tile_dev_intr(struct pt_regs *regs, int intnum)
79{
80 int depth = __get_cpu_var(irq_depth)++;
81 unsigned long original_irqs;
82 unsigned long remaining_irqs;
83 struct pt_regs *old_regs;
84
85#if CHIP_HAS_IPI()
86 /*
87 * Pending interrupts are listed in an SPR. We might be
88 * nested, so be sure to only handle irqs that weren't already
89 * masked by a previous interrupt. Then, mask out the ones
90 * we're going to handle.
91 */
92 unsigned long masked = __insn_mfspr(SPR_IPI_MASK_1);
93 original_irqs = __insn_mfspr(SPR_IPI_EVENT_1) & ~masked;
94 __insn_mtspr(SPR_IPI_MASK_SET_1, original_irqs);
95#else
96 /*
97 * Hypervisor performs the equivalent of the Gx code above and
98 * then puts the pending interrupt mask into a system save reg
99 * for us to find.
100 */
101 original_irqs = __insn_mfspr(SPR_SYSTEM_SAVE_1_3);
102#endif
103 remaining_irqs = original_irqs;
104
105 /* Track time spent here in an interrupt context. */
106 old_regs = set_irq_regs(regs);
107 irq_enter();
108
109#ifdef CONFIG_DEBUG_STACKOVERFLOW
110 /* Debugging check for stack overflow: less than 1/8th stack free? */
111 {
112 long sp = stack_pointer - (long) current_thread_info();
113 if (unlikely(sp < (sizeof(struct thread_info) + STACK_WARN))) {
114 pr_emerg("tile_dev_intr: "
115 "stack overflow: %ld\n",
116 sp - sizeof(struct thread_info));
117 dump_stack();
118 }
119 }
120#endif
121 while (remaining_irqs) {
122 unsigned long irq = __ffs(remaining_irqs);
123 remaining_irqs &= ~(1UL << irq);
124
125 /* Count device irqs; Linux IPIs are counted elsewhere. */
126 if (irq != IRQ_RESCHEDULE)
127 __get_cpu_var(irq_stat).irq_dev_intr_count++;
128
129 generic_handle_irq(irq);
130 }
131
132 /*
133 * If we weren't nested, turn on all enabled interrupts,
134 * including any that were reenabled during interrupt
135 * handling.
136 */
137 if (depth == 0)
138 unmask_irqs(~__get_cpu_var(irq_disable_mask));
139
140 __get_cpu_var(irq_depth)--;
141
142 /*
143 * Track time spent against the current process again and
144 * process any softirqs if they are waiting.
145 */
146 irq_exit();
147 set_irq_regs(old_regs);
148}
149
150
151/*
152 * Remove an irq from the disabled mask. If we're in an interrupt
153 * context, defer enabling the HW interrupt until we leave.
154 */
155void enable_percpu_irq(unsigned int irq)
156{
157 get_cpu_var(irq_disable_mask) &= ~(1UL << irq);
158 if (__get_cpu_var(irq_depth) == 0)
159 unmask_irqs(1UL << irq);
160 put_cpu_var(irq_disable_mask);
161}
162EXPORT_SYMBOL(enable_percpu_irq);
163
164/*
165 * Add an irq to the disabled mask. We disable the HW interrupt
166 * immediately so that there's no possibility of it firing. If we're
167 * in an interrupt context, the return path is careful to avoid
168 * unmasking a newly disabled interrupt.
169 */
170void disable_percpu_irq(unsigned int irq)
171{
172 get_cpu_var(irq_disable_mask) |= (1UL << irq);
173 mask_irqs(1UL << irq);
174 put_cpu_var(irq_disable_mask);
175}
176EXPORT_SYMBOL(disable_percpu_irq);
177
178/* Mask an interrupt. */
179static void tile_irq_chip_mask(unsigned int irq)
180{
181 mask_irqs(1UL << irq);
182}
183
184/* Unmask an interrupt. */
185static void tile_irq_chip_unmask(unsigned int irq)
186{
187 unmask_irqs(1UL << irq);
188}
189
190/*
191 * Clear an interrupt before processing it so that any new assertions
192 * will trigger another irq.
193 */
194static void tile_irq_chip_ack(unsigned int irq)
195{
196 if ((unsigned long)get_irq_chip_data(irq) != IS_HW_CLEARED)
197 clear_irqs(1UL << irq);
198}
199
200/*
201 * For per-cpu interrupts, we need to avoid unmasking any interrupts
202 * that we disabled via disable_percpu_irq().
203 */
204static void tile_irq_chip_eoi(unsigned int irq)
205{
206 if (!(__get_cpu_var(irq_disable_mask) & (1UL << irq)))
207 unmask_irqs(1UL << irq);
208}
209
210static struct irq_chip tile_irq_chip = {
211 .typename = "tile_irq_chip",
212 .ack = tile_irq_chip_ack,
213 .eoi = tile_irq_chip_eoi,
214 .mask = tile_irq_chip_mask,
215 .unmask = tile_irq_chip_unmask,
216};
217
218void __init init_IRQ(void)
219{
220 ipi_init();
221}
222
223void __cpuinit setup_irq_regs(void)
224{
225 /* Enable interrupt delivery. */
226 unmask_irqs(~0UL);
227#if CHIP_HAS_IPI()
228 raw_local_irq_unmask(INT_IPI_1);
229#endif
230}
231
232void tile_irq_activate(unsigned int irq, int tile_irq_type)
233{
234 /*
235 * We use handle_level_irq() by default because the pending
236 * interrupt vector (whether modeled by the HV on TILE64 and
237 * TILEPro or implemented in hardware on TILE-Gx) has
238 * level-style semantics for each bit. An interrupt fires
239 * whenever a bit is high, not just at edges.
240 */
241 irq_flow_handler_t handle = handle_level_irq;
242 if (tile_irq_type == TILE_IRQ_PERCPU)
243 handle = handle_percpu_irq;
244 set_irq_chip_and_handler(irq, &tile_irq_chip, handle);
245
246 /*
247 * Flag interrupts that are hardware-cleared so that ack()
248 * won't clear them.
249 */
250 if (tile_irq_type == TILE_IRQ_HW_CLEAR)
251 set_irq_chip_data(irq, (void *)IS_HW_CLEARED);
252}
253EXPORT_SYMBOL(tile_irq_activate);
254
255
256void ack_bad_irq(unsigned int irq)
257{
258 pr_err("unexpected IRQ trap at vector %02x\n", irq);
259}
260
261/*
262 * Generic, controller-independent functions:
263 */
264
265int show_interrupts(struct seq_file *p, void *v)
266{
267 int i = *(loff_t *) v, j;
268 struct irqaction *action;
269 unsigned long flags;
270
271 if (i == 0) {
272 seq_printf(p, " ");
273 for (j = 0; j < NR_CPUS; j++)
274 if (cpu_online(j))
275 seq_printf(p, "CPU%-8d", j);
276 seq_putc(p, '\n');
277 }
278
279 if (i < NR_IRQS) {
280 raw_spin_lock_irqsave(&irq_desc[i].lock, flags);
281 action = irq_desc[i].action;
282 if (!action)
283 goto skip;
284 seq_printf(p, "%3d: ", i);
285#ifndef CONFIG_SMP
286 seq_printf(p, "%10u ", kstat_irqs(i));
287#else
288 for_each_online_cpu(j)
289 seq_printf(p, "%10u ", kstat_irqs_cpu(i, j));
290#endif
291 seq_printf(p, " %14s", irq_desc[i].chip->typename);
292 seq_printf(p, " %s", action->name);
293
294 for (action = action->next; action; action = action->next)
295 seq_printf(p, ", %s", action->name);
296
297 seq_putc(p, '\n');
298skip:
299 raw_spin_unlock_irqrestore(&irq_desc[i].lock, flags);
300 }
301 return 0;
302}
303
304#if CHIP_HAS_IPI()
305int create_irq(void)
306{
307 unsigned long flags;
308 int result;
309
310 spin_lock_irqsave(&available_irqs_lock, flags);
311 if (available_irqs == 0)
312 result = -ENOMEM;
313 else {
314 result = __ffs(available_irqs);
315 available_irqs &= ~(1UL << result);
316 dynamic_irq_init(result);
317 }
318 spin_unlock_irqrestore(&available_irqs_lock, flags);
319
320 return result;
321}
322EXPORT_SYMBOL(create_irq);
323
324void destroy_irq(unsigned int irq)
325{
326 unsigned long flags;
327
328 spin_lock_irqsave(&available_irqs_lock, flags);
329 available_irqs |= (1UL << irq);
330 dynamic_irq_cleanup(irq);
331 spin_unlock_irqrestore(&available_irqs_lock, flags);
332}
333EXPORT_SYMBOL(destroy_irq);
334#endif
diff --git a/arch/tile/kernel/machine_kexec.c b/arch/tile/kernel/machine_kexec.c
new file mode 100644
index 000000000000..ba7a265d6179
--- /dev/null
+++ b/arch/tile/kernel/machine_kexec.c
@@ -0,0 +1,279 @@
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 * based on machine_kexec.c from other architectures in linux-2.6.18
15 */
16
17#include <linux/mm.h>
18#include <linux/kexec.h>
19#include <linux/delay.h>
20#include <linux/reboot.h>
21#include <linux/errno.h>
22#include <linux/vmalloc.h>
23#include <linux/cpumask.h>
24#include <linux/kernel.h>
25#include <linux/elf.h>
26#include <linux/highmem.h>
27#include <linux/mmu_context.h>
28#include <linux/io.h>
29#include <linux/timex.h>
30#include <asm/pgtable.h>
31#include <asm/pgalloc.h>
32#include <asm/cacheflush.h>
33#include <asm/checksum.h>
34#include <hv/hypervisor.h>
35
36
37/*
38 * This stuff is not in elf.h and is not in any other kernel include.
39 * This stuff is needed below in the little boot notes parser to
40 * extract the command line so we can pass it to the hypervisor.
41 */
42struct Elf32_Bhdr {
43 Elf32_Word b_signature;
44 Elf32_Word b_size;
45 Elf32_Half b_checksum;
46 Elf32_Half b_records;
47};
48#define ELF_BOOT_MAGIC 0x0E1FB007
49#define EBN_COMMAND_LINE 0x00000004
50#define roundupsz(X) (((X) + 3) & ~3)
51
52/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
53
54
55void machine_shutdown(void)
56{
57 /*
58 * Normally we would stop all the other processors here, but
59 * the check in machine_kexec_prepare below ensures we'll only
60 * get this far if we've been booted with "nosmp" on the
61 * command line or without CONFIG_SMP so there's nothing to do
62 * here (for now).
63 */
64}
65
66void machine_crash_shutdown(struct pt_regs *regs)
67{
68 /*
69 * Cannot happen. This type of kexec is disabled on this
70 * architecture (and enforced in machine_kexec_prepare below).
71 */
72}
73
74
75int machine_kexec_prepare(struct kimage *image)
76{
77 if (num_online_cpus() > 1) {
78 pr_warning("%s: detected attempt to kexec "
79 "with num_online_cpus() > 1\n",
80 __func__);
81 return -ENOSYS;
82 }
83 if (image->type != KEXEC_TYPE_DEFAULT) {
84 pr_warning("%s: detected attempt to kexec "
85 "with unsupported type: %d\n",
86 __func__,
87 image->type);
88 return -ENOSYS;
89 }
90 return 0;
91}
92
93void machine_kexec_cleanup(struct kimage *image)
94{
95 /*
96 * We did nothing in machine_kexec_prepare,
97 * so we have nothing to do here.
98 */
99}
100
101/*
102 * If we can find elf boot notes on this page, return the command
103 * line. Otherwise, silently return null. Somewhat kludgy, but no
104 * good way to do this without significantly rearchitecting the
105 * architecture-independent kexec code.
106 */
107
108static unsigned char *kexec_bn2cl(void *pg)
109{
110 struct Elf32_Bhdr *bhdrp;
111 Elf32_Nhdr *nhdrp;
112 unsigned char *desc;
113 unsigned char *command_line;
114 __sum16 csum;
115
116 bhdrp = (struct Elf32_Bhdr *) pg;
117
118 /*
119 * This routine is invoked for every source page, so make
120 * sure to quietly ignore every impossible page.
121 */
122 if (bhdrp->b_signature != ELF_BOOT_MAGIC ||
123 bhdrp->b_size > PAGE_SIZE)
124 return 0;
125
126 /*
127 * If we get a checksum mismatch, warn with the checksum
128 * so we can diagnose better.
129 */
130 csum = ip_compute_csum(pg, bhdrp->b_size);
131 if (csum != 0) {
132 pr_warning("%s: bad checksum %#x (size %d)\n",
133 __func__, csum, bhdrp->b_size);
134 return 0;
135 }
136
137 nhdrp = (Elf32_Nhdr *) (bhdrp + 1);
138
139 while (nhdrp->n_type != EBN_COMMAND_LINE) {
140
141 desc = (unsigned char *) (nhdrp + 1);
142 desc += roundupsz(nhdrp->n_descsz);
143
144 nhdrp = (Elf32_Nhdr *) desc;
145
146 /* still in bounds? */
147 if ((unsigned char *) (nhdrp + 1) >
148 ((unsigned char *) pg) + bhdrp->b_size) {
149
150 pr_info("%s: out of bounds\n", __func__);
151 return 0;
152 }
153 }
154
155 command_line = (unsigned char *) (nhdrp + 1);
156 desc = command_line;
157
158 while (*desc != '\0') {
159 desc++;
160 if (((unsigned long)desc & PAGE_MASK) != (unsigned long)pg) {
161 pr_info("%s: ran off end of page\n",
162 __func__);
163 return 0;
164 }
165 }
166
167 return command_line;
168}
169
170static void kexec_find_and_set_command_line(struct kimage *image)
171{
172 kimage_entry_t *ptr, entry;
173
174 unsigned char *command_line = 0;
175 unsigned char *r;
176 HV_Errno hverr;
177
178 for (ptr = &image->head;
179 (entry = *ptr) && !(entry & IND_DONE);
180 ptr = (entry & IND_INDIRECTION) ?
181 phys_to_virt((entry & PAGE_MASK)) : ptr + 1) {
182
183 if ((entry & IND_SOURCE)) {
184 void *va =
185 kmap_atomic_pfn(entry >> PAGE_SHIFT, KM_USER0);
186 r = kexec_bn2cl(va);
187 if (r) {
188 command_line = r;
189 break;
190 }
191 kunmap_atomic(va, KM_USER0);
192 }
193 }
194
195 if (command_line != 0) {
196 pr_info("setting new command line to \"%s\"\n",
197 command_line);
198
199 hverr = hv_set_command_line(
200 (HV_VirtAddr) command_line, strlen(command_line));
201 kunmap_atomic(command_line, KM_USER0);
202 } else {
203 pr_info("%s: no command line found; making empty\n",
204 __func__);
205 hverr = hv_set_command_line((HV_VirtAddr) command_line, 0);
206 }
207 if (hverr)
208 pr_warning("%s: hv_set_command_line returned error: %d\n",
209 __func__, hverr);
210}
211
212/*
213 * The kexec code range-checks all its PAs, so to avoid having it run
214 * amok and allocate memory and then sequester it from every other
215 * controller, we force it to come from controller zero. We also
216 * disable the oom-killer since if we do end up running out of memory,
217 * that almost certainly won't help.
218 */
219struct page *kimage_alloc_pages_arch(gfp_t gfp_mask, unsigned int order)
220{
221 gfp_mask |= __GFP_THISNODE | __GFP_NORETRY;
222 return alloc_pages_node(0, gfp_mask, order);
223}
224
225static void setup_quasi_va_is_pa(void)
226{
227 HV_PTE *pgtable;
228 HV_PTE pte;
229 int i;
230
231 /*
232 * Flush our TLB to prevent conflicts between the previous contents
233 * and the new stuff we're about to add.
234 */
235 local_flush_tlb_all();
236
237 /* setup VA is PA, at least up to PAGE_OFFSET */
238
239 pgtable = (HV_PTE *)current->mm->pgd;
240 pte = hv_pte(_PAGE_KERNEL | _PAGE_HUGE_PAGE);
241 pte = hv_pte_set_mode(pte, HV_PTE_MODE_CACHE_NO_L3);
242
243 for (i = 0; i < pgd_index(PAGE_OFFSET); i++)
244 pgtable[i] = pfn_pte(i << (HPAGE_SHIFT - PAGE_SHIFT), pte);
245}
246
247
248NORET_TYPE void machine_kexec(struct kimage *image)
249{
250 void *reboot_code_buffer;
251 NORET_TYPE void (*rnk)(unsigned long, void *, unsigned long)
252 ATTRIB_NORET;
253
254 /* Mask all interrupts before starting to reboot. */
255 interrupt_mask_set_mask(~0ULL);
256
257 kexec_find_and_set_command_line(image);
258
259 /*
260 * Adjust the home caching of the control page to be cached on
261 * this cpu, and copy the assembly helper into the control
262 * code page, which we map in the vmalloc area.
263 */
264 homecache_change_page_home(image->control_code_page, 0,
265 smp_processor_id());
266 reboot_code_buffer = vmap(&image->control_code_page, 1, 0,
267 __pgprot(_PAGE_KERNEL | _PAGE_EXECUTABLE));
268 memcpy(reboot_code_buffer, relocate_new_kernel,
269 relocate_new_kernel_size);
270 __flush_icache_range(
271 (unsigned long) reboot_code_buffer,
272 (unsigned long) reboot_code_buffer + relocate_new_kernel_size);
273
274 setup_quasi_va_is_pa();
275
276 /* now call it */
277 rnk = reboot_code_buffer;
278 (*rnk)(image->head, reboot_code_buffer, image->start);
279}
diff --git a/arch/tile/kernel/messaging.c b/arch/tile/kernel/messaging.c
new file mode 100644
index 000000000000..6d23ed271d10
--- /dev/null
+++ b/arch/tile/kernel/messaging.c
@@ -0,0 +1,116 @@
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#include <linux/percpu.h>
16#include <linux/smp.h>
17#include <linux/hardirq.h>
18#include <linux/ptrace.h>
19#include <asm/hv_driver.h>
20#include <asm/irq_regs.h>
21#include <asm/traps.h>
22#include <hv/hypervisor.h>
23#include <arch/interrupts.h>
24
25/* All messages are stored here */
26static DEFINE_PER_CPU(HV_MsgState, msg_state);
27
28void __cpuinit init_messaging(void)
29{
30 /* Allocate storage for messages in kernel space */
31 HV_MsgState *state = &__get_cpu_var(msg_state);
32 int rc = hv_register_message_state(state);
33 if (rc != HV_OK)
34 panic("hv_register_message_state: error %d", rc);
35
36 /* Make sure downcall interrupts will be enabled. */
37 raw_local_irq_unmask(INT_INTCTRL_1);
38}
39
40void hv_message_intr(struct pt_regs *regs, int intnum)
41{
42 /*
43 * We enter with interrupts disabled and leave them disabled,
44 * to match expectations of called functions (e.g.
45 * do_ccupdate_local() in mm/slab.c). This is also consistent
46 * with normal call entry for device interrupts.
47 */
48
49 int message[HV_MAX_MESSAGE_SIZE/sizeof(int)];
50 HV_RcvMsgInfo rmi;
51 int nmsgs = 0;
52
53 /* Track time spent here in an interrupt context */
54 struct pt_regs *old_regs = set_irq_regs(regs);
55 irq_enter();
56
57#ifdef CONFIG_DEBUG_STACKOVERFLOW
58 /* Debugging check for stack overflow: less than 1/8th stack free? */
59 {
60 long sp = stack_pointer - (long) current_thread_info();
61 if (unlikely(sp < (sizeof(struct thread_info) + STACK_WARN))) {
62 pr_emerg("hv_message_intr: "
63 "stack overflow: %ld\n",
64 sp - sizeof(struct thread_info));
65 dump_stack();
66 }
67 }
68#endif
69
70 while (1) {
71 rmi = hv_receive_message(__get_cpu_var(msg_state),
72 (HV_VirtAddr) message,
73 sizeof(message));
74 if (rmi.msglen == 0)
75 break;
76
77 if (rmi.msglen < 0)
78 panic("hv_receive_message failed: %d", rmi.msglen);
79
80 ++nmsgs;
81
82 if (rmi.source == HV_MSG_TILE) {
83 int tag;
84
85 /* we just send tags for now */
86 BUG_ON(rmi.msglen != sizeof(int));
87
88 tag = message[0];
89#ifdef CONFIG_SMP
90 evaluate_message(message[0]);
91#else
92 panic("Received IPI message %d in UP mode", tag);
93#endif
94 } else if (rmi.source == HV_MSG_INTR) {
95 HV_IntrMsg *him = (HV_IntrMsg *)message;
96 struct hv_driver_cb *cb =
97 (struct hv_driver_cb *)him->intarg;
98 cb->callback(cb, him->intdata);
99 __get_cpu_var(irq_stat).irq_hv_msg_count++;
100 }
101 }
102
103 /*
104 * We shouldn't have gotten a message downcall with no
105 * messages available.
106 */
107 if (nmsgs == 0)
108 panic("Message downcall invoked with no messages!");
109
110 /*
111 * Track time spent against the current process again and
112 * process any softirqs if they are waiting.
113 */
114 irq_exit();
115 set_irq_regs(old_regs);
116}
diff --git a/arch/tile/kernel/module.c b/arch/tile/kernel/module.c
new file mode 100644
index 000000000000..e2ab82b7c7e7
--- /dev/null
+++ b/arch/tile/kernel/module.c
@@ -0,0 +1,257 @@
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 * Based on i386 version, copyright (C) 2001 Rusty Russell.
15 */
16
17#include <linux/moduleloader.h>
18#include <linux/elf.h>
19#include <linux/vmalloc.h>
20#include <linux/fs.h>
21#include <linux/string.h>
22#include <linux/kernel.h>
23#include <asm/opcode-tile.h>
24#include <asm/pgtable.h>
25
26#ifdef __tilegx__
27# define Elf_Rela Elf64_Rela
28# define ELF_R_SYM ELF64_R_SYM
29# define ELF_R_TYPE ELF64_R_TYPE
30#else
31# define Elf_Rela Elf32_Rela
32# define ELF_R_SYM ELF32_R_SYM
33# define ELF_R_TYPE ELF32_R_TYPE
34#endif
35
36#ifdef MODULE_DEBUG
37#define DEBUGP printk
38#else
39#define DEBUGP(fmt...)
40#endif
41
42/*
43 * Allocate some address space in the range MEM_MODULE_START to
44 * MEM_MODULE_END and populate it with memory.
45 */
46void *module_alloc(unsigned long size)
47{
48 struct page **pages;
49 pgprot_t prot_rwx = __pgprot(_PAGE_KERNEL | _PAGE_KERNEL_EXEC);
50 struct vm_struct *area;
51 int i = 0;
52 int npages;
53
54 if (size == 0)
55 return NULL;
56 npages = (size + PAGE_SIZE - 1) / PAGE_SIZE;
57 pages = kmalloc(npages * sizeof(struct page *), GFP_KERNEL);
58 if (pages == NULL)
59 return NULL;
60 for (; i < npages; ++i) {
61 pages[i] = alloc_page(GFP_KERNEL | __GFP_HIGHMEM);
62 if (!pages[i])
63 goto error;
64 }
65
66 area = __get_vm_area(size, VM_ALLOC, MEM_MODULE_START, MEM_MODULE_END);
67 if (!area)
68 goto error;
69
70 if (map_vm_area(area, prot_rwx, &pages)) {
71 vunmap(area->addr);
72 goto error;
73 }
74
75 return area->addr;
76
77error:
78 while (--i >= 0)
79 __free_page(pages[i]);
80 kfree(pages);
81 return NULL;
82}
83
84
85/* Free memory returned from module_alloc */
86void module_free(struct module *mod, void *module_region)
87{
88 vfree(module_region);
89 /*
90 * FIXME: If module_region == mod->init_region, trim exception
91 * table entries.
92 */
93}
94
95/* We don't need anything special. */
96int module_frob_arch_sections(Elf_Ehdr *hdr,
97 Elf_Shdr *sechdrs,
98 char *secstrings,
99 struct module *mod)
100{
101 return 0;
102}
103
104int apply_relocate(Elf_Shdr *sechdrs,
105 const char *strtab,
106 unsigned int symindex,
107 unsigned int relsec,
108 struct module *me)
109{
110 pr_err("module %s: .rel relocation unsupported\n", me->name);
111 return -ENOEXEC;
112}
113
114#ifdef __tilegx__
115/*
116 * Validate that the high 16 bits of "value" is just the sign-extension of
117 * the low 48 bits.
118 */
119static int validate_hw2_last(long value, struct module *me)
120{
121 if (((value << 16) >> 16) != value) {
122 pr_warning("module %s: Out of range HW2_LAST value %#lx\n",
123 me->name, value);
124 return 0;
125 }
126 return 1;
127}
128
129/*
130 * Validate that "value" isn't too big to hold in a JumpOff relocation.
131 */
132static int validate_jumpoff(long value)
133{
134 /* Determine size of jump offset. */
135 int shift = __builtin_clzl(get_JumpOff_X1(create_JumpOff_X1(-1)));
136
137 /* Check to see if it fits into the relocation slot. */
138 long f = get_JumpOff_X1(create_JumpOff_X1(value));
139 f = (f << shift) >> shift;
140
141 return f == value;
142}
143#endif
144
145int apply_relocate_add(Elf_Shdr *sechdrs,
146 const char *strtab,
147 unsigned int symindex,
148 unsigned int relsec,
149 struct module *me)
150{
151 unsigned int i;
152 Elf_Rela *rel = (void *)sechdrs[relsec].sh_addr;
153 Elf_Sym *sym;
154 u64 *location;
155 unsigned long value;
156
157 DEBUGP("Applying relocate section %u to %u\n", relsec,
158 sechdrs[relsec].sh_info);
159 for (i = 0; i < sechdrs[relsec].sh_size / sizeof(*rel); i++) {
160 /* This is where to make the change */
161 location = (void *)sechdrs[sechdrs[relsec].sh_info].sh_addr
162 + rel[i].r_offset;
163 /*
164 * This is the symbol it is referring to.
165 * Note that all undefined symbols have been resolved.
166 */
167 sym = (Elf_Sym *)sechdrs[symindex].sh_addr
168 + ELF_R_SYM(rel[i].r_info);
169 value = sym->st_value + rel[i].r_addend;
170
171 switch (ELF_R_TYPE(rel[i].r_info)) {
172
173#define MUNGE(func) (*location = ((*location & ~func(-1)) | func(value)))
174
175#ifndef __tilegx__
176 case R_TILE_32:
177 *(uint32_t *)location = value;
178 break;
179 case R_TILE_IMM16_X0_HA:
180 value = (value + 0x8000) >> 16;
181 /*FALLTHROUGH*/
182 case R_TILE_IMM16_X0_LO:
183 MUNGE(create_Imm16_X0);
184 break;
185 case R_TILE_IMM16_X1_HA:
186 value = (value + 0x8000) >> 16;
187 /*FALLTHROUGH*/
188 case R_TILE_IMM16_X1_LO:
189 MUNGE(create_Imm16_X1);
190 break;
191 case R_TILE_JOFFLONG_X1:
192 value -= (unsigned long) location; /* pc-relative */
193 value = (long) value >> 3; /* count by instrs */
194 MUNGE(create_JOffLong_X1);
195 break;
196#else
197 case R_TILEGX_64:
198 *location = value;
199 break;
200 case R_TILEGX_IMM16_X0_HW2_LAST:
201 if (!validate_hw2_last(value, me))
202 return -ENOEXEC;
203 value >>= 16;
204 /*FALLTHROUGH*/
205 case R_TILEGX_IMM16_X0_HW1:
206 value >>= 16;
207 /*FALLTHROUGH*/
208 case R_TILEGX_IMM16_X0_HW0:
209 MUNGE(create_Imm16_X0);
210 break;
211 case R_TILEGX_IMM16_X1_HW2_LAST:
212 if (!validate_hw2_last(value, me))
213 return -ENOEXEC;
214 value >>= 16;
215 /*FALLTHROUGH*/
216 case R_TILEGX_IMM16_X1_HW1:
217 value >>= 16;
218 /*FALLTHROUGH*/
219 case R_TILEGX_IMM16_X1_HW0:
220 MUNGE(create_Imm16_X1);
221 break;
222 case R_TILEGX_JUMPOFF_X1:
223 value -= (unsigned long) location; /* pc-relative */
224 value = (long) value >> 3; /* count by instrs */
225 if (!validate_jumpoff(value)) {
226 pr_warning("module %s: Out of range jump to"
227 " %#llx at %#llx (%p)\n", me->name,
228 sym->st_value + rel[i].r_addend,
229 rel[i].r_offset, location);
230 return -ENOEXEC;
231 }
232 MUNGE(create_JumpOff_X1);
233 break;
234#endif
235
236#undef MUNGE
237
238 default:
239 pr_err("module %s: Unknown relocation: %d\n",
240 me->name, (int) ELF_R_TYPE(rel[i].r_info));
241 return -ENOEXEC;
242 }
243 }
244 return 0;
245}
246
247int module_finalize(const Elf_Ehdr *hdr,
248 const Elf_Shdr *sechdrs,
249 struct module *me)
250{
251 /* FIXME: perhaps remove the "writable" bit from the TLB? */
252 return 0;
253}
254
255void module_arch_cleanup(struct module *mod)
256{
257}
diff --git a/arch/tile/kernel/pci-dma.c b/arch/tile/kernel/pci-dma.c
new file mode 100644
index 000000000000..5ad5e13b0fa6
--- /dev/null
+++ b/arch/tile/kernel/pci-dma.c
@@ -0,0 +1,251 @@
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#include <linux/mm.h>
16#include <linux/dma-mapping.h>
17#include <linux/vmalloc.h>
18#include <asm/tlbflush.h>
19#include <asm/homecache.h>
20
21/* Generic DMA mapping functions: */
22
23/*
24 * Allocate what Linux calls "coherent" memory, which for us just
25 * means uncached.
26 */
27void *dma_alloc_coherent(struct device *dev,
28 size_t size,
29 dma_addr_t *dma_handle,
30 gfp_t gfp)
31{
32 u64 dma_mask = dev->coherent_dma_mask ?: DMA_BIT_MASK(32);
33 int node = dev_to_node(dev);
34 int order = get_order(size);
35 struct page *pg;
36 dma_addr_t addr;
37
38 gfp |= __GFP_ZERO;
39
40 /*
41 * By forcing NUMA node 0 for 32-bit masks we ensure that the
42 * high 32 bits of the resulting PA will be zero. If the mask
43 * size is, e.g., 24, we may still not be able to guarantee a
44 * suitable memory address, in which case we will return NULL.
45 * But such devices are uncommon.
46 */
47 if (dma_mask <= DMA_BIT_MASK(32))
48 node = 0;
49
50 pg = homecache_alloc_pages_node(node, gfp, order, PAGE_HOME_UNCACHED);
51 if (pg == NULL)
52 return NULL;
53
54 addr = page_to_phys(pg);
55 if (addr + size > dma_mask) {
56 homecache_free_pages(addr, order);
57 return NULL;
58 }
59
60 *dma_handle = addr;
61 return page_address(pg);
62}
63EXPORT_SYMBOL(dma_alloc_coherent);
64
65/*
66 * Free memory that was allocated with dma_alloc_coherent.
67 */
68void dma_free_coherent(struct device *dev, size_t size,
69 void *vaddr, dma_addr_t dma_handle)
70{
71 homecache_free_pages((unsigned long)vaddr, get_order(size));
72}
73EXPORT_SYMBOL(dma_free_coherent);
74
75/*
76 * The map routines "map" the specified address range for DMA
77 * accesses. The memory belongs to the device after this call is
78 * issued, until it is unmapped with dma_unmap_single.
79 *
80 * We don't need to do any mapping, we just flush the address range
81 * out of the cache and return a DMA address.
82 *
83 * The unmap routines do whatever is necessary before the processor
84 * accesses the memory again, and must be called before the driver
85 * touches the memory. We can get away with a cache invalidate if we
86 * can count on nothing having been touched.
87 */
88
89
90/*
91 * dma_map_single can be passed any memory address, and there appear
92 * to be no alignment constraints.
93 *
94 * There is a chance that the start of the buffer will share a cache
95 * line with some other data that has been touched in the meantime.
96 */
97dma_addr_t dma_map_single(struct device *dev, void *ptr, size_t size,
98 enum dma_data_direction direction)
99{
100 struct page *page;
101 dma_addr_t dma_addr;
102 int thispage;
103
104 BUG_ON(!valid_dma_direction(direction));
105 WARN_ON(size == 0);
106
107 dma_addr = __pa(ptr);
108
109 /* We might have been handed a buffer that wraps a page boundary */
110 while ((int)size > 0) {
111 /* The amount to flush that's on this page */
112 thispage = PAGE_SIZE - ((unsigned long)ptr & (PAGE_SIZE - 1));
113 thispage = min((int)thispage, (int)size);
114 /* Is this valid for any page we could be handed? */
115 page = pfn_to_page(kaddr_to_pfn(ptr));
116 homecache_flush_cache(page, 0);
117 ptr += thispage;
118 size -= thispage;
119 }
120
121 return dma_addr;
122}
123EXPORT_SYMBOL(dma_map_single);
124
125void dma_unmap_single(struct device *dev, dma_addr_t dma_addr, size_t size,
126 enum dma_data_direction direction)
127{
128 BUG_ON(!valid_dma_direction(direction));
129}
130EXPORT_SYMBOL(dma_unmap_single);
131
132int dma_map_sg(struct device *dev, struct scatterlist *sglist, int nents,
133 enum dma_data_direction direction)
134{
135 struct scatterlist *sg;
136 int i;
137
138 BUG_ON(!valid_dma_direction(direction));
139
140 WARN_ON(nents == 0 || sglist->length == 0);
141
142 for_each_sg(sglist, sg, nents, i) {
143 struct page *page;
144 sg->dma_address = sg_phys(sg);
145 page = pfn_to_page(sg->dma_address >> PAGE_SHIFT);
146 homecache_flush_cache(page, 0);
147 }
148
149 return nents;
150}
151EXPORT_SYMBOL(dma_map_sg);
152
153void dma_unmap_sg(struct device *dev, struct scatterlist *sg, int nhwentries,
154 enum dma_data_direction direction)
155{
156 BUG_ON(!valid_dma_direction(direction));
157}
158EXPORT_SYMBOL(dma_unmap_sg);
159
160dma_addr_t dma_map_page(struct device *dev, struct page *page,
161 unsigned long offset, size_t size,
162 enum dma_data_direction direction)
163{
164 BUG_ON(!valid_dma_direction(direction));
165
166 homecache_flush_cache(page, 0);
167
168 return page_to_pa(page) + offset;
169}
170EXPORT_SYMBOL(dma_map_page);
171
172void dma_unmap_page(struct device *dev, dma_addr_t dma_address, size_t size,
173 enum dma_data_direction direction)
174{
175 BUG_ON(!valid_dma_direction(direction));
176}
177EXPORT_SYMBOL(dma_unmap_page);
178
179void dma_sync_single_for_cpu(struct device *dev, dma_addr_t dma_handle,
180 size_t size, enum dma_data_direction direction)
181{
182 BUG_ON(!valid_dma_direction(direction));
183}
184EXPORT_SYMBOL(dma_sync_single_for_cpu);
185
186void dma_sync_single_for_device(struct device *dev, dma_addr_t dma_handle,
187 size_t size, enum dma_data_direction direction)
188{
189 unsigned long start = PFN_DOWN(dma_handle);
190 unsigned long end = PFN_DOWN(dma_handle + size - 1);
191 unsigned long i;
192
193 BUG_ON(!valid_dma_direction(direction));
194 for (i = start; i <= end; ++i)
195 homecache_flush_cache(pfn_to_page(i), 0);
196}
197EXPORT_SYMBOL(dma_sync_single_for_device);
198
199void dma_sync_sg_for_cpu(struct device *dev, struct scatterlist *sg, int nelems,
200 enum dma_data_direction direction)
201{
202 BUG_ON(!valid_dma_direction(direction));
203 WARN_ON(nelems == 0 || sg[0].length == 0);
204}
205EXPORT_SYMBOL(dma_sync_sg_for_cpu);
206
207/*
208 * Flush and invalidate cache for scatterlist.
209 */
210void dma_sync_sg_for_device(struct device *dev, struct scatterlist *sglist,
211 int nelems, enum dma_data_direction direction)
212{
213 struct scatterlist *sg;
214 int i;
215
216 BUG_ON(!valid_dma_direction(direction));
217 WARN_ON(nelems == 0 || sglist->length == 0);
218
219 for_each_sg(sglist, sg, nelems, i) {
220 dma_sync_single_for_device(dev, sg->dma_address,
221 sg_dma_len(sg), direction);
222 }
223}
224EXPORT_SYMBOL(dma_sync_sg_for_device);
225
226void dma_sync_single_range_for_cpu(struct device *dev, dma_addr_t dma_handle,
227 unsigned long offset, size_t size,
228 enum dma_data_direction direction)
229{
230 dma_sync_single_for_cpu(dev, dma_handle + offset, size, direction);
231}
232EXPORT_SYMBOL(dma_sync_single_range_for_cpu);
233
234void dma_sync_single_range_for_device(struct device *dev,
235 dma_addr_t dma_handle,
236 unsigned long offset, size_t size,
237 enum dma_data_direction direction)
238{
239 dma_sync_single_for_device(dev, dma_handle + offset, size, direction);
240}
241EXPORT_SYMBOL(dma_sync_single_range_for_device);
242
243/*
244 * dma_alloc_noncoherent() returns non-cacheable memory, so there's no
245 * need to do any flushing here.
246 */
247void dma_cache_sync(void *vaddr, size_t size,
248 enum dma_data_direction direction)
249{
250}
251EXPORT_SYMBOL(dma_cache_sync);
diff --git a/arch/tile/kernel/proc.c b/arch/tile/kernel/proc.c
new file mode 100644
index 000000000000..2e02c41ddf3b
--- /dev/null
+++ b/arch/tile/kernel/proc.c
@@ -0,0 +1,90 @@
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#include <linux/smp.h>
16#include <linux/seq_file.h>
17#include <linux/threads.h>
18#include <linux/cpumask.h>
19#include <linux/timex.h>
20#include <linux/delay.h>
21#include <linux/fs.h>
22#include <linux/proc_fs.h>
23#include <linux/sysctl.h>
24#include <linux/hardirq.h>
25#include <linux/mman.h>
26#include <asm/pgtable.h>
27#include <asm/processor.h>
28#include <asm/sections.h>
29#include <asm/homecache.h>
30#include <arch/chip.h>
31
32
33/*
34 * Support /proc/cpuinfo
35 */
36
37#define cpu_to_ptr(n) ((void *)((long)(n)+1))
38#define ptr_to_cpu(p) ((long)(p) - 1)
39
40static int show_cpuinfo(struct seq_file *m, void *v)
41{
42 int n = ptr_to_cpu(v);
43
44 if (n == 0) {
45 char buf[NR_CPUS*5];
46 cpulist_scnprintf(buf, sizeof(buf), cpu_online_mask);
47 seq_printf(m, "cpu count\t: %d\n", num_online_cpus());
48 seq_printf(m, "cpu list\t: %s\n", buf);
49 seq_printf(m, "model name\t: %s\n", chip_model);
50 seq_printf(m, "flags\t\t:\n"); /* nothing for now */
51 seq_printf(m, "cpu MHz\t\t: %llu.%06llu\n",
52 get_clock_rate() / 1000000,
53 (get_clock_rate() % 1000000));
54 seq_printf(m, "bogomips\t: %lu.%02lu\n\n",
55 loops_per_jiffy/(500000/HZ),
56 (loops_per_jiffy/(5000/HZ)) % 100);
57 }
58
59#ifdef CONFIG_SMP
60 if (!cpu_online(n))
61 return 0;
62#endif
63
64 seq_printf(m, "processor\t: %d\n", n);
65
66 /* Print only num_online_cpus() blank lines total. */
67 if (cpumask_next(n, cpu_online_mask) < nr_cpu_ids)
68 seq_printf(m, "\n");
69
70 return 0;
71}
72
73static void *c_start(struct seq_file *m, loff_t *pos)
74{
75 return *pos < nr_cpu_ids ? cpu_to_ptr(*pos) : NULL;
76}
77static void *c_next(struct seq_file *m, void *v, loff_t *pos)
78{
79 ++*pos;
80 return c_start(m, pos);
81}
82static void c_stop(struct seq_file *m, void *v)
83{
84}
85const struct seq_operations cpuinfo_op = {
86 .start = c_start,
87 .next = c_next,
88 .stop = c_stop,
89 .show = show_cpuinfo,
90};
diff --git a/arch/tile/kernel/process.c b/arch/tile/kernel/process.c
new file mode 100644
index 000000000000..985cc28c74c5
--- /dev/null
+++ b/arch/tile/kernel/process.c
@@ -0,0 +1,672 @@
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#include <linux/sched.h>
16#include <linux/preempt.h>
17#include <linux/module.h>
18#include <linux/fs.h>
19#include <linux/kprobes.h>
20#include <linux/elfcore.h>
21#include <linux/tick.h>
22#include <linux/init.h>
23#include <linux/mm.h>
24#include <linux/compat.h>
25#include <linux/hardirq.h>
26#include <linux/syscalls.h>
27#include <linux/kernel.h>
28#include <asm/system.h>
29#include <asm/stack.h>
30#include <asm/homecache.h>
31#include <asm/syscalls.h>
32#ifdef CONFIG_HARDWALL
33#include <asm/hardwall.h>
34#endif
35#include <arch/chip.h>
36#include <arch/abi.h>
37
38
39/*
40 * Use the (x86) "idle=poll" option to prefer low latency when leaving the
41 * idle loop over low power while in the idle loop, e.g. if we have
42 * one thread per core and we want to get threads out of futex waits fast.
43 */
44static int no_idle_nap;
45static int __init idle_setup(char *str)
46{
47 if (!str)
48 return -EINVAL;
49
50 if (!strcmp(str, "poll")) {
51 pr_info("using polling idle threads.\n");
52 no_idle_nap = 1;
53 } else if (!strcmp(str, "halt"))
54 no_idle_nap = 0;
55 else
56 return -1;
57
58 return 0;
59}
60early_param("idle", idle_setup);
61
62/*
63 * The idle thread. There's no useful work to be
64 * done, so just try to conserve power and have a
65 * low exit latency (ie sit in a loop waiting for
66 * somebody to say that they'd like to reschedule)
67 */
68void cpu_idle(void)
69{
70 int cpu = smp_processor_id();
71
72
73 current_thread_info()->status |= TS_POLLING;
74
75 if (no_idle_nap) {
76 while (1) {
77 while (!need_resched())
78 cpu_relax();
79 schedule();
80 }
81 }
82
83 /* endless idle loop with no priority at all */
84 while (1) {
85 tick_nohz_stop_sched_tick(1);
86 while (!need_resched()) {
87 if (cpu_is_offline(cpu))
88 BUG(); /* no HOTPLUG_CPU */
89
90 local_irq_disable();
91 __get_cpu_var(irq_stat).idle_timestamp = jiffies;
92 current_thread_info()->status &= ~TS_POLLING;
93 /*
94 * TS_POLLING-cleared state must be visible before we
95 * test NEED_RESCHED:
96 */
97 smp_mb();
98
99 if (!need_resched())
100 _cpu_idle();
101 else
102 local_irq_enable();
103 current_thread_info()->status |= TS_POLLING;
104 }
105 tick_nohz_restart_sched_tick();
106 preempt_enable_no_resched();
107 schedule();
108 preempt_disable();
109 }
110}
111
112struct thread_info *alloc_thread_info(struct task_struct *task)
113{
114 struct page *page;
115 gfp_t flags = GFP_KERNEL;
116
117#ifdef CONFIG_DEBUG_STACK_USAGE
118 flags |= __GFP_ZERO;
119#endif
120
121 page = alloc_pages(flags, THREAD_SIZE_ORDER);
122 if (!page)
123 return NULL;
124
125 return (struct thread_info *)page_address(page);
126}
127
128/*
129 * Free a thread_info node, and all of its derivative
130 * data structures.
131 */
132void free_thread_info(struct thread_info *info)
133{
134 struct single_step_state *step_state = info->step_state;
135
136#ifdef CONFIG_HARDWALL
137 /*
138 * We free a thread_info from the context of the task that has
139 * been scheduled next, so the original task is already dead.
140 * Calling deactivate here just frees up the data structures.
141 * If the task we're freeing held the last reference to a
142 * hardwall fd, it would have been released prior to this point
143 * anyway via exit_files(), and "hardwall" would be NULL by now.
144 */
145 if (info->task->thread.hardwall)
146 hardwall_deactivate(info->task);
147#endif
148
149 if (step_state) {
150
151 /*
152 * FIXME: we don't munmap step_state->buffer
153 * because the mm_struct for this process (info->task->mm)
154 * has already been zeroed in exit_mm(). Keeping a
155 * reference to it here seems like a bad move, so this
156 * means we can't munmap() the buffer, and therefore if we
157 * ptrace multiple threads in a process, we will slowly
158 * leak user memory. (Note that as soon as the last
159 * thread in a process dies, we will reclaim all user
160 * memory including single-step buffers in the usual way.)
161 * We should either assign a kernel VA to this buffer
162 * somehow, or we should associate the buffer(s) with the
163 * mm itself so we can clean them up that way.
164 */
165 kfree(step_state);
166 }
167
168 free_page((unsigned long)info);
169}
170
171static void save_arch_state(struct thread_struct *t);
172
173int copy_thread(unsigned long clone_flags, unsigned long sp,
174 unsigned long stack_size,
175 struct task_struct *p, struct pt_regs *regs)
176{
177 struct pt_regs *childregs;
178 unsigned long ksp;
179
180 /*
181 * When creating a new kernel thread we pass sp as zero.
182 * Assign it to a reasonable value now that we have the stack.
183 */
184 if (sp == 0 && regs->ex1 == PL_ICS_EX1(KERNEL_PL, 0))
185 sp = KSTK_TOP(p);
186
187 /*
188 * Do not clone step state from the parent; each thread
189 * must make its own lazily.
190 */
191 task_thread_info(p)->step_state = NULL;
192
193 /*
194 * Start new thread in ret_from_fork so it schedules properly
195 * and then return from interrupt like the parent.
196 */
197 p->thread.pc = (unsigned long) ret_from_fork;
198
199 /* Save user stack top pointer so we can ID the stack vm area later. */
200 p->thread.usp0 = sp;
201
202 /* Record the pid of the process that created this one. */
203 p->thread.creator_pid = current->pid;
204
205 /*
206 * Copy the registers onto the kernel stack so the
207 * return-from-interrupt code will reload it into registers.
208 */
209 childregs = task_pt_regs(p);
210 *childregs = *regs;
211 childregs->regs[0] = 0; /* return value is zero */
212 childregs->sp = sp; /* override with new user stack pointer */
213
214 /*
215 * Copy the callee-saved registers from the passed pt_regs struct
216 * into the context-switch callee-saved registers area.
217 * We have to restore the callee-saved registers since we may
218 * be cloning a userspace task with userspace register state,
219 * and we won't be unwinding the same kernel frames to restore them.
220 * Zero out the C ABI save area to mark the top of the stack.
221 */
222 ksp = (unsigned long) childregs;
223 ksp -= C_ABI_SAVE_AREA_SIZE; /* interrupt-entry save area */
224 ((long *)ksp)[0] = ((long *)ksp)[1] = 0;
225 ksp -= CALLEE_SAVED_REGS_COUNT * sizeof(unsigned long);
226 memcpy((void *)ksp, &regs->regs[CALLEE_SAVED_FIRST_REG],
227 CALLEE_SAVED_REGS_COUNT * sizeof(unsigned long));
228 ksp -= C_ABI_SAVE_AREA_SIZE; /* __switch_to() save area */
229 ((long *)ksp)[0] = ((long *)ksp)[1] = 0;
230 p->thread.ksp = ksp;
231
232#if CHIP_HAS_TILE_DMA()
233 /*
234 * No DMA in the new thread. We model this on the fact that
235 * fork() clears the pending signals, alarms, and aio for the child.
236 */
237 memset(&p->thread.tile_dma_state, 0, sizeof(struct tile_dma_state));
238 memset(&p->thread.dma_async_tlb, 0, sizeof(struct async_tlb));
239#endif
240
241#if CHIP_HAS_SN_PROC()
242 /* Likewise, the new thread is not running static processor code. */
243 p->thread.sn_proc_running = 0;
244 memset(&p->thread.sn_async_tlb, 0, sizeof(struct async_tlb));
245#endif
246
247#if CHIP_HAS_PROC_STATUS_SPR()
248 /* New thread has its miscellaneous processor state bits clear. */
249 p->thread.proc_status = 0;
250#endif
251
252#ifdef CONFIG_HARDWALL
253 /* New thread does not own any networks. */
254 p->thread.hardwall = NULL;
255#endif
256
257
258 /*
259 * Start the new thread with the current architecture state
260 * (user interrupt masks, etc.).
261 */
262 save_arch_state(&p->thread);
263
264 return 0;
265}
266
267/*
268 * Return "current" if it looks plausible, or else a pointer to a dummy.
269 * This can be helpful if we are just trying to emit a clean panic.
270 */
271struct task_struct *validate_current(void)
272{
273 static struct task_struct corrupt = { .comm = "<corrupt>" };
274 struct task_struct *tsk = current;
275 if (unlikely((unsigned long)tsk < PAGE_OFFSET ||
276 (void *)tsk > high_memory ||
277 ((unsigned long)tsk & (__alignof__(*tsk) - 1)) != 0)) {
278 pr_err("Corrupt 'current' %p (sp %#lx)\n", tsk, stack_pointer);
279 tsk = &corrupt;
280 }
281 return tsk;
282}
283
284/* Take and return the pointer to the previous task, for schedule_tail(). */
285struct task_struct *sim_notify_fork(struct task_struct *prev)
286{
287 struct task_struct *tsk = current;
288 __insn_mtspr(SPR_SIM_CONTROL, SIM_CONTROL_OS_FORK_PARENT |
289 (tsk->thread.creator_pid << _SIM_CONTROL_OPERATOR_BITS));
290 __insn_mtspr(SPR_SIM_CONTROL, SIM_CONTROL_OS_FORK |
291 (tsk->pid << _SIM_CONTROL_OPERATOR_BITS));
292 return prev;
293}
294
295int dump_task_regs(struct task_struct *tsk, elf_gregset_t *regs)
296{
297 struct pt_regs *ptregs = task_pt_regs(tsk);
298 elf_core_copy_regs(regs, ptregs);
299 return 1;
300}
301
302#if CHIP_HAS_TILE_DMA()
303
304/* Allow user processes to access the DMA SPRs */
305void grant_dma_mpls(void)
306{
307 __insn_mtspr(SPR_MPL_DMA_CPL_SET_0, 1);
308 __insn_mtspr(SPR_MPL_DMA_NOTIFY_SET_0, 1);
309}
310
311/* Forbid user processes from accessing the DMA SPRs */
312void restrict_dma_mpls(void)
313{
314 __insn_mtspr(SPR_MPL_DMA_CPL_SET_1, 1);
315 __insn_mtspr(SPR_MPL_DMA_NOTIFY_SET_1, 1);
316}
317
318/* Pause the DMA engine, then save off its state registers. */
319static void save_tile_dma_state(struct tile_dma_state *dma)
320{
321 unsigned long state = __insn_mfspr(SPR_DMA_USER_STATUS);
322 unsigned long post_suspend_state;
323
324 /* If we're running, suspend the engine. */
325 if ((state & DMA_STATUS_MASK) == SPR_DMA_STATUS__RUNNING_MASK)
326 __insn_mtspr(SPR_DMA_CTR, SPR_DMA_CTR__SUSPEND_MASK);
327
328 /*
329 * Wait for the engine to idle, then save regs. Note that we
330 * want to record the "running" bit from before suspension,
331 * and the "done" bit from after, so that we can properly
332 * distinguish a case where the user suspended the engine from
333 * the case where the kernel suspended as part of the context
334 * swap.
335 */
336 do {
337 post_suspend_state = __insn_mfspr(SPR_DMA_USER_STATUS);
338 } while (post_suspend_state & SPR_DMA_STATUS__BUSY_MASK);
339
340 dma->src = __insn_mfspr(SPR_DMA_SRC_ADDR);
341 dma->src_chunk = __insn_mfspr(SPR_DMA_SRC_CHUNK_ADDR);
342 dma->dest = __insn_mfspr(SPR_DMA_DST_ADDR);
343 dma->dest_chunk = __insn_mfspr(SPR_DMA_DST_CHUNK_ADDR);
344 dma->strides = __insn_mfspr(SPR_DMA_STRIDE);
345 dma->chunk_size = __insn_mfspr(SPR_DMA_CHUNK_SIZE);
346 dma->byte = __insn_mfspr(SPR_DMA_BYTE);
347 dma->status = (state & SPR_DMA_STATUS__RUNNING_MASK) |
348 (post_suspend_state & SPR_DMA_STATUS__DONE_MASK);
349}
350
351/* Restart a DMA that was running before we were context-switched out. */
352static void restore_tile_dma_state(struct thread_struct *t)
353{
354 const struct tile_dma_state *dma = &t->tile_dma_state;
355
356 /*
357 * The only way to restore the done bit is to run a zero
358 * length transaction.
359 */
360 if ((dma->status & SPR_DMA_STATUS__DONE_MASK) &&
361 !(__insn_mfspr(SPR_DMA_USER_STATUS) & SPR_DMA_STATUS__DONE_MASK)) {
362 __insn_mtspr(SPR_DMA_BYTE, 0);
363 __insn_mtspr(SPR_DMA_CTR, SPR_DMA_CTR__REQUEST_MASK);
364 while (__insn_mfspr(SPR_DMA_USER_STATUS) &
365 SPR_DMA_STATUS__BUSY_MASK)
366 ;
367 }
368
369 __insn_mtspr(SPR_DMA_SRC_ADDR, dma->src);
370 __insn_mtspr(SPR_DMA_SRC_CHUNK_ADDR, dma->src_chunk);
371 __insn_mtspr(SPR_DMA_DST_ADDR, dma->dest);
372 __insn_mtspr(SPR_DMA_DST_CHUNK_ADDR, dma->dest_chunk);
373 __insn_mtspr(SPR_DMA_STRIDE, dma->strides);
374 __insn_mtspr(SPR_DMA_CHUNK_SIZE, dma->chunk_size);
375 __insn_mtspr(SPR_DMA_BYTE, dma->byte);
376
377 /*
378 * Restart the engine if we were running and not done.
379 * Clear a pending async DMA fault that we were waiting on return
380 * to user space to execute, since we expect the DMA engine
381 * to regenerate those faults for us now. Note that we don't
382 * try to clear the TIF_ASYNC_TLB flag, since it's relatively
383 * harmless if set, and it covers both DMA and the SN processor.
384 */
385 if ((dma->status & DMA_STATUS_MASK) == SPR_DMA_STATUS__RUNNING_MASK) {
386 t->dma_async_tlb.fault_num = 0;
387 __insn_mtspr(SPR_DMA_CTR, SPR_DMA_CTR__REQUEST_MASK);
388 }
389}
390
391#endif
392
393static void save_arch_state(struct thread_struct *t)
394{
395#if CHIP_HAS_SPLIT_INTR_MASK()
396 t->interrupt_mask = __insn_mfspr(SPR_INTERRUPT_MASK_0_0) |
397 ((u64)__insn_mfspr(SPR_INTERRUPT_MASK_0_1) << 32);
398#else
399 t->interrupt_mask = __insn_mfspr(SPR_INTERRUPT_MASK_0);
400#endif
401 t->ex_context[0] = __insn_mfspr(SPR_EX_CONTEXT_0_0);
402 t->ex_context[1] = __insn_mfspr(SPR_EX_CONTEXT_0_1);
403 t->system_save[0] = __insn_mfspr(SPR_SYSTEM_SAVE_0_0);
404 t->system_save[1] = __insn_mfspr(SPR_SYSTEM_SAVE_0_1);
405 t->system_save[2] = __insn_mfspr(SPR_SYSTEM_SAVE_0_2);
406 t->system_save[3] = __insn_mfspr(SPR_SYSTEM_SAVE_0_3);
407 t->intctrl_0 = __insn_mfspr(SPR_INTCTRL_0_STATUS);
408#if CHIP_HAS_PROC_STATUS_SPR()
409 t->proc_status = __insn_mfspr(SPR_PROC_STATUS);
410#endif
411}
412
413static void restore_arch_state(const struct thread_struct *t)
414{
415#if CHIP_HAS_SPLIT_INTR_MASK()
416 __insn_mtspr(SPR_INTERRUPT_MASK_0_0, (u32) t->interrupt_mask);
417 __insn_mtspr(SPR_INTERRUPT_MASK_0_1, t->interrupt_mask >> 32);
418#else
419 __insn_mtspr(SPR_INTERRUPT_MASK_0, t->interrupt_mask);
420#endif
421 __insn_mtspr(SPR_EX_CONTEXT_0_0, t->ex_context[0]);
422 __insn_mtspr(SPR_EX_CONTEXT_0_1, t->ex_context[1]);
423 __insn_mtspr(SPR_SYSTEM_SAVE_0_0, t->system_save[0]);
424 __insn_mtspr(SPR_SYSTEM_SAVE_0_1, t->system_save[1]);
425 __insn_mtspr(SPR_SYSTEM_SAVE_0_2, t->system_save[2]);
426 __insn_mtspr(SPR_SYSTEM_SAVE_0_3, t->system_save[3]);
427 __insn_mtspr(SPR_INTCTRL_0_STATUS, t->intctrl_0);
428#if CHIP_HAS_PROC_STATUS_SPR()
429 __insn_mtspr(SPR_PROC_STATUS, t->proc_status);
430#endif
431#if CHIP_HAS_TILE_RTF_HWM()
432 /*
433 * Clear this whenever we switch back to a process in case
434 * the previous process was monkeying with it. Even if enabled
435 * in CBOX_MSR1 via TILE_RTF_HWM_MIN, it's still just a
436 * performance hint, so isn't worth a full save/restore.
437 */
438 __insn_mtspr(SPR_TILE_RTF_HWM, 0);
439#endif
440}
441
442
443void _prepare_arch_switch(struct task_struct *next)
444{
445#if CHIP_HAS_SN_PROC()
446 int snctl;
447#endif
448#if CHIP_HAS_TILE_DMA()
449 struct tile_dma_state *dma = &current->thread.tile_dma_state;
450 if (dma->enabled)
451 save_tile_dma_state(dma);
452#endif
453#if CHIP_HAS_SN_PROC()
454 /*
455 * Suspend the static network processor if it was running.
456 * We do not suspend the fabric itself, just like we don't
457 * try to suspend the UDN.
458 */
459 snctl = __insn_mfspr(SPR_SNCTL);
460 current->thread.sn_proc_running =
461 (snctl & SPR_SNCTL__FRZPROC_MASK) == 0;
462 if (current->thread.sn_proc_running)
463 __insn_mtspr(SPR_SNCTL, snctl | SPR_SNCTL__FRZPROC_MASK);
464#endif
465}
466
467
468struct task_struct *__sched _switch_to(struct task_struct *prev,
469 struct task_struct *next)
470{
471 /* DMA state is already saved; save off other arch state. */
472 save_arch_state(&prev->thread);
473
474#if CHIP_HAS_TILE_DMA()
475 /*
476 * Restore DMA in new task if desired.
477 * Note that it is only safe to restart here since interrupts
478 * are disabled, so we can't take any DMATLB miss or access
479 * interrupts before we have finished switching stacks.
480 */
481 if (next->thread.tile_dma_state.enabled) {
482 restore_tile_dma_state(&next->thread);
483 grant_dma_mpls();
484 } else {
485 restrict_dma_mpls();
486 }
487#endif
488
489 /* Restore other arch state. */
490 restore_arch_state(&next->thread);
491
492#if CHIP_HAS_SN_PROC()
493 /*
494 * Restart static network processor in the new process
495 * if it was running before.
496 */
497 if (next->thread.sn_proc_running) {
498 int snctl = __insn_mfspr(SPR_SNCTL);
499 __insn_mtspr(SPR_SNCTL, snctl & ~SPR_SNCTL__FRZPROC_MASK);
500 }
501#endif
502
503#ifdef CONFIG_HARDWALL
504 /* Enable or disable access to the network registers appropriately. */
505 if (prev->thread.hardwall != NULL) {
506 if (next->thread.hardwall == NULL)
507 restrict_network_mpls();
508 } else if (next->thread.hardwall != NULL) {
509 grant_network_mpls();
510 }
511#endif
512
513 /*
514 * Switch kernel SP, PC, and callee-saved registers.
515 * In the context of the new task, return the old task pointer
516 * (i.e. the task that actually called __switch_to).
517 * Pass the value to use for SYSTEM_SAVE_1_0 when we reset our sp.
518 */
519 return __switch_to(prev, next, next_current_ksp0(next));
520}
521
522long _sys_fork(struct pt_regs *regs)
523{
524 return do_fork(SIGCHLD, regs->sp, regs, 0, NULL, NULL);
525}
526
527long _sys_clone(unsigned long clone_flags, unsigned long newsp,
528 void __user *parent_tidptr, void __user *child_tidptr,
529 struct pt_regs *regs)
530{
531 if (!newsp)
532 newsp = regs->sp;
533 return do_fork(clone_flags, newsp, regs, 0,
534 parent_tidptr, child_tidptr);
535}
536
537long _sys_vfork(struct pt_regs *regs)
538{
539 return do_fork(CLONE_VFORK | CLONE_VM | SIGCHLD, regs->sp,
540 regs, 0, NULL, NULL);
541}
542
543/*
544 * sys_execve() executes a new program.
545 */
546long _sys_execve(const char __user *path,
547 const char __user *const __user *argv,
548 const char __user *const __user *envp, struct pt_regs *regs)
549{
550 long error;
551 char *filename;
552
553 filename = getname(path);
554 error = PTR_ERR(filename);
555 if (IS_ERR(filename))
556 goto out;
557 error = do_execve(filename, argv, envp, regs);
558 putname(filename);
559out:
560 return error;
561}
562
563#ifdef CONFIG_COMPAT
564long _compat_sys_execve(char __user *path, compat_uptr_t __user *argv,
565 compat_uptr_t __user *envp, struct pt_regs *regs)
566{
567 long error;
568 char *filename;
569
570 filename = getname(path);
571 error = PTR_ERR(filename);
572 if (IS_ERR(filename))
573 goto out;
574 error = compat_do_execve(filename, argv, envp, regs);
575 putname(filename);
576out:
577 return error;
578}
579#endif
580
581unsigned long get_wchan(struct task_struct *p)
582{
583 struct KBacktraceIterator kbt;
584
585 if (!p || p == current || p->state == TASK_RUNNING)
586 return 0;
587
588 for (KBacktraceIterator_init(&kbt, p, NULL);
589 !KBacktraceIterator_end(&kbt);
590 KBacktraceIterator_next(&kbt)) {
591 if (!in_sched_functions(kbt.it.pc))
592 return kbt.it.pc;
593 }
594
595 return 0;
596}
597
598/*
599 * We pass in lr as zero (cleared in kernel_thread) and the caller
600 * part of the backtrace ABI on the stack also zeroed (in copy_thread)
601 * so that backtraces will stop with this function.
602 * Note that we don't use r0, since copy_thread() clears it.
603 */
604static void start_kernel_thread(int dummy, int (*fn)(int), int arg)
605{
606 do_exit(fn(arg));
607}
608
609/*
610 * Create a kernel thread
611 */
612int kernel_thread(int (*fn)(void *), void * arg, unsigned long flags)
613{
614 struct pt_regs regs;
615
616 memset(&regs, 0, sizeof(regs));
617 regs.ex1 = PL_ICS_EX1(KERNEL_PL, 0); /* run at kernel PL, no ICS */
618 regs.pc = (long) start_kernel_thread;
619 regs.flags = PT_FLAGS_CALLER_SAVES; /* need to restore r1 and r2 */
620 regs.regs[1] = (long) fn; /* function pointer */
621 regs.regs[2] = (long) arg; /* parameter register */
622
623 /* Ok, create the new process.. */
624 return do_fork(flags | CLONE_VM | CLONE_UNTRACED, 0, &regs,
625 0, NULL, NULL);
626}
627EXPORT_SYMBOL(kernel_thread);
628
629/* Flush thread state. */
630void flush_thread(void)
631{
632 /* Nothing */
633}
634
635/*
636 * Free current thread data structures etc..
637 */
638void exit_thread(void)
639{
640 /* Nothing */
641}
642
643void show_regs(struct pt_regs *regs)
644{
645 struct task_struct *tsk = validate_current();
646 int i;
647
648 pr_err("\n");
649 pr_err(" Pid: %d, comm: %20s, CPU: %d\n",
650 tsk->pid, tsk->comm, smp_processor_id());
651#ifdef __tilegx__
652 for (i = 0; i < 51; i += 3)
653 pr_err(" r%-2d: "REGFMT" r%-2d: "REGFMT" r%-2d: "REGFMT"\n",
654 i, regs->regs[i], i+1, regs->regs[i+1],
655 i+2, regs->regs[i+2]);
656 pr_err(" r51: "REGFMT" r52: "REGFMT" tp : "REGFMT"\n",
657 regs->regs[51], regs->regs[52], regs->tp);
658 pr_err(" sp : "REGFMT" lr : "REGFMT"\n", regs->sp, regs->lr);
659#else
660 for (i = 0; i < 52; i += 3)
661 pr_err(" r%-2d: "REGFMT" r%-2d: "REGFMT
662 " r%-2d: "REGFMT" r%-2d: "REGFMT"\n",
663 i, regs->regs[i], i+1, regs->regs[i+1],
664 i+2, regs->regs[i+2], i+3, regs->regs[i+3]);
665 pr_err(" r52: "REGFMT" tp : "REGFMT" sp : "REGFMT" lr : "REGFMT"\n",
666 regs->regs[52], regs->tp, regs->sp, regs->lr);
667#endif
668 pr_err(" pc : "REGFMT" ex1: %ld faultnum: %ld\n",
669 regs->pc, regs->ex1, regs->faultnum);
670
671 dump_stack_regs(regs);
672}
diff --git a/arch/tile/kernel/ptrace.c b/arch/tile/kernel/ptrace.c
new file mode 100644
index 000000000000..7161bd03d2fd
--- /dev/null
+++ b/arch/tile/kernel/ptrace.c
@@ -0,0 +1,205 @@
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 * Copied from i386: Ross Biro 1/23/92
15 */
16
17#include <linux/kernel.h>
18#include <linux/ptrace.h>
19#include <linux/kprobes.h>
20#include <linux/compat.h>
21#include <linux/uaccess.h>
22#include <asm/traps.h>
23
24void user_enable_single_step(struct task_struct *child)
25{
26 set_tsk_thread_flag(child, TIF_SINGLESTEP);
27}
28
29void user_disable_single_step(struct task_struct *child)
30{
31 clear_tsk_thread_flag(child, TIF_SINGLESTEP);
32}
33
34/*
35 * This routine will put a word on the process's privileged stack.
36 */
37static void putreg(struct task_struct *task,
38 unsigned long addr, unsigned long value)
39{
40 unsigned int regno = addr / sizeof(unsigned long);
41 struct pt_regs *childregs = task_pt_regs(task);
42 childregs->regs[regno] = value;
43 childregs->flags |= PT_FLAGS_RESTORE_REGS;
44}
45
46static unsigned long getreg(struct task_struct *task, unsigned long addr)
47{
48 unsigned int regno = addr / sizeof(unsigned long);
49 struct pt_regs *childregs = task_pt_regs(task);
50 return childregs->regs[regno];
51}
52
53/*
54 * Called by kernel/ptrace.c when detaching..
55 */
56void ptrace_disable(struct task_struct *child)
57{
58 clear_tsk_thread_flag(child, TIF_SINGLESTEP);
59
60 /*
61 * These two are currently unused, but will be set by arch_ptrace()
62 * and used in the syscall assembly when we do support them.
63 */
64 clear_tsk_thread_flag(child, TIF_SYSCALL_TRACE);
65}
66
67long arch_ptrace(struct task_struct *child, long request, long addr, long data)
68{
69 unsigned long __user *datap;
70 unsigned long tmp;
71 int i;
72 long ret = -EIO;
73
74#ifdef CONFIG_COMPAT
75 if (task_thread_info(current)->status & TS_COMPAT)
76 data = (u32)data;
77 if (task_thread_info(child)->status & TS_COMPAT)
78 addr = (u32)addr;
79#endif
80 datap = (unsigned long __user __force *)data;
81
82 switch (request) {
83
84 case PTRACE_PEEKUSR: /* Read register from pt_regs. */
85 if (addr & (sizeof(data)-1))
86 break;
87 if (addr < 0 || addr >= PTREGS_SIZE)
88 break;
89 tmp = getreg(child, addr); /* Read register */
90 ret = put_user(tmp, datap);
91 break;
92
93 case PTRACE_POKEUSR: /* Write register in pt_regs. */
94 if (addr & (sizeof(data)-1))
95 break;
96 if (addr < 0 || addr >= PTREGS_SIZE)
97 break;
98 putreg(child, addr, data); /* Write register */
99 ret = 0;
100 break;
101
102 case PTRACE_GETREGS: /* Get all registers from the child. */
103 if (!access_ok(VERIFY_WRITE, datap, PTREGS_SIZE))
104 break;
105 for (i = 0; i < PTREGS_SIZE; i += sizeof(long)) {
106 ret = __put_user(getreg(child, i), datap);
107 if (ret != 0)
108 break;
109 datap++;
110 }
111 break;
112
113 case PTRACE_SETREGS: /* Set all registers in the child. */
114 if (!access_ok(VERIFY_READ, datap, PTREGS_SIZE))
115 break;
116 for (i = 0; i < PTREGS_SIZE; i += sizeof(long)) {
117 ret = __get_user(tmp, datap);
118 if (ret != 0)
119 break;
120 putreg(child, i, tmp);
121 datap++;
122 }
123 break;
124
125 case PTRACE_GETFPREGS: /* Get the child FPU state. */
126 case PTRACE_SETFPREGS: /* Set the child FPU state. */
127 break;
128
129 case PTRACE_SETOPTIONS:
130 /* Support TILE-specific ptrace options. */
131 child->ptrace &= ~PT_TRACE_MASK_TILE;
132 tmp = data & PTRACE_O_MASK_TILE;
133 data &= ~PTRACE_O_MASK_TILE;
134 ret = ptrace_request(child, request, addr, data);
135 if (tmp & PTRACE_O_TRACEMIGRATE)
136 child->ptrace |= PT_TRACE_MIGRATE;
137 break;
138
139 default:
140#ifdef CONFIG_COMPAT
141 if (task_thread_info(current)->status & TS_COMPAT) {
142 ret = compat_ptrace_request(child, request,
143 addr, data);
144 break;
145 }
146#endif
147 ret = ptrace_request(child, request, addr, data);
148 break;
149 }
150
151 return ret;
152}
153
154#ifdef CONFIG_COMPAT
155/* Not used; we handle compat issues in arch_ptrace() directly. */
156long compat_arch_ptrace(struct task_struct *child, compat_long_t request,
157 compat_ulong_t addr, compat_ulong_t data)
158{
159 BUG();
160}
161#endif
162
163void do_syscall_trace(void)
164{
165 if (!test_thread_flag(TIF_SYSCALL_TRACE))
166 return;
167
168 if (!(current->ptrace & PT_PTRACED))
169 return;
170
171 /*
172 * The 0x80 provides a way for the tracing parent to distinguish
173 * between a syscall stop and SIGTRAP delivery
174 */
175 ptrace_notify(SIGTRAP|((current->ptrace & PT_TRACESYSGOOD) ? 0x80 : 0));
176
177 /*
178 * this isn't the same as continuing with a signal, but it will do
179 * for normal use. strace only continues with a signal if the
180 * stopping signal is not SIGTRAP. -brl
181 */
182 if (current->exit_code) {
183 send_sig(current->exit_code, current, 1);
184 current->exit_code = 0;
185 }
186}
187
188void send_sigtrap(struct task_struct *tsk, struct pt_regs *regs, int error_code)
189{
190 struct siginfo info;
191
192 memset(&info, 0, sizeof(info));
193 info.si_signo = SIGTRAP;
194 info.si_code = TRAP_BRKPT;
195 info.si_addr = (void __user *) regs->pc;
196
197 /* Send us the fakey SIGTRAP */
198 force_sig_info(SIGTRAP, &info, tsk);
199}
200
201/* Handle synthetic interrupt delivered only by the simulator. */
202void __kprobes do_breakpoint(struct pt_regs* regs, int fault_num)
203{
204 send_sigtrap(current, regs, fault_num);
205}
diff --git a/arch/tile/kernel/reboot.c b/arch/tile/kernel/reboot.c
new file mode 100644
index 000000000000..acd86d20beba
--- /dev/null
+++ b/arch/tile/kernel/reboot.c
@@ -0,0 +1,51 @@
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#include <linux/stddef.h>
16#include <linux/reboot.h>
17#include <linux/smp.h>
18#include <linux/pm.h>
19#include <asm/page.h>
20#include <asm/setup.h>
21#include <hv/hypervisor.h>
22
23#ifndef CONFIG_SMP
24#define smp_send_stop()
25#endif
26
27void machine_halt(void)
28{
29 warn_early_printk();
30 raw_local_irq_disable_all();
31 smp_send_stop();
32 hv_halt();
33}
34
35void machine_power_off(void)
36{
37 warn_early_printk();
38 raw_local_irq_disable_all();
39 smp_send_stop();
40 hv_power_off();
41}
42
43void machine_restart(char *cmd)
44{
45 raw_local_irq_disable_all();
46 smp_send_stop();
47 hv_restart((HV_VirtAddr) "vmlinux", (HV_VirtAddr) cmd);
48}
49
50/* No interesting distinction to be made here. */
51void (*pm_power_off)(void) = NULL;
diff --git a/arch/tile/kernel/regs_32.S b/arch/tile/kernel/regs_32.S
new file mode 100644
index 000000000000..e88d6e122783
--- /dev/null
+++ b/arch/tile/kernel/regs_32.S
@@ -0,0 +1,145 @@
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#include <linux/linkage.h>
16#include <asm/system.h>
17#include <asm/ptrace.h>
18#include <asm/asm-offsets.h>
19#include <arch/spr_def.h>
20#include <asm/processor.h>
21
22/*
23 * See <asm/system.h>; called with prev and next task_struct pointers.
24 * "prev" is returned in r0 for _switch_to and also for ret_from_fork.
25 *
26 * We want to save pc/sp in "prev", and get the new pc/sp from "next".
27 * We also need to save all the callee-saved registers on the stack.
28 *
29 * Intel enables/disables access to the hardware cycle counter in
30 * seccomp (secure computing) environments if necessary, based on
31 * has_secure_computing(). We might want to do this at some point,
32 * though it would require virtualizing the other SPRs under WORLD_ACCESS.
33 *
34 * Since we're saving to the stack, we omit sp from this list.
35 * And for parallels with other architectures, we save lr separately,
36 * in the thread_struct itself (as the "pc" field).
37 *
38 * This code also needs to be aligned with process.c copy_thread()
39 */
40
41#if CALLEE_SAVED_REGS_COUNT != 24
42# error Mismatch between <asm/system.h> and kernel/entry.S
43#endif
44#define FRAME_SIZE ((2 + CALLEE_SAVED_REGS_COUNT) * 4)
45
46#define SAVE_REG(r) { sw r12, r; addi r12, r12, 4 }
47#define LOAD_REG(r) { lw r, r12; addi r12, r12, 4 }
48#define FOR_EACH_CALLEE_SAVED_REG(f) \
49 f(r30); f(r31); \
50 f(r32); f(r33); f(r34); f(r35); f(r36); f(r37); f(r38); f(r39); \
51 f(r40); f(r41); f(r42); f(r43); f(r44); f(r45); f(r46); f(r47); \
52 f(r48); f(r49); f(r50); f(r51); f(r52);
53
54STD_ENTRY_SECTION(__switch_to, .sched.text)
55 {
56 move r10, sp
57 sw sp, lr
58 addi sp, sp, -FRAME_SIZE
59 }
60 {
61 addi r11, sp, 4
62 addi r12, sp, 8
63 }
64 {
65 sw r11, r10
66 addli r4, r1, TASK_STRUCT_THREAD_KSP_OFFSET
67 }
68 {
69 lw r13, r4 /* Load new sp to a temp register early. */
70 addli r3, r0, TASK_STRUCT_THREAD_KSP_OFFSET
71 }
72 FOR_EACH_CALLEE_SAVED_REG(SAVE_REG)
73 {
74 sw r3, sp
75 addli r3, r0, TASK_STRUCT_THREAD_PC_OFFSET
76 }
77 {
78 sw r3, lr
79 addli r4, r1, TASK_STRUCT_THREAD_PC_OFFSET
80 }
81 {
82 lw lr, r4
83 addi r12, r13, 8
84 }
85 {
86 /* Update sp and ksp0 simultaneously to avoid backtracer warnings. */
87 move sp, r13
88 mtspr SYSTEM_SAVE_1_0, r2
89 }
90 FOR_EACH_CALLEE_SAVED_REG(LOAD_REG)
91.L__switch_to_pc:
92 {
93 addi sp, sp, FRAME_SIZE
94 jrp lr /* r0 is still valid here, so return it */
95 }
96 STD_ENDPROC(__switch_to)
97
98/* Return a suitable address for the backtracer for suspended threads */
99STD_ENTRY_SECTION(get_switch_to_pc, .sched.text)
100 lnk r0
101 {
102 addli r0, r0, .L__switch_to_pc - .
103 jrp lr
104 }
105 STD_ENDPROC(get_switch_to_pc)
106
107STD_ENTRY(get_pt_regs)
108 .irp reg, r0, r1, r2, r3, r4, r5, r6, r7, \
109 r8, r9, r10, r11, r12, r13, r14, r15, \
110 r16, r17, r18, r19, r20, r21, r22, r23, \
111 r24, r25, r26, r27, r28, r29, r30, r31, \
112 r32, r33, r34, r35, r36, r37, r38, r39, \
113 r40, r41, r42, r43, r44, r45, r46, r47, \
114 r48, r49, r50, r51, r52, tp, sp
115 {
116 sw r0, \reg
117 addi r0, r0, 4
118 }
119 .endr
120 {
121 sw r0, lr
122 addi r0, r0, PTREGS_OFFSET_PC - PTREGS_OFFSET_LR
123 }
124 lnk r1
125 {
126 sw r0, r1
127 addi r0, r0, PTREGS_OFFSET_EX1 - PTREGS_OFFSET_PC
128 }
129 mfspr r1, INTERRUPT_CRITICAL_SECTION
130 shli r1, r1, SPR_EX_CONTEXT_1_1__ICS_SHIFT
131 ori r1, r1, KERNEL_PL
132 {
133 sw r0, r1
134 addi r0, r0, PTREGS_OFFSET_FAULTNUM - PTREGS_OFFSET_EX1
135 }
136 {
137 sw r0, zero /* clear faultnum */
138 addi r0, r0, PTREGS_OFFSET_ORIG_R0 - PTREGS_OFFSET_FAULTNUM
139 }
140 {
141 sw r0, zero /* clear orig_r0 */
142 addli r0, r0, -PTREGS_OFFSET_ORIG_R0 /* restore r0 to base */
143 }
144 jrp lr
145 STD_ENDPROC(get_pt_regs)
diff --git a/arch/tile/kernel/relocate_kernel.S b/arch/tile/kernel/relocate_kernel.S
new file mode 100644
index 000000000000..010b418515f8
--- /dev/null
+++ b/arch/tile/kernel/relocate_kernel.S
@@ -0,0 +1,280 @@
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 * copy new kernel into place and then call hv_reexec
15 *
16 */
17
18#include <linux/linkage.h>
19#include <arch/chip.h>
20#include <asm/page.h>
21#include <hv/hypervisor.h>
22
23#define ___hvb MEM_SV_INTRPT + HV_GLUE_START_CPA
24
25#define ___hv_dispatch(f) (___hvb + (HV_DISPATCH_ENTRY_SIZE * f))
26
27#define ___hv_console_putc ___hv_dispatch(HV_DISPATCH_CONSOLE_PUTC)
28#define ___hv_halt ___hv_dispatch(HV_DISPATCH_HALT)
29#define ___hv_reexec ___hv_dispatch(HV_DISPATCH_REEXEC)
30#define ___hv_flush_remote ___hv_dispatch(HV_DISPATCH_FLUSH_REMOTE)
31
32#undef RELOCATE_NEW_KERNEL_VERBOSE
33
34STD_ENTRY(relocate_new_kernel)
35
36 move r30, r0 /* page list */
37 move r31, r1 /* address of page we are on */
38 move r32, r2 /* start address of new kernel */
39
40 shri r1, r1, PAGE_SHIFT
41 addi r1, r1, 1
42 shli sp, r1, PAGE_SHIFT
43 addi sp, sp, -8
44 /* we now have a stack (whether we need one or not) */
45
46 moveli r40, lo16(___hv_console_putc)
47 auli r40, r40, ha16(___hv_console_putc)
48
49#ifdef RELOCATE_NEW_KERNEL_VERBOSE
50 moveli r0, 'r'
51 jalr r40
52
53 moveli r0, '_'
54 jalr r40
55
56 moveli r0, 'n'
57 jalr r40
58
59 moveli r0, '_'
60 jalr r40
61
62 moveli r0, 'k'
63 jalr r40
64
65 moveli r0, '\n'
66 jalr r40
67#endif
68
69 /*
70 * Throughout this code r30 is pointer to the element of page
71 * list we are working on.
72 *
73 * Normally we get to the next element of the page list by
74 * incrementing r30 by four. The exception is if the element
75 * on the page list is an IND_INDIRECTION in which case we use
76 * the element with the low bits masked off as the new value
77 * of r30.
78 *
79 * To get this started, we need the value passed to us (which
80 * will always be an IND_INDIRECTION) in memory somewhere with
81 * r30 pointing at it. To do that, we push the value passed
82 * to us on the stack and make r30 point to it.
83 */
84
85 sw sp, r30
86 move r30, sp
87 addi sp, sp, -8
88
89#if CHIP_HAS_CBOX_HOME_MAP()
90 /*
91 * On TILEPro, we need to flush all tiles' caches, since we may
92 * have been doing hash-for-home caching there. Note that we
93 * must do this _after_ we're completely done modifying any memory
94 * other than our output buffer (which we know is locally cached).
95 * We want the caches to be fully clean when we do the reexec,
96 * because the hypervisor is going to do this flush again at that
97 * point, and we don't want that second flush to overwrite any memory.
98 */
99 {
100 move r0, zero /* cache_pa */
101 move r1, zero
102 }
103 {
104 auli r2, zero, ha16(HV_FLUSH_EVICT_L2) /* cache_control */
105 movei r3, -1 /* cache_cpumask; -1 means all client tiles */
106 }
107 {
108 move r4, zero /* tlb_va */
109 move r5, zero /* tlb_length */
110 }
111 {
112 move r6, zero /* tlb_pgsize */
113 move r7, zero /* tlb_cpumask */
114 }
115 {
116 move r8, zero /* asids */
117 moveli r20, lo16(___hv_flush_remote)
118 }
119 {
120 move r9, zero /* asidcount */
121 auli r20, r20, ha16(___hv_flush_remote)
122 }
123
124 jalr r20
125#endif
126
127 /* r33 is destination pointer, default to zero */
128
129 moveli r33, 0
130
131.Lloop: lw r10, r30
132
133 andi r9, r10, 0xf /* low 4 bits tell us what type it is */
134 xor r10, r10, r9 /* r10 is now value with low 4 bits stripped */
135
136 seqi r0, r9, 0x1 /* IND_DESTINATION */
137 bzt r0, .Ltry2
138
139 move r33, r10
140
141#ifdef RELOCATE_NEW_KERNEL_VERBOSE
142 moveli r0, 'd'
143 jalr r40
144#endif
145
146 addi r30, r30, 4
147 j .Lloop
148
149.Ltry2:
150 seqi r0, r9, 0x2 /* IND_INDIRECTION */
151 bzt r0, .Ltry4
152
153 move r30, r10
154
155#ifdef RELOCATE_NEW_KERNEL_VERBOSE
156 moveli r0, 'i'
157 jalr r40
158#endif
159
160 j .Lloop
161
162.Ltry4:
163 seqi r0, r9, 0x4 /* IND_DONE */
164 bzt r0, .Ltry8
165
166 mf
167
168#ifdef RELOCATE_NEW_KERNEL_VERBOSE
169 moveli r0, 'D'
170 jalr r40
171 moveli r0, '\n'
172 jalr r40
173#endif
174
175 move r0, r32
176 moveli r1, 0 /* arg to hv_reexec is 64 bits */
177
178 moveli r41, lo16(___hv_reexec)
179 auli r41, r41, ha16(___hv_reexec)
180
181 jalr r41
182
183 /* we should not get here */
184
185 moveli r0, '?'
186 jalr r40
187 moveli r0, '\n'
188 jalr r40
189
190 j .Lhalt
191
192.Ltry8: seqi r0, r9, 0x8 /* IND_SOURCE */
193 bz r0, .Lerr /* unknown type */
194
195 /* copy page at r10 to page at r33 */
196
197 move r11, r33
198
199 moveli r0, lo16(PAGE_SIZE)
200 auli r0, r0, ha16(PAGE_SIZE)
201 add r33, r33, r0
202
203 /* copy word at r10 to word at r11 until r11 equals r33 */
204
205 /* We know page size must be multiple of 16, so we can unroll
206 * 16 times safely without any edge case checking.
207 *
208 * Issue a flush of the destination every 16 words to avoid
209 * incoherence when starting the new kernel. (Now this is
210 * just good paranoia because the hv_reexec call will also
211 * take care of this.)
212 */
213
2141:
215 { lw r0, r10; addi r10, r10, 4 }
216 { sw r11, r0; addi r11, r11, 4 }
217 { lw r0, r10; addi r10, r10, 4 }
218 { sw r11, r0; addi r11, r11, 4 }
219 { lw r0, r10; addi r10, r10, 4 }
220 { sw r11, r0; addi r11, r11, 4 }
221 { lw r0, r10; addi r10, r10, 4 }
222 { sw r11, r0; addi r11, r11, 4 }
223 { lw r0, r10; addi r10, r10, 4 }
224 { sw r11, r0; addi r11, r11, 4 }
225 { lw r0, r10; addi r10, r10, 4 }
226 { sw r11, r0; addi r11, r11, 4 }
227 { lw r0, r10; addi r10, r10, 4 }
228 { sw r11, r0; addi r11, r11, 4 }
229 { lw r0, r10; addi r10, r10, 4 }
230 { sw r11, r0; addi r11, r11, 4 }
231 { lw r0, r10; addi r10, r10, 4 }
232 { sw r11, r0; addi r11, r11, 4 }
233 { lw r0, r10; addi r10, r10, 4 }
234 { sw r11, r0; addi r11, r11, 4 }
235 { lw r0, r10; addi r10, r10, 4 }
236 { sw r11, r0; addi r11, r11, 4 }
237 { lw r0, r10; addi r10, r10, 4 }
238 { sw r11, r0; addi r11, r11, 4 }
239 { lw r0, r10; addi r10, r10, 4 }
240 { sw r11, r0; addi r11, r11, 4 }
241 { lw r0, r10; addi r10, r10, 4 }
242 { sw r11, r0; addi r11, r11, 4 }
243 { lw r0, r10; addi r10, r10, 4 }
244 { sw r11, r0; addi r11, r11, 4 }
245 { lw r0, r10; addi r10, r10, 4 }
246 { sw r11, r0 }
247 { flush r11 ; addi r11, r11, 4 }
248
249 seq r0, r33, r11
250 bzt r0, 1b
251
252#ifdef RELOCATE_NEW_KERNEL_VERBOSE
253 moveli r0, 's'
254 jalr r40
255#endif
256
257 addi r30, r30, 4
258 j .Lloop
259
260
261.Lerr: moveli r0, 'e'
262 jalr r40
263 moveli r0, 'r'
264 jalr r40
265 moveli r0, 'r'
266 jalr r40
267 moveli r0, '\n'
268 jalr r40
269.Lhalt:
270 moveli r41, lo16(___hv_halt)
271 auli r41, r41, ha16(___hv_halt)
272
273 jalr r41
274 STD_ENDPROC(relocate_new_kernel)
275
276 .section .rodata,"a"
277
278 .globl relocate_new_kernel_size
279relocate_new_kernel_size:
280 .long .Lend_relocate_new_kernel - relocate_new_kernel
diff --git a/arch/tile/kernel/setup.c b/arch/tile/kernel/setup.c
new file mode 100644
index 000000000000..e7d54c73d5c1
--- /dev/null
+++ b/arch/tile/kernel/setup.c
@@ -0,0 +1,1511 @@
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#include <linux/sched.h>
16#include <linux/kernel.h>
17#include <linux/mmzone.h>
18#include <linux/bootmem.h>
19#include <linux/module.h>
20#include <linux/node.h>
21#include <linux/cpu.h>
22#include <linux/ioport.h>
23#include <linux/irq.h>
24#include <linux/kexec.h>
25#include <linux/pci.h>
26#include <linux/initrd.h>
27#include <linux/io.h>
28#include <linux/highmem.h>
29#include <linux/smp.h>
30#include <linux/timex.h>
31#include <asm/setup.h>
32#include <asm/sections.h>
33#include <asm/sections.h>
34#include <asm/cacheflush.h>
35#include <asm/cacheflush.h>
36#include <asm/pgalloc.h>
37#include <asm/mmu_context.h>
38#include <hv/hypervisor.h>
39#include <arch/interrupts.h>
40
41/* <linux/smp.h> doesn't provide this definition. */
42#ifndef CONFIG_SMP
43#define setup_max_cpus 1
44#endif
45
46static inline int ABS(int x) { return x >= 0 ? x : -x; }
47
48/* Chip information */
49char chip_model[64] __write_once;
50
51struct pglist_data node_data[MAX_NUMNODES] __read_mostly;
52EXPORT_SYMBOL(node_data);
53
54/* We only create bootmem data on node 0. */
55static bootmem_data_t __initdata node0_bdata;
56
57/* Information on the NUMA nodes that we compute early */
58unsigned long __cpuinitdata node_start_pfn[MAX_NUMNODES];
59unsigned long __cpuinitdata node_end_pfn[MAX_NUMNODES];
60unsigned long __initdata node_memmap_pfn[MAX_NUMNODES];
61unsigned long __initdata node_percpu_pfn[MAX_NUMNODES];
62unsigned long __initdata node_free_pfn[MAX_NUMNODES];
63
64#ifdef CONFIG_HIGHMEM
65/* Page frame index of end of lowmem on each controller. */
66unsigned long __cpuinitdata node_lowmem_end_pfn[MAX_NUMNODES];
67
68/* Number of pages that can be mapped into lowmem. */
69static unsigned long __initdata mappable_physpages;
70#endif
71
72/* Data on which physical memory controller corresponds to which NUMA node */
73int node_controller[MAX_NUMNODES] = { [0 ... MAX_NUMNODES-1] = -1 };
74
75#ifdef CONFIG_HIGHMEM
76/* Map information from VAs to PAs */
77unsigned long pbase_map[1 << (32 - HPAGE_SHIFT)]
78 __write_once __attribute__((aligned(L2_CACHE_BYTES)));
79EXPORT_SYMBOL(pbase_map);
80
81/* Map information from PAs to VAs */
82void *vbase_map[NR_PA_HIGHBIT_VALUES]
83 __write_once __attribute__((aligned(L2_CACHE_BYTES)));
84EXPORT_SYMBOL(vbase_map);
85#endif
86
87/* Node number as a function of the high PA bits */
88int highbits_to_node[NR_PA_HIGHBIT_VALUES] __write_once;
89EXPORT_SYMBOL(highbits_to_node);
90
91static unsigned int __initdata maxmem_pfn = -1U;
92static unsigned int __initdata maxnodemem_pfn[MAX_NUMNODES] = {
93 [0 ... MAX_NUMNODES-1] = -1U
94};
95static nodemask_t __initdata isolnodes;
96
97#ifdef CONFIG_PCI
98enum { DEFAULT_PCI_RESERVE_MB = 64 };
99static unsigned int __initdata pci_reserve_mb = DEFAULT_PCI_RESERVE_MB;
100unsigned long __initdata pci_reserve_start_pfn = -1U;
101unsigned long __initdata pci_reserve_end_pfn = -1U;
102#endif
103
104static int __init setup_maxmem(char *str)
105{
106 long maxmem_mb;
107 if (str == NULL || strict_strtol(str, 0, &maxmem_mb) != 0 ||
108 maxmem_mb == 0)
109 return -EINVAL;
110
111 maxmem_pfn = (maxmem_mb >> (HPAGE_SHIFT - 20)) <<
112 (HPAGE_SHIFT - PAGE_SHIFT);
113 pr_info("Forcing RAM used to no more than %dMB\n",
114 maxmem_pfn >> (20 - PAGE_SHIFT));
115 return 0;
116}
117early_param("maxmem", setup_maxmem);
118
119static int __init setup_maxnodemem(char *str)
120{
121 char *endp;
122 long maxnodemem_mb, node;
123
124 node = str ? simple_strtoul(str, &endp, 0) : INT_MAX;
125 if (node >= MAX_NUMNODES || *endp != ':' ||
126 strict_strtol(endp+1, 0, &maxnodemem_mb) != 0)
127 return -EINVAL;
128
129 maxnodemem_pfn[node] = (maxnodemem_mb >> (HPAGE_SHIFT - 20)) <<
130 (HPAGE_SHIFT - PAGE_SHIFT);
131 pr_info("Forcing RAM used on node %ld to no more than %dMB\n",
132 node, maxnodemem_pfn[node] >> (20 - PAGE_SHIFT));
133 return 0;
134}
135early_param("maxnodemem", setup_maxnodemem);
136
137static int __init setup_isolnodes(char *str)
138{
139 char buf[MAX_NUMNODES * 5];
140 if (str == NULL || nodelist_parse(str, isolnodes) != 0)
141 return -EINVAL;
142
143 nodelist_scnprintf(buf, sizeof(buf), isolnodes);
144 pr_info("Set isolnodes value to '%s'\n", buf);
145 return 0;
146}
147early_param("isolnodes", setup_isolnodes);
148
149#ifdef CONFIG_PCI
150static int __init setup_pci_reserve(char* str)
151{
152 unsigned long mb;
153
154 if (str == NULL || strict_strtoul(str, 0, &mb) != 0 ||
155 mb > 3 * 1024)
156 return -EINVAL;
157
158 pci_reserve_mb = mb;
159 pr_info("Reserving %dMB for PCIE root complex mappings\n",
160 pci_reserve_mb);
161 return 0;
162}
163early_param("pci_reserve", setup_pci_reserve);
164#endif
165
166#ifndef __tilegx__
167/*
168 * vmalloc=size forces the vmalloc area to be exactly 'size' bytes.
169 * This can be used to increase (or decrease) the vmalloc area.
170 */
171static int __init parse_vmalloc(char *arg)
172{
173 if (!arg)
174 return -EINVAL;
175
176 VMALLOC_RESERVE = (memparse(arg, &arg) + PGDIR_SIZE - 1) & PGDIR_MASK;
177
178 /* See validate_va() for more on this test. */
179 if ((long)_VMALLOC_START >= 0)
180 early_panic("\"vmalloc=%#lx\" value too large: maximum %#lx\n",
181 VMALLOC_RESERVE, _VMALLOC_END - 0x80000000UL);
182
183 return 0;
184}
185early_param("vmalloc", parse_vmalloc);
186#endif
187
188#ifdef CONFIG_HIGHMEM
189/*
190 * Determine for each controller where its lowmem is mapped and how
191 * much of it is mapped there. On controller zero, the first few
192 * megabytes are mapped at 0xfd000000 as code, so in principle we
193 * could start our data mappings higher up, but for now we don't
194 * bother, to avoid additional confusion.
195 *
196 * One question is whether, on systems with more than 768 Mb and
197 * controllers of different sizes, to map in a proportionate amount of
198 * each one, or to try to map the same amount from each controller.
199 * (E.g. if we have three controllers with 256MB, 1GB, and 256MB
200 * respectively, do we map 256MB from each, or do we map 128 MB, 512
201 * MB, and 128 MB respectively?) For now we use a proportionate
202 * solution like the latter.
203 *
204 * The VA/PA mapping demands that we align our decisions at 16 MB
205 * boundaries so that we can rapidly convert VA to PA.
206 */
207static void *__init setup_pa_va_mapping(void)
208{
209 unsigned long curr_pages = 0;
210 unsigned long vaddr = PAGE_OFFSET;
211 nodemask_t highonlynodes = isolnodes;
212 int i, j;
213
214 memset(pbase_map, -1, sizeof(pbase_map));
215 memset(vbase_map, -1, sizeof(vbase_map));
216
217 /* Node zero cannot be isolated for LOWMEM purposes. */
218 node_clear(0, highonlynodes);
219
220 /* Count up the number of pages on non-highonlynodes controllers. */
221 mappable_physpages = 0;
222 for_each_online_node(i) {
223 if (!node_isset(i, highonlynodes))
224 mappable_physpages +=
225 node_end_pfn[i] - node_start_pfn[i];
226 }
227
228 for_each_online_node(i) {
229 unsigned long start = node_start_pfn[i];
230 unsigned long end = node_end_pfn[i];
231 unsigned long size = end - start;
232 unsigned long vaddr_end;
233
234 if (node_isset(i, highonlynodes)) {
235 /* Mark this controller as having no lowmem. */
236 node_lowmem_end_pfn[i] = start;
237 continue;
238 }
239
240 curr_pages += size;
241 if (mappable_physpages > MAXMEM_PFN) {
242 vaddr_end = PAGE_OFFSET +
243 (((u64)curr_pages * MAXMEM_PFN /
244 mappable_physpages)
245 << PAGE_SHIFT);
246 } else {
247 vaddr_end = PAGE_OFFSET + (curr_pages << PAGE_SHIFT);
248 }
249 for (j = 0; vaddr < vaddr_end; vaddr += HPAGE_SIZE, ++j) {
250 unsigned long this_pfn =
251 start + (j << HUGETLB_PAGE_ORDER);
252 pbase_map[vaddr >> HPAGE_SHIFT] = this_pfn;
253 if (vbase_map[__pfn_to_highbits(this_pfn)] ==
254 (void *)-1)
255 vbase_map[__pfn_to_highbits(this_pfn)] =
256 (void *)(vaddr & HPAGE_MASK);
257 }
258 node_lowmem_end_pfn[i] = start + (j << HUGETLB_PAGE_ORDER);
259 BUG_ON(node_lowmem_end_pfn[i] > end);
260 }
261
262 /* Return highest address of any mapped memory. */
263 return (void *)vaddr;
264}
265#endif /* CONFIG_HIGHMEM */
266
267/*
268 * Register our most important memory mappings with the debug stub.
269 *
270 * This is up to 4 mappings for lowmem, one mapping per memory
271 * controller, plus one for our text segment.
272 */
273static void __cpuinit store_permanent_mappings(void)
274{
275 int i;
276
277 for_each_online_node(i) {
278 HV_PhysAddr pa = ((HV_PhysAddr)node_start_pfn[i]) << PAGE_SHIFT;
279#ifdef CONFIG_HIGHMEM
280 HV_PhysAddr high_mapped_pa = node_lowmem_end_pfn[i];
281#else
282 HV_PhysAddr high_mapped_pa = node_end_pfn[i];
283#endif
284
285 unsigned long pages = high_mapped_pa - node_start_pfn[i];
286 HV_VirtAddr addr = (HV_VirtAddr) __va(pa);
287 hv_store_mapping(addr, pages << PAGE_SHIFT, pa);
288 }
289
290 hv_store_mapping((HV_VirtAddr)_stext,
291 (uint32_t)(_einittext - _stext), 0);
292}
293
294/*
295 * Use hv_inquire_physical() to populate node_{start,end}_pfn[]
296 * and node_online_map, doing suitable sanity-checking.
297 * Also set min_low_pfn, max_low_pfn, and max_pfn.
298 */
299static void __init setup_memory(void)
300{
301 int i, j;
302 int highbits_seen[NR_PA_HIGHBIT_VALUES] = { 0 };
303#ifdef CONFIG_HIGHMEM
304 long highmem_pages;
305#endif
306#ifndef __tilegx__
307 int cap;
308#endif
309#if defined(CONFIG_HIGHMEM) || defined(__tilegx__)
310 long lowmem_pages;
311#endif
312
313 /* We are using a char to hold the cpu_2_node[] mapping */
314 BUG_ON(MAX_NUMNODES > 127);
315
316 /* Discover the ranges of memory available to us */
317 for (i = 0; ; ++i) {
318 unsigned long start, size, end, highbits;
319 HV_PhysAddrRange range = hv_inquire_physical(i);
320 if (range.size == 0)
321 break;
322#ifdef CONFIG_FLATMEM
323 if (i > 0) {
324 pr_err("Can't use discontiguous PAs: %#llx..%#llx\n",
325 range.size, range.start + range.size);
326 continue;
327 }
328#endif
329#ifndef __tilegx__
330 if ((unsigned long)range.start) {
331 pr_err("Range not at 4GB multiple: %#llx..%#llx\n",
332 range.start, range.start + range.size);
333 continue;
334 }
335#endif
336 if ((range.start & (HPAGE_SIZE-1)) != 0 ||
337 (range.size & (HPAGE_SIZE-1)) != 0) {
338 unsigned long long start_pa = range.start;
339 unsigned long long orig_size = range.size;
340 range.start = (start_pa + HPAGE_SIZE - 1) & HPAGE_MASK;
341 range.size -= (range.start - start_pa);
342 range.size &= HPAGE_MASK;
343 pr_err("Range not hugepage-aligned: %#llx..%#llx:"
344 " now %#llx-%#llx\n",
345 start_pa, start_pa + orig_size,
346 range.start, range.start + range.size);
347 }
348 highbits = __pa_to_highbits(range.start);
349 if (highbits >= NR_PA_HIGHBIT_VALUES) {
350 pr_err("PA high bits too high: %#llx..%#llx\n",
351 range.start, range.start + range.size);
352 continue;
353 }
354 if (highbits_seen[highbits]) {
355 pr_err("Range overlaps in high bits: %#llx..%#llx\n",
356 range.start, range.start + range.size);
357 continue;
358 }
359 highbits_seen[highbits] = 1;
360 if (PFN_DOWN(range.size) > maxnodemem_pfn[i]) {
361 int max_size = maxnodemem_pfn[i];
362 if (max_size > 0) {
363 pr_err("Maxnodemem reduced node %d to"
364 " %d pages\n", i, max_size);
365 range.size = PFN_PHYS(max_size);
366 } else {
367 pr_err("Maxnodemem disabled node %d\n", i);
368 continue;
369 }
370 }
371 if (num_physpages + PFN_DOWN(range.size) > maxmem_pfn) {
372 int max_size = maxmem_pfn - num_physpages;
373 if (max_size > 0) {
374 pr_err("Maxmem reduced node %d to %d pages\n",
375 i, max_size);
376 range.size = PFN_PHYS(max_size);
377 } else {
378 pr_err("Maxmem disabled node %d\n", i);
379 continue;
380 }
381 }
382 if (i >= MAX_NUMNODES) {
383 pr_err("Too many PA nodes (#%d): %#llx...%#llx\n",
384 i, range.size, range.size + range.start);
385 continue;
386 }
387
388 start = range.start >> PAGE_SHIFT;
389 size = range.size >> PAGE_SHIFT;
390 end = start + size;
391
392#ifndef __tilegx__
393 if (((HV_PhysAddr)end << PAGE_SHIFT) !=
394 (range.start + range.size)) {
395 pr_err("PAs too high to represent: %#llx..%#llx\n",
396 range.start, range.start + range.size);
397 continue;
398 }
399#endif
400#ifdef CONFIG_PCI
401 /*
402 * Blocks that overlap the pci reserved region must
403 * have enough space to hold the maximum percpu data
404 * region at the top of the range. If there isn't
405 * enough space above the reserved region, just
406 * truncate the node.
407 */
408 if (start <= pci_reserve_start_pfn &&
409 end > pci_reserve_start_pfn) {
410 unsigned int per_cpu_size =
411 __per_cpu_end - __per_cpu_start;
412 unsigned int percpu_pages =
413 NR_CPUS * (PFN_UP(per_cpu_size) >> PAGE_SHIFT);
414 if (end < pci_reserve_end_pfn + percpu_pages) {
415 end = pci_reserve_start_pfn;
416 pr_err("PCI mapping region reduced node %d to"
417 " %ld pages\n", i, end - start);
418 }
419 }
420#endif
421
422 for (j = __pfn_to_highbits(start);
423 j <= __pfn_to_highbits(end - 1); j++)
424 highbits_to_node[j] = i;
425
426 node_start_pfn[i] = start;
427 node_end_pfn[i] = end;
428 node_controller[i] = range.controller;
429 num_physpages += size;
430 max_pfn = end;
431
432 /* Mark node as online */
433 node_set(i, node_online_map);
434 node_set(i, node_possible_map);
435 }
436
437#ifndef __tilegx__
438 /*
439 * For 4KB pages, mem_map "struct page" data is 1% of the size
440 * of the physical memory, so can be quite big (640 MB for
441 * four 16G zones). These structures must be mapped in
442 * lowmem, and since we currently cap out at about 768 MB,
443 * it's impractical to try to use this much address space.
444 * For now, arbitrarily cap the amount of physical memory
445 * we're willing to use at 8 million pages (32GB of 4KB pages).
446 */
447 cap = 8 * 1024 * 1024; /* 8 million pages */
448 if (num_physpages > cap) {
449 int num_nodes = num_online_nodes();
450 int cap_each = cap / num_nodes;
451 unsigned long dropped_pages = 0;
452 for (i = 0; i < num_nodes; ++i) {
453 int size = node_end_pfn[i] - node_start_pfn[i];
454 if (size > cap_each) {
455 dropped_pages += (size - cap_each);
456 node_end_pfn[i] = node_start_pfn[i] + cap_each;
457 }
458 }
459 num_physpages -= dropped_pages;
460 pr_warning("Only using %ldMB memory;"
461 " ignoring %ldMB.\n",
462 num_physpages >> (20 - PAGE_SHIFT),
463 dropped_pages >> (20 - PAGE_SHIFT));
464 pr_warning("Consider using a larger page size.\n");
465 }
466#endif
467
468 /* Heap starts just above the last loaded address. */
469 min_low_pfn = PFN_UP((unsigned long)_end - PAGE_OFFSET);
470
471#ifdef CONFIG_HIGHMEM
472 /* Find where we map lowmem from each controller. */
473 high_memory = setup_pa_va_mapping();
474
475 /* Set max_low_pfn based on what node 0 can directly address. */
476 max_low_pfn = node_lowmem_end_pfn[0];
477
478 lowmem_pages = (mappable_physpages > MAXMEM_PFN) ?
479 MAXMEM_PFN : mappable_physpages;
480 highmem_pages = (long) (num_physpages - lowmem_pages);
481
482 pr_notice("%ldMB HIGHMEM available.\n",
483 pages_to_mb(highmem_pages > 0 ? highmem_pages : 0));
484 pr_notice("%ldMB LOWMEM available.\n",
485 pages_to_mb(lowmem_pages));
486#else
487 /* Set max_low_pfn based on what node 0 can directly address. */
488 max_low_pfn = node_end_pfn[0];
489
490#ifndef __tilegx__
491 if (node_end_pfn[0] > MAXMEM_PFN) {
492 pr_warning("Only using %ldMB LOWMEM.\n",
493 MAXMEM>>20);
494 pr_warning("Use a HIGHMEM enabled kernel.\n");
495 max_low_pfn = MAXMEM_PFN;
496 max_pfn = MAXMEM_PFN;
497 num_physpages = MAXMEM_PFN;
498 node_end_pfn[0] = MAXMEM_PFN;
499 } else {
500 pr_notice("%ldMB memory available.\n",
501 pages_to_mb(node_end_pfn[0]));
502 }
503 for (i = 1; i < MAX_NUMNODES; ++i) {
504 node_start_pfn[i] = 0;
505 node_end_pfn[i] = 0;
506 }
507 high_memory = __va(node_end_pfn[0]);
508#else
509 lowmem_pages = 0;
510 for (i = 0; i < MAX_NUMNODES; ++i) {
511 int pages = node_end_pfn[i] - node_start_pfn[i];
512 lowmem_pages += pages;
513 if (pages)
514 high_memory = pfn_to_kaddr(node_end_pfn[i]);
515 }
516 pr_notice("%ldMB memory available.\n",
517 pages_to_mb(lowmem_pages));
518#endif
519#endif
520}
521
522static void __init setup_bootmem_allocator(void)
523{
524 unsigned long bootmap_size, first_alloc_pfn, last_alloc_pfn;
525
526 /* Provide a node 0 bdata. */
527 NODE_DATA(0)->bdata = &node0_bdata;
528
529#ifdef CONFIG_PCI
530 /* Don't let boot memory alias the PCI region. */
531 last_alloc_pfn = min(max_low_pfn, pci_reserve_start_pfn);
532#else
533 last_alloc_pfn = max_low_pfn;
534#endif
535
536 /*
537 * Initialize the boot-time allocator (with low memory only):
538 * The first argument says where to put the bitmap, and the
539 * second says where the end of allocatable memory is.
540 */
541 bootmap_size = init_bootmem(min_low_pfn, last_alloc_pfn);
542
543 /*
544 * Let the bootmem allocator use all the space we've given it
545 * except for its own bitmap.
546 */
547 first_alloc_pfn = min_low_pfn + PFN_UP(bootmap_size);
548 if (first_alloc_pfn >= last_alloc_pfn)
549 early_panic("Not enough memory on controller 0 for bootmem\n");
550
551 free_bootmem(PFN_PHYS(first_alloc_pfn),
552 PFN_PHYS(last_alloc_pfn - first_alloc_pfn));
553
554#ifdef CONFIG_KEXEC
555 if (crashk_res.start != crashk_res.end)
556 reserve_bootmem(crashk_res.start,
557 crashk_res.end - crashk_res.start + 1, 0);
558#endif
559
560}
561
562void *__init alloc_remap(int nid, unsigned long size)
563{
564 int pages = node_end_pfn[nid] - node_start_pfn[nid];
565 void *map = pfn_to_kaddr(node_memmap_pfn[nid]);
566 BUG_ON(size != pages * sizeof(struct page));
567 memset(map, 0, size);
568 return map;
569}
570
571static int __init percpu_size(void)
572{
573 int size = ALIGN(__per_cpu_end - __per_cpu_start, PAGE_SIZE);
574#ifdef CONFIG_MODULES
575 if (size < PERCPU_ENOUGH_ROOM)
576 size = PERCPU_ENOUGH_ROOM;
577#endif
578 /* In several places we assume the per-cpu data fits on a huge page. */
579 BUG_ON(kdata_huge && size > HPAGE_SIZE);
580 return size;
581}
582
583static inline unsigned long alloc_bootmem_pfn(int size, unsigned long goal)
584{
585 void *kva = __alloc_bootmem(size, PAGE_SIZE, goal);
586 unsigned long pfn = kaddr_to_pfn(kva);
587 BUG_ON(goal && PFN_PHYS(pfn) != goal);
588 return pfn;
589}
590
591static void __init zone_sizes_init(void)
592{
593 unsigned long zones_size[MAX_NR_ZONES] = { 0 };
594 unsigned long node_percpu[MAX_NUMNODES] = { 0 };
595 int size = percpu_size();
596 int num_cpus = smp_height * smp_width;
597 int i;
598
599 for (i = 0; i < num_cpus; ++i)
600 node_percpu[cpu_to_node(i)] += size;
601
602 for_each_online_node(i) {
603 unsigned long start = node_start_pfn[i];
604 unsigned long end = node_end_pfn[i];
605#ifdef CONFIG_HIGHMEM
606 unsigned long lowmem_end = node_lowmem_end_pfn[i];
607#else
608 unsigned long lowmem_end = end;
609#endif
610 int memmap_size = (end - start) * sizeof(struct page);
611 node_free_pfn[i] = start;
612
613 /*
614 * Set aside pages for per-cpu data and the mem_map array.
615 *
616 * Since the per-cpu data requires special homecaching,
617 * if we are in kdata_huge mode, we put it at the end of
618 * the lowmem region. If we're not in kdata_huge mode,
619 * we take the per-cpu pages from the bottom of the
620 * controller, since that avoids fragmenting a huge page
621 * that users might want. We always take the memmap
622 * from the bottom of the controller, since with
623 * kdata_huge that lets it be under a huge TLB entry.
624 *
625 * If the user has requested isolnodes for a controller,
626 * though, there'll be no lowmem, so we just alloc_bootmem
627 * the memmap. There will be no percpu memory either.
628 */
629 if (__pfn_to_highbits(start) == 0) {
630 /* In low PAs, allocate via bootmem. */
631 unsigned long goal = 0;
632 node_memmap_pfn[i] =
633 alloc_bootmem_pfn(memmap_size, goal);
634 if (kdata_huge)
635 goal = PFN_PHYS(lowmem_end) - node_percpu[i];
636 if (node_percpu[i])
637 node_percpu_pfn[i] =
638 alloc_bootmem_pfn(node_percpu[i], goal);
639 } else if (cpu_isset(i, isolnodes)) {
640 node_memmap_pfn[i] = alloc_bootmem_pfn(memmap_size, 0);
641 BUG_ON(node_percpu[i] != 0);
642 } else {
643 /* In high PAs, just reserve some pages. */
644 node_memmap_pfn[i] = node_free_pfn[i];
645 node_free_pfn[i] += PFN_UP(memmap_size);
646 if (!kdata_huge) {
647 node_percpu_pfn[i] = node_free_pfn[i];
648 node_free_pfn[i] += PFN_UP(node_percpu[i]);
649 } else {
650 node_percpu_pfn[i] =
651 lowmem_end - PFN_UP(node_percpu[i]);
652 }
653 }
654
655#ifdef CONFIG_HIGHMEM
656 if (start > lowmem_end) {
657 zones_size[ZONE_NORMAL] = 0;
658 zones_size[ZONE_HIGHMEM] = end - start;
659 } else {
660 zones_size[ZONE_NORMAL] = lowmem_end - start;
661 zones_size[ZONE_HIGHMEM] = end - lowmem_end;
662 }
663#else
664 zones_size[ZONE_NORMAL] = end - start;
665#endif
666
667 /*
668 * Everyone shares node 0's bootmem allocator, but
669 * we use alloc_remap(), above, to put the actual
670 * struct page array on the individual controllers,
671 * which is most of the data that we actually care about.
672 * We can't place bootmem allocators on the other
673 * controllers since the bootmem allocator can only
674 * operate on 32-bit physical addresses.
675 */
676 NODE_DATA(i)->bdata = NODE_DATA(0)->bdata;
677
678 free_area_init_node(i, zones_size, start, NULL);
679 printk(KERN_DEBUG " DMA zone: %ld per-cpu pages\n",
680 PFN_UP(node_percpu[i]));
681
682 /* Track the type of memory on each node */
683 if (zones_size[ZONE_NORMAL])
684 node_set_state(i, N_NORMAL_MEMORY);
685#ifdef CONFIG_HIGHMEM
686 if (end != start)
687 node_set_state(i, N_HIGH_MEMORY);
688#endif
689
690 node_set_online(i);
691 }
692}
693
694#ifdef CONFIG_NUMA
695
696/* which logical CPUs are on which nodes */
697struct cpumask node_2_cpu_mask[MAX_NUMNODES] __write_once;
698EXPORT_SYMBOL(node_2_cpu_mask);
699
700/* which node each logical CPU is on */
701char cpu_2_node[NR_CPUS] __write_once __attribute__((aligned(L2_CACHE_BYTES)));
702EXPORT_SYMBOL(cpu_2_node);
703
704/* Return cpu_to_node() except for cpus not yet assigned, which return -1 */
705static int __init cpu_to_bound_node(int cpu, struct cpumask* unbound_cpus)
706{
707 if (!cpu_possible(cpu) || cpumask_test_cpu(cpu, unbound_cpus))
708 return -1;
709 else
710 return cpu_to_node(cpu);
711}
712
713/* Return number of immediately-adjacent tiles sharing the same NUMA node. */
714static int __init node_neighbors(int node, int cpu,
715 struct cpumask *unbound_cpus)
716{
717 int neighbors = 0;
718 int w = smp_width;
719 int h = smp_height;
720 int x = cpu % w;
721 int y = cpu / w;
722 if (x > 0 && cpu_to_bound_node(cpu-1, unbound_cpus) == node)
723 ++neighbors;
724 if (x < w-1 && cpu_to_bound_node(cpu+1, unbound_cpus) == node)
725 ++neighbors;
726 if (y > 0 && cpu_to_bound_node(cpu-w, unbound_cpus) == node)
727 ++neighbors;
728 if (y < h-1 && cpu_to_bound_node(cpu+w, unbound_cpus) == node)
729 ++neighbors;
730 return neighbors;
731}
732
733static void __init setup_numa_mapping(void)
734{
735 int distance[MAX_NUMNODES][NR_CPUS];
736 HV_Coord coord;
737 int cpu, node, cpus, i, x, y;
738 int num_nodes = num_online_nodes();
739 struct cpumask unbound_cpus;
740 nodemask_t default_nodes;
741
742 cpumask_clear(&unbound_cpus);
743
744 /* Get set of nodes we will use for defaults */
745 nodes_andnot(default_nodes, node_online_map, isolnodes);
746 if (nodes_empty(default_nodes)) {
747 BUG_ON(!node_isset(0, node_online_map));
748 pr_err("Forcing NUMA node zero available as a default node\n");
749 node_set(0, default_nodes);
750 }
751
752 /* Populate the distance[] array */
753 memset(distance, -1, sizeof(distance));
754 cpu = 0;
755 for (coord.y = 0; coord.y < smp_height; ++coord.y) {
756 for (coord.x = 0; coord.x < smp_width;
757 ++coord.x, ++cpu) {
758 BUG_ON(cpu >= nr_cpu_ids);
759 if (!cpu_possible(cpu)) {
760 cpu_2_node[cpu] = -1;
761 continue;
762 }
763 for_each_node_mask(node, default_nodes) {
764 HV_MemoryControllerInfo info =
765 hv_inquire_memory_controller(
766 coord, node_controller[node]);
767 distance[node][cpu] =
768 ABS(info.coord.x) + ABS(info.coord.y);
769 }
770 cpumask_set_cpu(cpu, &unbound_cpus);
771 }
772 }
773 cpus = cpu;
774
775 /*
776 * Round-robin through the NUMA nodes until all the cpus are
777 * assigned. We could be more clever here (e.g. create four
778 * sorted linked lists on the same set of cpu nodes, and pull
779 * off them in round-robin sequence, removing from all four
780 * lists each time) but given the relatively small numbers
781 * involved, O(n^2) seem OK for a one-time cost.
782 */
783 node = first_node(default_nodes);
784 while (!cpumask_empty(&unbound_cpus)) {
785 int best_cpu = -1;
786 int best_distance = INT_MAX;
787 for (cpu = 0; cpu < cpus; ++cpu) {
788 if (cpumask_test_cpu(cpu, &unbound_cpus)) {
789 /*
790 * Compute metric, which is how much
791 * closer the cpu is to this memory
792 * controller than the others, shifted
793 * up, and then the number of
794 * neighbors already in the node as an
795 * epsilon adjustment to try to keep
796 * the nodes compact.
797 */
798 int d = distance[node][cpu] * num_nodes;
799 for_each_node_mask(i, default_nodes) {
800 if (i != node)
801 d -= distance[i][cpu];
802 }
803 d *= 8; /* allow space for epsilon */
804 d -= node_neighbors(node, cpu, &unbound_cpus);
805 if (d < best_distance) {
806 best_cpu = cpu;
807 best_distance = d;
808 }
809 }
810 }
811 BUG_ON(best_cpu < 0);
812 cpumask_set_cpu(best_cpu, &node_2_cpu_mask[node]);
813 cpu_2_node[best_cpu] = node;
814 cpumask_clear_cpu(best_cpu, &unbound_cpus);
815 node = next_node(node, default_nodes);
816 if (node == MAX_NUMNODES)
817 node = first_node(default_nodes);
818 }
819
820 /* Print out node assignments and set defaults for disabled cpus */
821 cpu = 0;
822 for (y = 0; y < smp_height; ++y) {
823 printk(KERN_DEBUG "NUMA cpu-to-node row %d:", y);
824 for (x = 0; x < smp_width; ++x, ++cpu) {
825 if (cpu_to_node(cpu) < 0) {
826 pr_cont(" -");
827 cpu_2_node[cpu] = first_node(default_nodes);
828 } else {
829 pr_cont(" %d", cpu_to_node(cpu));
830 }
831 }
832 pr_cont("\n");
833 }
834}
835
836static struct cpu cpu_devices[NR_CPUS];
837
838static int __init topology_init(void)
839{
840 int i;
841
842 for_each_online_node(i)
843 register_one_node(i);
844
845 for_each_present_cpu(i)
846 register_cpu(&cpu_devices[i], i);
847
848 return 0;
849}
850
851subsys_initcall(topology_init);
852
853#else /* !CONFIG_NUMA */
854
855#define setup_numa_mapping() do { } while (0)
856
857#endif /* CONFIG_NUMA */
858
859/**
860 * setup_cpu() - Do all necessary per-cpu, tile-specific initialization.
861 * @boot: Is this the boot cpu?
862 *
863 * Called from setup_arch() on the boot cpu, or online_secondary().
864 */
865void __cpuinit setup_cpu(int boot)
866{
867 /* The boot cpu sets up its permanent mappings much earlier. */
868 if (!boot)
869 store_permanent_mappings();
870
871 /* Allow asynchronous TLB interrupts. */
872#if CHIP_HAS_TILE_DMA()
873 raw_local_irq_unmask(INT_DMATLB_MISS);
874 raw_local_irq_unmask(INT_DMATLB_ACCESS);
875#endif
876#if CHIP_HAS_SN_PROC()
877 raw_local_irq_unmask(INT_SNITLB_MISS);
878#endif
879
880 /*
881 * Allow user access to many generic SPRs, like the cycle
882 * counter, PASS/FAIL/DONE, INTERRUPT_CRITICAL_SECTION, etc.
883 */
884 __insn_mtspr(SPR_MPL_WORLD_ACCESS_SET_0, 1);
885
886#if CHIP_HAS_SN()
887 /* Static network is not restricted. */
888 __insn_mtspr(SPR_MPL_SN_ACCESS_SET_0, 1);
889#endif
890#if CHIP_HAS_SN_PROC()
891 __insn_mtspr(SPR_MPL_SN_NOTIFY_SET_0, 1);
892 __insn_mtspr(SPR_MPL_SN_CPL_SET_0, 1);
893#endif
894
895 /*
896 * Set the MPL for interrupt control 0 to user level.
897 * This includes access to the SYSTEM_SAVE and EX_CONTEXT SPRs,
898 * as well as the PL 0 interrupt mask.
899 */
900 __insn_mtspr(SPR_MPL_INTCTRL_0_SET_0, 1);
901
902 /* Initialize IRQ support for this cpu. */
903 setup_irq_regs();
904
905#ifdef CONFIG_HARDWALL
906 /* Reset the network state on this cpu. */
907 reset_network_state();
908#endif
909}
910
911static int __initdata set_initramfs_file;
912static char __initdata initramfs_file[128] = "initramfs.cpio.gz";
913
914static int __init setup_initramfs_file(char *str)
915{
916 if (str == NULL)
917 return -EINVAL;
918 strncpy(initramfs_file, str, sizeof(initramfs_file) - 1);
919 set_initramfs_file = 1;
920
921 return 0;
922}
923early_param("initramfs_file", setup_initramfs_file);
924
925/*
926 * We look for an additional "initramfs.cpio.gz" file in the hvfs.
927 * If there is one, we allocate some memory for it and it will be
928 * unpacked to the initramfs after any built-in initramfs_data.
929 */
930static void __init load_hv_initrd(void)
931{
932 HV_FS_StatInfo stat;
933 int fd, rc;
934 void *initrd;
935
936 fd = hv_fs_findfile((HV_VirtAddr) initramfs_file);
937 if (fd == HV_ENOENT) {
938 if (set_initramfs_file)
939 pr_warning("No such hvfs initramfs file '%s'\n",
940 initramfs_file);
941 return;
942 }
943 BUG_ON(fd < 0);
944 stat = hv_fs_fstat(fd);
945 BUG_ON(stat.size < 0);
946 if (stat.flags & HV_FS_ISDIR) {
947 pr_warning("Ignoring hvfs file '%s': it's a directory.\n",
948 initramfs_file);
949 return;
950 }
951 initrd = alloc_bootmem_pages(stat.size);
952 rc = hv_fs_pread(fd, (HV_VirtAddr) initrd, stat.size, 0);
953 if (rc != stat.size) {
954 pr_err("Error reading %d bytes from hvfs file '%s': %d\n",
955 stat.size, initramfs_file, rc);
956 free_initrd_mem((unsigned long) initrd, stat.size);
957 return;
958 }
959 initrd_start = (unsigned long) initrd;
960 initrd_end = initrd_start + stat.size;
961}
962
963void __init free_initrd_mem(unsigned long begin, unsigned long end)
964{
965 free_bootmem(__pa(begin), end - begin);
966}
967
968static void __init validate_hv(void)
969{
970 /*
971 * It may already be too late, but let's check our built-in
972 * configuration against what the hypervisor is providing.
973 */
974 unsigned long glue_size = hv_sysconf(HV_SYSCONF_GLUE_SIZE);
975 int hv_page_size = hv_sysconf(HV_SYSCONF_PAGE_SIZE_SMALL);
976 int hv_hpage_size = hv_sysconf(HV_SYSCONF_PAGE_SIZE_LARGE);
977 HV_ASIDRange asid_range;
978
979#ifndef CONFIG_SMP
980 HV_Topology topology = hv_inquire_topology();
981 BUG_ON(topology.coord.x != 0 || topology.coord.y != 0);
982 if (topology.width != 1 || topology.height != 1) {
983 pr_warning("Warning: booting UP kernel on %dx%d grid;"
984 " will ignore all but first tile.\n",
985 topology.width, topology.height);
986 }
987#endif
988
989 if (PAGE_OFFSET + HV_GLUE_START_CPA + glue_size > (unsigned long)_text)
990 early_panic("Hypervisor glue size %ld is too big!\n",
991 glue_size);
992 if (hv_page_size != PAGE_SIZE)
993 early_panic("Hypervisor page size %#x != our %#lx\n",
994 hv_page_size, PAGE_SIZE);
995 if (hv_hpage_size != HPAGE_SIZE)
996 early_panic("Hypervisor huge page size %#x != our %#lx\n",
997 hv_hpage_size, HPAGE_SIZE);
998
999#ifdef CONFIG_SMP
1000 /*
1001 * Some hypervisor APIs take a pointer to a bitmap array
1002 * whose size is at least the number of cpus on the chip.
1003 * We use a struct cpumask for this, so it must be big enough.
1004 */
1005 if ((smp_height * smp_width) > nr_cpu_ids)
1006 early_panic("Hypervisor %d x %d grid too big for Linux"
1007 " NR_CPUS %d\n", smp_height, smp_width,
1008 nr_cpu_ids);
1009#endif
1010
1011 /*
1012 * Check that we're using allowed ASIDs, and initialize the
1013 * various asid variables to their appropriate initial states.
1014 */
1015 asid_range = hv_inquire_asid(0);
1016 __get_cpu_var(current_asid) = min_asid = asid_range.start;
1017 max_asid = asid_range.start + asid_range.size - 1;
1018
1019 if (hv_confstr(HV_CONFSTR_CHIP_MODEL, (HV_VirtAddr)chip_model,
1020 sizeof(chip_model)) < 0) {
1021 pr_err("Warning: HV_CONFSTR_CHIP_MODEL not available\n");
1022 strlcpy(chip_model, "unknown", sizeof(chip_model));
1023 }
1024}
1025
1026static void __init validate_va(void)
1027{
1028#ifndef __tilegx__ /* FIXME: GX: probably some validation relevant here */
1029 /*
1030 * Similarly, make sure we're only using allowed VAs.
1031 * We assume we can contiguously use MEM_USER_INTRPT .. MEM_HV_INTRPT,
1032 * and 0 .. KERNEL_HIGH_VADDR.
1033 * In addition, make sure we CAN'T use the end of memory, since
1034 * we use the last chunk of each pgd for the pgd_list.
1035 */
1036 int i, fc_fd_ok = 0;
1037 unsigned long max_va = 0;
1038 unsigned long list_va =
1039 ((PGD_LIST_OFFSET / sizeof(pgd_t)) << PGDIR_SHIFT);
1040
1041 for (i = 0; ; ++i) {
1042 HV_VirtAddrRange range = hv_inquire_virtual(i);
1043 if (range.size == 0)
1044 break;
1045 if (range.start <= MEM_USER_INTRPT &&
1046 range.start + range.size >= MEM_HV_INTRPT)
1047 fc_fd_ok = 1;
1048 if (range.start == 0)
1049 max_va = range.size;
1050 BUG_ON(range.start + range.size > list_va);
1051 }
1052 if (!fc_fd_ok)
1053 early_panic("Hypervisor not configured for VAs 0xfc/0xfd\n");
1054 if (max_va == 0)
1055 early_panic("Hypervisor not configured for low VAs\n");
1056 if (max_va < KERNEL_HIGH_VADDR)
1057 early_panic("Hypervisor max VA %#lx smaller than %#lx\n",
1058 max_va, KERNEL_HIGH_VADDR);
1059
1060 /* Kernel PCs must have their high bit set; see intvec.S. */
1061 if ((long)VMALLOC_START >= 0)
1062 early_panic(
1063 "Linux VMALLOC region below the 2GB line (%#lx)!\n"
1064 "Reconfigure the kernel with fewer NR_HUGE_VMAPS\n"
1065 "or smaller VMALLOC_RESERVE.\n",
1066 VMALLOC_START);
1067#endif
1068}
1069
1070/*
1071 * cpu_lotar_map lists all the cpus that are valid for the supervisor
1072 * to cache data on at a page level, i.e. what cpus can be placed in
1073 * the LOTAR field of a PTE. It is equivalent to the set of possible
1074 * cpus plus any other cpus that are willing to share their cache.
1075 * It is set by hv_inquire_tiles(HV_INQ_TILES_LOTAR).
1076 */
1077struct cpumask __write_once cpu_lotar_map;
1078EXPORT_SYMBOL(cpu_lotar_map);
1079
1080#if CHIP_HAS_CBOX_HOME_MAP()
1081/*
1082 * hash_for_home_map lists all the tiles that hash-for-home data
1083 * will be cached on. Note that this may includes tiles that are not
1084 * valid for this supervisor to use otherwise (e.g. if a hypervisor
1085 * device is being shared between multiple supervisors).
1086 * It is set by hv_inquire_tiles(HV_INQ_TILES_HFH_CACHE).
1087 */
1088struct cpumask hash_for_home_map;
1089EXPORT_SYMBOL(hash_for_home_map);
1090#endif
1091
1092/*
1093 * cpu_cacheable_map lists all the cpus whose caches the hypervisor can
1094 * flush on our behalf. It is set to cpu_possible_map OR'ed with
1095 * hash_for_home_map, and it is what should be passed to
1096 * hv_flush_remote() to flush all caches. Note that if there are
1097 * dedicated hypervisor driver tiles that have authorized use of their
1098 * cache, those tiles will only appear in cpu_lotar_map, NOT in
1099 * cpu_cacheable_map, as they are a special case.
1100 */
1101struct cpumask __write_once cpu_cacheable_map;
1102EXPORT_SYMBOL(cpu_cacheable_map);
1103
1104static __initdata struct cpumask disabled_map;
1105
1106static int __init disabled_cpus(char *str)
1107{
1108 int boot_cpu = smp_processor_id();
1109
1110 if (str == NULL || cpulist_parse_crop(str, &disabled_map) != 0)
1111 return -EINVAL;
1112 if (cpumask_test_cpu(boot_cpu, &disabled_map)) {
1113 pr_err("disabled_cpus: can't disable boot cpu %d\n", boot_cpu);
1114 cpumask_clear_cpu(boot_cpu, &disabled_map);
1115 }
1116 return 0;
1117}
1118
1119early_param("disabled_cpus", disabled_cpus);
1120
1121void __init print_disabled_cpus(void)
1122{
1123 if (!cpumask_empty(&disabled_map)) {
1124 char buf[100];
1125 cpulist_scnprintf(buf, sizeof(buf), &disabled_map);
1126 pr_info("CPUs not available for Linux: %s\n", buf);
1127 }
1128}
1129
1130static void __init setup_cpu_maps(void)
1131{
1132 struct cpumask hv_disabled_map, cpu_possible_init;
1133 int boot_cpu = smp_processor_id();
1134 int cpus, i, rc;
1135
1136 /* Learn which cpus are allowed by the hypervisor. */
1137 rc = hv_inquire_tiles(HV_INQ_TILES_AVAIL,
1138 (HV_VirtAddr) cpumask_bits(&cpu_possible_init),
1139 sizeof(cpu_cacheable_map));
1140 if (rc < 0)
1141 early_panic("hv_inquire_tiles(AVAIL) failed: rc %d\n", rc);
1142 if (!cpumask_test_cpu(boot_cpu, &cpu_possible_init))
1143 early_panic("Boot CPU %d disabled by hypervisor!\n", boot_cpu);
1144
1145 /* Compute the cpus disabled by the hvconfig file. */
1146 cpumask_complement(&hv_disabled_map, &cpu_possible_init);
1147
1148 /* Include them with the cpus disabled by "disabled_cpus". */
1149 cpumask_or(&disabled_map, &disabled_map, &hv_disabled_map);
1150
1151 /*
1152 * Disable every cpu after "setup_max_cpus". But don't mark
1153 * as disabled the cpus that are outside of our initial rectangle,
1154 * since that turns out to be confusing.
1155 */
1156 cpus = 1; /* this cpu */
1157 cpumask_set_cpu(boot_cpu, &disabled_map); /* ignore this cpu */
1158 for (i = 0; cpus < setup_max_cpus; ++i)
1159 if (!cpumask_test_cpu(i, &disabled_map))
1160 ++cpus;
1161 for (; i < smp_height * smp_width; ++i)
1162 cpumask_set_cpu(i, &disabled_map);
1163 cpumask_clear_cpu(boot_cpu, &disabled_map); /* reset this cpu */
1164 for (i = smp_height * smp_width; i < NR_CPUS; ++i)
1165 cpumask_clear_cpu(i, &disabled_map);
1166
1167 /*
1168 * Setup cpu_possible map as every cpu allocated to us, minus
1169 * the results of any "disabled_cpus" settings.
1170 */
1171 cpumask_andnot(&cpu_possible_init, &cpu_possible_init, &disabled_map);
1172 init_cpu_possible(&cpu_possible_init);
1173
1174 /* Learn which cpus are valid for LOTAR caching. */
1175 rc = hv_inquire_tiles(HV_INQ_TILES_LOTAR,
1176 (HV_VirtAddr) cpumask_bits(&cpu_lotar_map),
1177 sizeof(cpu_lotar_map));
1178 if (rc < 0) {
1179 pr_err("warning: no HV_INQ_TILES_LOTAR; using AVAIL\n");
1180 cpu_lotar_map = cpu_possible_map;
1181 }
1182
1183#if CHIP_HAS_CBOX_HOME_MAP()
1184 /* Retrieve set of CPUs used for hash-for-home caching */
1185 rc = hv_inquire_tiles(HV_INQ_TILES_HFH_CACHE,
1186 (HV_VirtAddr) hash_for_home_map.bits,
1187 sizeof(hash_for_home_map));
1188 if (rc < 0)
1189 early_panic("hv_inquire_tiles(HFH_CACHE) failed: rc %d\n", rc);
1190 cpumask_or(&cpu_cacheable_map, &cpu_possible_map, &hash_for_home_map);
1191#else
1192 cpu_cacheable_map = cpu_possible_map;
1193#endif
1194}
1195
1196
1197static int __init dataplane(char *str)
1198{
1199 pr_warning("WARNING: dataplane support disabled in this kernel\n");
1200 return 0;
1201}
1202
1203early_param("dataplane", dataplane);
1204
1205#ifdef CONFIG_CMDLINE_BOOL
1206static char __initdata builtin_cmdline[COMMAND_LINE_SIZE] = CONFIG_CMDLINE;
1207#endif
1208
1209void __init setup_arch(char **cmdline_p)
1210{
1211 int len;
1212
1213#if defined(CONFIG_CMDLINE_BOOL) && defined(CONFIG_CMDLINE_OVERRIDE)
1214 len = hv_get_command_line((HV_VirtAddr) boot_command_line,
1215 COMMAND_LINE_SIZE);
1216 if (boot_command_line[0])
1217 pr_warning("WARNING: ignoring dynamic command line \"%s\"\n",
1218 boot_command_line);
1219 strlcpy(boot_command_line, builtin_cmdline, COMMAND_LINE_SIZE);
1220#else
1221 char *hv_cmdline;
1222#if defined(CONFIG_CMDLINE_BOOL)
1223 if (builtin_cmdline[0]) {
1224 int builtin_len = strlcpy(boot_command_line, builtin_cmdline,
1225 COMMAND_LINE_SIZE);
1226 if (builtin_len < COMMAND_LINE_SIZE-1)
1227 boot_command_line[builtin_len++] = ' ';
1228 hv_cmdline = &boot_command_line[builtin_len];
1229 len = COMMAND_LINE_SIZE - builtin_len;
1230 } else
1231#endif
1232 {
1233 hv_cmdline = boot_command_line;
1234 len = COMMAND_LINE_SIZE;
1235 }
1236 len = hv_get_command_line((HV_VirtAddr) hv_cmdline, len);
1237 if (len < 0 || len > COMMAND_LINE_SIZE)
1238 early_panic("hv_get_command_line failed: %d\n", len);
1239#endif
1240
1241 *cmdline_p = boot_command_line;
1242
1243 /* Set disabled_map and setup_max_cpus very early */
1244 parse_early_param();
1245
1246 /* Make sure the kernel is compatible with the hypervisor. */
1247 validate_hv();
1248 validate_va();
1249
1250 setup_cpu_maps();
1251
1252
1253#ifdef CONFIG_PCI
1254 /*
1255 * Initialize the PCI structures. This is done before memory
1256 * setup so that we know whether or not a pci_reserve region
1257 * is necessary.
1258 */
1259 if (tile_pci_init() == 0)
1260 pci_reserve_mb = 0;
1261
1262 /* PCI systems reserve a region just below 4GB for mapping iomem. */
1263 pci_reserve_end_pfn = (1 << (32 - PAGE_SHIFT));
1264 pci_reserve_start_pfn = pci_reserve_end_pfn -
1265 (pci_reserve_mb << (20 - PAGE_SHIFT));
1266#endif
1267
1268 init_mm.start_code = (unsigned long) _text;
1269 init_mm.end_code = (unsigned long) _etext;
1270 init_mm.end_data = (unsigned long) _edata;
1271 init_mm.brk = (unsigned long) _end;
1272
1273 setup_memory();
1274 store_permanent_mappings();
1275 setup_bootmem_allocator();
1276
1277 /*
1278 * NOTE: before this point _nobody_ is allowed to allocate
1279 * any memory using the bootmem allocator.
1280 */
1281
1282 paging_init();
1283 setup_numa_mapping();
1284 zone_sizes_init();
1285 set_page_homes();
1286 setup_cpu(1);
1287 setup_clock();
1288 load_hv_initrd();
1289}
1290
1291
1292/*
1293 * Set up per-cpu memory.
1294 */
1295
1296unsigned long __per_cpu_offset[NR_CPUS] __write_once;
1297EXPORT_SYMBOL(__per_cpu_offset);
1298
1299static size_t __initdata pfn_offset[MAX_NUMNODES] = { 0 };
1300static unsigned long __initdata percpu_pfn[NR_CPUS] = { 0 };
1301
1302/*
1303 * As the percpu code allocates pages, we return the pages from the
1304 * end of the node for the specified cpu.
1305 */
1306static void *__init pcpu_fc_alloc(unsigned int cpu, size_t size, size_t align)
1307{
1308 int nid = cpu_to_node(cpu);
1309 unsigned long pfn = node_percpu_pfn[nid] + pfn_offset[nid];
1310
1311 BUG_ON(size % PAGE_SIZE != 0);
1312 pfn_offset[nid] += size / PAGE_SIZE;
1313 if (percpu_pfn[cpu] == 0)
1314 percpu_pfn[cpu] = pfn;
1315 return pfn_to_kaddr(pfn);
1316}
1317
1318/*
1319 * Pages reserved for percpu memory are not freeable, and in any case we are
1320 * on a short path to panic() in setup_per_cpu_area() at this point anyway.
1321 */
1322static void __init pcpu_fc_free(void *ptr, size_t size)
1323{
1324}
1325
1326/*
1327 * Set up vmalloc page tables using bootmem for the percpu code.
1328 */
1329static void __init pcpu_fc_populate_pte(unsigned long addr)
1330{
1331 pgd_t *pgd;
1332 pud_t *pud;
1333 pmd_t *pmd;
1334 pte_t *pte;
1335
1336 BUG_ON(pgd_addr_invalid(addr));
1337
1338 pgd = swapper_pg_dir + pgd_index(addr);
1339 pud = pud_offset(pgd, addr);
1340 BUG_ON(!pud_present(*pud));
1341 pmd = pmd_offset(pud, addr);
1342 if (pmd_present(*pmd)) {
1343 BUG_ON(pmd_huge_page(*pmd));
1344 } else {
1345 pte = __alloc_bootmem(L2_KERNEL_PGTABLE_SIZE,
1346 HV_PAGE_TABLE_ALIGN, 0);
1347 pmd_populate_kernel(&init_mm, pmd, pte);
1348 }
1349}
1350
1351void __init setup_per_cpu_areas(void)
1352{
1353 struct page *pg;
1354 unsigned long delta, pfn, lowmem_va;
1355 unsigned long size = percpu_size();
1356 char *ptr;
1357 int rc, cpu, i;
1358
1359 rc = pcpu_page_first_chunk(PERCPU_MODULE_RESERVE, pcpu_fc_alloc,
1360 pcpu_fc_free, pcpu_fc_populate_pte);
1361 if (rc < 0)
1362 panic("Cannot initialize percpu area (err=%d)", rc);
1363
1364 delta = (unsigned long)pcpu_base_addr - (unsigned long)__per_cpu_start;
1365 for_each_possible_cpu(cpu) {
1366 __per_cpu_offset[cpu] = delta + pcpu_unit_offsets[cpu];
1367
1368 /* finv the copy out of cache so we can change homecache */
1369 ptr = pcpu_base_addr + pcpu_unit_offsets[cpu];
1370 __finv_buffer(ptr, size);
1371 pfn = percpu_pfn[cpu];
1372
1373 /* Rewrite the page tables to cache on that cpu */
1374 pg = pfn_to_page(pfn);
1375 for (i = 0; i < size; i += PAGE_SIZE, ++pfn, ++pg) {
1376
1377 /* Update the vmalloc mapping and page home. */
1378 pte_t *ptep =
1379 virt_to_pte(NULL, (unsigned long)ptr + i);
1380 pte_t pte = *ptep;
1381 BUG_ON(pfn != pte_pfn(pte));
1382 pte = hv_pte_set_mode(pte, HV_PTE_MODE_CACHE_TILE_L3);
1383 pte = set_remote_cache_cpu(pte, cpu);
1384 set_pte(ptep, pte);
1385
1386 /* Update the lowmem mapping for consistency. */
1387 lowmem_va = (unsigned long)pfn_to_kaddr(pfn);
1388 ptep = virt_to_pte(NULL, lowmem_va);
1389 if (pte_huge(*ptep)) {
1390 printk(KERN_DEBUG "early shatter of huge page"
1391 " at %#lx\n", lowmem_va);
1392 shatter_pmd((pmd_t *)ptep);
1393 ptep = virt_to_pte(NULL, lowmem_va);
1394 BUG_ON(pte_huge(*ptep));
1395 }
1396 BUG_ON(pfn != pte_pfn(*ptep));
1397 set_pte(ptep, pte);
1398 }
1399 }
1400
1401 /* Set our thread pointer appropriately. */
1402 set_my_cpu_offset(__per_cpu_offset[smp_processor_id()]);
1403
1404 /* Make sure the finv's have completed. */
1405 mb_incoherent();
1406
1407 /* Flush the TLB so we reference it properly from here on out. */
1408 local_flush_tlb_all();
1409}
1410
1411static struct resource data_resource = {
1412 .name = "Kernel data",
1413 .start = 0,
1414 .end = 0,
1415 .flags = IORESOURCE_BUSY | IORESOURCE_MEM
1416};
1417
1418static struct resource code_resource = {
1419 .name = "Kernel code",
1420 .start = 0,
1421 .end = 0,
1422 .flags = IORESOURCE_BUSY | IORESOURCE_MEM
1423};
1424
1425/*
1426 * We reserve all resources above 4GB so that PCI won't try to put
1427 * mappings above 4GB; the standard allows that for some devices but
1428 * the probing code trunates values to 32 bits.
1429 */
1430#ifdef CONFIG_PCI
1431static struct resource* __init
1432insert_non_bus_resource(void)
1433{
1434 struct resource *res =
1435 kzalloc(sizeof(struct resource), GFP_ATOMIC);
1436 res->name = "Non-Bus Physical Address Space";
1437 res->start = (1ULL << 32);
1438 res->end = -1LL;
1439 res->flags = IORESOURCE_BUSY | IORESOURCE_MEM;
1440 if (insert_resource(&iomem_resource, res)) {
1441 kfree(res);
1442 return NULL;
1443 }
1444 return res;
1445}
1446#endif
1447
1448static struct resource* __init
1449insert_ram_resource(u64 start_pfn, u64 end_pfn)
1450{
1451 struct resource *res =
1452 kzalloc(sizeof(struct resource), GFP_ATOMIC);
1453 res->name = "System RAM";
1454 res->start = start_pfn << PAGE_SHIFT;
1455 res->end = (end_pfn << PAGE_SHIFT) - 1;
1456 res->flags = IORESOURCE_BUSY | IORESOURCE_MEM;
1457 if (insert_resource(&iomem_resource, res)) {
1458 kfree(res);
1459 return NULL;
1460 }
1461 return res;
1462}
1463
1464/*
1465 * Request address space for all standard resources
1466 *
1467 * If the system includes PCI root complex drivers, we need to create
1468 * a window just below 4GB where PCI BARs can be mapped.
1469 */
1470static int __init request_standard_resources(void)
1471{
1472 int i;
1473 enum { CODE_DELTA = MEM_SV_INTRPT - PAGE_OFFSET };
1474
1475 iomem_resource.end = -1LL;
1476#ifdef CONFIG_PCI
1477 insert_non_bus_resource();
1478#endif
1479
1480 for_each_online_node(i) {
1481 u64 start_pfn = node_start_pfn[i];
1482 u64 end_pfn = node_end_pfn[i];
1483
1484#ifdef CONFIG_PCI
1485 if (start_pfn <= pci_reserve_start_pfn &&
1486 end_pfn > pci_reserve_start_pfn) {
1487 if (end_pfn > pci_reserve_end_pfn)
1488 insert_ram_resource(pci_reserve_end_pfn,
1489 end_pfn);
1490 end_pfn = pci_reserve_start_pfn;
1491 }
1492#endif
1493 insert_ram_resource(start_pfn, end_pfn);
1494 }
1495
1496 code_resource.start = __pa(_text - CODE_DELTA);
1497 code_resource.end = __pa(_etext - CODE_DELTA)-1;
1498 data_resource.start = __pa(_sdata);
1499 data_resource.end = __pa(_end)-1;
1500
1501 insert_resource(&iomem_resource, &code_resource);
1502 insert_resource(&iomem_resource, &data_resource);
1503
1504#ifdef CONFIG_KEXEC
1505 insert_resource(&iomem_resource, &crashk_res);
1506#endif
1507
1508 return 0;
1509}
1510
1511subsys_initcall(request_standard_resources);
diff --git a/arch/tile/kernel/signal.c b/arch/tile/kernel/signal.c
new file mode 100644
index 000000000000..45b66a3c991f
--- /dev/null
+++ b/arch/tile/kernel/signal.c
@@ -0,0 +1,358 @@
1/*
2 * Copyright (C) 1991, 1992 Linus Torvalds
3 * Copyright 2010 Tilera Corporation. All Rights Reserved.
4 *
5 * This program is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU General Public License
7 * as published by the Free Software Foundation, version 2.
8 *
9 * This program is distributed in the hope that it will be useful, but
10 * WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, GOOD TITLE or
12 * NON INFRINGEMENT. See the GNU General Public License for
13 * more details.
14 */
15
16#include <linux/sched.h>
17#include <linux/mm.h>
18#include <linux/smp.h>
19#include <linux/smp_lock.h>
20#include <linux/kernel.h>
21#include <linux/signal.h>
22#include <linux/errno.h>
23#include <linux/wait.h>
24#include <linux/unistd.h>
25#include <linux/stddef.h>
26#include <linux/personality.h>
27#include <linux/suspend.h>
28#include <linux/ptrace.h>
29#include <linux/elf.h>
30#include <linux/compat.h>
31#include <linux/syscalls.h>
32#include <linux/uaccess.h>
33#include <asm/processor.h>
34#include <asm/ucontext.h>
35#include <asm/sigframe.h>
36#include <asm/syscalls.h>
37#include <arch/interrupts.h>
38
39#define DEBUG_SIG 0
40
41#define _BLOCKABLE (~(sigmask(SIGKILL) | sigmask(SIGSTOP)))
42
43
44long _sys_sigaltstack(const stack_t __user *uss,
45 stack_t __user *uoss, struct pt_regs *regs)
46{
47 return do_sigaltstack(uss, uoss, regs->sp);
48}
49
50
51/*
52 * Do a signal return; undo the signal stack.
53 */
54
55int restore_sigcontext(struct pt_regs *regs,
56 struct sigcontext __user *sc, long *pr0)
57{
58 int err = 0;
59 int i;
60
61 /* Always make any pending restarted system calls return -EINTR */
62 current_thread_info()->restart_block.fn = do_no_restart_syscall;
63
64 for (i = 0; i < sizeof(struct pt_regs)/sizeof(long); ++i)
65 err |= __get_user(((long *)regs)[i],
66 &((long __user *)(&sc->regs))[i]);
67
68 regs->faultnum = INT_SWINT_1_SIGRETURN;
69
70 err |= __get_user(*pr0, &sc->regs.regs[0]);
71 return err;
72}
73
74/* sigreturn() returns long since it restores r0 in the interrupted code. */
75long _sys_rt_sigreturn(struct pt_regs *regs)
76{
77 struct rt_sigframe __user *frame =
78 (struct rt_sigframe __user *)(regs->sp);
79 sigset_t set;
80 long r0;
81
82 if (!access_ok(VERIFY_READ, frame, sizeof(*frame)))
83 goto badframe;
84 if (__copy_from_user(&set, &frame->uc.uc_sigmask, sizeof(set)))
85 goto badframe;
86
87 sigdelsetmask(&set, ~_BLOCKABLE);
88 spin_lock_irq(&current->sighand->siglock);
89 current->blocked = set;
90 recalc_sigpending();
91 spin_unlock_irq(&current->sighand->siglock);
92
93 if (restore_sigcontext(regs, &frame->uc.uc_mcontext, &r0))
94 goto badframe;
95
96 if (do_sigaltstack(&frame->uc.uc_stack, NULL, regs->sp) == -EFAULT)
97 goto badframe;
98
99 return r0;
100
101badframe:
102 force_sig(SIGSEGV, current);
103 return 0;
104}
105
106/*
107 * Set up a signal frame.
108 */
109
110int setup_sigcontext(struct sigcontext __user *sc, struct pt_regs *regs)
111{
112 int i, err = 0;
113
114 for (i = 0; i < sizeof(struct pt_regs)/sizeof(long); ++i)
115 err |= __put_user(((long *)regs)[i],
116 &((long __user *)(&sc->regs))[i]);
117
118 return err;
119}
120
121/*
122 * Determine which stack to use..
123 */
124static inline void __user *get_sigframe(struct k_sigaction *ka,
125 struct pt_regs *regs,
126 size_t frame_size)
127{
128 unsigned long sp;
129
130 /* Default to using normal stack */
131 sp = regs->sp;
132
133 /*
134 * If we are on the alternate signal stack and would overflow
135 * it, don't. Return an always-bogus address instead so we
136 * will die with SIGSEGV.
137 */
138 if (on_sig_stack(sp) && !likely(on_sig_stack(sp - frame_size)))
139 return (void __user __force *)-1UL;
140
141 /* This is the X/Open sanctioned signal stack switching. */
142 if (ka->sa.sa_flags & SA_ONSTACK) {
143 if (sas_ss_flags(sp) == 0)
144 sp = current->sas_ss_sp + current->sas_ss_size;
145 }
146
147 sp -= frame_size;
148 /*
149 * Align the stack pointer according to the TILE ABI,
150 * i.e. so that on function entry (sp & 15) == 0.
151 */
152 sp &= -16UL;
153 return (void __user *) sp;
154}
155
156static int setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info,
157 sigset_t *set, struct pt_regs *regs)
158{
159 unsigned long restorer;
160 struct rt_sigframe __user *frame;
161 int err = 0;
162 int usig;
163
164 frame = get_sigframe(ka, regs, sizeof(*frame));
165
166 if (!access_ok(VERIFY_WRITE, frame, sizeof(*frame)))
167 goto give_sigsegv;
168
169 usig = current_thread_info()->exec_domain
170 && current_thread_info()->exec_domain->signal_invmap
171 && sig < 32
172 ? current_thread_info()->exec_domain->signal_invmap[sig]
173 : sig;
174
175 /* Always write at least the signal number for the stack backtracer. */
176 if (ka->sa.sa_flags & SA_SIGINFO) {
177 /* At sigreturn time, restore the callee-save registers too. */
178 err |= copy_siginfo_to_user(&frame->info, info);
179 regs->flags |= PT_FLAGS_RESTORE_REGS;
180 } else {
181 err |= __put_user(info->si_signo, &frame->info.si_signo);
182 }
183
184 /* Create the ucontext. */
185 err |= __clear_user(&frame->save_area, sizeof(frame->save_area));
186 err |= __put_user(0, &frame->uc.uc_flags);
187 err |= __put_user(NULL, &frame->uc.uc_link);
188 err |= __put_user((void __user *)(current->sas_ss_sp),
189 &frame->uc.uc_stack.ss_sp);
190 err |= __put_user(sas_ss_flags(regs->sp),
191 &frame->uc.uc_stack.ss_flags);
192 err |= __put_user(current->sas_ss_size, &frame->uc.uc_stack.ss_size);
193 err |= setup_sigcontext(&frame->uc.uc_mcontext, regs);
194 err |= __copy_to_user(&frame->uc.uc_sigmask, set, sizeof(*set));
195 if (err)
196 goto give_sigsegv;
197
198 restorer = VDSO_BASE;
199 if (ka->sa.sa_flags & SA_RESTORER)
200 restorer = (unsigned long) ka->sa.sa_restorer;
201
202 /*
203 * Set up registers for signal handler.
204 * Registers that we don't modify keep the value they had from
205 * user-space at the time we took the signal.
206 */
207 regs->pc = (unsigned long) ka->sa.sa_handler;
208 regs->ex1 = PL_ICS_EX1(USER_PL, 1); /* set crit sec in handler */
209 regs->sp = (unsigned long) frame;
210 regs->lr = restorer;
211 regs->regs[0] = (unsigned long) usig;
212
213 if (ka->sa.sa_flags & SA_SIGINFO) {
214 /* Need extra arguments, so mark to restore caller-saves. */
215 regs->regs[1] = (unsigned long) &frame->info;
216 regs->regs[2] = (unsigned long) &frame->uc;
217 regs->flags |= PT_FLAGS_CALLER_SAVES;
218 }
219
220 /*
221 * Notify any tracer that was single-stepping it.
222 * The tracer may want to single-step inside the
223 * handler too.
224 */
225 if (test_thread_flag(TIF_SINGLESTEP))
226 ptrace_notify(SIGTRAP);
227
228 return 0;
229
230give_sigsegv:
231 force_sigsegv(sig, current);
232 return -EFAULT;
233}
234
235/*
236 * OK, we're invoking a handler
237 */
238
239static int handle_signal(unsigned long sig, siginfo_t *info,
240 struct k_sigaction *ka, sigset_t *oldset,
241 struct pt_regs *regs)
242{
243 int ret;
244
245
246 /* Are we from a system call? */
247 if (regs->faultnum == INT_SWINT_1) {
248 /* If so, check system call restarting.. */
249 switch (regs->regs[0]) {
250 case -ERESTART_RESTARTBLOCK:
251 case -ERESTARTNOHAND:
252 regs->regs[0] = -EINTR;
253 break;
254
255 case -ERESTARTSYS:
256 if (!(ka->sa.sa_flags & SA_RESTART)) {
257 regs->regs[0] = -EINTR;
258 break;
259 }
260 /* fallthrough */
261 case -ERESTARTNOINTR:
262 /* Reload caller-saves to restore r0..r5 and r10. */
263 regs->flags |= PT_FLAGS_CALLER_SAVES;
264 regs->regs[0] = regs->orig_r0;
265 regs->pc -= 8;
266 }
267 }
268
269 /* Set up the stack frame */
270#ifdef CONFIG_COMPAT
271 if (is_compat_task())
272 ret = compat_setup_rt_frame(sig, ka, info, oldset, regs);
273 else
274#endif
275 ret = setup_rt_frame(sig, ka, info, oldset, regs);
276 if (ret == 0) {
277 /* This code is only called from system calls or from
278 * the work_pending path in the return-to-user code, and
279 * either way we can re-enable interrupts unconditionally.
280 */
281 spin_lock_irq(&current->sighand->siglock);
282 sigorsets(&current->blocked,
283 &current->blocked, &ka->sa.sa_mask);
284 if (!(ka->sa.sa_flags & SA_NODEFER))
285 sigaddset(&current->blocked, sig);
286 recalc_sigpending();
287 spin_unlock_irq(&current->sighand->siglock);
288 }
289
290 return ret;
291}
292
293/*
294 * Note that 'init' is a special process: it doesn't get signals it doesn't
295 * want to handle. Thus you cannot kill init even with a SIGKILL even by
296 * mistake.
297 */
298void do_signal(struct pt_regs *regs)
299{
300 siginfo_t info;
301 int signr;
302 struct k_sigaction ka;
303 sigset_t *oldset;
304
305 /*
306 * i386 will check if we're coming from kernel mode and bail out
307 * here. In my experience this just turns weird crashes into
308 * weird spin-hangs. But if we find a case where this seems
309 * helpful, we can reinstate the check on "!user_mode(regs)".
310 */
311
312 if (current_thread_info()->status & TS_RESTORE_SIGMASK)
313 oldset = &current->saved_sigmask;
314 else
315 oldset = &current->blocked;
316
317 signr = get_signal_to_deliver(&info, &ka, regs, NULL);
318 if (signr > 0) {
319 /* Whee! Actually deliver the signal. */
320 if (handle_signal(signr, &info, &ka, oldset, regs) == 0) {
321 /*
322 * A signal was successfully delivered; the saved
323 * sigmask will have been stored in the signal frame,
324 * and will be restored by sigreturn, so we can simply
325 * clear the TS_RESTORE_SIGMASK flag.
326 */
327 current_thread_info()->status &= ~TS_RESTORE_SIGMASK;
328 }
329
330 return;
331 }
332
333 /* Did we come from a system call? */
334 if (regs->faultnum == INT_SWINT_1) {
335 /* Restart the system call - no handlers present */
336 switch (regs->regs[0]) {
337 case -ERESTARTNOHAND:
338 case -ERESTARTSYS:
339 case -ERESTARTNOINTR:
340 regs->flags |= PT_FLAGS_CALLER_SAVES;
341 regs->regs[0] = regs->orig_r0;
342 regs->pc -= 8;
343 break;
344
345 case -ERESTART_RESTARTBLOCK:
346 regs->flags |= PT_FLAGS_CALLER_SAVES;
347 regs->regs[TREG_SYSCALL_NR] = __NR_restart_syscall;
348 regs->pc -= 8;
349 break;
350 }
351 }
352
353 /* If there's no signal to deliver, just put the saved sigmask back. */
354 if (current_thread_info()->status & TS_RESTORE_SIGMASK) {
355 current_thread_info()->status &= ~TS_RESTORE_SIGMASK;
356 sigprocmask(SIG_SETMASK, &current->saved_sigmask, NULL);
357 }
358}
diff --git a/arch/tile/kernel/single_step.c b/arch/tile/kernel/single_step.c
new file mode 100644
index 000000000000..5ec4b9c651f2
--- /dev/null
+++ b/arch/tile/kernel/single_step.c
@@ -0,0 +1,663 @@
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 * A code-rewriter that enables instruction single-stepping.
15 * Derived from iLib's single-stepping code.
16 */
17
18#ifndef __tilegx__ /* No support for single-step yet. */
19
20/* These functions are only used on the TILE platform */
21#include <linux/slab.h>
22#include <linux/thread_info.h>
23#include <linux/uaccess.h>
24#include <linux/mman.h>
25#include <linux/types.h>
26#include <linux/err.h>
27#include <asm/cacheflush.h>
28#include <asm/opcode-tile.h>
29#include <asm/opcode_constants.h>
30#include <arch/abi.h>
31
32#define signExtend17(val) sign_extend((val), 17)
33#define TILE_X1_MASK (0xffffffffULL << 31)
34
35int unaligned_printk;
36
37static int __init setup_unaligned_printk(char *str)
38{
39 long val;
40 if (strict_strtol(str, 0, &val) != 0)
41 return 0;
42 unaligned_printk = val;
43 pr_info("Printk for each unaligned data accesses is %s\n",
44 unaligned_printk ? "enabled" : "disabled");
45 return 1;
46}
47__setup("unaligned_printk=", setup_unaligned_printk);
48
49unsigned int unaligned_fixup_count;
50
51enum mem_op {
52 MEMOP_NONE,
53 MEMOP_LOAD,
54 MEMOP_STORE,
55 MEMOP_LOAD_POSTINCR,
56 MEMOP_STORE_POSTINCR
57};
58
59static inline tile_bundle_bits set_BrOff_X1(tile_bundle_bits n, int32_t offset)
60{
61 tile_bundle_bits result;
62
63 /* mask out the old offset */
64 tile_bundle_bits mask = create_BrOff_X1(-1);
65 result = n & (~mask);
66
67 /* or in the new offset */
68 result |= create_BrOff_X1(offset);
69
70 return result;
71}
72
73static inline tile_bundle_bits move_X1(tile_bundle_bits n, int dest, int src)
74{
75 tile_bundle_bits result;
76 tile_bundle_bits op;
77
78 result = n & (~TILE_X1_MASK);
79
80 op = create_Opcode_X1(SPECIAL_0_OPCODE_X1) |
81 create_RRROpcodeExtension_X1(OR_SPECIAL_0_OPCODE_X1) |
82 create_Dest_X1(dest) |
83 create_SrcB_X1(TREG_ZERO) |
84 create_SrcA_X1(src) ;
85
86 result |= op;
87 return result;
88}
89
90static inline tile_bundle_bits nop_X1(tile_bundle_bits n)
91{
92 return move_X1(n, TREG_ZERO, TREG_ZERO);
93}
94
95static inline tile_bundle_bits addi_X1(
96 tile_bundle_bits n, int dest, int src, int imm)
97{
98 n &= ~TILE_X1_MASK;
99
100 n |= (create_SrcA_X1(src) |
101 create_Dest_X1(dest) |
102 create_Imm8_X1(imm) |
103 create_S_X1(0) |
104 create_Opcode_X1(IMM_0_OPCODE_X1) |
105 create_ImmOpcodeExtension_X1(ADDI_IMM_0_OPCODE_X1));
106
107 return n;
108}
109
110static tile_bundle_bits rewrite_load_store_unaligned(
111 struct single_step_state *state,
112 tile_bundle_bits bundle,
113 struct pt_regs *regs,
114 enum mem_op mem_op,
115 int size, int sign_ext)
116{
117 unsigned char __user *addr;
118 int val_reg, addr_reg, err, val;
119
120 /* Get address and value registers */
121 if (bundle & TILE_BUNDLE_Y_ENCODING_MASK) {
122 addr_reg = get_SrcA_Y2(bundle);
123 val_reg = get_SrcBDest_Y2(bundle);
124 } else if (mem_op == MEMOP_LOAD || mem_op == MEMOP_LOAD_POSTINCR) {
125 addr_reg = get_SrcA_X1(bundle);
126 val_reg = get_Dest_X1(bundle);
127 } else {
128 addr_reg = get_SrcA_X1(bundle);
129 val_reg = get_SrcB_X1(bundle);
130 }
131
132 /*
133 * If registers are not GPRs, don't try to handle it.
134 *
135 * FIXME: we could handle non-GPR loads by getting the real value
136 * from memory, writing it to the single step buffer, using a
137 * temp_reg to hold a pointer to that memory, then executing that
138 * instruction and resetting temp_reg. For non-GPR stores, it's a
139 * little trickier; we could use the single step buffer for that
140 * too, but we'd have to add some more state bits so that we could
141 * call back in here to copy that value to the real target. For
142 * now, we just handle the simple case.
143 */
144 if ((val_reg >= PTREGS_NR_GPRS &&
145 (val_reg != TREG_ZERO ||
146 mem_op == MEMOP_LOAD ||
147 mem_op == MEMOP_LOAD_POSTINCR)) ||
148 addr_reg >= PTREGS_NR_GPRS)
149 return bundle;
150
151 /* If it's aligned, don't handle it specially */
152 addr = (void __user *)regs->regs[addr_reg];
153 if (((unsigned long)addr % size) == 0)
154 return bundle;
155
156#ifndef __LITTLE_ENDIAN
157# error We assume little-endian representation with copy_xx_user size 2 here
158#endif
159 /* Handle unaligned load/store */
160 if (mem_op == MEMOP_LOAD || mem_op == MEMOP_LOAD_POSTINCR) {
161 unsigned short val_16;
162 switch (size) {
163 case 2:
164 err = copy_from_user(&val_16, addr, sizeof(val_16));
165 val = sign_ext ? ((short)val_16) : val_16;
166 break;
167 case 4:
168 err = copy_from_user(&val, addr, sizeof(val));
169 break;
170 default:
171 BUG();
172 }
173 if (err == 0) {
174 state->update_reg = val_reg;
175 state->update_value = val;
176 state->update = 1;
177 }
178 } else {
179 val = (val_reg == TREG_ZERO) ? 0 : regs->regs[val_reg];
180 err = copy_to_user(addr, &val, size);
181 }
182
183 if (err) {
184 siginfo_t info = {
185 .si_signo = SIGSEGV,
186 .si_code = SEGV_MAPERR,
187 .si_addr = addr
188 };
189 force_sig_info(info.si_signo, &info, current);
190 return (tile_bundle_bits) 0;
191 }
192
193 if (unaligned_fixup == 0) {
194 siginfo_t info = {
195 .si_signo = SIGBUS,
196 .si_code = BUS_ADRALN,
197 .si_addr = addr
198 };
199 force_sig_info(info.si_signo, &info, current);
200 return (tile_bundle_bits) 0;
201 }
202
203 if (unaligned_printk || unaligned_fixup_count == 0) {
204 pr_info("Process %d/%s: PC %#lx: Fixup of"
205 " unaligned %s at %#lx.\n",
206 current->pid, current->comm, regs->pc,
207 (mem_op == MEMOP_LOAD ||
208 mem_op == MEMOP_LOAD_POSTINCR) ?
209 "load" : "store",
210 (unsigned long)addr);
211 if (!unaligned_printk) {
212#define P pr_info
213P("\n");
214P("Unaligned fixups in the kernel will slow your application considerably.\n");
215P("To find them, write a \"1\" to /proc/sys/tile/unaligned_fixup/printk,\n");
216P("which requests the kernel show all unaligned fixups, or write a \"0\"\n");
217P("to /proc/sys/tile/unaligned_fixup/enabled, in which case each unaligned\n");
218P("access will become a SIGBUS you can debug. No further warnings will be\n");
219P("shown so as to avoid additional slowdown, but you can track the number\n");
220P("of fixups performed via /proc/sys/tile/unaligned_fixup/count.\n");
221P("Use the tile-addr2line command (see \"info addr2line\") to decode PCs.\n");
222P("\n");
223#undef P
224 }
225 }
226 ++unaligned_fixup_count;
227
228 if (bundle & TILE_BUNDLE_Y_ENCODING_MASK) {
229 /* Convert the Y2 instruction to a prefetch. */
230 bundle &= ~(create_SrcBDest_Y2(-1) |
231 create_Opcode_Y2(-1));
232 bundle |= (create_SrcBDest_Y2(TREG_ZERO) |
233 create_Opcode_Y2(LW_OPCODE_Y2));
234 /* Replace the load postincr with an addi */
235 } else if (mem_op == MEMOP_LOAD_POSTINCR) {
236 bundle = addi_X1(bundle, addr_reg, addr_reg,
237 get_Imm8_X1(bundle));
238 /* Replace the store postincr with an addi */
239 } else if (mem_op == MEMOP_STORE_POSTINCR) {
240 bundle = addi_X1(bundle, addr_reg, addr_reg,
241 get_Dest_Imm8_X1(bundle));
242 } else {
243 /* Convert the X1 instruction to a nop. */
244 bundle &= ~(create_Opcode_X1(-1) |
245 create_UnShOpcodeExtension_X1(-1) |
246 create_UnOpcodeExtension_X1(-1));
247 bundle |= (create_Opcode_X1(SHUN_0_OPCODE_X1) |
248 create_UnShOpcodeExtension_X1(
249 UN_0_SHUN_0_OPCODE_X1) |
250 create_UnOpcodeExtension_X1(
251 NOP_UN_0_SHUN_0_OPCODE_X1));
252 }
253
254 return bundle;
255}
256
257/**
258 * single_step_once() - entry point when single stepping has been triggered.
259 * @regs: The machine register state
260 *
261 * When we arrive at this routine via a trampoline, the single step
262 * engine copies the executing bundle to the single step buffer.
263 * If the instruction is a condition branch, then the target is
264 * reset to one past the next instruction. If the instruction
265 * sets the lr, then that is noted. If the instruction is a jump
266 * or call, then the new target pc is preserved and the current
267 * bundle instruction set to null.
268 *
269 * The necessary post-single-step rewriting information is stored in
270 * single_step_state-> We use data segment values because the
271 * stack will be rewound when we run the rewritten single-stepped
272 * instruction.
273 */
274void single_step_once(struct pt_regs *regs)
275{
276 extern tile_bundle_bits __single_step_ill_insn;
277 extern tile_bundle_bits __single_step_j_insn;
278 extern tile_bundle_bits __single_step_addli_insn;
279 extern tile_bundle_bits __single_step_auli_insn;
280 struct thread_info *info = (void *)current_thread_info();
281 struct single_step_state *state = info->step_state;
282 int is_single_step = test_ti_thread_flag(info, TIF_SINGLESTEP);
283 tile_bundle_bits __user *buffer, *pc;
284 tile_bundle_bits bundle;
285 int temp_reg;
286 int target_reg = TREG_LR;
287 int err;
288 enum mem_op mem_op = MEMOP_NONE;
289 int size = 0, sign_ext = 0; /* happy compiler */
290
291 asm(
292" .pushsection .rodata.single_step\n"
293" .align 8\n"
294" .globl __single_step_ill_insn\n"
295"__single_step_ill_insn:\n"
296" ill\n"
297" .globl __single_step_addli_insn\n"
298"__single_step_addli_insn:\n"
299" { nop; addli r0, zero, 0 }\n"
300" .globl __single_step_auli_insn\n"
301"__single_step_auli_insn:\n"
302" { nop; auli r0, r0, 0 }\n"
303" .globl __single_step_j_insn\n"
304"__single_step_j_insn:\n"
305" j .\n"
306" .popsection\n"
307 );
308
309 if (state == NULL) {
310 /* allocate a page of writable, executable memory */
311 state = kmalloc(sizeof(struct single_step_state), GFP_KERNEL);
312 if (state == NULL) {
313 pr_err("Out of kernel memory trying to single-step\n");
314 return;
315 }
316
317 /* allocate a cache line of writable, executable memory */
318 down_write(&current->mm->mmap_sem);
319 buffer = (void __user *) do_mmap(NULL, 0, 64,
320 PROT_EXEC | PROT_READ | PROT_WRITE,
321 MAP_PRIVATE | MAP_ANONYMOUS,
322 0);
323 up_write(&current->mm->mmap_sem);
324
325 if (IS_ERR((void __force *)buffer)) {
326 kfree(state);
327 pr_err("Out of kernel pages trying to single-step\n");
328 return;
329 }
330
331 state->buffer = buffer;
332 state->is_enabled = 0;
333
334 info->step_state = state;
335
336 /* Validate our stored instruction patterns */
337 BUG_ON(get_Opcode_X1(__single_step_addli_insn) !=
338 ADDLI_OPCODE_X1);
339 BUG_ON(get_Opcode_X1(__single_step_auli_insn) !=
340 AULI_OPCODE_X1);
341 BUG_ON(get_SrcA_X1(__single_step_addli_insn) != TREG_ZERO);
342 BUG_ON(get_Dest_X1(__single_step_addli_insn) != 0);
343 BUG_ON(get_JOffLong_X1(__single_step_j_insn) != 0);
344 }
345
346 /*
347 * If we are returning from a syscall, we still haven't hit the
348 * "ill" for the swint1 instruction. So back the PC up to be
349 * pointing at the swint1, but we'll actually return directly
350 * back to the "ill" so we come back in via SIGILL as if we
351 * had "executed" the swint1 without ever being in kernel space.
352 */
353 if (regs->faultnum == INT_SWINT_1)
354 regs->pc -= 8;
355
356 pc = (tile_bundle_bits __user *)(regs->pc);
357 if (get_user(bundle, pc) != 0) {
358 pr_err("Couldn't read instruction at %p trying to step\n", pc);
359 return;
360 }
361
362 /* We'll follow the instruction with 2 ill op bundles */
363 state->orig_pc = (unsigned long)pc;
364 state->next_pc = (unsigned long)(pc + 1);
365 state->branch_next_pc = 0;
366 state->update = 0;
367
368 if (!(bundle & TILE_BUNDLE_Y_ENCODING_MASK)) {
369 /* two wide, check for control flow */
370 int opcode = get_Opcode_X1(bundle);
371
372 switch (opcode) {
373 /* branches */
374 case BRANCH_OPCODE_X1:
375 {
376 int32_t offset = signExtend17(get_BrOff_X1(bundle));
377
378 /*
379 * For branches, we use a rewriting trick to let the
380 * hardware evaluate whether the branch is taken or
381 * untaken. We record the target offset and then
382 * rewrite the branch instruction to target 1 insn
383 * ahead if the branch is taken. We then follow the
384 * rewritten branch with two bundles, each containing
385 * an "ill" instruction. The supervisor examines the
386 * pc after the single step code is executed, and if
387 * the pc is the first ill instruction, then the
388 * branch (if any) was not taken. If the pc is the
389 * second ill instruction, then the branch was
390 * taken. The new pc is computed for these cases, and
391 * inserted into the registers for the thread. If
392 * the pc is the start of the single step code, then
393 * an exception or interrupt was taken before the
394 * code started processing, and the same "original"
395 * pc is restored. This change, different from the
396 * original implementation, has the advantage of
397 * executing a single user instruction.
398 */
399 state->branch_next_pc = (unsigned long)(pc + offset);
400
401 /* rewrite branch offset to go forward one bundle */
402 bundle = set_BrOff_X1(bundle, 2);
403 }
404 break;
405
406 /* jumps */
407 case JALB_OPCODE_X1:
408 case JALF_OPCODE_X1:
409 state->update = 1;
410 state->next_pc =
411 (unsigned long) (pc + get_JOffLong_X1(bundle));
412 break;
413
414 case JB_OPCODE_X1:
415 case JF_OPCODE_X1:
416 state->next_pc =
417 (unsigned long) (pc + get_JOffLong_X1(bundle));
418 bundle = nop_X1(bundle);
419 break;
420
421 case SPECIAL_0_OPCODE_X1:
422 switch (get_RRROpcodeExtension_X1(bundle)) {
423 /* jump-register */
424 case JALRP_SPECIAL_0_OPCODE_X1:
425 case JALR_SPECIAL_0_OPCODE_X1:
426 state->update = 1;
427 state->next_pc =
428 regs->regs[get_SrcA_X1(bundle)];
429 break;
430
431 case JRP_SPECIAL_0_OPCODE_X1:
432 case JR_SPECIAL_0_OPCODE_X1:
433 state->next_pc =
434 regs->regs[get_SrcA_X1(bundle)];
435 bundle = nop_X1(bundle);
436 break;
437
438 case LNK_SPECIAL_0_OPCODE_X1:
439 state->update = 1;
440 target_reg = get_Dest_X1(bundle);
441 break;
442
443 /* stores */
444 case SH_SPECIAL_0_OPCODE_X1:
445 mem_op = MEMOP_STORE;
446 size = 2;
447 break;
448
449 case SW_SPECIAL_0_OPCODE_X1:
450 mem_op = MEMOP_STORE;
451 size = 4;
452 break;
453 }
454 break;
455
456 /* loads and iret */
457 case SHUN_0_OPCODE_X1:
458 if (get_UnShOpcodeExtension_X1(bundle) ==
459 UN_0_SHUN_0_OPCODE_X1) {
460 switch (get_UnOpcodeExtension_X1(bundle)) {
461 case LH_UN_0_SHUN_0_OPCODE_X1:
462 mem_op = MEMOP_LOAD;
463 size = 2;
464 sign_ext = 1;
465 break;
466
467 case LH_U_UN_0_SHUN_0_OPCODE_X1:
468 mem_op = MEMOP_LOAD;
469 size = 2;
470 sign_ext = 0;
471 break;
472
473 case LW_UN_0_SHUN_0_OPCODE_X1:
474 mem_op = MEMOP_LOAD;
475 size = 4;
476 break;
477
478 case IRET_UN_0_SHUN_0_OPCODE_X1:
479 {
480 unsigned long ex0_0 = __insn_mfspr(
481 SPR_EX_CONTEXT_0_0);
482 unsigned long ex0_1 = __insn_mfspr(
483 SPR_EX_CONTEXT_0_1);
484 /*
485 * Special-case it if we're iret'ing
486 * to PL0 again. Otherwise just let
487 * it run and it will generate SIGILL.
488 */
489 if (EX1_PL(ex0_1) == USER_PL) {
490 state->next_pc = ex0_0;
491 regs->ex1 = ex0_1;
492 bundle = nop_X1(bundle);
493 }
494 }
495 }
496 }
497 break;
498
499#if CHIP_HAS_WH64()
500 /* postincrement operations */
501 case IMM_0_OPCODE_X1:
502 switch (get_ImmOpcodeExtension_X1(bundle)) {
503 case LWADD_IMM_0_OPCODE_X1:
504 mem_op = MEMOP_LOAD_POSTINCR;
505 size = 4;
506 break;
507
508 case LHADD_IMM_0_OPCODE_X1:
509 mem_op = MEMOP_LOAD_POSTINCR;
510 size = 2;
511 sign_ext = 1;
512 break;
513
514 case LHADD_U_IMM_0_OPCODE_X1:
515 mem_op = MEMOP_LOAD_POSTINCR;
516 size = 2;
517 sign_ext = 0;
518 break;
519
520 case SWADD_IMM_0_OPCODE_X1:
521 mem_op = MEMOP_STORE_POSTINCR;
522 size = 4;
523 break;
524
525 case SHADD_IMM_0_OPCODE_X1:
526 mem_op = MEMOP_STORE_POSTINCR;
527 size = 2;
528 break;
529
530 default:
531 break;
532 }
533 break;
534#endif /* CHIP_HAS_WH64() */
535 }
536
537 if (state->update) {
538 /*
539 * Get an available register. We start with a
540 * bitmask with 1's for available registers.
541 * We truncate to the low 32 registers since
542 * we are guaranteed to have set bits in the
543 * low 32 bits, then use ctz to pick the first.
544 */
545 u32 mask = (u32) ~((1ULL << get_Dest_X0(bundle)) |
546 (1ULL << get_SrcA_X0(bundle)) |
547 (1ULL << get_SrcB_X0(bundle)) |
548 (1ULL << target_reg));
549 temp_reg = __builtin_ctz(mask);
550 state->update_reg = temp_reg;
551 state->update_value = regs->regs[temp_reg];
552 regs->regs[temp_reg] = (unsigned long) (pc+1);
553 regs->flags |= PT_FLAGS_RESTORE_REGS;
554 bundle = move_X1(bundle, target_reg, temp_reg);
555 }
556 } else {
557 int opcode = get_Opcode_Y2(bundle);
558
559 switch (opcode) {
560 /* loads */
561 case LH_OPCODE_Y2:
562 mem_op = MEMOP_LOAD;
563 size = 2;
564 sign_ext = 1;
565 break;
566
567 case LH_U_OPCODE_Y2:
568 mem_op = MEMOP_LOAD;
569 size = 2;
570 sign_ext = 0;
571 break;
572
573 case LW_OPCODE_Y2:
574 mem_op = MEMOP_LOAD;
575 size = 4;
576 break;
577
578 /* stores */
579 case SH_OPCODE_Y2:
580 mem_op = MEMOP_STORE;
581 size = 2;
582 break;
583
584 case SW_OPCODE_Y2:
585 mem_op = MEMOP_STORE;
586 size = 4;
587 break;
588 }
589 }
590
591 /*
592 * Check if we need to rewrite an unaligned load/store.
593 * Returning zero is a special value meaning we need to SIGSEGV.
594 */
595 if (mem_op != MEMOP_NONE && unaligned_fixup >= 0) {
596 bundle = rewrite_load_store_unaligned(state, bundle, regs,
597 mem_op, size, sign_ext);
598 if (bundle == 0)
599 return;
600 }
601
602 /* write the bundle to our execution area */
603 buffer = state->buffer;
604 err = __put_user(bundle, buffer++);
605
606 /*
607 * If we're really single-stepping, we take an INT_ILL after.
608 * If we're just handling an unaligned access, we can just
609 * jump directly back to where we were in user code.
610 */
611 if (is_single_step) {
612 err |= __put_user(__single_step_ill_insn, buffer++);
613 err |= __put_user(__single_step_ill_insn, buffer++);
614 } else {
615 long delta;
616
617 if (state->update) {
618 /* We have some state to update; do it inline */
619 int ha16;
620 bundle = __single_step_addli_insn;
621 bundle |= create_Dest_X1(state->update_reg);
622 bundle |= create_Imm16_X1(state->update_value);
623 err |= __put_user(bundle, buffer++);
624 bundle = __single_step_auli_insn;
625 bundle |= create_Dest_X1(state->update_reg);
626 bundle |= create_SrcA_X1(state->update_reg);
627 ha16 = (state->update_value + 0x8000) >> 16;
628 bundle |= create_Imm16_X1(ha16);
629 err |= __put_user(bundle, buffer++);
630 state->update = 0;
631 }
632
633 /* End with a jump back to the next instruction */
634 delta = ((regs->pc + TILE_BUNDLE_SIZE_IN_BYTES) -
635 (unsigned long)buffer) >>
636 TILE_LOG2_BUNDLE_ALIGNMENT_IN_BYTES;
637 bundle = __single_step_j_insn;
638 bundle |= create_JOffLong_X1(delta);
639 err |= __put_user(bundle, buffer++);
640 }
641
642 if (err) {
643 pr_err("Fault when writing to single-step buffer\n");
644 return;
645 }
646
647 /*
648 * Flush the buffer.
649 * We do a local flush only, since this is a thread-specific buffer.
650 */
651 __flush_icache_range((unsigned long)state->buffer,
652 (unsigned long)buffer);
653
654 /* Indicate enabled */
655 state->is_enabled = is_single_step;
656 regs->pc = (unsigned long)state->buffer;
657
658 /* Fault immediately if we are coming back from a syscall. */
659 if (regs->faultnum == INT_SWINT_1)
660 regs->pc += 8;
661}
662
663#endif /* !__tilegx__ */
diff --git a/arch/tile/kernel/smp.c b/arch/tile/kernel/smp.c
new file mode 100644
index 000000000000..1cb5ec79de04
--- /dev/null
+++ b/arch/tile/kernel/smp.c
@@ -0,0 +1,256 @@
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 * TILE SMP support routines.
15 */
16
17#include <linux/smp.h>
18#include <linux/interrupt.h>
19#include <linux/io.h>
20#include <linux/irq.h>
21#include <linux/module.h>
22#include <asm/cacheflush.h>
23
24HV_Topology smp_topology __write_once;
25EXPORT_SYMBOL(smp_topology);
26
27#if CHIP_HAS_IPI()
28static unsigned long __iomem *ipi_mappings[NR_CPUS];
29#endif
30
31
32/*
33 * Top-level send_IPI*() functions to send messages to other cpus.
34 */
35
36/* Set by smp_send_stop() to avoid recursive panics. */
37static int stopping_cpus;
38
39void send_IPI_single(int cpu, int tag)
40{
41 HV_Recipient recip = {
42 .y = cpu / smp_width,
43 .x = cpu % smp_width,
44 .state = HV_TO_BE_SENT
45 };
46 int rc = hv_send_message(&recip, 1, (HV_VirtAddr)&tag, sizeof(tag));
47 BUG_ON(rc <= 0);
48}
49
50void send_IPI_many(const struct cpumask *mask, int tag)
51{
52 HV_Recipient recip[NR_CPUS];
53 int cpu, sent;
54 int nrecip = 0;
55 int my_cpu = smp_processor_id();
56 for_each_cpu(cpu, mask) {
57 HV_Recipient *r;
58 BUG_ON(cpu == my_cpu);
59 r = &recip[nrecip++];
60 r->y = cpu / smp_width;
61 r->x = cpu % smp_width;
62 r->state = HV_TO_BE_SENT;
63 }
64 sent = 0;
65 while (sent < nrecip) {
66 int rc = hv_send_message(recip, nrecip,
67 (HV_VirtAddr)&tag, sizeof(tag));
68 if (rc <= 0) {
69 if (!stopping_cpus) /* avoid recursive panic */
70 panic("hv_send_message returned %d", rc);
71 break;
72 }
73 sent += rc;
74 }
75}
76
77void send_IPI_allbutself(int tag)
78{
79 struct cpumask mask;
80 cpumask_copy(&mask, cpu_online_mask);
81 cpumask_clear_cpu(smp_processor_id(), &mask);
82 send_IPI_many(&mask, tag);
83}
84
85
86/*
87 * Provide smp_call_function_mask, but also run function locally
88 * if specified in the mask.
89 */
90void on_each_cpu_mask(const struct cpumask *mask, void (*func)(void *),
91 void *info, bool wait)
92{
93 int cpu = get_cpu();
94 smp_call_function_many(mask, func, info, wait);
95 if (cpumask_test_cpu(cpu, mask)) {
96 local_irq_disable();
97 func(info);
98 local_irq_enable();
99 }
100 put_cpu();
101}
102
103
104/*
105 * Functions related to starting/stopping cpus.
106 */
107
108/* Handler to start the current cpu. */
109static void smp_start_cpu_interrupt(void)
110{
111 get_irq_regs()->pc = start_cpu_function_addr;
112}
113
114/* Handler to stop the current cpu. */
115static void smp_stop_cpu_interrupt(void)
116{
117 set_cpu_online(smp_processor_id(), 0);
118 raw_local_irq_disable_all();
119 for (;;)
120 asm("nap");
121}
122
123/* This function calls the 'stop' function on all other CPUs in the system. */
124void smp_send_stop(void)
125{
126 stopping_cpus = 1;
127 send_IPI_allbutself(MSG_TAG_STOP_CPU);
128}
129
130
131/*
132 * Dispatch code called from hv_message_intr() for HV_MSG_TILE hv messages.
133 */
134void evaluate_message(int tag)
135{
136 switch (tag) {
137 case MSG_TAG_START_CPU: /* Start up a cpu */
138 smp_start_cpu_interrupt();
139 break;
140
141 case MSG_TAG_STOP_CPU: /* Sent to shut down slave CPU's */
142 smp_stop_cpu_interrupt();
143 break;
144
145 case MSG_TAG_CALL_FUNCTION_MANY: /* Call function on cpumask */
146 generic_smp_call_function_interrupt();
147 break;
148
149 case MSG_TAG_CALL_FUNCTION_SINGLE: /* Call function on one other CPU */
150 generic_smp_call_function_single_interrupt();
151 break;
152
153 default:
154 panic("Unknown IPI message tag %d", tag);
155 break;
156 }
157}
158
159
160/*
161 * flush_icache_range() code uses smp_call_function().
162 */
163
164struct ipi_flush {
165 unsigned long start;
166 unsigned long end;
167};
168
169static void ipi_flush_icache_range(void *info)
170{
171 struct ipi_flush *flush = (struct ipi_flush *) info;
172 __flush_icache_range(flush->start, flush->end);
173}
174
175void flush_icache_range(unsigned long start, unsigned long end)
176{
177 struct ipi_flush flush = { start, end };
178 preempt_disable();
179 on_each_cpu(ipi_flush_icache_range, &flush, 1);
180 preempt_enable();
181}
182
183
184/* Called when smp_send_reschedule() triggers IRQ_RESCHEDULE. */
185static irqreturn_t handle_reschedule_ipi(int irq, void *token)
186{
187 /*
188 * Nothing to do here; when we return from interrupt, the
189 * rescheduling will occur there. But do bump the interrupt
190 * profiler count in the meantime.
191 */
192 __get_cpu_var(irq_stat).irq_resched_count++;
193
194 return IRQ_HANDLED;
195}
196
197static struct irqaction resched_action = {
198 .handler = handle_reschedule_ipi,
199 .name = "resched",
200 .dev_id = handle_reschedule_ipi /* unique token */,
201};
202
203void __init ipi_init(void)
204{
205#if CHIP_HAS_IPI()
206 int cpu;
207 /* Map IPI trigger MMIO addresses. */
208 for_each_possible_cpu(cpu) {
209 HV_Coord tile;
210 HV_PTE pte;
211 unsigned long offset;
212
213 tile.x = cpu_x(cpu);
214 tile.y = cpu_y(cpu);
215 if (hv_get_ipi_pte(tile, 1, &pte) != 0)
216 panic("Failed to initialize IPI for cpu %d\n", cpu);
217
218 offset = hv_pte_get_pfn(pte) << PAGE_SHIFT;
219 ipi_mappings[cpu] = ioremap_prot(offset, PAGE_SIZE, pte);
220 }
221#endif
222
223 /* Bind handle_reschedule_ipi() to IRQ_RESCHEDULE. */
224 tile_irq_activate(IRQ_RESCHEDULE, TILE_IRQ_PERCPU);
225 BUG_ON(setup_irq(IRQ_RESCHEDULE, &resched_action));
226}
227
228#if CHIP_HAS_IPI()
229
230void smp_send_reschedule(int cpu)
231{
232 WARN_ON(cpu_is_offline(cpu));
233
234 /*
235 * We just want to do an MMIO store. The traditional writeq()
236 * functions aren't really correct here, since they're always
237 * directed at the PCI shim. For now, just do a raw store,
238 * casting away the __iomem attribute.
239 */
240 ((unsigned long __force *)ipi_mappings[cpu])[IRQ_RESCHEDULE] = 0;
241}
242
243#else
244
245void smp_send_reschedule(int cpu)
246{
247 HV_Coord coord;
248
249 WARN_ON(cpu_is_offline(cpu));
250
251 coord.y = cpu_y(cpu);
252 coord.x = cpu_x(cpu);
253 hv_trigger_ipi(coord, IRQ_RESCHEDULE);
254}
255
256#endif /* CHIP_HAS_IPI() */
diff --git a/arch/tile/kernel/smpboot.c b/arch/tile/kernel/smpboot.c
new file mode 100644
index 000000000000..74d62d098edf
--- /dev/null
+++ b/arch/tile/kernel/smpboot.c
@@ -0,0 +1,278 @@
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#include <linux/module.h>
16#include <linux/init.h>
17#include <linux/kernel.h>
18#include <linux/mm.h>
19#include <linux/sched.h>
20#include <linux/kernel_stat.h>
21#include <linux/smp_lock.h>
22#include <linux/bootmem.h>
23#include <linux/notifier.h>
24#include <linux/cpu.h>
25#include <linux/percpu.h>
26#include <linux/delay.h>
27#include <linux/err.h>
28#include <linux/irq.h>
29#include <asm/mmu_context.h>
30#include <asm/tlbflush.h>
31#include <asm/sections.h>
32
33/* State of each CPU. */
34static DEFINE_PER_CPU(int, cpu_state) = { 0 };
35
36/* The messaging code jumps to this pointer during boot-up */
37unsigned long start_cpu_function_addr;
38
39/* Called very early during startup to mark boot cpu as online */
40void __init smp_prepare_boot_cpu(void)
41{
42 int cpu = smp_processor_id();
43 set_cpu_online(cpu, 1);
44 set_cpu_present(cpu, 1);
45 __get_cpu_var(cpu_state) = CPU_ONLINE;
46
47 init_messaging();
48}
49
50static void start_secondary(void);
51
52/*
53 * Called at the top of init() to launch all the other CPUs.
54 * They run free to complete their initialization and then wait
55 * until they get an IPI from the boot cpu to come online.
56 */
57void __init smp_prepare_cpus(unsigned int max_cpus)
58{
59 long rc;
60 int cpu, cpu_count;
61 int boot_cpu = smp_processor_id();
62
63 current_thread_info()->cpu = boot_cpu;
64
65 /*
66 * Pin this task to the boot CPU while we bring up the others,
67 * just to make sure we don't uselessly migrate as they come up.
68 */
69 rc = sched_setaffinity(current->pid, cpumask_of(boot_cpu));
70 if (rc != 0)
71 pr_err("Couldn't set init affinity to boot cpu (%ld)\n", rc);
72
73 /* Print information about disabled and dataplane cpus. */
74 print_disabled_cpus();
75
76 /*
77 * Tell the messaging subsystem how to respond to the
78 * startup message. We use a level of indirection to avoid
79 * confusing the linker with the fact that the messaging
80 * subsystem is calling __init code.
81 */
82 start_cpu_function_addr = (unsigned long) &online_secondary;
83
84 /* Set up thread context for all new processors. */
85 cpu_count = 1;
86 for (cpu = 0; cpu < NR_CPUS; ++cpu) {
87 struct task_struct *idle;
88
89 if (cpu == boot_cpu)
90 continue;
91
92 if (!cpu_possible(cpu)) {
93 /*
94 * Make this processor do nothing on boot.
95 * Note that we don't give the boot_pc function
96 * a stack, so it has to be assembly code.
97 */
98 per_cpu(boot_sp, cpu) = 0;
99 per_cpu(boot_pc, cpu) = (unsigned long) smp_nap;
100 continue;
101 }
102
103 /* Create a new idle thread to run start_secondary() */
104 idle = fork_idle(cpu);
105 if (IS_ERR(idle))
106 panic("failed fork for CPU %d", cpu);
107 idle->thread.pc = (unsigned long) start_secondary;
108
109 /* Make this thread the boot thread for this processor */
110 per_cpu(boot_sp, cpu) = task_ksp0(idle);
111 per_cpu(boot_pc, cpu) = idle->thread.pc;
112
113 ++cpu_count;
114 }
115 BUG_ON(cpu_count > (max_cpus ? max_cpus : 1));
116
117 /* Fire up the other tiles, if any */
118 init_cpu_present(cpu_possible_mask);
119 if (cpumask_weight(cpu_present_mask) > 1) {
120 mb(); /* make sure all data is visible to new processors */
121 hv_start_all_tiles();
122 }
123}
124
125static __initdata struct cpumask init_affinity;
126
127static __init int reset_init_affinity(void)
128{
129 long rc = sched_setaffinity(current->pid, &init_affinity);
130 if (rc != 0)
131 pr_warning("couldn't reset init affinity (%ld)\n",
132 rc);
133 return 0;
134}
135late_initcall(reset_init_affinity);
136
137static struct cpumask cpu_started __cpuinitdata;
138
139/*
140 * Activate a secondary processor. Very minimal; don't add anything
141 * to this path without knowing what you're doing, since SMP booting
142 * is pretty fragile.
143 */
144static void __cpuinit start_secondary(void)
145{
146 int cpuid = smp_processor_id();
147
148 /* Set our thread pointer appropriately. */
149 set_my_cpu_offset(__per_cpu_offset[cpuid]);
150
151 preempt_disable();
152
153 /*
154 * In large machines even this will slow us down, since we
155 * will be contending for for the printk spinlock.
156 */
157 /* printk(KERN_DEBUG "Initializing CPU#%d\n", cpuid); */
158
159 /* Initialize the current asid for our first page table. */
160 __get_cpu_var(current_asid) = min_asid;
161
162 /* Set up this thread as another owner of the init_mm */
163 atomic_inc(&init_mm.mm_count);
164 current->active_mm = &init_mm;
165 if (current->mm)
166 BUG();
167 enter_lazy_tlb(&init_mm, current);
168
169 /* Allow hypervisor messages to be received */
170 init_messaging();
171 local_irq_enable();
172
173 /* Indicate that we're ready to come up. */
174 /* Must not do this before we're ready to receive messages */
175 if (cpumask_test_and_set_cpu(cpuid, &cpu_started)) {
176 pr_warning("CPU#%d already started!\n", cpuid);
177 for (;;)
178 local_irq_enable();
179 }
180
181 smp_nap();
182}
183
184/*
185 * Bring a secondary processor online.
186 */
187void __cpuinit online_secondary(void)
188{
189 /*
190 * low-memory mappings have been cleared, flush them from
191 * the local TLBs too.
192 */
193 local_flush_tlb();
194
195 BUG_ON(in_interrupt());
196
197 /* This must be done before setting cpu_online_mask */
198 wmb();
199
200 /*
201 * We need to hold call_lock, so there is no inconsistency
202 * between the time smp_call_function() determines number of
203 * IPI recipients, and the time when the determination is made
204 * for which cpus receive the IPI. Holding this
205 * lock helps us to not include this cpu in a currently in progress
206 * smp_call_function().
207 */
208 ipi_call_lock();
209 set_cpu_online(smp_processor_id(), 1);
210 ipi_call_unlock();
211 __get_cpu_var(cpu_state) = CPU_ONLINE;
212
213 /* Set up tile-specific state for this cpu. */
214 setup_cpu(0);
215
216 /* Set up tile-timer clock-event device on this cpu */
217 setup_tile_timer();
218
219 preempt_enable();
220
221 cpu_idle();
222}
223
224int __cpuinit __cpu_up(unsigned int cpu)
225{
226 /* Wait 5s total for all CPUs for them to come online */
227 static int timeout;
228 for (; !cpumask_test_cpu(cpu, &cpu_started); timeout++) {
229 if (timeout >= 50000) {
230 pr_info("skipping unresponsive cpu%d\n", cpu);
231 local_irq_enable();
232 return -EIO;
233 }
234 udelay(100);
235 }
236
237 local_irq_enable();
238 per_cpu(cpu_state, cpu) = CPU_UP_PREPARE;
239
240 /* Unleash the CPU! */
241 send_IPI_single(cpu, MSG_TAG_START_CPU);
242 while (!cpumask_test_cpu(cpu, cpu_online_mask))
243 cpu_relax();
244 return 0;
245}
246
247static void panic_start_cpu(void)
248{
249 panic("Received a MSG_START_CPU IPI after boot finished.");
250}
251
252void __init smp_cpus_done(unsigned int max_cpus)
253{
254 int cpu, next, rc;
255
256 /* Reset the response to a (now illegal) MSG_START_CPU IPI. */
257 start_cpu_function_addr = (unsigned long) &panic_start_cpu;
258
259 cpumask_copy(&init_affinity, cpu_online_mask);
260
261 /*
262 * Pin ourselves to a single cpu in the initial affinity set
263 * so that kernel mappings for the rootfs are not in the dataplane,
264 * if set, and to avoid unnecessary migrating during bringup.
265 * Use the last cpu just in case the whole chip has been
266 * isolated from the scheduler, to keep init away from likely
267 * more useful user code. This also ensures that work scheduled
268 * via schedule_delayed_work() in the init routines will land
269 * on this cpu.
270 */
271 for (cpu = cpumask_first(&init_affinity);
272 (next = cpumask_next(cpu, &init_affinity)) < nr_cpu_ids;
273 cpu = next)
274 ;
275 rc = sched_setaffinity(current->pid, cpumask_of(cpu));
276 if (rc != 0)
277 pr_err("Couldn't set init affinity to cpu %d (%d)\n", cpu, rc);
278}
diff --git a/arch/tile/kernel/stack.c b/arch/tile/kernel/stack.c
new file mode 100644
index 000000000000..38a68b0b4581
--- /dev/null
+++ b/arch/tile/kernel/stack.c
@@ -0,0 +1,478 @@
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#include <linux/sched.h>
16#include <linux/kernel.h>
17#include <linux/kprobes.h>
18#include <linux/module.h>
19#include <linux/pfn.h>
20#include <linux/kallsyms.h>
21#include <linux/stacktrace.h>
22#include <linux/uaccess.h>
23#include <linux/mmzone.h>
24#include <asm/backtrace.h>
25#include <asm/page.h>
26#include <asm/tlbflush.h>
27#include <asm/ucontext.h>
28#include <asm/sigframe.h>
29#include <asm/stack.h>
30#include <arch/abi.h>
31#include <arch/interrupts.h>
32
33
34/* Is address on the specified kernel stack? */
35static int in_kernel_stack(struct KBacktraceIterator *kbt, VirtualAddress sp)
36{
37 ulong kstack_base = (ulong) kbt->task->stack;
38 if (kstack_base == 0) /* corrupt task pointer; just follow stack... */
39 return sp >= PAGE_OFFSET && sp < (unsigned long)high_memory;
40 return sp >= kstack_base && sp < kstack_base + THREAD_SIZE;
41}
42
43/* Is address in the specified kernel code? */
44static int in_kernel_text(VirtualAddress address)
45{
46 return (address >= MEM_SV_INTRPT &&
47 address < MEM_SV_INTRPT + HPAGE_SIZE);
48}
49
50/* Is address valid for reading? */
51static int valid_address(struct KBacktraceIterator *kbt, VirtualAddress address)
52{
53 HV_PTE *l1_pgtable = kbt->pgtable;
54 HV_PTE *l2_pgtable;
55 unsigned long pfn;
56 HV_PTE pte;
57 struct page *page;
58
59 if (l1_pgtable == NULL)
60 return 0; /* can't read user space in other tasks */
61
62 pte = l1_pgtable[HV_L1_INDEX(address)];
63 if (!hv_pte_get_present(pte))
64 return 0;
65 pfn = hv_pte_get_pfn(pte);
66 if (pte_huge(pte)) {
67 if (!pfn_valid(pfn)) {
68 pr_err("huge page has bad pfn %#lx\n", pfn);
69 return 0;
70 }
71 return hv_pte_get_present(pte) && hv_pte_get_readable(pte);
72 }
73
74 page = pfn_to_page(pfn);
75 if (PageHighMem(page)) {
76 pr_err("L2 page table not in LOWMEM (%#llx)\n",
77 HV_PFN_TO_CPA(pfn));
78 return 0;
79 }
80 l2_pgtable = (HV_PTE *)pfn_to_kaddr(pfn);
81 pte = l2_pgtable[HV_L2_INDEX(address)];
82 return hv_pte_get_present(pte) && hv_pte_get_readable(pte);
83}
84
85/* Callback for backtracer; basically a glorified memcpy */
86static bool read_memory_func(void *result, VirtualAddress address,
87 unsigned int size, void *vkbt)
88{
89 int retval;
90 struct KBacktraceIterator *kbt = (struct KBacktraceIterator *)vkbt;
91 if (in_kernel_text(address)) {
92 /* OK to read kernel code. */
93 } else if (address >= PAGE_OFFSET) {
94 /* We only tolerate kernel-space reads of this task's stack */
95 if (!in_kernel_stack(kbt, address))
96 return 0;
97 } else if (!valid_address(kbt, address)) {
98 return 0; /* invalid user-space address */
99 }
100 pagefault_disable();
101 retval = __copy_from_user_inatomic(result,
102 (void __user __force *)address,
103 size);
104 pagefault_enable();
105 return (retval == 0);
106}
107
108/* Return a pt_regs pointer for a valid fault handler frame */
109static struct pt_regs *valid_fault_handler(struct KBacktraceIterator* kbt)
110{
111 const char *fault = NULL; /* happy compiler */
112 char fault_buf[64];
113 VirtualAddress sp = kbt->it.sp;
114 struct pt_regs *p;
115
116 if (!in_kernel_stack(kbt, sp))
117 return NULL;
118 if (!in_kernel_stack(kbt, sp + C_ABI_SAVE_AREA_SIZE + PTREGS_SIZE-1))
119 return NULL;
120 p = (struct pt_regs *)(sp + C_ABI_SAVE_AREA_SIZE);
121 if (p->faultnum == INT_SWINT_1 || p->faultnum == INT_SWINT_1_SIGRETURN)
122 fault = "syscall";
123 else {
124 if (kbt->verbose) { /* else we aren't going to use it */
125 snprintf(fault_buf, sizeof(fault_buf),
126 "interrupt %ld", p->faultnum);
127 fault = fault_buf;
128 }
129 }
130 if (EX1_PL(p->ex1) == KERNEL_PL &&
131 in_kernel_text(p->pc) &&
132 in_kernel_stack(kbt, p->sp) &&
133 p->sp >= sp) {
134 if (kbt->verbose)
135 pr_err(" <%s while in kernel mode>\n", fault);
136 } else if (EX1_PL(p->ex1) == USER_PL &&
137 p->pc < PAGE_OFFSET &&
138 p->sp < PAGE_OFFSET) {
139 if (kbt->verbose)
140 pr_err(" <%s while in user mode>\n", fault);
141 } else if (kbt->verbose) {
142 pr_err(" (odd fault: pc %#lx, sp %#lx, ex1 %#lx?)\n",
143 p->pc, p->sp, p->ex1);
144 p = NULL;
145 }
146 if (!kbt->profile || (INT_MASK(p->faultnum) & QUEUED_INTERRUPTS) == 0)
147 return p;
148 return NULL;
149}
150
151/* Is the pc pointing to a sigreturn trampoline? */
152static int is_sigreturn(VirtualAddress pc)
153{
154 return (pc == VDSO_BASE);
155}
156
157/* Return a pt_regs pointer for a valid signal handler frame */
158static struct pt_regs *valid_sigframe(struct KBacktraceIterator* kbt)
159{
160 BacktraceIterator *b = &kbt->it;
161
162 if (b->pc == VDSO_BASE) {
163 struct rt_sigframe *frame;
164 unsigned long sigframe_top =
165 b->sp + sizeof(struct rt_sigframe) - 1;
166 if (!valid_address(kbt, b->sp) ||
167 !valid_address(kbt, sigframe_top)) {
168 if (kbt->verbose)
169 pr_err(" (odd signal: sp %#lx?)\n",
170 (unsigned long)(b->sp));
171 return NULL;
172 }
173 frame = (struct rt_sigframe *)b->sp;
174 if (kbt->verbose) {
175 pr_err(" <received signal %d>\n",
176 frame->info.si_signo);
177 }
178 return &frame->uc.uc_mcontext.regs;
179 }
180 return NULL;
181}
182
183static int KBacktraceIterator_is_sigreturn(struct KBacktraceIterator *kbt)
184{
185 return is_sigreturn(kbt->it.pc);
186}
187
188static int KBacktraceIterator_restart(struct KBacktraceIterator *kbt)
189{
190 struct pt_regs *p;
191
192 p = valid_fault_handler(kbt);
193 if (p == NULL)
194 p = valid_sigframe(kbt);
195 if (p == NULL)
196 return 0;
197 backtrace_init(&kbt->it, read_memory_func, kbt,
198 p->pc, p->lr, p->sp, p->regs[52]);
199 kbt->new_context = 1;
200 return 1;
201}
202
203/* Find a frame that isn't a sigreturn, if there is one. */
204static int KBacktraceIterator_next_item_inclusive(
205 struct KBacktraceIterator *kbt)
206{
207 for (;;) {
208 do {
209 if (!KBacktraceIterator_is_sigreturn(kbt))
210 return 1;
211 } while (backtrace_next(&kbt->it));
212
213 if (!KBacktraceIterator_restart(kbt))
214 return 0;
215 }
216}
217
218/*
219 * If the current sp is on a page different than what we recorded
220 * as the top-of-kernel-stack last time we context switched, we have
221 * probably blown the stack, and nothing is going to work out well.
222 * If we can at least get out a warning, that may help the debug,
223 * though we probably won't be able to backtrace into the code that
224 * actually did the recursive damage.
225 */
226static void validate_stack(struct pt_regs *regs)
227{
228 int cpu = smp_processor_id();
229 unsigned long ksp0 = get_current_ksp0();
230 unsigned long ksp0_base = ksp0 - THREAD_SIZE;
231 unsigned long sp = stack_pointer;
232
233 if (EX1_PL(regs->ex1) == KERNEL_PL && regs->sp >= ksp0) {
234 pr_err("WARNING: cpu %d: kernel stack page %#lx underrun!\n"
235 " sp %#lx (%#lx in caller), caller pc %#lx, lr %#lx\n",
236 cpu, ksp0_base, sp, regs->sp, regs->pc, regs->lr);
237 }
238
239 else if (sp < ksp0_base + sizeof(struct thread_info)) {
240 pr_err("WARNING: cpu %d: kernel stack page %#lx overrun!\n"
241 " sp %#lx (%#lx in caller), caller pc %#lx, lr %#lx\n",
242 cpu, ksp0_base, sp, regs->sp, regs->pc, regs->lr);
243 }
244}
245
246void KBacktraceIterator_init(struct KBacktraceIterator *kbt,
247 struct task_struct *t, struct pt_regs *regs)
248{
249 VirtualAddress pc, lr, sp, r52;
250 int is_current;
251
252 /*
253 * Set up callback information. We grab the kernel stack base
254 * so we will allow reads of that address range, and if we're
255 * asking about the current process we grab the page table
256 * so we can check user accesses before trying to read them.
257 * We flush the TLB to avoid any weird skew issues.
258 */
259 is_current = (t == NULL);
260 kbt->is_current = is_current;
261 if (is_current)
262 t = validate_current();
263 kbt->task = t;
264 kbt->pgtable = NULL;
265 kbt->verbose = 0; /* override in caller if desired */
266 kbt->profile = 0; /* override in caller if desired */
267 kbt->end = 0;
268 kbt->new_context = 0;
269 if (is_current) {
270 HV_PhysAddr pgdir_pa = hv_inquire_context().page_table;
271 if (pgdir_pa == (unsigned long)swapper_pg_dir - PAGE_OFFSET) {
272 /*
273 * Not just an optimization: this also allows
274 * this to work at all before va/pa mappings
275 * are set up.
276 */
277 kbt->pgtable = swapper_pg_dir;
278 } else {
279 struct page *page = pfn_to_page(PFN_DOWN(pgdir_pa));
280 if (!PageHighMem(page))
281 kbt->pgtable = __va(pgdir_pa);
282 else
283 pr_err("page table not in LOWMEM"
284 " (%#llx)\n", pgdir_pa);
285 }
286 local_flush_tlb_all();
287 validate_stack(regs);
288 }
289
290 if (regs == NULL) {
291 if (is_current || t->state == TASK_RUNNING) {
292 /* Can't do this; we need registers */
293 kbt->end = 1;
294 return;
295 }
296 pc = get_switch_to_pc();
297 lr = t->thread.pc;
298 sp = t->thread.ksp;
299 r52 = 0;
300 } else {
301 pc = regs->pc;
302 lr = regs->lr;
303 sp = regs->sp;
304 r52 = regs->regs[52];
305 }
306
307 backtrace_init(&kbt->it, read_memory_func, kbt, pc, lr, sp, r52);
308 kbt->end = !KBacktraceIterator_next_item_inclusive(kbt);
309}
310EXPORT_SYMBOL(KBacktraceIterator_init);
311
312int KBacktraceIterator_end(struct KBacktraceIterator *kbt)
313{
314 return kbt->end;
315}
316EXPORT_SYMBOL(KBacktraceIterator_end);
317
318void KBacktraceIterator_next(struct KBacktraceIterator *kbt)
319{
320 kbt->new_context = 0;
321 if (!backtrace_next(&kbt->it) &&
322 !KBacktraceIterator_restart(kbt)) {
323 kbt->end = 1;
324 return;
325 }
326
327 kbt->end = !KBacktraceIterator_next_item_inclusive(kbt);
328}
329EXPORT_SYMBOL(KBacktraceIterator_next);
330
331/*
332 * This method wraps the backtracer's more generic support.
333 * It is only invoked from the architecture-specific code; show_stack()
334 * and dump_stack() (in entry.S) are architecture-independent entry points.
335 */
336void tile_show_stack(struct KBacktraceIterator *kbt, int headers)
337{
338 int i;
339
340 if (headers) {
341 /*
342 * Add a blank line since if we are called from panic(),
343 * then bust_spinlocks() spit out a space in front of us
344 * and it will mess up our KERN_ERR.
345 */
346 pr_err("\n");
347 pr_err("Starting stack dump of tid %d, pid %d (%s)"
348 " on cpu %d at cycle %lld\n",
349 kbt->task->pid, kbt->task->tgid, kbt->task->comm,
350 smp_processor_id(), get_cycles());
351 }
352 kbt->verbose = 1;
353 i = 0;
354 for (; !KBacktraceIterator_end(kbt); KBacktraceIterator_next(kbt)) {
355 char *modname;
356 const char *name;
357 unsigned long address = kbt->it.pc;
358 unsigned long offset, size;
359 char namebuf[KSYM_NAME_LEN+100];
360
361 if (address >= PAGE_OFFSET)
362 name = kallsyms_lookup(address, &size, &offset,
363 &modname, namebuf);
364 else
365 name = NULL;
366
367 if (!name)
368 namebuf[0] = '\0';
369 else {
370 size_t namelen = strlen(namebuf);
371 size_t remaining = (sizeof(namebuf) - 1) - namelen;
372 char *p = namebuf + namelen;
373 int rc = snprintf(p, remaining, "+%#lx/%#lx ",
374 offset, size);
375 if (modname && rc < remaining)
376 snprintf(p + rc, remaining - rc,
377 "[%s] ", modname);
378 namebuf[sizeof(namebuf)-1] = '\0';
379 }
380
381 pr_err(" frame %d: 0x%lx %s(sp 0x%lx)\n",
382 i++, address, namebuf, (unsigned long)(kbt->it.sp));
383
384 if (i >= 100) {
385 pr_err("Stack dump truncated"
386 " (%d frames)\n", i);
387 break;
388 }
389 }
390 if (headers)
391 pr_err("Stack dump complete\n");
392}
393EXPORT_SYMBOL(tile_show_stack);
394
395
396/* This is called from show_regs() and _dump_stack() */
397void dump_stack_regs(struct pt_regs *regs)
398{
399 struct KBacktraceIterator kbt;
400 KBacktraceIterator_init(&kbt, NULL, regs);
401 tile_show_stack(&kbt, 1);
402}
403EXPORT_SYMBOL(dump_stack_regs);
404
405static struct pt_regs *regs_to_pt_regs(struct pt_regs *regs,
406 ulong pc, ulong lr, ulong sp, ulong r52)
407{
408 memset(regs, 0, sizeof(struct pt_regs));
409 regs->pc = pc;
410 regs->lr = lr;
411 regs->sp = sp;
412 regs->regs[52] = r52;
413 return regs;
414}
415
416/* This is called from dump_stack() and just converts to pt_regs */
417void _dump_stack(int dummy, ulong pc, ulong lr, ulong sp, ulong r52)
418{
419 struct pt_regs regs;
420 dump_stack_regs(regs_to_pt_regs(&regs, pc, lr, sp, r52));
421}
422
423/* This is called from KBacktraceIterator_init_current() */
424void _KBacktraceIterator_init_current(struct KBacktraceIterator *kbt, ulong pc,
425 ulong lr, ulong sp, ulong r52)
426{
427 struct pt_regs regs;
428 KBacktraceIterator_init(kbt, NULL,
429 regs_to_pt_regs(&regs, pc, lr, sp, r52));
430}
431
432/* This is called only from kernel/sched.c, with esp == NULL */
433void show_stack(struct task_struct *task, unsigned long *esp)
434{
435 struct KBacktraceIterator kbt;
436 if (task == NULL || task == current)
437 KBacktraceIterator_init_current(&kbt);
438 else
439 KBacktraceIterator_init(&kbt, task, NULL);
440 tile_show_stack(&kbt, 0);
441}
442
443#ifdef CONFIG_STACKTRACE
444
445/* Support generic Linux stack API too */
446
447void save_stack_trace_tsk(struct task_struct *task, struct stack_trace *trace)
448{
449 struct KBacktraceIterator kbt;
450 int skip = trace->skip;
451 int i = 0;
452
453 if (task == NULL || task == current)
454 KBacktraceIterator_init_current(&kbt);
455 else
456 KBacktraceIterator_init(&kbt, task, NULL);
457 for (; !KBacktraceIterator_end(&kbt); KBacktraceIterator_next(&kbt)) {
458 if (skip) {
459 --skip;
460 continue;
461 }
462 if (i >= trace->max_entries || kbt.it.pc < PAGE_OFFSET)
463 break;
464 trace->entries[i++] = kbt.it.pc;
465 }
466 trace->nr_entries = i;
467}
468EXPORT_SYMBOL(save_stack_trace_tsk);
469
470void save_stack_trace(struct stack_trace *trace)
471{
472 save_stack_trace_tsk(NULL, trace);
473}
474
475#endif
476
477/* In entry.S */
478EXPORT_SYMBOL(KBacktraceIterator_init_current);
diff --git a/arch/tile/kernel/sys.c b/arch/tile/kernel/sys.c
new file mode 100644
index 000000000000..f0f87eab8c39
--- /dev/null
+++ b/arch/tile/kernel/sys.c
@@ -0,0 +1,120 @@
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 * This file contains various random system calls that
15 * have a non-standard calling sequence on the Linux/TILE
16 * platform.
17 */
18
19#include <linux/errno.h>
20#include <linux/sched.h>
21#include <linux/mm.h>
22#include <linux/smp.h>
23#include <linux/smp_lock.h>
24#include <linux/syscalls.h>
25#include <linux/mman.h>
26#include <linux/file.h>
27#include <linux/mempolicy.h>
28#include <linux/binfmts.h>
29#include <linux/fs.h>
30#include <linux/compat.h>
31#include <linux/uaccess.h>
32#include <linux/signal.h>
33#include <asm/syscalls.h>
34#include <asm/pgtable.h>
35#include <asm/homecache.h>
36#include <arch/chip.h>
37
38SYSCALL_DEFINE0(flush_cache)
39{
40 homecache_evict(cpumask_of(smp_processor_id()));
41 return 0;
42}
43
44/*
45 * Syscalls that pass 64-bit values on 32-bit systems normally
46 * pass them as (low,high) word packed into the immediately adjacent
47 * registers. If the low word naturally falls on an even register,
48 * our ABI makes it work correctly; if not, we adjust it here.
49 * Handling it here means we don't have to fix uclibc AND glibc AND
50 * any other standard libcs we want to support.
51 */
52
53#if !defined(__tilegx__) || defined(CONFIG_COMPAT)
54
55ssize_t sys32_readahead(int fd, u32 offset_lo, u32 offset_hi, u32 count)
56{
57 return sys_readahead(fd, ((loff_t)offset_hi << 32) | offset_lo, count);
58}
59
60long sys32_fadvise64(int fd, u32 offset_lo, u32 offset_hi,
61 u32 len, int advice)
62{
63 return sys_fadvise64_64(fd, ((loff_t)offset_hi << 32) | offset_lo,
64 len, advice);
65}
66
67int sys32_fadvise64_64(int fd, u32 offset_lo, u32 offset_hi,
68 u32 len_lo, u32 len_hi, int advice)
69{
70 return sys_fadvise64_64(fd, ((loff_t)offset_hi << 32) | offset_lo,
71 ((loff_t)len_hi << 32) | len_lo, advice);
72}
73
74#endif /* 32-bit syscall wrappers */
75
76/* Note: used by the compat code even in 64-bit Linux. */
77SYSCALL_DEFINE6(mmap2, unsigned long, addr, unsigned long, len,
78 unsigned long, prot, unsigned long, flags,
79 unsigned long, fd, unsigned long, off_4k)
80{
81#define PAGE_ADJUST (PAGE_SHIFT - 12)
82 if (off_4k & ((1 << PAGE_ADJUST) - 1))
83 return -EINVAL;
84 return sys_mmap_pgoff(addr, len, prot, flags, fd,
85 off_4k >> PAGE_ADJUST);
86}
87
88#ifdef __tilegx__
89SYSCALL_DEFINE6(mmap, unsigned long, addr, unsigned long, len,
90 unsigned long, prot, unsigned long, flags,
91 unsigned long, fd, off_t, offset)
92{
93 if (offset & ((1 << PAGE_SHIFT) - 1))
94 return -EINVAL;
95 return sys_mmap_pgoff(addr, len, prot, flags, fd,
96 offset >> PAGE_SHIFT);
97}
98#endif
99
100
101/* Provide the actual syscall number to call mapping. */
102#undef __SYSCALL
103#define __SYSCALL(nr, call) [nr] = (call),
104
105#ifndef __tilegx__
106/* See comments at the top of the file. */
107#define sys_fadvise64 sys32_fadvise64
108#define sys_fadvise64_64 sys32_fadvise64_64
109#define sys_readahead sys32_readahead
110#define sys_sync_file_range sys_sync_file_range2
111#endif
112
113/*
114 * Note that we can't include <linux/unistd.h> here since the header
115 * guard will defeat us; <asm/unistd.h> checks for __SYSCALL as well.
116 */
117void *sys_call_table[__NR_syscalls] = {
118 [0 ... __NR_syscalls-1] = sys_ni_syscall,
119#include <asm/unistd.h>
120};
diff --git a/arch/tile/kernel/tile-desc_32.c b/arch/tile/kernel/tile-desc_32.c
new file mode 100644
index 000000000000..69af0e150f78
--- /dev/null
+++ b/arch/tile/kernel/tile-desc_32.c
@@ -0,0 +1,2498 @@
1/* This define is BFD_RELOC_##x for real bfd, or -1 for everyone else. */
2#define BFD_RELOC(x) -1
3
4/* Special registers. */
5#define TREG_LR 55
6#define TREG_SN 56
7#define TREG_ZERO 63
8
9/* FIXME: Rename this. */
10#include <asm/opcode-tile.h>
11
12#include <linux/stddef.h>
13
14const struct tile_opcode tile_opcodes[395] =
15{
16 { "bpt", TILE_OPC_BPT, 0x2, 0, TREG_ZERO, 0,
17 { { 0, }, { }, { 0, }, { 0, }, { 0, } },
18 },
19 { "info", TILE_OPC_INFO, 0xf, 1, TREG_ZERO, 1,
20 { { 0 }, { 1 }, { 2 }, { 3 }, { 0, } },
21 },
22 { "infol", TILE_OPC_INFOL, 0x3, 1, TREG_ZERO, 1,
23 { { 4 }, { 5 }, { 0, }, { 0, }, { 0, } },
24 },
25 { "j", TILE_OPC_J, 0x2, 1, TREG_ZERO, 1,
26 { { 0, }, { 6 }, { 0, }, { 0, }, { 0, } },
27 },
28 { "jal", TILE_OPC_JAL, 0x2, 1, TREG_LR, 1,
29 { { 0, }, { 6 }, { 0, }, { 0, }, { 0, } },
30 },
31 { "move", TILE_OPC_MOVE, 0xf, 2, TREG_ZERO, 1,
32 { { 7, 8 }, { 9, 10 }, { 11, 12 }, { 13, 14 }, { 0, } },
33 },
34 { "move.sn", TILE_OPC_MOVE_SN, 0x3, 2, TREG_SN, 1,
35 { { 7, 8 }, { 9, 10 }, { 0, }, { 0, }, { 0, } },
36 },
37 { "movei", TILE_OPC_MOVEI, 0xf, 2, TREG_ZERO, 1,
38 { { 7, 0 }, { 9, 1 }, { 11, 2 }, { 13, 3 }, { 0, } },
39 },
40 { "movei.sn", TILE_OPC_MOVEI_SN, 0x3, 2, TREG_SN, 1,
41 { { 7, 0 }, { 9, 1 }, { 0, }, { 0, }, { 0, } },
42 },
43 { "moveli", TILE_OPC_MOVELI, 0x3, 2, TREG_ZERO, 1,
44 { { 7, 4 }, { 9, 5 }, { 0, }, { 0, }, { 0, } },
45 },
46 { "moveli.sn", TILE_OPC_MOVELI_SN, 0x3, 2, TREG_SN, 1,
47 { { 7, 4 }, { 9, 5 }, { 0, }, { 0, }, { 0, } },
48 },
49 { "movelis", TILE_OPC_MOVELIS, 0x3, 2, TREG_SN, 1,
50 { { 7, 4 }, { 9, 5 }, { 0, }, { 0, }, { 0, } },
51 },
52 { "prefetch", TILE_OPC_PREFETCH, 0x12, 1, TREG_ZERO, 1,
53 { { 0, }, { 10 }, { 0, }, { 0, }, { 15 } },
54 },
55 { "raise", TILE_OPC_RAISE, 0x2, 0, TREG_ZERO, 1,
56 { { 0, }, { }, { 0, }, { 0, }, { 0, } },
57 },
58 { "add", TILE_OPC_ADD, 0xf, 3, TREG_ZERO, 1,
59 { { 7, 8, 16 }, { 9, 10, 17 }, { 11, 12, 18 }, { 13, 14, 19 }, { 0, } },
60 },
61 { "add.sn", TILE_OPC_ADD_SN, 0x3, 3, TREG_SN, 1,
62 { { 7, 8, 16 }, { 9, 10, 17 }, { 0, }, { 0, }, { 0, } },
63 },
64 { "addb", TILE_OPC_ADDB, 0x3, 3, TREG_ZERO, 1,
65 { { 7, 8, 16 }, { 9, 10, 17 }, { 0, }, { 0, }, { 0, } },
66 },
67 { "addb.sn", TILE_OPC_ADDB_SN, 0x3, 3, TREG_SN, 1,
68 { { 7, 8, 16 }, { 9, 10, 17 }, { 0, }, { 0, }, { 0, } },
69 },
70 { "addbs_u", TILE_OPC_ADDBS_U, 0x3, 3, TREG_ZERO, 1,
71 { { 7, 8, 16 }, { 9, 10, 17 }, { 0, }, { 0, }, { 0, } },
72 },
73 { "addbs_u.sn", TILE_OPC_ADDBS_U_SN, 0x3, 3, TREG_SN, 1,
74 { { 7, 8, 16 }, { 9, 10, 17 }, { 0, }, { 0, }, { 0, } },
75 },
76 { "addh", TILE_OPC_ADDH, 0x3, 3, TREG_ZERO, 1,
77 { { 7, 8, 16 }, { 9, 10, 17 }, { 0, }, { 0, }, { 0, } },
78 },
79 { "addh.sn", TILE_OPC_ADDH_SN, 0x3, 3, TREG_SN, 1,
80 { { 7, 8, 16 }, { 9, 10, 17 }, { 0, }, { 0, }, { 0, } },
81 },
82 { "addhs", TILE_OPC_ADDHS, 0x3, 3, TREG_ZERO, 1,
83 { { 7, 8, 16 }, { 9, 10, 17 }, { 0, }, { 0, }, { 0, } },
84 },
85 { "addhs.sn", TILE_OPC_ADDHS_SN, 0x3, 3, TREG_SN, 1,
86 { { 7, 8, 16 }, { 9, 10, 17 }, { 0, }, { 0, }, { 0, } },
87 },
88 { "addi", TILE_OPC_ADDI, 0xf, 3, TREG_ZERO, 1,
89 { { 7, 8, 0 }, { 9, 10, 1 }, { 11, 12, 2 }, { 13, 14, 3 }, { 0, } },
90 },
91 { "addi.sn", TILE_OPC_ADDI_SN, 0x3, 3, TREG_SN, 1,
92 { { 7, 8, 0 }, { 9, 10, 1 }, { 0, }, { 0, }, { 0, } },
93 },
94 { "addib", TILE_OPC_ADDIB, 0x3, 3, TREG_ZERO, 1,
95 { { 7, 8, 0 }, { 9, 10, 1 }, { 0, }, { 0, }, { 0, } },
96 },
97 { "addib.sn", TILE_OPC_ADDIB_SN, 0x3, 3, TREG_SN, 1,
98 { { 7, 8, 0 }, { 9, 10, 1 }, { 0, }, { 0, }, { 0, } },
99 },
100 { "addih", TILE_OPC_ADDIH, 0x3, 3, TREG_ZERO, 1,
101 { { 7, 8, 0 }, { 9, 10, 1 }, { 0, }, { 0, }, { 0, } },
102 },
103 { "addih.sn", TILE_OPC_ADDIH_SN, 0x3, 3, TREG_SN, 1,
104 { { 7, 8, 0 }, { 9, 10, 1 }, { 0, }, { 0, }, { 0, } },
105 },
106 { "addli", TILE_OPC_ADDLI, 0x3, 3, TREG_ZERO, 1,
107 { { 7, 8, 4 }, { 9, 10, 5 }, { 0, }, { 0, }, { 0, } },
108 },
109 { "addli.sn", TILE_OPC_ADDLI_SN, 0x3, 3, TREG_SN, 1,
110 { { 7, 8, 4 }, { 9, 10, 5 }, { 0, }, { 0, }, { 0, } },
111 },
112 { "addlis", TILE_OPC_ADDLIS, 0x3, 3, TREG_SN, 1,
113 { { 7, 8, 4 }, { 9, 10, 5 }, { 0, }, { 0, }, { 0, } },
114 },
115 { "adds", TILE_OPC_ADDS, 0x3, 3, TREG_ZERO, 1,
116 { { 7, 8, 16 }, { 9, 10, 17 }, { 0, }, { 0, }, { 0, } },
117 },
118 { "adds.sn", TILE_OPC_ADDS_SN, 0x3, 3, TREG_SN, 1,
119 { { 7, 8, 16 }, { 9, 10, 17 }, { 0, }, { 0, }, { 0, } },
120 },
121 { "adiffb_u", TILE_OPC_ADIFFB_U, 0x1, 3, TREG_ZERO, 1,
122 { { 7, 8, 16 }, { 0, }, { 0, }, { 0, }, { 0, } },
123 },
124 { "adiffb_u.sn", TILE_OPC_ADIFFB_U_SN, 0x1, 3, TREG_SN, 1,
125 { { 7, 8, 16 }, { 0, }, { 0, }, { 0, }, { 0, } },
126 },
127 { "adiffh", TILE_OPC_ADIFFH, 0x1, 3, TREG_ZERO, 1,
128 { { 7, 8, 16 }, { 0, }, { 0, }, { 0, }, { 0, } },
129 },
130 { "adiffh.sn", TILE_OPC_ADIFFH_SN, 0x1, 3, TREG_SN, 1,
131 { { 7, 8, 16 }, { 0, }, { 0, }, { 0, }, { 0, } },
132 },
133 { "and", TILE_OPC_AND, 0xf, 3, TREG_ZERO, 1,
134 { { 7, 8, 16 }, { 9, 10, 17 }, { 11, 12, 18 }, { 13, 14, 19 }, { 0, } },
135 },
136 { "and.sn", TILE_OPC_AND_SN, 0x3, 3, TREG_SN, 1,
137 { { 7, 8, 16 }, { 9, 10, 17 }, { 0, }, { 0, }, { 0, } },
138 },
139 { "andi", TILE_OPC_ANDI, 0xf, 3, TREG_ZERO, 1,
140 { { 7, 8, 0 }, { 9, 10, 1 }, { 11, 12, 2 }, { 13, 14, 3 }, { 0, } },
141 },
142 { "andi.sn", TILE_OPC_ANDI_SN, 0x3, 3, TREG_SN, 1,
143 { { 7, 8, 0 }, { 9, 10, 1 }, { 0, }, { 0, }, { 0, } },
144 },
145 { "auli", TILE_OPC_AULI, 0x3, 3, TREG_ZERO, 1,
146 { { 7, 8, 4 }, { 9, 10, 5 }, { 0, }, { 0, }, { 0, } },
147 },
148 { "avgb_u", TILE_OPC_AVGB_U, 0x1, 3, TREG_ZERO, 1,
149 { { 7, 8, 16 }, { 0, }, { 0, }, { 0, }, { 0, } },
150 },
151 { "avgb_u.sn", TILE_OPC_AVGB_U_SN, 0x1, 3, TREG_SN, 1,
152 { { 7, 8, 16 }, { 0, }, { 0, }, { 0, }, { 0, } },
153 },
154 { "avgh", TILE_OPC_AVGH, 0x1, 3, TREG_ZERO, 1,
155 { { 7, 8, 16 }, { 0, }, { 0, }, { 0, }, { 0, } },
156 },
157 { "avgh.sn", TILE_OPC_AVGH_SN, 0x1, 3, TREG_SN, 1,
158 { { 7, 8, 16 }, { 0, }, { 0, }, { 0, }, { 0, } },
159 },
160 { "bbns", TILE_OPC_BBNS, 0x2, 2, TREG_ZERO, 1,
161 { { 0, }, { 10, 20 }, { 0, }, { 0, }, { 0, } },
162 },
163 { "bbns.sn", TILE_OPC_BBNS_SN, 0x2, 2, TREG_SN, 1,
164 { { 0, }, { 10, 20 }, { 0, }, { 0, }, { 0, } },
165 },
166 { "bbnst", TILE_OPC_BBNST, 0x2, 2, TREG_ZERO, 1,
167 { { 0, }, { 10, 20 }, { 0, }, { 0, }, { 0, } },
168 },
169 { "bbnst.sn", TILE_OPC_BBNST_SN, 0x2, 2, TREG_SN, 1,
170 { { 0, }, { 10, 20 }, { 0, }, { 0, }, { 0, } },
171 },
172 { "bbs", TILE_OPC_BBS, 0x2, 2, TREG_ZERO, 1,
173 { { 0, }, { 10, 20 }, { 0, }, { 0, }, { 0, } },
174 },
175 { "bbs.sn", TILE_OPC_BBS_SN, 0x2, 2, TREG_SN, 1,
176 { { 0, }, { 10, 20 }, { 0, }, { 0, }, { 0, } },
177 },
178 { "bbst", TILE_OPC_BBST, 0x2, 2, TREG_ZERO, 1,
179 { { 0, }, { 10, 20 }, { 0, }, { 0, }, { 0, } },
180 },
181 { "bbst.sn", TILE_OPC_BBST_SN, 0x2, 2, TREG_SN, 1,
182 { { 0, }, { 10, 20 }, { 0, }, { 0, }, { 0, } },
183 },
184 { "bgez", TILE_OPC_BGEZ, 0x2, 2, TREG_ZERO, 1,
185 { { 0, }, { 10, 20 }, { 0, }, { 0, }, { 0, } },
186 },
187 { "bgez.sn", TILE_OPC_BGEZ_SN, 0x2, 2, TREG_SN, 1,
188 { { 0, }, { 10, 20 }, { 0, }, { 0, }, { 0, } },
189 },
190 { "bgezt", TILE_OPC_BGEZT, 0x2, 2, TREG_ZERO, 1,
191 { { 0, }, { 10, 20 }, { 0, }, { 0, }, { 0, } },
192 },
193 { "bgezt.sn", TILE_OPC_BGEZT_SN, 0x2, 2, TREG_SN, 1,
194 { { 0, }, { 10, 20 }, { 0, }, { 0, }, { 0, } },
195 },
196 { "bgz", TILE_OPC_BGZ, 0x2, 2, TREG_ZERO, 1,
197 { { 0, }, { 10, 20 }, { 0, }, { 0, }, { 0, } },
198 },
199 { "bgz.sn", TILE_OPC_BGZ_SN, 0x2, 2, TREG_SN, 1,
200 { { 0, }, { 10, 20 }, { 0, }, { 0, }, { 0, } },
201 },
202 { "bgzt", TILE_OPC_BGZT, 0x2, 2, TREG_ZERO, 1,
203 { { 0, }, { 10, 20 }, { 0, }, { 0, }, { 0, } },
204 },
205 { "bgzt.sn", TILE_OPC_BGZT_SN, 0x2, 2, TREG_SN, 1,
206 { { 0, }, { 10, 20 }, { 0, }, { 0, }, { 0, } },
207 },
208 { "bitx", TILE_OPC_BITX, 0x5, 2, TREG_ZERO, 1,
209 { { 7, 8 }, { 0, }, { 11, 12 }, { 0, }, { 0, } },
210 },
211 { "bitx.sn", TILE_OPC_BITX_SN, 0x1, 2, TREG_SN, 1,
212 { { 7, 8 }, { 0, }, { 0, }, { 0, }, { 0, } },
213 },
214 { "blez", TILE_OPC_BLEZ, 0x2, 2, TREG_ZERO, 1,
215 { { 0, }, { 10, 20 }, { 0, }, { 0, }, { 0, } },
216 },
217 { "blez.sn", TILE_OPC_BLEZ_SN, 0x2, 2, TREG_SN, 1,
218 { { 0, }, { 10, 20 }, { 0, }, { 0, }, { 0, } },
219 },
220 { "blezt", TILE_OPC_BLEZT, 0x2, 2, TREG_ZERO, 1,
221 { { 0, }, { 10, 20 }, { 0, }, { 0, }, { 0, } },
222 },
223 { "blezt.sn", TILE_OPC_BLEZT_SN, 0x2, 2, TREG_SN, 1,
224 { { 0, }, { 10, 20 }, { 0, }, { 0, }, { 0, } },
225 },
226 { "blz", TILE_OPC_BLZ, 0x2, 2, TREG_ZERO, 1,
227 { { 0, }, { 10, 20 }, { 0, }, { 0, }, { 0, } },
228 },
229 { "blz.sn", TILE_OPC_BLZ_SN, 0x2, 2, TREG_SN, 1,
230 { { 0, }, { 10, 20 }, { 0, }, { 0, }, { 0, } },
231 },
232 { "blzt", TILE_OPC_BLZT, 0x2, 2, TREG_ZERO, 1,
233 { { 0, }, { 10, 20 }, { 0, }, { 0, }, { 0, } },
234 },
235 { "blzt.sn", TILE_OPC_BLZT_SN, 0x2, 2, TREG_SN, 1,
236 { { 0, }, { 10, 20 }, { 0, }, { 0, }, { 0, } },
237 },
238 { "bnz", TILE_OPC_BNZ, 0x2, 2, TREG_ZERO, 1,
239 { { 0, }, { 10, 20 }, { 0, }, { 0, }, { 0, } },
240 },
241 { "bnz.sn", TILE_OPC_BNZ_SN, 0x2, 2, TREG_SN, 1,
242 { { 0, }, { 10, 20 }, { 0, }, { 0, }, { 0, } },
243 },
244 { "bnzt", TILE_OPC_BNZT, 0x2, 2, TREG_ZERO, 1,
245 { { 0, }, { 10, 20 }, { 0, }, { 0, }, { 0, } },
246 },
247 { "bnzt.sn", TILE_OPC_BNZT_SN, 0x2, 2, TREG_SN, 1,
248 { { 0, }, { 10, 20 }, { 0, }, { 0, }, { 0, } },
249 },
250 { "bytex", TILE_OPC_BYTEX, 0x5, 2, TREG_ZERO, 1,
251 { { 7, 8 }, { 0, }, { 11, 12 }, { 0, }, { 0, } },
252 },
253 { "bytex.sn", TILE_OPC_BYTEX_SN, 0x1, 2, TREG_SN, 1,
254 { { 7, 8 }, { 0, }, { 0, }, { 0, }, { 0, } },
255 },
256 { "bz", TILE_OPC_BZ, 0x2, 2, TREG_ZERO, 1,
257 { { 0, }, { 10, 20 }, { 0, }, { 0, }, { 0, } },
258 },
259 { "bz.sn", TILE_OPC_BZ_SN, 0x2, 2, TREG_SN, 1,
260 { { 0, }, { 10, 20 }, { 0, }, { 0, }, { 0, } },
261 },
262 { "bzt", TILE_OPC_BZT, 0x2, 2, TREG_ZERO, 1,
263 { { 0, }, { 10, 20 }, { 0, }, { 0, }, { 0, } },
264 },
265 { "bzt.sn", TILE_OPC_BZT_SN, 0x2, 2, TREG_SN, 1,
266 { { 0, }, { 10, 20 }, { 0, }, { 0, }, { 0, } },
267 },
268 { "clz", TILE_OPC_CLZ, 0x5, 2, TREG_ZERO, 1,
269 { { 7, 8 }, { 0, }, { 11, 12 }, { 0, }, { 0, } },
270 },
271 { "clz.sn", TILE_OPC_CLZ_SN, 0x1, 2, TREG_SN, 1,
272 { { 7, 8 }, { 0, }, { 0, }, { 0, }, { 0, } },
273 },
274 { "crc32_32", TILE_OPC_CRC32_32, 0x1, 3, TREG_ZERO, 1,
275 { { 7, 8, 16 }, { 0, }, { 0, }, { 0, }, { 0, } },
276 },
277 { "crc32_32.sn", TILE_OPC_CRC32_32_SN, 0x1, 3, TREG_SN, 1,
278 { { 7, 8, 16 }, { 0, }, { 0, }, { 0, }, { 0, } },
279 },
280 { "crc32_8", TILE_OPC_CRC32_8, 0x1, 3, TREG_ZERO, 1,
281 { { 7, 8, 16 }, { 0, }, { 0, }, { 0, }, { 0, } },
282 },
283 { "crc32_8.sn", TILE_OPC_CRC32_8_SN, 0x1, 3, TREG_SN, 1,
284 { { 7, 8, 16 }, { 0, }, { 0, }, { 0, }, { 0, } },
285 },
286 { "ctz", TILE_OPC_CTZ, 0x5, 2, TREG_ZERO, 1,
287 { { 7, 8 }, { 0, }, { 11, 12 }, { 0, }, { 0, } },
288 },
289 { "ctz.sn", TILE_OPC_CTZ_SN, 0x1, 2, TREG_SN, 1,
290 { { 7, 8 }, { 0, }, { 0, }, { 0, }, { 0, } },
291 },
292 { "drain", TILE_OPC_DRAIN, 0x2, 0, TREG_ZERO, 0,
293 { { 0, }, { }, { 0, }, { 0, }, { 0, } },
294 },
295 { "dtlbpr", TILE_OPC_DTLBPR, 0x2, 1, TREG_ZERO, 1,
296 { { 0, }, { 10 }, { 0, }, { 0, }, { 0, } },
297 },
298 { "dword_align", TILE_OPC_DWORD_ALIGN, 0x1, 3, TREG_ZERO, 1,
299 { { 21, 8, 16 }, { 0, }, { 0, }, { 0, }, { 0, } },
300 },
301 { "dword_align.sn", TILE_OPC_DWORD_ALIGN_SN, 0x1, 3, TREG_SN, 1,
302 { { 21, 8, 16 }, { 0, }, { 0, }, { 0, }, { 0, } },
303 },
304 { "finv", TILE_OPC_FINV, 0x2, 1, TREG_ZERO, 1,
305 { { 0, }, { 10 }, { 0, }, { 0, }, { 0, } },
306 },
307 { "flush", TILE_OPC_FLUSH, 0x2, 1, TREG_ZERO, 1,
308 { { 0, }, { 10 }, { 0, }, { 0, }, { 0, } },
309 },
310 { "fnop", TILE_OPC_FNOP, 0xf, 0, TREG_ZERO, 1,
311 { { }, { }, { }, { }, { 0, } },
312 },
313 { "icoh", TILE_OPC_ICOH, 0x2, 1, TREG_ZERO, 1,
314 { { 0, }, { 10 }, { 0, }, { 0, }, { 0, } },
315 },
316 { "ill", TILE_OPC_ILL, 0xa, 0, TREG_ZERO, 1,
317 { { 0, }, { }, { 0, }, { }, { 0, } },
318 },
319 { "inthb", TILE_OPC_INTHB, 0x3, 3, TREG_ZERO, 1,
320 { { 7, 8, 16 }, { 9, 10, 17 }, { 0, }, { 0, }, { 0, } },
321 },
322 { "inthb.sn", TILE_OPC_INTHB_SN, 0x3, 3, TREG_SN, 1,
323 { { 7, 8, 16 }, { 9, 10, 17 }, { 0, }, { 0, }, { 0, } },
324 },
325 { "inthh", TILE_OPC_INTHH, 0x3, 3, TREG_ZERO, 1,
326 { { 7, 8, 16 }, { 9, 10, 17 }, { 0, }, { 0, }, { 0, } },
327 },
328 { "inthh.sn", TILE_OPC_INTHH_SN, 0x3, 3, TREG_SN, 1,
329 { { 7, 8, 16 }, { 9, 10, 17 }, { 0, }, { 0, }, { 0, } },
330 },
331 { "intlb", TILE_OPC_INTLB, 0x3, 3, TREG_ZERO, 1,
332 { { 7, 8, 16 }, { 9, 10, 17 }, { 0, }, { 0, }, { 0, } },
333 },
334 { "intlb.sn", TILE_OPC_INTLB_SN, 0x3, 3, TREG_SN, 1,
335 { { 7, 8, 16 }, { 9, 10, 17 }, { 0, }, { 0, }, { 0, } },
336 },
337 { "intlh", TILE_OPC_INTLH, 0x3, 3, TREG_ZERO, 1,
338 { { 7, 8, 16 }, { 9, 10, 17 }, { 0, }, { 0, }, { 0, } },
339 },
340 { "intlh.sn", TILE_OPC_INTLH_SN, 0x3, 3, TREG_SN, 1,
341 { { 7, 8, 16 }, { 9, 10, 17 }, { 0, }, { 0, }, { 0, } },
342 },
343 { "inv", TILE_OPC_INV, 0x2, 1, TREG_ZERO, 1,
344 { { 0, }, { 10 }, { 0, }, { 0, }, { 0, } },
345 },
346 { "iret", TILE_OPC_IRET, 0x2, 0, TREG_ZERO, 1,
347 { { 0, }, { }, { 0, }, { 0, }, { 0, } },
348 },
349 { "jalb", TILE_OPC_JALB, 0x2, 1, TREG_LR, 1,
350 { { 0, }, { 22 }, { 0, }, { 0, }, { 0, } },
351 },
352 { "jalf", TILE_OPC_JALF, 0x2, 1, TREG_LR, 1,
353 { { 0, }, { 22 }, { 0, }, { 0, }, { 0, } },
354 },
355 { "jalr", TILE_OPC_JALR, 0x2, 1, TREG_LR, 1,
356 { { 0, }, { 10 }, { 0, }, { 0, }, { 0, } },
357 },
358 { "jalrp", TILE_OPC_JALRP, 0x2, 1, TREG_LR, 1,
359 { { 0, }, { 10 }, { 0, }, { 0, }, { 0, } },
360 },
361 { "jb", TILE_OPC_JB, 0x2, 1, TREG_ZERO, 1,
362 { { 0, }, { 22 }, { 0, }, { 0, }, { 0, } },
363 },
364 { "jf", TILE_OPC_JF, 0x2, 1, TREG_ZERO, 1,
365 { { 0, }, { 22 }, { 0, }, { 0, }, { 0, } },
366 },
367 { "jr", TILE_OPC_JR, 0x2, 1, TREG_ZERO, 1,
368 { { 0, }, { 10 }, { 0, }, { 0, }, { 0, } },
369 },
370 { "jrp", TILE_OPC_JRP, 0x2, 1, TREG_ZERO, 1,
371 { { 0, }, { 10 }, { 0, }, { 0, }, { 0, } },
372 },
373 { "lb", TILE_OPC_LB, 0x12, 2, TREG_ZERO, 1,
374 { { 0, }, { 9, 10 }, { 0, }, { 0, }, { 23, 15 } },
375 },
376 { "lb.sn", TILE_OPC_LB_SN, 0x2, 2, TREG_SN, 1,
377 { { 0, }, { 9, 10 }, { 0, }, { 0, }, { 0, } },
378 },
379 { "lb_u", TILE_OPC_LB_U, 0x12, 2, TREG_ZERO, 1,
380 { { 0, }, { 9, 10 }, { 0, }, { 0, }, { 23, 15 } },
381 },
382 { "lb_u.sn", TILE_OPC_LB_U_SN, 0x2, 2, TREG_SN, 1,
383 { { 0, }, { 9, 10 }, { 0, }, { 0, }, { 0, } },
384 },
385 { "lbadd", TILE_OPC_LBADD, 0x2, 3, TREG_ZERO, 1,
386 { { 0, }, { 9, 24, 1 }, { 0, }, { 0, }, { 0, } },
387 },
388 { "lbadd.sn", TILE_OPC_LBADD_SN, 0x2, 3, TREG_SN, 1,
389 { { 0, }, { 9, 24, 1 }, { 0, }, { 0, }, { 0, } },
390 },
391 { "lbadd_u", TILE_OPC_LBADD_U, 0x2, 3, TREG_ZERO, 1,
392 { { 0, }, { 9, 24, 1 }, { 0, }, { 0, }, { 0, } },
393 },
394 { "lbadd_u.sn", TILE_OPC_LBADD_U_SN, 0x2, 3, TREG_SN, 1,
395 { { 0, }, { 9, 24, 1 }, { 0, }, { 0, }, { 0, } },
396 },
397 { "lh", TILE_OPC_LH, 0x12, 2, TREG_ZERO, 1,
398 { { 0, }, { 9, 10 }, { 0, }, { 0, }, { 23, 15 } },
399 },
400 { "lh.sn", TILE_OPC_LH_SN, 0x2, 2, TREG_SN, 1,
401 { { 0, }, { 9, 10 }, { 0, }, { 0, }, { 0, } },
402 },
403 { "lh_u", TILE_OPC_LH_U, 0x12, 2, TREG_ZERO, 1,
404 { { 0, }, { 9, 10 }, { 0, }, { 0, }, { 23, 15 } },
405 },
406 { "lh_u.sn", TILE_OPC_LH_U_SN, 0x2, 2, TREG_SN, 1,
407 { { 0, }, { 9, 10 }, { 0, }, { 0, }, { 0, } },
408 },
409 { "lhadd", TILE_OPC_LHADD, 0x2, 3, TREG_ZERO, 1,
410 { { 0, }, { 9, 24, 1 }, { 0, }, { 0, }, { 0, } },
411 },
412 { "lhadd.sn", TILE_OPC_LHADD_SN, 0x2, 3, TREG_SN, 1,
413 { { 0, }, { 9, 24, 1 }, { 0, }, { 0, }, { 0, } },
414 },
415 { "lhadd_u", TILE_OPC_LHADD_U, 0x2, 3, TREG_ZERO, 1,
416 { { 0, }, { 9, 24, 1 }, { 0, }, { 0, }, { 0, } },
417 },
418 { "lhadd_u.sn", TILE_OPC_LHADD_U_SN, 0x2, 3, TREG_SN, 1,
419 { { 0, }, { 9, 24, 1 }, { 0, }, { 0, }, { 0, } },
420 },
421 { "lnk", TILE_OPC_LNK, 0x2, 1, TREG_ZERO, 1,
422 { { 0, }, { 9 }, { 0, }, { 0, }, { 0, } },
423 },
424 { "lnk.sn", TILE_OPC_LNK_SN, 0x2, 1, TREG_SN, 1,
425 { { 0, }, { 9 }, { 0, }, { 0, }, { 0, } },
426 },
427 { "lw", TILE_OPC_LW, 0x12, 2, TREG_ZERO, 1,
428 { { 0, }, { 9, 10 }, { 0, }, { 0, }, { 23, 15 } },
429 },
430 { "lw.sn", TILE_OPC_LW_SN, 0x2, 2, TREG_SN, 1,
431 { { 0, }, { 9, 10 }, { 0, }, { 0, }, { 0, } },
432 },
433 { "lw_na", TILE_OPC_LW_NA, 0x2, 2, TREG_ZERO, 1,
434 { { 0, }, { 9, 10 }, { 0, }, { 0, }, { 0, } },
435 },
436 { "lw_na.sn", TILE_OPC_LW_NA_SN, 0x2, 2, TREG_SN, 1,
437 { { 0, }, { 9, 10 }, { 0, }, { 0, }, { 0, } },
438 },
439 { "lwadd", TILE_OPC_LWADD, 0x2, 3, TREG_ZERO, 1,
440 { { 0, }, { 9, 24, 1 }, { 0, }, { 0, }, { 0, } },
441 },
442 { "lwadd.sn", TILE_OPC_LWADD_SN, 0x2, 3, TREG_SN, 1,
443 { { 0, }, { 9, 24, 1 }, { 0, }, { 0, }, { 0, } },
444 },
445 { "lwadd_na", TILE_OPC_LWADD_NA, 0x2, 3, TREG_ZERO, 1,
446 { { 0, }, { 9, 24, 1 }, { 0, }, { 0, }, { 0, } },
447 },
448 { "lwadd_na.sn", TILE_OPC_LWADD_NA_SN, 0x2, 3, TREG_SN, 1,
449 { { 0, }, { 9, 24, 1 }, { 0, }, { 0, }, { 0, } },
450 },
451 { "maxb_u", TILE_OPC_MAXB_U, 0x3, 3, TREG_ZERO, 1,
452 { { 7, 8, 16 }, { 9, 10, 17 }, { 0, }, { 0, }, { 0, } },
453 },
454 { "maxb_u.sn", TILE_OPC_MAXB_U_SN, 0x3, 3, TREG_SN, 1,
455 { { 7, 8, 16 }, { 9, 10, 17 }, { 0, }, { 0, }, { 0, } },
456 },
457 { "maxh", TILE_OPC_MAXH, 0x3, 3, TREG_ZERO, 1,
458 { { 7, 8, 16 }, { 9, 10, 17 }, { 0, }, { 0, }, { 0, } },
459 },
460 { "maxh.sn", TILE_OPC_MAXH_SN, 0x3, 3, TREG_SN, 1,
461 { { 7, 8, 16 }, { 9, 10, 17 }, { 0, }, { 0, }, { 0, } },
462 },
463 { "maxib_u", TILE_OPC_MAXIB_U, 0x3, 3, TREG_ZERO, 1,
464 { { 7, 8, 0 }, { 9, 10, 1 }, { 0, }, { 0, }, { 0, } },
465 },
466 { "maxib_u.sn", TILE_OPC_MAXIB_U_SN, 0x3, 3, TREG_SN, 1,
467 { { 7, 8, 0 }, { 9, 10, 1 }, { 0, }, { 0, }, { 0, } },
468 },
469 { "maxih", TILE_OPC_MAXIH, 0x3, 3, TREG_ZERO, 1,
470 { { 7, 8, 0 }, { 9, 10, 1 }, { 0, }, { 0, }, { 0, } },
471 },
472 { "maxih.sn", TILE_OPC_MAXIH_SN, 0x3, 3, TREG_SN, 1,
473 { { 7, 8, 0 }, { 9, 10, 1 }, { 0, }, { 0, }, { 0, } },
474 },
475 { "mf", TILE_OPC_MF, 0x2, 0, TREG_ZERO, 1,
476 { { 0, }, { }, { 0, }, { 0, }, { 0, } },
477 },
478 { "mfspr", TILE_OPC_MFSPR, 0x2, 2, TREG_ZERO, 1,
479 { { 0, }, { 9, 25 }, { 0, }, { 0, }, { 0, } },
480 },
481 { "minb_u", TILE_OPC_MINB_U, 0x3, 3, TREG_ZERO, 1,
482 { { 7, 8, 16 }, { 9, 10, 17 }, { 0, }, { 0, }, { 0, } },
483 },
484 { "minb_u.sn", TILE_OPC_MINB_U_SN, 0x3, 3, TREG_SN, 1,
485 { { 7, 8, 16 }, { 9, 10, 17 }, { 0, }, { 0, }, { 0, } },
486 },
487 { "minh", TILE_OPC_MINH, 0x3, 3, TREG_ZERO, 1,
488 { { 7, 8, 16 }, { 9, 10, 17 }, { 0, }, { 0, }, { 0, } },
489 },
490 { "minh.sn", TILE_OPC_MINH_SN, 0x3, 3, TREG_SN, 1,
491 { { 7, 8, 16 }, { 9, 10, 17 }, { 0, }, { 0, }, { 0, } },
492 },
493 { "minib_u", TILE_OPC_MINIB_U, 0x3, 3, TREG_ZERO, 1,
494 { { 7, 8, 0 }, { 9, 10, 1 }, { 0, }, { 0, }, { 0, } },
495 },
496 { "minib_u.sn", TILE_OPC_MINIB_U_SN, 0x3, 3, TREG_SN, 1,
497 { { 7, 8, 0 }, { 9, 10, 1 }, { 0, }, { 0, }, { 0, } },
498 },
499 { "minih", TILE_OPC_MINIH, 0x3, 3, TREG_ZERO, 1,
500 { { 7, 8, 0 }, { 9, 10, 1 }, { 0, }, { 0, }, { 0, } },
501 },
502 { "minih.sn", TILE_OPC_MINIH_SN, 0x3, 3, TREG_SN, 1,
503 { { 7, 8, 0 }, { 9, 10, 1 }, { 0, }, { 0, }, { 0, } },
504 },
505 { "mm", TILE_OPC_MM, 0x3, 5, TREG_ZERO, 1,
506 { { 7, 8, 16, 26, 27 }, { 9, 10, 17, 28, 29 }, { 0, }, { 0, }, { 0, } },
507 },
508 { "mnz", TILE_OPC_MNZ, 0xf, 3, TREG_ZERO, 1,
509 { { 7, 8, 16 }, { 9, 10, 17 }, { 11, 12, 18 }, { 13, 14, 19 }, { 0, } },
510 },
511 { "mnz.sn", TILE_OPC_MNZ_SN, 0x3, 3, TREG_SN, 1,
512 { { 7, 8, 16 }, { 9, 10, 17 }, { 0, }, { 0, }, { 0, } },
513 },
514 { "mnzb", TILE_OPC_MNZB, 0x3, 3, TREG_ZERO, 1,
515 { { 7, 8, 16 }, { 9, 10, 17 }, { 0, }, { 0, }, { 0, } },
516 },
517 { "mnzb.sn", TILE_OPC_MNZB_SN, 0x3, 3, TREG_SN, 1,
518 { { 7, 8, 16 }, { 9, 10, 17 }, { 0, }, { 0, }, { 0, } },
519 },
520 { "mnzh", TILE_OPC_MNZH, 0x3, 3, TREG_ZERO, 1,
521 { { 7, 8, 16 }, { 9, 10, 17 }, { 0, }, { 0, }, { 0, } },
522 },
523 { "mnzh.sn", TILE_OPC_MNZH_SN, 0x3, 3, TREG_SN, 1,
524 { { 7, 8, 16 }, { 9, 10, 17 }, { 0, }, { 0, }, { 0, } },
525 },
526 { "mtspr", TILE_OPC_MTSPR, 0x2, 2, TREG_ZERO, 1,
527 { { 0, }, { 30, 10 }, { 0, }, { 0, }, { 0, } },
528 },
529 { "mulhh_ss", TILE_OPC_MULHH_SS, 0x5, 3, TREG_ZERO, 1,
530 { { 7, 8, 16 }, { 0, }, { 11, 12, 18 }, { 0, }, { 0, } },
531 },
532 { "mulhh_ss.sn", TILE_OPC_MULHH_SS_SN, 0x1, 3, TREG_SN, 1,
533 { { 7, 8, 16 }, { 0, }, { 0, }, { 0, }, { 0, } },
534 },
535 { "mulhh_su", TILE_OPC_MULHH_SU, 0x1, 3, TREG_ZERO, 1,
536 { { 7, 8, 16 }, { 0, }, { 0, }, { 0, }, { 0, } },
537 },
538 { "mulhh_su.sn", TILE_OPC_MULHH_SU_SN, 0x1, 3, TREG_SN, 1,
539 { { 7, 8, 16 }, { 0, }, { 0, }, { 0, }, { 0, } },
540 },
541 { "mulhh_uu", TILE_OPC_MULHH_UU, 0x5, 3, TREG_ZERO, 1,
542 { { 7, 8, 16 }, { 0, }, { 11, 12, 18 }, { 0, }, { 0, } },
543 },
544 { "mulhh_uu.sn", TILE_OPC_MULHH_UU_SN, 0x1, 3, TREG_SN, 1,
545 { { 7, 8, 16 }, { 0, }, { 0, }, { 0, }, { 0, } },
546 },
547 { "mulhha_ss", TILE_OPC_MULHHA_SS, 0x5, 3, TREG_ZERO, 1,
548 { { 21, 8, 16 }, { 0, }, { 31, 12, 18 }, { 0, }, { 0, } },
549 },
550 { "mulhha_ss.sn", TILE_OPC_MULHHA_SS_SN, 0x1, 3, TREG_SN, 1,
551 { { 21, 8, 16 }, { 0, }, { 0, }, { 0, }, { 0, } },
552 },
553 { "mulhha_su", TILE_OPC_MULHHA_SU, 0x1, 3, TREG_ZERO, 1,
554 { { 21, 8, 16 }, { 0, }, { 0, }, { 0, }, { 0, } },
555 },
556 { "mulhha_su.sn", TILE_OPC_MULHHA_SU_SN, 0x1, 3, TREG_SN, 1,
557 { { 21, 8, 16 }, { 0, }, { 0, }, { 0, }, { 0, } },
558 },
559 { "mulhha_uu", TILE_OPC_MULHHA_UU, 0x5, 3, TREG_ZERO, 1,
560 { { 21, 8, 16 }, { 0, }, { 31, 12, 18 }, { 0, }, { 0, } },
561 },
562 { "mulhha_uu.sn", TILE_OPC_MULHHA_UU_SN, 0x1, 3, TREG_SN, 1,
563 { { 21, 8, 16 }, { 0, }, { 0, }, { 0, }, { 0, } },
564 },
565 { "mulhhsa_uu", TILE_OPC_MULHHSA_UU, 0x1, 3, TREG_ZERO, 1,
566 { { 21, 8, 16 }, { 0, }, { 0, }, { 0, }, { 0, } },
567 },
568 { "mulhhsa_uu.sn", TILE_OPC_MULHHSA_UU_SN, 0x1, 3, TREG_SN, 1,
569 { { 21, 8, 16 }, { 0, }, { 0, }, { 0, }, { 0, } },
570 },
571 { "mulhl_ss", TILE_OPC_MULHL_SS, 0x1, 3, TREG_ZERO, 1,
572 { { 7, 8, 16 }, { 0, }, { 0, }, { 0, }, { 0, } },
573 },
574 { "mulhl_ss.sn", TILE_OPC_MULHL_SS_SN, 0x1, 3, TREG_SN, 1,
575 { { 7, 8, 16 }, { 0, }, { 0, }, { 0, }, { 0, } },
576 },
577 { "mulhl_su", TILE_OPC_MULHL_SU, 0x1, 3, TREG_ZERO, 1,
578 { { 7, 8, 16 }, { 0, }, { 0, }, { 0, }, { 0, } },
579 },
580 { "mulhl_su.sn", TILE_OPC_MULHL_SU_SN, 0x1, 3, TREG_SN, 1,
581 { { 7, 8, 16 }, { 0, }, { 0, }, { 0, }, { 0, } },
582 },
583 { "mulhl_us", TILE_OPC_MULHL_US, 0x1, 3, TREG_ZERO, 1,
584 { { 7, 8, 16 }, { 0, }, { 0, }, { 0, }, { 0, } },
585 },
586 { "mulhl_us.sn", TILE_OPC_MULHL_US_SN, 0x1, 3, TREG_SN, 1,
587 { { 7, 8, 16 }, { 0, }, { 0, }, { 0, }, { 0, } },
588 },
589 { "mulhl_uu", TILE_OPC_MULHL_UU, 0x1, 3, TREG_ZERO, 1,
590 { { 7, 8, 16 }, { 0, }, { 0, }, { 0, }, { 0, } },
591 },
592 { "mulhl_uu.sn", TILE_OPC_MULHL_UU_SN, 0x1, 3, TREG_SN, 1,
593 { { 7, 8, 16 }, { 0, }, { 0, }, { 0, }, { 0, } },
594 },
595 { "mulhla_ss", TILE_OPC_MULHLA_SS, 0x1, 3, TREG_ZERO, 1,
596 { { 21, 8, 16 }, { 0, }, { 0, }, { 0, }, { 0, } },
597 },
598 { "mulhla_ss.sn", TILE_OPC_MULHLA_SS_SN, 0x1, 3, TREG_SN, 1,
599 { { 21, 8, 16 }, { 0, }, { 0, }, { 0, }, { 0, } },
600 },
601 { "mulhla_su", TILE_OPC_MULHLA_SU, 0x1, 3, TREG_ZERO, 1,
602 { { 21, 8, 16 }, { 0, }, { 0, }, { 0, }, { 0, } },
603 },
604 { "mulhla_su.sn", TILE_OPC_MULHLA_SU_SN, 0x1, 3, TREG_SN, 1,
605 { { 21, 8, 16 }, { 0, }, { 0, }, { 0, }, { 0, } },
606 },
607 { "mulhla_us", TILE_OPC_MULHLA_US, 0x1, 3, TREG_ZERO, 1,
608 { { 21, 8, 16 }, { 0, }, { 0, }, { 0, }, { 0, } },
609 },
610 { "mulhla_us.sn", TILE_OPC_MULHLA_US_SN, 0x1, 3, TREG_SN, 1,
611 { { 21, 8, 16 }, { 0, }, { 0, }, { 0, }, { 0, } },
612 },
613 { "mulhla_uu", TILE_OPC_MULHLA_UU, 0x1, 3, TREG_ZERO, 1,
614 { { 21, 8, 16 }, { 0, }, { 0, }, { 0, }, { 0, } },
615 },
616 { "mulhla_uu.sn", TILE_OPC_MULHLA_UU_SN, 0x1, 3, TREG_SN, 1,
617 { { 21, 8, 16 }, { 0, }, { 0, }, { 0, }, { 0, } },
618 },
619 { "mulhlsa_uu", TILE_OPC_MULHLSA_UU, 0x5, 3, TREG_ZERO, 1,
620 { { 21, 8, 16 }, { 0, }, { 31, 12, 18 }, { 0, }, { 0, } },
621 },
622 { "mulhlsa_uu.sn", TILE_OPC_MULHLSA_UU_SN, 0x1, 3, TREG_SN, 1,
623 { { 21, 8, 16 }, { 0, }, { 0, }, { 0, }, { 0, } },
624 },
625 { "mulll_ss", TILE_OPC_MULLL_SS, 0x5, 3, TREG_ZERO, 1,
626 { { 7, 8, 16 }, { 0, }, { 11, 12, 18 }, { 0, }, { 0, } },
627 },
628 { "mulll_ss.sn", TILE_OPC_MULLL_SS_SN, 0x1, 3, TREG_SN, 1,
629 { { 7, 8, 16 }, { 0, }, { 0, }, { 0, }, { 0, } },
630 },
631 { "mulll_su", TILE_OPC_MULLL_SU, 0x1, 3, TREG_ZERO, 1,
632 { { 7, 8, 16 }, { 0, }, { 0, }, { 0, }, { 0, } },
633 },
634 { "mulll_su.sn", TILE_OPC_MULLL_SU_SN, 0x1, 3, TREG_SN, 1,
635 { { 7, 8, 16 }, { 0, }, { 0, }, { 0, }, { 0, } },
636 },
637 { "mulll_uu", TILE_OPC_MULLL_UU, 0x5, 3, TREG_ZERO, 1,
638 { { 7, 8, 16 }, { 0, }, { 11, 12, 18 }, { 0, }, { 0, } },
639 },
640 { "mulll_uu.sn", TILE_OPC_MULLL_UU_SN, 0x1, 3, TREG_SN, 1,
641 { { 7, 8, 16 }, { 0, }, { 0, }, { 0, }, { 0, } },
642 },
643 { "mullla_ss", TILE_OPC_MULLLA_SS, 0x5, 3, TREG_ZERO, 1,
644 { { 21, 8, 16 }, { 0, }, { 31, 12, 18 }, { 0, }, { 0, } },
645 },
646 { "mullla_ss.sn", TILE_OPC_MULLLA_SS_SN, 0x1, 3, TREG_SN, 1,
647 { { 21, 8, 16 }, { 0, }, { 0, }, { 0, }, { 0, } },
648 },
649 { "mullla_su", TILE_OPC_MULLLA_SU, 0x1, 3, TREG_ZERO, 1,
650 { { 21, 8, 16 }, { 0, }, { 0, }, { 0, }, { 0, } },
651 },
652 { "mullla_su.sn", TILE_OPC_MULLLA_SU_SN, 0x1, 3, TREG_SN, 1,
653 { { 21, 8, 16 }, { 0, }, { 0, }, { 0, }, { 0, } },
654 },
655 { "mullla_uu", TILE_OPC_MULLLA_UU, 0x5, 3, TREG_ZERO, 1,
656 { { 21, 8, 16 }, { 0, }, { 31, 12, 18 }, { 0, }, { 0, } },
657 },
658 { "mullla_uu.sn", TILE_OPC_MULLLA_UU_SN, 0x1, 3, TREG_SN, 1,
659 { { 21, 8, 16 }, { 0, }, { 0, }, { 0, }, { 0, } },
660 },
661 { "mulllsa_uu", TILE_OPC_MULLLSA_UU, 0x1, 3, TREG_ZERO, 1,
662 { { 21, 8, 16 }, { 0, }, { 0, }, { 0, }, { 0, } },
663 },
664 { "mulllsa_uu.sn", TILE_OPC_MULLLSA_UU_SN, 0x1, 3, TREG_SN, 1,
665 { { 21, 8, 16 }, { 0, }, { 0, }, { 0, }, { 0, } },
666 },
667 { "mvnz", TILE_OPC_MVNZ, 0x5, 3, TREG_ZERO, 1,
668 { { 21, 8, 16 }, { 0, }, { 31, 12, 18 }, { 0, }, { 0, } },
669 },
670 { "mvnz.sn", TILE_OPC_MVNZ_SN, 0x1, 3, TREG_SN, 1,
671 { { 21, 8, 16 }, { 0, }, { 0, }, { 0, }, { 0, } },
672 },
673 { "mvz", TILE_OPC_MVZ, 0x5, 3, TREG_ZERO, 1,
674 { { 21, 8, 16 }, { 0, }, { 31, 12, 18 }, { 0, }, { 0, } },
675 },
676 { "mvz.sn", TILE_OPC_MVZ_SN, 0x1, 3, TREG_SN, 1,
677 { { 21, 8, 16 }, { 0, }, { 0, }, { 0, }, { 0, } },
678 },
679 { "mz", TILE_OPC_MZ, 0xf, 3, TREG_ZERO, 1,
680 { { 7, 8, 16 }, { 9, 10, 17 }, { 11, 12, 18 }, { 13, 14, 19 }, { 0, } },
681 },
682 { "mz.sn", TILE_OPC_MZ_SN, 0x3, 3, TREG_SN, 1,
683 { { 7, 8, 16 }, { 9, 10, 17 }, { 0, }, { 0, }, { 0, } },
684 },
685 { "mzb", TILE_OPC_MZB, 0x3, 3, TREG_ZERO, 1,
686 { { 7, 8, 16 }, { 9, 10, 17 }, { 0, }, { 0, }, { 0, } },
687 },
688 { "mzb.sn", TILE_OPC_MZB_SN, 0x3, 3, TREG_SN, 1,
689 { { 7, 8, 16 }, { 9, 10, 17 }, { 0, }, { 0, }, { 0, } },
690 },
691 { "mzh", TILE_OPC_MZH, 0x3, 3, TREG_ZERO, 1,
692 { { 7, 8, 16 }, { 9, 10, 17 }, { 0, }, { 0, }, { 0, } },
693 },
694 { "mzh.sn", TILE_OPC_MZH_SN, 0x3, 3, TREG_SN, 1,
695 { { 7, 8, 16 }, { 9, 10, 17 }, { 0, }, { 0, }, { 0, } },
696 },
697 { "nap", TILE_OPC_NAP, 0x2, 0, TREG_ZERO, 0,
698 { { 0, }, { }, { 0, }, { 0, }, { 0, } },
699 },
700 { "nop", TILE_OPC_NOP, 0xf, 0, TREG_ZERO, 1,
701 { { }, { }, { }, { }, { 0, } },
702 },
703 { "nor", TILE_OPC_NOR, 0xf, 3, TREG_ZERO, 1,
704 { { 7, 8, 16 }, { 9, 10, 17 }, { 11, 12, 18 }, { 13, 14, 19 }, { 0, } },
705 },
706 { "nor.sn", TILE_OPC_NOR_SN, 0x3, 3, TREG_SN, 1,
707 { { 7, 8, 16 }, { 9, 10, 17 }, { 0, }, { 0, }, { 0, } },
708 },
709 { "or", TILE_OPC_OR, 0xf, 3, TREG_ZERO, 1,
710 { { 7, 8, 16 }, { 9, 10, 17 }, { 11, 12, 18 }, { 13, 14, 19 }, { 0, } },
711 },
712 { "or.sn", TILE_OPC_OR_SN, 0x3, 3, TREG_SN, 1,
713 { { 7, 8, 16 }, { 9, 10, 17 }, { 0, }, { 0, }, { 0, } },
714 },
715 { "ori", TILE_OPC_ORI, 0xf, 3, TREG_ZERO, 1,
716 { { 7, 8, 0 }, { 9, 10, 1 }, { 11, 12, 2 }, { 13, 14, 3 }, { 0, } },
717 },
718 { "ori.sn", TILE_OPC_ORI_SN, 0x3, 3, TREG_SN, 1,
719 { { 7, 8, 0 }, { 9, 10, 1 }, { 0, }, { 0, }, { 0, } },
720 },
721 { "packbs_u", TILE_OPC_PACKBS_U, 0x3, 3, TREG_ZERO, 1,
722 { { 7, 8, 16 }, { 9, 10, 17 }, { 0, }, { 0, }, { 0, } },
723 },
724 { "packbs_u.sn", TILE_OPC_PACKBS_U_SN, 0x3, 3, TREG_SN, 1,
725 { { 7, 8, 16 }, { 9, 10, 17 }, { 0, }, { 0, }, { 0, } },
726 },
727 { "packhb", TILE_OPC_PACKHB, 0x3, 3, TREG_ZERO, 1,
728 { { 7, 8, 16 }, { 9, 10, 17 }, { 0, }, { 0, }, { 0, } },
729 },
730 { "packhb.sn", TILE_OPC_PACKHB_SN, 0x3, 3, TREG_SN, 1,
731 { { 7, 8, 16 }, { 9, 10, 17 }, { 0, }, { 0, }, { 0, } },
732 },
733 { "packhs", TILE_OPC_PACKHS, 0x3, 3, TREG_ZERO, 1,
734 { { 7, 8, 16 }, { 9, 10, 17 }, { 0, }, { 0, }, { 0, } },
735 },
736 { "packhs.sn", TILE_OPC_PACKHS_SN, 0x3, 3, TREG_SN, 1,
737 { { 7, 8, 16 }, { 9, 10, 17 }, { 0, }, { 0, }, { 0, } },
738 },
739 { "packlb", TILE_OPC_PACKLB, 0x3, 3, TREG_ZERO, 1,
740 { { 7, 8, 16 }, { 9, 10, 17 }, { 0, }, { 0, }, { 0, } },
741 },
742 { "packlb.sn", TILE_OPC_PACKLB_SN, 0x3, 3, TREG_SN, 1,
743 { { 7, 8, 16 }, { 9, 10, 17 }, { 0, }, { 0, }, { 0, } },
744 },
745 { "pcnt", TILE_OPC_PCNT, 0x5, 2, TREG_ZERO, 1,
746 { { 7, 8 }, { 0, }, { 11, 12 }, { 0, }, { 0, } },
747 },
748 { "pcnt.sn", TILE_OPC_PCNT_SN, 0x1, 2, TREG_SN, 1,
749 { { 7, 8 }, { 0, }, { 0, }, { 0, }, { 0, } },
750 },
751 { "rl", TILE_OPC_RL, 0xf, 3, TREG_ZERO, 1,
752 { { 7, 8, 16 }, { 9, 10, 17 }, { 11, 12, 18 }, { 13, 14, 19 }, { 0, } },
753 },
754 { "rl.sn", TILE_OPC_RL_SN, 0x3, 3, TREG_SN, 1,
755 { { 7, 8, 16 }, { 9, 10, 17 }, { 0, }, { 0, }, { 0, } },
756 },
757 { "rli", TILE_OPC_RLI, 0xf, 3, TREG_ZERO, 1,
758 { { 7, 8, 32 }, { 9, 10, 33 }, { 11, 12, 34 }, { 13, 14, 35 }, { 0, } },
759 },
760 { "rli.sn", TILE_OPC_RLI_SN, 0x3, 3, TREG_SN, 1,
761 { { 7, 8, 32 }, { 9, 10, 33 }, { 0, }, { 0, }, { 0, } },
762 },
763 { "s1a", TILE_OPC_S1A, 0xf, 3, TREG_ZERO, 1,
764 { { 7, 8, 16 }, { 9, 10, 17 }, { 11, 12, 18 }, { 13, 14, 19 }, { 0, } },
765 },
766 { "s1a.sn", TILE_OPC_S1A_SN, 0x3, 3, TREG_SN, 1,
767 { { 7, 8, 16 }, { 9, 10, 17 }, { 0, }, { 0, }, { 0, } },
768 },
769 { "s2a", TILE_OPC_S2A, 0xf, 3, TREG_ZERO, 1,
770 { { 7, 8, 16 }, { 9, 10, 17 }, { 11, 12, 18 }, { 13, 14, 19 }, { 0, } },
771 },
772 { "s2a.sn", TILE_OPC_S2A_SN, 0x3, 3, TREG_SN, 1,
773 { { 7, 8, 16 }, { 9, 10, 17 }, { 0, }, { 0, }, { 0, } },
774 },
775 { "s3a", TILE_OPC_S3A, 0xf, 3, TREG_ZERO, 1,
776 { { 7, 8, 16 }, { 9, 10, 17 }, { 11, 12, 18 }, { 13, 14, 19 }, { 0, } },
777 },
778 { "s3a.sn", TILE_OPC_S3A_SN, 0x3, 3, TREG_SN, 1,
779 { { 7, 8, 16 }, { 9, 10, 17 }, { 0, }, { 0, }, { 0, } },
780 },
781 { "sadab_u", TILE_OPC_SADAB_U, 0x1, 3, TREG_ZERO, 1,
782 { { 21, 8, 16 }, { 0, }, { 0, }, { 0, }, { 0, } },
783 },
784 { "sadab_u.sn", TILE_OPC_SADAB_U_SN, 0x1, 3, TREG_SN, 1,
785 { { 21, 8, 16 }, { 0, }, { 0, }, { 0, }, { 0, } },
786 },
787 { "sadah", TILE_OPC_SADAH, 0x1, 3, TREG_ZERO, 1,
788 { { 21, 8, 16 }, { 0, }, { 0, }, { 0, }, { 0, } },
789 },
790 { "sadah.sn", TILE_OPC_SADAH_SN, 0x1, 3, TREG_SN, 1,
791 { { 21, 8, 16 }, { 0, }, { 0, }, { 0, }, { 0, } },
792 },
793 { "sadah_u", TILE_OPC_SADAH_U, 0x1, 3, TREG_ZERO, 1,
794 { { 21, 8, 16 }, { 0, }, { 0, }, { 0, }, { 0, } },
795 },
796 { "sadah_u.sn", TILE_OPC_SADAH_U_SN, 0x1, 3, TREG_SN, 1,
797 { { 21, 8, 16 }, { 0, }, { 0, }, { 0, }, { 0, } },
798 },
799 { "sadb_u", TILE_OPC_SADB_U, 0x1, 3, TREG_ZERO, 1,
800 { { 7, 8, 16 }, { 0, }, { 0, }, { 0, }, { 0, } },
801 },
802 { "sadb_u.sn", TILE_OPC_SADB_U_SN, 0x1, 3, TREG_SN, 1,
803 { { 7, 8, 16 }, { 0, }, { 0, }, { 0, }, { 0, } },
804 },
805 { "sadh", TILE_OPC_SADH, 0x1, 3, TREG_ZERO, 1,
806 { { 7, 8, 16 }, { 0, }, { 0, }, { 0, }, { 0, } },
807 },
808 { "sadh.sn", TILE_OPC_SADH_SN, 0x1, 3, TREG_SN, 1,
809 { { 7, 8, 16 }, { 0, }, { 0, }, { 0, }, { 0, } },
810 },
811 { "sadh_u", TILE_OPC_SADH_U, 0x1, 3, TREG_ZERO, 1,
812 { { 7, 8, 16 }, { 0, }, { 0, }, { 0, }, { 0, } },
813 },
814 { "sadh_u.sn", TILE_OPC_SADH_U_SN, 0x1, 3, TREG_SN, 1,
815 { { 7, 8, 16 }, { 0, }, { 0, }, { 0, }, { 0, } },
816 },
817 { "sb", TILE_OPC_SB, 0x12, 2, TREG_ZERO, 1,
818 { { 0, }, { 10, 17 }, { 0, }, { 0, }, { 15, 36 } },
819 },
820 { "sbadd", TILE_OPC_SBADD, 0x2, 3, TREG_ZERO, 1,
821 { { 0, }, { 24, 17, 37 }, { 0, }, { 0, }, { 0, } },
822 },
823 { "seq", TILE_OPC_SEQ, 0xf, 3, TREG_ZERO, 1,
824 { { 7, 8, 16 }, { 9, 10, 17 }, { 11, 12, 18 }, { 13, 14, 19 }, { 0, } },
825 },
826 { "seq.sn", TILE_OPC_SEQ_SN, 0x3, 3, TREG_SN, 1,
827 { { 7, 8, 16 }, { 9, 10, 17 }, { 0, }, { 0, }, { 0, } },
828 },
829 { "seqb", TILE_OPC_SEQB, 0x3, 3, TREG_ZERO, 1,
830 { { 7, 8, 16 }, { 9, 10, 17 }, { 0, }, { 0, }, { 0, } },
831 },
832 { "seqb.sn", TILE_OPC_SEQB_SN, 0x3, 3, TREG_SN, 1,
833 { { 7, 8, 16 }, { 9, 10, 17 }, { 0, }, { 0, }, { 0, } },
834 },
835 { "seqh", TILE_OPC_SEQH, 0x3, 3, TREG_ZERO, 1,
836 { { 7, 8, 16 }, { 9, 10, 17 }, { 0, }, { 0, }, { 0, } },
837 },
838 { "seqh.sn", TILE_OPC_SEQH_SN, 0x3, 3, TREG_SN, 1,
839 { { 7, 8, 16 }, { 9, 10, 17 }, { 0, }, { 0, }, { 0, } },
840 },
841 { "seqi", TILE_OPC_SEQI, 0xf, 3, TREG_ZERO, 1,
842 { { 7, 8, 0 }, { 9, 10, 1 }, { 11, 12, 2 }, { 13, 14, 3 }, { 0, } },
843 },
844 { "seqi.sn", TILE_OPC_SEQI_SN, 0x3, 3, TREG_SN, 1,
845 { { 7, 8, 0 }, { 9, 10, 1 }, { 0, }, { 0, }, { 0, } },
846 },
847 { "seqib", TILE_OPC_SEQIB, 0x3, 3, TREG_ZERO, 1,
848 { { 7, 8, 0 }, { 9, 10, 1 }, { 0, }, { 0, }, { 0, } },
849 },
850 { "seqib.sn", TILE_OPC_SEQIB_SN, 0x3, 3, TREG_SN, 1,
851 { { 7, 8, 0 }, { 9, 10, 1 }, { 0, }, { 0, }, { 0, } },
852 },
853 { "seqih", TILE_OPC_SEQIH, 0x3, 3, TREG_ZERO, 1,
854 { { 7, 8, 0 }, { 9, 10, 1 }, { 0, }, { 0, }, { 0, } },
855 },
856 { "seqih.sn", TILE_OPC_SEQIH_SN, 0x3, 3, TREG_SN, 1,
857 { { 7, 8, 0 }, { 9, 10, 1 }, { 0, }, { 0, }, { 0, } },
858 },
859 { "sh", TILE_OPC_SH, 0x12, 2, TREG_ZERO, 1,
860 { { 0, }, { 10, 17 }, { 0, }, { 0, }, { 15, 36 } },
861 },
862 { "shadd", TILE_OPC_SHADD, 0x2, 3, TREG_ZERO, 1,
863 { { 0, }, { 24, 17, 37 }, { 0, }, { 0, }, { 0, } },
864 },
865 { "shl", TILE_OPC_SHL, 0xf, 3, TREG_ZERO, 1,
866 { { 7, 8, 16 }, { 9, 10, 17 }, { 11, 12, 18 }, { 13, 14, 19 }, { 0, } },
867 },
868 { "shl.sn", TILE_OPC_SHL_SN, 0x3, 3, TREG_SN, 1,
869 { { 7, 8, 16 }, { 9, 10, 17 }, { 0, }, { 0, }, { 0, } },
870 },
871 { "shlb", TILE_OPC_SHLB, 0x3, 3, TREG_ZERO, 1,
872 { { 7, 8, 16 }, { 9, 10, 17 }, { 0, }, { 0, }, { 0, } },
873 },
874 { "shlb.sn", TILE_OPC_SHLB_SN, 0x3, 3, TREG_SN, 1,
875 { { 7, 8, 16 }, { 9, 10, 17 }, { 0, }, { 0, }, { 0, } },
876 },
877 { "shlh", TILE_OPC_SHLH, 0x3, 3, TREG_ZERO, 1,
878 { { 7, 8, 16 }, { 9, 10, 17 }, { 0, }, { 0, }, { 0, } },
879 },
880 { "shlh.sn", TILE_OPC_SHLH_SN, 0x3, 3, TREG_SN, 1,
881 { { 7, 8, 16 }, { 9, 10, 17 }, { 0, }, { 0, }, { 0, } },
882 },
883 { "shli", TILE_OPC_SHLI, 0xf, 3, TREG_ZERO, 1,
884 { { 7, 8, 32 }, { 9, 10, 33 }, { 11, 12, 34 }, { 13, 14, 35 }, { 0, } },
885 },
886 { "shli.sn", TILE_OPC_SHLI_SN, 0x3, 3, TREG_SN, 1,
887 { { 7, 8, 32 }, { 9, 10, 33 }, { 0, }, { 0, }, { 0, } },
888 },
889 { "shlib", TILE_OPC_SHLIB, 0x3, 3, TREG_ZERO, 1,
890 { { 7, 8, 32 }, { 9, 10, 33 }, { 0, }, { 0, }, { 0, } },
891 },
892 { "shlib.sn", TILE_OPC_SHLIB_SN, 0x3, 3, TREG_SN, 1,
893 { { 7, 8, 32 }, { 9, 10, 33 }, { 0, }, { 0, }, { 0, } },
894 },
895 { "shlih", TILE_OPC_SHLIH, 0x3, 3, TREG_ZERO, 1,
896 { { 7, 8, 32 }, { 9, 10, 33 }, { 0, }, { 0, }, { 0, } },
897 },
898 { "shlih.sn", TILE_OPC_SHLIH_SN, 0x3, 3, TREG_SN, 1,
899 { { 7, 8, 32 }, { 9, 10, 33 }, { 0, }, { 0, }, { 0, } },
900 },
901 { "shr", TILE_OPC_SHR, 0xf, 3, TREG_ZERO, 1,
902 { { 7, 8, 16 }, { 9, 10, 17 }, { 11, 12, 18 }, { 13, 14, 19 }, { 0, } },
903 },
904 { "shr.sn", TILE_OPC_SHR_SN, 0x3, 3, TREG_SN, 1,
905 { { 7, 8, 16 }, { 9, 10, 17 }, { 0, }, { 0, }, { 0, } },
906 },
907 { "shrb", TILE_OPC_SHRB, 0x3, 3, TREG_ZERO, 1,
908 { { 7, 8, 16 }, { 9, 10, 17 }, { 0, }, { 0, }, { 0, } },
909 },
910 { "shrb.sn", TILE_OPC_SHRB_SN, 0x3, 3, TREG_SN, 1,
911 { { 7, 8, 16 }, { 9, 10, 17 }, { 0, }, { 0, }, { 0, } },
912 },
913 { "shrh", TILE_OPC_SHRH, 0x3, 3, TREG_ZERO, 1,
914 { { 7, 8, 16 }, { 9, 10, 17 }, { 0, }, { 0, }, { 0, } },
915 },
916 { "shrh.sn", TILE_OPC_SHRH_SN, 0x3, 3, TREG_SN, 1,
917 { { 7, 8, 16 }, { 9, 10, 17 }, { 0, }, { 0, }, { 0, } },
918 },
919 { "shri", TILE_OPC_SHRI, 0xf, 3, TREG_ZERO, 1,
920 { { 7, 8, 32 }, { 9, 10, 33 }, { 11, 12, 34 }, { 13, 14, 35 }, { 0, } },
921 },
922 { "shri.sn", TILE_OPC_SHRI_SN, 0x3, 3, TREG_SN, 1,
923 { { 7, 8, 32 }, { 9, 10, 33 }, { 0, }, { 0, }, { 0, } },
924 },
925 { "shrib", TILE_OPC_SHRIB, 0x3, 3, TREG_ZERO, 1,
926 { { 7, 8, 32 }, { 9, 10, 33 }, { 0, }, { 0, }, { 0, } },
927 },
928 { "shrib.sn", TILE_OPC_SHRIB_SN, 0x3, 3, TREG_SN, 1,
929 { { 7, 8, 32 }, { 9, 10, 33 }, { 0, }, { 0, }, { 0, } },
930 },
931 { "shrih", TILE_OPC_SHRIH, 0x3, 3, TREG_ZERO, 1,
932 { { 7, 8, 32 }, { 9, 10, 33 }, { 0, }, { 0, }, { 0, } },
933 },
934 { "shrih.sn", TILE_OPC_SHRIH_SN, 0x3, 3, TREG_SN, 1,
935 { { 7, 8, 32 }, { 9, 10, 33 }, { 0, }, { 0, }, { 0, } },
936 },
937 { "slt", TILE_OPC_SLT, 0xf, 3, TREG_ZERO, 1,
938 { { 7, 8, 16 }, { 9, 10, 17 }, { 11, 12, 18 }, { 13, 14, 19 }, { 0, } },
939 },
940 { "slt.sn", TILE_OPC_SLT_SN, 0x3, 3, TREG_SN, 1,
941 { { 7, 8, 16 }, { 9, 10, 17 }, { 0, }, { 0, }, { 0, } },
942 },
943 { "slt_u", TILE_OPC_SLT_U, 0xf, 3, TREG_ZERO, 1,
944 { { 7, 8, 16 }, { 9, 10, 17 }, { 11, 12, 18 }, { 13, 14, 19 }, { 0, } },
945 },
946 { "slt_u.sn", TILE_OPC_SLT_U_SN, 0x3, 3, TREG_SN, 1,
947 { { 7, 8, 16 }, { 9, 10, 17 }, { 0, }, { 0, }, { 0, } },
948 },
949 { "sltb", TILE_OPC_SLTB, 0x3, 3, TREG_ZERO, 1,
950 { { 7, 8, 16 }, { 9, 10, 17 }, { 0, }, { 0, }, { 0, } },
951 },
952 { "sltb.sn", TILE_OPC_SLTB_SN, 0x3, 3, TREG_SN, 1,
953 { { 7, 8, 16 }, { 9, 10, 17 }, { 0, }, { 0, }, { 0, } },
954 },
955 { "sltb_u", TILE_OPC_SLTB_U, 0x3, 3, TREG_ZERO, 1,
956 { { 7, 8, 16 }, { 9, 10, 17 }, { 0, }, { 0, }, { 0, } },
957 },
958 { "sltb_u.sn", TILE_OPC_SLTB_U_SN, 0x3, 3, TREG_SN, 1,
959 { { 7, 8, 16 }, { 9, 10, 17 }, { 0, }, { 0, }, { 0, } },
960 },
961 { "slte", TILE_OPC_SLTE, 0xf, 3, TREG_ZERO, 1,
962 { { 7, 8, 16 }, { 9, 10, 17 }, { 11, 12, 18 }, { 13, 14, 19 }, { 0, } },
963 },
964 { "slte.sn", TILE_OPC_SLTE_SN, 0x3, 3, TREG_SN, 1,
965 { { 7, 8, 16 }, { 9, 10, 17 }, { 0, }, { 0, }, { 0, } },
966 },
967 { "slte_u", TILE_OPC_SLTE_U, 0xf, 3, TREG_ZERO, 1,
968 { { 7, 8, 16 }, { 9, 10, 17 }, { 11, 12, 18 }, { 13, 14, 19 }, { 0, } },
969 },
970 { "slte_u.sn", TILE_OPC_SLTE_U_SN, 0x3, 3, TREG_SN, 1,
971 { { 7, 8, 16 }, { 9, 10, 17 }, { 0, }, { 0, }, { 0, } },
972 },
973 { "slteb", TILE_OPC_SLTEB, 0x3, 3, TREG_ZERO, 1,
974 { { 7, 8, 16 }, { 9, 10, 17 }, { 0, }, { 0, }, { 0, } },
975 },
976 { "slteb.sn", TILE_OPC_SLTEB_SN, 0x3, 3, TREG_SN, 1,
977 { { 7, 8, 16 }, { 9, 10, 17 }, { 0, }, { 0, }, { 0, } },
978 },
979 { "slteb_u", TILE_OPC_SLTEB_U, 0x3, 3, TREG_ZERO, 1,
980 { { 7, 8, 16 }, { 9, 10, 17 }, { 0, }, { 0, }, { 0, } },
981 },
982 { "slteb_u.sn", TILE_OPC_SLTEB_U_SN, 0x3, 3, TREG_SN, 1,
983 { { 7, 8, 16 }, { 9, 10, 17 }, { 0, }, { 0, }, { 0, } },
984 },
985 { "slteh", TILE_OPC_SLTEH, 0x3, 3, TREG_ZERO, 1,
986 { { 7, 8, 16 }, { 9, 10, 17 }, { 0, }, { 0, }, { 0, } },
987 },
988 { "slteh.sn", TILE_OPC_SLTEH_SN, 0x3, 3, TREG_SN, 1,
989 { { 7, 8, 16 }, { 9, 10, 17 }, { 0, }, { 0, }, { 0, } },
990 },
991 { "slteh_u", TILE_OPC_SLTEH_U, 0x3, 3, TREG_ZERO, 1,
992 { { 7, 8, 16 }, { 9, 10, 17 }, { 0, }, { 0, }, { 0, } },
993 },
994 { "slteh_u.sn", TILE_OPC_SLTEH_U_SN, 0x3, 3, TREG_SN, 1,
995 { { 7, 8, 16 }, { 9, 10, 17 }, { 0, }, { 0, }, { 0, } },
996 },
997 { "slth", TILE_OPC_SLTH, 0x3, 3, TREG_ZERO, 1,
998 { { 7, 8, 16 }, { 9, 10, 17 }, { 0, }, { 0, }, { 0, } },
999 },
1000 { "slth.sn", TILE_OPC_SLTH_SN, 0x3, 3, TREG_SN, 1,
1001 { { 7, 8, 16 }, { 9, 10, 17 }, { 0, }, { 0, }, { 0, } },
1002 },
1003 { "slth_u", TILE_OPC_SLTH_U, 0x3, 3, TREG_ZERO, 1,
1004 { { 7, 8, 16 }, { 9, 10, 17 }, { 0, }, { 0, }, { 0, } },
1005 },
1006 { "slth_u.sn", TILE_OPC_SLTH_U_SN, 0x3, 3, TREG_SN, 1,
1007 { { 7, 8, 16 }, { 9, 10, 17 }, { 0, }, { 0, }, { 0, } },
1008 },
1009 { "slti", TILE_OPC_SLTI, 0xf, 3, TREG_ZERO, 1,
1010 { { 7, 8, 0 }, { 9, 10, 1 }, { 11, 12, 2 }, { 13, 14, 3 }, { 0, } },
1011 },
1012 { "slti.sn", TILE_OPC_SLTI_SN, 0x3, 3, TREG_SN, 1,
1013 { { 7, 8, 0 }, { 9, 10, 1 }, { 0, }, { 0, }, { 0, } },
1014 },
1015 { "slti_u", TILE_OPC_SLTI_U, 0xf, 3, TREG_ZERO, 1,
1016 { { 7, 8, 0 }, { 9, 10, 1 }, { 11, 12, 2 }, { 13, 14, 3 }, { 0, } },
1017 },
1018 { "slti_u.sn", TILE_OPC_SLTI_U_SN, 0x3, 3, TREG_SN, 1,
1019 { { 7, 8, 0 }, { 9, 10, 1 }, { 0, }, { 0, }, { 0, } },
1020 },
1021 { "sltib", TILE_OPC_SLTIB, 0x3, 3, TREG_ZERO, 1,
1022 { { 7, 8, 0 }, { 9, 10, 1 }, { 0, }, { 0, }, { 0, } },
1023 },
1024 { "sltib.sn", TILE_OPC_SLTIB_SN, 0x3, 3, TREG_SN, 1,
1025 { { 7, 8, 0 }, { 9, 10, 1 }, { 0, }, { 0, }, { 0, } },
1026 },
1027 { "sltib_u", TILE_OPC_SLTIB_U, 0x3, 3, TREG_ZERO, 1,
1028 { { 7, 8, 0 }, { 9, 10, 1 }, { 0, }, { 0, }, { 0, } },
1029 },
1030 { "sltib_u.sn", TILE_OPC_SLTIB_U_SN, 0x3, 3, TREG_SN, 1,
1031 { { 7, 8, 0 }, { 9, 10, 1 }, { 0, }, { 0, }, { 0, } },
1032 },
1033 { "sltih", TILE_OPC_SLTIH, 0x3, 3, TREG_ZERO, 1,
1034 { { 7, 8, 0 }, { 9, 10, 1 }, { 0, }, { 0, }, { 0, } },
1035 },
1036 { "sltih.sn", TILE_OPC_SLTIH_SN, 0x3, 3, TREG_SN, 1,
1037 { { 7, 8, 0 }, { 9, 10, 1 }, { 0, }, { 0, }, { 0, } },
1038 },
1039 { "sltih_u", TILE_OPC_SLTIH_U, 0x3, 3, TREG_ZERO, 1,
1040 { { 7, 8, 0 }, { 9, 10, 1 }, { 0, }, { 0, }, { 0, } },
1041 },
1042 { "sltih_u.sn", TILE_OPC_SLTIH_U_SN, 0x3, 3, TREG_SN, 1,
1043 { { 7, 8, 0 }, { 9, 10, 1 }, { 0, }, { 0, }, { 0, } },
1044 },
1045 { "sne", TILE_OPC_SNE, 0xf, 3, TREG_ZERO, 1,
1046 { { 7, 8, 16 }, { 9, 10, 17 }, { 11, 12, 18 }, { 13, 14, 19 }, { 0, } },
1047 },
1048 { "sne.sn", TILE_OPC_SNE_SN, 0x3, 3, TREG_SN, 1,
1049 { { 7, 8, 16 }, { 9, 10, 17 }, { 0, }, { 0, }, { 0, } },
1050 },
1051 { "sneb", TILE_OPC_SNEB, 0x3, 3, TREG_ZERO, 1,
1052 { { 7, 8, 16 }, { 9, 10, 17 }, { 0, }, { 0, }, { 0, } },
1053 },
1054 { "sneb.sn", TILE_OPC_SNEB_SN, 0x3, 3, TREG_SN, 1,
1055 { { 7, 8, 16 }, { 9, 10, 17 }, { 0, }, { 0, }, { 0, } },
1056 },
1057 { "sneh", TILE_OPC_SNEH, 0x3, 3, TREG_ZERO, 1,
1058 { { 7, 8, 16 }, { 9, 10, 17 }, { 0, }, { 0, }, { 0, } },
1059 },
1060 { "sneh.sn", TILE_OPC_SNEH_SN, 0x3, 3, TREG_SN, 1,
1061 { { 7, 8, 16 }, { 9, 10, 17 }, { 0, }, { 0, }, { 0, } },
1062 },
1063 { "sra", TILE_OPC_SRA, 0xf, 3, TREG_ZERO, 1,
1064 { { 7, 8, 16 }, { 9, 10, 17 }, { 11, 12, 18 }, { 13, 14, 19 }, { 0, } },
1065 },
1066 { "sra.sn", TILE_OPC_SRA_SN, 0x3, 3, TREG_SN, 1,
1067 { { 7, 8, 16 }, { 9, 10, 17 }, { 0, }, { 0, }, { 0, } },
1068 },
1069 { "srab", TILE_OPC_SRAB, 0x3, 3, TREG_ZERO, 1,
1070 { { 7, 8, 16 }, { 9, 10, 17 }, { 0, }, { 0, }, { 0, } },
1071 },
1072 { "srab.sn", TILE_OPC_SRAB_SN, 0x3, 3, TREG_SN, 1,
1073 { { 7, 8, 16 }, { 9, 10, 17 }, { 0, }, { 0, }, { 0, } },
1074 },
1075 { "srah", TILE_OPC_SRAH, 0x3, 3, TREG_ZERO, 1,
1076 { { 7, 8, 16 }, { 9, 10, 17 }, { 0, }, { 0, }, { 0, } },
1077 },
1078 { "srah.sn", TILE_OPC_SRAH_SN, 0x3, 3, TREG_SN, 1,
1079 { { 7, 8, 16 }, { 9, 10, 17 }, { 0, }, { 0, }, { 0, } },
1080 },
1081 { "srai", TILE_OPC_SRAI, 0xf, 3, TREG_ZERO, 1,
1082 { { 7, 8, 32 }, { 9, 10, 33 }, { 11, 12, 34 }, { 13, 14, 35 }, { 0, } },
1083 },
1084 { "srai.sn", TILE_OPC_SRAI_SN, 0x3, 3, TREG_SN, 1,
1085 { { 7, 8, 32 }, { 9, 10, 33 }, { 0, }, { 0, }, { 0, } },
1086 },
1087 { "sraib", TILE_OPC_SRAIB, 0x3, 3, TREG_ZERO, 1,
1088 { { 7, 8, 32 }, { 9, 10, 33 }, { 0, }, { 0, }, { 0, } },
1089 },
1090 { "sraib.sn", TILE_OPC_SRAIB_SN, 0x3, 3, TREG_SN, 1,
1091 { { 7, 8, 32 }, { 9, 10, 33 }, { 0, }, { 0, }, { 0, } },
1092 },
1093 { "sraih", TILE_OPC_SRAIH, 0x3, 3, TREG_ZERO, 1,
1094 { { 7, 8, 32 }, { 9, 10, 33 }, { 0, }, { 0, }, { 0, } },
1095 },
1096 { "sraih.sn", TILE_OPC_SRAIH_SN, 0x3, 3, TREG_SN, 1,
1097 { { 7, 8, 32 }, { 9, 10, 33 }, { 0, }, { 0, }, { 0, } },
1098 },
1099 { "sub", TILE_OPC_SUB, 0xf, 3, TREG_ZERO, 1,
1100 { { 7, 8, 16 }, { 9, 10, 17 }, { 11, 12, 18 }, { 13, 14, 19 }, { 0, } },
1101 },
1102 { "sub.sn", TILE_OPC_SUB_SN, 0x3, 3, TREG_SN, 1,
1103 { { 7, 8, 16 }, { 9, 10, 17 }, { 0, }, { 0, }, { 0, } },
1104 },
1105 { "subb", TILE_OPC_SUBB, 0x3, 3, TREG_ZERO, 1,
1106 { { 7, 8, 16 }, { 9, 10, 17 }, { 0, }, { 0, }, { 0, } },
1107 },
1108 { "subb.sn", TILE_OPC_SUBB_SN, 0x3, 3, TREG_SN, 1,
1109 { { 7, 8, 16 }, { 9, 10, 17 }, { 0, }, { 0, }, { 0, } },
1110 },
1111 { "subbs_u", TILE_OPC_SUBBS_U, 0x3, 3, TREG_ZERO, 1,
1112 { { 7, 8, 16 }, { 9, 10, 17 }, { 0, }, { 0, }, { 0, } },
1113 },
1114 { "subbs_u.sn", TILE_OPC_SUBBS_U_SN, 0x3, 3, TREG_SN, 1,
1115 { { 7, 8, 16 }, { 9, 10, 17 }, { 0, }, { 0, }, { 0, } },
1116 },
1117 { "subh", TILE_OPC_SUBH, 0x3, 3, TREG_ZERO, 1,
1118 { { 7, 8, 16 }, { 9, 10, 17 }, { 0, }, { 0, }, { 0, } },
1119 },
1120 { "subh.sn", TILE_OPC_SUBH_SN, 0x3, 3, TREG_SN, 1,
1121 { { 7, 8, 16 }, { 9, 10, 17 }, { 0, }, { 0, }, { 0, } },
1122 },
1123 { "subhs", TILE_OPC_SUBHS, 0x3, 3, TREG_ZERO, 1,
1124 { { 7, 8, 16 }, { 9, 10, 17 }, { 0, }, { 0, }, { 0, } },
1125 },
1126 { "subhs.sn", TILE_OPC_SUBHS_SN, 0x3, 3, TREG_SN, 1,
1127 { { 7, 8, 16 }, { 9, 10, 17 }, { 0, }, { 0, }, { 0, } },
1128 },
1129 { "subs", TILE_OPC_SUBS, 0x3, 3, TREG_ZERO, 1,
1130 { { 7, 8, 16 }, { 9, 10, 17 }, { 0, }, { 0, }, { 0, } },
1131 },
1132 { "subs.sn", TILE_OPC_SUBS_SN, 0x3, 3, TREG_SN, 1,
1133 { { 7, 8, 16 }, { 9, 10, 17 }, { 0, }, { 0, }, { 0, } },
1134 },
1135 { "sw", TILE_OPC_SW, 0x12, 2, TREG_ZERO, 1,
1136 { { 0, }, { 10, 17 }, { 0, }, { 0, }, { 15, 36 } },
1137 },
1138 { "swadd", TILE_OPC_SWADD, 0x2, 3, TREG_ZERO, 1,
1139 { { 0, }, { 24, 17, 37 }, { 0, }, { 0, }, { 0, } },
1140 },
1141 { "swint0", TILE_OPC_SWINT0, 0x2, 0, TREG_ZERO, 0,
1142 { { 0, }, { }, { 0, }, { 0, }, { 0, } },
1143 },
1144 { "swint1", TILE_OPC_SWINT1, 0x2, 0, TREG_ZERO, 0,
1145 { { 0, }, { }, { 0, }, { 0, }, { 0, } },
1146 },
1147 { "swint2", TILE_OPC_SWINT2, 0x2, 0, TREG_ZERO, 0,
1148 { { 0, }, { }, { 0, }, { 0, }, { 0, } },
1149 },
1150 { "swint3", TILE_OPC_SWINT3, 0x2, 0, TREG_ZERO, 0,
1151 { { 0, }, { }, { 0, }, { 0, }, { 0, } },
1152 },
1153 { "tblidxb0", TILE_OPC_TBLIDXB0, 0x5, 2, TREG_ZERO, 1,
1154 { { 21, 8 }, { 0, }, { 31, 12 }, { 0, }, { 0, } },
1155 },
1156 { "tblidxb0.sn", TILE_OPC_TBLIDXB0_SN, 0x1, 2, TREG_SN, 1,
1157 { { 21, 8 }, { 0, }, { 0, }, { 0, }, { 0, } },
1158 },
1159 { "tblidxb1", TILE_OPC_TBLIDXB1, 0x5, 2, TREG_ZERO, 1,
1160 { { 21, 8 }, { 0, }, { 31, 12 }, { 0, }, { 0, } },
1161 },
1162 { "tblidxb1.sn", TILE_OPC_TBLIDXB1_SN, 0x1, 2, TREG_SN, 1,
1163 { { 21, 8 }, { 0, }, { 0, }, { 0, }, { 0, } },
1164 },
1165 { "tblidxb2", TILE_OPC_TBLIDXB2, 0x5, 2, TREG_ZERO, 1,
1166 { { 21, 8 }, { 0, }, { 31, 12 }, { 0, }, { 0, } },
1167 },
1168 { "tblidxb2.sn", TILE_OPC_TBLIDXB2_SN, 0x1, 2, TREG_SN, 1,
1169 { { 21, 8 }, { 0, }, { 0, }, { 0, }, { 0, } },
1170 },
1171 { "tblidxb3", TILE_OPC_TBLIDXB3, 0x5, 2, TREG_ZERO, 1,
1172 { { 21, 8 }, { 0, }, { 31, 12 }, { 0, }, { 0, } },
1173 },
1174 { "tblidxb3.sn", TILE_OPC_TBLIDXB3_SN, 0x1, 2, TREG_SN, 1,
1175 { { 21, 8 }, { 0, }, { 0, }, { 0, }, { 0, } },
1176 },
1177 { "tns", TILE_OPC_TNS, 0x2, 2, TREG_ZERO, 1,
1178 { { 0, }, { 9, 10 }, { 0, }, { 0, }, { 0, } },
1179 },
1180 { "tns.sn", TILE_OPC_TNS_SN, 0x2, 2, TREG_SN, 1,
1181 { { 0, }, { 9, 10 }, { 0, }, { 0, }, { 0, } },
1182 },
1183 { "wh64", TILE_OPC_WH64, 0x2, 1, TREG_ZERO, 1,
1184 { { 0, }, { 10 }, { 0, }, { 0, }, { 0, } },
1185 },
1186 { "xor", TILE_OPC_XOR, 0xf, 3, TREG_ZERO, 1,
1187 { { 7, 8, 16 }, { 9, 10, 17 }, { 11, 12, 18 }, { 13, 14, 19 }, { 0, } },
1188 },
1189 { "xor.sn", TILE_OPC_XOR_SN, 0x3, 3, TREG_SN, 1,
1190 { { 7, 8, 16 }, { 9, 10, 17 }, { 0, }, { 0, }, { 0, } },
1191 },
1192 { "xori", TILE_OPC_XORI, 0x3, 3, TREG_ZERO, 1,
1193 { { 7, 8, 0 }, { 9, 10, 1 }, { 0, }, { 0, }, { 0, } },
1194 },
1195 { "xori.sn", TILE_OPC_XORI_SN, 0x3, 3, TREG_SN, 1,
1196 { { 7, 8, 0 }, { 9, 10, 1 }, { 0, }, { 0, }, { 0, } },
1197 },
1198 { NULL, TILE_OPC_NONE, 0, 0, TREG_ZERO, 0, { { 0, } },
1199 }
1200};
1201#define BITFIELD(start, size) ((start) | (((1 << (size)) - 1) << 6))
1202#define CHILD(array_index) (TILE_OPC_NONE + (array_index))
1203
1204static const unsigned short decode_X0_fsm[1153] =
1205{
1206 BITFIELD(22, 9) /* index 0 */,
1207 CHILD(513), CHILD(530), CHILD(547), CHILD(564), CHILD(596), CHILD(613),
1208 CHILD(630), TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE,
1209 TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE,
1210 TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE,
1211 TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE,
1212 TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE,
1213 TILE_OPC_NONE, CHILD(663), CHILD(680), CHILD(697), CHILD(714), CHILD(746),
1214 CHILD(763), CHILD(780), TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE,
1215 TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE,
1216 TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE,
1217 TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE,
1218 TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE,
1219 TILE_OPC_NONE, TILE_OPC_NONE, CHILD(813), CHILD(813), CHILD(813),
1220 CHILD(813), CHILD(813), CHILD(813), CHILD(813), CHILD(813), CHILD(813),
1221 CHILD(813), CHILD(813), CHILD(813), CHILD(813), CHILD(813), CHILD(813),
1222 CHILD(813), CHILD(813), CHILD(813), CHILD(813), CHILD(813), CHILD(813),
1223 CHILD(813), CHILD(813), CHILD(813), CHILD(813), CHILD(813), CHILD(813),
1224 CHILD(813), CHILD(813), CHILD(813), CHILD(813), CHILD(813), CHILD(813),
1225 CHILD(813), CHILD(813), CHILD(813), CHILD(813), CHILD(813), CHILD(813),
1226 CHILD(813), CHILD(813), CHILD(813), CHILD(813), CHILD(813), CHILD(813),
1227 CHILD(813), CHILD(813), CHILD(813), CHILD(813), CHILD(813), CHILD(813),
1228 CHILD(813), CHILD(813), CHILD(813), CHILD(813), CHILD(813), CHILD(813),
1229 CHILD(813), CHILD(813), CHILD(813), CHILD(813), CHILD(813), CHILD(813),
1230 CHILD(813), CHILD(828), CHILD(828), CHILD(828), CHILD(828), CHILD(828),
1231 CHILD(828), CHILD(828), CHILD(828), CHILD(828), CHILD(828), CHILD(828),
1232 CHILD(828), CHILD(828), CHILD(828), CHILD(828), CHILD(828), CHILD(828),
1233 CHILD(828), CHILD(828), CHILD(828), CHILD(828), CHILD(828), CHILD(828),
1234 CHILD(828), CHILD(828), CHILD(828), CHILD(828), CHILD(828), CHILD(828),
1235 CHILD(828), CHILD(828), CHILD(828), CHILD(828), CHILD(828), CHILD(828),
1236 CHILD(828), CHILD(828), CHILD(828), CHILD(828), CHILD(828), CHILD(828),
1237 CHILD(828), CHILD(828), CHILD(828), CHILD(828), CHILD(828), CHILD(828),
1238 CHILD(828), CHILD(828), CHILD(828), CHILD(828), CHILD(828), CHILD(828),
1239 CHILD(828), CHILD(828), CHILD(828), CHILD(828), CHILD(828), CHILD(828),
1240 CHILD(828), CHILD(828), CHILD(828), CHILD(828), CHILD(828), CHILD(843),
1241 CHILD(843), CHILD(843), CHILD(843), CHILD(843), CHILD(843), CHILD(843),
1242 CHILD(843), CHILD(843), CHILD(843), CHILD(843), CHILD(843), CHILD(843),
1243 CHILD(843), CHILD(843), CHILD(843), CHILD(843), CHILD(843), CHILD(843),
1244 CHILD(843), CHILD(843), CHILD(843), CHILD(843), CHILD(843), CHILD(843),
1245 CHILD(843), CHILD(843), CHILD(843), CHILD(843), CHILD(843), CHILD(843),
1246 CHILD(843), CHILD(843), CHILD(843), CHILD(843), CHILD(843), CHILD(843),
1247 CHILD(843), CHILD(843), CHILD(843), CHILD(843), CHILD(843), CHILD(843),
1248 CHILD(843), CHILD(843), CHILD(843), CHILD(843), CHILD(843), CHILD(843),
1249 CHILD(843), CHILD(843), CHILD(843), CHILD(843), CHILD(843), CHILD(843),
1250 CHILD(843), CHILD(843), CHILD(843), CHILD(843), CHILD(843), CHILD(843),
1251 CHILD(843), CHILD(843), CHILD(843), CHILD(873), CHILD(878), CHILD(883),
1252 CHILD(903), CHILD(908), TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE,
1253 TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE,
1254 TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE,
1255 TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE,
1256 TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE,
1257 TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, CHILD(913),
1258 CHILD(918), CHILD(923), CHILD(943), CHILD(948), TILE_OPC_NONE,
1259 TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE,
1260 TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE,
1261 TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE,
1262 TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE,
1263 TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE,
1264 TILE_OPC_NONE, CHILD(953), TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE,
1265 TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE,
1266 TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE,
1267 TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE,
1268 TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE,
1269 TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE,
1270 TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, CHILD(988), TILE_OPC_NONE,
1271 TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE,
1272 TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE,
1273 TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE,
1274 TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE,
1275 TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE,
1276 TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE,
1277 TILE_OPC_MM, TILE_OPC_MM, TILE_OPC_MM, TILE_OPC_MM, TILE_OPC_MM,
1278 TILE_OPC_MM, TILE_OPC_MM, TILE_OPC_MM, TILE_OPC_MM, TILE_OPC_MM,
1279 TILE_OPC_MM, TILE_OPC_MM, TILE_OPC_MM, TILE_OPC_MM, TILE_OPC_MM,
1280 TILE_OPC_MM, TILE_OPC_MM, TILE_OPC_MM, TILE_OPC_MM, TILE_OPC_MM,
1281 TILE_OPC_MM, TILE_OPC_MM, TILE_OPC_MM, TILE_OPC_MM, TILE_OPC_MM,
1282 TILE_OPC_MM, TILE_OPC_MM, TILE_OPC_MM, TILE_OPC_MM, TILE_OPC_MM,
1283 TILE_OPC_MM, TILE_OPC_MM, TILE_OPC_MM, TILE_OPC_MM, TILE_OPC_MM,
1284 TILE_OPC_MM, TILE_OPC_MM, TILE_OPC_MM, TILE_OPC_MM, TILE_OPC_MM,
1285 TILE_OPC_MM, TILE_OPC_MM, TILE_OPC_MM, TILE_OPC_MM, TILE_OPC_MM,
1286 TILE_OPC_MM, TILE_OPC_MM, TILE_OPC_MM, TILE_OPC_MM, TILE_OPC_MM,
1287 TILE_OPC_MM, TILE_OPC_MM, TILE_OPC_MM, TILE_OPC_MM, TILE_OPC_MM,
1288 TILE_OPC_MM, TILE_OPC_MM, TILE_OPC_MM, TILE_OPC_MM, TILE_OPC_MM,
1289 TILE_OPC_MM, TILE_OPC_MM, TILE_OPC_MM, TILE_OPC_MM, CHILD(993),
1290 TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE,
1291 TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE,
1292 TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE,
1293 TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE,
1294 TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE,
1295 TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE,
1296 TILE_OPC_NONE, CHILD(1076), TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE,
1297 TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE,
1298 TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE,
1299 TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE,
1300 TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE,
1301 TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE,
1302 TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE,
1303 BITFIELD(18, 4) /* index 513 */,
1304 TILE_OPC_NONE, TILE_OPC_ADDB, TILE_OPC_ADDH, TILE_OPC_ADD,
1305 TILE_OPC_ADIFFB_U, TILE_OPC_ADIFFH, TILE_OPC_AND, TILE_OPC_AVGB_U,
1306 TILE_OPC_AVGH, TILE_OPC_CRC32_32, TILE_OPC_CRC32_8, TILE_OPC_INTHB,
1307 TILE_OPC_INTHH, TILE_OPC_INTLB, TILE_OPC_INTLH, TILE_OPC_MAXB_U,
1308 BITFIELD(18, 4) /* index 530 */,
1309 TILE_OPC_MAXH, TILE_OPC_MINB_U, TILE_OPC_MINH, TILE_OPC_MNZB, TILE_OPC_MNZH,
1310 TILE_OPC_MNZ, TILE_OPC_MULHHA_SS, TILE_OPC_MULHHA_SU, TILE_OPC_MULHHA_UU,
1311 TILE_OPC_MULHHSA_UU, TILE_OPC_MULHH_SS, TILE_OPC_MULHH_SU,
1312 TILE_OPC_MULHH_UU, TILE_OPC_MULHLA_SS, TILE_OPC_MULHLA_SU,
1313 TILE_OPC_MULHLA_US,
1314 BITFIELD(18, 4) /* index 547 */,
1315 TILE_OPC_MULHLA_UU, TILE_OPC_MULHLSA_UU, TILE_OPC_MULHL_SS,
1316 TILE_OPC_MULHL_SU, TILE_OPC_MULHL_US, TILE_OPC_MULHL_UU, TILE_OPC_MULLLA_SS,
1317 TILE_OPC_MULLLA_SU, TILE_OPC_MULLLA_UU, TILE_OPC_MULLLSA_UU,
1318 TILE_OPC_MULLL_SS, TILE_OPC_MULLL_SU, TILE_OPC_MULLL_UU, TILE_OPC_MVNZ,
1319 TILE_OPC_MVZ, TILE_OPC_MZB,
1320 BITFIELD(18, 4) /* index 564 */,
1321 TILE_OPC_MZH, TILE_OPC_MZ, TILE_OPC_NOR, CHILD(581), TILE_OPC_PACKHB,
1322 TILE_OPC_PACKLB, TILE_OPC_RL, TILE_OPC_S1A, TILE_OPC_S2A, TILE_OPC_S3A,
1323 TILE_OPC_SADAB_U, TILE_OPC_SADAH, TILE_OPC_SADAH_U, TILE_OPC_SADB_U,
1324 TILE_OPC_SADH, TILE_OPC_SADH_U,
1325 BITFIELD(12, 2) /* index 581 */,
1326 TILE_OPC_OR, TILE_OPC_OR, TILE_OPC_OR, CHILD(586),
1327 BITFIELD(14, 2) /* index 586 */,
1328 TILE_OPC_OR, TILE_OPC_OR, TILE_OPC_OR, CHILD(591),
1329 BITFIELD(16, 2) /* index 591 */,
1330 TILE_OPC_OR, TILE_OPC_OR, TILE_OPC_OR, TILE_OPC_MOVE,
1331 BITFIELD(18, 4) /* index 596 */,
1332 TILE_OPC_SEQB, TILE_OPC_SEQH, TILE_OPC_SEQ, TILE_OPC_SHLB, TILE_OPC_SHLH,
1333 TILE_OPC_SHL, TILE_OPC_SHRB, TILE_OPC_SHRH, TILE_OPC_SHR, TILE_OPC_SLTB,
1334 TILE_OPC_SLTB_U, TILE_OPC_SLTEB, TILE_OPC_SLTEB_U, TILE_OPC_SLTEH,
1335 TILE_OPC_SLTEH_U, TILE_OPC_SLTE,
1336 BITFIELD(18, 4) /* index 613 */,
1337 TILE_OPC_SLTE_U, TILE_OPC_SLTH, TILE_OPC_SLTH_U, TILE_OPC_SLT,
1338 TILE_OPC_SLT_U, TILE_OPC_SNEB, TILE_OPC_SNEH, TILE_OPC_SNE, TILE_OPC_SRAB,
1339 TILE_OPC_SRAH, TILE_OPC_SRA, TILE_OPC_SUBB, TILE_OPC_SUBH, TILE_OPC_SUB,
1340 TILE_OPC_XOR, TILE_OPC_DWORD_ALIGN,
1341 BITFIELD(18, 3) /* index 630 */,
1342 CHILD(639), CHILD(642), CHILD(645), CHILD(648), CHILD(651), CHILD(654),
1343 CHILD(657), CHILD(660),
1344 BITFIELD(21, 1) /* index 639 */,
1345 TILE_OPC_ADDS, TILE_OPC_NONE,
1346 BITFIELD(21, 1) /* index 642 */,
1347 TILE_OPC_SUBS, TILE_OPC_NONE,
1348 BITFIELD(21, 1) /* index 645 */,
1349 TILE_OPC_ADDBS_U, TILE_OPC_NONE,
1350 BITFIELD(21, 1) /* index 648 */,
1351 TILE_OPC_ADDHS, TILE_OPC_NONE,
1352 BITFIELD(21, 1) /* index 651 */,
1353 TILE_OPC_SUBBS_U, TILE_OPC_NONE,
1354 BITFIELD(21, 1) /* index 654 */,
1355 TILE_OPC_SUBHS, TILE_OPC_NONE,
1356 BITFIELD(21, 1) /* index 657 */,
1357 TILE_OPC_PACKHS, TILE_OPC_NONE,
1358 BITFIELD(21, 1) /* index 660 */,
1359 TILE_OPC_PACKBS_U, TILE_OPC_NONE,
1360 BITFIELD(18, 4) /* index 663 */,
1361 TILE_OPC_NONE, TILE_OPC_ADDB_SN, TILE_OPC_ADDH_SN, TILE_OPC_ADD_SN,
1362 TILE_OPC_ADIFFB_U_SN, TILE_OPC_ADIFFH_SN, TILE_OPC_AND_SN,
1363 TILE_OPC_AVGB_U_SN, TILE_OPC_AVGH_SN, TILE_OPC_CRC32_32_SN,
1364 TILE_OPC_CRC32_8_SN, TILE_OPC_INTHB_SN, TILE_OPC_INTHH_SN,
1365 TILE_OPC_INTLB_SN, TILE_OPC_INTLH_SN, TILE_OPC_MAXB_U_SN,
1366 BITFIELD(18, 4) /* index 680 */,
1367 TILE_OPC_MAXH_SN, TILE_OPC_MINB_U_SN, TILE_OPC_MINH_SN, TILE_OPC_MNZB_SN,
1368 TILE_OPC_MNZH_SN, TILE_OPC_MNZ_SN, TILE_OPC_MULHHA_SS_SN,
1369 TILE_OPC_MULHHA_SU_SN, TILE_OPC_MULHHA_UU_SN, TILE_OPC_MULHHSA_UU_SN,
1370 TILE_OPC_MULHH_SS_SN, TILE_OPC_MULHH_SU_SN, TILE_OPC_MULHH_UU_SN,
1371 TILE_OPC_MULHLA_SS_SN, TILE_OPC_MULHLA_SU_SN, TILE_OPC_MULHLA_US_SN,
1372 BITFIELD(18, 4) /* index 697 */,
1373 TILE_OPC_MULHLA_UU_SN, TILE_OPC_MULHLSA_UU_SN, TILE_OPC_MULHL_SS_SN,
1374 TILE_OPC_MULHL_SU_SN, TILE_OPC_MULHL_US_SN, TILE_OPC_MULHL_UU_SN,
1375 TILE_OPC_MULLLA_SS_SN, TILE_OPC_MULLLA_SU_SN, TILE_OPC_MULLLA_UU_SN,
1376 TILE_OPC_MULLLSA_UU_SN, TILE_OPC_MULLL_SS_SN, TILE_OPC_MULLL_SU_SN,
1377 TILE_OPC_MULLL_UU_SN, TILE_OPC_MVNZ_SN, TILE_OPC_MVZ_SN, TILE_OPC_MZB_SN,
1378 BITFIELD(18, 4) /* index 714 */,
1379 TILE_OPC_MZH_SN, TILE_OPC_MZ_SN, TILE_OPC_NOR_SN, CHILD(731),
1380 TILE_OPC_PACKHB_SN, TILE_OPC_PACKLB_SN, TILE_OPC_RL_SN, TILE_OPC_S1A_SN,
1381 TILE_OPC_S2A_SN, TILE_OPC_S3A_SN, TILE_OPC_SADAB_U_SN, TILE_OPC_SADAH_SN,
1382 TILE_OPC_SADAH_U_SN, TILE_OPC_SADB_U_SN, TILE_OPC_SADH_SN,
1383 TILE_OPC_SADH_U_SN,
1384 BITFIELD(12, 2) /* index 731 */,
1385 TILE_OPC_OR_SN, TILE_OPC_OR_SN, TILE_OPC_OR_SN, CHILD(736),
1386 BITFIELD(14, 2) /* index 736 */,
1387 TILE_OPC_OR_SN, TILE_OPC_OR_SN, TILE_OPC_OR_SN, CHILD(741),
1388 BITFIELD(16, 2) /* index 741 */,
1389 TILE_OPC_OR_SN, TILE_OPC_OR_SN, TILE_OPC_OR_SN, TILE_OPC_MOVE_SN,
1390 BITFIELD(18, 4) /* index 746 */,
1391 TILE_OPC_SEQB_SN, TILE_OPC_SEQH_SN, TILE_OPC_SEQ_SN, TILE_OPC_SHLB_SN,
1392 TILE_OPC_SHLH_SN, TILE_OPC_SHL_SN, TILE_OPC_SHRB_SN, TILE_OPC_SHRH_SN,
1393 TILE_OPC_SHR_SN, TILE_OPC_SLTB_SN, TILE_OPC_SLTB_U_SN, TILE_OPC_SLTEB_SN,
1394 TILE_OPC_SLTEB_U_SN, TILE_OPC_SLTEH_SN, TILE_OPC_SLTEH_U_SN,
1395 TILE_OPC_SLTE_SN,
1396 BITFIELD(18, 4) /* index 763 */,
1397 TILE_OPC_SLTE_U_SN, TILE_OPC_SLTH_SN, TILE_OPC_SLTH_U_SN, TILE_OPC_SLT_SN,
1398 TILE_OPC_SLT_U_SN, TILE_OPC_SNEB_SN, TILE_OPC_SNEH_SN, TILE_OPC_SNE_SN,
1399 TILE_OPC_SRAB_SN, TILE_OPC_SRAH_SN, TILE_OPC_SRA_SN, TILE_OPC_SUBB_SN,
1400 TILE_OPC_SUBH_SN, TILE_OPC_SUB_SN, TILE_OPC_XOR_SN, TILE_OPC_DWORD_ALIGN_SN,
1401 BITFIELD(18, 3) /* index 780 */,
1402 CHILD(789), CHILD(792), CHILD(795), CHILD(798), CHILD(801), CHILD(804),
1403 CHILD(807), CHILD(810),
1404 BITFIELD(21, 1) /* index 789 */,
1405 TILE_OPC_ADDS_SN, TILE_OPC_NONE,
1406 BITFIELD(21, 1) /* index 792 */,
1407 TILE_OPC_SUBS_SN, TILE_OPC_NONE,
1408 BITFIELD(21, 1) /* index 795 */,
1409 TILE_OPC_ADDBS_U_SN, TILE_OPC_NONE,
1410 BITFIELD(21, 1) /* index 798 */,
1411 TILE_OPC_ADDHS_SN, TILE_OPC_NONE,
1412 BITFIELD(21, 1) /* index 801 */,
1413 TILE_OPC_SUBBS_U_SN, TILE_OPC_NONE,
1414 BITFIELD(21, 1) /* index 804 */,
1415 TILE_OPC_SUBHS_SN, TILE_OPC_NONE,
1416 BITFIELD(21, 1) /* index 807 */,
1417 TILE_OPC_PACKHS_SN, TILE_OPC_NONE,
1418 BITFIELD(21, 1) /* index 810 */,
1419 TILE_OPC_PACKBS_U_SN, TILE_OPC_NONE,
1420 BITFIELD(6, 2) /* index 813 */,
1421 TILE_OPC_ADDLI_SN, TILE_OPC_ADDLI_SN, TILE_OPC_ADDLI_SN, CHILD(818),
1422 BITFIELD(8, 2) /* index 818 */,
1423 TILE_OPC_ADDLI_SN, TILE_OPC_ADDLI_SN, TILE_OPC_ADDLI_SN, CHILD(823),
1424 BITFIELD(10, 2) /* index 823 */,
1425 TILE_OPC_ADDLI_SN, TILE_OPC_ADDLI_SN, TILE_OPC_ADDLI_SN, TILE_OPC_MOVELI_SN,
1426 BITFIELD(6, 2) /* index 828 */,
1427 TILE_OPC_ADDLI, TILE_OPC_ADDLI, TILE_OPC_ADDLI, CHILD(833),
1428 BITFIELD(8, 2) /* index 833 */,
1429 TILE_OPC_ADDLI, TILE_OPC_ADDLI, TILE_OPC_ADDLI, CHILD(838),
1430 BITFIELD(10, 2) /* index 838 */,
1431 TILE_OPC_ADDLI, TILE_OPC_ADDLI, TILE_OPC_ADDLI, TILE_OPC_MOVELI,
1432 BITFIELD(0, 2) /* index 843 */,
1433 TILE_OPC_AULI, TILE_OPC_AULI, TILE_OPC_AULI, CHILD(848),
1434 BITFIELD(2, 2) /* index 848 */,
1435 TILE_OPC_AULI, TILE_OPC_AULI, TILE_OPC_AULI, CHILD(853),
1436 BITFIELD(4, 2) /* index 853 */,
1437 TILE_OPC_AULI, TILE_OPC_AULI, TILE_OPC_AULI, CHILD(858),
1438 BITFIELD(6, 2) /* index 858 */,
1439 TILE_OPC_AULI, TILE_OPC_AULI, TILE_OPC_AULI, CHILD(863),
1440 BITFIELD(8, 2) /* index 863 */,
1441 TILE_OPC_AULI, TILE_OPC_AULI, TILE_OPC_AULI, CHILD(868),
1442 BITFIELD(10, 2) /* index 868 */,
1443 TILE_OPC_AULI, TILE_OPC_AULI, TILE_OPC_AULI, TILE_OPC_INFOL,
1444 BITFIELD(20, 2) /* index 873 */,
1445 TILE_OPC_NONE, TILE_OPC_ADDIB, TILE_OPC_ADDIH, TILE_OPC_ADDI,
1446 BITFIELD(20, 2) /* index 878 */,
1447 TILE_OPC_MAXIB_U, TILE_OPC_MAXIH, TILE_OPC_MINIB_U, TILE_OPC_MINIH,
1448 BITFIELD(20, 2) /* index 883 */,
1449 CHILD(888), TILE_OPC_SEQIB, TILE_OPC_SEQIH, TILE_OPC_SEQI,
1450 BITFIELD(6, 2) /* index 888 */,
1451 TILE_OPC_ORI, TILE_OPC_ORI, TILE_OPC_ORI, CHILD(893),
1452 BITFIELD(8, 2) /* index 893 */,
1453 TILE_OPC_ORI, TILE_OPC_ORI, TILE_OPC_ORI, CHILD(898),
1454 BITFIELD(10, 2) /* index 898 */,
1455 TILE_OPC_ORI, TILE_OPC_ORI, TILE_OPC_ORI, TILE_OPC_MOVEI,
1456 BITFIELD(20, 2) /* index 903 */,
1457 TILE_OPC_SLTIB, TILE_OPC_SLTIB_U, TILE_OPC_SLTIH, TILE_OPC_SLTIH_U,
1458 BITFIELD(20, 2) /* index 908 */,
1459 TILE_OPC_SLTI, TILE_OPC_SLTI_U, TILE_OPC_NONE, TILE_OPC_NONE,
1460 BITFIELD(20, 2) /* index 913 */,
1461 TILE_OPC_NONE, TILE_OPC_ADDIB_SN, TILE_OPC_ADDIH_SN, TILE_OPC_ADDI_SN,
1462 BITFIELD(20, 2) /* index 918 */,
1463 TILE_OPC_MAXIB_U_SN, TILE_OPC_MAXIH_SN, TILE_OPC_MINIB_U_SN,
1464 TILE_OPC_MINIH_SN,
1465 BITFIELD(20, 2) /* index 923 */,
1466 CHILD(928), TILE_OPC_SEQIB_SN, TILE_OPC_SEQIH_SN, TILE_OPC_SEQI_SN,
1467 BITFIELD(6, 2) /* index 928 */,
1468 TILE_OPC_ORI_SN, TILE_OPC_ORI_SN, TILE_OPC_ORI_SN, CHILD(933),
1469 BITFIELD(8, 2) /* index 933 */,
1470 TILE_OPC_ORI_SN, TILE_OPC_ORI_SN, TILE_OPC_ORI_SN, CHILD(938),
1471 BITFIELD(10, 2) /* index 938 */,
1472 TILE_OPC_ORI_SN, TILE_OPC_ORI_SN, TILE_OPC_ORI_SN, TILE_OPC_MOVEI_SN,
1473 BITFIELD(20, 2) /* index 943 */,
1474 TILE_OPC_SLTIB_SN, TILE_OPC_SLTIB_U_SN, TILE_OPC_SLTIH_SN,
1475 TILE_OPC_SLTIH_U_SN,
1476 BITFIELD(20, 2) /* index 948 */,
1477 TILE_OPC_SLTI_SN, TILE_OPC_SLTI_U_SN, TILE_OPC_NONE, TILE_OPC_NONE,
1478 BITFIELD(20, 2) /* index 953 */,
1479 TILE_OPC_NONE, CHILD(958), TILE_OPC_XORI, TILE_OPC_NONE,
1480 BITFIELD(0, 2) /* index 958 */,
1481 TILE_OPC_ANDI, TILE_OPC_ANDI, TILE_OPC_ANDI, CHILD(963),
1482 BITFIELD(2, 2) /* index 963 */,
1483 TILE_OPC_ANDI, TILE_OPC_ANDI, TILE_OPC_ANDI, CHILD(968),
1484 BITFIELD(4, 2) /* index 968 */,
1485 TILE_OPC_ANDI, TILE_OPC_ANDI, TILE_OPC_ANDI, CHILD(973),
1486 BITFIELD(6, 2) /* index 973 */,
1487 TILE_OPC_ANDI, TILE_OPC_ANDI, TILE_OPC_ANDI, CHILD(978),
1488 BITFIELD(8, 2) /* index 978 */,
1489 TILE_OPC_ANDI, TILE_OPC_ANDI, TILE_OPC_ANDI, CHILD(983),
1490 BITFIELD(10, 2) /* index 983 */,
1491 TILE_OPC_ANDI, TILE_OPC_ANDI, TILE_OPC_ANDI, TILE_OPC_INFO,
1492 BITFIELD(20, 2) /* index 988 */,
1493 TILE_OPC_NONE, TILE_OPC_ANDI_SN, TILE_OPC_XORI_SN, TILE_OPC_NONE,
1494 BITFIELD(17, 5) /* index 993 */,
1495 TILE_OPC_NONE, TILE_OPC_RLI, TILE_OPC_SHLIB, TILE_OPC_SHLIH, TILE_OPC_SHLI,
1496 TILE_OPC_SHRIB, TILE_OPC_SHRIH, TILE_OPC_SHRI, TILE_OPC_SRAIB,
1497 TILE_OPC_SRAIH, TILE_OPC_SRAI, CHILD(1026), TILE_OPC_NONE, TILE_OPC_NONE,
1498 TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE,
1499 TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE,
1500 TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE,
1501 TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE,
1502 BITFIELD(12, 4) /* index 1026 */,
1503 TILE_OPC_NONE, CHILD(1043), CHILD(1046), CHILD(1049), CHILD(1052),
1504 CHILD(1055), CHILD(1058), CHILD(1061), CHILD(1064), CHILD(1067),
1505 CHILD(1070), CHILD(1073), TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE,
1506 TILE_OPC_NONE,
1507 BITFIELD(16, 1) /* index 1043 */,
1508 TILE_OPC_BITX, TILE_OPC_NONE,
1509 BITFIELD(16, 1) /* index 1046 */,
1510 TILE_OPC_BYTEX, TILE_OPC_NONE,
1511 BITFIELD(16, 1) /* index 1049 */,
1512 TILE_OPC_CLZ, TILE_OPC_NONE,
1513 BITFIELD(16, 1) /* index 1052 */,
1514 TILE_OPC_CTZ, TILE_OPC_NONE,
1515 BITFIELD(16, 1) /* index 1055 */,
1516 TILE_OPC_FNOP, TILE_OPC_NONE,
1517 BITFIELD(16, 1) /* index 1058 */,
1518 TILE_OPC_NOP, TILE_OPC_NONE,
1519 BITFIELD(16, 1) /* index 1061 */,
1520 TILE_OPC_PCNT, TILE_OPC_NONE,
1521 BITFIELD(16, 1) /* index 1064 */,
1522 TILE_OPC_TBLIDXB0, TILE_OPC_NONE,
1523 BITFIELD(16, 1) /* index 1067 */,
1524 TILE_OPC_TBLIDXB1, TILE_OPC_NONE,
1525 BITFIELD(16, 1) /* index 1070 */,
1526 TILE_OPC_TBLIDXB2, TILE_OPC_NONE,
1527 BITFIELD(16, 1) /* index 1073 */,
1528 TILE_OPC_TBLIDXB3, TILE_OPC_NONE,
1529 BITFIELD(17, 5) /* index 1076 */,
1530 TILE_OPC_NONE, TILE_OPC_RLI_SN, TILE_OPC_SHLIB_SN, TILE_OPC_SHLIH_SN,
1531 TILE_OPC_SHLI_SN, TILE_OPC_SHRIB_SN, TILE_OPC_SHRIH_SN, TILE_OPC_SHRI_SN,
1532 TILE_OPC_SRAIB_SN, TILE_OPC_SRAIH_SN, TILE_OPC_SRAI_SN, CHILD(1109),
1533 TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE,
1534 TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE,
1535 TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE,
1536 TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE,
1537 BITFIELD(12, 4) /* index 1109 */,
1538 TILE_OPC_NONE, CHILD(1126), CHILD(1129), CHILD(1132), CHILD(1135),
1539 CHILD(1055), CHILD(1058), CHILD(1138), CHILD(1141), CHILD(1144),
1540 CHILD(1147), CHILD(1150), TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE,
1541 TILE_OPC_NONE,
1542 BITFIELD(16, 1) /* index 1126 */,
1543 TILE_OPC_BITX_SN, TILE_OPC_NONE,
1544 BITFIELD(16, 1) /* index 1129 */,
1545 TILE_OPC_BYTEX_SN, TILE_OPC_NONE,
1546 BITFIELD(16, 1) /* index 1132 */,
1547 TILE_OPC_CLZ_SN, TILE_OPC_NONE,
1548 BITFIELD(16, 1) /* index 1135 */,
1549 TILE_OPC_CTZ_SN, TILE_OPC_NONE,
1550 BITFIELD(16, 1) /* index 1138 */,
1551 TILE_OPC_PCNT_SN, TILE_OPC_NONE,
1552 BITFIELD(16, 1) /* index 1141 */,
1553 TILE_OPC_TBLIDXB0_SN, TILE_OPC_NONE,
1554 BITFIELD(16, 1) /* index 1144 */,
1555 TILE_OPC_TBLIDXB1_SN, TILE_OPC_NONE,
1556 BITFIELD(16, 1) /* index 1147 */,
1557 TILE_OPC_TBLIDXB2_SN, TILE_OPC_NONE,
1558 BITFIELD(16, 1) /* index 1150 */,
1559 TILE_OPC_TBLIDXB3_SN, TILE_OPC_NONE,
1560};
1561
1562static const unsigned short decode_X1_fsm[1540] =
1563{
1564 BITFIELD(54, 9) /* index 0 */,
1565 TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE,
1566 TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE,
1567 TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE,
1568 TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE,
1569 TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE,
1570 TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE,
1571 TILE_OPC_NONE, TILE_OPC_NONE, CHILD(513), CHILD(561), CHILD(594),
1572 TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE,
1573 TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE,
1574 TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, CHILD(641), CHILD(689),
1575 CHILD(722), TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE,
1576 TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE,
1577 TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, CHILD(766),
1578 CHILD(766), CHILD(766), CHILD(766), CHILD(766), CHILD(766), CHILD(766),
1579 CHILD(766), CHILD(766), CHILD(766), CHILD(766), CHILD(766), CHILD(766),
1580 CHILD(766), CHILD(766), CHILD(766), CHILD(766), CHILD(766), CHILD(766),
1581 CHILD(766), CHILD(766), CHILD(766), CHILD(766), CHILD(766), CHILD(766),
1582 CHILD(766), CHILD(766), CHILD(766), CHILD(766), CHILD(766), CHILD(766),
1583 CHILD(766), CHILD(781), CHILD(781), CHILD(781), CHILD(781), CHILD(781),
1584 CHILD(781), CHILD(781), CHILD(781), CHILD(781), CHILD(781), CHILD(781),
1585 CHILD(781), CHILD(781), CHILD(781), CHILD(781), CHILD(781), CHILD(781),
1586 CHILD(781), CHILD(781), CHILD(781), CHILD(781), CHILD(781), CHILD(781),
1587 CHILD(781), CHILD(781), CHILD(781), CHILD(781), CHILD(781), CHILD(781),
1588 CHILD(781), CHILD(781), CHILD(781), CHILD(796), CHILD(796), CHILD(796),
1589 CHILD(796), CHILD(796), CHILD(796), CHILD(796), CHILD(796), CHILD(796),
1590 CHILD(796), CHILD(796), CHILD(796), CHILD(796), CHILD(796), CHILD(796),
1591 CHILD(796), CHILD(796), CHILD(796), CHILD(796), CHILD(796), CHILD(796),
1592 CHILD(796), CHILD(796), CHILD(796), CHILD(796), CHILD(796), CHILD(796),
1593 CHILD(796), CHILD(796), CHILD(796), CHILD(796), CHILD(796), CHILD(826),
1594 CHILD(826), CHILD(826), CHILD(826), CHILD(826), CHILD(826), CHILD(826),
1595 CHILD(826), CHILD(826), CHILD(826), CHILD(826), CHILD(826), CHILD(826),
1596 CHILD(826), CHILD(826), CHILD(826), CHILD(843), CHILD(843), CHILD(843),
1597 CHILD(843), CHILD(843), CHILD(843), CHILD(843), CHILD(843), CHILD(843),
1598 CHILD(843), CHILD(843), CHILD(843), CHILD(843), CHILD(843), CHILD(843),
1599 CHILD(843), CHILD(860), CHILD(899), CHILD(923), CHILD(932), TILE_OPC_NONE,
1600 TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE,
1601 TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE,
1602 TILE_OPC_NONE, CHILD(941), CHILD(950), CHILD(974), CHILD(983),
1603 TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE,
1604 TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE,
1605 TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_MM, TILE_OPC_MM, TILE_OPC_MM,
1606 TILE_OPC_MM, TILE_OPC_MM, TILE_OPC_MM, TILE_OPC_MM, TILE_OPC_MM,
1607 TILE_OPC_MM, TILE_OPC_MM, TILE_OPC_MM, TILE_OPC_MM, TILE_OPC_MM,
1608 TILE_OPC_MM, TILE_OPC_MM, TILE_OPC_MM, TILE_OPC_MM, TILE_OPC_MM,
1609 TILE_OPC_MM, TILE_OPC_MM, TILE_OPC_MM, TILE_OPC_MM, TILE_OPC_MM,
1610 TILE_OPC_MM, TILE_OPC_MM, TILE_OPC_MM, TILE_OPC_MM, TILE_OPC_MM,
1611 TILE_OPC_MM, TILE_OPC_MM, TILE_OPC_MM, TILE_OPC_MM, CHILD(992),
1612 TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE,
1613 TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE,
1614 TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE,
1615 CHILD(1334), TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE,
1616 TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE,
1617 TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE,
1618 TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE,
1619 TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE,
1620 TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE,
1621 TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE,
1622 TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE,
1623 TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE,
1624 TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_J, TILE_OPC_J,
1625 TILE_OPC_J, TILE_OPC_J, TILE_OPC_J, TILE_OPC_J, TILE_OPC_J, TILE_OPC_J,
1626 TILE_OPC_J, TILE_OPC_J, TILE_OPC_J, TILE_OPC_J, TILE_OPC_J, TILE_OPC_J,
1627 TILE_OPC_J, TILE_OPC_J, TILE_OPC_J, TILE_OPC_J, TILE_OPC_J, TILE_OPC_J,
1628 TILE_OPC_J, TILE_OPC_J, TILE_OPC_J, TILE_OPC_J, TILE_OPC_J, TILE_OPC_J,
1629 TILE_OPC_J, TILE_OPC_J, TILE_OPC_J, TILE_OPC_J, TILE_OPC_J, TILE_OPC_J,
1630 TILE_OPC_J, TILE_OPC_J, TILE_OPC_J, TILE_OPC_J, TILE_OPC_J, TILE_OPC_J,
1631 TILE_OPC_J, TILE_OPC_J, TILE_OPC_J, TILE_OPC_J, TILE_OPC_J, TILE_OPC_J,
1632 TILE_OPC_J, TILE_OPC_J, TILE_OPC_J, TILE_OPC_J, TILE_OPC_J, TILE_OPC_J,
1633 TILE_OPC_J, TILE_OPC_J, TILE_OPC_J, TILE_OPC_J, TILE_OPC_J, TILE_OPC_J,
1634 TILE_OPC_J, TILE_OPC_J, TILE_OPC_J, TILE_OPC_J, TILE_OPC_J, TILE_OPC_J,
1635 TILE_OPC_J, TILE_OPC_J, TILE_OPC_JAL, TILE_OPC_JAL, TILE_OPC_JAL,
1636 TILE_OPC_JAL, TILE_OPC_JAL, TILE_OPC_JAL, TILE_OPC_JAL, TILE_OPC_JAL,
1637 TILE_OPC_JAL, TILE_OPC_JAL, TILE_OPC_JAL, TILE_OPC_JAL, TILE_OPC_JAL,
1638 TILE_OPC_JAL, TILE_OPC_JAL, TILE_OPC_JAL, TILE_OPC_JAL, TILE_OPC_JAL,
1639 TILE_OPC_JAL, TILE_OPC_JAL, TILE_OPC_JAL, TILE_OPC_JAL, TILE_OPC_JAL,
1640 TILE_OPC_JAL, TILE_OPC_JAL, TILE_OPC_JAL, TILE_OPC_JAL, TILE_OPC_JAL,
1641 TILE_OPC_JAL, TILE_OPC_JAL, TILE_OPC_JAL, TILE_OPC_JAL, TILE_OPC_JAL,
1642 TILE_OPC_JAL, TILE_OPC_JAL, TILE_OPC_JAL, TILE_OPC_JAL, TILE_OPC_JAL,
1643 TILE_OPC_JAL, TILE_OPC_JAL, TILE_OPC_JAL, TILE_OPC_JAL, TILE_OPC_JAL,
1644 TILE_OPC_JAL, TILE_OPC_JAL, TILE_OPC_JAL, TILE_OPC_JAL, TILE_OPC_JAL,
1645 TILE_OPC_JAL, TILE_OPC_JAL, TILE_OPC_JAL, TILE_OPC_JAL, TILE_OPC_JAL,
1646 TILE_OPC_JAL, TILE_OPC_JAL, TILE_OPC_JAL, TILE_OPC_JAL, TILE_OPC_JAL,
1647 TILE_OPC_JAL, TILE_OPC_JAL, TILE_OPC_JAL, TILE_OPC_JAL, TILE_OPC_JAL,
1648 TILE_OPC_JAL, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE,
1649 TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE,
1650 TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE,
1651 TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE,
1652 TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE,
1653 TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE,
1654 TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE,
1655 TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE,
1656 TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE,
1657 TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE,
1658 TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE,
1659 TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE,
1660 TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE,
1661 BITFIELD(49, 5) /* index 513 */,
1662 TILE_OPC_NONE, TILE_OPC_ADDB, TILE_OPC_ADDH, TILE_OPC_ADD, TILE_OPC_AND,
1663 TILE_OPC_INTHB, TILE_OPC_INTHH, TILE_OPC_INTLB, TILE_OPC_INTLH,
1664 TILE_OPC_JALRP, TILE_OPC_JALR, TILE_OPC_JRP, TILE_OPC_JR, TILE_OPC_LNK,
1665 TILE_OPC_MAXB_U, TILE_OPC_MAXH, TILE_OPC_MINB_U, TILE_OPC_MINH,
1666 TILE_OPC_MNZB, TILE_OPC_MNZH, TILE_OPC_MNZ, TILE_OPC_MZB, TILE_OPC_MZH,
1667 TILE_OPC_MZ, TILE_OPC_NOR, CHILD(546), TILE_OPC_PACKHB, TILE_OPC_PACKLB,
1668 TILE_OPC_RL, TILE_OPC_S1A, TILE_OPC_S2A, TILE_OPC_S3A,
1669 BITFIELD(43, 2) /* index 546 */,
1670 TILE_OPC_OR, TILE_OPC_OR, TILE_OPC_OR, CHILD(551),
1671 BITFIELD(45, 2) /* index 551 */,
1672 TILE_OPC_OR, TILE_OPC_OR, TILE_OPC_OR, CHILD(556),
1673 BITFIELD(47, 2) /* index 556 */,
1674 TILE_OPC_OR, TILE_OPC_OR, TILE_OPC_OR, TILE_OPC_MOVE,
1675 BITFIELD(49, 5) /* index 561 */,
1676 TILE_OPC_SB, TILE_OPC_SEQB, TILE_OPC_SEQH, TILE_OPC_SEQ, TILE_OPC_SHLB,
1677 TILE_OPC_SHLH, TILE_OPC_SHL, TILE_OPC_SHRB, TILE_OPC_SHRH, TILE_OPC_SHR,
1678 TILE_OPC_SH, TILE_OPC_SLTB, TILE_OPC_SLTB_U, TILE_OPC_SLTEB,
1679 TILE_OPC_SLTEB_U, TILE_OPC_SLTEH, TILE_OPC_SLTEH_U, TILE_OPC_SLTE,
1680 TILE_OPC_SLTE_U, TILE_OPC_SLTH, TILE_OPC_SLTH_U, TILE_OPC_SLT,
1681 TILE_OPC_SLT_U, TILE_OPC_SNEB, TILE_OPC_SNEH, TILE_OPC_SNE, TILE_OPC_SRAB,
1682 TILE_OPC_SRAH, TILE_OPC_SRA, TILE_OPC_SUBB, TILE_OPC_SUBH, TILE_OPC_SUB,
1683 BITFIELD(49, 4) /* index 594 */,
1684 CHILD(611), CHILD(614), CHILD(617), CHILD(620), CHILD(623), CHILD(626),
1685 CHILD(629), CHILD(632), CHILD(635), CHILD(638), TILE_OPC_NONE,
1686 TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE,
1687 BITFIELD(53, 1) /* index 611 */,
1688 TILE_OPC_SW, TILE_OPC_NONE,
1689 BITFIELD(53, 1) /* index 614 */,
1690 TILE_OPC_XOR, TILE_OPC_NONE,
1691 BITFIELD(53, 1) /* index 617 */,
1692 TILE_OPC_ADDS, TILE_OPC_NONE,
1693 BITFIELD(53, 1) /* index 620 */,
1694 TILE_OPC_SUBS, TILE_OPC_NONE,
1695 BITFIELD(53, 1) /* index 623 */,
1696 TILE_OPC_ADDBS_U, TILE_OPC_NONE,
1697 BITFIELD(53, 1) /* index 626 */,
1698 TILE_OPC_ADDHS, TILE_OPC_NONE,
1699 BITFIELD(53, 1) /* index 629 */,
1700 TILE_OPC_SUBBS_U, TILE_OPC_NONE,
1701 BITFIELD(53, 1) /* index 632 */,
1702 TILE_OPC_SUBHS, TILE_OPC_NONE,
1703 BITFIELD(53, 1) /* index 635 */,
1704 TILE_OPC_PACKHS, TILE_OPC_NONE,
1705 BITFIELD(53, 1) /* index 638 */,
1706 TILE_OPC_PACKBS_U, TILE_OPC_NONE,
1707 BITFIELD(49, 5) /* index 641 */,
1708 TILE_OPC_NONE, TILE_OPC_ADDB_SN, TILE_OPC_ADDH_SN, TILE_OPC_ADD_SN,
1709 TILE_OPC_AND_SN, TILE_OPC_INTHB_SN, TILE_OPC_INTHH_SN, TILE_OPC_INTLB_SN,
1710 TILE_OPC_INTLH_SN, TILE_OPC_JALRP, TILE_OPC_JALR, TILE_OPC_JRP, TILE_OPC_JR,
1711 TILE_OPC_LNK_SN, TILE_OPC_MAXB_U_SN, TILE_OPC_MAXH_SN, TILE_OPC_MINB_U_SN,
1712 TILE_OPC_MINH_SN, TILE_OPC_MNZB_SN, TILE_OPC_MNZH_SN, TILE_OPC_MNZ_SN,
1713 TILE_OPC_MZB_SN, TILE_OPC_MZH_SN, TILE_OPC_MZ_SN, TILE_OPC_NOR_SN,
1714 CHILD(674), TILE_OPC_PACKHB_SN, TILE_OPC_PACKLB_SN, TILE_OPC_RL_SN,
1715 TILE_OPC_S1A_SN, TILE_OPC_S2A_SN, TILE_OPC_S3A_SN,
1716 BITFIELD(43, 2) /* index 674 */,
1717 TILE_OPC_OR_SN, TILE_OPC_OR_SN, TILE_OPC_OR_SN, CHILD(679),
1718 BITFIELD(45, 2) /* index 679 */,
1719 TILE_OPC_OR_SN, TILE_OPC_OR_SN, TILE_OPC_OR_SN, CHILD(684),
1720 BITFIELD(47, 2) /* index 684 */,
1721 TILE_OPC_OR_SN, TILE_OPC_OR_SN, TILE_OPC_OR_SN, TILE_OPC_MOVE_SN,
1722 BITFIELD(49, 5) /* index 689 */,
1723 TILE_OPC_SB, TILE_OPC_SEQB_SN, TILE_OPC_SEQH_SN, TILE_OPC_SEQ_SN,
1724 TILE_OPC_SHLB_SN, TILE_OPC_SHLH_SN, TILE_OPC_SHL_SN, TILE_OPC_SHRB_SN,
1725 TILE_OPC_SHRH_SN, TILE_OPC_SHR_SN, TILE_OPC_SH, TILE_OPC_SLTB_SN,
1726 TILE_OPC_SLTB_U_SN, TILE_OPC_SLTEB_SN, TILE_OPC_SLTEB_U_SN,
1727 TILE_OPC_SLTEH_SN, TILE_OPC_SLTEH_U_SN, TILE_OPC_SLTE_SN,
1728 TILE_OPC_SLTE_U_SN, TILE_OPC_SLTH_SN, TILE_OPC_SLTH_U_SN, TILE_OPC_SLT_SN,
1729 TILE_OPC_SLT_U_SN, TILE_OPC_SNEB_SN, TILE_OPC_SNEH_SN, TILE_OPC_SNE_SN,
1730 TILE_OPC_SRAB_SN, TILE_OPC_SRAH_SN, TILE_OPC_SRA_SN, TILE_OPC_SUBB_SN,
1731 TILE_OPC_SUBH_SN, TILE_OPC_SUB_SN,
1732 BITFIELD(49, 4) /* index 722 */,
1733 CHILD(611), CHILD(739), CHILD(742), CHILD(745), CHILD(748), CHILD(751),
1734 CHILD(754), CHILD(757), CHILD(760), CHILD(763), TILE_OPC_NONE,
1735 TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE,
1736 BITFIELD(53, 1) /* index 739 */,
1737 TILE_OPC_XOR_SN, TILE_OPC_NONE,
1738 BITFIELD(53, 1) /* index 742 */,
1739 TILE_OPC_ADDS_SN, TILE_OPC_NONE,
1740 BITFIELD(53, 1) /* index 745 */,
1741 TILE_OPC_SUBS_SN, TILE_OPC_NONE,
1742 BITFIELD(53, 1) /* index 748 */,
1743 TILE_OPC_ADDBS_U_SN, TILE_OPC_NONE,
1744 BITFIELD(53, 1) /* index 751 */,
1745 TILE_OPC_ADDHS_SN, TILE_OPC_NONE,
1746 BITFIELD(53, 1) /* index 754 */,
1747 TILE_OPC_SUBBS_U_SN, TILE_OPC_NONE,
1748 BITFIELD(53, 1) /* index 757 */,
1749 TILE_OPC_SUBHS_SN, TILE_OPC_NONE,
1750 BITFIELD(53, 1) /* index 760 */,
1751 TILE_OPC_PACKHS_SN, TILE_OPC_NONE,
1752 BITFIELD(53, 1) /* index 763 */,
1753 TILE_OPC_PACKBS_U_SN, TILE_OPC_NONE,
1754 BITFIELD(37, 2) /* index 766 */,
1755 TILE_OPC_ADDLI_SN, TILE_OPC_ADDLI_SN, TILE_OPC_ADDLI_SN, CHILD(771),
1756 BITFIELD(39, 2) /* index 771 */,
1757 TILE_OPC_ADDLI_SN, TILE_OPC_ADDLI_SN, TILE_OPC_ADDLI_SN, CHILD(776),
1758 BITFIELD(41, 2) /* index 776 */,
1759 TILE_OPC_ADDLI_SN, TILE_OPC_ADDLI_SN, TILE_OPC_ADDLI_SN, TILE_OPC_MOVELI_SN,
1760 BITFIELD(37, 2) /* index 781 */,
1761 TILE_OPC_ADDLI, TILE_OPC_ADDLI, TILE_OPC_ADDLI, CHILD(786),
1762 BITFIELD(39, 2) /* index 786 */,
1763 TILE_OPC_ADDLI, TILE_OPC_ADDLI, TILE_OPC_ADDLI, CHILD(791),
1764 BITFIELD(41, 2) /* index 791 */,
1765 TILE_OPC_ADDLI, TILE_OPC_ADDLI, TILE_OPC_ADDLI, TILE_OPC_MOVELI,
1766 BITFIELD(31, 2) /* index 796 */,
1767 TILE_OPC_AULI, TILE_OPC_AULI, TILE_OPC_AULI, CHILD(801),
1768 BITFIELD(33, 2) /* index 801 */,
1769 TILE_OPC_AULI, TILE_OPC_AULI, TILE_OPC_AULI, CHILD(806),
1770 BITFIELD(35, 2) /* index 806 */,
1771 TILE_OPC_AULI, TILE_OPC_AULI, TILE_OPC_AULI, CHILD(811),
1772 BITFIELD(37, 2) /* index 811 */,
1773 TILE_OPC_AULI, TILE_OPC_AULI, TILE_OPC_AULI, CHILD(816),
1774 BITFIELD(39, 2) /* index 816 */,
1775 TILE_OPC_AULI, TILE_OPC_AULI, TILE_OPC_AULI, CHILD(821),
1776 BITFIELD(41, 2) /* index 821 */,
1777 TILE_OPC_AULI, TILE_OPC_AULI, TILE_OPC_AULI, TILE_OPC_INFOL,
1778 BITFIELD(31, 4) /* index 826 */,
1779 TILE_OPC_BZ, TILE_OPC_BZT, TILE_OPC_BNZ, TILE_OPC_BNZT, TILE_OPC_BGZ,
1780 TILE_OPC_BGZT, TILE_OPC_BGEZ, TILE_OPC_BGEZT, TILE_OPC_BLZ, TILE_OPC_BLZT,
1781 TILE_OPC_BLEZ, TILE_OPC_BLEZT, TILE_OPC_BBS, TILE_OPC_BBST, TILE_OPC_BBNS,
1782 TILE_OPC_BBNST,
1783 BITFIELD(31, 4) /* index 843 */,
1784 TILE_OPC_BZ_SN, TILE_OPC_BZT_SN, TILE_OPC_BNZ_SN, TILE_OPC_BNZT_SN,
1785 TILE_OPC_BGZ_SN, TILE_OPC_BGZT_SN, TILE_OPC_BGEZ_SN, TILE_OPC_BGEZT_SN,
1786 TILE_OPC_BLZ_SN, TILE_OPC_BLZT_SN, TILE_OPC_BLEZ_SN, TILE_OPC_BLEZT_SN,
1787 TILE_OPC_BBS_SN, TILE_OPC_BBST_SN, TILE_OPC_BBNS_SN, TILE_OPC_BBNST_SN,
1788 BITFIELD(51, 3) /* index 860 */,
1789 TILE_OPC_NONE, TILE_OPC_ADDIB, TILE_OPC_ADDIH, TILE_OPC_ADDI, CHILD(869),
1790 TILE_OPC_MAXIB_U, TILE_OPC_MAXIH, TILE_OPC_MFSPR,
1791 BITFIELD(31, 2) /* index 869 */,
1792 TILE_OPC_ANDI, TILE_OPC_ANDI, TILE_OPC_ANDI, CHILD(874),
1793 BITFIELD(33, 2) /* index 874 */,
1794 TILE_OPC_ANDI, TILE_OPC_ANDI, TILE_OPC_ANDI, CHILD(879),
1795 BITFIELD(35, 2) /* index 879 */,
1796 TILE_OPC_ANDI, TILE_OPC_ANDI, TILE_OPC_ANDI, CHILD(884),
1797 BITFIELD(37, 2) /* index 884 */,
1798 TILE_OPC_ANDI, TILE_OPC_ANDI, TILE_OPC_ANDI, CHILD(889),
1799 BITFIELD(39, 2) /* index 889 */,
1800 TILE_OPC_ANDI, TILE_OPC_ANDI, TILE_OPC_ANDI, CHILD(894),
1801 BITFIELD(41, 2) /* index 894 */,
1802 TILE_OPC_ANDI, TILE_OPC_ANDI, TILE_OPC_ANDI, TILE_OPC_INFO,
1803 BITFIELD(51, 3) /* index 899 */,
1804 TILE_OPC_MINIB_U, TILE_OPC_MINIH, TILE_OPC_MTSPR, CHILD(908),
1805 TILE_OPC_SEQIB, TILE_OPC_SEQIH, TILE_OPC_SEQI, TILE_OPC_SLTIB,
1806 BITFIELD(37, 2) /* index 908 */,
1807 TILE_OPC_ORI, TILE_OPC_ORI, TILE_OPC_ORI, CHILD(913),
1808 BITFIELD(39, 2) /* index 913 */,
1809 TILE_OPC_ORI, TILE_OPC_ORI, TILE_OPC_ORI, CHILD(918),
1810 BITFIELD(41, 2) /* index 918 */,
1811 TILE_OPC_ORI, TILE_OPC_ORI, TILE_OPC_ORI, TILE_OPC_MOVEI,
1812 BITFIELD(51, 3) /* index 923 */,
1813 TILE_OPC_SLTIB_U, TILE_OPC_SLTIH, TILE_OPC_SLTIH_U, TILE_OPC_SLTI,
1814 TILE_OPC_SLTI_U, TILE_OPC_XORI, TILE_OPC_LBADD, TILE_OPC_LBADD_U,
1815 BITFIELD(51, 3) /* index 932 */,
1816 TILE_OPC_LHADD, TILE_OPC_LHADD_U, TILE_OPC_LWADD, TILE_OPC_LWADD_NA,
1817 TILE_OPC_SBADD, TILE_OPC_SHADD, TILE_OPC_SWADD, TILE_OPC_NONE,
1818 BITFIELD(51, 3) /* index 941 */,
1819 TILE_OPC_NONE, TILE_OPC_ADDIB_SN, TILE_OPC_ADDIH_SN, TILE_OPC_ADDI_SN,
1820 TILE_OPC_ANDI_SN, TILE_OPC_MAXIB_U_SN, TILE_OPC_MAXIH_SN, TILE_OPC_MFSPR,
1821 BITFIELD(51, 3) /* index 950 */,
1822 TILE_OPC_MINIB_U_SN, TILE_OPC_MINIH_SN, TILE_OPC_MTSPR, CHILD(959),
1823 TILE_OPC_SEQIB_SN, TILE_OPC_SEQIH_SN, TILE_OPC_SEQI_SN, TILE_OPC_SLTIB_SN,
1824 BITFIELD(37, 2) /* index 959 */,
1825 TILE_OPC_ORI_SN, TILE_OPC_ORI_SN, TILE_OPC_ORI_SN, CHILD(964),
1826 BITFIELD(39, 2) /* index 964 */,
1827 TILE_OPC_ORI_SN, TILE_OPC_ORI_SN, TILE_OPC_ORI_SN, CHILD(969),
1828 BITFIELD(41, 2) /* index 969 */,
1829 TILE_OPC_ORI_SN, TILE_OPC_ORI_SN, TILE_OPC_ORI_SN, TILE_OPC_MOVEI_SN,
1830 BITFIELD(51, 3) /* index 974 */,
1831 TILE_OPC_SLTIB_U_SN, TILE_OPC_SLTIH_SN, TILE_OPC_SLTIH_U_SN,
1832 TILE_OPC_SLTI_SN, TILE_OPC_SLTI_U_SN, TILE_OPC_XORI_SN, TILE_OPC_LBADD_SN,
1833 TILE_OPC_LBADD_U_SN,
1834 BITFIELD(51, 3) /* index 983 */,
1835 TILE_OPC_LHADD_SN, TILE_OPC_LHADD_U_SN, TILE_OPC_LWADD_SN,
1836 TILE_OPC_LWADD_NA_SN, TILE_OPC_SBADD, TILE_OPC_SHADD, TILE_OPC_SWADD,
1837 TILE_OPC_NONE,
1838 BITFIELD(46, 7) /* index 992 */,
1839 TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, CHILD(1121),
1840 CHILD(1121), CHILD(1121), CHILD(1121), CHILD(1124), CHILD(1124),
1841 CHILD(1124), CHILD(1124), CHILD(1127), CHILD(1127), CHILD(1127),
1842 CHILD(1127), CHILD(1130), CHILD(1130), CHILD(1130), CHILD(1130),
1843 CHILD(1133), CHILD(1133), CHILD(1133), CHILD(1133), CHILD(1136),
1844 CHILD(1136), CHILD(1136), CHILD(1136), CHILD(1139), CHILD(1139),
1845 CHILD(1139), CHILD(1139), CHILD(1142), CHILD(1142), CHILD(1142),
1846 CHILD(1142), CHILD(1145), CHILD(1145), CHILD(1145), CHILD(1145),
1847 CHILD(1148), CHILD(1148), CHILD(1148), CHILD(1148), CHILD(1151),
1848 CHILD(1242), CHILD(1290), CHILD(1323), TILE_OPC_NONE, TILE_OPC_NONE,
1849 TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE,
1850 TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE,
1851 TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE,
1852 TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE,
1853 TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE,
1854 TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE,
1855 TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE,
1856 TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE,
1857 TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE,
1858 TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE,
1859 TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE,
1860 TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE,
1861 TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE,
1862 TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE,
1863 TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE,
1864 TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE,
1865 BITFIELD(53, 1) /* index 1121 */,
1866 TILE_OPC_RLI, TILE_OPC_NONE,
1867 BITFIELD(53, 1) /* index 1124 */,
1868 TILE_OPC_SHLIB, TILE_OPC_NONE,
1869 BITFIELD(53, 1) /* index 1127 */,
1870 TILE_OPC_SHLIH, TILE_OPC_NONE,
1871 BITFIELD(53, 1) /* index 1130 */,
1872 TILE_OPC_SHLI, TILE_OPC_NONE,
1873 BITFIELD(53, 1) /* index 1133 */,
1874 TILE_OPC_SHRIB, TILE_OPC_NONE,
1875 BITFIELD(53, 1) /* index 1136 */,
1876 TILE_OPC_SHRIH, TILE_OPC_NONE,
1877 BITFIELD(53, 1) /* index 1139 */,
1878 TILE_OPC_SHRI, TILE_OPC_NONE,
1879 BITFIELD(53, 1) /* index 1142 */,
1880 TILE_OPC_SRAIB, TILE_OPC_NONE,
1881 BITFIELD(53, 1) /* index 1145 */,
1882 TILE_OPC_SRAIH, TILE_OPC_NONE,
1883 BITFIELD(53, 1) /* index 1148 */,
1884 TILE_OPC_SRAI, TILE_OPC_NONE,
1885 BITFIELD(43, 3) /* index 1151 */,
1886 TILE_OPC_NONE, CHILD(1160), CHILD(1163), CHILD(1166), CHILD(1169),
1887 CHILD(1172), CHILD(1175), CHILD(1178),
1888 BITFIELD(53, 1) /* index 1160 */,
1889 TILE_OPC_DRAIN, TILE_OPC_NONE,
1890 BITFIELD(53, 1) /* index 1163 */,
1891 TILE_OPC_DTLBPR, TILE_OPC_NONE,
1892 BITFIELD(53, 1) /* index 1166 */,
1893 TILE_OPC_FINV, TILE_OPC_NONE,
1894 BITFIELD(53, 1) /* index 1169 */,
1895 TILE_OPC_FLUSH, TILE_OPC_NONE,
1896 BITFIELD(53, 1) /* index 1172 */,
1897 TILE_OPC_FNOP, TILE_OPC_NONE,
1898 BITFIELD(53, 1) /* index 1175 */,
1899 TILE_OPC_ICOH, TILE_OPC_NONE,
1900 BITFIELD(31, 2) /* index 1178 */,
1901 CHILD(1183), CHILD(1211), CHILD(1239), CHILD(1239),
1902 BITFIELD(53, 1) /* index 1183 */,
1903 CHILD(1186), TILE_OPC_NONE,
1904 BITFIELD(33, 2) /* index 1186 */,
1905 TILE_OPC_ILL, TILE_OPC_ILL, TILE_OPC_ILL, CHILD(1191),
1906 BITFIELD(35, 2) /* index 1191 */,
1907 TILE_OPC_ILL, CHILD(1196), TILE_OPC_ILL, TILE_OPC_ILL,
1908 BITFIELD(37, 2) /* index 1196 */,
1909 TILE_OPC_ILL, CHILD(1201), TILE_OPC_ILL, TILE_OPC_ILL,
1910 BITFIELD(39, 2) /* index 1201 */,
1911 TILE_OPC_ILL, CHILD(1206), TILE_OPC_ILL, TILE_OPC_ILL,
1912 BITFIELD(41, 2) /* index 1206 */,
1913 TILE_OPC_ILL, TILE_OPC_ILL, TILE_OPC_BPT, TILE_OPC_ILL,
1914 BITFIELD(53, 1) /* index 1211 */,
1915 CHILD(1214), TILE_OPC_NONE,
1916 BITFIELD(33, 2) /* index 1214 */,
1917 TILE_OPC_ILL, TILE_OPC_ILL, TILE_OPC_ILL, CHILD(1219),
1918 BITFIELD(35, 2) /* index 1219 */,
1919 TILE_OPC_ILL, CHILD(1224), TILE_OPC_ILL, TILE_OPC_ILL,
1920 BITFIELD(37, 2) /* index 1224 */,
1921 TILE_OPC_ILL, CHILD(1229), TILE_OPC_ILL, TILE_OPC_ILL,
1922 BITFIELD(39, 2) /* index 1229 */,
1923 TILE_OPC_ILL, CHILD(1234), TILE_OPC_ILL, TILE_OPC_ILL,
1924 BITFIELD(41, 2) /* index 1234 */,
1925 TILE_OPC_ILL, TILE_OPC_ILL, TILE_OPC_RAISE, TILE_OPC_ILL,
1926 BITFIELD(53, 1) /* index 1239 */,
1927 TILE_OPC_ILL, TILE_OPC_NONE,
1928 BITFIELD(43, 3) /* index 1242 */,
1929 CHILD(1251), CHILD(1254), CHILD(1257), CHILD(1275), CHILD(1278),
1930 CHILD(1281), CHILD(1284), CHILD(1287),
1931 BITFIELD(53, 1) /* index 1251 */,
1932 TILE_OPC_INV, TILE_OPC_NONE,
1933 BITFIELD(53, 1) /* index 1254 */,
1934 TILE_OPC_IRET, TILE_OPC_NONE,
1935 BITFIELD(53, 1) /* index 1257 */,
1936 CHILD(1260), TILE_OPC_NONE,
1937 BITFIELD(31, 2) /* index 1260 */,
1938 TILE_OPC_LB, TILE_OPC_LB, TILE_OPC_LB, CHILD(1265),
1939 BITFIELD(33, 2) /* index 1265 */,
1940 TILE_OPC_LB, TILE_OPC_LB, TILE_OPC_LB, CHILD(1270),
1941 BITFIELD(35, 2) /* index 1270 */,
1942 TILE_OPC_LB, TILE_OPC_LB, TILE_OPC_LB, TILE_OPC_PREFETCH,
1943 BITFIELD(53, 1) /* index 1275 */,
1944 TILE_OPC_LB_U, TILE_OPC_NONE,
1945 BITFIELD(53, 1) /* index 1278 */,
1946 TILE_OPC_LH, TILE_OPC_NONE,
1947 BITFIELD(53, 1) /* index 1281 */,
1948 TILE_OPC_LH_U, TILE_OPC_NONE,
1949 BITFIELD(53, 1) /* index 1284 */,
1950 TILE_OPC_LW, TILE_OPC_NONE,
1951 BITFIELD(53, 1) /* index 1287 */,
1952 TILE_OPC_MF, TILE_OPC_NONE,
1953 BITFIELD(43, 3) /* index 1290 */,
1954 CHILD(1299), CHILD(1302), CHILD(1305), CHILD(1308), CHILD(1311),
1955 CHILD(1314), CHILD(1317), CHILD(1320),
1956 BITFIELD(53, 1) /* index 1299 */,
1957 TILE_OPC_NAP, TILE_OPC_NONE,
1958 BITFIELD(53, 1) /* index 1302 */,
1959 TILE_OPC_NOP, TILE_OPC_NONE,
1960 BITFIELD(53, 1) /* index 1305 */,
1961 TILE_OPC_SWINT0, TILE_OPC_NONE,
1962 BITFIELD(53, 1) /* index 1308 */,
1963 TILE_OPC_SWINT1, TILE_OPC_NONE,
1964 BITFIELD(53, 1) /* index 1311 */,
1965 TILE_OPC_SWINT2, TILE_OPC_NONE,
1966 BITFIELD(53, 1) /* index 1314 */,
1967 TILE_OPC_SWINT3, TILE_OPC_NONE,
1968 BITFIELD(53, 1) /* index 1317 */,
1969 TILE_OPC_TNS, TILE_OPC_NONE,
1970 BITFIELD(53, 1) /* index 1320 */,
1971 TILE_OPC_WH64, TILE_OPC_NONE,
1972 BITFIELD(43, 2) /* index 1323 */,
1973 CHILD(1328), TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE,
1974 BITFIELD(45, 1) /* index 1328 */,
1975 CHILD(1331), TILE_OPC_NONE,
1976 BITFIELD(53, 1) /* index 1331 */,
1977 TILE_OPC_LW_NA, TILE_OPC_NONE,
1978 BITFIELD(46, 7) /* index 1334 */,
1979 TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, CHILD(1463),
1980 CHILD(1463), CHILD(1463), CHILD(1463), CHILD(1466), CHILD(1466),
1981 CHILD(1466), CHILD(1466), CHILD(1469), CHILD(1469), CHILD(1469),
1982 CHILD(1469), CHILD(1472), CHILD(1472), CHILD(1472), CHILD(1472),
1983 CHILD(1475), CHILD(1475), CHILD(1475), CHILD(1475), CHILD(1478),
1984 CHILD(1478), CHILD(1478), CHILD(1478), CHILD(1481), CHILD(1481),
1985 CHILD(1481), CHILD(1481), CHILD(1484), CHILD(1484), CHILD(1484),
1986 CHILD(1484), CHILD(1487), CHILD(1487), CHILD(1487), CHILD(1487),
1987 CHILD(1490), CHILD(1490), CHILD(1490), CHILD(1490), CHILD(1151),
1988 CHILD(1493), CHILD(1517), CHILD(1529), TILE_OPC_NONE, TILE_OPC_NONE,
1989 TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE,
1990 TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE,
1991 TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE,
1992 TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE,
1993 TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE,
1994 TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE,
1995 TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE,
1996 TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE,
1997 TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE,
1998 TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE,
1999 TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE,
2000 TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE,
2001 TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE,
2002 TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE,
2003 TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE,
2004 TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE,
2005 BITFIELD(53, 1) /* index 1463 */,
2006 TILE_OPC_RLI_SN, TILE_OPC_NONE,
2007 BITFIELD(53, 1) /* index 1466 */,
2008 TILE_OPC_SHLIB_SN, TILE_OPC_NONE,
2009 BITFIELD(53, 1) /* index 1469 */,
2010 TILE_OPC_SHLIH_SN, TILE_OPC_NONE,
2011 BITFIELD(53, 1) /* index 1472 */,
2012 TILE_OPC_SHLI_SN, TILE_OPC_NONE,
2013 BITFIELD(53, 1) /* index 1475 */,
2014 TILE_OPC_SHRIB_SN, TILE_OPC_NONE,
2015 BITFIELD(53, 1) /* index 1478 */,
2016 TILE_OPC_SHRIH_SN, TILE_OPC_NONE,
2017 BITFIELD(53, 1) /* index 1481 */,
2018 TILE_OPC_SHRI_SN, TILE_OPC_NONE,
2019 BITFIELD(53, 1) /* index 1484 */,
2020 TILE_OPC_SRAIB_SN, TILE_OPC_NONE,
2021 BITFIELD(53, 1) /* index 1487 */,
2022 TILE_OPC_SRAIH_SN, TILE_OPC_NONE,
2023 BITFIELD(53, 1) /* index 1490 */,
2024 TILE_OPC_SRAI_SN, TILE_OPC_NONE,
2025 BITFIELD(43, 3) /* index 1493 */,
2026 CHILD(1251), CHILD(1254), CHILD(1502), CHILD(1505), CHILD(1508),
2027 CHILD(1511), CHILD(1514), CHILD(1287),
2028 BITFIELD(53, 1) /* index 1502 */,
2029 TILE_OPC_LB_SN, TILE_OPC_NONE,
2030 BITFIELD(53, 1) /* index 1505 */,
2031 TILE_OPC_LB_U_SN, TILE_OPC_NONE,
2032 BITFIELD(53, 1) /* index 1508 */,
2033 TILE_OPC_LH_SN, TILE_OPC_NONE,
2034 BITFIELD(53, 1) /* index 1511 */,
2035 TILE_OPC_LH_U_SN, TILE_OPC_NONE,
2036 BITFIELD(53, 1) /* index 1514 */,
2037 TILE_OPC_LW_SN, TILE_OPC_NONE,
2038 BITFIELD(43, 3) /* index 1517 */,
2039 CHILD(1299), CHILD(1302), CHILD(1305), CHILD(1308), CHILD(1311),
2040 CHILD(1314), CHILD(1526), CHILD(1320),
2041 BITFIELD(53, 1) /* index 1526 */,
2042 TILE_OPC_TNS_SN, TILE_OPC_NONE,
2043 BITFIELD(43, 2) /* index 1529 */,
2044 CHILD(1534), TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE,
2045 BITFIELD(45, 1) /* index 1534 */,
2046 CHILD(1537), TILE_OPC_NONE,
2047 BITFIELD(53, 1) /* index 1537 */,
2048 TILE_OPC_LW_NA_SN, TILE_OPC_NONE,
2049};
2050
2051static const unsigned short decode_Y0_fsm[168] =
2052{
2053 BITFIELD(27, 4) /* index 0 */,
2054 TILE_OPC_NONE, CHILD(17), CHILD(22), CHILD(27), CHILD(47), CHILD(52),
2055 CHILD(57), CHILD(62), CHILD(67), TILE_OPC_ADDI, CHILD(72), CHILD(102),
2056 TILE_OPC_SEQI, CHILD(117), TILE_OPC_SLTI, TILE_OPC_SLTI_U,
2057 BITFIELD(18, 2) /* index 17 */,
2058 TILE_OPC_ADD, TILE_OPC_S1A, TILE_OPC_S2A, TILE_OPC_SUB,
2059 BITFIELD(18, 2) /* index 22 */,
2060 TILE_OPC_MNZ, TILE_OPC_MVNZ, TILE_OPC_MVZ, TILE_OPC_MZ,
2061 BITFIELD(18, 2) /* index 27 */,
2062 TILE_OPC_AND, TILE_OPC_NOR, CHILD(32), TILE_OPC_XOR,
2063 BITFIELD(12, 2) /* index 32 */,
2064 TILE_OPC_OR, TILE_OPC_OR, TILE_OPC_OR, CHILD(37),
2065 BITFIELD(14, 2) /* index 37 */,
2066 TILE_OPC_OR, TILE_OPC_OR, TILE_OPC_OR, CHILD(42),
2067 BITFIELD(16, 2) /* index 42 */,
2068 TILE_OPC_OR, TILE_OPC_OR, TILE_OPC_OR, TILE_OPC_MOVE,
2069 BITFIELD(18, 2) /* index 47 */,
2070 TILE_OPC_RL, TILE_OPC_SHL, TILE_OPC_SHR, TILE_OPC_SRA,
2071 BITFIELD(18, 2) /* index 52 */,
2072 TILE_OPC_SLTE, TILE_OPC_SLTE_U, TILE_OPC_SLT, TILE_OPC_SLT_U,
2073 BITFIELD(18, 2) /* index 57 */,
2074 TILE_OPC_MULHLSA_UU, TILE_OPC_S3A, TILE_OPC_SEQ, TILE_OPC_SNE,
2075 BITFIELD(18, 2) /* index 62 */,
2076 TILE_OPC_MULHH_SS, TILE_OPC_MULHH_UU, TILE_OPC_MULLL_SS, TILE_OPC_MULLL_UU,
2077 BITFIELD(18, 2) /* index 67 */,
2078 TILE_OPC_MULHHA_SS, TILE_OPC_MULHHA_UU, TILE_OPC_MULLLA_SS,
2079 TILE_OPC_MULLLA_UU,
2080 BITFIELD(0, 2) /* index 72 */,
2081 TILE_OPC_ANDI, TILE_OPC_ANDI, TILE_OPC_ANDI, CHILD(77),
2082 BITFIELD(2, 2) /* index 77 */,
2083 TILE_OPC_ANDI, TILE_OPC_ANDI, TILE_OPC_ANDI, CHILD(82),
2084 BITFIELD(4, 2) /* index 82 */,
2085 TILE_OPC_ANDI, TILE_OPC_ANDI, TILE_OPC_ANDI, CHILD(87),
2086 BITFIELD(6, 2) /* index 87 */,
2087 TILE_OPC_ANDI, TILE_OPC_ANDI, TILE_OPC_ANDI, CHILD(92),
2088 BITFIELD(8, 2) /* index 92 */,
2089 TILE_OPC_ANDI, TILE_OPC_ANDI, TILE_OPC_ANDI, CHILD(97),
2090 BITFIELD(10, 2) /* index 97 */,
2091 TILE_OPC_ANDI, TILE_OPC_ANDI, TILE_OPC_ANDI, TILE_OPC_INFO,
2092 BITFIELD(6, 2) /* index 102 */,
2093 TILE_OPC_ORI, TILE_OPC_ORI, TILE_OPC_ORI, CHILD(107),
2094 BITFIELD(8, 2) /* index 107 */,
2095 TILE_OPC_ORI, TILE_OPC_ORI, TILE_OPC_ORI, CHILD(112),
2096 BITFIELD(10, 2) /* index 112 */,
2097 TILE_OPC_ORI, TILE_OPC_ORI, TILE_OPC_ORI, TILE_OPC_MOVEI,
2098 BITFIELD(15, 5) /* index 117 */,
2099 TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_RLI,
2100 TILE_OPC_RLI, TILE_OPC_RLI, TILE_OPC_RLI, TILE_OPC_SHLI, TILE_OPC_SHLI,
2101 TILE_OPC_SHLI, TILE_OPC_SHLI, TILE_OPC_SHRI, TILE_OPC_SHRI, TILE_OPC_SHRI,
2102 TILE_OPC_SHRI, TILE_OPC_SRAI, TILE_OPC_SRAI, TILE_OPC_SRAI, TILE_OPC_SRAI,
2103 CHILD(150), CHILD(159), TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE,
2104 TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE,
2105 TILE_OPC_NONE, TILE_OPC_NONE,
2106 BITFIELD(12, 3) /* index 150 */,
2107 TILE_OPC_NONE, TILE_OPC_BITX, TILE_OPC_BYTEX, TILE_OPC_CLZ, TILE_OPC_CTZ,
2108 TILE_OPC_FNOP, TILE_OPC_NOP, TILE_OPC_PCNT,
2109 BITFIELD(12, 3) /* index 159 */,
2110 TILE_OPC_TBLIDXB0, TILE_OPC_TBLIDXB1, TILE_OPC_TBLIDXB2, TILE_OPC_TBLIDXB3,
2111 TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE,
2112};
2113
2114static const unsigned short decode_Y1_fsm[140] =
2115{
2116 BITFIELD(59, 4) /* index 0 */,
2117 TILE_OPC_NONE, CHILD(17), CHILD(22), CHILD(27), CHILD(47), CHILD(52),
2118 CHILD(57), TILE_OPC_ADDI, CHILD(62), CHILD(92), TILE_OPC_SEQI, CHILD(107),
2119 TILE_OPC_SLTI, TILE_OPC_SLTI_U, TILE_OPC_NONE, TILE_OPC_NONE,
2120 BITFIELD(49, 2) /* index 17 */,
2121 TILE_OPC_ADD, TILE_OPC_S1A, TILE_OPC_S2A, TILE_OPC_SUB,
2122 BITFIELD(49, 2) /* index 22 */,
2123 TILE_OPC_NONE, TILE_OPC_MNZ, TILE_OPC_MZ, TILE_OPC_NONE,
2124 BITFIELD(49, 2) /* index 27 */,
2125 TILE_OPC_AND, TILE_OPC_NOR, CHILD(32), TILE_OPC_XOR,
2126 BITFIELD(43, 2) /* index 32 */,
2127 TILE_OPC_OR, TILE_OPC_OR, TILE_OPC_OR, CHILD(37),
2128 BITFIELD(45, 2) /* index 37 */,
2129 TILE_OPC_OR, TILE_OPC_OR, TILE_OPC_OR, CHILD(42),
2130 BITFIELD(47, 2) /* index 42 */,
2131 TILE_OPC_OR, TILE_OPC_OR, TILE_OPC_OR, TILE_OPC_MOVE,
2132 BITFIELD(49, 2) /* index 47 */,
2133 TILE_OPC_RL, TILE_OPC_SHL, TILE_OPC_SHR, TILE_OPC_SRA,
2134 BITFIELD(49, 2) /* index 52 */,
2135 TILE_OPC_SLTE, TILE_OPC_SLTE_U, TILE_OPC_SLT, TILE_OPC_SLT_U,
2136 BITFIELD(49, 2) /* index 57 */,
2137 TILE_OPC_NONE, TILE_OPC_S3A, TILE_OPC_SEQ, TILE_OPC_SNE,
2138 BITFIELD(31, 2) /* index 62 */,
2139 TILE_OPC_ANDI, TILE_OPC_ANDI, TILE_OPC_ANDI, CHILD(67),
2140 BITFIELD(33, 2) /* index 67 */,
2141 TILE_OPC_ANDI, TILE_OPC_ANDI, TILE_OPC_ANDI, CHILD(72),
2142 BITFIELD(35, 2) /* index 72 */,
2143 TILE_OPC_ANDI, TILE_OPC_ANDI, TILE_OPC_ANDI, CHILD(77),
2144 BITFIELD(37, 2) /* index 77 */,
2145 TILE_OPC_ANDI, TILE_OPC_ANDI, TILE_OPC_ANDI, CHILD(82),
2146 BITFIELD(39, 2) /* index 82 */,
2147 TILE_OPC_ANDI, TILE_OPC_ANDI, TILE_OPC_ANDI, CHILD(87),
2148 BITFIELD(41, 2) /* index 87 */,
2149 TILE_OPC_ANDI, TILE_OPC_ANDI, TILE_OPC_ANDI, TILE_OPC_INFO,
2150 BITFIELD(37, 2) /* index 92 */,
2151 TILE_OPC_ORI, TILE_OPC_ORI, TILE_OPC_ORI, CHILD(97),
2152 BITFIELD(39, 2) /* index 97 */,
2153 TILE_OPC_ORI, TILE_OPC_ORI, TILE_OPC_ORI, CHILD(102),
2154 BITFIELD(41, 2) /* index 102 */,
2155 TILE_OPC_ORI, TILE_OPC_ORI, TILE_OPC_ORI, TILE_OPC_MOVEI,
2156 BITFIELD(48, 3) /* index 107 */,
2157 TILE_OPC_NONE, TILE_OPC_RLI, TILE_OPC_SHLI, TILE_OPC_SHRI, TILE_OPC_SRAI,
2158 CHILD(116), TILE_OPC_NONE, TILE_OPC_NONE,
2159 BITFIELD(43, 3) /* index 116 */,
2160 TILE_OPC_NONE, CHILD(125), CHILD(130), CHILD(135), TILE_OPC_NONE,
2161 TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE,
2162 BITFIELD(46, 2) /* index 125 */,
2163 TILE_OPC_FNOP, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE,
2164 BITFIELD(46, 2) /* index 130 */,
2165 TILE_OPC_ILL, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE,
2166 BITFIELD(46, 2) /* index 135 */,
2167 TILE_OPC_NOP, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE,
2168};
2169
2170static const unsigned short decode_Y2_fsm[24] =
2171{
2172 BITFIELD(56, 3) /* index 0 */,
2173 CHILD(9), TILE_OPC_LB_U, TILE_OPC_LH, TILE_OPC_LH_U, TILE_OPC_LW,
2174 TILE_OPC_SB, TILE_OPC_SH, TILE_OPC_SW,
2175 BITFIELD(20, 2) /* index 9 */,
2176 TILE_OPC_LB, TILE_OPC_LB, TILE_OPC_LB, CHILD(14),
2177 BITFIELD(22, 2) /* index 14 */,
2178 TILE_OPC_LB, TILE_OPC_LB, TILE_OPC_LB, CHILD(19),
2179 BITFIELD(24, 2) /* index 19 */,
2180 TILE_OPC_LB, TILE_OPC_LB, TILE_OPC_LB, TILE_OPC_PREFETCH,
2181};
2182
2183#undef BITFIELD
2184#undef CHILD
2185const unsigned short * const
2186tile_bundle_decoder_fsms[TILE_NUM_PIPELINE_ENCODINGS] =
2187{
2188 decode_X0_fsm,
2189 decode_X1_fsm,
2190 decode_Y0_fsm,
2191 decode_Y1_fsm,
2192 decode_Y2_fsm
2193};
2194const struct tile_operand tile_operands[43] =
2195{
2196 {
2197 TILE_OP_TYPE_IMMEDIATE, BFD_RELOC(TILE_IMM8_X0),
2198 8, 1, 0, 0, 0, 0,
2199 create_Imm8_X0, get_Imm8_X0
2200 },
2201 {
2202 TILE_OP_TYPE_IMMEDIATE, BFD_RELOC(TILE_IMM8_X1),
2203 8, 1, 0, 0, 0, 0,
2204 create_Imm8_X1, get_Imm8_X1
2205 },
2206 {
2207 TILE_OP_TYPE_IMMEDIATE, BFD_RELOC(TILE_IMM8_Y0),
2208 8, 1, 0, 0, 0, 0,
2209 create_Imm8_Y0, get_Imm8_Y0
2210 },
2211 {
2212 TILE_OP_TYPE_IMMEDIATE, BFD_RELOC(TILE_IMM8_Y1),
2213 8, 1, 0, 0, 0, 0,
2214 create_Imm8_Y1, get_Imm8_Y1
2215 },
2216 {
2217 TILE_OP_TYPE_IMMEDIATE, BFD_RELOC(TILE_IMM16_X0),
2218 16, 1, 0, 0, 0, 0,
2219 create_Imm16_X0, get_Imm16_X0
2220 },
2221 {
2222 TILE_OP_TYPE_IMMEDIATE, BFD_RELOC(TILE_IMM16_X1),
2223 16, 1, 0, 0, 0, 0,
2224 create_Imm16_X1, get_Imm16_X1
2225 },
2226 {
2227 TILE_OP_TYPE_ADDRESS, BFD_RELOC(TILE_JOFFLONG_X1),
2228 29, 1, 0, 0, 1, TILE_LOG2_BUNDLE_ALIGNMENT_IN_BYTES,
2229 create_JOffLong_X1, get_JOffLong_X1
2230 },
2231 {
2232 TILE_OP_TYPE_REGISTER, BFD_RELOC(NONE),
2233 6, 0, 0, 1, 0, 0,
2234 create_Dest_X0, get_Dest_X0
2235 },
2236 {
2237 TILE_OP_TYPE_REGISTER, BFD_RELOC(NONE),
2238 6, 0, 1, 0, 0, 0,
2239 create_SrcA_X0, get_SrcA_X0
2240 },
2241 {
2242 TILE_OP_TYPE_REGISTER, BFD_RELOC(NONE),
2243 6, 0, 0, 1, 0, 0,
2244 create_Dest_X1, get_Dest_X1
2245 },
2246 {
2247 TILE_OP_TYPE_REGISTER, BFD_RELOC(NONE),
2248 6, 0, 1, 0, 0, 0,
2249 create_SrcA_X1, get_SrcA_X1
2250 },
2251 {
2252 TILE_OP_TYPE_REGISTER, BFD_RELOC(NONE),
2253 6, 0, 0, 1, 0, 0,
2254 create_Dest_Y0, get_Dest_Y0
2255 },
2256 {
2257 TILE_OP_TYPE_REGISTER, BFD_RELOC(NONE),
2258 6, 0, 1, 0, 0, 0,
2259 create_SrcA_Y0, get_SrcA_Y0
2260 },
2261 {
2262 TILE_OP_TYPE_REGISTER, BFD_RELOC(NONE),
2263 6, 0, 0, 1, 0, 0,
2264 create_Dest_Y1, get_Dest_Y1
2265 },
2266 {
2267 TILE_OP_TYPE_REGISTER, BFD_RELOC(NONE),
2268 6, 0, 1, 0, 0, 0,
2269 create_SrcA_Y1, get_SrcA_Y1
2270 },
2271 {
2272 TILE_OP_TYPE_REGISTER, BFD_RELOC(NONE),
2273 6, 0, 1, 0, 0, 0,
2274 create_SrcA_Y2, get_SrcA_Y2
2275 },
2276 {
2277 TILE_OP_TYPE_REGISTER, BFD_RELOC(NONE),
2278 6, 0, 1, 0, 0, 0,
2279 create_SrcB_X0, get_SrcB_X0
2280 },
2281 {
2282 TILE_OP_TYPE_REGISTER, BFD_RELOC(NONE),
2283 6, 0, 1, 0, 0, 0,
2284 create_SrcB_X1, get_SrcB_X1
2285 },
2286 {
2287 TILE_OP_TYPE_REGISTER, BFD_RELOC(NONE),
2288 6, 0, 1, 0, 0, 0,
2289 create_SrcB_Y0, get_SrcB_Y0
2290 },
2291 {
2292 TILE_OP_TYPE_REGISTER, BFD_RELOC(NONE),
2293 6, 0, 1, 0, 0, 0,
2294 create_SrcB_Y1, get_SrcB_Y1
2295 },
2296 {
2297 TILE_OP_TYPE_ADDRESS, BFD_RELOC(TILE_BROFF_X1),
2298 17, 1, 0, 0, 1, TILE_LOG2_BUNDLE_ALIGNMENT_IN_BYTES,
2299 create_BrOff_X1, get_BrOff_X1
2300 },
2301 {
2302 TILE_OP_TYPE_REGISTER, BFD_RELOC(NONE),
2303 6, 0, 1, 1, 0, 0,
2304 create_Dest_X0, get_Dest_X0
2305 },
2306 {
2307 TILE_OP_TYPE_ADDRESS, BFD_RELOC(NONE),
2308 28, 1, 0, 0, 1, TILE_LOG2_BUNDLE_ALIGNMENT_IN_BYTES,
2309 create_JOff_X1, get_JOff_X1
2310 },
2311 {
2312 TILE_OP_TYPE_REGISTER, BFD_RELOC(NONE),
2313 6, 0, 0, 1, 0, 0,
2314 create_SrcBDest_Y2, get_SrcBDest_Y2
2315 },
2316 {
2317 TILE_OP_TYPE_REGISTER, BFD_RELOC(NONE),
2318 6, 0, 1, 1, 0, 0,
2319 create_SrcA_X1, get_SrcA_X1
2320 },
2321 {
2322 TILE_OP_TYPE_SPR, BFD_RELOC(TILE_MF_IMM15_X1),
2323 15, 0, 0, 0, 0, 0,
2324 create_MF_Imm15_X1, get_MF_Imm15_X1
2325 },
2326 {
2327 TILE_OP_TYPE_IMMEDIATE, BFD_RELOC(TILE_MMSTART_X0),
2328 5, 0, 0, 0, 0, 0,
2329 create_MMStart_X0, get_MMStart_X0
2330 },
2331 {
2332 TILE_OP_TYPE_IMMEDIATE, BFD_RELOC(TILE_MMEND_X0),
2333 5, 0, 0, 0, 0, 0,
2334 create_MMEnd_X0, get_MMEnd_X0
2335 },
2336 {
2337 TILE_OP_TYPE_IMMEDIATE, BFD_RELOC(TILE_MMSTART_X1),
2338 5, 0, 0, 0, 0, 0,
2339 create_MMStart_X1, get_MMStart_X1
2340 },
2341 {
2342 TILE_OP_TYPE_IMMEDIATE, BFD_RELOC(TILE_MMEND_X1),
2343 5, 0, 0, 0, 0, 0,
2344 create_MMEnd_X1, get_MMEnd_X1
2345 },
2346 {
2347 TILE_OP_TYPE_SPR, BFD_RELOC(TILE_MT_IMM15_X1),
2348 15, 0, 0, 0, 0, 0,
2349 create_MT_Imm15_X1, get_MT_Imm15_X1
2350 },
2351 {
2352 TILE_OP_TYPE_REGISTER, BFD_RELOC(NONE),
2353 6, 0, 1, 1, 0, 0,
2354 create_Dest_Y0, get_Dest_Y0
2355 },
2356 {
2357 TILE_OP_TYPE_IMMEDIATE, BFD_RELOC(TILE_SHAMT_X0),
2358 5, 0, 0, 0, 0, 0,
2359 create_ShAmt_X0, get_ShAmt_X0
2360 },
2361 {
2362 TILE_OP_TYPE_IMMEDIATE, BFD_RELOC(TILE_SHAMT_X1),
2363 5, 0, 0, 0, 0, 0,
2364 create_ShAmt_X1, get_ShAmt_X1
2365 },
2366 {
2367 TILE_OP_TYPE_IMMEDIATE, BFD_RELOC(TILE_SHAMT_Y0),
2368 5, 0, 0, 0, 0, 0,
2369 create_ShAmt_Y0, get_ShAmt_Y0
2370 },
2371 {
2372 TILE_OP_TYPE_IMMEDIATE, BFD_RELOC(TILE_SHAMT_Y1),
2373 5, 0, 0, 0, 0, 0,
2374 create_ShAmt_Y1, get_ShAmt_Y1
2375 },
2376 {
2377 TILE_OP_TYPE_REGISTER, BFD_RELOC(NONE),
2378 6, 0, 1, 0, 0, 0,
2379 create_SrcBDest_Y2, get_SrcBDest_Y2
2380 },
2381 {
2382 TILE_OP_TYPE_IMMEDIATE, BFD_RELOC(NONE),
2383 8, 1, 0, 0, 0, 0,
2384 create_Dest_Imm8_X1, get_Dest_Imm8_X1
2385 },
2386 {
2387 TILE_OP_TYPE_ADDRESS, BFD_RELOC(TILE_SN_BROFF),
2388 10, 1, 0, 0, 1, TILE_LOG2_SN_INSTRUCTION_SIZE_IN_BYTES,
2389 create_BrOff_SN, get_BrOff_SN
2390 },
2391 {
2392 TILE_OP_TYPE_IMMEDIATE, BFD_RELOC(TILE_SN_UIMM8),
2393 8, 0, 0, 0, 0, 0,
2394 create_Imm8_SN, get_Imm8_SN
2395 },
2396 {
2397 TILE_OP_TYPE_IMMEDIATE, BFD_RELOC(TILE_SN_IMM8),
2398 8, 1, 0, 0, 0, 0,
2399 create_Imm8_SN, get_Imm8_SN
2400 },
2401 {
2402 TILE_OP_TYPE_REGISTER, BFD_RELOC(NONE),
2403 2, 0, 0, 1, 0, 0,
2404 create_Dest_SN, get_Dest_SN
2405 },
2406 {
2407 TILE_OP_TYPE_REGISTER, BFD_RELOC(NONE),
2408 2, 0, 1, 0, 0, 0,
2409 create_Src_SN, get_Src_SN
2410 }
2411};
2412
2413
2414
2415
2416/* Given a set of bundle bits and the lookup FSM for a specific pipe,
2417 * returns which instruction the bundle contains in that pipe.
2418 */
2419static const struct tile_opcode *
2420find_opcode(tile_bundle_bits bits, const unsigned short *table)
2421{
2422 int index = 0;
2423
2424 while (1)
2425 {
2426 unsigned short bitspec = table[index];
2427 unsigned int bitfield =
2428 ((unsigned int)(bits >> (bitspec & 63))) & (bitspec >> 6);
2429
2430 unsigned short next = table[index + 1 + bitfield];
2431 if (next <= TILE_OPC_NONE)
2432 return &tile_opcodes[next];
2433
2434 index = next - TILE_OPC_NONE;
2435 }
2436}
2437
2438
2439int
2440parse_insn_tile(tile_bundle_bits bits,
2441 unsigned int pc,
2442 struct tile_decoded_instruction
2443 decoded[TILE_MAX_INSTRUCTIONS_PER_BUNDLE])
2444{
2445 int num_instructions = 0;
2446 int pipe;
2447
2448 int min_pipe, max_pipe;
2449 if ((bits & TILE_BUNDLE_Y_ENCODING_MASK) == 0)
2450 {
2451 min_pipe = TILE_PIPELINE_X0;
2452 max_pipe = TILE_PIPELINE_X1;
2453 }
2454 else
2455 {
2456 min_pipe = TILE_PIPELINE_Y0;
2457 max_pipe = TILE_PIPELINE_Y2;
2458 }
2459
2460 /* For each pipe, find an instruction that fits. */
2461 for (pipe = min_pipe; pipe <= max_pipe; pipe++)
2462 {
2463 const struct tile_opcode *opc;
2464 struct tile_decoded_instruction *d;
2465 int i;
2466
2467 d = &decoded[num_instructions++];
2468 opc = find_opcode (bits, tile_bundle_decoder_fsms[pipe]);
2469 d->opcode = opc;
2470
2471 /* Decode each operand, sign extending, etc. as appropriate. */
2472 for (i = 0; i < opc->num_operands; i++)
2473 {
2474 const struct tile_operand *op =
2475 &tile_operands[opc->operands[pipe][i]];
2476 int opval = op->extract (bits);
2477 if (op->is_signed)
2478 {
2479 /* Sign-extend the operand. */
2480 int shift = (int)((sizeof(int) * 8) - op->num_bits);
2481 opval = (opval << shift) >> shift;
2482 }
2483
2484 /* Adjust PC-relative scaled branch offsets. */
2485 if (op->type == TILE_OP_TYPE_ADDRESS)
2486 {
2487 opval *= TILE_BUNDLE_SIZE_IN_BYTES;
2488 opval += (int)pc;
2489 }
2490
2491 /* Record the final value. */
2492 d->operands[i] = op;
2493 d->operand_values[i] = opval;
2494 }
2495 }
2496
2497 return num_instructions;
2498}
diff --git a/arch/tile/kernel/time.c b/arch/tile/kernel/time.c
new file mode 100644
index 000000000000..6bed820e1421
--- /dev/null
+++ b/arch/tile/kernel/time.c
@@ -0,0 +1,226 @@
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 * Support the cycle counter clocksource and tile timer clock event device.
15 */
16
17#include <linux/time.h>
18#include <linux/timex.h>
19#include <linux/clocksource.h>
20#include <linux/clockchips.h>
21#include <linux/hardirq.h>
22#include <linux/sched.h>
23#include <linux/smp.h>
24#include <linux/delay.h>
25#include <asm/irq_regs.h>
26#include <asm/traps.h>
27#include <hv/hypervisor.h>
28#include <arch/interrupts.h>
29#include <arch/spr_def.h>
30
31
32/*
33 * Define the cycle counter clock source.
34 */
35
36/* How many cycles per second we are running at. */
37static cycles_t cycles_per_sec __write_once;
38
39cycles_t get_clock_rate(void)
40{
41 return cycles_per_sec;
42}
43
44#if CHIP_HAS_SPLIT_CYCLE()
45cycles_t get_cycles(void)
46{
47 unsigned int high = __insn_mfspr(SPR_CYCLE_HIGH);
48 unsigned int low = __insn_mfspr(SPR_CYCLE_LOW);
49 unsigned int high2 = __insn_mfspr(SPR_CYCLE_HIGH);
50
51 while (unlikely(high != high2)) {
52 low = __insn_mfspr(SPR_CYCLE_LOW);
53 high = high2;
54 high2 = __insn_mfspr(SPR_CYCLE_HIGH);
55 }
56
57 return (((cycles_t)high) << 32) | low;
58}
59#endif
60
61/*
62 * We use a relatively small shift value so that sched_clock()
63 * won't wrap around very often.
64 */
65#define SCHED_CLOCK_SHIFT 10
66
67static unsigned long sched_clock_mult __write_once;
68
69static cycles_t clocksource_get_cycles(struct clocksource *cs)
70{
71 return get_cycles();
72}
73
74static struct clocksource cycle_counter_cs = {
75 .name = "cycle counter",
76 .rating = 300,
77 .read = clocksource_get_cycles,
78 .mask = CLOCKSOURCE_MASK(64),
79 .shift = 22, /* typical value, e.g. x86 tsc uses this */
80 .flags = CLOCK_SOURCE_IS_CONTINUOUS,
81};
82
83/*
84 * Called very early from setup_arch() to set cycles_per_sec.
85 * We initialize it early so we can use it to set up loops_per_jiffy.
86 */
87void __init setup_clock(void)
88{
89 cycles_per_sec = hv_sysconf(HV_SYSCONF_CPU_SPEED);
90 sched_clock_mult =
91 clocksource_hz2mult(cycles_per_sec, SCHED_CLOCK_SHIFT);
92 cycle_counter_cs.mult =
93 clocksource_hz2mult(cycles_per_sec, cycle_counter_cs.shift);
94}
95
96void __init calibrate_delay(void)
97{
98 loops_per_jiffy = get_clock_rate() / HZ;
99 pr_info("Clock rate yields %lu.%02lu BogoMIPS (lpj=%lu)\n",
100 loops_per_jiffy/(500000/HZ),
101 (loops_per_jiffy/(5000/HZ)) % 100, loops_per_jiffy);
102}
103
104/* Called fairly late in init/main.c, but before we go smp. */
105void __init time_init(void)
106{
107 /* Initialize and register the clock source. */
108 clocksource_register(&cycle_counter_cs);
109
110 /* Start up the tile-timer interrupt source on the boot cpu. */
111 setup_tile_timer();
112}
113
114
115/*
116 * Define the tile timer clock event device. The timer is driven by
117 * the TILE_TIMER_CONTROL register, which consists of a 31-bit down
118 * counter, plus bit 31, which signifies that the counter has wrapped
119 * from zero to (2**31) - 1. The INT_TILE_TIMER interrupt will be
120 * raised as long as bit 31 is set.
121 *
122 * The TILE_MINSEC value represents the largest range of real-time
123 * we can possibly cover with the timer, based on MAX_TICK combined
124 * with the slowest reasonable clock rate we might run at.
125 */
126
127#define MAX_TICK 0x7fffffff /* we have 31 bits of countdown timer */
128#define TILE_MINSEC 5 /* timer covers no more than 5 seconds */
129
130static int tile_timer_set_next_event(unsigned long ticks,
131 struct clock_event_device *evt)
132{
133 BUG_ON(ticks > MAX_TICK);
134 __insn_mtspr(SPR_TILE_TIMER_CONTROL, ticks);
135 raw_local_irq_unmask_now(INT_TILE_TIMER);
136 return 0;
137}
138
139/*
140 * Whenever anyone tries to change modes, we just mask interrupts
141 * and wait for the next event to get set.
142 */
143static void tile_timer_set_mode(enum clock_event_mode mode,
144 struct clock_event_device *evt)
145{
146 raw_local_irq_mask_now(INT_TILE_TIMER);
147}
148
149/*
150 * Set min_delta_ns to 1 microsecond, since it takes about
151 * that long to fire the interrupt.
152 */
153static DEFINE_PER_CPU(struct clock_event_device, tile_timer) = {
154 .name = "tile timer",
155 .features = CLOCK_EVT_FEAT_ONESHOT,
156 .min_delta_ns = 1000,
157 .rating = 100,
158 .irq = -1,
159 .set_next_event = tile_timer_set_next_event,
160 .set_mode = tile_timer_set_mode,
161};
162
163void __cpuinit setup_tile_timer(void)
164{
165 struct clock_event_device *evt = &__get_cpu_var(tile_timer);
166
167 /* Fill in fields that are speed-specific. */
168 clockevents_calc_mult_shift(evt, cycles_per_sec, TILE_MINSEC);
169 evt->max_delta_ns = clockevent_delta2ns(MAX_TICK, evt);
170
171 /* Mark as being for this cpu only. */
172 evt->cpumask = cpumask_of(smp_processor_id());
173
174 /* Start out with timer not firing. */
175 raw_local_irq_mask_now(INT_TILE_TIMER);
176
177 /* Register tile timer. */
178 clockevents_register_device(evt);
179}
180
181/* Called from the interrupt vector. */
182void do_timer_interrupt(struct pt_regs *regs, int fault_num)
183{
184 struct pt_regs *old_regs = set_irq_regs(regs);
185 struct clock_event_device *evt = &__get_cpu_var(tile_timer);
186
187 /*
188 * Mask the timer interrupt here, since we are a oneshot timer
189 * and there are now by definition no events pending.
190 */
191 raw_local_irq_mask(INT_TILE_TIMER);
192
193 /* Track time spent here in an interrupt context */
194 irq_enter();
195
196 /* Track interrupt count. */
197 __get_cpu_var(irq_stat).irq_timer_count++;
198
199 /* Call the generic timer handler */
200 evt->event_handler(evt);
201
202 /*
203 * Track time spent against the current process again and
204 * process any softirqs if they are waiting.
205 */
206 irq_exit();
207
208 set_irq_regs(old_regs);
209}
210
211/*
212 * Scheduler clock - returns current time in nanosec units.
213 * Note that with LOCKDEP, this is called during lockdep_init(), and
214 * we will claim that sched_clock() is zero for a little while, until
215 * we run setup_clock(), above.
216 */
217unsigned long long sched_clock(void)
218{
219 return clocksource_cyc2ns(get_cycles(),
220 sched_clock_mult, SCHED_CLOCK_SHIFT);
221}
222
223int setup_profiling_timer(unsigned int multiplier)
224{
225 return -EINVAL;
226}
diff --git a/arch/tile/kernel/tlb.c b/arch/tile/kernel/tlb.c
new file mode 100644
index 000000000000..2dffc1044d83
--- /dev/null
+++ b/arch/tile/kernel/tlb.c
@@ -0,0 +1,97 @@
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
16#include <linux/cpumask.h>
17#include <linux/module.h>
18#include <asm/tlbflush.h>
19#include <asm/homecache.h>
20#include <hv/hypervisor.h>
21
22/* From tlbflush.h */
23DEFINE_PER_CPU(int, current_asid);
24int min_asid, max_asid;
25
26/*
27 * Note that we flush the L1I (for VM_EXEC pages) as well as the TLB
28 * so that when we are unmapping an executable page, we also flush it.
29 * Combined with flushing the L1I at context switch time, this means
30 * we don't have to do any other icache flushes.
31 */
32
33void flush_tlb_mm(struct mm_struct *mm)
34{
35 HV_Remote_ASID asids[NR_CPUS];
36 int i = 0, cpu;
37 for_each_cpu(cpu, &mm->cpu_vm_mask) {
38 HV_Remote_ASID *asid = &asids[i++];
39 asid->y = cpu / smp_topology.width;
40 asid->x = cpu % smp_topology.width;
41 asid->asid = per_cpu(current_asid, cpu);
42 }
43 flush_remote(0, HV_FLUSH_EVICT_L1I, &mm->cpu_vm_mask,
44 0, 0, 0, NULL, asids, i);
45}
46
47void flush_tlb_current_task(void)
48{
49 flush_tlb_mm(current->mm);
50}
51
52void flush_tlb_page_mm(const struct vm_area_struct *vma, struct mm_struct *mm,
53 unsigned long va)
54{
55 unsigned long size = hv_page_size(vma);
56 int cache = (vma->vm_flags & VM_EXEC) ? HV_FLUSH_EVICT_L1I : 0;
57 flush_remote(0, cache, &mm->cpu_vm_mask,
58 va, size, size, &mm->cpu_vm_mask, NULL, 0);
59}
60
61void flush_tlb_page(const struct vm_area_struct *vma, unsigned long va)
62{
63 flush_tlb_page_mm(vma, vma->vm_mm, va);
64}
65EXPORT_SYMBOL(flush_tlb_page);
66
67void flush_tlb_range(const struct vm_area_struct *vma,
68 unsigned long start, unsigned long end)
69{
70 unsigned long size = hv_page_size(vma);
71 struct mm_struct *mm = vma->vm_mm;
72 int cache = (vma->vm_flags & VM_EXEC) ? HV_FLUSH_EVICT_L1I : 0;
73 flush_remote(0, cache, &mm->cpu_vm_mask, start, end - start, size,
74 &mm->cpu_vm_mask, NULL, 0);
75}
76
77void flush_tlb_all(void)
78{
79 int i;
80 for (i = 0; ; ++i) {
81 HV_VirtAddrRange r = hv_inquire_virtual(i);
82 if (r.size == 0)
83 break;
84 flush_remote(0, HV_FLUSH_EVICT_L1I, cpu_online_mask,
85 r.start, r.size, PAGE_SIZE, cpu_online_mask,
86 NULL, 0);
87 flush_remote(0, 0, NULL,
88 r.start, r.size, HPAGE_SIZE, cpu_online_mask,
89 NULL, 0);
90 }
91}
92
93void flush_tlb_kernel_range(unsigned long start, unsigned long end)
94{
95 flush_remote(0, HV_FLUSH_EVICT_L1I, cpu_online_mask,
96 start, end - start, PAGE_SIZE, cpu_online_mask, NULL, 0);
97}
diff --git a/arch/tile/kernel/traps.c b/arch/tile/kernel/traps.c
new file mode 100644
index 000000000000..0f362dc2c57f
--- /dev/null
+++ b/arch/tile/kernel/traps.c
@@ -0,0 +1,319 @@
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#include <linux/sched.h>
16#include <linux/kernel.h>
17#include <linux/kprobes.h>
18#include <linux/module.h>
19#include <linux/reboot.h>
20#include <linux/uaccess.h>
21#include <linux/ptrace.h>
22#include <asm/opcode-tile.h>
23#include <asm/opcode_constants.h>
24#include <asm/stack.h>
25#include <asm/traps.h>
26
27#include <arch/interrupts.h>
28#include <arch/spr_def.h>
29
30void __init trap_init(void)
31{
32 /* Nothing needed here since we link code at .intrpt1 */
33}
34
35int unaligned_fixup = 1;
36
37static int __init setup_unaligned_fixup(char *str)
38{
39 /*
40 * Say "=-1" to completely disable it. If you just do "=0", we
41 * will still parse the instruction, then fire a SIGBUS with
42 * the correct address from inside the single_step code.
43 */
44 long val;
45 if (strict_strtol(str, 0, &val) != 0)
46 return 0;
47 unaligned_fixup = val;
48 pr_info("Fixups for unaligned data accesses are %s\n",
49 unaligned_fixup >= 0 ?
50 (unaligned_fixup ? "enabled" : "disabled") :
51 "completely disabled");
52 return 1;
53}
54__setup("unaligned_fixup=", setup_unaligned_fixup);
55
56#if CHIP_HAS_TILE_DMA()
57
58static int dma_disabled;
59
60static int __init nodma(char *str)
61{
62 pr_info("User-space DMA is disabled\n");
63 dma_disabled = 1;
64 return 1;
65}
66__setup("nodma", nodma);
67
68/* How to decode SPR_GPV_REASON */
69#define IRET_ERROR (1U << 31)
70#define MT_ERROR (1U << 30)
71#define MF_ERROR (1U << 29)
72#define SPR_INDEX ((1U << 15) - 1)
73#define SPR_MPL_SHIFT 9 /* starting bit position for MPL encoded in SPR */
74
75/*
76 * See if this GPV is just to notify the kernel of SPR use and we can
77 * retry the user instruction after adjusting some MPLs suitably.
78 */
79static int retry_gpv(unsigned int gpv_reason)
80{
81 int mpl;
82
83 if (gpv_reason & IRET_ERROR)
84 return 0;
85
86 BUG_ON((gpv_reason & (MT_ERROR|MF_ERROR)) == 0);
87 mpl = (gpv_reason & SPR_INDEX) >> SPR_MPL_SHIFT;
88 if (mpl == INT_DMA_NOTIFY && !dma_disabled) {
89 /* User is turning on DMA. Allow it and retry. */
90 printk(KERN_DEBUG "Process %d/%s is now enabled for DMA\n",
91 current->pid, current->comm);
92 BUG_ON(current->thread.tile_dma_state.enabled);
93 current->thread.tile_dma_state.enabled = 1;
94 grant_dma_mpls();
95 return 1;
96 }
97
98 return 0;
99}
100
101#endif /* CHIP_HAS_TILE_DMA() */
102
103#ifdef __tilegx__
104#define bundle_bits tilegx_bundle_bits
105#else
106#define bundle_bits tile_bundle_bits
107#endif
108
109extern bundle_bits bpt_code;
110
111asm(".pushsection .rodata.bpt_code,\"a\";"
112 ".align 8;"
113 "bpt_code: bpt;"
114 ".size bpt_code,.-bpt_code;"
115 ".popsection");
116
117static int special_ill(bundle_bits bundle, int *sigp, int *codep)
118{
119 int sig, code, maxcode;
120
121 if (bundle == bpt_code) {
122 *sigp = SIGTRAP;
123 *codep = TRAP_BRKPT;
124 return 1;
125 }
126
127 /* If it's a "raise" bundle, then "ill" must be in pipe X1. */
128#ifdef __tilegx__
129 if ((bundle & TILEGX_BUNDLE_MODE_MASK) != 0)
130 return 0;
131 if (get_Opcode_X1(bundle) != RRR_0_OPCODE_X1)
132 return 0;
133 if (get_RRROpcodeExtension_X1(bundle) != UNARY_RRR_0_OPCODE_X1)
134 return 0;
135 if (get_UnaryOpcodeExtension_X1(bundle) != ILL_UNARY_OPCODE_X1)
136 return 0;
137#else
138 if (bundle & TILE_BUNDLE_Y_ENCODING_MASK)
139 return 0;
140 if (get_Opcode_X1(bundle) != SHUN_0_OPCODE_X1)
141 return 0;
142 if (get_UnShOpcodeExtension_X1(bundle) != UN_0_SHUN_0_OPCODE_X1)
143 return 0;
144 if (get_UnOpcodeExtension_X1(bundle) != ILL_UN_0_SHUN_0_OPCODE_X1)
145 return 0;
146#endif
147
148 /* Check that the magic distinguishers are set to mean "raise". */
149 if (get_Dest_X1(bundle) != 29 || get_SrcA_X1(bundle) != 37)
150 return 0;
151
152 /* There must be an "addli zero, zero, VAL" in X0. */
153 if (get_Opcode_X0(bundle) != ADDLI_OPCODE_X0)
154 return 0;
155 if (get_Dest_X0(bundle) != TREG_ZERO)
156 return 0;
157 if (get_SrcA_X0(bundle) != TREG_ZERO)
158 return 0;
159
160 /*
161 * Validate the proposed signal number and si_code value.
162 * Note that we embed these in the static instruction itself
163 * so that we perturb the register state as little as possible
164 * at the time of the actual fault; it's unlikely you'd ever
165 * need to dynamically choose which kind of fault to raise
166 * from user space.
167 */
168 sig = get_Imm16_X0(bundle) & 0x3f;
169 switch (sig) {
170 case SIGILL:
171 maxcode = NSIGILL;
172 break;
173 case SIGFPE:
174 maxcode = NSIGFPE;
175 break;
176 case SIGSEGV:
177 maxcode = NSIGSEGV;
178 break;
179 case SIGBUS:
180 maxcode = NSIGBUS;
181 break;
182 case SIGTRAP:
183 maxcode = NSIGTRAP;
184 break;
185 default:
186 return 0;
187 }
188 code = (get_Imm16_X0(bundle) >> 6) & 0xf;
189 if (code <= 0 || code > maxcode)
190 return 0;
191
192 /* Make it the requested signal. */
193 *sigp = sig;
194 *codep = code | __SI_FAULT;
195 return 1;
196}
197
198void __kprobes do_trap(struct pt_regs *regs, int fault_num,
199 unsigned long reason)
200{
201 siginfo_t info = { 0 };
202 int signo, code;
203 unsigned long address;
204 bundle_bits instr;
205
206 /* Re-enable interrupts. */
207 local_irq_enable();
208
209 /*
210 * If it hits in kernel mode and we can't fix it up, just exit the
211 * current process and hope for the best.
212 */
213 if (!user_mode(regs)) {
214 if (fixup_exception(regs)) /* only UNALIGN_DATA in practice */
215 return;
216 pr_alert("Kernel took bad trap %d at PC %#lx\n",
217 fault_num, regs->pc);
218 if (fault_num == INT_GPV)
219 pr_alert("GPV_REASON is %#lx\n", reason);
220 show_regs(regs);
221 do_exit(SIGKILL); /* FIXME: implement i386 die() */
222 return;
223 }
224
225 switch (fault_num) {
226 case INT_ILL:
227 if (copy_from_user(&instr, (void __user *)regs->pc,
228 sizeof(instr))) {
229 pr_err("Unreadable instruction for INT_ILL:"
230 " %#lx\n", regs->pc);
231 do_exit(SIGKILL);
232 return;
233 }
234 if (!special_ill(instr, &signo, &code)) {
235 signo = SIGILL;
236 code = ILL_ILLOPC;
237 }
238 address = regs->pc;
239 break;
240 case INT_GPV:
241#if CHIP_HAS_TILE_DMA()
242 if (retry_gpv(reason))
243 return;
244#endif
245 /*FALLTHROUGH*/
246 case INT_UDN_ACCESS:
247 case INT_IDN_ACCESS:
248#if CHIP_HAS_SN()
249 case INT_SN_ACCESS:
250#endif
251 signo = SIGILL;
252 code = ILL_PRVREG;
253 address = regs->pc;
254 break;
255 case INT_SWINT_3:
256 case INT_SWINT_2:
257 case INT_SWINT_0:
258 signo = SIGILL;
259 code = ILL_ILLTRP;
260 address = regs->pc;
261 break;
262 case INT_UNALIGN_DATA:
263#ifndef __tilegx__ /* FIXME: GX: no single-step yet */
264 if (unaligned_fixup >= 0) {
265 struct single_step_state *state =
266 current_thread_info()->step_state;
267 if (!state ||
268 (void __user *)(regs->pc) != state->buffer) {
269 single_step_once(regs);
270 return;
271 }
272 }
273#endif
274 signo = SIGBUS;
275 code = BUS_ADRALN;
276 address = 0;
277 break;
278 case INT_DOUBLE_FAULT:
279 /*
280 * For double fault, "reason" is actually passed as
281 * SYSTEM_SAVE_1_2, the hypervisor's double-fault info, so
282 * we can provide the original fault number rather than
283 * the uninteresting "INT_DOUBLE_FAULT" so the user can
284 * learn what actually struck while PL0 ICS was set.
285 */
286 fault_num = reason;
287 signo = SIGILL;
288 code = ILL_DBLFLT;
289 address = regs->pc;
290 break;
291#ifdef __tilegx__
292 case INT_ILL_TRANS:
293 signo = SIGSEGV;
294 code = SEGV_MAPERR;
295 if (reason & SPR_ILL_TRANS_REASON__I_STREAM_VA_RMASK)
296 address = regs->pc;
297 else
298 address = 0; /* FIXME: GX: single-step for address */
299 break;
300#endif
301 default:
302 panic("Unexpected do_trap interrupt number %d", fault_num);
303 return;
304 }
305
306 info.si_signo = signo;
307 info.si_code = code;
308 info.si_addr = (void __user *)address;
309 if (signo == SIGILL)
310 info.si_trapno = fault_num;
311 force_sig_info(signo, &info, current);
312}
313
314void kernel_double_fault(int dummy, ulong pc, ulong lr, ulong sp, ulong r52)
315{
316 _dump_stack(dummy, pc, lr, sp, r52);
317 pr_emerg("Double fault: exiting\n");
318 machine_halt();
319}
diff --git a/arch/tile/kernel/vmlinux.lds.S b/arch/tile/kernel/vmlinux.lds.S
new file mode 100644
index 000000000000..25fdc0c1839a
--- /dev/null
+++ b/arch/tile/kernel/vmlinux.lds.S
@@ -0,0 +1,98 @@
1#include <asm-generic/vmlinux.lds.h>
2#include <asm/page.h>
3#include <asm/cache.h>
4#include <asm/thread_info.h>
5#include <hv/hypervisor.h>
6
7/* Text loads starting from the supervisor interrupt vector address. */
8#define TEXT_OFFSET MEM_SV_INTRPT
9
10OUTPUT_ARCH(tile)
11ENTRY(_start)
12jiffies = jiffies_64;
13
14PHDRS
15{
16 intrpt1 PT_LOAD ;
17 text PT_LOAD ;
18 data PT_LOAD ;
19}
20SECTIONS
21{
22 /* Text is loaded with a different VA than data; start with text. */
23 #undef LOAD_OFFSET
24 #define LOAD_OFFSET TEXT_OFFSET
25
26 /* Interrupt vectors */
27 .intrpt1 (LOAD_OFFSET) : AT ( 0 ) /* put at the start of physical memory */
28 {
29 _text = .;
30 _stext = .;
31 *(.intrpt1)
32 } :intrpt1 =0
33
34 /* Hypervisor call vectors */
35 #include "hvglue.lds"
36
37 /* Now the real code */
38 . = ALIGN(0x20000);
39 .text : AT (ADDR(.text) - LOAD_OFFSET) {
40 HEAD_TEXT
41 SCHED_TEXT
42 LOCK_TEXT
43 __fix_text_end = .; /* tile-cpack won't rearrange before this */
44 TEXT_TEXT
45 *(.text.*)
46 *(.coldtext*)
47 *(.fixup)
48 *(.gnu.warning)
49 } :text =0
50 _etext = .;
51
52 /* "Init" is divided into two areas with very different virtual addresses. */
53 INIT_TEXT_SECTION(PAGE_SIZE)
54
55 /* Now we skip back to PAGE_OFFSET for the data. */
56 . = (. - TEXT_OFFSET + PAGE_OFFSET);
57 #undef LOAD_OFFSET
58 #define LOAD_OFFSET PAGE_OFFSET
59
60 . = ALIGN(PAGE_SIZE);
61 VMLINUX_SYMBOL(_sinitdata) = .;
62 .init.page : AT (ADDR(.init.page) - LOAD_OFFSET) {
63 *(.init.page)
64 } :data =0
65 INIT_DATA_SECTION(16)
66 PERCPU(PAGE_SIZE)
67 . = ALIGN(PAGE_SIZE);
68 VMLINUX_SYMBOL(_einitdata) = .;
69
70 _sdata = .; /* Start of data section */
71
72 RO_DATA_SECTION(PAGE_SIZE)
73
74 /* initially writeable, then read-only */
75 . = ALIGN(PAGE_SIZE);
76 __w1data_begin = .;
77 .w1data : AT(ADDR(.w1data) - LOAD_OFFSET) {
78 VMLINUX_SYMBOL(__w1data_begin) = .;
79 *(.w1data)
80 VMLINUX_SYMBOL(__w1data_end) = .;
81 }
82
83 RW_DATA_SECTION(L2_CACHE_BYTES, PAGE_SIZE, THREAD_SIZE)
84
85 _edata = .;
86
87 EXCEPTION_TABLE(L2_CACHE_BYTES)
88 NOTES
89
90
91 BSS_SECTION(8, PAGE_SIZE, 1)
92 _end = . ;
93
94 STABS_DEBUG
95 DWARF_DEBUG
96
97 DISCARDS
98}
diff --git a/arch/tile/lib/Makefile b/arch/tile/lib/Makefile
new file mode 100644
index 000000000000..746dc81ed3c4
--- /dev/null
+++ b/arch/tile/lib/Makefile
@@ -0,0 +1,18 @@
1#
2# Makefile for TILE-specific library files..
3#
4
5lib-y = cacheflush.o checksum.o cpumask.o delay.o \
6 mb_incoherent.o uaccess.o \
7 memcpy_$(BITS).o memchr_$(BITS).o memmove_$(BITS).o memset_$(BITS).o \
8 strchr_$(BITS).o strlen_$(BITS).o
9
10ifeq ($(CONFIG_TILEGX),y)
11lib-y += memcpy_user_64.o
12else
13lib-y += atomic_32.o atomic_asm_32.o memcpy_tile64.o
14endif
15
16lib-$(CONFIG_SMP) += spinlock_$(BITS).o usercopy_$(BITS).o
17
18obj-$(CONFIG_MODULES) += exports.o
diff --git a/arch/tile/lib/atomic_32.c b/arch/tile/lib/atomic_32.c
new file mode 100644
index 000000000000..8040b42a8eea
--- /dev/null
+++ b/arch/tile/lib/atomic_32.c
@@ -0,0 +1,330 @@
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#include <linux/cache.h>
16#include <linux/delay.h>
17#include <linux/uaccess.h>
18#include <linux/module.h>
19#include <linux/mm.h>
20#include <asm/atomic.h>
21#include <asm/futex.h>
22#include <arch/chip.h>
23
24/* See <asm/atomic_32.h> */
25#if ATOMIC_LOCKS_FOUND_VIA_TABLE()
26
27/*
28 * A block of memory containing locks for atomic ops. Each instance of this
29 * struct will be homed on a different CPU.
30 */
31struct atomic_locks_on_cpu {
32 int lock[ATOMIC_HASH_L2_SIZE];
33} __attribute__((aligned(ATOMIC_HASH_L2_SIZE * 4)));
34
35static DEFINE_PER_CPU(struct atomic_locks_on_cpu, atomic_lock_pool);
36
37/* The locks we'll use until __init_atomic_per_cpu is called. */
38static struct atomic_locks_on_cpu __initdata initial_atomic_locks;
39
40/* Hash into this vector to get a pointer to lock for the given atomic. */
41struct atomic_locks_on_cpu *atomic_lock_ptr[ATOMIC_HASH_L1_SIZE]
42 __write_once = {
43 [0 ... ATOMIC_HASH_L1_SIZE-1] (&initial_atomic_locks)
44};
45
46#else /* ATOMIC_LOCKS_FOUND_VIA_TABLE() */
47
48/* This page is remapped on startup to be hash-for-home. */
49int atomic_locks[PAGE_SIZE / sizeof(int) /* Only ATOMIC_HASH_SIZE is used */]
50 __attribute__((aligned(PAGE_SIZE), section(".bss.page_aligned")));
51
52#endif /* ATOMIC_LOCKS_FOUND_VIA_TABLE() */
53
54static inline int *__atomic_hashed_lock(volatile void *v)
55{
56 /* NOTE: this code must match "sys_cmpxchg" in kernel/intvec.S */
57#if ATOMIC_LOCKS_FOUND_VIA_TABLE()
58 unsigned long i =
59 (unsigned long) v & ((PAGE_SIZE-1) & -sizeof(long long));
60 unsigned long n = __insn_crc32_32(0, i);
61
62 /* Grab high bits for L1 index. */
63 unsigned long l1_index = n >> ((sizeof(n) * 8) - ATOMIC_HASH_L1_SHIFT);
64 /* Grab low bits for L2 index. */
65 unsigned long l2_index = n & (ATOMIC_HASH_L2_SIZE - 1);
66
67 return &atomic_lock_ptr[l1_index]->lock[l2_index];
68#else
69 /*
70 * Use bits [3, 3 + ATOMIC_HASH_SHIFT) as the lock index.
71 * Using mm works here because atomic_locks is page aligned.
72 */
73 unsigned long ptr = __insn_mm((unsigned long)v >> 1,
74 (unsigned long)atomic_locks,
75 2, (ATOMIC_HASH_SHIFT + 2) - 1);
76 return (int *)ptr;
77#endif
78}
79
80#ifdef CONFIG_SMP
81/* Return whether the passed pointer is a valid atomic lock pointer. */
82static int is_atomic_lock(int *p)
83{
84#if ATOMIC_LOCKS_FOUND_VIA_TABLE()
85 int i;
86 for (i = 0; i < ATOMIC_HASH_L1_SIZE; ++i) {
87
88 if (p >= &atomic_lock_ptr[i]->lock[0] &&
89 p < &atomic_lock_ptr[i]->lock[ATOMIC_HASH_L2_SIZE]) {
90 return 1;
91 }
92 }
93 return 0;
94#else
95 return p >= &atomic_locks[0] && p < &atomic_locks[ATOMIC_HASH_SIZE];
96#endif
97}
98
99void __atomic_fault_unlock(int *irqlock_word)
100{
101 BUG_ON(!is_atomic_lock(irqlock_word));
102 BUG_ON(*irqlock_word != 1);
103 *irqlock_word = 0;
104}
105
106#endif /* CONFIG_SMP */
107
108static inline int *__atomic_setup(volatile void *v)
109{
110 /* Issue a load to the target to bring it into cache. */
111 *(volatile int *)v;
112 return __atomic_hashed_lock(v);
113}
114
115int _atomic_xchg(atomic_t *v, int n)
116{
117 return __atomic_xchg(&v->counter, __atomic_setup(v), n).val;
118}
119EXPORT_SYMBOL(_atomic_xchg);
120
121int _atomic_xchg_add(atomic_t *v, int i)
122{
123 return __atomic_xchg_add(&v->counter, __atomic_setup(v), i).val;
124}
125EXPORT_SYMBOL(_atomic_xchg_add);
126
127int _atomic_xchg_add_unless(atomic_t *v, int a, int u)
128{
129 /*
130 * Note: argument order is switched here since it is easier
131 * to use the first argument consistently as the "old value"
132 * in the assembly, as is done for _atomic_cmpxchg().
133 */
134 return __atomic_xchg_add_unless(&v->counter, __atomic_setup(v), u, a)
135 .val;
136}
137EXPORT_SYMBOL(_atomic_xchg_add_unless);
138
139int _atomic_cmpxchg(atomic_t *v, int o, int n)
140{
141 return __atomic_cmpxchg(&v->counter, __atomic_setup(v), o, n).val;
142}
143EXPORT_SYMBOL(_atomic_cmpxchg);
144
145unsigned long _atomic_or(volatile unsigned long *p, unsigned long mask)
146{
147 return __atomic_or((int *)p, __atomic_setup(p), mask).val;
148}
149EXPORT_SYMBOL(_atomic_or);
150
151unsigned long _atomic_andn(volatile unsigned long *p, unsigned long mask)
152{
153 return __atomic_andn((int *)p, __atomic_setup(p), mask).val;
154}
155EXPORT_SYMBOL(_atomic_andn);
156
157unsigned long _atomic_xor(volatile unsigned long *p, unsigned long mask)
158{
159 return __atomic_xor((int *)p, __atomic_setup(p), mask).val;
160}
161EXPORT_SYMBOL(_atomic_xor);
162
163
164u64 _atomic64_xchg(atomic64_t *v, u64 n)
165{
166 return __atomic64_xchg(&v->counter, __atomic_setup(v), n);
167}
168EXPORT_SYMBOL(_atomic64_xchg);
169
170u64 _atomic64_xchg_add(atomic64_t *v, u64 i)
171{
172 return __atomic64_xchg_add(&v->counter, __atomic_setup(v), i);
173}
174EXPORT_SYMBOL(_atomic64_xchg_add);
175
176u64 _atomic64_xchg_add_unless(atomic64_t *v, u64 a, u64 u)
177{
178 /*
179 * Note: argument order is switched here since it is easier
180 * to use the first argument consistently as the "old value"
181 * in the assembly, as is done for _atomic_cmpxchg().
182 */
183 return __atomic64_xchg_add_unless(&v->counter, __atomic_setup(v),
184 u, a);
185}
186EXPORT_SYMBOL(_atomic64_xchg_add_unless);
187
188u64 _atomic64_cmpxchg(atomic64_t *v, u64 o, u64 n)
189{
190 return __atomic64_cmpxchg(&v->counter, __atomic_setup(v), o, n);
191}
192EXPORT_SYMBOL(_atomic64_cmpxchg);
193
194
195static inline int *__futex_setup(int __user *v)
196{
197 /*
198 * Issue a prefetch to the counter to bring it into cache.
199 * As for __atomic_setup, but we can't do a read into the L1
200 * since it might fault; instead we do a prefetch into the L2.
201 */
202 __insn_prefetch(v);
203 return __atomic_hashed_lock((int __force *)v);
204}
205
206struct __get_user futex_set(int __user *v, int i)
207{
208 return __atomic_xchg((int __force *)v, __futex_setup(v), i);
209}
210
211struct __get_user futex_add(int __user *v, int n)
212{
213 return __atomic_xchg_add((int __force *)v, __futex_setup(v), n);
214}
215
216struct __get_user futex_or(int __user *v, int n)
217{
218 return __atomic_or((int __force *)v, __futex_setup(v), n);
219}
220
221struct __get_user futex_andn(int __user *v, int n)
222{
223 return __atomic_andn((int __force *)v, __futex_setup(v), n);
224}
225
226struct __get_user futex_xor(int __user *v, int n)
227{
228 return __atomic_xor((int __force *)v, __futex_setup(v), n);
229}
230
231struct __get_user futex_cmpxchg(int __user *v, int o, int n)
232{
233 return __atomic_cmpxchg((int __force *)v, __futex_setup(v), o, n);
234}
235
236/*
237 * If any of the atomic or futex routines hit a bad address (not in
238 * the page tables at kernel PL) this routine is called. The futex
239 * routines are never used on kernel space, and the normal atomics and
240 * bitops are never used on user space. So a fault on kernel space
241 * must be fatal, but a fault on userspace is a futex fault and we
242 * need to return -EFAULT. Note that the context this routine is
243 * invoked in is the context of the "_atomic_xxx()" routines called
244 * by the functions in this file.
245 */
246struct __get_user __atomic_bad_address(int __user *addr)
247{
248 if (unlikely(!access_ok(VERIFY_WRITE, addr, sizeof(int))))
249 panic("Bad address used for kernel atomic op: %p\n", addr);
250 return (struct __get_user) { .err = -EFAULT };
251}
252
253
254#if CHIP_HAS_CBOX_HOME_MAP()
255static int __init noatomichash(char *str)
256{
257 pr_warning("noatomichash is deprecated.\n");
258 return 1;
259}
260__setup("noatomichash", noatomichash);
261#endif
262
263void __init __init_atomic_per_cpu(void)
264{
265#if ATOMIC_LOCKS_FOUND_VIA_TABLE()
266
267 unsigned int i;
268 int actual_cpu;
269
270 /*
271 * Before this is called from setup, we just have one lock for
272 * all atomic objects/operations. Here we replace the
273 * elements of atomic_lock_ptr so that they point at per_cpu
274 * integers. This seemingly over-complex approach stems from
275 * the fact that DEFINE_PER_CPU defines an entry for each cpu
276 * in the grid, not each cpu from 0..ATOMIC_HASH_SIZE-1. But
277 * for efficient hashing of atomics to their locks we want a
278 * compile time constant power of 2 for the size of this
279 * table, so we use ATOMIC_HASH_SIZE.
280 *
281 * Here we populate atomic_lock_ptr from the per cpu
282 * atomic_lock_pool, interspersing by actual cpu so that
283 * subsequent elements are homed on consecutive cpus.
284 */
285
286 actual_cpu = cpumask_first(cpu_possible_mask);
287
288 for (i = 0; i < ATOMIC_HASH_L1_SIZE; ++i) {
289 /*
290 * Preincrement to slightly bias against using cpu 0,
291 * which has plenty of stuff homed on it already.
292 */
293 actual_cpu = cpumask_next(actual_cpu, cpu_possible_mask);
294 if (actual_cpu >= nr_cpu_ids)
295 actual_cpu = cpumask_first(cpu_possible_mask);
296
297 atomic_lock_ptr[i] = &per_cpu(atomic_lock_pool, actual_cpu);
298 }
299
300#else /* ATOMIC_LOCKS_FOUND_VIA_TABLE() */
301
302 /* Validate power-of-two and "bigger than cpus" assumption */
303 BUG_ON(ATOMIC_HASH_SIZE & (ATOMIC_HASH_SIZE-1));
304 BUG_ON(ATOMIC_HASH_SIZE < nr_cpu_ids);
305
306 /*
307 * On TILEPro we prefer to use a single hash-for-home
308 * page, since this means atomic operations are less
309 * likely to encounter a TLB fault and thus should
310 * in general perform faster. You may wish to disable
311 * this in situations where few hash-for-home tiles
312 * are configured.
313 */
314 BUG_ON((unsigned long)atomic_locks % PAGE_SIZE != 0);
315
316 /* The locks must all fit on one page. */
317 BUG_ON(ATOMIC_HASH_SIZE * sizeof(int) > PAGE_SIZE);
318
319 /*
320 * We use the page offset of the atomic value's address as
321 * an index into atomic_locks, excluding the low 3 bits.
322 * That should not produce more indices than ATOMIC_HASH_SIZE.
323 */
324 BUG_ON((PAGE_SIZE >> 3) > ATOMIC_HASH_SIZE);
325
326#endif /* ATOMIC_LOCKS_FOUND_VIA_TABLE() */
327
328 /* The futex code makes this assumption, so we validate it here. */
329 BUG_ON(sizeof(atomic_t) != sizeof(int));
330}
diff --git a/arch/tile/lib/atomic_asm_32.S b/arch/tile/lib/atomic_asm_32.S
new file mode 100644
index 000000000000..5a5514b77e78
--- /dev/null
+++ b/arch/tile/lib/atomic_asm_32.S
@@ -0,0 +1,196 @@
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 * Support routines for atomic operations. Each function takes:
15 *
16 * r0: address to manipulate
17 * r1: pointer to atomic lock guarding this operation (for FUTEX_LOCK_REG)
18 * r2: new value to write, or for cmpxchg/add_unless, value to compare against
19 * r3: (cmpxchg/xchg_add_unless) new value to write or add;
20 * (atomic64 ops) high word of value to write
21 * r4/r5: (cmpxchg64/add_unless64) new value to write or add
22 *
23 * The 32-bit routines return a "struct __get_user" so that the futex code
24 * has an opportunity to return -EFAULT to the user if needed.
25 * The 64-bit routines just return a "long long" with the value,
26 * since they are only used from kernel space and don't expect to fault.
27 * Support for 16-bit ops is included in the framework but we don't provide
28 * any (x86_64 has an atomic_inc_short(), so we might want to some day).
29 *
30 * Note that the caller is advised to issue a suitable L1 or L2
31 * prefetch on the address being manipulated to avoid extra stalls.
32 * In addition, the hot path is on two icache lines, and we start with
33 * a jump to the second line to make sure they are both in cache so
34 * that we never stall waiting on icache fill while holding the lock.
35 * (This doesn't work out with most 64-bit ops, since they consume
36 * too many bundles, so may take an extra i-cache stall.)
37 *
38 * These routines set the INTERRUPT_CRITICAL_SECTION bit, just
39 * like sys_cmpxchg(), so that NMIs like PERF_COUNT will not interrupt
40 * the code, just page faults.
41 *
42 * If the load or store faults in a way that can be directly fixed in
43 * the do_page_fault_ics() handler (e.g. a vmalloc reference) we fix it
44 * directly, return to the instruction that faulted, and retry it.
45 *
46 * If the load or store faults in a way that potentially requires us
47 * to release the atomic lock, then retry (e.g. a migrating PTE), we
48 * reset the PC in do_page_fault_ics() to the "tns" instruction so
49 * that on return we will reacquire the lock and restart the op. We
50 * are somewhat overloading the exception_table_entry notion by doing
51 * this, since those entries are not normally used for migrating PTEs.
52 *
53 * If the main page fault handler discovers a bad address, it will see
54 * the PC pointing to the "tns" instruction (due to the earlier
55 * exception_table_entry processing in do_page_fault_ics), and
56 * re-reset the PC to the fault handler, atomic_bad_address(), which
57 * effectively takes over from the atomic op and can either return a
58 * bad "struct __get_user" (for user addresses) or can just panic (for
59 * bad kernel addresses).
60 *
61 * Note that if the value we would store is the same as what we
62 * loaded, we bypass the load. Other platforms with true atomics can
63 * make the guarantee that a non-atomic __clear_bit(), for example,
64 * can safely race with an atomic test_and_set_bit(); this example is
65 * from bit_spinlock.h in slub_lock() / slub_unlock(). We can't do
66 * that on Tile since the "atomic" op is really just a
67 * read/modify/write, and can race with the non-atomic
68 * read/modify/write. However, if we can short-circuit the write when
69 * it is not needed, in the atomic case, we avoid the race.
70 */
71
72#include <linux/linkage.h>
73#include <asm/atomic.h>
74#include <asm/page.h>
75#include <asm/processor.h>
76
77 .section .text.atomic,"ax"
78ENTRY(__start_atomic_asm_code)
79
80 .macro atomic_op, name, bitwidth, body
81 .align 64
82STD_ENTRY_SECTION(__atomic\name, .text.atomic)
83 {
84 movei r24, 1
85 j 4f /* branch to second cache line */
86 }
871: {
88 .ifc \bitwidth,16
89 lh r22, r0
90 .else
91 lw r22, r0
92 addi r28, r0, 4
93 .endif
94 }
95 .ifc \bitwidth,64
96 lw r23, r28
97 .endif
98 \body /* set r24, and r25 if 64-bit */
99 {
100 seq r26, r22, r24
101 seq r27, r23, r25
102 }
103 .ifc \bitwidth,64
104 bbnst r27, 2f
105 .endif
106 bbs r26, 3f /* skip write-back if it's the same value */
1072: {
108 .ifc \bitwidth,16
109 sh r0, r24
110 .else
111 sw r0, r24
112 .endif
113 }
114 .ifc \bitwidth,64
115 sw r28, r25
116 .endif
117 mf
1183: {
119 move r0, r22
120 .ifc \bitwidth,64
121 move r1, r23
122 .else
123 move r1, zero
124 .endif
125 sw ATOMIC_LOCK_REG_NAME, zero
126 }
127 mtspr INTERRUPT_CRITICAL_SECTION, zero
128 jrp lr
1294: {
130 move ATOMIC_LOCK_REG_NAME, r1
131 mtspr INTERRUPT_CRITICAL_SECTION, r24
132 }
133#ifndef CONFIG_SMP
134 j 1b /* no atomic locks */
135#else
136 {
137 tns r21, ATOMIC_LOCK_REG_NAME
138 moveli r23, 2048 /* maximum backoff time in cycles */
139 }
140 {
141 bzt r21, 1b /* branch if lock acquired */
142 moveli r25, 32 /* starting backoff time in cycles */
143 }
1445: mtspr INTERRUPT_CRITICAL_SECTION, zero
145 mfspr r26, CYCLE_LOW /* get start point for this backoff */
1466: mfspr r22, CYCLE_LOW /* test to see if we've backed off enough */
147 sub r22, r22, r26
148 slt r22, r22, r25
149 bbst r22, 6b
150 {
151 mtspr INTERRUPT_CRITICAL_SECTION, r24
152 shli r25, r25, 1 /* double the backoff; retry the tns */
153 }
154 {
155 tns r21, ATOMIC_LOCK_REG_NAME
156 slt r26, r23, r25 /* is the proposed backoff too big? */
157 }
158 {
159 bzt r21, 1b /* branch if lock acquired */
160 mvnz r25, r26, r23
161 }
162 j 5b
163#endif
164 STD_ENDPROC(__atomic\name)
165 .ifc \bitwidth,32
166 .pushsection __ex_table,"a"
167 .word 1b, __atomic\name
168 .word 2b, __atomic\name
169 .word __atomic\name, __atomic_bad_address
170 .popsection
171 .endif
172 .endm
173
174atomic_op _cmpxchg, 32, "seq r26, r22, r2; { bbns r26, 3f; move r24, r3 }"
175atomic_op _xchg, 32, "move r24, r2"
176atomic_op _xchg_add, 32, "add r24, r22, r2"
177atomic_op _xchg_add_unless, 32, \
178 "sne r26, r22, r2; { bbns r26, 3f; add r24, r22, r3 }"
179atomic_op _or, 32, "or r24, r22, r2"
180atomic_op _andn, 32, "nor r2, r2, zero; and r24, r22, r2"
181atomic_op _xor, 32, "xor r24, r22, r2"
182
183atomic_op 64_cmpxchg, 64, "{ seq r26, r22, r2; seq r27, r23, r3 }; \
184 { bbns r26, 3f; move r24, r4 }; { bbns r27, 3f; move r25, r5 }"
185atomic_op 64_xchg, 64, "{ move r24, r2; move r25, r3 }"
186atomic_op 64_xchg_add, 64, "{ add r24, r22, r2; add r25, r23, r3 }; \
187 slt_u r26, r24, r22; add r25, r25, r26"
188atomic_op 64_xchg_add_unless, 64, \
189 "{ sne r26, r22, r2; sne r27, r23, r3 }; \
190 { bbns r26, 3f; add r24, r22, r4 }; \
191 { bbns r27, 3f; add r25, r23, r5 }; \
192 slt_u r26, r24, r22; add r25, r25, r26"
193
194 jrp lr /* happy backtracer */
195
196ENTRY(__end_atomic_asm_code)
diff --git a/arch/tile/lib/cacheflush.c b/arch/tile/lib/cacheflush.c
new file mode 100644
index 000000000000..11b6164c2097
--- /dev/null
+++ b/arch/tile/lib/cacheflush.c
@@ -0,0 +1,23 @@
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#include <asm/page.h>
16#include <asm/cacheflush.h>
17#include <arch/icache.h>
18
19
20void __flush_icache_range(unsigned long start, unsigned long end)
21{
22 invalidate_icache((const void *)start, end - start, PAGE_SIZE);
23}
diff --git a/arch/tile/lib/checksum.c b/arch/tile/lib/checksum.c
new file mode 100644
index 000000000000..e4bab5bd3f31
--- /dev/null
+++ b/arch/tile/lib/checksum.c
@@ -0,0 +1,102 @@
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 * Support code for the main lib/checksum.c.
14 */
15
16#include <net/checksum.h>
17#include <linux/module.h>
18
19static inline unsigned int longto16(unsigned long x)
20{
21 unsigned long ret;
22#ifdef __tilegx__
23 ret = __insn_v2sadu(x, 0);
24 ret = __insn_v2sadu(ret, 0);
25#else
26 ret = __insn_sadh_u(x, 0);
27 ret = __insn_sadh_u(ret, 0);
28#endif
29 return ret;
30}
31
32__wsum do_csum(const unsigned char *buff, int len)
33{
34 int odd, count;
35 unsigned long result = 0;
36
37 if (len <= 0)
38 goto out;
39 odd = 1 & (unsigned long) buff;
40 if (odd) {
41 result = (*buff << 8);
42 len--;
43 buff++;
44 }
45 count = len >> 1; /* nr of 16-bit words.. */
46 if (count) {
47 if (2 & (unsigned long) buff) {
48 result += *(const unsigned short *)buff;
49 count--;
50 len -= 2;
51 buff += 2;
52 }
53 count >>= 1; /* nr of 32-bit words.. */
54 if (count) {
55#ifdef __tilegx__
56 if (4 & (unsigned long) buff) {
57 unsigned int w = *(const unsigned int *)buff;
58 result = __insn_v2sadau(result, w, 0);
59 count--;
60 len -= 4;
61 buff += 4;
62 }
63 count >>= 1; /* nr of 64-bit words.. */
64#endif
65
66 /*
67 * This algorithm could wrap around for very
68 * large buffers, but those should be impossible.
69 */
70 BUG_ON(count >= 65530);
71
72 while (count) {
73 unsigned long w = *(const unsigned long *)buff;
74 count--;
75 buff += sizeof(w);
76#ifdef __tilegx__
77 result = __insn_v2sadau(result, w, 0);
78#else
79 result = __insn_sadah_u(result, w, 0);
80#endif
81 }
82#ifdef __tilegx__
83 if (len & 4) {
84 unsigned int w = *(const unsigned int *)buff;
85 result = __insn_v2sadau(result, w, 0);
86 buff += 4;
87 }
88#endif
89 }
90 if (len & 2) {
91 result += *(const unsigned short *) buff;
92 buff += 2;
93 }
94 }
95 if (len & 1)
96 result += *buff;
97 result = longto16(result);
98 if (odd)
99 result = swab16(result);
100out:
101 return result;
102}
diff --git a/arch/tile/lib/cpumask.c b/arch/tile/lib/cpumask.c
new file mode 100644
index 000000000000..fdc403614d12
--- /dev/null
+++ b/arch/tile/lib/cpumask.c
@@ -0,0 +1,52 @@
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#include <linux/cpumask.h>
16#include <linux/ctype.h>
17#include <linux/errno.h>
18#include <linux/smp.h>
19
20/*
21 * Allow cropping out bits beyond the end of the array.
22 * Move to "lib" directory if more clients want to use this routine.
23 */
24int bitmap_parselist_crop(const char *bp, unsigned long *maskp, int nmaskbits)
25{
26 unsigned a, b;
27
28 bitmap_zero(maskp, nmaskbits);
29 do {
30 if (!isdigit(*bp))
31 return -EINVAL;
32 a = simple_strtoul(bp, (char **)&bp, 10);
33 b = a;
34 if (*bp == '-') {
35 bp++;
36 if (!isdigit(*bp))
37 return -EINVAL;
38 b = simple_strtoul(bp, (char **)&bp, 10);
39 }
40 if (!(a <= b))
41 return -EINVAL;
42 if (b >= nmaskbits)
43 b = nmaskbits-1;
44 while (a <= b) {
45 set_bit(a, maskp);
46 a++;
47 }
48 if (*bp == ',')
49 bp++;
50 } while (*bp != '\0' && *bp != '\n');
51 return 0;
52}
diff --git a/arch/tile/lib/delay.c b/arch/tile/lib/delay.c
new file mode 100644
index 000000000000..5801b03c13ef
--- /dev/null
+++ b/arch/tile/lib/delay.c
@@ -0,0 +1,34 @@
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#include <linux/module.h>
16#include <linux/delay.h>
17#include <linux/thread_info.h>
18#include <asm/fixmap.h>
19#include <hv/hypervisor.h>
20
21void __udelay(unsigned long usecs)
22{
23 hv_nanosleep(usecs * 1000);
24}
25EXPORT_SYMBOL(__udelay);
26
27void __ndelay(unsigned long nsecs)
28{
29 hv_nanosleep(nsecs);
30}
31EXPORT_SYMBOL(__ndelay);
32
33/* FIXME: should be declared in a header somewhere. */
34EXPORT_SYMBOL(__delay);
diff --git a/arch/tile/lib/exports.c b/arch/tile/lib/exports.c
new file mode 100644
index 000000000000..ce5dbf56578f
--- /dev/null
+++ b/arch/tile/lib/exports.c
@@ -0,0 +1,85 @@
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 * Exports from assembler code and from libtile-cc.
15 */
16
17#include <linux/module.h>
18
19/* arch/tile/lib/usercopy.S */
20#include <linux/uaccess.h>
21EXPORT_SYMBOL(__get_user_1);
22EXPORT_SYMBOL(__get_user_2);
23EXPORT_SYMBOL(__get_user_4);
24EXPORT_SYMBOL(__get_user_8);
25EXPORT_SYMBOL(__put_user_1);
26EXPORT_SYMBOL(__put_user_2);
27EXPORT_SYMBOL(__put_user_4);
28EXPORT_SYMBOL(__put_user_8);
29EXPORT_SYMBOL(strnlen_user_asm);
30EXPORT_SYMBOL(strncpy_from_user_asm);
31EXPORT_SYMBOL(clear_user_asm);
32
33/* arch/tile/kernel/entry.S */
34#include <linux/kernel.h>
35#include <asm/processor.h>
36EXPORT_SYMBOL(current_text_addr);
37EXPORT_SYMBOL(dump_stack);
38
39/* arch/tile/lib/, various memcpy files */
40EXPORT_SYMBOL(memcpy);
41EXPORT_SYMBOL(__copy_to_user_inatomic);
42EXPORT_SYMBOL(__copy_from_user_inatomic);
43EXPORT_SYMBOL(__copy_from_user_zeroing);
44#ifdef __tilegx__
45EXPORT_SYMBOL(__copy_in_user_inatomic);
46#endif
47
48/* hypervisor glue */
49#include <hv/hypervisor.h>
50EXPORT_SYMBOL(hv_dev_open);
51EXPORT_SYMBOL(hv_dev_pread);
52EXPORT_SYMBOL(hv_dev_pwrite);
53EXPORT_SYMBOL(hv_dev_preada);
54EXPORT_SYMBOL(hv_dev_pwritea);
55EXPORT_SYMBOL(hv_dev_poll);
56EXPORT_SYMBOL(hv_dev_poll_cancel);
57EXPORT_SYMBOL(hv_dev_close);
58EXPORT_SYMBOL(hv_sysconf);
59EXPORT_SYMBOL(hv_confstr);
60
61/* libgcc.a */
62uint32_t __udivsi3(uint32_t dividend, uint32_t divisor);
63EXPORT_SYMBOL(__udivsi3);
64int32_t __divsi3(int32_t dividend, int32_t divisor);
65EXPORT_SYMBOL(__divsi3);
66uint64_t __udivdi3(uint64_t dividend, uint64_t divisor);
67EXPORT_SYMBOL(__udivdi3);
68int64_t __divdi3(int64_t dividend, int64_t divisor);
69EXPORT_SYMBOL(__divdi3);
70uint32_t __umodsi3(uint32_t dividend, uint32_t divisor);
71EXPORT_SYMBOL(__umodsi3);
72int32_t __modsi3(int32_t dividend, int32_t divisor);
73EXPORT_SYMBOL(__modsi3);
74uint64_t __umoddi3(uint64_t dividend, uint64_t divisor);
75EXPORT_SYMBOL(__umoddi3);
76int64_t __moddi3(int64_t dividend, int64_t divisor);
77EXPORT_SYMBOL(__moddi3);
78#ifndef __tilegx__
79uint64_t __ll_mul(uint64_t n0, uint64_t n1);
80EXPORT_SYMBOL(__ll_mul);
81int64_t __muldi3(int64_t, int64_t);
82EXPORT_SYMBOL(__muldi3);
83uint64_t __lshrdi3(uint64_t, unsigned int);
84EXPORT_SYMBOL(__lshrdi3);
85#endif
diff --git a/arch/tile/lib/mb_incoherent.S b/arch/tile/lib/mb_incoherent.S
new file mode 100644
index 000000000000..989ad7b68d5a
--- /dev/null
+++ b/arch/tile/lib/mb_incoherent.S
@@ -0,0 +1,34 @@
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 * Assembly code for invoking the HV's fence_incoherent syscall.
15 */
16
17#include <linux/linkage.h>
18#include <hv/syscall_public.h>
19#include <arch/abi.h>
20#include <arch/chip.h>
21
22#if !CHIP_HAS_MF_WAITS_FOR_VICTIMS()
23
24/*
25 * Invoke the hypervisor's fence_incoherent syscall, which guarantees
26 * that all victims for cachelines homed on this tile have reached memory.
27 */
28STD_ENTRY(__mb_incoherent)
29 moveli TREG_SYSCALL_NR_NAME, HV_SYS_fence_incoherent
30 swint2
31 jrp lr
32 STD_ENDPROC(__mb_incoherent)
33
34#endif
diff --git a/arch/tile/lib/memchr_32.c b/arch/tile/lib/memchr_32.c
new file mode 100644
index 000000000000..6235283b4859
--- /dev/null
+++ b/arch/tile/lib/memchr_32.c
@@ -0,0 +1,68 @@
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#include <linux/types.h>
16#include <linux/string.h>
17#include <linux/module.h>
18
19void *memchr(const void *s, int c, size_t n)
20{
21 /* Get an aligned pointer. */
22 const uintptr_t s_int = (uintptr_t) s;
23 const uint32_t *p = (const uint32_t *)(s_int & -4);
24
25 /* Create four copies of the byte for which we are looking. */
26 const uint32_t goal = 0x01010101 * (uint8_t) c;
27
28 /* Read the first word, but munge it so that bytes before the array
29 * will not match goal.
30 *
31 * Note that this shift count expression works because we know
32 * shift counts are taken mod 32.
33 */
34 const uint32_t before_mask = (1 << (s_int << 3)) - 1;
35 uint32_t v = (*p | before_mask) ^ (goal & before_mask);
36
37 /* Compute the address of the last byte. */
38 const char *const last_byte_ptr = (const char *)s + n - 1;
39
40 /* Compute the address of the word containing the last byte. */
41 const uint32_t *const last_word_ptr =
42 (const uint32_t *)((uintptr_t) last_byte_ptr & -4);
43
44 uint32_t bits;
45 char *ret;
46
47 if (__builtin_expect(n == 0, 0)) {
48 /* Don't dereference any memory if the array is empty. */
49 return NULL;
50 }
51
52 while ((bits = __insn_seqb(v, goal)) == 0) {
53 if (__builtin_expect(p == last_word_ptr, 0)) {
54 /* We already read the last word in the array,
55 * so give up.
56 */
57 return NULL;
58 }
59 v = *++p;
60 }
61
62 /* We found a match, but it might be in a byte past the end
63 * of the array.
64 */
65 ret = ((char *)p) + (__insn_ctz(bits) >> 3);
66 return (ret <= last_byte_ptr) ? ret : NULL;
67}
68EXPORT_SYMBOL(memchr);
diff --git a/arch/tile/lib/memcpy_32.S b/arch/tile/lib/memcpy_32.S
new file mode 100644
index 000000000000..30c3b7ebb55d
--- /dev/null
+++ b/arch/tile/lib/memcpy_32.S
@@ -0,0 +1,616 @@
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 * This file shares the implementation of the userspace memcpy and
15 * the kernel's memcpy, copy_to_user and copy_from_user.
16 */
17
18#include <arch/chip.h>
19
20
21#include <linux/linkage.h>
22
23/* On TILE64, we wrap these functions via arch/tile/lib/memcpy_tile64.c */
24#if !CHIP_HAS_COHERENT_LOCAL_CACHE()
25#define memcpy __memcpy_asm
26#define __copy_to_user_inatomic __copy_to_user_inatomic_asm
27#define __copy_from_user_inatomic __copy_from_user_inatomic_asm
28#define __copy_from_user_zeroing __copy_from_user_zeroing_asm
29#endif
30
31#define IS_MEMCPY 0
32#define IS_COPY_FROM_USER 1
33#define IS_COPY_FROM_USER_ZEROING 2
34#define IS_COPY_TO_USER -1
35
36 .section .text.memcpy_common, "ax"
37 .align 64
38
39/* Use this to preface each bundle that can cause an exception so
40 * the kernel can clean up properly. The special cleanup code should
41 * not use these, since it knows what it is doing.
42 */
43#define EX \
44 .pushsection __ex_table, "a"; \
45 .word 9f, memcpy_common_fixup; \
46 .popsection; \
47 9
48
49
50/* __copy_from_user_inatomic takes the kernel target address in r0,
51 * the user source in r1, and the bytes to copy in r2.
52 * It returns the number of uncopiable bytes (hopefully zero) in r0.
53 */
54ENTRY(__copy_from_user_inatomic)
55.type __copy_from_user_inatomic, @function
56 FEEDBACK_ENTER_EXPLICIT(__copy_from_user_inatomic, \
57 .text.memcpy_common, \
58 .Lend_memcpy_common - __copy_from_user_inatomic)
59 { movei r29, IS_COPY_FROM_USER; j memcpy_common }
60 .size __copy_from_user_inatomic, . - __copy_from_user_inatomic
61
62/* __copy_from_user_zeroing is like __copy_from_user_inatomic, but
63 * any uncopiable bytes are zeroed in the target.
64 */
65ENTRY(__copy_from_user_zeroing)
66.type __copy_from_user_zeroing, @function
67 FEEDBACK_REENTER(__copy_from_user_inatomic)
68 { movei r29, IS_COPY_FROM_USER_ZEROING; j memcpy_common }
69 .size __copy_from_user_zeroing, . - __copy_from_user_zeroing
70
71/* __copy_to_user_inatomic takes the user target address in r0,
72 * the kernel source in r1, and the bytes to copy in r2.
73 * It returns the number of uncopiable bytes (hopefully zero) in r0.
74 */
75ENTRY(__copy_to_user_inatomic)
76.type __copy_to_user_inatomic, @function
77 FEEDBACK_REENTER(__copy_from_user_inatomic)
78 { movei r29, IS_COPY_TO_USER; j memcpy_common }
79 .size __copy_to_user_inatomic, . - __copy_to_user_inatomic
80
81ENTRY(memcpy)
82.type memcpy, @function
83 FEEDBACK_REENTER(__copy_from_user_inatomic)
84 { movei r29, IS_MEMCPY }
85 .size memcpy, . - memcpy
86 /* Fall through */
87
88 .type memcpy_common, @function
89memcpy_common:
90 /* On entry, r29 holds one of the IS_* macro values from above. */
91
92
93 /* r0 is the dest, r1 is the source, r2 is the size. */
94
95 /* Save aside original dest so we can return it at the end. */
96 { sw sp, lr; move r23, r0; or r4, r0, r1 }
97
98 /* Check for an empty size. */
99 { bz r2, .Ldone; andi r4, r4, 3 }
100
101 /* Save aside original values in case of a fault. */
102 { move r24, r1; move r25, r2 }
103 move r27, lr
104
105 /* Check for an unaligned source or dest. */
106 { bnz r4, .Lcopy_unaligned_maybe_many; addli r4, r2, -256 }
107
108.Lcheck_aligned_copy_size:
109 /* If we are copying < 256 bytes, branch to simple case. */
110 { blzt r4, .Lcopy_8_check; slti_u r8, r2, 8 }
111
112 /* Copying >= 256 bytes, so jump to complex prefetching loop. */
113 { andi r6, r1, 63; j .Lcopy_many }
114
115/*
116 *
117 * Aligned 4 byte at a time copy loop
118 *
119 */
120
121.Lcopy_8_loop:
122 /* Copy two words at a time to hide load latency. */
123EX: { lw r3, r1; addi r1, r1, 4; slti_u r8, r2, 16 }
124EX: { lw r4, r1; addi r1, r1, 4 }
125EX: { sw r0, r3; addi r0, r0, 4; addi r2, r2, -4 }
126EX: { sw r0, r4; addi r0, r0, 4; addi r2, r2, -4 }
127.Lcopy_8_check:
128 { bzt r8, .Lcopy_8_loop; slti_u r4, r2, 4 }
129
130 /* Copy odd leftover word, if any. */
131 { bnzt r4, .Lcheck_odd_stragglers }
132EX: { lw r3, r1; addi r1, r1, 4 }
133EX: { sw r0, r3; addi r0, r0, 4; addi r2, r2, -4 }
134
135.Lcheck_odd_stragglers:
136 { bnz r2, .Lcopy_unaligned_few }
137
138.Ldone:
139 /* For memcpy return original dest address, else zero. */
140 { mz r0, r29, r23; jrp lr }
141
142
143/*
144 *
145 * Prefetching multiple cache line copy handler (for large transfers).
146 *
147 */
148
149 /* Copy words until r1 is cache-line-aligned. */
150.Lalign_loop:
151EX: { lw r3, r1; addi r1, r1, 4 }
152 { andi r6, r1, 63 }
153EX: { sw r0, r3; addi r0, r0, 4; addi r2, r2, -4 }
154.Lcopy_many:
155 { bnzt r6, .Lalign_loop; addi r9, r0, 63 }
156
157 { addi r3, r1, 60; andi r9, r9, -64 }
158
159#if CHIP_HAS_WH64()
160 /* No need to prefetch dst, we'll just do the wh64
161 * right before we copy a line.
162 */
163#endif
164
165EX: { lw r5, r3; addi r3, r3, 64; movei r4, 1 }
166 /* Intentionally stall for a few cycles to leave L2 cache alone. */
167 { bnzt zero, .; move r27, lr }
168EX: { lw r6, r3; addi r3, r3, 64 }
169 /* Intentionally stall for a few cycles to leave L2 cache alone. */
170 { bnzt zero, . }
171EX: { lw r7, r3; addi r3, r3, 64 }
172#if !CHIP_HAS_WH64()
173 /* Prefetch the dest */
174 /* Intentionally stall for a few cycles to leave L2 cache alone. */
175 { bnzt zero, . }
176 /* Use a real load to cause a TLB miss if necessary. We aren't using
177 * r28, so this should be fine.
178 */
179EX: { lw r28, r9; addi r9, r9, 64 }
180 /* Intentionally stall for a few cycles to leave L2 cache alone. */
181 { bnzt zero, . }
182 { prefetch r9; addi r9, r9, 64 }
183 /* Intentionally stall for a few cycles to leave L2 cache alone. */
184 { bnzt zero, . }
185 { prefetch r9; addi r9, r9, 64 }
186#endif
187 /* Intentionally stall for a few cycles to leave L2 cache alone. */
188 { bz zero, .Lbig_loop2 }
189
190 /* On entry to this loop:
191 * - r0 points to the start of dst line 0
192 * - r1 points to start of src line 0
193 * - r2 >= (256 - 60), only the first time the loop trips.
194 * - r3 contains r1 + 128 + 60 [pointer to end of source line 2]
195 * This is our prefetch address. When we get near the end
196 * rather than prefetching off the end this is changed to point
197 * to some "safe" recently loaded address.
198 * - r5 contains *(r1 + 60) [i.e. last word of source line 0]
199 * - r6 contains *(r1 + 64 + 60) [i.e. last word of source line 1]
200 * - r9 contains ((r0 + 63) & -64)
201 * [start of next dst cache line.]
202 */
203
204.Lbig_loop:
205 { jal .Lcopy_line2; add r15, r1, r2 }
206
207.Lbig_loop2:
208 /* Copy line 0, first stalling until r5 is ready. */
209EX: { move r12, r5; lw r16, r1 }
210 { bz r4, .Lcopy_8_check; slti_u r8, r2, 8 }
211 /* Prefetch several lines ahead. */
212EX: { lw r5, r3; addi r3, r3, 64 }
213 { jal .Lcopy_line }
214
215 /* Copy line 1, first stalling until r6 is ready. */
216EX: { move r12, r6; lw r16, r1 }
217 { bz r4, .Lcopy_8_check; slti_u r8, r2, 8 }
218 /* Prefetch several lines ahead. */
219EX: { lw r6, r3; addi r3, r3, 64 }
220 { jal .Lcopy_line }
221
222 /* Copy line 2, first stalling until r7 is ready. */
223EX: { move r12, r7; lw r16, r1 }
224 { bz r4, .Lcopy_8_check; slti_u r8, r2, 8 }
225 /* Prefetch several lines ahead. */
226EX: { lw r7, r3; addi r3, r3, 64 }
227 /* Use up a caches-busy cycle by jumping back to the top of the
228 * loop. Might as well get it out of the way now.
229 */
230 { j .Lbig_loop }
231
232
233 /* On entry:
234 * - r0 points to the destination line.
235 * - r1 points to the source line.
236 * - r3 is the next prefetch address.
237 * - r9 holds the last address used for wh64.
238 * - r12 = WORD_15
239 * - r16 = WORD_0.
240 * - r17 == r1 + 16.
241 * - r27 holds saved lr to restore.
242 *
243 * On exit:
244 * - r0 is incremented by 64.
245 * - r1 is incremented by 64, unless that would point to a word
246 * beyond the end of the source array, in which case it is redirected
247 * to point to an arbitrary word already in the cache.
248 * - r2 is decremented by 64.
249 * - r3 is unchanged, unless it points to a word beyond the
250 * end of the source array, in which case it is redirected
251 * to point to an arbitrary word already in the cache.
252 * Redirecting is OK since if we are that close to the end
253 * of the array we will not come back to this subroutine
254 * and use the contents of the prefetched address.
255 * - r4 is nonzero iff r2 >= 64.
256 * - r9 is incremented by 64, unless it points beyond the
257 * end of the last full destination cache line, in which
258 * case it is redirected to a "safe address" that can be
259 * clobbered (sp - 64)
260 * - lr contains the value in r27.
261 */
262
263/* r26 unused */
264
265.Lcopy_line:
266 /* TODO: when r3 goes past the end, we would like to redirect it
267 * to prefetch the last partial cache line (if any) just once, for the
268 * benefit of the final cleanup loop. But we don't want to
269 * prefetch that line more than once, or subsequent prefetches
270 * will go into the RTF. But then .Lbig_loop should unconditionally
271 * branch to top of loop to execute final prefetch, and its
272 * nop should become a conditional branch.
273 */
274
275 /* We need two non-memory cycles here to cover the resources
276 * used by the loads initiated by the caller.
277 */
278 { add r15, r1, r2 }
279.Lcopy_line2:
280 { slt_u r13, r3, r15; addi r17, r1, 16 }
281
282 /* NOTE: this will stall for one cycle as L1 is busy. */
283
284 /* Fill second L1D line. */
285EX: { lw r17, r17; addi r1, r1, 48; mvz r3, r13, r1 } /* r17 = WORD_4 */
286
287#if CHIP_HAS_WH64()
288 /* Prepare destination line for writing. */
289EX: { wh64 r9; addi r9, r9, 64 }
290#else
291 /* Prefetch dest line */
292 { prefetch r9; addi r9, r9, 64 }
293#endif
294 /* Load seven words that are L1D hits to cover wh64 L2 usage. */
295
296 /* Load the three remaining words from the last L1D line, which
297 * we know has already filled the L1D.
298 */
299EX: { lw r4, r1; addi r1, r1, 4; addi r20, r1, 16 } /* r4 = WORD_12 */
300EX: { lw r8, r1; addi r1, r1, 4; slt_u r13, r20, r15 }/* r8 = WORD_13 */
301EX: { lw r11, r1; addi r1, r1, -52; mvz r20, r13, r1 } /* r11 = WORD_14 */
302
303 /* Load the three remaining words from the first L1D line, first
304 * stalling until it has filled by "looking at" r16.
305 */
306EX: { lw r13, r1; addi r1, r1, 4; move zero, r16 } /* r13 = WORD_1 */
307EX: { lw r14, r1; addi r1, r1, 4 } /* r14 = WORD_2 */
308EX: { lw r15, r1; addi r1, r1, 8; addi r10, r0, 60 } /* r15 = WORD_3 */
309
310 /* Load second word from the second L1D line, first
311 * stalling until it has filled by "looking at" r17.
312 */
313EX: { lw r19, r1; addi r1, r1, 4; move zero, r17 } /* r19 = WORD_5 */
314
315 /* Store last word to the destination line, potentially dirtying it
316 * for the first time, which keeps the L2 busy for two cycles.
317 */
318EX: { sw r10, r12 } /* store(WORD_15) */
319
320 /* Use two L1D hits to cover the sw L2 access above. */
321EX: { lw r10, r1; addi r1, r1, 4 } /* r10 = WORD_6 */
322EX: { lw r12, r1; addi r1, r1, 4 } /* r12 = WORD_7 */
323
324 /* Fill third L1D line. */
325EX: { lw r18, r1; addi r1, r1, 4 } /* r18 = WORD_8 */
326
327 /* Store first L1D line. */
328EX: { sw r0, r16; addi r0, r0, 4; add r16, r0, r2 } /* store(WORD_0) */
329EX: { sw r0, r13; addi r0, r0, 4; andi r16, r16, -64 } /* store(WORD_1) */
330EX: { sw r0, r14; addi r0, r0, 4; slt_u r16, r9, r16 } /* store(WORD_2) */
331#if CHIP_HAS_WH64()
332EX: { sw r0, r15; addi r0, r0, 4; addi r13, sp, -64 } /* store(WORD_3) */
333#else
334 /* Back up the r9 to a cache line we are already storing to
335 * if it gets past the end of the dest vector. Strictly speaking,
336 * we don't need to back up to the start of a cache line, but it's free
337 * and tidy, so why not?
338 */
339EX: { sw r0, r15; addi r0, r0, 4; andi r13, r0, -64 } /* store(WORD_3) */
340#endif
341 /* Store second L1D line. */
342EX: { sw r0, r17; addi r0, r0, 4; mvz r9, r16, r13 }/* store(WORD_4) */
343EX: { sw r0, r19; addi r0, r0, 4 } /* store(WORD_5) */
344EX: { sw r0, r10; addi r0, r0, 4 } /* store(WORD_6) */
345EX: { sw r0, r12; addi r0, r0, 4 } /* store(WORD_7) */
346
347EX: { lw r13, r1; addi r1, r1, 4; move zero, r18 } /* r13 = WORD_9 */
348EX: { lw r14, r1; addi r1, r1, 4 } /* r14 = WORD_10 */
349EX: { lw r15, r1; move r1, r20 } /* r15 = WORD_11 */
350
351 /* Store third L1D line. */
352EX: { sw r0, r18; addi r0, r0, 4 } /* store(WORD_8) */
353EX: { sw r0, r13; addi r0, r0, 4 } /* store(WORD_9) */
354EX: { sw r0, r14; addi r0, r0, 4 } /* store(WORD_10) */
355EX: { sw r0, r15; addi r0, r0, 4 } /* store(WORD_11) */
356
357 /* Store rest of fourth L1D line. */
358EX: { sw r0, r4; addi r0, r0, 4 } /* store(WORD_12) */
359 {
360EX: sw r0, r8 /* store(WORD_13) */
361 addi r0, r0, 4
362 /* Will r2 be > 64 after we subtract 64 below? */
363 shri r4, r2, 7
364 }
365 {
366EX: sw r0, r11 /* store(WORD_14) */
367 addi r0, r0, 8
368 /* Record 64 bytes successfully copied. */
369 addi r2, r2, -64
370 }
371
372 { jrp lr; move lr, r27 }
373
374 /* Convey to the backtrace library that the stack frame is size
375 * zero, and the real return address is on the stack rather than
376 * in 'lr'.
377 */
378 { info 8 }
379
380 .align 64
381.Lcopy_unaligned_maybe_many:
382 /* Skip the setup overhead if we aren't copying many bytes. */
383 { slti_u r8, r2, 20; sub r4, zero, r0 }
384 { bnzt r8, .Lcopy_unaligned_few; andi r4, r4, 3 }
385 { bz r4, .Ldest_is_word_aligned; add r18, r1, r2 }
386
387/*
388 *
389 * unaligned 4 byte at a time copy handler.
390 *
391 */
392
393 /* Copy single bytes until r0 == 0 mod 4, so we can store words. */
394.Lalign_dest_loop:
395EX: { lb_u r3, r1; addi r1, r1, 1; addi r4, r4, -1 }
396EX: { sb r0, r3; addi r0, r0, 1; addi r2, r2, -1 }
397 { bnzt r4, .Lalign_dest_loop; andi r3, r1, 3 }
398
399 /* If source and dest are now *both* aligned, do an aligned copy. */
400 { bz r3, .Lcheck_aligned_copy_size; addli r4, r2, -256 }
401
402.Ldest_is_word_aligned:
403
404#if CHIP_HAS_DWORD_ALIGN()
405EX: { andi r8, r0, 63; lwadd_na r6, r1, 4}
406 { slti_u r9, r2, 64; bz r8, .Ldest_is_L2_line_aligned }
407
408 /* This copies unaligned words until either there are fewer
409 * than 4 bytes left to copy, or until the destination pointer
410 * is cache-aligned, whichever comes first.
411 *
412 * On entry:
413 * - r0 is the next store address.
414 * - r1 points 4 bytes past the load address corresponding to r0.
415 * - r2 >= 4
416 * - r6 is the next aligned word loaded.
417 */
418.Lcopy_unaligned_src_words:
419EX: { lwadd_na r7, r1, 4; slti_u r8, r2, 4 + 4 }
420 /* stall */
421 { dword_align r6, r7, r1; slti_u r9, r2, 64 + 4 }
422EX: { swadd r0, r6, 4; addi r2, r2, -4 }
423 { bnz r8, .Lcleanup_unaligned_words; andi r8, r0, 63 }
424 { bnzt r8, .Lcopy_unaligned_src_words; move r6, r7 }
425
426 /* On entry:
427 * - r0 is the next store address.
428 * - r1 points 4 bytes past the load address corresponding to r0.
429 * - r2 >= 4 (# of bytes left to store).
430 * - r6 is the next aligned src word value.
431 * - r9 = (r2 < 64U).
432 * - r18 points one byte past the end of source memory.
433 */
434.Ldest_is_L2_line_aligned:
435
436 {
437 /* Not a full cache line remains. */
438 bnz r9, .Lcleanup_unaligned_words
439 move r7, r6
440 }
441
442 /* r2 >= 64 */
443
444 /* Kick off two prefetches, but don't go past the end. */
445 { addi r3, r1, 63 - 4; addi r8, r1, 64 + 63 - 4 }
446 { prefetch r3; move r3, r8; slt_u r8, r8, r18 }
447 { mvz r3, r8, r1; addi r8, r3, 64 }
448 { prefetch r3; move r3, r8; slt_u r8, r8, r18 }
449 { mvz r3, r8, r1; movei r17, 0 }
450
451.Lcopy_unaligned_line:
452 /* Prefetch another line. */
453 { prefetch r3; addi r15, r1, 60; addi r3, r3, 64 }
454 /* Fire off a load of the last word we are about to copy. */
455EX: { lw_na r15, r15; slt_u r8, r3, r18 }
456
457EX: { mvz r3, r8, r1; wh64 r0 }
458
459 /* This loop runs twice.
460 *
461 * On entry:
462 * - r17 is even before the first iteration, and odd before
463 * the second. It is incremented inside the loop. Encountering
464 * an even value at the end of the loop makes it stop.
465 */
466.Lcopy_half_an_unaligned_line:
467EX: {
468 /* Stall until the last byte is ready. In the steady state this
469 * guarantees all words to load below will be in the L2 cache, which
470 * avoids shunting the loads to the RTF.
471 */
472 move zero, r15
473 lwadd_na r7, r1, 16
474 }
475EX: { lwadd_na r11, r1, 12 }
476EX: { lwadd_na r14, r1, -24 }
477EX: { lwadd_na r8, r1, 4 }
478EX: { lwadd_na r9, r1, 4 }
479EX: {
480 lwadd_na r10, r1, 8
481 /* r16 = (r2 < 64), after we subtract 32 from r2 below. */
482 slti_u r16, r2, 64 + 32
483 }
484EX: { lwadd_na r12, r1, 4; addi r17, r17, 1 }
485EX: { lwadd_na r13, r1, 8; dword_align r6, r7, r1 }
486EX: { swadd r0, r6, 4; dword_align r7, r8, r1 }
487EX: { swadd r0, r7, 4; dword_align r8, r9, r1 }
488EX: { swadd r0, r8, 4; dword_align r9, r10, r1 }
489EX: { swadd r0, r9, 4; dword_align r10, r11, r1 }
490EX: { swadd r0, r10, 4; dword_align r11, r12, r1 }
491EX: { swadd r0, r11, 4; dword_align r12, r13, r1 }
492EX: { swadd r0, r12, 4; dword_align r13, r14, r1 }
493EX: { swadd r0, r13, 4; addi r2, r2, -32 }
494 { move r6, r14; bbst r17, .Lcopy_half_an_unaligned_line }
495
496 { bzt r16, .Lcopy_unaligned_line; move r7, r6 }
497
498 /* On entry:
499 * - r0 is the next store address.
500 * - r1 points 4 bytes past the load address corresponding to r0.
501 * - r2 >= 0 (# of bytes left to store).
502 * - r7 is the next aligned src word value.
503 */
504.Lcleanup_unaligned_words:
505 /* Handle any trailing bytes. */
506 { bz r2, .Lcopy_unaligned_done; slti_u r8, r2, 4 }
507 { bzt r8, .Lcopy_unaligned_src_words; move r6, r7 }
508
509 /* Move r1 back to the point where it corresponds to r0. */
510 { addi r1, r1, -4 }
511
512#else /* !CHIP_HAS_DWORD_ALIGN() */
513
514 /* Compute right/left shift counts and load initial source words. */
515 { andi r5, r1, -4; andi r3, r1, 3 }
516EX: { lw r6, r5; addi r5, r5, 4; shli r3, r3, 3 }
517EX: { lw r7, r5; addi r5, r5, 4; sub r4, zero, r3 }
518
519 /* Load and store one word at a time, using shifts and ORs
520 * to correct for the misaligned src.
521 */
522.Lcopy_unaligned_src_loop:
523 { shr r6, r6, r3; shl r8, r7, r4 }
524EX: { lw r7, r5; or r8, r8, r6; move r6, r7 }
525EX: { sw r0, r8; addi r0, r0, 4; addi r2, r2, -4 }
526 { addi r5, r5, 4; slti_u r8, r2, 8 }
527 { bzt r8, .Lcopy_unaligned_src_loop; addi r1, r1, 4 }
528
529 { bz r2, .Lcopy_unaligned_done }
530#endif /* !CHIP_HAS_DWORD_ALIGN() */
531
532 /* Fall through */
533
534/*
535 *
536 * 1 byte at a time copy handler.
537 *
538 */
539
540.Lcopy_unaligned_few:
541EX: { lb_u r3, r1; addi r1, r1, 1 }
542EX: { sb r0, r3; addi r0, r0, 1; addi r2, r2, -1 }
543 { bnzt r2, .Lcopy_unaligned_few }
544
545.Lcopy_unaligned_done:
546
547 /* For memcpy return original dest address, else zero. */
548 { mz r0, r29, r23; jrp lr }
549
550.Lend_memcpy_common:
551 .size memcpy_common, .Lend_memcpy_common - memcpy_common
552
553 .section .fixup,"ax"
554memcpy_common_fixup:
555 .type memcpy_common_fixup, @function
556
557 /* Skip any bytes we already successfully copied.
558 * r2 (num remaining) is correct, but r0 (dst) and r1 (src)
559 * may not be quite right because of unrolling and prefetching.
560 * So we need to recompute their values as the address just
561 * after the last byte we are sure was successfully loaded and
562 * then stored.
563 */
564
565 /* Determine how many bytes we successfully copied. */
566 { sub r3, r25, r2 }
567
568 /* Add this to the original r0 and r1 to get their new values. */
569 { add r0, r23, r3; add r1, r24, r3 }
570
571 { bzt r29, memcpy_fixup_loop }
572 { blzt r29, copy_to_user_fixup_loop }
573
574copy_from_user_fixup_loop:
575 /* Try copying the rest one byte at a time, expecting a load fault. */
576.Lcfu: { lb_u r3, r1; addi r1, r1, 1 }
577 { sb r0, r3; addi r0, r0, 1; addi r2, r2, -1 }
578 { bnzt r2, copy_from_user_fixup_loop }
579
580.Lcopy_from_user_fixup_zero_remainder:
581 { bbs r29, 2f } /* low bit set means IS_COPY_FROM_USER */
582 /* byte-at-a-time loop faulted, so zero the rest. */
583 { move r3, r2; bz r2, 2f /* should be impossible, but handle it. */ }
5841: { sb r0, zero; addi r0, r0, 1; addi r3, r3, -1 }
585 { bnzt r3, 1b }
5862: move lr, r27
587 { move r0, r2; jrp lr }
588
589copy_to_user_fixup_loop:
590 /* Try copying the rest one byte at a time, expecting a store fault. */
591 { lb_u r3, r1; addi r1, r1, 1 }
592.Lctu: { sb r0, r3; addi r0, r0, 1; addi r2, r2, -1 }
593 { bnzt r2, copy_to_user_fixup_loop }
594.Lcopy_to_user_fixup_done:
595 move lr, r27
596 { move r0, r2; jrp lr }
597
598memcpy_fixup_loop:
599 /* Try copying the rest one byte at a time. We expect a disastrous
600 * fault to happen since we are in fixup code, but let it happen.
601 */
602 { lb_u r3, r1; addi r1, r1, 1 }
603 { sb r0, r3; addi r0, r0, 1; addi r2, r2, -1 }
604 { bnzt r2, memcpy_fixup_loop }
605 /* This should be unreachable, we should have faulted again.
606 * But be paranoid and handle it in case some interrupt changed
607 * the TLB or something.
608 */
609 move lr, r27
610 { move r0, r23; jrp lr }
611
612 .size memcpy_common_fixup, . - memcpy_common_fixup
613
614 .section __ex_table,"a"
615 .word .Lcfu, .Lcopy_from_user_fixup_zero_remainder
616 .word .Lctu, .Lcopy_to_user_fixup_done
diff --git a/arch/tile/lib/memcpy_tile64.c b/arch/tile/lib/memcpy_tile64.c
new file mode 100644
index 000000000000..dfedea7b266b
--- /dev/null
+++ b/arch/tile/lib/memcpy_tile64.c
@@ -0,0 +1,271 @@
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#include <linux/string.h>
16#include <linux/smp.h>
17#include <linux/module.h>
18#include <linux/uaccess.h>
19#include <asm/fixmap.h>
20#include <asm/kmap_types.h>
21#include <asm/tlbflush.h>
22#include <hv/hypervisor.h>
23#include <arch/chip.h>
24
25
26#if !CHIP_HAS_COHERENT_LOCAL_CACHE()
27
28/* Defined in memcpy.S */
29extern unsigned long __memcpy_asm(void *to, const void *from, unsigned long n);
30extern unsigned long __copy_to_user_inatomic_asm(
31 void __user *to, const void *from, unsigned long n);
32extern unsigned long __copy_from_user_inatomic_asm(
33 void *to, const void __user *from, unsigned long n);
34extern unsigned long __copy_from_user_zeroing_asm(
35 void *to, const void __user *from, unsigned long n);
36
37typedef unsigned long (*memcpy_t)(void *, const void *, unsigned long);
38
39/* Size above which to consider TLB games for performance */
40#define LARGE_COPY_CUTOFF 2048
41
42/* Communicate to the simulator what we are trying to do. */
43#define sim_allow_multiple_caching(b) \
44 __insn_mtspr(SPR_SIM_CONTROL, \
45 SIM_CONTROL_ALLOW_MULTIPLE_CACHING | ((b) << _SIM_CONTROL_OPERATOR_BITS))
46
47/*
48 * Copy memory by briefly enabling incoherent cacheline-at-a-time mode.
49 *
50 * We set up our own source and destination PTEs that we fully control.
51 * This is the only way to guarantee that we don't race with another
52 * thread that is modifying the PTE; we can't afford to try the
53 * copy_{to,from}_user() technique of catching the interrupt, since
54 * we must run with interrupts disabled to avoid the risk of some
55 * other code seeing the incoherent data in our cache. (Recall that
56 * our cache is indexed by PA, so even if the other code doesn't use
57 * our KM_MEMCPY virtual addresses, they'll still hit in cache using
58 * the normal VAs that aren't supposed to hit in cache.)
59 */
60static void memcpy_multicache(void *dest, const void *source,
61 pte_t dst_pte, pte_t src_pte, int len)
62{
63 int idx;
64 unsigned long flags, newsrc, newdst;
65 pmd_t *pmdp;
66 pte_t *ptep;
67 int cpu = get_cpu();
68
69 /*
70 * Disable interrupts so that we don't recurse into memcpy()
71 * in an interrupt handler, nor accidentally reference
72 * the PA of the source from an interrupt routine. Also
73 * notify the simulator that we're playing games so we don't
74 * generate spurious coherency warnings.
75 */
76 local_irq_save(flags);
77 sim_allow_multiple_caching(1);
78
79 /* Set up the new dest mapping */
80 idx = FIX_KMAP_BEGIN + (KM_TYPE_NR * cpu) + KM_MEMCPY0;
81 newdst = __fix_to_virt(idx) + ((unsigned long)dest & (PAGE_SIZE-1));
82 pmdp = pmd_offset(pud_offset(pgd_offset_k(newdst), newdst), newdst);
83 ptep = pte_offset_kernel(pmdp, newdst);
84 if (pte_val(*ptep) != pte_val(dst_pte)) {
85 set_pte(ptep, dst_pte);
86 local_flush_tlb_page(NULL, newdst, PAGE_SIZE);
87 }
88
89 /* Set up the new source mapping */
90 idx += (KM_MEMCPY0 - KM_MEMCPY1);
91 src_pte = hv_pte_set_nc(src_pte);
92 src_pte = hv_pte_clear_writable(src_pte); /* be paranoid */
93 newsrc = __fix_to_virt(idx) + ((unsigned long)source & (PAGE_SIZE-1));
94 pmdp = pmd_offset(pud_offset(pgd_offset_k(newsrc), newsrc), newsrc);
95 ptep = pte_offset_kernel(pmdp, newsrc);
96 *ptep = src_pte; /* set_pte() would be confused by this */
97 local_flush_tlb_page(NULL, newsrc, PAGE_SIZE);
98
99 /* Actually move the data. */
100 __memcpy_asm((void *)newdst, (const void *)newsrc, len);
101
102 /*
103 * Remap the source as locally-cached and not OLOC'ed so that
104 * we can inval without also invaling the remote cpu's cache.
105 * This also avoids known errata with inv'ing cacheable oloc data.
106 */
107 src_pte = hv_pte_set_mode(src_pte, HV_PTE_MODE_CACHE_NO_L3);
108 src_pte = hv_pte_set_writable(src_pte); /* need write access for inv */
109 *ptep = src_pte; /* set_pte() would be confused by this */
110 local_flush_tlb_page(NULL, newsrc, PAGE_SIZE);
111
112 /*
113 * Do the actual invalidation, covering the full L2 cache line
114 * at the end since __memcpy_asm() is somewhat aggressive.
115 */
116 __inv_buffer((void *)newsrc, len);
117
118 /*
119 * We're done: notify the simulator that all is back to normal,
120 * and re-enable interrupts and pre-emption.
121 */
122 sim_allow_multiple_caching(0);
123 local_irq_restore(flags);
124 put_cpu();
125}
126
127/*
128 * Identify large copies from remotely-cached memory, and copy them
129 * via memcpy_multicache() if they look good, otherwise fall back
130 * to the particular kind of copying passed as the memcpy_t function.
131 */
132static unsigned long fast_copy(void *dest, const void *source, int len,
133 memcpy_t func)
134{
135 /*
136 * Check if it's big enough to bother with. We may end up doing a
137 * small copy via TLB manipulation if we're near a page boundary,
138 * but presumably we'll make it up when we hit the second page.
139 */
140 while (len >= LARGE_COPY_CUTOFF) {
141 int copy_size, bytes_left_on_page;
142 pte_t *src_ptep, *dst_ptep;
143 pte_t src_pte, dst_pte;
144 struct page *src_page, *dst_page;
145
146 /* Is the source page oloc'ed to a remote cpu? */
147retry_source:
148 src_ptep = virt_to_pte(current->mm, (unsigned long)source);
149 if (src_ptep == NULL)
150 break;
151 src_pte = *src_ptep;
152 if (!hv_pte_get_present(src_pte) ||
153 !hv_pte_get_readable(src_pte) ||
154 hv_pte_get_mode(src_pte) != HV_PTE_MODE_CACHE_TILE_L3)
155 break;
156 if (get_remote_cache_cpu(src_pte) == smp_processor_id())
157 break;
158 src_page = pfn_to_page(hv_pte_get_pfn(src_pte));
159 get_page(src_page);
160 if (pte_val(src_pte) != pte_val(*src_ptep)) {
161 put_page(src_page);
162 goto retry_source;
163 }
164 if (pte_huge(src_pte)) {
165 /* Adjust the PTE to correspond to a small page */
166 int pfn = hv_pte_get_pfn(src_pte);
167 pfn += (((unsigned long)source & (HPAGE_SIZE-1))
168 >> PAGE_SHIFT);
169 src_pte = pfn_pte(pfn, src_pte);
170 src_pte = pte_mksmall(src_pte);
171 }
172
173 /* Is the destination page writable? */
174retry_dest:
175 dst_ptep = virt_to_pte(current->mm, (unsigned long)dest);
176 if (dst_ptep == NULL) {
177 put_page(src_page);
178 break;
179 }
180 dst_pte = *dst_ptep;
181 if (!hv_pte_get_present(dst_pte) ||
182 !hv_pte_get_writable(dst_pte)) {
183 put_page(src_page);
184 break;
185 }
186 dst_page = pfn_to_page(hv_pte_get_pfn(dst_pte));
187 if (dst_page == src_page) {
188 /*
189 * Source and dest are on the same page; this
190 * potentially exposes us to incoherence if any
191 * part of src and dest overlap on a cache line.
192 * Just give up rather than trying to be precise.
193 */
194 put_page(src_page);
195 break;
196 }
197 get_page(dst_page);
198 if (pte_val(dst_pte) != pte_val(*dst_ptep)) {
199 put_page(dst_page);
200 goto retry_dest;
201 }
202 if (pte_huge(dst_pte)) {
203 /* Adjust the PTE to correspond to a small page */
204 int pfn = hv_pte_get_pfn(dst_pte);
205 pfn += (((unsigned long)dest & (HPAGE_SIZE-1))
206 >> PAGE_SHIFT);
207 dst_pte = pfn_pte(pfn, dst_pte);
208 dst_pte = pte_mksmall(dst_pte);
209 }
210
211 /* All looks good: create a cachable PTE and copy from it */
212 copy_size = len;
213 bytes_left_on_page =
214 PAGE_SIZE - (((int)source) & (PAGE_SIZE-1));
215 if (copy_size > bytes_left_on_page)
216 copy_size = bytes_left_on_page;
217 bytes_left_on_page =
218 PAGE_SIZE - (((int)dest) & (PAGE_SIZE-1));
219 if (copy_size > bytes_left_on_page)
220 copy_size = bytes_left_on_page;
221 memcpy_multicache(dest, source, dst_pte, src_pte, copy_size);
222
223 /* Release the pages */
224 put_page(dst_page);
225 put_page(src_page);
226
227 /* Continue on the next page */
228 dest += copy_size;
229 source += copy_size;
230 len -= copy_size;
231 }
232
233 return func(dest, source, len);
234}
235
236void *memcpy(void *to, const void *from, __kernel_size_t n)
237{
238 if (n < LARGE_COPY_CUTOFF)
239 return (void *)__memcpy_asm(to, from, n);
240 else
241 return (void *)fast_copy(to, from, n, __memcpy_asm);
242}
243
244unsigned long __copy_to_user_inatomic(void __user *to, const void *from,
245 unsigned long n)
246{
247 if (n < LARGE_COPY_CUTOFF)
248 return __copy_to_user_inatomic_asm(to, from, n);
249 else
250 return fast_copy(to, from, n, __copy_to_user_inatomic_asm);
251}
252
253unsigned long __copy_from_user_inatomic(void *to, const void __user *from,
254 unsigned long n)
255{
256 if (n < LARGE_COPY_CUTOFF)
257 return __copy_from_user_inatomic_asm(to, from, n);
258 else
259 return fast_copy(to, from, n, __copy_from_user_inatomic_asm);
260}
261
262unsigned long __copy_from_user_zeroing(void *to, const void __user *from,
263 unsigned long n)
264{
265 if (n < LARGE_COPY_CUTOFF)
266 return __copy_from_user_zeroing_asm(to, from, n);
267 else
268 return fast_copy(to, from, n, __copy_from_user_zeroing_asm);
269}
270
271#endif /* !CHIP_HAS_COHERENT_LOCAL_CACHE() */
diff --git a/arch/tile/lib/memmove_32.c b/arch/tile/lib/memmove_32.c
new file mode 100644
index 000000000000..fd615ae6ade7
--- /dev/null
+++ b/arch/tile/lib/memmove_32.c
@@ -0,0 +1,63 @@
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#include <linux/types.h>
16#include <linux/string.h>
17#include <linux/module.h>
18
19void *memmove(void *dest, const void *src, size_t n)
20{
21 if ((const char *)src >= (char *)dest + n
22 || (char *)dest >= (const char *)src + n) {
23 /* We found no overlap, so let memcpy do all the heavy
24 * lifting (prefetching, etc.)
25 */
26 return memcpy(dest, src, n);
27 }
28
29 if (n != 0) {
30 const uint8_t *in;
31 uint8_t x;
32 uint8_t *out;
33 int stride;
34
35 if (src < dest) {
36 /* copy backwards */
37 in = (const uint8_t *)src + n - 1;
38 out = (uint8_t *)dest + n - 1;
39 stride = -1;
40 } else {
41 /* copy forwards */
42 in = (const uint8_t *)src;
43 out = (uint8_t *)dest;
44 stride = 1;
45 }
46
47 /* Manually software-pipeline this loop. */
48 x = *in;
49 in += stride;
50
51 while (--n != 0) {
52 *out = x;
53 out += stride;
54 x = *in;
55 in += stride;
56 }
57
58 *out = x;
59 }
60
61 return dest;
62}
63EXPORT_SYMBOL(memmove);
diff --git a/arch/tile/lib/memset_32.c b/arch/tile/lib/memset_32.c
new file mode 100644
index 000000000000..d014c1fbcbc2
--- /dev/null
+++ b/arch/tile/lib/memset_32.c
@@ -0,0 +1,250 @@
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#include <arch/chip.h>
16
17#include <linux/types.h>
18#include <linux/string.h>
19#include <linux/module.h>
20
21
22void *memset(void *s, int c, size_t n)
23{
24 uint32_t *out32;
25 int n32;
26 uint32_t v16, v32;
27 uint8_t *out8 = s;
28#if !CHIP_HAS_WH64()
29 int ahead32;
30#else
31 int to_align32;
32#endif
33
34 /* Experimentation shows that a trivial tight loop is a win up until
35 * around a size of 20, where writing a word at a time starts to win.
36 */
37#define BYTE_CUTOFF 20
38
39#if BYTE_CUTOFF < 3
40 /* This must be at least at least this big, or some code later
41 * on doesn't work.
42 */
43#error "BYTE_CUTOFF is too small"
44#endif
45
46 if (n < BYTE_CUTOFF) {
47 /* Strangely, this turns out to be the tightest way to
48 * write this loop.
49 */
50 if (n != 0) {
51 do {
52 /* Strangely, combining these into one line
53 * performs worse.
54 */
55 *out8 = c;
56 out8++;
57 } while (--n != 0);
58 }
59
60 return s;
61 }
62
63#if !CHIP_HAS_WH64()
64 /* Use a spare issue slot to start prefetching the first cache
65 * line early. This instruction is free as the store can be buried
66 * in otherwise idle issue slots doing ALU ops.
67 */
68 __insn_prefetch(out8);
69
70 /* We prefetch the end so that a short memset that spans two cache
71 * lines gets some prefetching benefit. Again we believe this is free
72 * to issue.
73 */
74 __insn_prefetch(&out8[n - 1]);
75#endif /* !CHIP_HAS_WH64() */
76
77
78 /* Align 'out8'. We know n >= 3 so this won't write past the end. */
79 while (((uintptr_t) out8 & 3) != 0) {
80 *out8++ = c;
81 --n;
82 }
83
84 /* Align 'n'. */
85 while (n & 3)
86 out8[--n] = c;
87
88 out32 = (uint32_t *) out8;
89 n32 = n >> 2;
90
91 /* Tile input byte out to 32 bits. */
92 v16 = __insn_intlb(c, c);
93 v32 = __insn_intlh(v16, v16);
94
95 /* This must be at least 8 or the following loop doesn't work. */
96#define CACHE_LINE_SIZE_IN_WORDS (CHIP_L2_LINE_SIZE() / 4)
97
98#if !CHIP_HAS_WH64()
99
100 ahead32 = CACHE_LINE_SIZE_IN_WORDS;
101
102 /* We already prefetched the first and last cache lines, so
103 * we only need to do more prefetching if we are storing
104 * to more than two cache lines.
105 */
106 if (n32 > CACHE_LINE_SIZE_IN_WORDS * 2) {
107 int i;
108
109 /* Prefetch the next several cache lines.
110 * This is the setup code for the software-pipelined
111 * loop below.
112 */
113#define MAX_PREFETCH 5
114 ahead32 = n32 & -CACHE_LINE_SIZE_IN_WORDS;
115 if (ahead32 > MAX_PREFETCH * CACHE_LINE_SIZE_IN_WORDS)
116 ahead32 = MAX_PREFETCH * CACHE_LINE_SIZE_IN_WORDS;
117
118 for (i = CACHE_LINE_SIZE_IN_WORDS;
119 i < ahead32; i += CACHE_LINE_SIZE_IN_WORDS)
120 __insn_prefetch(&out32[i]);
121 }
122
123 if (n32 > ahead32) {
124 while (1) {
125 int j;
126
127 /* Prefetch by reading one word several cache lines
128 * ahead. Since loads are non-blocking this will
129 * cause the full cache line to be read while we are
130 * finishing earlier cache lines. Using a store
131 * here causes microarchitectural performance
132 * problems where a victimizing store miss goes to
133 * the head of the retry FIFO and locks the pipe for
134 * a few cycles. So a few subsequent stores in this
135 * loop go into the retry FIFO, and then later
136 * stores see other stores to the same cache line
137 * are already in the retry FIFO and themselves go
138 * into the retry FIFO, filling it up and grinding
139 * to a halt waiting for the original miss to be
140 * satisfied.
141 */
142 __insn_prefetch(&out32[ahead32]);
143
144#if CACHE_LINE_SIZE_IN_WORDS % 4 != 0
145#error "Unhandled CACHE_LINE_SIZE_IN_WORDS"
146#endif
147
148 n32 -= CACHE_LINE_SIZE_IN_WORDS;
149
150 /* Save icache space by only partially unrolling
151 * this loop.
152 */
153 for (j = CACHE_LINE_SIZE_IN_WORDS / 4; j > 0; j--) {
154 *out32++ = v32;
155 *out32++ = v32;
156 *out32++ = v32;
157 *out32++ = v32;
158 }
159
160 /* To save compiled code size, reuse this loop even
161 * when we run out of prefetching to do by dropping
162 * ahead32 down.
163 */
164 if (n32 <= ahead32) {
165 /* Not even a full cache line left,
166 * so stop now.
167 */
168 if (n32 < CACHE_LINE_SIZE_IN_WORDS)
169 break;
170
171 /* Choose a small enough value that we don't
172 * prefetch past the end. There's no sense
173 * in touching cache lines we don't have to.
174 */
175 ahead32 = CACHE_LINE_SIZE_IN_WORDS - 1;
176 }
177 }
178 }
179
180#else /* CHIP_HAS_WH64() */
181
182 /* Determine how many words we need to emit before the 'out32'
183 * pointer becomes aligned modulo the cache line size.
184 */
185 to_align32 =
186 (-((uintptr_t)out32 >> 2)) & (CACHE_LINE_SIZE_IN_WORDS - 1);
187
188 /* Only bother aligning and using wh64 if there is at least
189 * one full cache line to process. This check also prevents
190 * overrunning the end of the buffer with alignment words.
191 */
192 if (to_align32 <= n32 - CACHE_LINE_SIZE_IN_WORDS) {
193 int lines_left;
194
195 /* Align out32 mod the cache line size so we can use wh64. */
196 n32 -= to_align32;
197 for (; to_align32 != 0; to_align32--) {
198 *out32 = v32;
199 out32++;
200 }
201
202 /* Use unsigned divide to turn this into a right shift. */
203 lines_left = (unsigned)n32 / CACHE_LINE_SIZE_IN_WORDS;
204
205 do {
206 /* Only wh64 a few lines at a time, so we don't
207 * exceed the maximum number of victim lines.
208 */
209 int x = ((lines_left < CHIP_MAX_OUTSTANDING_VICTIMS())
210 ? lines_left
211 : CHIP_MAX_OUTSTANDING_VICTIMS());
212 uint32_t *wh = out32;
213 int i = x;
214 int j;
215
216 lines_left -= x;
217
218 do {
219 __insn_wh64(wh);
220 wh += CACHE_LINE_SIZE_IN_WORDS;
221 } while (--i);
222
223 for (j = x * (CACHE_LINE_SIZE_IN_WORDS / 4);
224 j != 0; j--) {
225 *out32++ = v32;
226 *out32++ = v32;
227 *out32++ = v32;
228 *out32++ = v32;
229 }
230 } while (lines_left != 0);
231
232 /* We processed all full lines above, so only this many
233 * words remain to be processed.
234 */
235 n32 &= CACHE_LINE_SIZE_IN_WORDS - 1;
236 }
237
238#endif /* CHIP_HAS_WH64() */
239
240 /* Now handle any leftover values. */
241 if (n32 != 0) {
242 do {
243 *out32 = v32;
244 out32++;
245 } while (--n32 != 0);
246 }
247
248 return s;
249}
250EXPORT_SYMBOL(memset);
diff --git a/arch/tile/lib/spinlock_32.c b/arch/tile/lib/spinlock_32.c
new file mode 100644
index 000000000000..485e24d62c6b
--- /dev/null
+++ b/arch/tile/lib/spinlock_32.c
@@ -0,0 +1,221 @@
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#include <linux/spinlock.h>
16#include <linux/module.h>
17#include <asm/processor.h>
18
19#include "spinlock_common.h"
20
21void arch_spin_lock(arch_spinlock_t *lock)
22{
23 int my_ticket;
24 int iterations = 0;
25 int delta;
26
27 while ((my_ticket = __insn_tns((void *)&lock->next_ticket)) & 1)
28 delay_backoff(iterations++);
29
30 /* Increment the next ticket number, implicitly releasing tns lock. */
31 lock->next_ticket = my_ticket + TICKET_QUANTUM;
32
33 /* Wait until it's our turn. */
34 while ((delta = my_ticket - lock->current_ticket) != 0)
35 relax((128 / CYCLES_PER_RELAX_LOOP) * delta);
36}
37EXPORT_SYMBOL(arch_spin_lock);
38
39int arch_spin_trylock(arch_spinlock_t *lock)
40{
41 /*
42 * Grab a ticket; no need to retry if it's busy, we'll just
43 * treat that the same as "locked", since someone else
44 * will lock it momentarily anyway.
45 */
46 int my_ticket = __insn_tns((void *)&lock->next_ticket);
47
48 if (my_ticket == lock->current_ticket) {
49 /* Not currently locked, so lock it by keeping this ticket. */
50 lock->next_ticket = my_ticket + TICKET_QUANTUM;
51 /* Success! */
52 return 1;
53 }
54
55 if (!(my_ticket & 1)) {
56 /* Release next_ticket. */
57 lock->next_ticket = my_ticket;
58 }
59
60 return 0;
61}
62EXPORT_SYMBOL(arch_spin_trylock);
63
64void arch_spin_unlock_wait(arch_spinlock_t *lock)
65{
66 u32 iterations = 0;
67 while (arch_spin_is_locked(lock))
68 delay_backoff(iterations++);
69}
70EXPORT_SYMBOL(arch_spin_unlock_wait);
71
72/*
73 * The low byte is always reserved to be the marker for a "tns" operation
74 * since the low bit is set to "1" by a tns. The next seven bits are
75 * zeroes. The next byte holds the "next" writer value, i.e. the ticket
76 * available for the next task that wants to write. The third byte holds
77 * the current writer value, i.e. the writer who holds the current ticket.
78 * If current == next == 0, there are no interested writers.
79 */
80#define WR_NEXT_SHIFT _WR_NEXT_SHIFT
81#define WR_CURR_SHIFT _WR_CURR_SHIFT
82#define WR_WIDTH _WR_WIDTH
83#define WR_MASK ((1 << WR_WIDTH) - 1)
84
85/*
86 * The last eight bits hold the active reader count. This has to be
87 * zero before a writer can start to write.
88 */
89#define RD_COUNT_SHIFT _RD_COUNT_SHIFT
90#define RD_COUNT_WIDTH _RD_COUNT_WIDTH
91#define RD_COUNT_MASK ((1 << RD_COUNT_WIDTH) - 1)
92
93
94/* Lock the word, spinning until there are no tns-ers. */
95static inline u32 get_rwlock(arch_rwlock_t *rwlock)
96{
97 u32 iterations = 0;
98 for (;;) {
99 u32 val = __insn_tns((int *)&rwlock->lock);
100 if (unlikely(val & 1)) {
101 delay_backoff(iterations++);
102 continue;
103 }
104 return val;
105 }
106}
107
108int arch_read_trylock_slow(arch_rwlock_t *rwlock)
109{
110 u32 val = get_rwlock(rwlock);
111 int locked = (val << RD_COUNT_WIDTH) == 0;
112 rwlock->lock = val + (locked << RD_COUNT_SHIFT);
113 return locked;
114}
115EXPORT_SYMBOL(arch_read_trylock_slow);
116
117void arch_read_unlock_slow(arch_rwlock_t *rwlock)
118{
119 u32 val = get_rwlock(rwlock);
120 rwlock->lock = val - (1 << RD_COUNT_SHIFT);
121}
122EXPORT_SYMBOL(arch_read_unlock_slow);
123
124void arch_write_unlock_slow(arch_rwlock_t *rwlock, u32 val)
125{
126 u32 eq, mask = 1 << WR_CURR_SHIFT;
127 while (unlikely(val & 1)) {
128 /* Limited backoff since we are the highest-priority task. */
129 relax(4);
130 val = __insn_tns((int *)&rwlock->lock);
131 }
132 val = __insn_addb(val, mask);
133 eq = __insn_seqb(val, val << (WR_CURR_SHIFT - WR_NEXT_SHIFT));
134 val = __insn_mz(eq & mask, val);
135 rwlock->lock = val;
136}
137EXPORT_SYMBOL(arch_write_unlock_slow);
138
139/*
140 * We spin until everything but the reader bits (which are in the high
141 * part of the word) are zero, i.e. no active or waiting writers, no tns.
142 *
143 * ISSUE: This approach can permanently starve readers. A reader who sees
144 * a writer could instead take a ticket lock (just like a writer would),
145 * and atomically enter read mode (with 1 reader) when it gets the ticket.
146 * This way both readers and writers will always make forward progress
147 * in a finite time.
148 */
149void arch_read_lock_slow(arch_rwlock_t *rwlock, u32 val)
150{
151 u32 iterations = 0;
152 do {
153 if (!(val & 1))
154 rwlock->lock = val;
155 delay_backoff(iterations++);
156 val = __insn_tns((int *)&rwlock->lock);
157 } while ((val << RD_COUNT_WIDTH) != 0);
158 rwlock->lock = val + (1 << RD_COUNT_SHIFT);
159}
160EXPORT_SYMBOL(arch_read_lock_slow);
161
162void arch_write_lock_slow(arch_rwlock_t *rwlock, u32 val)
163{
164 /*
165 * The trailing underscore on this variable (and curr_ below)
166 * reminds us that the high bits are garbage; we mask them out
167 * when we compare them.
168 */
169 u32 my_ticket_;
170
171 /* Take out the next ticket; this will also stop would-be readers. */
172 if (val & 1)
173 val = get_rwlock(rwlock);
174 rwlock->lock = __insn_addb(val, 1 << WR_NEXT_SHIFT);
175
176 /* Extract my ticket value from the original word. */
177 my_ticket_ = val >> WR_NEXT_SHIFT;
178
179 /*
180 * Wait until the "current" field matches our ticket, and
181 * there are no remaining readers.
182 */
183 for (;;) {
184 u32 curr_ = val >> WR_CURR_SHIFT;
185 u32 readers = val >> RD_COUNT_SHIFT;
186 u32 delta = ((my_ticket_ - curr_) & WR_MASK) + !!readers;
187 if (likely(delta == 0))
188 break;
189
190 /* Delay based on how many lock-holders are still out there. */
191 relax((256 / CYCLES_PER_RELAX_LOOP) * delta);
192
193 /*
194 * Get a non-tns value to check; we don't need to tns
195 * it ourselves. Since we're not tns'ing, we retry
196 * more rapidly to get a valid value.
197 */
198 while ((val = rwlock->lock) & 1)
199 relax(4);
200 }
201}
202EXPORT_SYMBOL(arch_write_lock_slow);
203
204int __tns_atomic_acquire(atomic_t *lock)
205{
206 int ret;
207 u32 iterations = 0;
208
209 BUG_ON(__insn_mfspr(SPR_INTERRUPT_CRITICAL_SECTION));
210 __insn_mtspr(SPR_INTERRUPT_CRITICAL_SECTION, 1);
211
212 while ((ret = __insn_tns((void *)&lock->counter)) == 1)
213 delay_backoff(iterations++);
214 return ret;
215}
216
217void __tns_atomic_release(atomic_t *p, int v)
218{
219 p->counter = v;
220 __insn_mtspr(SPR_INTERRUPT_CRITICAL_SECTION, 0);
221}
diff --git a/arch/tile/lib/spinlock_common.h b/arch/tile/lib/spinlock_common.h
new file mode 100644
index 000000000000..c10109809132
--- /dev/null
+++ b/arch/tile/lib/spinlock_common.h
@@ -0,0 +1,64 @@
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 * This file is included into spinlock_32.c or _64.c.
14 */
15
16/*
17 * The mfspr in __spinlock_relax() is 5 or 6 cycles plus 2 for loop
18 * overhead.
19 */
20#ifdef __tilegx__
21#define CYCLES_PER_RELAX_LOOP 7
22#else
23#define CYCLES_PER_RELAX_LOOP 8
24#endif
25
26/*
27 * Idle the core for CYCLES_PER_RELAX_LOOP * iterations cycles.
28 */
29static inline void
30relax(int iterations)
31{
32 for (/*above*/; iterations > 0; iterations--)
33 __insn_mfspr(SPR_PASS);
34 barrier();
35}
36
37/* Perform bounded exponential backoff.*/
38static void delay_backoff(int iterations)
39{
40 u32 exponent, loops;
41
42 /*
43 * 2^exponent is how many times we go around the loop,
44 * which takes 8 cycles. We want to start with a 16- to 31-cycle
45 * loop, so we need to go around minimum 2 = 2^1 times, so we
46 * bias the original value up by 1.
47 */
48 exponent = iterations + 1;
49
50 /*
51 * Don't allow exponent to exceed 7, so we have 128 loops,
52 * or 1,024 (to 2,047) cycles, as our maximum.
53 */
54 if (exponent > 8)
55 exponent = 8;
56
57 loops = 1 << exponent;
58
59 /* Add a randomness factor so two cpus never get in lock step. */
60 loops += __insn_crc32_32(stack_pointer, get_cycles_low()) &
61 (loops - 1);
62
63 relax(1 << exponent);
64}
diff --git a/arch/tile/lib/strchr_32.c b/arch/tile/lib/strchr_32.c
new file mode 100644
index 000000000000..c94e6f7ae7b5
--- /dev/null
+++ b/arch/tile/lib/strchr_32.c
@@ -0,0 +1,66 @@
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#include <linux/types.h>
16#include <linux/string.h>
17#include <linux/module.h>
18
19#undef strchr
20
21char *strchr(const char *s, int c)
22{
23 int z, g;
24
25 /* Get an aligned pointer. */
26 const uintptr_t s_int = (uintptr_t) s;
27 const uint32_t *p = (const uint32_t *)(s_int & -4);
28
29 /* Create four copies of the byte for which we are looking. */
30 const uint32_t goal = 0x01010101 * (uint8_t) c;
31
32 /* Read the first aligned word, but force bytes before the string to
33 * match neither zero nor goal (we make sure the high bit of each
34 * byte is 1, and the low 7 bits are all the opposite of the goal
35 * byte).
36 *
37 * Note that this shift count expression works because we know shift
38 * counts are taken mod 32.
39 */
40 const uint32_t before_mask = (1 << (s_int << 3)) - 1;
41 uint32_t v = (*p | before_mask) ^ (goal & __insn_shrib(before_mask, 1));
42
43 uint32_t zero_matches, goal_matches;
44 while (1) {
45 /* Look for a terminating '\0'. */
46 zero_matches = __insn_seqb(v, 0);
47
48 /* Look for the goal byte. */
49 goal_matches = __insn_seqb(v, goal);
50
51 if (__builtin_expect(zero_matches | goal_matches, 0))
52 break;
53
54 v = *++p;
55 }
56
57 z = __insn_ctz(zero_matches);
58 g = __insn_ctz(goal_matches);
59
60 /* If we found c before '\0' we got a match. Note that if c == '\0'
61 * then g == z, and we correctly return the address of the '\0'
62 * rather than NULL.
63 */
64 return (g <= z) ? ((char *)p) + (g >> 3) : NULL;
65}
66EXPORT_SYMBOL(strchr);
diff --git a/arch/tile/lib/strlen_32.c b/arch/tile/lib/strlen_32.c
new file mode 100644
index 000000000000..f26f88e11e4a
--- /dev/null
+++ b/arch/tile/lib/strlen_32.c
@@ -0,0 +1,36 @@
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#include <linux/types.h>
16#include <linux/string.h>
17#include <linux/module.h>
18
19size_t strlen(const char *s)
20{
21 /* Get an aligned pointer. */
22 const uintptr_t s_int = (uintptr_t) s;
23 const uint32_t *p = (const uint32_t *)(s_int & -4);
24
25 /* Read the first word, but force bytes before the string to be nonzero.
26 * This expression works because we know shift counts are taken mod 32.
27 */
28 uint32_t v = *p | ((1 << (s_int << 3)) - 1);
29
30 uint32_t bits;
31 while ((bits = __insn_seqb(v, 0)) == 0)
32 v = *++p;
33
34 return ((const char *)p) + (__insn_ctz(bits) >> 3) - s;
35}
36EXPORT_SYMBOL(strlen);
diff --git a/arch/tile/lib/uaccess.c b/arch/tile/lib/uaccess.c
new file mode 100644
index 000000000000..f8d398c9ee7f
--- /dev/null
+++ b/arch/tile/lib/uaccess.c
@@ -0,0 +1,32 @@
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#include <linux/uaccess.h>
16#include <linux/module.h>
17
18int __range_ok(unsigned long addr, unsigned long size)
19{
20 unsigned long limit = current_thread_info()->addr_limit.seg;
21 return !((addr < limit && size <= limit - addr) ||
22 is_arch_mappable_range(addr, size));
23}
24EXPORT_SYMBOL(__range_ok);
25
26#ifdef CONFIG_DEBUG_COPY_FROM_USER
27void copy_from_user_overflow(void)
28{
29 WARN(1, "Buffer overflow detected!\n");
30}
31EXPORT_SYMBOL(copy_from_user_overflow);
32#endif
diff --git a/arch/tile/lib/usercopy_32.S b/arch/tile/lib/usercopy_32.S
new file mode 100644
index 000000000000..979f76d83746
--- /dev/null
+++ b/arch/tile/lib/usercopy_32.S
@@ -0,0 +1,223 @@
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#include <linux/linkage.h>
16#include <asm/errno.h>
17#include <asm/cache.h>
18#include <arch/chip.h>
19
20/* Access user memory, but use MMU to avoid propagating kernel exceptions. */
21
22 .pushsection .fixup,"ax"
23
24get_user_fault:
25 { move r0, zero; move r1, zero }
26 { movei r2, -EFAULT; jrp lr }
27 ENDPROC(get_user_fault)
28
29put_user_fault:
30 { movei r0, -EFAULT; jrp lr }
31 ENDPROC(put_user_fault)
32
33 .popsection
34
35/*
36 * __get_user_N functions take a pointer in r0, and return 0 in r2
37 * on success, with the value in r0; or else -EFAULT in r2.
38 */
39#define __get_user_N(bytes, LOAD) \
40 STD_ENTRY(__get_user_##bytes); \
411: { LOAD r0, r0; move r1, zero; move r2, zero }; \
42 jrp lr; \
43 STD_ENDPROC(__get_user_##bytes); \
44 .pushsection __ex_table,"a"; \
45 .word 1b, get_user_fault; \
46 .popsection
47
48__get_user_N(1, lb_u)
49__get_user_N(2, lh_u)
50__get_user_N(4, lw)
51
52/*
53 * __get_user_8 takes a pointer in r0, and returns 0 in r2
54 * on success, with the value in r0/r1; or else -EFAULT in r2.
55 */
56 STD_ENTRY(__get_user_8);
571: { lw r0, r0; addi r1, r0, 4 };
582: { lw r1, r1; move r2, zero };
59 jrp lr;
60 STD_ENDPROC(__get_user_8);
61 .pushsection __ex_table,"a";
62 .word 1b, get_user_fault;
63 .word 2b, get_user_fault;
64 .popsection
65
66/*
67 * __put_user_N functions take a value in r0 and a pointer in r1,
68 * and return 0 in r0 on success or -EFAULT on failure.
69 */
70#define __put_user_N(bytes, STORE) \
71 STD_ENTRY(__put_user_##bytes); \
721: { STORE r1, r0; move r0, zero }; \
73 jrp lr; \
74 STD_ENDPROC(__put_user_##bytes); \
75 .pushsection __ex_table,"a"; \
76 .word 1b, put_user_fault; \
77 .popsection
78
79__put_user_N(1, sb)
80__put_user_N(2, sh)
81__put_user_N(4, sw)
82
83/*
84 * __put_user_8 takes a value in r0/r1 and a pointer in r2,
85 * and returns 0 in r0 on success or -EFAULT on failure.
86 */
87STD_ENTRY(__put_user_8)
881: { sw r2, r0; addi r2, r2, 4 }
892: { sw r2, r1; move r0, zero }
90 jrp lr
91 STD_ENDPROC(__put_user_8)
92 .pushsection __ex_table,"a"
93 .word 1b, put_user_fault
94 .word 2b, put_user_fault
95 .popsection
96
97
98/*
99 * strnlen_user_asm takes the pointer in r0, and the length bound in r1.
100 * It returns the length, including the terminating NUL, or zero on exception.
101 * If length is greater than the bound, returns one plus the bound.
102 */
103STD_ENTRY(strnlen_user_asm)
104 { bz r1, 2f; addi r3, r0, -1 } /* bias down to include NUL */
1051: { lb_u r4, r0; addi r1, r1, -1 }
106 bz r4, 2f
107 { bnzt r1, 1b; addi r0, r0, 1 }
1082: { sub r0, r0, r3; jrp lr }
109 STD_ENDPROC(strnlen_user_asm)
110 .pushsection .fixup,"ax"
111strnlen_user_fault:
112 { move r0, zero; jrp lr }
113 ENDPROC(strnlen_user_fault)
114 .section __ex_table,"a"
115 .word 1b, strnlen_user_fault
116 .popsection
117
118/*
119 * strncpy_from_user_asm takes the kernel target pointer in r0,
120 * the userspace source pointer in r1, and the length bound (including
121 * the trailing NUL) in r2. On success, it returns the string length
122 * (not including the trailing NUL), or -EFAULT on failure.
123 */
124STD_ENTRY(strncpy_from_user_asm)
125 { bz r2, 2f; move r3, r0 }
1261: { lb_u r4, r1; addi r1, r1, 1; addi r2, r2, -1 }
127 { sb r0, r4; addi r0, r0, 1 }
128 bz r2, 2f
129 bnzt r4, 1b
130 addi r0, r0, -1 /* don't count the trailing NUL */
1312: { sub r0, r0, r3; jrp lr }
132 STD_ENDPROC(strncpy_from_user_asm)
133 .pushsection .fixup,"ax"
134strncpy_from_user_fault:
135 { movei r0, -EFAULT; jrp lr }
136 ENDPROC(strncpy_from_user_fault)
137 .section __ex_table,"a"
138 .word 1b, strncpy_from_user_fault
139 .popsection
140
141/*
142 * clear_user_asm takes the user target address in r0 and the
143 * number of bytes to zero in r1.
144 * It returns the number of uncopiable bytes (hopefully zero) in r0.
145 * Note that we don't use a separate .fixup section here since we fall
146 * through into the "fixup" code as the last straight-line bundle anyway.
147 */
148STD_ENTRY(clear_user_asm)
149 { bz r1, 2f; or r2, r0, r1 }
150 andi r2, r2, 3
151 bzt r2, .Lclear_aligned_user_asm
1521: { sb r0, zero; addi r0, r0, 1; addi r1, r1, -1 }
153 bnzt r1, 1b
1542: { move r0, r1; jrp lr }
155 .pushsection __ex_table,"a"
156 .word 1b, 2b
157 .popsection
158
159.Lclear_aligned_user_asm:
1601: { sw r0, zero; addi r0, r0, 4; addi r1, r1, -4 }
161 bnzt r1, 1b
1622: { move r0, r1; jrp lr }
163 STD_ENDPROC(clear_user_asm)
164 .pushsection __ex_table,"a"
165 .word 1b, 2b
166 .popsection
167
168/*
169 * flush_user_asm takes the user target address in r0 and the
170 * number of bytes to flush in r1.
171 * It returns the number of unflushable bytes (hopefully zero) in r0.
172 */
173STD_ENTRY(flush_user_asm)
174 bz r1, 2f
175 { movei r2, L2_CACHE_BYTES; add r1, r0, r1 }
176 { sub r2, zero, r2; addi r1, r1, L2_CACHE_BYTES-1 }
177 { and r0, r0, r2; and r1, r1, r2 }
178 { sub r1, r1, r0 }
1791: { flush r0; addi r1, r1, -CHIP_FLUSH_STRIDE() }
180 { addi r0, r0, CHIP_FLUSH_STRIDE(); bnzt r1, 1b }
1812: { move r0, r1; jrp lr }
182 STD_ENDPROC(flush_user_asm)
183 .pushsection __ex_table,"a"
184 .word 1b, 2b
185 .popsection
186
187/*
188 * inv_user_asm takes the user target address in r0 and the
189 * number of bytes to invalidate in r1.
190 * It returns the number of not inv'able bytes (hopefully zero) in r0.
191 */
192STD_ENTRY(inv_user_asm)
193 bz r1, 2f
194 { movei r2, L2_CACHE_BYTES; add r1, r0, r1 }
195 { sub r2, zero, r2; addi r1, r1, L2_CACHE_BYTES-1 }
196 { and r0, r0, r2; and r1, r1, r2 }
197 { sub r1, r1, r0 }
1981: { inv r0; addi r1, r1, -CHIP_INV_STRIDE() }
199 { addi r0, r0, CHIP_INV_STRIDE(); bnzt r1, 1b }
2002: { move r0, r1; jrp lr }
201 STD_ENDPROC(inv_user_asm)
202 .pushsection __ex_table,"a"
203 .word 1b, 2b
204 .popsection
205
206/*
207 * finv_user_asm takes the user target address in r0 and the
208 * number of bytes to flush-invalidate in r1.
209 * It returns the number of not finv'able bytes (hopefully zero) in r0.
210 */
211STD_ENTRY(finv_user_asm)
212 bz r1, 2f
213 { movei r2, L2_CACHE_BYTES; add r1, r0, r1 }
214 { sub r2, zero, r2; addi r1, r1, L2_CACHE_BYTES-1 }
215 { and r0, r0, r2; and r1, r1, r2 }
216 { sub r1, r1, r0 }
2171: { finv r0; addi r1, r1, -CHIP_FINV_STRIDE() }
218 { addi r0, r0, CHIP_FINV_STRIDE(); bnzt r1, 1b }
2192: { move r0, r1; jrp lr }
220 STD_ENDPROC(finv_user_asm)
221 .pushsection __ex_table,"a"
222 .word 1b, 2b
223 .popsection
diff --git a/arch/tile/mm/Makefile b/arch/tile/mm/Makefile
new file mode 100644
index 000000000000..e252aeddc17d
--- /dev/null
+++ b/arch/tile/mm/Makefile
@@ -0,0 +1,9 @@
1#
2# Makefile for the linux tile-specific parts of the memory manager.
3#
4
5obj-y := init.o pgtable.o fault.o extable.o elf.o \
6 mmap.o homecache.o migrate_$(BITS).o
7
8obj-$(CONFIG_HUGETLB_PAGE) += hugetlbpage.o
9obj-$(CONFIG_HIGHMEM) += highmem.o
diff --git a/arch/tile/mm/elf.c b/arch/tile/mm/elf.c
new file mode 100644
index 000000000000..55e58e93bfc5
--- /dev/null
+++ b/arch/tile/mm/elf.c
@@ -0,0 +1,164 @@
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#include <linux/mm.h>
16#include <linux/pagemap.h>
17#include <linux/binfmts.h>
18#include <linux/compat.h>
19#include <linux/mman.h>
20#include <linux/elf.h>
21#include <asm/pgtable.h>
22#include <asm/pgalloc.h>
23#include <asm/sections.h>
24
25/* Notify a running simulator, if any, that an exec just occurred. */
26static void sim_notify_exec(const char *binary_name)
27{
28 unsigned char c;
29 do {
30 c = *binary_name++;
31 __insn_mtspr(SPR_SIM_CONTROL,
32 (SIM_CONTROL_OS_EXEC
33 | (c << _SIM_CONTROL_OPERATOR_BITS)));
34
35 } while (c);
36}
37
38static int notify_exec(void)
39{
40 int retval = 0; /* failure */
41 struct vm_area_struct *vma = current->mm->mmap;
42 while (vma) {
43 if ((vma->vm_flags & VM_EXECUTABLE) && vma->vm_file)
44 break;
45 vma = vma->vm_next;
46 }
47 if (vma) {
48 char *buf = (char *) __get_free_page(GFP_KERNEL);
49 if (buf) {
50 char *path = d_path(&vma->vm_file->f_path,
51 buf, PAGE_SIZE);
52 if (!IS_ERR(path)) {
53 sim_notify_exec(path);
54 retval = 1;
55 }
56 free_page((unsigned long)buf);
57 }
58 }
59 return retval;
60}
61
62/* Notify a running simulator, if any, that we loaded an interpreter. */
63static void sim_notify_interp(unsigned long load_addr)
64{
65 size_t i;
66 for (i = 0; i < sizeof(load_addr); i++) {
67 unsigned char c = load_addr >> (i * 8);
68 __insn_mtspr(SPR_SIM_CONTROL,
69 (SIM_CONTROL_OS_INTERP
70 | (c << _SIM_CONTROL_OPERATOR_BITS)));
71 }
72}
73
74
75/* Kernel address of page used to map read-only kernel data into userspace. */
76static void *vdso_page;
77
78/* One-entry array used for install_special_mapping. */
79static struct page *vdso_pages[1];
80
81static int __init vdso_setup(void)
82{
83 vdso_page = (void *)get_zeroed_page(GFP_ATOMIC);
84 memcpy(vdso_page, __rt_sigreturn, __rt_sigreturn_end - __rt_sigreturn);
85 vdso_pages[0] = virt_to_page(vdso_page);
86 return 0;
87}
88device_initcall(vdso_setup);
89
90const char *arch_vma_name(struct vm_area_struct *vma)
91{
92 if (vma->vm_private_data == vdso_pages)
93 return "[vdso]";
94#ifndef __tilegx__
95 if (vma->vm_start == MEM_USER_INTRPT)
96 return "[intrpt]";
97#endif
98 return NULL;
99}
100
101int arch_setup_additional_pages(struct linux_binprm *bprm,
102 int executable_stack)
103{
104 struct mm_struct *mm = current->mm;
105 unsigned long vdso_base;
106 int retval = 0;
107
108 /*
109 * Notify the simulator that an exec just occurred.
110 * If we can't find the filename of the mapping, just use
111 * whatever was passed as the linux_binprm filename.
112 */
113 if (!notify_exec())
114 sim_notify_exec(bprm->filename);
115
116 down_write(&mm->mmap_sem);
117
118 /*
119 * MAYWRITE to allow gdb to COW and set breakpoints
120 *
121 * Make sure the vDSO gets into every core dump. Dumping its
122 * contents makes post-mortem fully interpretable later
123 * without matching up the same kernel and hardware config to
124 * see what PC values meant.
125 */
126 vdso_base = VDSO_BASE;
127 retval = install_special_mapping(mm, vdso_base, PAGE_SIZE,
128 VM_READ|VM_EXEC|
129 VM_MAYREAD|VM_MAYWRITE|VM_MAYEXEC|
130 VM_ALWAYSDUMP,
131 vdso_pages);
132
133#ifndef __tilegx__
134 /*
135 * Set up a user-interrupt mapping here; the user can't
136 * create one themselves since it is above TASK_SIZE.
137 * We make it unwritable by default, so the model for adding
138 * interrupt vectors always involves an mprotect.
139 */
140 if (!retval) {
141 unsigned long addr = MEM_USER_INTRPT;
142 addr = mmap_region(NULL, addr, INTRPT_SIZE,
143 MAP_FIXED|MAP_ANONYMOUS|MAP_PRIVATE,
144 VM_READ|VM_EXEC|
145 VM_MAYREAD|VM_MAYWRITE|VM_MAYEXEC, 0);
146 if (addr > (unsigned long) -PAGE_SIZE)
147 retval = (int) addr;
148 }
149#endif
150
151 up_write(&mm->mmap_sem);
152
153 return retval;
154}
155
156
157void elf_plat_init(struct pt_regs *regs, unsigned long load_addr)
158{
159 /* Zero all registers. */
160 memset(regs, 0, sizeof(*regs));
161
162 /* Report the interpreter's load address. */
163 sim_notify_interp(load_addr);
164}
diff --git a/arch/tile/mm/extable.c b/arch/tile/mm/extable.c
new file mode 100644
index 000000000000..4fb0acb9d154
--- /dev/null
+++ b/arch/tile/mm/extable.c
@@ -0,0 +1,30 @@
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#include <linux/module.h>
16#include <linux/spinlock.h>
17#include <linux/uaccess.h>
18
19int fixup_exception(struct pt_regs *regs)
20{
21 const struct exception_table_entry *fixup;
22
23 fixup = search_exception_tables(regs->pc);
24 if (fixup) {
25 regs->pc = fixup->fixup;
26 return 1;
27 }
28
29 return 0;
30}
diff --git a/arch/tile/mm/fault.c b/arch/tile/mm/fault.c
new file mode 100644
index 000000000000..704f3e8a4385
--- /dev/null
+++ b/arch/tile/mm/fault.c
@@ -0,0 +1,875 @@
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 * From i386 code copyright (C) 1995 Linus Torvalds
15 */
16
17#include <linux/signal.h>
18#include <linux/sched.h>
19#include <linux/kernel.h>
20#include <linux/errno.h>
21#include <linux/string.h>
22#include <linux/types.h>
23#include <linux/ptrace.h>
24#include <linux/mman.h>
25#include <linux/mm.h>
26#include <linux/smp.h>
27#include <linux/smp_lock.h>
28#include <linux/interrupt.h>
29#include <linux/init.h>
30#include <linux/tty.h>
31#include <linux/vt_kern.h> /* For unblank_screen() */
32#include <linux/highmem.h>
33#include <linux/module.h>
34#include <linux/kprobes.h>
35#include <linux/hugetlb.h>
36#include <linux/syscalls.h>
37#include <linux/uaccess.h>
38
39#include <asm/system.h>
40#include <asm/pgalloc.h>
41#include <asm/sections.h>
42#include <asm/traps.h>
43#include <asm/syscalls.h>
44
45#include <arch/interrupts.h>
46
47static noinline void force_sig_info_fault(int si_signo, int si_code,
48 unsigned long address, int fault_num, struct task_struct *tsk)
49{
50 siginfo_t info;
51
52 if (unlikely(tsk->pid < 2)) {
53 panic("Signal %d (code %d) at %#lx sent to %s!",
54 si_signo, si_code & 0xffff, address,
55 tsk->pid ? "init" : "the idle task");
56 }
57
58 info.si_signo = si_signo;
59 info.si_errno = 0;
60 info.si_code = si_code;
61 info.si_addr = (void __user *)address;
62 info.si_trapno = fault_num;
63 force_sig_info(si_signo, &info, tsk);
64}
65
66#ifndef __tilegx__
67/*
68 * Synthesize the fault a PL0 process would get by doing a word-load of
69 * an unaligned address or a high kernel address. Called indirectly
70 * from sys_cmpxchg() in kernel/intvec.S.
71 */
72int _sys_cmpxchg_badaddr(unsigned long address, struct pt_regs *regs)
73{
74 if (address >= PAGE_OFFSET)
75 force_sig_info_fault(SIGSEGV, SEGV_MAPERR, address,
76 INT_DTLB_MISS, current);
77 else
78 force_sig_info_fault(SIGBUS, BUS_ADRALN, address,
79 INT_UNALIGN_DATA, current);
80
81 /*
82 * Adjust pc to point at the actual instruction, which is unusual
83 * for syscalls normally, but is appropriate when we are claiming
84 * that a syscall swint1 caused a page fault or bus error.
85 */
86 regs->pc -= 8;
87
88 /*
89 * Mark this as a caller-save interrupt, like a normal page fault,
90 * so that when we go through the signal handler path we will
91 * properly restore r0, r1, and r2 for the signal handler arguments.
92 */
93 regs->flags |= PT_FLAGS_CALLER_SAVES;
94
95 return 0;
96}
97#endif
98
99static inline pmd_t *vmalloc_sync_one(pgd_t *pgd, unsigned long address)
100{
101 unsigned index = pgd_index(address);
102 pgd_t *pgd_k;
103 pud_t *pud, *pud_k;
104 pmd_t *pmd, *pmd_k;
105
106 pgd += index;
107 pgd_k = init_mm.pgd + index;
108
109 if (!pgd_present(*pgd_k))
110 return NULL;
111
112 pud = pud_offset(pgd, address);
113 pud_k = pud_offset(pgd_k, address);
114 if (!pud_present(*pud_k))
115 return NULL;
116
117 pmd = pmd_offset(pud, address);
118 pmd_k = pmd_offset(pud_k, address);
119 if (!pmd_present(*pmd_k))
120 return NULL;
121 if (!pmd_present(*pmd)) {
122 set_pmd(pmd, *pmd_k);
123 arch_flush_lazy_mmu_mode();
124 } else
125 BUG_ON(pmd_ptfn(*pmd) != pmd_ptfn(*pmd_k));
126 return pmd_k;
127}
128
129/*
130 * Handle a fault on the vmalloc or module mapping area
131 */
132static inline int vmalloc_fault(pgd_t *pgd, unsigned long address)
133{
134 pmd_t *pmd_k;
135 pte_t *pte_k;
136
137 /* Make sure we are in vmalloc area */
138 if (!(address >= VMALLOC_START && address < VMALLOC_END))
139 return -1;
140
141 /*
142 * Synchronize this task's top level page-table
143 * with the 'reference' page table.
144 */
145 pmd_k = vmalloc_sync_one(pgd, address);
146 if (!pmd_k)
147 return -1;
148 if (pmd_huge(*pmd_k))
149 return 0; /* support TILE huge_vmap() API */
150 pte_k = pte_offset_kernel(pmd_k, address);
151 if (!pte_present(*pte_k))
152 return -1;
153 return 0;
154}
155
156/* Wait until this PTE has completed migration. */
157static void wait_for_migration(pte_t *pte)
158{
159 if (pte_migrating(*pte)) {
160 /*
161 * Wait until the migrater fixes up this pte.
162 * We scale the loop count by the clock rate so we'll wait for
163 * a few seconds here.
164 */
165 int retries = 0;
166 int bound = get_clock_rate();
167 while (pte_migrating(*pte)) {
168 barrier();
169 if (++retries > bound)
170 panic("Hit migrating PTE (%#llx) and"
171 " page PFN %#lx still migrating",
172 pte->val, pte_pfn(*pte));
173 }
174 }
175}
176
177/*
178 * It's not generally safe to use "current" to get the page table pointer,
179 * since we might be running an oprofile interrupt in the middle of a
180 * task switch.
181 */
182static pgd_t *get_current_pgd(void)
183{
184 HV_Context ctx = hv_inquire_context();
185 unsigned long pgd_pfn = ctx.page_table >> PAGE_SHIFT;
186 struct page *pgd_page = pfn_to_page(pgd_pfn);
187 BUG_ON(PageHighMem(pgd_page)); /* oops, HIGHPTE? */
188 return (pgd_t *) __va(ctx.page_table);
189}
190
191/*
192 * We can receive a page fault from a migrating PTE at any time.
193 * Handle it by just waiting until the fault resolves.
194 *
195 * It's also possible to get a migrating kernel PTE that resolves
196 * itself during the downcall from hypervisor to Linux. We just check
197 * here to see if the PTE seems valid, and if so we retry it.
198 *
199 * NOTE! We MUST NOT take any locks for this case. We may be in an
200 * interrupt or a critical region, and must do as little as possible.
201 * Similarly, we can't use atomic ops here, since we may be handling a
202 * fault caused by an atomic op access.
203 */
204static int handle_migrating_pte(pgd_t *pgd, int fault_num,
205 unsigned long address,
206 int is_kernel_mode, int write)
207{
208 pud_t *pud;
209 pmd_t *pmd;
210 pte_t *pte;
211 pte_t pteval;
212
213 if (pgd_addr_invalid(address))
214 return 0;
215
216 pgd += pgd_index(address);
217 pud = pud_offset(pgd, address);
218 if (!pud || !pud_present(*pud))
219 return 0;
220 pmd = pmd_offset(pud, address);
221 if (!pmd || !pmd_present(*pmd))
222 return 0;
223 pte = pmd_huge_page(*pmd) ? ((pte_t *)pmd) :
224 pte_offset_kernel(pmd, address);
225 pteval = *pte;
226 if (pte_migrating(pteval)) {
227 wait_for_migration(pte);
228 return 1;
229 }
230
231 if (!is_kernel_mode || !pte_present(pteval))
232 return 0;
233 if (fault_num == INT_ITLB_MISS) {
234 if (pte_exec(pteval))
235 return 1;
236 } else if (write) {
237 if (pte_write(pteval))
238 return 1;
239 } else {
240 if (pte_read(pteval))
241 return 1;
242 }
243
244 return 0;
245}
246
247/*
248 * This routine is responsible for faulting in user pages.
249 * It passes the work off to one of the appropriate routines.
250 * It returns true if the fault was successfully handled.
251 */
252static int handle_page_fault(struct pt_regs *regs,
253 int fault_num,
254 int is_page_fault,
255 unsigned long address,
256 int write)
257{
258 struct task_struct *tsk;
259 struct mm_struct *mm;
260 struct vm_area_struct *vma;
261 unsigned long stack_offset;
262 int fault;
263 int si_code;
264 int is_kernel_mode;
265 pgd_t *pgd;
266
267 /* on TILE, protection faults are always writes */
268 if (!is_page_fault)
269 write = 1;
270
271 is_kernel_mode = (EX1_PL(regs->ex1) != USER_PL);
272
273 tsk = validate_current();
274
275 /*
276 * Check to see if we might be overwriting the stack, and bail
277 * out if so. The page fault code is a relatively likely
278 * place to get trapped in an infinite regress, and once we
279 * overwrite the whole stack, it becomes very hard to recover.
280 */
281 stack_offset = stack_pointer & (THREAD_SIZE-1);
282 if (stack_offset < THREAD_SIZE / 8) {
283 pr_alert("Potential stack overrun: sp %#lx\n",
284 stack_pointer);
285 show_regs(regs);
286 pr_alert("Killing current process %d/%s\n",
287 tsk->pid, tsk->comm);
288 do_group_exit(SIGKILL);
289 }
290
291 /*
292 * Early on, we need to check for migrating PTE entries;
293 * see homecache.c. If we find a migrating PTE, we wait until
294 * the backing page claims to be done migrating, then we procede.
295 * For kernel PTEs, we rewrite the PTE and return and retry.
296 * Otherwise, we treat the fault like a normal "no PTE" fault,
297 * rather than trying to patch up the existing PTE.
298 */
299 pgd = get_current_pgd();
300 if (handle_migrating_pte(pgd, fault_num, address,
301 is_kernel_mode, write))
302 return 1;
303
304 si_code = SEGV_MAPERR;
305
306 /*
307 * We fault-in kernel-space virtual memory on-demand. The
308 * 'reference' page table is init_mm.pgd.
309 *
310 * NOTE! We MUST NOT take any locks for this case. We may
311 * be in an interrupt or a critical region, and should
312 * only copy the information from the master page table,
313 * nothing more.
314 *
315 * This verifies that the fault happens in kernel space
316 * and that the fault was not a protection fault.
317 */
318 if (unlikely(address >= TASK_SIZE &&
319 !is_arch_mappable_range(address, 0))) {
320 if (is_kernel_mode && is_page_fault &&
321 vmalloc_fault(pgd, address) >= 0)
322 return 1;
323 /*
324 * Don't take the mm semaphore here. If we fixup a prefetch
325 * fault we could otherwise deadlock.
326 */
327 mm = NULL; /* happy compiler */
328 vma = NULL;
329 goto bad_area_nosemaphore;
330 }
331
332 /*
333 * If we're trying to touch user-space addresses, we must
334 * be either at PL0, or else with interrupts enabled in the
335 * kernel, so either way we can re-enable interrupts here.
336 */
337 local_irq_enable();
338
339 mm = tsk->mm;
340
341 /*
342 * If we're in an interrupt, have no user context or are running in an
343 * atomic region then we must not take the fault.
344 */
345 if (in_atomic() || !mm) {
346 vma = NULL; /* happy compiler */
347 goto bad_area_nosemaphore;
348 }
349
350 /*
351 * When running in the kernel we expect faults to occur only to
352 * addresses in user space. All other faults represent errors in the
353 * kernel and should generate an OOPS. Unfortunately, in the case of an
354 * erroneous fault occurring in a code path which already holds mmap_sem
355 * we will deadlock attempting to validate the fault against the
356 * address space. Luckily the kernel only validly references user
357 * space from well defined areas of code, which are listed in the
358 * exceptions table.
359 *
360 * As the vast majority of faults will be valid we will only perform
361 * the source reference check when there is a possibility of a deadlock.
362 * Attempt to lock the address space, if we cannot we then validate the
363 * source. If this is invalid we can skip the address space check,
364 * thus avoiding the deadlock.
365 */
366 if (!down_read_trylock(&mm->mmap_sem)) {
367 if (is_kernel_mode &&
368 !search_exception_tables(regs->pc)) {
369 vma = NULL; /* happy compiler */
370 goto bad_area_nosemaphore;
371 }
372 down_read(&mm->mmap_sem);
373 }
374
375 vma = find_vma(mm, address);
376 if (!vma)
377 goto bad_area;
378 if (vma->vm_start <= address)
379 goto good_area;
380 if (!(vma->vm_flags & VM_GROWSDOWN))
381 goto bad_area;
382 if (regs->sp < PAGE_OFFSET) {
383 /*
384 * accessing the stack below sp is always a bug.
385 */
386 if (address < regs->sp)
387 goto bad_area;
388 }
389 if (expand_stack(vma, address))
390 goto bad_area;
391
392/*
393 * Ok, we have a good vm_area for this memory access, so
394 * we can handle it..
395 */
396good_area:
397 si_code = SEGV_ACCERR;
398 if (fault_num == INT_ITLB_MISS) {
399 if (!(vma->vm_flags & VM_EXEC))
400 goto bad_area;
401 } else if (write) {
402#ifdef TEST_VERIFY_AREA
403 if (!is_page_fault && regs->cs == KERNEL_CS)
404 pr_err("WP fault at "REGFMT"\n", regs->eip);
405#endif
406 if (!(vma->vm_flags & VM_WRITE))
407 goto bad_area;
408 } else {
409 if (!is_page_fault || !(vma->vm_flags & VM_READ))
410 goto bad_area;
411 }
412
413 survive:
414 /*
415 * If for any reason at all we couldn't handle the fault,
416 * make sure we exit gracefully rather than endlessly redo
417 * the fault.
418 */
419 fault = handle_mm_fault(mm, vma, address, write);
420 if (unlikely(fault & VM_FAULT_ERROR)) {
421 if (fault & VM_FAULT_OOM)
422 goto out_of_memory;
423 else if (fault & VM_FAULT_SIGBUS)
424 goto do_sigbus;
425 BUG();
426 }
427 if (fault & VM_FAULT_MAJOR)
428 tsk->maj_flt++;
429 else
430 tsk->min_flt++;
431
432#if CHIP_HAS_TILE_DMA() || CHIP_HAS_SN_PROC()
433 /*
434 * If this was an asynchronous fault,
435 * restart the appropriate engine.
436 */
437 switch (fault_num) {
438#if CHIP_HAS_TILE_DMA()
439 case INT_DMATLB_MISS:
440 case INT_DMATLB_MISS_DWNCL:
441 case INT_DMATLB_ACCESS:
442 case INT_DMATLB_ACCESS_DWNCL:
443 __insn_mtspr(SPR_DMA_CTR, SPR_DMA_CTR__REQUEST_MASK);
444 break;
445#endif
446#if CHIP_HAS_SN_PROC()
447 case INT_SNITLB_MISS:
448 case INT_SNITLB_MISS_DWNCL:
449 __insn_mtspr(SPR_SNCTL,
450 __insn_mfspr(SPR_SNCTL) &
451 ~SPR_SNCTL__FRZPROC_MASK);
452 break;
453#endif
454 }
455#endif
456
457 up_read(&mm->mmap_sem);
458 return 1;
459
460/*
461 * Something tried to access memory that isn't in our memory map..
462 * Fix it, but check if it's kernel or user first..
463 */
464bad_area:
465 up_read(&mm->mmap_sem);
466
467bad_area_nosemaphore:
468 /* User mode accesses just cause a SIGSEGV */
469 if (!is_kernel_mode) {
470 /*
471 * It's possible to have interrupts off here.
472 */
473 local_irq_enable();
474
475 force_sig_info_fault(SIGSEGV, si_code, address,
476 fault_num, tsk);
477 return 0;
478 }
479
480no_context:
481 /* Are we prepared to handle this kernel fault? */
482 if (fixup_exception(regs))
483 return 0;
484
485/*
486 * Oops. The kernel tried to access some bad page. We'll have to
487 * terminate things with extreme prejudice.
488 */
489
490 bust_spinlocks(1);
491
492 /* FIXME: no lookup_address() yet */
493#ifdef SUPPORT_LOOKUP_ADDRESS
494 if (fault_num == INT_ITLB_MISS) {
495 pte_t *pte = lookup_address(address);
496
497 if (pte && pte_present(*pte) && !pte_exec_kernel(*pte))
498 pr_crit("kernel tried to execute"
499 " non-executable page - exploit attempt?"
500 " (uid: %d)\n", current->uid);
501 }
502#endif
503 if (address < PAGE_SIZE)
504 pr_alert("Unable to handle kernel NULL pointer dereference\n");
505 else
506 pr_alert("Unable to handle kernel paging request\n");
507 pr_alert(" at virtual address "REGFMT", pc "REGFMT"\n",
508 address, regs->pc);
509
510 show_regs(regs);
511
512 if (unlikely(tsk->pid < 2)) {
513 panic("Kernel page fault running %s!",
514 tsk->pid ? "init" : "the idle task");
515 }
516
517 /*
518 * More FIXME: we should probably copy the i386 here and
519 * implement a generic die() routine. Not today.
520 */
521#ifdef SUPPORT_DIE
522 die("Oops", regs);
523#endif
524 bust_spinlocks(1);
525
526 do_group_exit(SIGKILL);
527
528/*
529 * We ran out of memory, or some other thing happened to us that made
530 * us unable to handle the page fault gracefully.
531 */
532out_of_memory:
533 up_read(&mm->mmap_sem);
534 if (is_global_init(tsk)) {
535 yield();
536 down_read(&mm->mmap_sem);
537 goto survive;
538 }
539 pr_alert("VM: killing process %s\n", tsk->comm);
540 if (!is_kernel_mode)
541 do_group_exit(SIGKILL);
542 goto no_context;
543
544do_sigbus:
545 up_read(&mm->mmap_sem);
546
547 /* Kernel mode? Handle exceptions or die */
548 if (is_kernel_mode)
549 goto no_context;
550
551 force_sig_info_fault(SIGBUS, BUS_ADRERR, address, fault_num, tsk);
552 return 0;
553}
554
555#ifndef __tilegx__
556
557/* We must release ICS before panicking or we won't get anywhere. */
558#define ics_panic(fmt, ...) do { \
559 __insn_mtspr(SPR_INTERRUPT_CRITICAL_SECTION, 0); \
560 panic(fmt, __VA_ARGS__); \
561} while (0)
562
563/*
564 * When we take an ITLB or DTLB fault or access violation in the
565 * supervisor while the critical section bit is set, the hypervisor is
566 * reluctant to write new values into the EX_CONTEXT_1_x registers,
567 * since that might indicate we have not yet squirreled the SPR
568 * contents away and can thus safely take a recursive interrupt.
569 * Accordingly, the hypervisor passes us the PC via SYSTEM_SAVE_1_2.
570 *
571 * Note that this routine is called before homecache_tlb_defer_enter(),
572 * which means that we can properly unlock any atomics that might
573 * be used there (good), but also means we must be very sensitive
574 * to not touch any data structures that might be located in memory
575 * that could migrate, as we could be entering the kernel on a dataplane
576 * cpu that has been deferring kernel TLB updates. This means, for
577 * example, that we can't migrate init_mm or its pgd.
578 */
579struct intvec_state do_page_fault_ics(struct pt_regs *regs, int fault_num,
580 unsigned long address,
581 unsigned long info)
582{
583 unsigned long pc = info & ~1;
584 int write = info & 1;
585 pgd_t *pgd = get_current_pgd();
586
587 /* Retval is 1 at first since we will handle the fault fully. */
588 struct intvec_state state = {
589 do_page_fault, fault_num, address, write, 1
590 };
591
592 /* Validate that we are plausibly in the right routine. */
593 if ((pc & 0x7) != 0 || pc < PAGE_OFFSET ||
594 (fault_num != INT_DTLB_MISS &&
595 fault_num != INT_DTLB_ACCESS)) {
596 unsigned long old_pc = regs->pc;
597 regs->pc = pc;
598 ics_panic("Bad ICS page fault args:"
599 " old PC %#lx, fault %d/%d at %#lx\n",
600 old_pc, fault_num, write, address);
601 }
602
603 /* We might be faulting on a vmalloc page, so check that first. */
604 if (fault_num != INT_DTLB_ACCESS && vmalloc_fault(pgd, address) >= 0)
605 return state;
606
607 /*
608 * If we faulted with ICS set in sys_cmpxchg, we are providing
609 * a user syscall service that should generate a signal on
610 * fault. We didn't set up a kernel stack on initial entry to
611 * sys_cmpxchg, but instead had one set up by the fault, which
612 * (because sys_cmpxchg never releases ICS) came to us via the
613 * SYSTEM_SAVE_1_2 mechanism, and thus EX_CONTEXT_1_[01] are
614 * still referencing the original user code. We release the
615 * atomic lock and rewrite pt_regs so that it appears that we
616 * came from user-space directly, and after we finish the
617 * fault we'll go back to user space and re-issue the swint.
618 * This way the backtrace information is correct if we need to
619 * emit a stack dump at any point while handling this.
620 *
621 * Must match register use in sys_cmpxchg().
622 */
623 if (pc >= (unsigned long) sys_cmpxchg &&
624 pc < (unsigned long) __sys_cmpxchg_end) {
625#ifdef CONFIG_SMP
626 /* Don't unlock before we could have locked. */
627 if (pc >= (unsigned long)__sys_cmpxchg_grab_lock) {
628 int *lock_ptr = (int *)(regs->regs[ATOMIC_LOCK_REG]);
629 __atomic_fault_unlock(lock_ptr);
630 }
631#endif
632 regs->sp = regs->regs[27];
633 }
634
635 /*
636 * We can also fault in the atomic assembly, in which
637 * case we use the exception table to do the first-level fixup.
638 * We may re-fixup again in the real fault handler if it
639 * turns out the faulting address is just bad, and not,
640 * for example, migrating.
641 */
642 else if (pc >= (unsigned long) __start_atomic_asm_code &&
643 pc < (unsigned long) __end_atomic_asm_code) {
644 const struct exception_table_entry *fixup;
645#ifdef CONFIG_SMP
646 /* Unlock the atomic lock. */
647 int *lock_ptr = (int *)(regs->regs[ATOMIC_LOCK_REG]);
648 __atomic_fault_unlock(lock_ptr);
649#endif
650 fixup = search_exception_tables(pc);
651 if (!fixup)
652 ics_panic("ICS atomic fault not in table:"
653 " PC %#lx, fault %d", pc, fault_num);
654 regs->pc = fixup->fixup;
655 regs->ex1 = PL_ICS_EX1(KERNEL_PL, 0);
656 }
657
658 /*
659 * NOTE: the one other type of access that might bring us here
660 * are the memory ops in __tns_atomic_acquire/__tns_atomic_release,
661 * but we don't have to check specially for them since we can
662 * always safely return to the address of the fault and retry,
663 * since no separate atomic locks are involved.
664 */
665
666 /*
667 * Now that we have released the atomic lock (if necessary),
668 * it's safe to spin if the PTE that caused the fault was migrating.
669 */
670 if (fault_num == INT_DTLB_ACCESS)
671 write = 1;
672 if (handle_migrating_pte(pgd, fault_num, address, 1, write))
673 return state;
674
675 /* Return zero so that we continue on with normal fault handling. */
676 state.retval = 0;
677 return state;
678}
679
680#endif /* !__tilegx__ */
681
682/*
683 * This routine handles page faults. It determines the address, and the
684 * problem, and then passes it handle_page_fault() for normal DTLB and
685 * ITLB issues, and for DMA or SN processor faults when we are in user
686 * space. For the latter, if we're in kernel mode, we just save the
687 * interrupt away appropriately and return immediately. We can't do
688 * page faults for user code while in kernel mode.
689 */
690void do_page_fault(struct pt_regs *regs, int fault_num,
691 unsigned long address, unsigned long write)
692{
693 int is_page_fault;
694
695 /* This case should have been handled by do_page_fault_ics(). */
696 BUG_ON(write & ~1);
697
698#if CHIP_HAS_TILE_DMA()
699 /*
700 * If it's a DMA fault, suspend the transfer while we're
701 * handling the miss; we'll restart after it's handled. If we
702 * don't suspend, it's possible that this process could swap
703 * out and back in, and restart the engine since the DMA is
704 * still 'running'.
705 */
706 if (fault_num == INT_DMATLB_MISS ||
707 fault_num == INT_DMATLB_ACCESS ||
708 fault_num == INT_DMATLB_MISS_DWNCL ||
709 fault_num == INT_DMATLB_ACCESS_DWNCL) {
710 __insn_mtspr(SPR_DMA_CTR, SPR_DMA_CTR__SUSPEND_MASK);
711 while (__insn_mfspr(SPR_DMA_USER_STATUS) &
712 SPR_DMA_STATUS__BUSY_MASK)
713 ;
714 }
715#endif
716
717 /* Validate fault num and decide if this is a first-time page fault. */
718 switch (fault_num) {
719 case INT_ITLB_MISS:
720 case INT_DTLB_MISS:
721#if CHIP_HAS_TILE_DMA()
722 case INT_DMATLB_MISS:
723 case INT_DMATLB_MISS_DWNCL:
724#endif
725#if CHIP_HAS_SN_PROC()
726 case INT_SNITLB_MISS:
727 case INT_SNITLB_MISS_DWNCL:
728#endif
729 is_page_fault = 1;
730 break;
731
732 case INT_DTLB_ACCESS:
733#if CHIP_HAS_TILE_DMA()
734 case INT_DMATLB_ACCESS:
735 case INT_DMATLB_ACCESS_DWNCL:
736#endif
737 is_page_fault = 0;
738 break;
739
740 default:
741 panic("Bad fault number %d in do_page_fault", fault_num);
742 }
743
744 if (EX1_PL(regs->ex1) != USER_PL) {
745 struct async_tlb *async;
746 switch (fault_num) {
747#if CHIP_HAS_TILE_DMA()
748 case INT_DMATLB_MISS:
749 case INT_DMATLB_ACCESS:
750 case INT_DMATLB_MISS_DWNCL:
751 case INT_DMATLB_ACCESS_DWNCL:
752 async = &current->thread.dma_async_tlb;
753 break;
754#endif
755#if CHIP_HAS_SN_PROC()
756 case INT_SNITLB_MISS:
757 case INT_SNITLB_MISS_DWNCL:
758 async = &current->thread.sn_async_tlb;
759 break;
760#endif
761 default:
762 async = NULL;
763 }
764 if (async) {
765
766 /*
767 * No vmalloc check required, so we can allow
768 * interrupts immediately at this point.
769 */
770 local_irq_enable();
771
772 set_thread_flag(TIF_ASYNC_TLB);
773 if (async->fault_num != 0) {
774 panic("Second async fault %d;"
775 " old fault was %d (%#lx/%ld)",
776 fault_num, async->fault_num,
777 address, write);
778 }
779 BUG_ON(fault_num == 0);
780 async->fault_num = fault_num;
781 async->is_fault = is_page_fault;
782 async->is_write = write;
783 async->address = address;
784 return;
785 }
786 }
787
788 handle_page_fault(regs, fault_num, is_page_fault, address, write);
789}
790
791
792#if CHIP_HAS_TILE_DMA() || CHIP_HAS_SN_PROC()
793/*
794 * Check an async_tlb structure to see if a deferred fault is waiting,
795 * and if so pass it to the page-fault code.
796 */
797static void handle_async_page_fault(struct pt_regs *regs,
798 struct async_tlb *async)
799{
800 if (async->fault_num) {
801 /*
802 * Clear async->fault_num before calling the page-fault
803 * handler so that if we re-interrupt before returning
804 * from the function we have somewhere to put the
805 * information from the new interrupt.
806 */
807 int fault_num = async->fault_num;
808 async->fault_num = 0;
809 handle_page_fault(regs, fault_num, async->is_fault,
810 async->address, async->is_write);
811 }
812}
813#endif /* CHIP_HAS_TILE_DMA() || CHIP_HAS_SN_PROC() */
814
815
816/*
817 * This routine effectively re-issues asynchronous page faults
818 * when we are returning to user space.
819 */
820void do_async_page_fault(struct pt_regs *regs)
821{
822 /*
823 * Clear thread flag early. If we re-interrupt while processing
824 * code here, we will reset it and recall this routine before
825 * returning to user space.
826 */
827 clear_thread_flag(TIF_ASYNC_TLB);
828
829#if CHIP_HAS_TILE_DMA()
830 handle_async_page_fault(regs, &current->thread.dma_async_tlb);
831#endif
832#if CHIP_HAS_SN_PROC()
833 handle_async_page_fault(regs, &current->thread.sn_async_tlb);
834#endif
835}
836
837void vmalloc_sync_all(void)
838{
839#ifdef __tilegx__
840 /* Currently all L1 kernel pmd's are static and shared. */
841 BUG_ON(pgd_index(VMALLOC_END) != pgd_index(VMALLOC_START));
842#else
843 /*
844 * Note that races in the updates of insync and start aren't
845 * problematic: insync can only get set bits added, and updates to
846 * start are only improving performance (without affecting correctness
847 * if undone).
848 */
849 static DECLARE_BITMAP(insync, PTRS_PER_PGD);
850 static unsigned long start = PAGE_OFFSET;
851 unsigned long address;
852
853 BUILD_BUG_ON(PAGE_OFFSET & ~PGDIR_MASK);
854 for (address = start; address >= PAGE_OFFSET; address += PGDIR_SIZE) {
855 if (!test_bit(pgd_index(address), insync)) {
856 unsigned long flags;
857 struct list_head *pos;
858
859 spin_lock_irqsave(&pgd_lock, flags);
860 list_for_each(pos, &pgd_list)
861 if (!vmalloc_sync_one(list_to_pgd(pos),
862 address)) {
863 /* Must be at first entry in list. */
864 BUG_ON(pos != pgd_list.next);
865 break;
866 }
867 spin_unlock_irqrestore(&pgd_lock, flags);
868 if (pos != pgd_list.next)
869 set_bit(pgd_index(address), insync);
870 }
871 if (address == start && test_bit(pgd_index(address), insync))
872 start = address + PGDIR_SIZE;
873 }
874#endif
875}
diff --git a/arch/tile/mm/highmem.c b/arch/tile/mm/highmem.c
new file mode 100644
index 000000000000..12ab137e7d4f
--- /dev/null
+++ b/arch/tile/mm/highmem.c
@@ -0,0 +1,328 @@
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#include <linux/highmem.h>
16#include <linux/module.h>
17#include <linux/pagemap.h>
18#include <asm/homecache.h>
19
20#define kmap_get_pte(vaddr) \
21 pte_offset_kernel(pmd_offset(pud_offset(pgd_offset_k(vaddr), (vaddr)),\
22 (vaddr)), (vaddr))
23
24
25void *kmap(struct page *page)
26{
27 void *kva;
28 unsigned long flags;
29 pte_t *ptep;
30
31 might_sleep();
32 if (!PageHighMem(page))
33 return page_address(page);
34 kva = kmap_high(page);
35
36 /*
37 * Rewrite the PTE under the lock. This ensures that the page
38 * is not currently migrating.
39 */
40 ptep = kmap_get_pte((unsigned long)kva);
41 flags = homecache_kpte_lock();
42 set_pte_at(&init_mm, kva, ptep, mk_pte(page, page_to_kpgprot(page)));
43 homecache_kpte_unlock(flags);
44
45 return kva;
46}
47EXPORT_SYMBOL(kmap);
48
49void kunmap(struct page *page)
50{
51 if (in_interrupt())
52 BUG();
53 if (!PageHighMem(page))
54 return;
55 kunmap_high(page);
56}
57EXPORT_SYMBOL(kunmap);
58
59static void debug_kmap_atomic_prot(enum km_type type)
60{
61#ifdef CONFIG_DEBUG_HIGHMEM
62 static unsigned warn_count = 10;
63
64 if (unlikely(warn_count == 0))
65 return;
66
67 if (unlikely(in_interrupt())) {
68 if (in_irq()) {
69 if (type != KM_IRQ0 && type != KM_IRQ1 &&
70 type != KM_BIO_SRC_IRQ &&
71 /* type != KM_BIO_DST_IRQ && */
72 type != KM_BOUNCE_READ) {
73 WARN_ON(1);
74 warn_count--;
75 }
76 } else if (!irqs_disabled()) { /* softirq */
77 if (type != KM_IRQ0 && type != KM_IRQ1 &&
78 type != KM_SOFTIRQ0 && type != KM_SOFTIRQ1 &&
79 type != KM_SKB_SUNRPC_DATA &&
80 type != KM_SKB_DATA_SOFTIRQ &&
81 type != KM_BOUNCE_READ) {
82 WARN_ON(1);
83 warn_count--;
84 }
85 }
86 }
87
88 if (type == KM_IRQ0 || type == KM_IRQ1 || type == KM_BOUNCE_READ ||
89 type == KM_BIO_SRC_IRQ /* || type == KM_BIO_DST_IRQ */) {
90 if (!irqs_disabled()) {
91 WARN_ON(1);
92 warn_count--;
93 }
94 } else if (type == KM_SOFTIRQ0 || type == KM_SOFTIRQ1) {
95 if (irq_count() == 0 && !irqs_disabled()) {
96 WARN_ON(1);
97 warn_count--;
98 }
99 }
100#endif
101}
102
103/*
104 * Describe a single atomic mapping of a page on a given cpu at a
105 * given address, and allow it to be linked into a list.
106 */
107struct atomic_mapped_page {
108 struct list_head list;
109 struct page *page;
110 int cpu;
111 unsigned long va;
112};
113
114static spinlock_t amp_lock = __SPIN_LOCK_UNLOCKED(&amp_lock);
115static struct list_head amp_list = LIST_HEAD_INIT(amp_list);
116
117/*
118 * Combining this structure with a per-cpu declaration lets us give
119 * each cpu an atomic_mapped_page structure per type.
120 */
121struct kmap_amps {
122 struct atomic_mapped_page per_type[KM_TYPE_NR];
123};
124static DEFINE_PER_CPU(struct kmap_amps, amps);
125
126/*
127 * Add a page and va, on this cpu, to the list of kmap_atomic pages,
128 * and write the new pte to memory. Writing the new PTE under the
129 * lock guarantees that it is either on the list before migration starts
130 * (if we won the race), or set_pte() sets the migrating bit in the PTE
131 * (if we lost the race). And doing it under the lock guarantees
132 * that when kmap_atomic_fix_one_pte() comes along, it finds a valid
133 * PTE in memory, iff the mapping is still on the amp_list.
134 *
135 * Finally, doing it under the lock lets us safely examine the page
136 * to see if it is immutable or not, for the generic kmap_atomic() case.
137 * If we examine it earlier we are exposed to a race where it looks
138 * writable earlier, but becomes immutable before we write the PTE.
139 */
140static void kmap_atomic_register(struct page *page, enum km_type type,
141 unsigned long va, pte_t *ptep, pte_t pteval)
142{
143 unsigned long flags;
144 struct atomic_mapped_page *amp;
145
146 flags = homecache_kpte_lock();
147 spin_lock(&amp_lock);
148
149 /* With interrupts disabled, now fill in the per-cpu info. */
150 amp = &__get_cpu_var(amps).per_type[type];
151 amp->page = page;
152 amp->cpu = smp_processor_id();
153 amp->va = va;
154
155 /* For generic kmap_atomic(), choose the PTE writability now. */
156 if (!pte_read(pteval))
157 pteval = mk_pte(page, page_to_kpgprot(page));
158
159 list_add(&amp->list, &amp_list);
160 set_pte(ptep, pteval);
161 arch_flush_lazy_mmu_mode();
162
163 spin_unlock(&amp_lock);
164 homecache_kpte_unlock(flags);
165}
166
167/*
168 * Remove a page and va, on this cpu, from the list of kmap_atomic pages.
169 * Linear-time search, but we count on the lists being short.
170 * We don't need to adjust the PTE under the lock (as opposed to the
171 * kmap_atomic_register() case), since we're just unconditionally
172 * zeroing the PTE after it's off the list.
173 */
174static void kmap_atomic_unregister(struct page *page, unsigned long va)
175{
176 unsigned long flags;
177 struct atomic_mapped_page *amp;
178 int cpu = smp_processor_id();
179 spin_lock_irqsave(&amp_lock, flags);
180 list_for_each_entry(amp, &amp_list, list) {
181 if (amp->page == page && amp->cpu == cpu && amp->va == va)
182 break;
183 }
184 BUG_ON(&amp->list == &amp_list);
185 list_del(&amp->list);
186 spin_unlock_irqrestore(&amp_lock, flags);
187}
188
189/* Helper routine for kmap_atomic_fix_kpte(), below. */
190static void kmap_atomic_fix_one_kpte(struct atomic_mapped_page *amp,
191 int finished)
192{
193 pte_t *ptep = kmap_get_pte(amp->va);
194 if (!finished) {
195 set_pte(ptep, pte_mkmigrate(*ptep));
196 flush_remote(0, 0, NULL, amp->va, PAGE_SIZE, PAGE_SIZE,
197 cpumask_of(amp->cpu), NULL, 0);
198 } else {
199 /*
200 * Rewrite a default kernel PTE for this page.
201 * We rely on the fact that set_pte() writes the
202 * present+migrating bits last.
203 */
204 pte_t pte = mk_pte(amp->page, page_to_kpgprot(amp->page));
205 set_pte(ptep, pte);
206 }
207}
208
209/*
210 * This routine is a helper function for homecache_fix_kpte(); see
211 * its comments for more information on the "finished" argument here.
212 *
213 * Note that we hold the lock while doing the remote flushes, which
214 * will stall any unrelated cpus trying to do kmap_atomic operations.
215 * We could just update the PTEs under the lock, and save away copies
216 * of the structs (or just the va+cpu), then flush them after we
217 * release the lock, but it seems easier just to do it all under the lock.
218 */
219void kmap_atomic_fix_kpte(struct page *page, int finished)
220{
221 struct atomic_mapped_page *amp;
222 unsigned long flags;
223 spin_lock_irqsave(&amp_lock, flags);
224 list_for_each_entry(amp, &amp_list, list) {
225 if (amp->page == page)
226 kmap_atomic_fix_one_kpte(amp, finished);
227 }
228 spin_unlock_irqrestore(&amp_lock, flags);
229}
230
231/*
232 * kmap_atomic/kunmap_atomic is significantly faster than kmap/kunmap
233 * because the kmap code must perform a global TLB invalidation when
234 * the kmap pool wraps.
235 *
236 * Note that they may be slower than on x86 (etc.) because unlike on
237 * those platforms, we do have to take a global lock to map and unmap
238 * pages on Tile (see above).
239 *
240 * When holding an atomic kmap is is not legal to sleep, so atomic
241 * kmaps are appropriate for short, tight code paths only.
242 */
243void *kmap_atomic_prot(struct page *page, enum km_type type, pgprot_t prot)
244{
245 enum fixed_addresses idx;
246 unsigned long vaddr;
247 pte_t *pte;
248
249 /* even !CONFIG_PREEMPT needs this, for in_atomic in do_page_fault */
250 pagefault_disable();
251
252 /* Avoid icache flushes by disallowing atomic executable mappings. */
253 BUG_ON(pte_exec(prot));
254
255 if (!PageHighMem(page))
256 return page_address(page);
257
258 debug_kmap_atomic_prot(type);
259
260 idx = type + KM_TYPE_NR*smp_processor_id();
261 vaddr = __fix_to_virt(FIX_KMAP_BEGIN + idx);
262 pte = kmap_get_pte(vaddr);
263 BUG_ON(!pte_none(*pte));
264
265 /* Register that this page is mapped atomically on this cpu. */
266 kmap_atomic_register(page, type, vaddr, pte, mk_pte(page, prot));
267
268 return (void *)vaddr;
269}
270EXPORT_SYMBOL(kmap_atomic_prot);
271
272void *kmap_atomic(struct page *page, enum km_type type)
273{
274 /* PAGE_NONE is a magic value that tells us to check immutability. */
275 return kmap_atomic_prot(page, type, PAGE_NONE);
276}
277EXPORT_SYMBOL(kmap_atomic);
278
279void kunmap_atomic_notypecheck(void *kvaddr, enum km_type type)
280{
281 unsigned long vaddr = (unsigned long) kvaddr & PAGE_MASK;
282 enum fixed_addresses idx = type + KM_TYPE_NR*smp_processor_id();
283
284 /*
285 * Force other mappings to Oops if they try to access this pte without
286 * first remapping it. Keeping stale mappings around is a bad idea.
287 */
288 if (vaddr == __fix_to_virt(FIX_KMAP_BEGIN+idx)) {
289 pte_t *pte = kmap_get_pte(vaddr);
290 pte_t pteval = *pte;
291 BUG_ON(!pte_present(pteval) && !pte_migrating(pteval));
292 kmap_atomic_unregister(pte_page(pteval), vaddr);
293 kpte_clear_flush(pte, vaddr);
294 } else {
295 /* Must be a lowmem page */
296 BUG_ON(vaddr < PAGE_OFFSET);
297 BUG_ON(vaddr >= (unsigned long)high_memory);
298 }
299
300 arch_flush_lazy_mmu_mode();
301 pagefault_enable();
302}
303EXPORT_SYMBOL(kunmap_atomic_notypecheck);
304
305/*
306 * This API is supposed to allow us to map memory without a "struct page".
307 * Currently we don't support this, though this may change in the future.
308 */
309void *kmap_atomic_pfn(unsigned long pfn, enum km_type type)
310{
311 return kmap_atomic(pfn_to_page(pfn), type);
312}
313void *kmap_atomic_prot_pfn(unsigned long pfn, enum km_type type, pgprot_t prot)
314{
315 return kmap_atomic_prot(pfn_to_page(pfn), type, prot);
316}
317
318struct page *kmap_atomic_to_page(void *ptr)
319{
320 pte_t *pte;
321 unsigned long vaddr = (unsigned long)ptr;
322
323 if (vaddr < FIXADDR_START)
324 return virt_to_page(ptr);
325
326 pte = kmap_get_pte(vaddr);
327 return pte_page(*pte);
328}
diff --git a/arch/tile/mm/homecache.c b/arch/tile/mm/homecache.c
new file mode 100644
index 000000000000..fb3b4a55cec4
--- /dev/null
+++ b/arch/tile/mm/homecache.c
@@ -0,0 +1,436 @@
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 * This code maintains the "home" for each page in the system.
15 */
16
17#include <linux/kernel.h>
18#include <linux/mm.h>
19#include <linux/spinlock.h>
20#include <linux/list.h>
21#include <linux/bootmem.h>
22#include <linux/rmap.h>
23#include <linux/pagemap.h>
24#include <linux/mutex.h>
25#include <linux/interrupt.h>
26#include <linux/sysctl.h>
27#include <linux/pagevec.h>
28#include <linux/ptrace.h>
29#include <linux/timex.h>
30#include <linux/cache.h>
31#include <linux/smp.h>
32#include <linux/module.h>
33
34#include <asm/page.h>
35#include <asm/sections.h>
36#include <asm/tlbflush.h>
37#include <asm/pgalloc.h>
38#include <asm/homecache.h>
39
40#include "migrate.h"
41
42
43#if CHIP_HAS_COHERENT_LOCAL_CACHE()
44
45/*
46 * The noallocl2 option suppresses all use of the L2 cache to cache
47 * locally from a remote home. There's no point in using it if we
48 * don't have coherent local caching, though.
49 */
50static int __write_once noallocl2;
51static int __init set_noallocl2(char *str)
52{
53 noallocl2 = 1;
54 return 0;
55}
56early_param("noallocl2", set_noallocl2);
57
58#else
59
60#define noallocl2 0
61
62#endif
63
64/* Provide no-op versions of these routines to keep flush_remote() cleaner. */
65#define mark_caches_evicted_start() 0
66#define mark_caches_evicted_finish(mask, timestamp) do {} while (0)
67
68
69/*
70 * Update the irq_stat for cpus that we are going to interrupt
71 * with TLB or cache flushes. Also handle removing dataplane cpus
72 * from the TLB flush set, and setting dataplane_tlb_state instead.
73 */
74static void hv_flush_update(const struct cpumask *cache_cpumask,
75 struct cpumask *tlb_cpumask,
76 unsigned long tlb_va, unsigned long tlb_length,
77 HV_Remote_ASID *asids, int asidcount)
78{
79 struct cpumask mask;
80 int i, cpu;
81
82 cpumask_clear(&mask);
83 if (cache_cpumask)
84 cpumask_or(&mask, &mask, cache_cpumask);
85 if (tlb_cpumask && tlb_length) {
86 cpumask_or(&mask, &mask, tlb_cpumask);
87 }
88
89 for (i = 0; i < asidcount; ++i)
90 cpumask_set_cpu(asids[i].y * smp_width + asids[i].x, &mask);
91
92 /*
93 * Don't bother to update atomically; losing a count
94 * here is not that critical.
95 */
96 for_each_cpu(cpu, &mask)
97 ++per_cpu(irq_stat, cpu).irq_hv_flush_count;
98}
99
100/*
101 * This wrapper function around hv_flush_remote() does several things:
102 *
103 * - Provides a return value error-checking panic path, since
104 * there's never any good reason for hv_flush_remote() to fail.
105 * - Accepts a 32-bit PFN rather than a 64-bit PA, which generally
106 * is the type that Linux wants to pass around anyway.
107 * - Centralizes the mark_caches_evicted() handling.
108 * - Canonicalizes that lengths of zero make cpumasks NULL.
109 * - Handles deferring TLB flushes for dataplane tiles.
110 * - Tracks remote interrupts in the per-cpu irq_cpustat_t.
111 *
112 * Note that we have to wait until the cache flush completes before
113 * updating the per-cpu last_cache_flush word, since otherwise another
114 * concurrent flush can race, conclude the flush has already
115 * completed, and start to use the page while it's still dirty
116 * remotely (running concurrently with the actual evict, presumably).
117 */
118void flush_remote(unsigned long cache_pfn, unsigned long cache_control,
119 const struct cpumask *cache_cpumask_orig,
120 HV_VirtAddr tlb_va, unsigned long tlb_length,
121 unsigned long tlb_pgsize,
122 const struct cpumask *tlb_cpumask_orig,
123 HV_Remote_ASID *asids, int asidcount)
124{
125 int rc;
126 int timestamp = 0; /* happy compiler */
127 struct cpumask cache_cpumask_copy, tlb_cpumask_copy;
128 struct cpumask *cache_cpumask, *tlb_cpumask;
129 HV_PhysAddr cache_pa;
130 char cache_buf[NR_CPUS*5], tlb_buf[NR_CPUS*5];
131
132 mb(); /* provided just to simplify "magic hypervisor" mode */
133
134 /*
135 * Canonicalize and copy the cpumasks.
136 */
137 if (cache_cpumask_orig && cache_control) {
138 cpumask_copy(&cache_cpumask_copy, cache_cpumask_orig);
139 cache_cpumask = &cache_cpumask_copy;
140 } else {
141 cpumask_clear(&cache_cpumask_copy);
142 cache_cpumask = NULL;
143 }
144 if (cache_cpumask == NULL)
145 cache_control = 0;
146 if (tlb_cpumask_orig && tlb_length) {
147 cpumask_copy(&tlb_cpumask_copy, tlb_cpumask_orig);
148 tlb_cpumask = &tlb_cpumask_copy;
149 } else {
150 cpumask_clear(&tlb_cpumask_copy);
151 tlb_cpumask = NULL;
152 }
153
154 hv_flush_update(cache_cpumask, tlb_cpumask, tlb_va, tlb_length,
155 asids, asidcount);
156 cache_pa = (HV_PhysAddr)cache_pfn << PAGE_SHIFT;
157 if (cache_control & HV_FLUSH_EVICT_L2)
158 timestamp = mark_caches_evicted_start();
159 rc = hv_flush_remote(cache_pa, cache_control,
160 cpumask_bits(cache_cpumask),
161 tlb_va, tlb_length, tlb_pgsize,
162 cpumask_bits(tlb_cpumask),
163 asids, asidcount);
164 if (cache_control & HV_FLUSH_EVICT_L2)
165 mark_caches_evicted_finish(cache_cpumask, timestamp);
166 if (rc == 0)
167 return;
168 cpumask_scnprintf(cache_buf, sizeof(cache_buf), &cache_cpumask_copy);
169 cpumask_scnprintf(tlb_buf, sizeof(tlb_buf), &tlb_cpumask_copy);
170
171 pr_err("hv_flush_remote(%#llx, %#lx, %p [%s],"
172 " %#lx, %#lx, %#lx, %p [%s], %p, %d) = %d\n",
173 cache_pa, cache_control, cache_cpumask, cache_buf,
174 (unsigned long)tlb_va, tlb_length, tlb_pgsize,
175 tlb_cpumask, tlb_buf,
176 asids, asidcount, rc);
177 panic("Unsafe to continue.");
178}
179
180void homecache_evict(const struct cpumask *mask)
181{
182 flush_remote(0, HV_FLUSH_EVICT_L2, mask, 0, 0, 0, NULL, NULL, 0);
183}
184
185/* Return a mask of the cpus whose caches currently own these pages. */
186static void homecache_mask(struct page *page, int pages,
187 struct cpumask *home_mask)
188{
189 int i;
190 cpumask_clear(home_mask);
191 for (i = 0; i < pages; ++i) {
192 int home = page_home(&page[i]);
193 if (home == PAGE_HOME_IMMUTABLE ||
194 home == PAGE_HOME_INCOHERENT) {
195 cpumask_copy(home_mask, cpu_possible_mask);
196 return;
197 }
198#if CHIP_HAS_CBOX_HOME_MAP()
199 if (home == PAGE_HOME_HASH) {
200 cpumask_or(home_mask, home_mask, &hash_for_home_map);
201 continue;
202 }
203#endif
204 if (home == PAGE_HOME_UNCACHED)
205 continue;
206 BUG_ON(home < 0 || home >= NR_CPUS);
207 cpumask_set_cpu(home, home_mask);
208 }
209}
210
211/*
212 * Return the passed length, or zero if it's long enough that we
213 * believe we should evict the whole L2 cache.
214 */
215static unsigned long cache_flush_length(unsigned long length)
216{
217 return (length >= CHIP_L2_CACHE_SIZE()) ? HV_FLUSH_EVICT_L2 : length;
218}
219
220/* On the simulator, confirm lines have been evicted everywhere. */
221static void validate_lines_evicted(unsigned long pfn, size_t length)
222{
223 sim_syscall(SIM_SYSCALL_VALIDATE_LINES_EVICTED,
224 (HV_PhysAddr)pfn << PAGE_SHIFT, length);
225}
226
227/* Flush a page out of whatever cache(s) it is in. */
228void homecache_flush_cache(struct page *page, int order)
229{
230 int pages = 1 << order;
231 int length = cache_flush_length(pages * PAGE_SIZE);
232 unsigned long pfn = page_to_pfn(page);
233 struct cpumask home_mask;
234
235 homecache_mask(page, pages, &home_mask);
236 flush_remote(pfn, length, &home_mask, 0, 0, 0, NULL, NULL, 0);
237 validate_lines_evicted(pfn, pages * PAGE_SIZE);
238}
239
240
241/* Report the home corresponding to a given PTE. */
242static int pte_to_home(pte_t pte)
243{
244 if (hv_pte_get_nc(pte))
245 return PAGE_HOME_IMMUTABLE;
246 switch (hv_pte_get_mode(pte)) {
247 case HV_PTE_MODE_CACHE_TILE_L3:
248 return get_remote_cache_cpu(pte);
249 case HV_PTE_MODE_CACHE_NO_L3:
250 return PAGE_HOME_INCOHERENT;
251 case HV_PTE_MODE_UNCACHED:
252 return PAGE_HOME_UNCACHED;
253#if CHIP_HAS_CBOX_HOME_MAP()
254 case HV_PTE_MODE_CACHE_HASH_L3:
255 return PAGE_HOME_HASH;
256#endif
257 }
258 panic("Bad PTE %#llx\n", pte.val);
259}
260
261/* Update the home of a PTE if necessary (can also be used for a pgprot_t). */
262pte_t pte_set_home(pte_t pte, int home)
263{
264 /* Check for non-linear file mapping "PTEs" and pass them through. */
265 if (pte_file(pte))
266 return pte;
267
268#if CHIP_HAS_MMIO()
269 /* Check for MMIO mappings and pass them through. */
270 if (hv_pte_get_mode(pte) == HV_PTE_MODE_MMIO)
271 return pte;
272#endif
273
274
275 /*
276 * Only immutable pages get NC mappings. If we have a
277 * non-coherent PTE, but the underlying page is not
278 * immutable, it's likely the result of a forced
279 * caching setting running up against ptrace setting
280 * the page to be writable underneath. In this case,
281 * just keep the PTE coherent.
282 */
283 if (hv_pte_get_nc(pte) && home != PAGE_HOME_IMMUTABLE) {
284 pte = hv_pte_clear_nc(pte);
285 pr_err("non-immutable page incoherently referenced: %#llx\n",
286 pte.val);
287 }
288
289 switch (home) {
290
291 case PAGE_HOME_UNCACHED:
292 pte = hv_pte_set_mode(pte, HV_PTE_MODE_UNCACHED);
293 break;
294
295 case PAGE_HOME_INCOHERENT:
296 pte = hv_pte_set_mode(pte, HV_PTE_MODE_CACHE_NO_L3);
297 break;
298
299 case PAGE_HOME_IMMUTABLE:
300 /*
301 * We could home this page anywhere, since it's immutable,
302 * but by default just home it to follow "hash_default".
303 */
304 BUG_ON(hv_pte_get_writable(pte));
305 if (pte_get_forcecache(pte)) {
306 /* Upgrade "force any cpu" to "No L3" for immutable. */
307 if (hv_pte_get_mode(pte) == HV_PTE_MODE_CACHE_TILE_L3
308 && pte_get_anyhome(pte)) {
309 pte = hv_pte_set_mode(pte,
310 HV_PTE_MODE_CACHE_NO_L3);
311 }
312 } else
313#if CHIP_HAS_CBOX_HOME_MAP()
314 if (hash_default)
315 pte = hv_pte_set_mode(pte, HV_PTE_MODE_CACHE_HASH_L3);
316 else
317#endif
318 pte = hv_pte_set_mode(pte, HV_PTE_MODE_CACHE_NO_L3);
319 pte = hv_pte_set_nc(pte);
320 break;
321
322#if CHIP_HAS_CBOX_HOME_MAP()
323 case PAGE_HOME_HASH:
324 pte = hv_pte_set_mode(pte, HV_PTE_MODE_CACHE_HASH_L3);
325 break;
326#endif
327
328 default:
329 BUG_ON(home < 0 || home >= NR_CPUS ||
330 !cpu_is_valid_lotar(home));
331 pte = hv_pte_set_mode(pte, HV_PTE_MODE_CACHE_TILE_L3);
332 pte = set_remote_cache_cpu(pte, home);
333 break;
334 }
335
336#if CHIP_HAS_NC_AND_NOALLOC_BITS()
337 if (noallocl2)
338 pte = hv_pte_set_no_alloc_l2(pte);
339
340 /* Simplify "no local and no l3" to "uncached" */
341 if (hv_pte_get_no_alloc_l2(pte) && hv_pte_get_no_alloc_l1(pte) &&
342 hv_pte_get_mode(pte) == HV_PTE_MODE_CACHE_NO_L3) {
343 pte = hv_pte_set_mode(pte, HV_PTE_MODE_UNCACHED);
344 }
345#endif
346
347 /* Checking this case here gives a better panic than from the hv. */
348 BUG_ON(hv_pte_get_mode(pte) == 0);
349
350 return pte;
351}
352EXPORT_SYMBOL(pte_set_home);
353
354/*
355 * The routines in this section are the "static" versions of the normal
356 * dynamic homecaching routines; they just set the home cache
357 * of a kernel page once, and require a full-chip cache/TLB flush,
358 * so they're not suitable for anything but infrequent use.
359 */
360
361#if CHIP_HAS_CBOX_HOME_MAP()
362static inline int initial_page_home(void) { return PAGE_HOME_HASH; }
363#else
364static inline int initial_page_home(void) { return 0; }
365#endif
366
367int page_home(struct page *page)
368{
369 if (PageHighMem(page)) {
370 return initial_page_home();
371 } else {
372 unsigned long kva = (unsigned long)page_address(page);
373 return pte_to_home(*virt_to_pte(NULL, kva));
374 }
375}
376
377void homecache_change_page_home(struct page *page, int order, int home)
378{
379 int i, pages = (1 << order);
380 unsigned long kva;
381
382 BUG_ON(PageHighMem(page));
383 BUG_ON(page_count(page) > 1);
384 BUG_ON(page_mapcount(page) != 0);
385 kva = (unsigned long) page_address(page);
386 flush_remote(0, HV_FLUSH_EVICT_L2, &cpu_cacheable_map,
387 kva, pages * PAGE_SIZE, PAGE_SIZE, cpu_online_mask,
388 NULL, 0);
389
390 for (i = 0; i < pages; ++i, kva += PAGE_SIZE) {
391 pte_t *ptep = virt_to_pte(NULL, kva);
392 pte_t pteval = *ptep;
393 BUG_ON(!pte_present(pteval) || pte_huge(pteval));
394 *ptep = pte_set_home(pteval, home);
395 }
396}
397
398struct page *homecache_alloc_pages(gfp_t gfp_mask,
399 unsigned int order, int home)
400{
401 struct page *page;
402 BUG_ON(gfp_mask & __GFP_HIGHMEM); /* must be lowmem */
403 page = alloc_pages(gfp_mask, order);
404 if (page)
405 homecache_change_page_home(page, order, home);
406 return page;
407}
408EXPORT_SYMBOL(homecache_alloc_pages);
409
410struct page *homecache_alloc_pages_node(int nid, gfp_t gfp_mask,
411 unsigned int order, int home)
412{
413 struct page *page;
414 BUG_ON(gfp_mask & __GFP_HIGHMEM); /* must be lowmem */
415 page = alloc_pages_node(nid, gfp_mask, order);
416 if (page)
417 homecache_change_page_home(page, order, home);
418 return page;
419}
420
421void homecache_free_pages(unsigned long addr, unsigned int order)
422{
423 struct page *page;
424
425 if (addr == 0)
426 return;
427
428 VM_BUG_ON(!virt_addr_valid((void *)addr));
429 page = virt_to_page((void *)addr);
430 if (put_page_testzero(page)) {
431 int pages = (1 << order);
432 homecache_change_page_home(page, order, initial_page_home());
433 while (pages--)
434 __free_page(page++);
435 }
436}
diff --git a/arch/tile/mm/hugetlbpage.c b/arch/tile/mm/hugetlbpage.c
new file mode 100644
index 000000000000..24688b697a8d
--- /dev/null
+++ b/arch/tile/mm/hugetlbpage.c
@@ -0,0 +1,343 @@
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 * TILE Huge TLB Page Support for Kernel.
15 * Taken from i386 hugetlb implementation:
16 * Copyright (C) 2002, Rohit Seth <rohit.seth@intel.com>
17 */
18
19#include <linux/init.h>
20#include <linux/fs.h>
21#include <linux/mm.h>
22#include <linux/hugetlb.h>
23#include <linux/pagemap.h>
24#include <linux/smp_lock.h>
25#include <linux/slab.h>
26#include <linux/err.h>
27#include <linux/sysctl.h>
28#include <linux/mman.h>
29#include <asm/tlb.h>
30#include <asm/tlbflush.h>
31
32pte_t *huge_pte_alloc(struct mm_struct *mm,
33 unsigned long addr, unsigned long sz)
34{
35 pgd_t *pgd;
36 pud_t *pud;
37 pte_t *pte = NULL;
38
39 /* We do not yet support multiple huge page sizes. */
40 BUG_ON(sz != PMD_SIZE);
41
42 pgd = pgd_offset(mm, addr);
43 pud = pud_alloc(mm, pgd, addr);
44 if (pud)
45 pte = (pte_t *) pmd_alloc(mm, pud, addr);
46 BUG_ON(pte && !pte_none(*pte) && !pte_huge(*pte));
47
48 return pte;
49}
50
51pte_t *huge_pte_offset(struct mm_struct *mm, unsigned long addr)
52{
53 pgd_t *pgd;
54 pud_t *pud;
55 pmd_t *pmd = NULL;
56
57 pgd = pgd_offset(mm, addr);
58 if (pgd_present(*pgd)) {
59 pud = pud_offset(pgd, addr);
60 if (pud_present(*pud))
61 pmd = pmd_offset(pud, addr);
62 }
63 return (pte_t *) pmd;
64}
65
66#ifdef HUGETLB_TEST
67struct page *follow_huge_addr(struct mm_struct *mm, unsigned long address,
68 int write)
69{
70 unsigned long start = address;
71 int length = 1;
72 int nr;
73 struct page *page;
74 struct vm_area_struct *vma;
75
76 vma = find_vma(mm, addr);
77 if (!vma || !is_vm_hugetlb_page(vma))
78 return ERR_PTR(-EINVAL);
79
80 pte = huge_pte_offset(mm, address);
81
82 /* hugetlb should be locked, and hence, prefaulted */
83 WARN_ON(!pte || pte_none(*pte));
84
85 page = &pte_page(*pte)[vpfn % (HPAGE_SIZE/PAGE_SIZE)];
86
87 WARN_ON(!PageHead(page));
88
89 return page;
90}
91
92int pmd_huge(pmd_t pmd)
93{
94 return 0;
95}
96
97int pud_huge(pud_t pud)
98{
99 return 0;
100}
101
102struct page *follow_huge_pmd(struct mm_struct *mm, unsigned long address,
103 pmd_t *pmd, int write)
104{
105 return NULL;
106}
107
108#else
109
110struct page *follow_huge_addr(struct mm_struct *mm, unsigned long address,
111 int write)
112{
113 return ERR_PTR(-EINVAL);
114}
115
116int pmd_huge(pmd_t pmd)
117{
118 return !!(pmd_val(pmd) & _PAGE_HUGE_PAGE);
119}
120
121int pud_huge(pud_t pud)
122{
123 return !!(pud_val(pud) & _PAGE_HUGE_PAGE);
124}
125
126struct page *follow_huge_pmd(struct mm_struct *mm, unsigned long address,
127 pmd_t *pmd, int write)
128{
129 struct page *page;
130
131 page = pte_page(*(pte_t *)pmd);
132 if (page)
133 page += ((address & ~PMD_MASK) >> PAGE_SHIFT);
134 return page;
135}
136
137struct page *follow_huge_pud(struct mm_struct *mm, unsigned long address,
138 pud_t *pud, int write)
139{
140 struct page *page;
141
142 page = pte_page(*(pte_t *)pud);
143 if (page)
144 page += ((address & ~PUD_MASK) >> PAGE_SHIFT);
145 return page;
146}
147
148int huge_pmd_unshare(struct mm_struct *mm, unsigned long *addr, pte_t *ptep)
149{
150 return 0;
151}
152
153#endif
154
155#ifdef HAVE_ARCH_HUGETLB_UNMAPPED_AREA
156static unsigned long hugetlb_get_unmapped_area_bottomup(struct file *file,
157 unsigned long addr, unsigned long len,
158 unsigned long pgoff, unsigned long flags)
159{
160 struct hstate *h = hstate_file(file);
161 struct mm_struct *mm = current->mm;
162 struct vm_area_struct *vma;
163 unsigned long start_addr;
164
165 if (len > mm->cached_hole_size) {
166 start_addr = mm->free_area_cache;
167 } else {
168 start_addr = TASK_UNMAPPED_BASE;
169 mm->cached_hole_size = 0;
170 }
171
172full_search:
173 addr = ALIGN(start_addr, huge_page_size(h));
174
175 for (vma = find_vma(mm, addr); ; vma = vma->vm_next) {
176 /* At this point: (!vma || addr < vma->vm_end). */
177 if (TASK_SIZE - len < addr) {
178 /*
179 * Start a new search - just in case we missed
180 * some holes.
181 */
182 if (start_addr != TASK_UNMAPPED_BASE) {
183 start_addr = TASK_UNMAPPED_BASE;
184 mm->cached_hole_size = 0;
185 goto full_search;
186 }
187 return -ENOMEM;
188 }
189 if (!vma || addr + len <= vma->vm_start) {
190 mm->free_area_cache = addr + len;
191 return addr;
192 }
193 if (addr + mm->cached_hole_size < vma->vm_start)
194 mm->cached_hole_size = vma->vm_start - addr;
195 addr = ALIGN(vma->vm_end, huge_page_size(h));
196 }
197}
198
199static unsigned long hugetlb_get_unmapped_area_topdown(struct file *file,
200 unsigned long addr0, unsigned long len,
201 unsigned long pgoff, unsigned long flags)
202{
203 struct hstate *h = hstate_file(file);
204 struct mm_struct *mm = current->mm;
205 struct vm_area_struct *vma, *prev_vma;
206 unsigned long base = mm->mmap_base, addr = addr0;
207 unsigned long largest_hole = mm->cached_hole_size;
208 int first_time = 1;
209
210 /* don't allow allocations above current base */
211 if (mm->free_area_cache > base)
212 mm->free_area_cache = base;
213
214 if (len <= largest_hole) {
215 largest_hole = 0;
216 mm->free_area_cache = base;
217 }
218try_again:
219 /* make sure it can fit in the remaining address space */
220 if (mm->free_area_cache < len)
221 goto fail;
222
223 /* either no address requested or cant fit in requested address hole */
224 addr = (mm->free_area_cache - len) & huge_page_mask(h);
225 do {
226 /*
227 * Lookup failure means no vma is above this address,
228 * i.e. return with success:
229 */
230 vma = find_vma_prev(mm, addr, &prev_vma);
231 if (!vma) {
232 return addr;
233 break;
234 }
235
236 /*
237 * new region fits between prev_vma->vm_end and
238 * vma->vm_start, use it:
239 */
240 if (addr + len <= vma->vm_start &&
241 (!prev_vma || (addr >= prev_vma->vm_end))) {
242 /* remember the address as a hint for next time */
243 mm->cached_hole_size = largest_hole;
244 mm->free_area_cache = addr;
245 return addr;
246 } else {
247 /* pull free_area_cache down to the first hole */
248 if (mm->free_area_cache == vma->vm_end) {
249 mm->free_area_cache = vma->vm_start;
250 mm->cached_hole_size = largest_hole;
251 }
252 }
253
254 /* remember the largest hole we saw so far */
255 if (addr + largest_hole < vma->vm_start)
256 largest_hole = vma->vm_start - addr;
257
258 /* try just below the current vma->vm_start */
259 addr = (vma->vm_start - len) & huge_page_mask(h);
260
261 } while (len <= vma->vm_start);
262
263fail:
264 /*
265 * if hint left us with no space for the requested
266 * mapping then try again:
267 */
268 if (first_time) {
269 mm->free_area_cache = base;
270 largest_hole = 0;
271 first_time = 0;
272 goto try_again;
273 }
274 /*
275 * A failed mmap() very likely causes application failure,
276 * so fall back to the bottom-up function here. This scenario
277 * can happen with large stack limits and large mmap()
278 * allocations.
279 */
280 mm->free_area_cache = TASK_UNMAPPED_BASE;
281 mm->cached_hole_size = ~0UL;
282 addr = hugetlb_get_unmapped_area_bottomup(file, addr0,
283 len, pgoff, flags);
284
285 /*
286 * Restore the topdown base:
287 */
288 mm->free_area_cache = base;
289 mm->cached_hole_size = ~0UL;
290
291 return addr;
292}
293
294unsigned long hugetlb_get_unmapped_area(struct file *file, unsigned long addr,
295 unsigned long len, unsigned long pgoff, unsigned long flags)
296{
297 struct hstate *h = hstate_file(file);
298 struct mm_struct *mm = current->mm;
299 struct vm_area_struct *vma;
300
301 if (len & ~huge_page_mask(h))
302 return -EINVAL;
303 if (len > TASK_SIZE)
304 return -ENOMEM;
305
306 if (flags & MAP_FIXED) {
307 if (prepare_hugepage_range(file, addr, len))
308 return -EINVAL;
309 return addr;
310 }
311
312 if (addr) {
313 addr = ALIGN(addr, huge_page_size(h));
314 vma = find_vma(mm, addr);
315 if (TASK_SIZE - len >= addr &&
316 (!vma || addr + len <= vma->vm_start))
317 return addr;
318 }
319 if (current->mm->get_unmapped_area == arch_get_unmapped_area)
320 return hugetlb_get_unmapped_area_bottomup(file, addr, len,
321 pgoff, flags);
322 else
323 return hugetlb_get_unmapped_area_topdown(file, addr, len,
324 pgoff, flags);
325}
326
327static __init int setup_hugepagesz(char *opt)
328{
329 unsigned long ps = memparse(opt, &opt);
330 if (ps == PMD_SIZE) {
331 hugetlb_add_hstate(PMD_SHIFT - PAGE_SHIFT);
332 } else if (ps == PUD_SIZE) {
333 hugetlb_add_hstate(PUD_SHIFT - PAGE_SHIFT);
334 } else {
335 pr_err("hugepagesz: Unsupported page size %lu M\n",
336 ps >> 20);
337 return 0;
338 }
339 return 1;
340}
341__setup("hugepagesz=", setup_hugepagesz);
342
343#endif /*HAVE_ARCH_HUGETLB_UNMAPPED_AREA*/
diff --git a/arch/tile/mm/init.c b/arch/tile/mm/init.c
new file mode 100644
index 000000000000..d89c9eacd162
--- /dev/null
+++ b/arch/tile/mm/init.c
@@ -0,0 +1,1085 @@
1/*
2 * Copyright (C) 1995 Linus Torvalds
3 * Copyright 2010 Tilera Corporation. All Rights Reserved.
4 *
5 * This program is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU General Public License
7 * as published by the Free Software Foundation, version 2.
8 *
9 * This program is distributed in the hope that it will be useful, but
10 * WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, GOOD TITLE or
12 * NON INFRINGEMENT. See the GNU General Public License for
13 * more details.
14 */
15
16#include <linux/module.h>
17#include <linux/signal.h>
18#include <linux/sched.h>
19#include <linux/kernel.h>
20#include <linux/errno.h>
21#include <linux/string.h>
22#include <linux/types.h>
23#include <linux/ptrace.h>
24#include <linux/mman.h>
25#include <linux/mm.h>
26#include <linux/hugetlb.h>
27#include <linux/swap.h>
28#include <linux/smp.h>
29#include <linux/init.h>
30#include <linux/highmem.h>
31#include <linux/pagemap.h>
32#include <linux/poison.h>
33#include <linux/bootmem.h>
34#include <linux/slab.h>
35#include <linux/proc_fs.h>
36#include <linux/efi.h>
37#include <linux/memory_hotplug.h>
38#include <linux/uaccess.h>
39#include <asm/mmu_context.h>
40#include <asm/processor.h>
41#include <asm/system.h>
42#include <asm/pgtable.h>
43#include <asm/pgalloc.h>
44#include <asm/dma.h>
45#include <asm/fixmap.h>
46#include <asm/tlb.h>
47#include <asm/tlbflush.h>
48#include <asm/sections.h>
49#include <asm/setup.h>
50#include <asm/homecache.h>
51#include <hv/hypervisor.h>
52#include <arch/chip.h>
53
54#include "migrate.h"
55
56/*
57 * We could set FORCE_MAX_ZONEORDER to "(HPAGE_SHIFT - PAGE_SHIFT + 1)"
58 * in the Tile Kconfig, but this generates configure warnings.
59 * Do it here and force people to get it right to compile this file.
60 * The problem is that with 4KB small pages and 16MB huge pages,
61 * the default value doesn't allow us to group enough small pages
62 * together to make up a huge page.
63 */
64#if CONFIG_FORCE_MAX_ZONEORDER < HPAGE_SHIFT - PAGE_SHIFT + 1
65# error "Change FORCE_MAX_ZONEORDER in arch/tile/Kconfig to match page size"
66#endif
67
68#define clear_pgd(pmdptr) (*(pmdptr) = hv_pte(0))
69
70#ifndef __tilegx__
71unsigned long VMALLOC_RESERVE = CONFIG_VMALLOC_RESERVE;
72#endif
73
74DEFINE_PER_CPU(struct mmu_gather, mmu_gathers);
75
76/* Create an L2 page table */
77static pte_t * __init alloc_pte(void)
78{
79 return __alloc_bootmem(L2_KERNEL_PGTABLE_SIZE, HV_PAGE_TABLE_ALIGN, 0);
80}
81
82/*
83 * L2 page tables per controller. We allocate these all at once from
84 * the bootmem allocator and store them here. This saves on kernel L2
85 * page table memory, compared to allocating a full 64K page per L2
86 * page table, and also means that in cases where we use huge pages,
87 * we are guaranteed to later be able to shatter those huge pages and
88 * switch to using these page tables instead, without requiring
89 * further allocation. Each l2_ptes[] entry points to the first page
90 * table for the first hugepage-size piece of memory on the
91 * controller; other page tables are just indexed directly, i.e. the
92 * L2 page tables are contiguous in memory for each controller.
93 */
94static pte_t *l2_ptes[MAX_NUMNODES];
95static int num_l2_ptes[MAX_NUMNODES];
96
97static void init_prealloc_ptes(int node, int pages)
98{
99 BUG_ON(pages & (HV_L2_ENTRIES-1));
100 if (pages) {
101 num_l2_ptes[node] = pages;
102 l2_ptes[node] = __alloc_bootmem(pages * sizeof(pte_t),
103 HV_PAGE_TABLE_ALIGN, 0);
104 }
105}
106
107pte_t *get_prealloc_pte(unsigned long pfn)
108{
109 int node = pfn_to_nid(pfn);
110 pfn &= ~(-1UL << (NR_PA_HIGHBIT_SHIFT - PAGE_SHIFT));
111 BUG_ON(node >= MAX_NUMNODES);
112 BUG_ON(pfn >= num_l2_ptes[node]);
113 return &l2_ptes[node][pfn];
114}
115
116/*
117 * What caching do we expect pages from the heap to have when
118 * they are allocated during bootup? (Once we've installed the
119 * "real" swapper_pg_dir.)
120 */
121static int initial_heap_home(void)
122{
123#if CHIP_HAS_CBOX_HOME_MAP()
124 if (hash_default)
125 return PAGE_HOME_HASH;
126#endif
127 return smp_processor_id();
128}
129
130/*
131 * Place a pointer to an L2 page table in a middle page
132 * directory entry.
133 */
134static void __init assign_pte(pmd_t *pmd, pte_t *page_table)
135{
136 phys_addr_t pa = __pa(page_table);
137 unsigned long l2_ptfn = pa >> HV_LOG2_PAGE_TABLE_ALIGN;
138 pte_t pteval = hv_pte_set_ptfn(__pgprot(_PAGE_TABLE), l2_ptfn);
139 BUG_ON((pa & (HV_PAGE_TABLE_ALIGN-1)) != 0);
140 pteval = pte_set_home(pteval, initial_heap_home());
141 *(pte_t *)pmd = pteval;
142 if (page_table != (pte_t *)pmd_page_vaddr(*pmd))
143 BUG();
144}
145
146#ifdef __tilegx__
147
148#if HV_L1_SIZE != HV_L2_SIZE
149# error Rework assumption that L1 and L2 page tables are same size.
150#endif
151
152/* Since pmd_t arrays and pte_t arrays are the same size, just use casts. */
153static inline pmd_t *alloc_pmd(void)
154{
155 return (pmd_t *)alloc_pte();
156}
157
158static inline void assign_pmd(pud_t *pud, pmd_t *pmd)
159{
160 assign_pte((pmd_t *)pud, (pte_t *)pmd);
161}
162
163#endif /* __tilegx__ */
164
165/* Replace the given pmd with a full PTE table. */
166void __init shatter_pmd(pmd_t *pmd)
167{
168 pte_t *pte = get_prealloc_pte(pte_pfn(*(pte_t *)pmd));
169 assign_pte(pmd, pte);
170}
171
172#ifdef CONFIG_HIGHMEM
173/*
174 * This function initializes a certain range of kernel virtual memory
175 * with new bootmem page tables, everywhere page tables are missing in
176 * the given range.
177 */
178
179/*
180 * NOTE: The pagetables are allocated contiguous on the physical space
181 * so we can cache the place of the first one and move around without
182 * checking the pgd every time.
183 */
184static void __init page_table_range_init(unsigned long start,
185 unsigned long end, pgd_t *pgd_base)
186{
187 pgd_t *pgd;
188 int pgd_idx;
189 unsigned long vaddr;
190
191 vaddr = start;
192 pgd_idx = pgd_index(vaddr);
193 pgd = pgd_base + pgd_idx;
194
195 for ( ; (pgd_idx < PTRS_PER_PGD) && (vaddr != end); pgd++, pgd_idx++) {
196 pmd_t *pmd = pmd_offset(pud_offset(pgd, vaddr), vaddr);
197 if (pmd_none(*pmd))
198 assign_pte(pmd, alloc_pte());
199 vaddr += PMD_SIZE;
200 }
201}
202#endif /* CONFIG_HIGHMEM */
203
204
205#if CHIP_HAS_CBOX_HOME_MAP()
206
207static int __initdata ktext_hash = 1; /* .text pages */
208static int __initdata kdata_hash = 1; /* .data and .bss pages */
209int __write_once hash_default = 1; /* kernel allocator pages */
210EXPORT_SYMBOL(hash_default);
211int __write_once kstack_hash = 1; /* if no homecaching, use h4h */
212#endif /* CHIP_HAS_CBOX_HOME_MAP */
213
214/*
215 * CPUs to use to for striping the pages of kernel data. If hash-for-home
216 * is available, this is only relevant if kcache_hash sets up the
217 * .data and .bss to be page-homed, and we don't want the default mode
218 * of using the full set of kernel cpus for the striping.
219 */
220static __initdata struct cpumask kdata_mask;
221static __initdata int kdata_arg_seen;
222
223int __write_once kdata_huge; /* if no homecaching, small pages */
224
225
226/* Combine a generic pgprot_t with cache home to get a cache-aware pgprot. */
227static pgprot_t __init construct_pgprot(pgprot_t prot, int home)
228{
229 prot = pte_set_home(prot, home);
230#if CHIP_HAS_CBOX_HOME_MAP()
231 if (home == PAGE_HOME_IMMUTABLE) {
232 if (ktext_hash)
233 prot = hv_pte_set_mode(prot, HV_PTE_MODE_CACHE_HASH_L3);
234 else
235 prot = hv_pte_set_mode(prot, HV_PTE_MODE_CACHE_NO_L3);
236 }
237#endif
238 return prot;
239}
240
241/*
242 * For a given kernel data VA, how should it be cached?
243 * We return the complete pgprot_t with caching bits set.
244 */
245static pgprot_t __init init_pgprot(ulong address)
246{
247 int cpu;
248 unsigned long page;
249 enum { CODE_DELTA = MEM_SV_INTRPT - PAGE_OFFSET };
250
251#if CHIP_HAS_CBOX_HOME_MAP()
252 /* For kdata=huge, everything is just hash-for-home. */
253 if (kdata_huge)
254 return construct_pgprot(PAGE_KERNEL, PAGE_HOME_HASH);
255#endif
256
257 /* We map the aliased pages of permanent text inaccessible. */
258 if (address < (ulong) _sinittext - CODE_DELTA)
259 return PAGE_NONE;
260
261 /*
262 * We map read-only data non-coherent for performance. We could
263 * use neighborhood caching on TILE64, but it's not clear it's a win.
264 */
265 if ((address >= (ulong) __start_rodata &&
266 address < (ulong) __end_rodata) ||
267 address == (ulong) empty_zero_page) {
268 return construct_pgprot(PAGE_KERNEL_RO, PAGE_HOME_IMMUTABLE);
269 }
270
271 /* As a performance optimization, keep the boot init stack here. */
272 if (address >= (ulong)&init_thread_union &&
273 address < (ulong)&init_thread_union + THREAD_SIZE)
274 return construct_pgprot(PAGE_KERNEL, smp_processor_id());
275
276#ifndef __tilegx__
277#if !ATOMIC_LOCKS_FOUND_VIA_TABLE()
278 /* Force the atomic_locks[] array page to be hash-for-home. */
279 if (address == (ulong) atomic_locks)
280 return construct_pgprot(PAGE_KERNEL, PAGE_HOME_HASH);
281#endif
282#endif
283
284 /*
285 * Everything else that isn't data or bss is heap, so mark it
286 * with the initial heap home (hash-for-home, or this cpu). This
287 * includes any addresses after the loaded image and any address before
288 * _einitdata, since we already captured the case of text before
289 * _sinittext, and __pa(einittext) is approximately __pa(sinitdata).
290 *
291 * All the LOWMEM pages that we mark this way will get their
292 * struct page homecache properly marked later, in set_page_homes().
293 * The HIGHMEM pages we leave with a default zero for their
294 * homes, but with a zero free_time we don't have to actually
295 * do a flush action the first time we use them, either.
296 */
297 if (address >= (ulong) _end || address < (ulong) _einitdata)
298 return construct_pgprot(PAGE_KERNEL, initial_heap_home());
299
300#if CHIP_HAS_CBOX_HOME_MAP()
301 /* Use hash-for-home if requested for data/bss. */
302 if (kdata_hash)
303 return construct_pgprot(PAGE_KERNEL, PAGE_HOME_HASH);
304#endif
305
306 /*
307 * Make the w1data homed like heap to start with, to avoid
308 * making it part of the page-striped data area when we're just
309 * going to convert it to read-only soon anyway.
310 */
311 if (address >= (ulong)__w1data_begin && address < (ulong)__w1data_end)
312 return construct_pgprot(PAGE_KERNEL, initial_heap_home());
313
314 /*
315 * Otherwise we just hand out consecutive cpus. To avoid
316 * requiring this function to hold state, we just walk forward from
317 * _sdata by PAGE_SIZE, skipping the readonly and init data, to reach
318 * the requested address, while walking cpu home around kdata_mask.
319 * This is typically no more than a dozen or so iterations.
320 */
321 page = (((ulong)__w1data_end) + PAGE_SIZE - 1) & PAGE_MASK;
322 BUG_ON(address < page || address >= (ulong)_end);
323 cpu = cpumask_first(&kdata_mask);
324 for (; page < address; page += PAGE_SIZE) {
325 if (page >= (ulong)&init_thread_union &&
326 page < (ulong)&init_thread_union + THREAD_SIZE)
327 continue;
328 if (page == (ulong)empty_zero_page)
329 continue;
330#ifndef __tilegx__
331#if !ATOMIC_LOCKS_FOUND_VIA_TABLE()
332 if (page == (ulong)atomic_locks)
333 continue;
334#endif
335#endif
336 cpu = cpumask_next(cpu, &kdata_mask);
337 if (cpu == NR_CPUS)
338 cpu = cpumask_first(&kdata_mask);
339 }
340 return construct_pgprot(PAGE_KERNEL, cpu);
341}
342
343/*
344 * This function sets up how we cache the kernel text. If we have
345 * hash-for-home support, normally that is used instead (see the
346 * kcache_hash boot flag for more information). But if we end up
347 * using a page-based caching technique, this option sets up the
348 * details of that. In addition, the "ktext=nocache" option may
349 * always be used to disable local caching of text pages, if desired.
350 */
351
352static int __initdata ktext_arg_seen;
353static int __initdata ktext_small;
354static int __initdata ktext_local;
355static int __initdata ktext_all;
356static int __initdata ktext_nondataplane;
357static int __initdata ktext_nocache;
358static struct cpumask __initdata ktext_mask;
359
360static int __init setup_ktext(char *str)
361{
362 if (str == NULL)
363 return -EINVAL;
364
365 /* If you have a leading "nocache", turn off ktext caching */
366 if (strncmp(str, "nocache", 7) == 0) {
367 ktext_nocache = 1;
368 pr_info("ktext: disabling local caching of kernel text\n");
369 str += 7;
370 if (*str == ',')
371 ++str;
372 if (*str == '\0')
373 return 0;
374 }
375
376 ktext_arg_seen = 1;
377
378 /* Default setting on Tile64: use a huge page */
379 if (strcmp(str, "huge") == 0)
380 pr_info("ktext: using one huge locally cached page\n");
381
382 /* Pay TLB cost but get no cache benefit: cache small pages locally */
383 else if (strcmp(str, "local") == 0) {
384 ktext_small = 1;
385 ktext_local = 1;
386 pr_info("ktext: using small pages with local caching\n");
387 }
388
389 /* Neighborhood cache ktext pages on all cpus. */
390 else if (strcmp(str, "all") == 0) {
391 ktext_small = 1;
392 ktext_all = 1;
393 pr_info("ktext: using maximal caching neighborhood\n");
394 }
395
396
397 /* Neighborhood ktext pages on specified mask */
398 else if (cpulist_parse(str, &ktext_mask) == 0) {
399 char buf[NR_CPUS * 5];
400 cpulist_scnprintf(buf, sizeof(buf), &ktext_mask);
401 if (cpumask_weight(&ktext_mask) > 1) {
402 ktext_small = 1;
403 pr_info("ktext: using caching neighborhood %s "
404 "with small pages\n", buf);
405 } else {
406 pr_info("ktext: caching on cpu %s with one huge page\n",
407 buf);
408 }
409 }
410
411 else if (*str)
412 return -EINVAL;
413
414 return 0;
415}
416
417early_param("ktext", setup_ktext);
418
419
420static inline pgprot_t ktext_set_nocache(pgprot_t prot)
421{
422 if (!ktext_nocache)
423 prot = hv_pte_set_nc(prot);
424#if CHIP_HAS_NC_AND_NOALLOC_BITS()
425 else
426 prot = hv_pte_set_no_alloc_l2(prot);
427#endif
428 return prot;
429}
430
431#ifndef __tilegx__
432static pmd_t *__init get_pmd(pgd_t pgtables[], unsigned long va)
433{
434 return pmd_offset(pud_offset(&pgtables[pgd_index(va)], va), va);
435}
436#else
437static pmd_t *__init get_pmd(pgd_t pgtables[], unsigned long va)
438{
439 pud_t *pud = pud_offset(&pgtables[pgd_index(va)], va);
440 if (pud_none(*pud))
441 assign_pmd(pud, alloc_pmd());
442 return pmd_offset(pud, va);
443}
444#endif
445
446/* Temporary page table we use for staging. */
447static pgd_t pgtables[PTRS_PER_PGD]
448 __attribute__((section(".init.page")));
449
450/*
451 * This maps the physical memory to kernel virtual address space, a total
452 * of max_low_pfn pages, by creating page tables starting from address
453 * PAGE_OFFSET.
454 *
455 * This routine transitions us from using a set of compiled-in large
456 * pages to using some more precise caching, including removing access
457 * to code pages mapped at PAGE_OFFSET (executed only at MEM_SV_START)
458 * marking read-only data as locally cacheable, striping the remaining
459 * .data and .bss across all the available tiles, and removing access
460 * to pages above the top of RAM (thus ensuring a page fault from a bad
461 * virtual address rather than a hypervisor shoot down for accessing
462 * memory outside the assigned limits).
463 */
464static void __init kernel_physical_mapping_init(pgd_t *pgd_base)
465{
466 unsigned long address, pfn;
467 pmd_t *pmd;
468 pte_t *pte;
469 int pte_ofs;
470 const struct cpumask *my_cpu_mask = cpumask_of(smp_processor_id());
471 struct cpumask kstripe_mask;
472 int rc, i;
473
474#if CHIP_HAS_CBOX_HOME_MAP()
475 if (ktext_arg_seen && ktext_hash) {
476 pr_warning("warning: \"ktext\" boot argument ignored"
477 " if \"kcache_hash\" sets up text hash-for-home\n");
478 ktext_small = 0;
479 }
480
481 if (kdata_arg_seen && kdata_hash) {
482 pr_warning("warning: \"kdata\" boot argument ignored"
483 " if \"kcache_hash\" sets up data hash-for-home\n");
484 }
485
486 if (kdata_huge && !hash_default) {
487 pr_warning("warning: disabling \"kdata=huge\"; requires"
488 " kcache_hash=all or =allbutstack\n");
489 kdata_huge = 0;
490 }
491#endif
492
493 /*
494 * Set up a mask for cpus to use for kernel striping.
495 * This is normally all cpus, but minus dataplane cpus if any.
496 * If the dataplane covers the whole chip, we stripe over
497 * the whole chip too.
498 */
499 cpumask_copy(&kstripe_mask, cpu_possible_mask);
500 if (!kdata_arg_seen)
501 kdata_mask = kstripe_mask;
502
503 /* Allocate and fill in L2 page tables */
504 for (i = 0; i < MAX_NUMNODES; ++i) {
505#ifdef CONFIG_HIGHMEM
506 unsigned long end_pfn = node_lowmem_end_pfn[i];
507#else
508 unsigned long end_pfn = node_end_pfn[i];
509#endif
510 unsigned long end_huge_pfn = 0;
511
512 /* Pre-shatter the last huge page to allow per-cpu pages. */
513 if (kdata_huge)
514 end_huge_pfn = end_pfn - (HPAGE_SIZE >> PAGE_SHIFT);
515
516 pfn = node_start_pfn[i];
517
518 /* Allocate enough memory to hold L2 page tables for node. */
519 init_prealloc_ptes(i, end_pfn - pfn);
520
521 address = (unsigned long) pfn_to_kaddr(pfn);
522 while (pfn < end_pfn) {
523 BUG_ON(address & (HPAGE_SIZE-1));
524 pmd = get_pmd(pgtables, address);
525 pte = get_prealloc_pte(pfn);
526 if (pfn < end_huge_pfn) {
527 pgprot_t prot = init_pgprot(address);
528 *(pte_t *)pmd = pte_mkhuge(pfn_pte(pfn, prot));
529 for (pte_ofs = 0; pte_ofs < PTRS_PER_PTE;
530 pfn++, pte_ofs++, address += PAGE_SIZE)
531 pte[pte_ofs] = pfn_pte(pfn, prot);
532 } else {
533 if (kdata_huge)
534 printk(KERN_DEBUG "pre-shattered huge"
535 " page at %#lx\n", address);
536 for (pte_ofs = 0; pte_ofs < PTRS_PER_PTE;
537 pfn++, pte_ofs++, address += PAGE_SIZE) {
538 pgprot_t prot = init_pgprot(address);
539 pte[pte_ofs] = pfn_pte(pfn, prot);
540 }
541 assign_pte(pmd, pte);
542 }
543 }
544 }
545
546 /*
547 * Set or check ktext_map now that we have cpu_possible_mask
548 * and kstripe_mask to work with.
549 */
550 if (ktext_all)
551 cpumask_copy(&ktext_mask, cpu_possible_mask);
552 else if (ktext_nondataplane)
553 ktext_mask = kstripe_mask;
554 else if (!cpumask_empty(&ktext_mask)) {
555 /* Sanity-check any mask that was requested */
556 struct cpumask bad;
557 cpumask_andnot(&bad, &ktext_mask, cpu_possible_mask);
558 cpumask_and(&ktext_mask, &ktext_mask, cpu_possible_mask);
559 if (!cpumask_empty(&bad)) {
560 char buf[NR_CPUS * 5];
561 cpulist_scnprintf(buf, sizeof(buf), &bad);
562 pr_info("ktext: not using unavailable cpus %s\n", buf);
563 }
564 if (cpumask_empty(&ktext_mask)) {
565 pr_warning("ktext: no valid cpus; caching on %d.\n",
566 smp_processor_id());
567 cpumask_copy(&ktext_mask,
568 cpumask_of(smp_processor_id()));
569 }
570 }
571
572 address = MEM_SV_INTRPT;
573 pmd = get_pmd(pgtables, address);
574 if (ktext_small) {
575 /* Allocate an L2 PTE for the kernel text */
576 int cpu = 0;
577 pgprot_t prot = construct_pgprot(PAGE_KERNEL_EXEC,
578 PAGE_HOME_IMMUTABLE);
579
580 if (ktext_local) {
581 if (ktext_nocache)
582 prot = hv_pte_set_mode(prot,
583 HV_PTE_MODE_UNCACHED);
584 else
585 prot = hv_pte_set_mode(prot,
586 HV_PTE_MODE_CACHE_NO_L3);
587 } else {
588 prot = hv_pte_set_mode(prot,
589 HV_PTE_MODE_CACHE_TILE_L3);
590 cpu = cpumask_first(&ktext_mask);
591
592 prot = ktext_set_nocache(prot);
593 }
594
595 BUG_ON(address != (unsigned long)_stext);
596 pfn = 0; /* code starts at PA 0 */
597 pte = alloc_pte();
598 for (pte_ofs = 0; address < (unsigned long)_einittext;
599 pfn++, pte_ofs++, address += PAGE_SIZE) {
600 if (!ktext_local) {
601 prot = set_remote_cache_cpu(prot, cpu);
602 cpu = cpumask_next(cpu, &ktext_mask);
603 if (cpu == NR_CPUS)
604 cpu = cpumask_first(&ktext_mask);
605 }
606 pte[pte_ofs] = pfn_pte(pfn, prot);
607 }
608 assign_pte(pmd, pte);
609 } else {
610 pte_t pteval = pfn_pte(0, PAGE_KERNEL_EXEC);
611 pteval = pte_mkhuge(pteval);
612#if CHIP_HAS_CBOX_HOME_MAP()
613 if (ktext_hash) {
614 pteval = hv_pte_set_mode(pteval,
615 HV_PTE_MODE_CACHE_HASH_L3);
616 pteval = ktext_set_nocache(pteval);
617 } else
618#endif /* CHIP_HAS_CBOX_HOME_MAP() */
619 if (cpumask_weight(&ktext_mask) == 1) {
620 pteval = set_remote_cache_cpu(pteval,
621 cpumask_first(&ktext_mask));
622 pteval = hv_pte_set_mode(pteval,
623 HV_PTE_MODE_CACHE_TILE_L3);
624 pteval = ktext_set_nocache(pteval);
625 } else if (ktext_nocache)
626 pteval = hv_pte_set_mode(pteval,
627 HV_PTE_MODE_UNCACHED);
628 else
629 pteval = hv_pte_set_mode(pteval,
630 HV_PTE_MODE_CACHE_NO_L3);
631 *(pte_t *)pmd = pteval;
632 }
633
634 /* Set swapper_pgprot here so it is flushed to memory right away. */
635 swapper_pgprot = init_pgprot((unsigned long)swapper_pg_dir);
636
637 /*
638 * Since we may be changing the caching of the stack and page
639 * table itself, we invoke an assembly helper to do the
640 * following steps:
641 *
642 * - flush the cache so we start with an empty slate
643 * - install pgtables[] as the real page table
644 * - flush the TLB so the new page table takes effect
645 */
646 rc = flush_and_install_context(__pa(pgtables),
647 init_pgprot((unsigned long)pgtables),
648 __get_cpu_var(current_asid),
649 cpumask_bits(my_cpu_mask));
650 BUG_ON(rc != 0);
651
652 /* Copy the page table back to the normal swapper_pg_dir. */
653 memcpy(pgd_base, pgtables, sizeof(pgtables));
654 __install_page_table(pgd_base, __get_cpu_var(current_asid),
655 swapper_pgprot);
656}
657
658/*
659 * devmem_is_allowed() checks to see if /dev/mem access to a certain address
660 * is valid. The argument is a physical page number.
661 *
662 * On Tile, the only valid things for which we can just hand out unchecked
663 * PTEs are the kernel code and data. Anything else might change its
664 * homing with time, and we wouldn't know to adjust the /dev/mem PTEs.
665 * Note that init_thread_union is released to heap soon after boot,
666 * so we include it in the init data.
667 *
668 * For TILE-Gx, we might want to consider allowing access to PA
669 * regions corresponding to PCI space, etc.
670 */
671int devmem_is_allowed(unsigned long pagenr)
672{
673 return pagenr < kaddr_to_pfn(_end) &&
674 !(pagenr >= kaddr_to_pfn(&init_thread_union) ||
675 pagenr < kaddr_to_pfn(_einitdata)) &&
676 !(pagenr >= kaddr_to_pfn(_sinittext) ||
677 pagenr <= kaddr_to_pfn(_einittext-1));
678}
679
680#ifdef CONFIG_HIGHMEM
681static void __init permanent_kmaps_init(pgd_t *pgd_base)
682{
683 pgd_t *pgd;
684 pud_t *pud;
685 pmd_t *pmd;
686 pte_t *pte;
687 unsigned long vaddr;
688
689 vaddr = PKMAP_BASE;
690 page_table_range_init(vaddr, vaddr + PAGE_SIZE*LAST_PKMAP, pgd_base);
691
692 pgd = swapper_pg_dir + pgd_index(vaddr);
693 pud = pud_offset(pgd, vaddr);
694 pmd = pmd_offset(pud, vaddr);
695 pte = pte_offset_kernel(pmd, vaddr);
696 pkmap_page_table = pte;
697}
698#endif /* CONFIG_HIGHMEM */
699
700
701static void __init init_free_pfn_range(unsigned long start, unsigned long end)
702{
703 unsigned long pfn;
704 struct page *page = pfn_to_page(start);
705
706 for (pfn = start; pfn < end; ) {
707 /* Optimize by freeing pages in large batches */
708 int order = __ffs(pfn);
709 int count, i;
710 struct page *p;
711
712 if (order >= MAX_ORDER)
713 order = MAX_ORDER-1;
714 count = 1 << order;
715 while (pfn + count > end) {
716 count >>= 1;
717 --order;
718 }
719 for (p = page, i = 0; i < count; ++i, ++p) {
720 __ClearPageReserved(p);
721 /*
722 * Hacky direct set to avoid unnecessary
723 * lock take/release for EVERY page here.
724 */
725 p->_count.counter = 0;
726 p->_mapcount.counter = -1;
727 }
728 init_page_count(page);
729 __free_pages(page, order);
730 totalram_pages += count;
731
732 page += count;
733 pfn += count;
734 }
735}
736
737static void __init set_non_bootmem_pages_init(void)
738{
739 struct zone *z;
740 for_each_zone(z) {
741 unsigned long start, end;
742 int nid = z->zone_pgdat->node_id;
743 int idx = zone_idx(z);
744
745 start = z->zone_start_pfn;
746 if (start == 0)
747 continue; /* bootmem */
748 end = start + z->spanned_pages;
749 if (idx == ZONE_NORMAL) {
750 BUG_ON(start != node_start_pfn[nid]);
751 start = node_free_pfn[nid];
752 }
753#ifdef CONFIG_HIGHMEM
754 if (idx == ZONE_HIGHMEM)
755 totalhigh_pages += z->spanned_pages;
756#endif
757 if (kdata_huge) {
758 unsigned long percpu_pfn = node_percpu_pfn[nid];
759 if (start < percpu_pfn && end > percpu_pfn)
760 end = percpu_pfn;
761 }
762#ifdef CONFIG_PCI
763 if (start <= pci_reserve_start_pfn &&
764 end > pci_reserve_start_pfn) {
765 if (end > pci_reserve_end_pfn)
766 init_free_pfn_range(pci_reserve_end_pfn, end);
767 end = pci_reserve_start_pfn;
768 }
769#endif
770 init_free_pfn_range(start, end);
771 }
772}
773
774/*
775 * paging_init() sets up the page tables - note that all of lowmem is
776 * already mapped by head.S.
777 */
778void __init paging_init(void)
779{
780#ifdef CONFIG_HIGHMEM
781 unsigned long vaddr, end;
782#endif
783#ifdef __tilegx__
784 pud_t *pud;
785#endif
786 pgd_t *pgd_base = swapper_pg_dir;
787
788 kernel_physical_mapping_init(pgd_base);
789
790#ifdef CONFIG_HIGHMEM
791 /*
792 * Fixed mappings, only the page table structure has to be
793 * created - mappings will be set by set_fixmap():
794 */
795 vaddr = __fix_to_virt(__end_of_fixed_addresses - 1) & PMD_MASK;
796 end = (FIXADDR_TOP + PMD_SIZE - 1) & PMD_MASK;
797 page_table_range_init(vaddr, end, pgd_base);
798 permanent_kmaps_init(pgd_base);
799#endif
800
801#ifdef __tilegx__
802 /*
803 * Since GX allocates just one pmd_t array worth of vmalloc space,
804 * we go ahead and allocate it statically here, then share it
805 * globally. As a result we don't have to worry about any task
806 * changing init_mm once we get up and running, and there's no
807 * need for e.g. vmalloc_sync_all().
808 */
809 BUILD_BUG_ON(pgd_index(VMALLOC_START) != pgd_index(VMALLOC_END));
810 pud = pud_offset(pgd_base + pgd_index(VMALLOC_START), VMALLOC_START);
811 assign_pmd(pud, alloc_pmd());
812#endif
813}
814
815
816/*
817 * Walk the kernel page tables and derive the page_home() from
818 * the PTEs, so that set_pte() can properly validate the caching
819 * of all PTEs it sees.
820 */
821void __init set_page_homes(void)
822{
823}
824
825static void __init set_max_mapnr_init(void)
826{
827#ifdef CONFIG_FLATMEM
828 max_mapnr = max_low_pfn;
829#endif
830}
831
832void __init mem_init(void)
833{
834 int codesize, datasize, initsize;
835 int i;
836#ifndef __tilegx__
837 void *last;
838#endif
839
840#ifdef CONFIG_FLATMEM
841 if (!mem_map)
842 BUG();
843#endif
844
845#ifdef CONFIG_HIGHMEM
846 /* check that fixmap and pkmap do not overlap */
847 if (PKMAP_ADDR(LAST_PKMAP-1) >= FIXADDR_START) {
848 pr_err("fixmap and kmap areas overlap"
849 " - this will crash\n");
850 pr_err("pkstart: %lxh pkend: %lxh fixstart %lxh\n",
851 PKMAP_BASE, PKMAP_ADDR(LAST_PKMAP-1),
852 FIXADDR_START);
853 BUG();
854 }
855#endif
856
857 set_max_mapnr_init();
858
859 /* this will put all bootmem onto the freelists */
860 totalram_pages += free_all_bootmem();
861
862 /* count all remaining LOWMEM and give all HIGHMEM to page allocator */
863 set_non_bootmem_pages_init();
864
865 codesize = (unsigned long)&_etext - (unsigned long)&_text;
866 datasize = (unsigned long)&_end - (unsigned long)&_sdata;
867 initsize = (unsigned long)&_einittext - (unsigned long)&_sinittext;
868 initsize += (unsigned long)&_einitdata - (unsigned long)&_sinitdata;
869
870 pr_info("Memory: %luk/%luk available (%dk kernel code, %dk data, %dk init, %ldk highmem)\n",
871 (unsigned long) nr_free_pages() << (PAGE_SHIFT-10),
872 num_physpages << (PAGE_SHIFT-10),
873 codesize >> 10,
874 datasize >> 10,
875 initsize >> 10,
876 (unsigned long) (totalhigh_pages << (PAGE_SHIFT-10))
877 );
878
879 /*
880 * In debug mode, dump some interesting memory mappings.
881 */
882#ifdef CONFIG_HIGHMEM
883 printk(KERN_DEBUG " KMAP %#lx - %#lx\n",
884 FIXADDR_START, FIXADDR_TOP + PAGE_SIZE - 1);
885 printk(KERN_DEBUG " PKMAP %#lx - %#lx\n",
886 PKMAP_BASE, PKMAP_ADDR(LAST_PKMAP) - 1);
887#endif
888#ifdef CONFIG_HUGEVMAP
889 printk(KERN_DEBUG " HUGEMAP %#lx - %#lx\n",
890 HUGE_VMAP_BASE, HUGE_VMAP_END - 1);
891#endif
892 printk(KERN_DEBUG " VMALLOC %#lx - %#lx\n",
893 _VMALLOC_START, _VMALLOC_END - 1);
894#ifdef __tilegx__
895 for (i = MAX_NUMNODES-1; i >= 0; --i) {
896 struct pglist_data *node = &node_data[i];
897 if (node->node_present_pages) {
898 unsigned long start = (unsigned long)
899 pfn_to_kaddr(node->node_start_pfn);
900 unsigned long end = start +
901 (node->node_present_pages << PAGE_SHIFT);
902 printk(KERN_DEBUG " MEM%d %#lx - %#lx\n",
903 i, start, end - 1);
904 }
905 }
906#else
907 last = high_memory;
908 for (i = MAX_NUMNODES-1; i >= 0; --i) {
909 if ((unsigned long)vbase_map[i] != -1UL) {
910 printk(KERN_DEBUG " LOWMEM%d %#lx - %#lx\n",
911 i, (unsigned long) (vbase_map[i]),
912 (unsigned long) (last-1));
913 last = vbase_map[i];
914 }
915 }
916#endif
917
918#ifndef __tilegx__
919 /*
920 * Convert from using one lock for all atomic operations to
921 * one per cpu.
922 */
923 __init_atomic_per_cpu();
924#endif
925}
926
927/*
928 * this is for the non-NUMA, single node SMP system case.
929 * Specifically, in the case of x86, we will always add
930 * memory to the highmem for now.
931 */
932#ifndef CONFIG_NEED_MULTIPLE_NODES
933int arch_add_memory(u64 start, u64 size)
934{
935 struct pglist_data *pgdata = &contig_page_data;
936 struct zone *zone = pgdata->node_zones + MAX_NR_ZONES-1;
937 unsigned long start_pfn = start >> PAGE_SHIFT;
938 unsigned long nr_pages = size >> PAGE_SHIFT;
939
940 return __add_pages(zone, start_pfn, nr_pages);
941}
942
943int remove_memory(u64 start, u64 size)
944{
945 return -EINVAL;
946}
947#endif
948
949struct kmem_cache *pgd_cache;
950
951void __init pgtable_cache_init(void)
952{
953 pgd_cache = kmem_cache_create("pgd",
954 PTRS_PER_PGD*sizeof(pgd_t),
955 PTRS_PER_PGD*sizeof(pgd_t),
956 0,
957 NULL);
958 if (!pgd_cache)
959 panic("pgtable_cache_init(): Cannot create pgd cache");
960}
961
962#if !CHIP_HAS_COHERENT_LOCAL_CACHE()
963/*
964 * The __w1data area holds data that is only written during initialization,
965 * and is read-only and thus freely cacheable thereafter. Fix the page
966 * table entries that cover that region accordingly.
967 */
968static void mark_w1data_ro(void)
969{
970 /* Loop over page table entries */
971 unsigned long addr = (unsigned long)__w1data_begin;
972 BUG_ON((addr & (PAGE_SIZE-1)) != 0);
973 for (; addr <= (unsigned long)__w1data_end - 1; addr += PAGE_SIZE) {
974 unsigned long pfn = kaddr_to_pfn((void *)addr);
975 pte_t *ptep = virt_to_pte(NULL, addr);
976 BUG_ON(pte_huge(*ptep)); /* not relevant for kdata_huge */
977 set_pte_at(&init_mm, addr, ptep, pfn_pte(pfn, PAGE_KERNEL_RO));
978 }
979}
980#endif
981
982#ifdef CONFIG_DEBUG_PAGEALLOC
983static long __write_once initfree;
984#else
985static long __write_once initfree = 1;
986#endif
987
988/* Select whether to free (1) or mark unusable (0) the __init pages. */
989static int __init set_initfree(char *str)
990{
991 strict_strtol(str, 0, &initfree);
992 pr_info("initfree: %s free init pages\n", initfree ? "will" : "won't");
993 return 1;
994}
995__setup("initfree=", set_initfree);
996
997static void free_init_pages(char *what, unsigned long begin, unsigned long end)
998{
999 unsigned long addr = (unsigned long) begin;
1000
1001 if (kdata_huge && !initfree) {
1002 pr_warning("Warning: ignoring initfree=0:"
1003 " incompatible with kdata=huge\n");
1004 initfree = 1;
1005 }
1006 end = (end + PAGE_SIZE - 1) & PAGE_MASK;
1007 local_flush_tlb_pages(NULL, begin, PAGE_SIZE, end - begin);
1008 for (addr = begin; addr < end; addr += PAGE_SIZE) {
1009 /*
1010 * Note we just reset the home here directly in the
1011 * page table. We know this is safe because our caller
1012 * just flushed the caches on all the other cpus,
1013 * and they won't be touching any of these pages.
1014 */
1015 int pfn = kaddr_to_pfn((void *)addr);
1016 struct page *page = pfn_to_page(pfn);
1017 pte_t *ptep = virt_to_pte(NULL, addr);
1018 if (!initfree) {
1019 /*
1020 * If debugging page accesses then do not free
1021 * this memory but mark them not present - any
1022 * buggy init-section access will create a
1023 * kernel page fault:
1024 */
1025 pte_clear(&init_mm, addr, ptep);
1026 continue;
1027 }
1028 __ClearPageReserved(page);
1029 init_page_count(page);
1030 if (pte_huge(*ptep))
1031 BUG_ON(!kdata_huge);
1032 else
1033 set_pte_at(&init_mm, addr, ptep,
1034 pfn_pte(pfn, PAGE_KERNEL));
1035 memset((void *)addr, POISON_FREE_INITMEM, PAGE_SIZE);
1036 free_page(addr);
1037 totalram_pages++;
1038 }
1039 pr_info("Freeing %s: %ldk freed\n", what, (end - begin) >> 10);
1040}
1041
1042void free_initmem(void)
1043{
1044 const unsigned long text_delta = MEM_SV_INTRPT - PAGE_OFFSET;
1045
1046 /*
1047 * Evict the dirty initdata on the boot cpu, evict the w1data
1048 * wherever it's homed, and evict all the init code everywhere.
1049 * We are guaranteed that no one will touch the init pages any
1050 * more, and although other cpus may be touching the w1data,
1051 * we only actually change the caching on tile64, which won't
1052 * be keeping local copies in the other tiles' caches anyway.
1053 */
1054 homecache_evict(&cpu_cacheable_map);
1055
1056 /* Free the data pages that we won't use again after init. */
1057 free_init_pages("unused kernel data",
1058 (unsigned long)_sinitdata,
1059 (unsigned long)_einitdata);
1060
1061 /*
1062 * Free the pages mapped from 0xc0000000 that correspond to code
1063 * pages from 0xfd000000 that we won't use again after init.
1064 */
1065 free_init_pages("unused kernel text",
1066 (unsigned long)_sinittext - text_delta,
1067 (unsigned long)_einittext - text_delta);
1068
1069#if !CHIP_HAS_COHERENT_LOCAL_CACHE()
1070 /*
1071 * Upgrade the .w1data section to globally cached.
1072 * We don't do this on tilepro, since the cache architecture
1073 * pretty much makes it irrelevant, and in any case we end
1074 * up having racing issues with other tiles that may touch
1075 * the data after we flush the cache but before we update
1076 * the PTEs and flush the TLBs, causing sharer shootdowns
1077 * later. Even though this is to clean data, it seems like
1078 * an unnecessary complication.
1079 */
1080 mark_w1data_ro();
1081#endif
1082
1083 /* Do a global TLB flush so everyone sees the changes. */
1084 flush_tlb_all();
1085}
diff --git a/arch/tile/mm/migrate.h b/arch/tile/mm/migrate.h
new file mode 100644
index 000000000000..cd45a0837fa6
--- /dev/null
+++ b/arch/tile/mm/migrate.h
@@ -0,0 +1,50 @@
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 * Structure definitions for migration, exposed here for use by
15 * arch/tile/kernel/asm-offsets.c.
16 */
17
18#ifndef MM_MIGRATE_H
19#define MM_MIGRATE_H
20
21#include <linux/cpumask.h>
22#include <hv/hypervisor.h>
23
24/*
25 * This function is used as a helper when setting up the initial
26 * page table (swapper_pg_dir).
27 */
28extern int flush_and_install_context(HV_PhysAddr page_table, HV_PTE access,
29 HV_ASID asid,
30 const unsigned long *cpumask);
31
32/*
33 * This function supports migration as a "helper" as follows:
34 *
35 * - Set the stack PTE itself to "migrating".
36 * - Do a global TLB flush for (va,length) and the specified ASIDs.
37 * - Do a cache-evict on all necessary cpus.
38 * - Write the new stack PTE.
39 *
40 * Note that any non-NULL pointers must not point to the page that
41 * is handled by the stack_pte itself.
42 */
43extern int homecache_migrate_stack_and_flush(pte_t stack_pte, unsigned long va,
44 size_t length, pte_t *stack_ptep,
45 const struct cpumask *cache_cpumask,
46 const struct cpumask *tlb_cpumask,
47 HV_Remote_ASID *asids,
48 int asidcount);
49
50#endif /* MM_MIGRATE_H */
diff --git a/arch/tile/mm/migrate_32.S b/arch/tile/mm/migrate_32.S
new file mode 100644
index 000000000000..f738765cd1e6
--- /dev/null
+++ b/arch/tile/mm/migrate_32.S
@@ -0,0 +1,211 @@
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 * This routine is a helper for migrating the home of a set of pages to
15 * a new cpu. See the documentation in homecache.c for more information.
16 */
17
18#include <linux/linkage.h>
19#include <linux/threads.h>
20#include <asm/page.h>
21#include <asm/types.h>
22#include <asm/asm-offsets.h>
23#include <hv/hypervisor.h>
24
25 .text
26
27/*
28 * First, some definitions that apply to all the code in the file.
29 */
30
31/* Locals (caller-save) */
32#define r_tmp r10
33#define r_save_sp r11
34
35/* What we save where in the stack frame; must include all callee-saves. */
36#define FRAME_SP 4
37#define FRAME_R30 8
38#define FRAME_R31 12
39#define FRAME_R32 16
40#define FRAME_R33 20
41#define FRAME_R34 24
42#define FRAME_R35 28
43#define FRAME_SIZE 32
44
45
46
47
48/*
49 * On entry:
50 *
51 * r0 low word of the new context PA to install (moved to r_context_lo)
52 * r1 high word of the new context PA to install (moved to r_context_hi)
53 * r2 low word of PTE to use for context access (moved to r_access_lo)
54 * r3 high word of PTE to use for context access (moved to r_access_lo)
55 * r4 ASID to use for new context (moved to r_asid)
56 * r5 pointer to cpumask with just this cpu set in it (r_my_cpumask)
57 */
58
59/* Arguments (caller-save) */
60#define r_context_lo_in r0
61#define r_context_hi_in r1
62#define r_access_lo_in r2
63#define r_access_hi_in r3
64#define r_asid_in r4
65#define r_my_cpumask r5
66
67/* Locals (callee-save); must not be more than FRAME_xxx above. */
68#define r_save_ics r30
69#define r_context_lo r31
70#define r_context_hi r32
71#define r_access_lo r33
72#define r_access_hi r34
73#define r_asid r35
74
75STD_ENTRY(flush_and_install_context)
76 /*
77 * Create a stack frame; we can't touch it once we flush the
78 * cache until we install the new page table and flush the TLB.
79 */
80 {
81 move r_save_sp, sp
82 sw sp, lr
83 addi sp, sp, -FRAME_SIZE
84 }
85 addi r_tmp, sp, FRAME_SP
86 {
87 sw r_tmp, r_save_sp
88 addi r_tmp, sp, FRAME_R30
89 }
90 {
91 sw r_tmp, r30
92 addi r_tmp, sp, FRAME_R31
93 }
94 {
95 sw r_tmp, r31
96 addi r_tmp, sp, FRAME_R32
97 }
98 {
99 sw r_tmp, r32
100 addi r_tmp, sp, FRAME_R33
101 }
102 {
103 sw r_tmp, r33
104 addi r_tmp, sp, FRAME_R34
105 }
106 {
107 sw r_tmp, r34
108 addi r_tmp, sp, FRAME_R35
109 }
110 sw r_tmp, r35
111
112 /* Move some arguments to callee-save registers. */
113 {
114 move r_context_lo, r_context_lo_in
115 move r_context_hi, r_context_hi_in
116 }
117 {
118 move r_access_lo, r_access_lo_in
119 move r_access_hi, r_access_hi_in
120 }
121 move r_asid, r_asid_in
122
123 /* Disable interrupts, since we can't use our stack. */
124 {
125 mfspr r_save_ics, INTERRUPT_CRITICAL_SECTION
126 movei r_tmp, 1
127 }
128 mtspr INTERRUPT_CRITICAL_SECTION, r_tmp
129
130 /* First, flush our L2 cache. */
131 {
132 move r0, zero /* cache_pa */
133 move r1, zero
134 }
135 {
136 auli r2, zero, ha16(HV_FLUSH_EVICT_L2) /* cache_control */
137 move r3, r_my_cpumask /* cache_cpumask */
138 }
139 {
140 move r4, zero /* tlb_va */
141 move r5, zero /* tlb_length */
142 }
143 {
144 move r6, zero /* tlb_pgsize */
145 move r7, zero /* tlb_cpumask */
146 }
147 {
148 move r8, zero /* asids */
149 move r9, zero /* asidcount */
150 }
151 jal hv_flush_remote
152 bnz r0, .Ldone
153
154 /* Now install the new page table. */
155 {
156 move r0, r_context_lo
157 move r1, r_context_hi
158 }
159 {
160 move r2, r_access_lo
161 move r3, r_access_hi
162 }
163 {
164 move r4, r_asid
165 movei r5, HV_CTX_DIRECTIO
166 }
167 jal hv_install_context
168 bnz r0, .Ldone
169
170 /* Finally, flush the TLB. */
171 {
172 movei r0, 0 /* preserve_global */
173 jal hv_flush_all
174 }
175
176.Ldone:
177 /* Reset interrupts back how they were before. */
178 mtspr INTERRUPT_CRITICAL_SECTION, r_save_ics
179
180 /* Restore the callee-saved registers and return. */
181 addli lr, sp, FRAME_SIZE
182 {
183 lw lr, lr
184 addli r_tmp, sp, FRAME_R30
185 }
186 {
187 lw r30, r_tmp
188 addli r_tmp, sp, FRAME_R31
189 }
190 {
191 lw r31, r_tmp
192 addli r_tmp, sp, FRAME_R32
193 }
194 {
195 lw r32, r_tmp
196 addli r_tmp, sp, FRAME_R33
197 }
198 {
199 lw r33, r_tmp
200 addli r_tmp, sp, FRAME_R34
201 }
202 {
203 lw r34, r_tmp
204 addli r_tmp, sp, FRAME_R35
205 }
206 {
207 lw r35, r_tmp
208 addi sp, sp, FRAME_SIZE
209 }
210 jrp lr
211 STD_ENDPROC(flush_and_install_context)
diff --git a/arch/tile/mm/mmap.c b/arch/tile/mm/mmap.c
new file mode 100644
index 000000000000..f96f4cec602a
--- /dev/null
+++ b/arch/tile/mm/mmap.c
@@ -0,0 +1,75 @@
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 * Taken from the i386 architecture and simplified.
15 */
16
17#include <linux/mm.h>
18#include <linux/random.h>
19#include <linux/limits.h>
20#include <linux/sched.h>
21#include <linux/mman.h>
22#include <linux/compat.h>
23
24/*
25 * Top of mmap area (just below the process stack).
26 *
27 * Leave an at least ~128 MB hole.
28 */
29#define MIN_GAP (128*1024*1024)
30#define MAX_GAP (TASK_SIZE/6*5)
31
32static inline unsigned long mmap_base(struct mm_struct *mm)
33{
34 unsigned long gap = rlimit(RLIMIT_STACK);
35 unsigned long random_factor = 0;
36
37 if (current->flags & PF_RANDOMIZE)
38 random_factor = get_random_int() % (1024*1024);
39
40 if (gap < MIN_GAP)
41 gap = MIN_GAP;
42 else if (gap > MAX_GAP)
43 gap = MAX_GAP;
44
45 return PAGE_ALIGN(TASK_SIZE - gap - random_factor);
46}
47
48/*
49 * This function, called very early during the creation of a new
50 * process VM image, sets up which VM layout function to use:
51 */
52void arch_pick_mmap_layout(struct mm_struct *mm)
53{
54#if !defined(__tilegx__)
55 int is_32bit = 1;
56#elif defined(CONFIG_COMPAT)
57 int is_32bit = is_compat_task();
58#else
59 int is_32bit = 0;
60#endif
61
62 /*
63 * Use standard layout if the expected stack growth is unlimited
64 * or we are running native 64 bits.
65 */
66 if (!is_32bit || rlimit(RLIMIT_STACK) == RLIM_INFINITY) {
67 mm->mmap_base = TASK_UNMAPPED_BASE;
68 mm->get_unmapped_area = arch_get_unmapped_area;
69 mm->unmap_area = arch_unmap_area;
70 } else {
71 mm->mmap_base = mmap_base(mm);
72 mm->get_unmapped_area = arch_get_unmapped_area_topdown;
73 mm->unmap_area = arch_unmap_area_topdown;
74 }
75}
diff --git a/arch/tile/mm/pgtable.c b/arch/tile/mm/pgtable.c
new file mode 100644
index 000000000000..335c24621c41
--- /dev/null
+++ b/arch/tile/mm/pgtable.c
@@ -0,0 +1,529 @@
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#include <linux/sched.h>
16#include <linux/kernel.h>
17#include <linux/errno.h>
18#include <linux/mm.h>
19#include <linux/swap.h>
20#include <linux/highmem.h>
21#include <linux/slab.h>
22#include <linux/pagemap.h>
23#include <linux/spinlock.h>
24#include <linux/cpumask.h>
25#include <linux/module.h>
26#include <linux/io.h>
27#include <linux/vmalloc.h>
28#include <linux/smp.h>
29
30#include <asm/system.h>
31#include <asm/pgtable.h>
32#include <asm/pgalloc.h>
33#include <asm/fixmap.h>
34#include <asm/tlb.h>
35#include <asm/tlbflush.h>
36#include <asm/homecache.h>
37
38#define K(x) ((x) << (PAGE_SHIFT-10))
39
40/*
41 * The normal show_free_areas() is too verbose on Tile, with dozens
42 * of processors and often four NUMA zones each with high and lowmem.
43 */
44void show_mem(void)
45{
46 struct zone *zone;
47
48 pr_err("Active:%lu inactive:%lu dirty:%lu writeback:%lu unstable:%lu"
49 " free:%lu\n slab:%lu mapped:%lu pagetables:%lu bounce:%lu"
50 " pagecache:%lu swap:%lu\n",
51 (global_page_state(NR_ACTIVE_ANON) +
52 global_page_state(NR_ACTIVE_FILE)),
53 (global_page_state(NR_INACTIVE_ANON) +
54 global_page_state(NR_INACTIVE_FILE)),
55 global_page_state(NR_FILE_DIRTY),
56 global_page_state(NR_WRITEBACK),
57 global_page_state(NR_UNSTABLE_NFS),
58 global_page_state(NR_FREE_PAGES),
59 (global_page_state(NR_SLAB_RECLAIMABLE) +
60 global_page_state(NR_SLAB_UNRECLAIMABLE)),
61 global_page_state(NR_FILE_MAPPED),
62 global_page_state(NR_PAGETABLE),
63 global_page_state(NR_BOUNCE),
64 global_page_state(NR_FILE_PAGES),
65 nr_swap_pages);
66
67 for_each_zone(zone) {
68 unsigned long flags, order, total = 0, largest_order = -1;
69
70 if (!populated_zone(zone))
71 continue;
72
73 spin_lock_irqsave(&zone->lock, flags);
74 for (order = 0; order < MAX_ORDER; order++) {
75 int nr = zone->free_area[order].nr_free;
76 total += nr << order;
77 if (nr)
78 largest_order = order;
79 }
80 spin_unlock_irqrestore(&zone->lock, flags);
81 pr_err("Node %d %7s: %lukB (largest %luKb)\n",
82 zone_to_nid(zone), zone->name,
83 K(total), largest_order ? K(1UL) << largest_order : 0);
84 }
85}
86
87/*
88 * Associate a virtual page frame with a given physical page frame
89 * and protection flags for that frame.
90 */
91static void set_pte_pfn(unsigned long vaddr, unsigned long pfn, pgprot_t flags)
92{
93 pgd_t *pgd;
94 pud_t *pud;
95 pmd_t *pmd;
96 pte_t *pte;
97
98 pgd = swapper_pg_dir + pgd_index(vaddr);
99 if (pgd_none(*pgd)) {
100 BUG();
101 return;
102 }
103 pud = pud_offset(pgd, vaddr);
104 if (pud_none(*pud)) {
105 BUG();
106 return;
107 }
108 pmd = pmd_offset(pud, vaddr);
109 if (pmd_none(*pmd)) {
110 BUG();
111 return;
112 }
113 pte = pte_offset_kernel(pmd, vaddr);
114 /* <pfn,flags> stored as-is, to permit clearing entries */
115 set_pte(pte, pfn_pte(pfn, flags));
116
117 /*
118 * It's enough to flush this one mapping.
119 * This appears conservative since it is only called
120 * from __set_fixmap.
121 */
122 local_flush_tlb_page(NULL, vaddr, PAGE_SIZE);
123}
124
125void __set_fixmap(enum fixed_addresses idx, unsigned long phys, pgprot_t flags)
126{
127 unsigned long address = __fix_to_virt(idx);
128
129 if (idx >= __end_of_fixed_addresses) {
130 BUG();
131 return;
132 }
133 set_pte_pfn(address, phys >> PAGE_SHIFT, flags);
134}
135
136#if defined(CONFIG_HIGHPTE)
137pte_t *_pte_offset_map(pmd_t *dir, unsigned long address, enum km_type type)
138{
139 pte_t *pte = kmap_atomic(pmd_page(*dir), type) +
140 (pmd_ptfn(*dir) << HV_LOG2_PAGE_TABLE_ALIGN) & ~PAGE_MASK;
141 return &pte[pte_index(address)];
142}
143#endif
144
145/*
146 * List of all pgd's needed so it can invalidate entries in both cached
147 * and uncached pgd's. This is essentially codepath-based locking
148 * against pageattr.c; it is the unique case in which a valid change
149 * of kernel pagetables can't be lazily synchronized by vmalloc faults.
150 * vmalloc faults work because attached pagetables are never freed.
151 * The locking scheme was chosen on the basis of manfred's
152 * recommendations and having no core impact whatsoever.
153 * -- wli
154 */
155DEFINE_SPINLOCK(pgd_lock);
156LIST_HEAD(pgd_list);
157
158static inline void pgd_list_add(pgd_t *pgd)
159{
160 list_add(pgd_to_list(pgd), &pgd_list);
161}
162
163static inline void pgd_list_del(pgd_t *pgd)
164{
165 list_del(pgd_to_list(pgd));
166}
167
168#define KERNEL_PGD_INDEX_START pgd_index(PAGE_OFFSET)
169#define KERNEL_PGD_PTRS (PTRS_PER_PGD - KERNEL_PGD_INDEX_START)
170
171static void pgd_ctor(pgd_t *pgd)
172{
173 unsigned long flags;
174
175 memset(pgd, 0, KERNEL_PGD_INDEX_START*sizeof(pgd_t));
176 spin_lock_irqsave(&pgd_lock, flags);
177
178#ifndef __tilegx__
179 /*
180 * Check that the user interrupt vector has no L2.
181 * It never should for the swapper, and new page tables
182 * should always start with an empty user interrupt vector.
183 */
184 BUG_ON(((u64 *)swapper_pg_dir)[pgd_index(MEM_USER_INTRPT)] != 0);
185#endif
186
187 clone_pgd_range(pgd + KERNEL_PGD_INDEX_START,
188 swapper_pg_dir + KERNEL_PGD_INDEX_START,
189 KERNEL_PGD_PTRS);
190
191 pgd_list_add(pgd);
192 spin_unlock_irqrestore(&pgd_lock, flags);
193}
194
195static void pgd_dtor(pgd_t *pgd)
196{
197 unsigned long flags; /* can be called from interrupt context */
198
199 spin_lock_irqsave(&pgd_lock, flags);
200 pgd_list_del(pgd);
201 spin_unlock_irqrestore(&pgd_lock, flags);
202}
203
204pgd_t *pgd_alloc(struct mm_struct *mm)
205{
206 pgd_t *pgd = kmem_cache_alloc(pgd_cache, GFP_KERNEL);
207 if (pgd)
208 pgd_ctor(pgd);
209 return pgd;
210}
211
212void pgd_free(struct mm_struct *mm, pgd_t *pgd)
213{
214 pgd_dtor(pgd);
215 kmem_cache_free(pgd_cache, pgd);
216}
217
218
219#define L2_USER_PGTABLE_PAGES (1 << L2_USER_PGTABLE_ORDER)
220
221struct page *pte_alloc_one(struct mm_struct *mm, unsigned long address)
222{
223 gfp_t flags = GFP_KERNEL|__GFP_REPEAT|__GFP_ZERO|__GFP_COMP;
224 struct page *p;
225
226#ifdef CONFIG_HIGHPTE
227 flags |= __GFP_HIGHMEM;
228#endif
229
230 p = alloc_pages(flags, L2_USER_PGTABLE_ORDER);
231 if (p == NULL)
232 return NULL;
233
234 pgtable_page_ctor(p);
235 return p;
236}
237
238/*
239 * Free page immediately (used in __pte_alloc if we raced with another
240 * process). We have to correct whatever pte_alloc_one() did before
241 * returning the pages to the allocator.
242 */
243void pte_free(struct mm_struct *mm, struct page *p)
244{
245 pgtable_page_dtor(p);
246 __free_pages(p, L2_USER_PGTABLE_ORDER);
247}
248
249void __pte_free_tlb(struct mmu_gather *tlb, struct page *pte,
250 unsigned long address)
251{
252 int i;
253
254 pgtable_page_dtor(pte);
255 tlb->need_flush = 1;
256 if (tlb_fast_mode(tlb)) {
257 struct page *pte_pages[L2_USER_PGTABLE_PAGES];
258 for (i = 0; i < L2_USER_PGTABLE_PAGES; ++i)
259 pte_pages[i] = pte + i;
260 free_pages_and_swap_cache(pte_pages, L2_USER_PGTABLE_PAGES);
261 return;
262 }
263 for (i = 0; i < L2_USER_PGTABLE_PAGES; ++i) {
264 tlb->pages[tlb->nr++] = pte + i;
265 if (tlb->nr >= FREE_PTE_NR)
266 tlb_flush_mmu(tlb, 0, 0);
267 }
268}
269
270#ifndef __tilegx__
271
272/*
273 * FIXME: needs to be atomic vs hypervisor writes. For now we make the
274 * window of vulnerability a bit smaller by doing an unlocked 8-bit update.
275 */
276int ptep_test_and_clear_young(struct vm_area_struct *vma,
277 unsigned long addr, pte_t *ptep)
278{
279#if HV_PTE_INDEX_ACCESSED < 8 || HV_PTE_INDEX_ACCESSED >= 16
280# error Code assumes HV_PTE "accessed" bit in second byte
281#endif
282 u8 *tmp = (u8 *)ptep;
283 u8 second_byte = tmp[1];
284 if (!(second_byte & (1 << (HV_PTE_INDEX_ACCESSED - 8))))
285 return 0;
286 tmp[1] = second_byte & ~(1 << (HV_PTE_INDEX_ACCESSED - 8));
287 return 1;
288}
289
290/*
291 * This implementation is atomic vs hypervisor writes, since the hypervisor
292 * always writes the low word (where "accessed" and "dirty" are) and this
293 * routine only writes the high word.
294 */
295void ptep_set_wrprotect(struct mm_struct *mm,
296 unsigned long addr, pte_t *ptep)
297{
298#if HV_PTE_INDEX_WRITABLE < 32
299# error Code assumes HV_PTE "writable" bit in high word
300#endif
301 u32 *tmp = (u32 *)ptep;
302 tmp[1] = tmp[1] & ~(1 << (HV_PTE_INDEX_WRITABLE - 32));
303}
304
305#endif
306
307pte_t *virt_to_pte(struct mm_struct* mm, unsigned long addr)
308{
309 pgd_t *pgd;
310 pud_t *pud;
311 pmd_t *pmd;
312
313 if (pgd_addr_invalid(addr))
314 return NULL;
315
316 pgd = mm ? pgd_offset(mm, addr) : swapper_pg_dir + pgd_index(addr);
317 pud = pud_offset(pgd, addr);
318 if (!pud_present(*pud))
319 return NULL;
320 pmd = pmd_offset(pud, addr);
321 if (pmd_huge_page(*pmd))
322 return (pte_t *)pmd;
323 if (!pmd_present(*pmd))
324 return NULL;
325 return pte_offset_kernel(pmd, addr);
326}
327
328pgprot_t set_remote_cache_cpu(pgprot_t prot, int cpu)
329{
330 unsigned int width = smp_width;
331 int x = cpu % width;
332 int y = cpu / width;
333 BUG_ON(y >= smp_height);
334 BUG_ON(hv_pte_get_mode(prot) != HV_PTE_MODE_CACHE_TILE_L3);
335 BUG_ON(cpu < 0 || cpu >= NR_CPUS);
336 BUG_ON(!cpu_is_valid_lotar(cpu));
337 return hv_pte_set_lotar(prot, HV_XY_TO_LOTAR(x, y));
338}
339
340int get_remote_cache_cpu(pgprot_t prot)
341{
342 HV_LOTAR lotar = hv_pte_get_lotar(prot);
343 int x = HV_LOTAR_X(lotar);
344 int y = HV_LOTAR_Y(lotar);
345 BUG_ON(hv_pte_get_mode(prot) != HV_PTE_MODE_CACHE_TILE_L3);
346 return x + y * smp_width;
347}
348
349void set_pte_order(pte_t *ptep, pte_t pte, int order)
350{
351 unsigned long pfn = pte_pfn(pte);
352 struct page *page = pfn_to_page(pfn);
353
354 /* Update the home of a PTE if necessary */
355 pte = pte_set_home(pte, page_home(page));
356
357#ifdef __tilegx__
358 *ptep = pte;
359#else
360 /*
361 * When setting a PTE, write the high bits first, then write
362 * the low bits. This sets the "present" bit only after the
363 * other bits are in place. If a particular PTE update
364 * involves transitioning from one valid PTE to another, it
365 * may be necessary to call set_pte_order() more than once,
366 * transitioning via a suitable intermediate state.
367 * Note that this sequence also means that if we are transitioning
368 * from any migrating PTE to a non-migrating one, we will not
369 * see a half-updated PTE with the migrating bit off.
370 */
371#if HV_PTE_INDEX_PRESENT >= 32 || HV_PTE_INDEX_MIGRATING >= 32
372# error Must write the present and migrating bits last
373#endif
374 ((u32 *)ptep)[1] = (u32)(pte_val(pte) >> 32);
375 barrier();
376 ((u32 *)ptep)[0] = (u32)(pte_val(pte));
377#endif
378}
379
380/* Can this mm load a PTE with cached_priority set? */
381static inline int mm_is_priority_cached(struct mm_struct *mm)
382{
383 return mm->context.priority_cached;
384}
385
386/*
387 * Add a priority mapping to an mm_context and
388 * notify the hypervisor if this is the first one.
389 */
390void start_mm_caching(struct mm_struct *mm)
391{
392 if (!mm_is_priority_cached(mm)) {
393 mm->context.priority_cached = -1U;
394 hv_set_caching(-1U);
395 }
396}
397
398/*
399 * Validate and return the priority_cached flag. We know if it's zero
400 * that we don't need to scan, since we immediately set it non-zero
401 * when we first consider a MAP_CACHE_PRIORITY mapping.
402 *
403 * We only _try_ to acquire the mmap_sem semaphore; if we can't acquire it,
404 * since we're in an interrupt context (servicing switch_mm) we don't
405 * worry about it and don't unset the "priority_cached" field.
406 * Presumably we'll come back later and have more luck and clear
407 * the value then; for now we'll just keep the cache marked for priority.
408 */
409static unsigned int update_priority_cached(struct mm_struct *mm)
410{
411 if (mm->context.priority_cached && down_write_trylock(&mm->mmap_sem)) {
412 struct vm_area_struct *vm;
413 for (vm = mm->mmap; vm; vm = vm->vm_next) {
414 if (hv_pte_get_cached_priority(vm->vm_page_prot))
415 break;
416 }
417 if (vm == NULL)
418 mm->context.priority_cached = 0;
419 up_write(&mm->mmap_sem);
420 }
421 return mm->context.priority_cached;
422}
423
424/* Set caching correctly for an mm that we are switching to. */
425void check_mm_caching(struct mm_struct *prev, struct mm_struct *next)
426{
427 if (!mm_is_priority_cached(next)) {
428 /*
429 * If the new mm doesn't use priority caching, just see if we
430 * need the hv_set_caching(), or can assume it's already zero.
431 */
432 if (mm_is_priority_cached(prev))
433 hv_set_caching(0);
434 } else {
435 hv_set_caching(update_priority_cached(next));
436 }
437}
438
439#if CHIP_HAS_MMIO()
440
441/* Map an arbitrary MMIO address, homed according to pgprot, into VA space. */
442void __iomem *ioremap_prot(resource_size_t phys_addr, unsigned long size,
443 pgprot_t home)
444{
445 void *addr;
446 struct vm_struct *area;
447 unsigned long offset, last_addr;
448 pgprot_t pgprot;
449
450 /* Don't allow wraparound or zero size */
451 last_addr = phys_addr + size - 1;
452 if (!size || last_addr < phys_addr)
453 return NULL;
454
455 /* Create a read/write, MMIO VA mapping homed at the requested shim. */
456 pgprot = PAGE_KERNEL;
457 pgprot = hv_pte_set_mode(pgprot, HV_PTE_MODE_MMIO);
458 pgprot = hv_pte_set_lotar(pgprot, hv_pte_get_lotar(home));
459
460 /*
461 * Mappings have to be page-aligned
462 */
463 offset = phys_addr & ~PAGE_MASK;
464 phys_addr &= PAGE_MASK;
465 size = PAGE_ALIGN(last_addr+1) - phys_addr;
466
467 /*
468 * Ok, go for it..
469 */
470 area = get_vm_area(size, VM_IOREMAP /* | other flags? */);
471 if (!area)
472 return NULL;
473 area->phys_addr = phys_addr;
474 addr = area->addr;
475 if (ioremap_page_range((unsigned long)addr, (unsigned long)addr + size,
476 phys_addr, pgprot)) {
477 remove_vm_area((void *)(PAGE_MASK & (unsigned long) addr));
478 return NULL;
479 }
480 return (__force void __iomem *) (offset + (char *)addr);
481}
482EXPORT_SYMBOL(ioremap_prot);
483
484/* Map a PCI MMIO bus address into VA space. */
485void __iomem *ioremap(resource_size_t phys_addr, unsigned long size)
486{
487 panic("ioremap for PCI MMIO is not supported");
488}
489EXPORT_SYMBOL(ioremap);
490
491/* Unmap an MMIO VA mapping. */
492void iounmap(volatile void __iomem *addr_in)
493{
494 volatile void __iomem *addr = (volatile void __iomem *)
495 (PAGE_MASK & (unsigned long __force)addr_in);
496#if 1
497 vunmap((void * __force)addr);
498#else
499 /* x86 uses this complicated flow instead of vunmap(). Is
500 * there any particular reason we should do the same? */
501 struct vm_struct *p, *o;
502
503 /* Use the vm area unlocked, assuming the caller
504 ensures there isn't another iounmap for the same address
505 in parallel. Reuse of the virtual address is prevented by
506 leaving it in the global lists until we're done with it.
507 cpa takes care of the direct mappings. */
508 read_lock(&vmlist_lock);
509 for (p = vmlist; p; p = p->next) {
510 if (p->addr == addr)
511 break;
512 }
513 read_unlock(&vmlist_lock);
514
515 if (!p) {
516 pr_err("iounmap: bad address %p\n", addr);
517 dump_stack();
518 return;
519 }
520
521 /* Finally remove it */
522 o = remove_vm_area((void *)addr);
523 BUG_ON(p != o || o == NULL);
524 kfree(p);
525#endif
526}
527EXPORT_SYMBOL(iounmap);
528
529#endif /* CHIP_HAS_MMIO() */